Skip to content

Commit

Permalink
jsonrpc: add "options" parameter to Player.Open which can take the pr…
Browse files Browse the repository at this point in the history
…operties "shuffled", "repeat" and "resume"
  • Loading branch information
Montellese committed Mar 27, 2012
1 parent cbe96a6 commit 487e5ad
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 37 deletions.
7 changes: 7 additions & 0 deletions xbmc/ApplicationMessenger.cpp
Expand Up @@ -331,6 +331,13 @@ case TMSG_POWERDOWN:
g_application.PlayMedia(*((*list)[0]), playlist);
else
{
// Handle "shuffled" option if present
if (list->HasProperty("shuffled") && list->GetProperty("shuffled").isBoolean())
g_playlistPlayer.SetShuffle(playlist, list->GetProperty("shuffled").asBoolean(), false);
// Handle "repeat" option if present
if (list->HasProperty("repeat") && list->GetProperty("repeat").isInteger())
g_playlistPlayer.SetRepeat(playlist, (PLAYLIST::REPEAT_STATE)list->GetProperty("repeat").asInteger(), false);

g_playlistPlayer.Add(playlist, (*list));
g_playlistPlayer.Play(pMsg->dwParam1);
}
Expand Down
91 changes: 72 additions & 19 deletions xbmc/interfaces/json-rpc/PlayerOperations.cpp
Expand Up @@ -279,8 +279,7 @@ JSONRPC_STATUS CPlayerOperations::Seek(const CStdString &method, ITransportLayer
case Video:
case Audio:
if (parameterObject["value"].isObject())
g_application.SeekTime(((parameterObject["value"]["hours"].asInteger() * 60) + parameterObject["value"]["minutes"].asInteger()) * 60 +
parameterObject["value"]["seconds"].asInteger() + ((double)parameterObject["value"]["milliseconds"].asInteger() / 1000.0));
g_application.SeekTime(ParseTimeInSeconds(parameterObject["value"]));
else if (IsType(parameterObject["value"], NumberValue))
g_application.SeekPercentage(parameterObject["value"].asFloat());
else if (parameterObject["value"].isString())
Expand Down Expand Up @@ -442,19 +441,27 @@ JSONRPC_STATUS CPlayerOperations::Rotate(const CStdString &method, ITransportLay

JSONRPC_STATUS CPlayerOperations::Open(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
{
CVariant optionShuffled = parameterObject["options"]["shuffled"];
CVariant optionRepeat = parameterObject["options"]["repeat"];
CVariant optionResume = parameterObject["options"]["resume"];

if (parameterObject["item"].isObject() && parameterObject["item"].isMember("playlistid"))
{
int playlistid = (int)parameterObject["item"]["playlistid"].asInteger();

if (playlistid < PLAYLIST_PICTURE)
{
// Apply the "shuffled" option if available
if (optionShuffled.isBoolean())
g_playlistPlayer.SetShuffle(playlistid, optionShuffled.asBoolean(), false);
// Apply the "repeat" option if available
if (!optionRepeat.isNull())
g_playlistPlayer.SetRepeat(playlistid, (REPEAT_STATE)ParseRepeatState(optionRepeat), false);
}

switch (playlistid)
{
case PLAYLIST_MUSIC:
if (g_playlistPlayer.GetCurrentPlaylist() != playlistid)
g_playlistPlayer.SetCurrentPlaylist(playlistid);

g_application.getApplicationMessenger().PlayListPlayerPlay((int)parameterObject["item"]["position"].asInteger());
OnPlaylistChanged();
break;

case PLAYLIST_VIDEO:
g_application.getApplicationMessenger().MediaPlay(playlistid, (int)parameterObject["item"]["position"].asInteger());
OnPlaylistChanged();
Expand All @@ -473,7 +480,8 @@ JSONRPC_STATUS CPlayerOperations::Open(const CStdString &method, ITransportLayer

exec += parameterObject["item"]["path"].asString();

if (parameterObject["item"]["random"].asBoolean())
if ((optionShuffled.isBoolean() && optionShuffled.asBoolean()) ||
(!optionShuffled.isBoolean() && parameterObject["item"]["random"].asBoolean()))
exec += ", random";
else
exec += ", notrandom";
Expand Down Expand Up @@ -513,10 +521,32 @@ JSONRPC_STATUS CPlayerOperations::Open(const CStdString &method, ITransportLayer
for (int index = 0; index < list.Size(); index++)
slideshow->Add(list[index].get());

if (optionShuffled.isBoolean() && optionShuffled.asBoolean())
slideshow->Shuffle();

return StartSlideshow();
}
else
{
// Handle "shuffled" option
if (optionShuffled.isBoolean())
list.SetProperty("shuffled", optionShuffled);
// Handle "repeat" option
if (!optionRepeat.isNull())
list.SetProperty("repeat", ParseRepeatState(optionRepeat));
// Handle "resume" option
if (list.Size() == 1)
{
if (optionResume.isBoolean() && optionResume.asBoolean())
list[0]->m_lStartOffset = STARTOFFSET_RESUME;
else if (optionResume.isDouble())
list[0]->SetProperty("StartPercent", optionResume);
else if (optionResume.isObject())
list[0]->m_lStartOffset = (int)(ParseTimeInSeconds(optionResume) * 75.0);
}

g_application.getApplicationMessenger().MediaPlay(list);
}

return ACK;
}
Expand Down Expand Up @@ -629,19 +659,11 @@ JSONRPC_STATUS CPlayerOperations::UnShuffle(const CStdString &method, ITransport

JSONRPC_STATUS CPlayerOperations::Repeat(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
{
REPEAT_STATE state = REPEAT_NONE;
std::string strState = parameterObject["state"].asString();

switch (GetPlayer(parameterObject["playerid"]))
{
case Video:
case Audio:
if (strState.compare("one") == 0)
state = REPEAT_ONE;
else if (strState.compare("all") == 0)
state = REPEAT_ALL;

g_application.getApplicationMessenger().PlayListPlayerRepeat(GetPlaylist(GetPlayer(parameterObject["playerid"])), state);
g_application.getApplicationMessenger().PlayListPlayerRepeat(GetPlaylist(GetPlayer(parameterObject["playerid"])), (REPEAT_STATE)ParseRepeatState(parameterObject["state"]));
OnPlaylistChanged();
break;

Expand Down Expand Up @@ -1318,3 +1340,34 @@ JSONRPC_STATUS CPlayerOperations::GetPropertyValue(PlayerType player, const CStd

return OK;
}

int CPlayerOperations::ParseRepeatState(const CVariant &repeat)
{
REPEAT_STATE state = REPEAT_NONE;
std::string strState = repeat.asString();

if (strState.compare("one") == 0)
state = REPEAT_ONE;
else if (strState.compare("all") == 0)
state = REPEAT_ALL;

return state;
}

double CPlayerOperations::ParseTimeInSeconds(const CVariant &time)
{
double seconds = 0.0;
if (time.isObject())
{
if (time.isMember("hours"))
seconds += time["hours"].asInteger() * 60 * 60;
if (time.isMember("minutes"))
seconds += time["minutes"].asInteger() * 60;
if (time.isMember("seconds"))
seconds += time["seconds"].asInteger();
if (time.isMember("milliseconds"))
seconds += time["milliseconds"].asDouble() / 1000.0;
}

return seconds;
}
3 changes: 3 additions & 0 deletions xbmc/interfaces/json-rpc/PlayerOperations.h
Expand Up @@ -76,5 +76,8 @@ namespace JSONRPC
static void SendSlideshowAction(int actionID);
static void OnPlaylistChanged();
static JSONRPC_STATUS GetPropertyValue(PlayerType player, const CStdString &property, CVariant &result);

static int ParseRepeatState(const CVariant &repeat);
static double ParseTimeInSeconds(const CVariant &time);
};
}
34 changes: 25 additions & 9 deletions xbmc/interfaces/json-rpc/ServiceDescription.h
Expand Up @@ -136,6 +136,16 @@ namespace JSONRPC
"\"minimum\": 0.0,"
"\"maximum\": 100.0"
"}",
"\"Player.Position.Time\": {"
"\"type\": \"object\","
"\"additionalProperties\": false,"
"\"properties\": {"
"\"hours\": { \"type\": \"integer\", \"minimum\": 0, \"maximum\": 23, \"default\": 0 },"
"\"minutes\": { \"type\": \"integer\", \"minimum\": 0, \"maximum\": 59, \"default\": 0 },"
"\"seconds\": { \"type\": \"integer\", \"minimum\": 0, \"maximum\": 59, \"default\": 0 },"
"\"milliseconds\": { \"type\": \"integer\", \"minimum\": 0, \"maximum\": 999, \"default\": 0 }"
"}"
"}",
"\"Player.Speed\": {"
"\"type\": \"object\","
"\"required\": true,"
Expand Down Expand Up @@ -951,11 +961,24 @@ namespace JSONRPC
"{ \"type\": \"object\", \"required\": true, \"additionalProperties\": false,"
"\"properties\": {"
"\"path\": { \"type\": \"string\", \"required\": true },"
"\"random\": { \"type\": \"boolean\", \"default\": true },"
"\"random\": { \"type\": \"boolean\", \"default\": true, \"description\": \"Deprecated, use the shuffled property of the options parameter instead\" },"
"\"recursive\": { \"type\": \"boolean\", \"default\": true }"
"}"
"}"
"]"
"},"
"{ \"name\": \"options\", \"type\": \"object\", \"additionalProperties\": false,"
"\"properties\": {"
"\"shuffled\": { \"$ref\": \"Optional.Boolean\" },"
"\"repeat\": { \"type\": [ \"null\", \"Player.Repeat\" ], \"default\": null },"
"\"resume\": { \"type\": ["
"{ \"type\": \"boolean\", \"required\": true, \"description\": \"Whether to resume from the resume point or not\" },"
"{ \"$ref\": \"Player.Position.Percentage\", \"required\": true, \"description\": \"Percentage value to start from\" },"
"{ \"$ref\": \"Player.Position.Time\", \"required\": true, \"description\": \"Time to start from\" }"
"],"
"\"default\": false"
"}"
"}"
"}"
"],"
"\"returns\": \"string\""
Expand Down Expand Up @@ -1050,14 +1073,7 @@ namespace JSONRPC
"{ \"name\": \"playerid\", \"$ref\": \"Player.Id\", \"required\": true },"
"{ \"name\": \"value\", \"required\": true, \"type\": ["
"{ \"$ref\": \"Player.Position.Percentage\", \"required\": true, \"description\": \"Percentage value to seek to\" },"
"{ \"type\": \"object\", \"additionalProperties\": false, \"required\": true, \"description\": \"Time to seek to\","
"\"properties\": {"
"\"hours\": { \"type\": \"integer\", \"minimum\": 0, \"maximum\": 23 },"
"\"minutes\": { \"type\": \"integer\", \"minimum\": 0, \"maximum\": 59 },"
"\"seconds\": { \"type\": \"integer\", \"minimum\": 0, \"maximum\": 59 },"
"\"milliseconds\": { \"type\": \"integer\", \"minimum\": 0, \"maximum\": 999 }"
"}"
"},"
"{ \"$ref\": \"Player.Position.Time\", \"required\": true, \"description\": \"Time to seek to\" },"
"{ \"type\": \"string\", \"enum\": [ \"smallforward\", \"smallbackward\", \"bigforward\", \"bigbackward\" ], \"required\": true, \"description\": \"Seek by predefined jumps\" }"
"]"
"}"
Expand Down
24 changes: 15 additions & 9 deletions xbmc/interfaces/json-rpc/methods.json
Expand Up @@ -114,11 +114,24 @@
{ "type": "object", "required": true, "additionalProperties": false,
"properties": {
"path": { "type": "string", "required": true },
"random": { "type": "boolean", "default": true },
"random": { "type": "boolean", "default": true, "description": "Deprecated, use the shuffled property of the options parameter instead" },
"recursive": { "type": "boolean", "default": true }
}
}
]
},
{ "name": "options", "type": "object", "additionalProperties": false,
"properties": {
"shuffled": { "$ref": "Optional.Boolean" },
"repeat": { "type": [ "null", "Player.Repeat" ], "default": null },
"resume": { "type": [
{ "type": "boolean", "required": true, "description": "Whether to resume from the resume point or not" },
{ "$ref": "Player.Position.Percentage", "required": true, "description": "Percentage value to start from" },
{ "$ref": "Player.Position.Time", "required": true, "description": "Time to start from" }
],
"default": false
}
}
}
],
"returns": "string"
Expand Down Expand Up @@ -213,14 +226,7 @@
{ "name": "playerid", "$ref": "Player.Id", "required": true },
{ "name": "value", "required": true, "type": [
{ "$ref": "Player.Position.Percentage", "required": true, "description": "Percentage value to seek to" },
{ "type": "object", "additionalProperties": false, "required": true, "description": "Time to seek to",
"properties": {
"hours": { "type": "integer", "minimum": 0, "maximum": 23 },
"minutes": { "type": "integer", "minimum": 0, "maximum": 59 },
"seconds": { "type": "integer", "minimum": 0, "maximum": 59 },
"milliseconds": { "type": "integer", "minimum": 0, "maximum": 999 }
}
},
{ "$ref": "Player.Position.Time", "required": true, "description": "Time to seek to" },
{ "type": "string", "enum": [ "smallforward", "smallbackward", "bigforward", "bigbackward" ], "required": true, "description": "Seek by predefined jumps" }
]
}
Expand Down
10 changes: 10 additions & 0 deletions xbmc/interfaces/json-rpc/types.json
Expand Up @@ -108,6 +108,16 @@
"minimum": 0.0,
"maximum": 100.0
},
"Player.Position.Time": {
"type": "object",
"additionalProperties": false,
"properties": {
"hours": { "type": "integer", "minimum": 0, "maximum": 23, "default": 0 },
"minutes": { "type": "integer", "minimum": 0, "maximum": 59, "default": 0 },
"seconds": { "type": "integer", "minimum": 0, "maximum": 59, "default": 0 },
"milliseconds": { "type": "integer", "minimum": 0, "maximum": 999, "default": 0 }
}
},
"Player.Speed": {
"type": "object",
"required": true,
Expand Down

0 comments on commit 487e5ad

Please sign in to comment.