diff options
author | Lars Op den Kamp <lars@opdenkamp.eu> | 2014-02-13 01:06:19 +0100 |
---|---|---|
committer | montellese <montellese@xbmc.org> | 2014-02-27 20:01:34 +0100 |
commit | 73219f1eb6be3b9d5501c3fccfb4569c132fead1 (patch) | |
tree | 5b5fbfacf40a63282003b42e53421bdbae4071ab | |
parent | 595e2fb80be16387e1b174dca7b8bd528d94e571 (diff) |
json-rpc: add PVR.GetTimers, PVR.GetTimerDetails, PVR.GetRecordings and PVR.GetRecordingDetails
-rw-r--r-- | addons/xbmc.json/addon.xml | 2 | ||||
-rw-r--r-- | xbmc/interfaces/json-rpc/FileItemHandler.cpp | 14 | ||||
-rw-r--r-- | xbmc/interfaces/json-rpc/JSONServiceDescription.cpp | 4 | ||||
-rw-r--r-- | xbmc/interfaces/json-rpc/PVROperations.cpp | 72 | ||||
-rw-r--r-- | xbmc/interfaces/json-rpc/PVROperations.h | 4 | ||||
-rw-r--r-- | xbmc/interfaces/json-rpc/ServiceDescription.h | 145 | ||||
-rw-r--r-- | xbmc/interfaces/json-rpc/methods.json | 66 | ||||
-rw-r--r-- | xbmc/interfaces/json-rpc/types.json | 77 |
8 files changed, 382 insertions, 2 deletions
diff --git a/addons/xbmc.json/addon.xml b/addons/xbmc.json/addon.xml index b046a3dbd5..1a26cd2800 100644 --- a/addons/xbmc.json/addon.xml +++ b/addons/xbmc.json/addon.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<addon id="xbmc.json" version="6.13.5" provider-name="Team XBMC"> +<addon id="xbmc.json" version="6.14.0" provider-name="Team XBMC"> <backwards-compatibility abi="6.0.0"/> <requires> <import addon="xbmc.core" version="0.1.0"/> diff --git a/xbmc/interfaces/json-rpc/FileItemHandler.cpp b/xbmc/interfaces/json-rpc/FileItemHandler.cpp index 3964431109..6cdc0ddcc6 100644 --- a/xbmc/interfaces/json-rpc/FileItemHandler.cpp +++ b/xbmc/interfaces/json-rpc/FileItemHandler.cpp @@ -40,6 +40,8 @@ #include "music/MusicThumbLoader.h" #include "Util.h" #include "pvr/channels/PVRChannel.h" +#include "pvr/recordings/PVRRecording.h" +#include "pvr/timers/PVRTimerInfoTag.h" #include "epg/Epg.h" #include "epg/EpgContainer.h" @@ -277,6 +279,10 @@ void CFileItemHandler::HandleFileItem(const char *ID, bool allowFile, const char object["file"] = item->GetVideoInfoTag()->GetPath().c_str(); if (item->HasMusicInfoTag() && !item->GetMusicInfoTag()->GetURL().empty()) object["file"] = item->GetMusicInfoTag()->GetURL().c_str(); + if (item->HasPVRRecordingInfoTag() && !item->GetPVRRecordingInfoTag()->GetPath().empty()) + object["file"] = item->GetPVRRecordingInfoTag()->GetPath().c_str(); + if (item->HasPVRTimerInfoTag() && !item->GetPVRTimerInfoTag()->m_strFileNameAndPath.empty()) + object["file"] = item->GetPVRTimerInfoTag()->m_strFileNameAndPath.c_str(); if (!object.isMember("file")) object["file"] = item->GetPath().c_str(); @@ -290,6 +296,10 @@ void CFileItemHandler::HandleFileItem(const char *ID, bool allowFile, const char object[ID] = item->GetPVRChannelInfoTag()->ChannelID(); else if (item->HasEPGInfoTag() && item->GetEPGInfoTag()->UniqueBroadcastID() > 0) object[ID] = item->GetEPGInfoTag()->UniqueBroadcastID(); + else if (item->HasPVRRecordingInfoTag() && item->GetPVRRecordingInfoTag()->m_iRecordingId > 0) + object[ID] = item->GetPVRRecordingInfoTag()->m_iRecordingId; + else if (item->HasPVRTimerInfoTag() && item->GetPVRTimerInfoTag()->m_iTimerId > 0) + object[ID] = item->GetPVRTimerInfoTag()->m_iTimerId; else if (item->HasMusicInfoTag() && item->GetMusicInfoTag()->GetDatabaseId() > 0) object[ID] = (int)item->GetMusicInfoTag()->GetDatabaseId(); else if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_iDbId > 0) @@ -348,6 +358,10 @@ void CFileItemHandler::HandleFileItem(const char *ID, bool allowFile, const char FillDetails(item->GetPVRChannelInfoTag(), item, fields, object, thumbLoader); if (item->HasEPGInfoTag()) FillDetails(item->GetEPGInfoTag(), item, fields, object, thumbLoader); + if (item->HasPVRRecordingInfoTag()) + FillDetails(item->GetPVRRecordingInfoTag(), item, fields, object, thumbLoader); + if (item->HasPVRTimerInfoTag()) + FillDetails(item->GetPVRTimerInfoTag(), item, fields, object, thumbLoader); if (item->HasVideoInfoTag()) FillDetails(item->GetVideoInfoTag(), item, fields, object, thumbLoader); if (item->HasMusicInfoTag()) diff --git a/xbmc/interfaces/json-rpc/JSONServiceDescription.cpp b/xbmc/interfaces/json-rpc/JSONServiceDescription.cpp index 097311584a..cfbfafe59a 100644 --- a/xbmc/interfaces/json-rpc/JSONServiceDescription.cpp +++ b/xbmc/interfaces/json-rpc/JSONServiceDescription.cpp @@ -171,6 +171,10 @@ JsonRpcMethodMap CJSONServiceDescription::m_methodMaps[] = { { "PVR.GetChannelDetails", CPVROperations::GetChannelDetails }, { "PVR.GetBroadcasts", CPVROperations::GetBroadcasts }, { "PVR.GetBroadcastDetails", CPVROperations::GetBroadcastDetails }, + { "PVR.GetTimers", CPVROperations::GetTimers }, + { "PVR.GetTimerDetails", CPVROperations::GetTimerDetails }, + { "PVR.GetRecordings", CPVROperations::GetRecordings }, + { "PVR.GetRecordingDetails", CPVROperations::GetRecordingDetails }, { "PVR.Record", CPVROperations::Record }, { "PVR.Scan", CPVROperations::Scan }, diff --git a/xbmc/interfaces/json-rpc/PVROperations.cpp b/xbmc/interfaces/json-rpc/PVROperations.cpp index a46b463746..81d72515f0 100644 --- a/xbmc/interfaces/json-rpc/PVROperations.cpp +++ b/xbmc/interfaces/json-rpc/PVROperations.cpp @@ -27,6 +27,8 @@ #include "pvr/channels/PVRChannel.h" #include "pvr/timers/PVRTimers.h" #include "pvr/timers/PVRTimerInfoTag.h" +#include "pvr/recordings/PVRRecordings.h" +#include "pvr/timers/PVRTimers.h" #include "epg/Epg.h" #include "epg/EpgContainer.h" @@ -300,3 +302,73 @@ void CPVROperations::FillChannelGroupDetails(const CPVRChannelGroupPtr &channelG result = object; } } + +JSONRPC_STATUS CPVROperations::GetTimers(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result) +{ + if (!g_PVRManager.IsStarted()) + return FailedToExecute; + + CPVRTimers* timers = g_PVRTimers; + if (!timers) + return FailedToExecute; + + CFileItemList timerList; + timers->GetAll(timerList); + + HandleFileItemList("timerid", false, "timers", timerList, parameterObject, result, true); + + return OK; +} + +JSONRPC_STATUS CPVROperations::GetTimerDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result) +{ + if (!g_PVRManager.IsStarted()) + return FailedToExecute; + + CPVRTimers* timers = g_PVRTimers; + if (!timers) + return FailedToExecute; + + CPVRTimerInfoTagPtr timer = timers->GetById((int)parameterObject["timerid"].asInteger()); + if (!timer) + return InvalidParams; + + HandleFileItem("timerid", false, "timerdetails", CFileItemPtr(new CFileItem(*timer)), parameterObject, parameterObject["properties"], result, false); + + return OK; +} + +JSONRPC_STATUS CPVROperations::GetRecordings(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result) +{ + if (!g_PVRManager.IsStarted()) + return FailedToExecute; + + CPVRRecordings* recordings = g_PVRRecordings; + if (!recordings) + return FailedToExecute; + + CFileItemList recordingsList; + recordings->GetAll(recordingsList); + + HandleFileItemList("recordingid", true, "recordings", recordingsList, parameterObject, result, true); + + return OK; +} + +JSONRPC_STATUS CPVROperations::GetRecordingDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result) +{ + if (!g_PVRManager.IsStarted()) + return FailedToExecute; + + CPVRRecordings* recordings = g_PVRRecordings; + if (!recordings) + return FailedToExecute; + + CFileItemPtr recording = recordings->GetById((int)parameterObject["recordingid"].asInteger()); + if (!recording) + return InvalidParams; + + HandleFileItem("recordingid", true, "recordingdetails", recording, parameterObject, parameterObject["properties"], result, false); + + return OK; +} diff --git a/xbmc/interfaces/json-rpc/PVROperations.h b/xbmc/interfaces/json-rpc/PVROperations.h index ab1afbec6c..415a77b174 100644 --- a/xbmc/interfaces/json-rpc/PVROperations.h +++ b/xbmc/interfaces/json-rpc/PVROperations.h @@ -35,6 +35,10 @@ namespace JSONRPC static JSONRPC_STATUS GetChannelDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result); static JSONRPC_STATUS GetBroadcasts(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result); static JSONRPC_STATUS GetBroadcastDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result); + static JSONRPC_STATUS GetTimers(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result); + static JSONRPC_STATUS GetTimerDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result); + static JSONRPC_STATUS GetRecordings(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result); + static JSONRPC_STATUS GetRecordingDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result); static JSONRPC_STATUS Record(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result); static JSONRPC_STATUS Scan(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result); diff --git a/xbmc/interfaces/json-rpc/ServiceDescription.h b/xbmc/interfaces/json-rpc/ServiceDescription.h index b45b6921f8..836da5617b 100644 --- a/xbmc/interfaces/json-rpc/ServiceDescription.h +++ b/xbmc/interfaces/json-rpc/ServiceDescription.h @@ -22,7 +22,7 @@ namespace JSONRPC { const char* const JSONRPC_SERVICE_ID = "http://xbmc.org/jsonrpc/ServiceDescription.json"; - const char* const JSONRPC_SERVICE_VERSION = "6.13.5"; + const char* const JSONRPC_SERVICE_VERSION = "6.14.0"; const char* const JSONRPC_SERVICE_DESCRIPTION = "JSON-RPC API of XBMC"; const char* const JSONRPC_SERVICE_TYPES[] = { @@ -60,6 +60,11 @@ namespace JSONRPC "}," "\"additionalProperties\": false" "}", + "\"Global.Weekday\": {" + "\"type\": \"string\"," + "\"enum\": [ \"monday\", \"tuesday\", \"wednesday\", \"thursday\"," + "\"friday\", \"saturday\", \"sunday\" ]" + "}", "\"Global.IncrementDecrement\": {" "\"type\": \"string\"," "\"enum\": [ \"increment\", \"decrement\" ]" @@ -854,6 +859,78 @@ namespace JSONRPC "\"rating\": { \"type\": \"integer\" }" "}" "}", + "\"PVR.TimerState\": {" + "\"type\": \"string\"," + "\"enum\": [ \"unknown\", \"new\", \"scheduled\", \"recording\", \"completed\"," + "\"aborted\", \"cancelled\", \"conflict_ok\", \"conflict_notok\"," + "\"error\" ]" + "}", + "\"PVR.Fields.Timer\": {" + "\"extends\": \"Item.Fields.Base\"," + "\"items\": { \"type\": \"string\"," + "\"enum\": [ \"title\", \"summary\", \"channelid\", \"isradio\", \"repeating\"," + "\"starttime\", \"endtime\", \"runtime\", \"lifetime\", \"firstday\"," + "\"weekdays\", \"priority\", \"startmargin\", \"endmargin\", \"state\"," + "\"file\", \"directory\" ]" + "}" + "}", + "\"PVR.Details.Timer\": {" + "\"extends\": \"Item.Details.Base\"," + "\"properties\": {" + "\"timerid\": { \"$ref\": \"Library.Id\", \"required\": true }," + "\"title\": { \"type\": \"string\" }," + "\"summary\": { \"type\": \"string\" }," + "\"channelid\": { \"$ref\": \"Library.Id\" }," + "\"isradio\": { \"type\": \"boolean\" }," + "\"repeating\": { \"type\": \"boolean\" }," + "\"starttime\": { \"type\": \"string\" }," + "\"endtime\": { \"type\": \"string\" }," + "\"runtime\": { \"type\": \"integer\" }," + "\"lifetime\": { \"type\": \"integer\" }," + "\"firstday\": { \"type\": \"string\" }," + "\"weekdays\": { \"type\": \"array\"," + "\"items\": { \"$ref\": \"Global.Weekday\" }," + "\"uniqueItems\": true" + "}," + "\"priority\": { \"type\": \"integer\" }," + "\"startmargin\": { \"type\": \"integer\" }," + "\"endmargin\": { \"type\": \"integer\" }," + "\"state\": { \"$ref\": \"PVR.TimerState\" }," + "\"file\": { \"type\": \"string\" }," + "\"directory\": { \"type\": \"string\" }" + "}" + "}", + "\"PVR.Fields.Recording\": {" + "\"extends\": \"Item.Fields.Base\"," + "\"items\": { \"type\": \"string\"," + "\"enum\": [ \"title\", \"plot\", \"plotoutline\", \"genre\", \"playcount\"," + "\"resume\", \"channel\", \"starttime\",\"endtime\", \"runtime\"," + "\"lifetime\", \"icon\", \"art\", \"streamurl\", \"file\"," + "\"directory\" ]" + "}" + "}", + "\"PVR.Details.Recording\": {" + "\"extends\": \"Item.Details.Base\"," + "\"properties\": {" + "\"recordingid\": { \"$ref\": \"Library.Id\", \"required\": true }," + "\"title\": { \"type\": \"string\" }," + "\"plot\": { \"type\": \"string\" }," + "\"plotoutline\": { \"type\": \"string\" }," + "\"genre\": { \"type\": \"string\" }," + "\"playcount\": { \"type\": \"integer\" }," + "\"resume\": { \"$ref\": \"Video.Resume\" }," + "\"channel\": { \"type\": \"string\" }," + "\"starttime\": { \"type\": \"string\" }," + "\"endtime\": { \"type\": \"string\" }," + "\"runtime\": { \"type\": \"integer\" }," + "\"lifetime\": { \"type\": \"integer\" }," + "\"icon\": { \"type\": \"string\" }," + "\"art\": { \"$ref\": \"Media.Artwork\" }," + "\"streamurl\": { \"type\": \"string\" }," + "\"file\": { \"type\": \"string\" }," + "\"directory\": { \"type\": \"string\" }" + "}" + "}", "\"Textures.Details.Size\": {" "\"type\": \"object\"," "\"properties\": {" @@ -3395,6 +3472,72 @@ namespace JSONRPC "}" "}" "}", + "\"PVR.GetTimers\": {" + "\"type\": \"method\"," + "\"description\": \"Retrieves the timers\"," + "\"transport\": \"Response\"," + "\"permission\": \"ReadData\"," + "\"params\": [" + "{ \"name\": \"properties\", \"$ref\": \"PVR.Fields.Timer\" }," + "{ \"name\": \"limits\", \"$ref\": \"List.Limits\" }" + "]," + "\"returns\": { \"type\": \"object\"," + "\"properties\": {" + "\"limits\": { \"$ref\": \"List.LimitsReturned\", \"required\": true }," + "\"timers\": { \"type\": \"array\", \"required\": true," + "\"items\": { \"$ref\": \"PVR.Details.Timer\" }" + "}" + "}" + "}" + "}", + "\"PVR.GetTimerDetails\": {" + "\"type\": \"method\"," + "\"description\": \"Retrieves the details of a specific timer\"," + "\"transport\": \"Response\"," + "\"permission\": \"ReadData\"," + "\"params\": [" + "{ \"name\": \"timerid\", \"$ref\": \"Library.Id\", \"required\": true }," + "{ \"name\": \"properties\", \"$ref\": \"PVR.Fields.Timer\" }" + "]," + "\"returns\": { \"type\": \"object\"," + "\"properties\": {" + "\"timerdetails\": { \"$ref\": \"PVR.Details.Timer\" }" + "}" + "}" + "}", + "\"PVR.GetRecordings\": {" + "\"type\": \"method\"," + "\"description\": \"Retrieves the recordings\"," + "\"transport\": \"Response\"," + "\"permission\": \"ReadData\"," + "\"params\": [" + "{ \"name\": \"properties\", \"$ref\": \"PVR.Fields.Recording\" }," + "{ \"name\": \"limits\", \"$ref\": \"List.Limits\" }" + "]," + "\"returns\": { \"type\": \"object\"," + "\"properties\": {" + "\"limits\": { \"$ref\": \"List.LimitsReturned\", \"required\": true }," + "\"recordings\": { \"type\": \"array\", \"required\": true," + "\"items\": { \"$ref\": \"PVR.Details.Recording\" }" + "}" + "}" + "}" + "}", + "\"PVR.GetRecordingDetails\": {" + "\"type\": \"method\"," + "\"description\": \"Retrieves the details of a specific recording\"," + "\"transport\": \"Response\"," + "\"permission\": \"ReadData\"," + "\"params\": [" + "{ \"name\": \"recordingid\", \"$ref\": \"Library.Id\", \"required\": true }," + "{ \"name\": \"properties\", \"$ref\": \"PVR.Fields.Recording\" }" + "]," + "\"returns\": { \"type\": \"object\"," + "\"properties\": {" + "\"recordingdetails\": { \"$ref\": \"PVR.Details.Recording\" }" + "}" + "}" + "}", "\"PVR.Record\": {" "\"type\": \"method\"," "\"description\": \"Toggle recording of a channel\"," diff --git a/xbmc/interfaces/json-rpc/methods.json b/xbmc/interfaces/json-rpc/methods.json index 1737e59d9c..49a7357a59 100644 --- a/xbmc/interfaces/json-rpc/methods.json +++ b/xbmc/interfaces/json-rpc/methods.json @@ -1755,6 +1755,72 @@ } } }, + "PVR.GetTimers": { + "type": "method", + "description": "Retrieves the timers", + "transport": "Response", + "permission": "ReadData", + "params": [ + { "name": "properties", "$ref": "PVR.Fields.Timer" }, + { "name": "limits", "$ref": "List.Limits" } + ], + "returns": { "type": "object", + "properties": { + "limits": { "$ref": "List.LimitsReturned", "required": true }, + "timers": { "type": "array", "required": true, + "items": { "$ref": "PVR.Details.Timer" } + } + } + } + }, + "PVR.GetTimerDetails": { + "type": "method", + "description": "Retrieves the details of a specific timer", + "transport": "Response", + "permission": "ReadData", + "params": [ + { "name": "timerid", "$ref": "Library.Id", "required": true }, + { "name": "properties", "$ref": "PVR.Fields.Timer" } + ], + "returns": { "type": "object", + "properties": { + "timerdetails": { "$ref": "PVR.Details.Timer" } + } + } + }, + "PVR.GetRecordings": { + "type": "method", + "description": "Retrieves the recordings", + "transport": "Response", + "permission": "ReadData", + "params": [ + { "name": "properties", "$ref": "PVR.Fields.Recording" }, + { "name": "limits", "$ref": "List.Limits" } + ], + "returns": { "type": "object", + "properties": { + "limits": { "$ref": "List.LimitsReturned", "required": true }, + "recordings": { "type": "array", "required": true, + "items": { "$ref": "PVR.Details.Recording" } + } + } + } + }, + "PVR.GetRecordingDetails": { + "type": "method", + "description": "Retrieves the details of a specific recording", + "transport": "Response", + "permission": "ReadData", + "params": [ + { "name": "recordingid", "$ref": "Library.Id", "required": true }, + { "name": "properties", "$ref": "PVR.Fields.Recording" } + ], + "returns": { "type": "object", + "properties": { + "recordingdetails": { "$ref": "PVR.Details.Recording" } + } + } + }, "PVR.Record": { "type": "method", "description": "Toggle recording of a channel", diff --git a/xbmc/interfaces/json-rpc/types.json b/xbmc/interfaces/json-rpc/types.json index 872b220226..a6b3f9bf89 100644 --- a/xbmc/interfaces/json-rpc/types.json +++ b/xbmc/interfaces/json-rpc/types.json @@ -33,6 +33,11 @@ }, "additionalProperties": false }, + "Global.Weekday": { + "type": "string", + "enum": [ "monday", "tuesday", "wednesday", "thursday", + "friday", "saturday", "sunday" ] + }, "Global.IncrementDecrement": { "type": "string", "enum": [ "increment", "decrement" ] @@ -827,6 +832,78 @@ "rating": { "type": "integer" } } }, + "PVR.TimerState": { + "type": "string", + "enum": [ "unknown", "new", "scheduled", "recording", "completed", + "aborted", "cancelled", "conflict_ok", "conflict_notok", + "error" ] + }, + "PVR.Fields.Timer": { + "extends": "Item.Fields.Base", + "items": { "type": "string", + "enum": [ "title", "summary", "channelid", "isradio", "repeating", + "starttime", "endtime", "runtime", "lifetime", "firstday", + "weekdays", "priority", "startmargin", "endmargin", "state", + "file", "directory" ] + } + }, + "PVR.Details.Timer": { + "extends": "Item.Details.Base", + "properties": { + "timerid": { "$ref": "Library.Id", "required": true }, + "title": { "type": "string" }, + "summary": { "type": "string" }, + "channelid": { "$ref": "Library.Id" }, + "isradio": { "type": "boolean" }, + "repeating": { "type": "boolean" }, + "starttime": { "type": "string" }, + "endtime": { "type": "string" }, + "runtime": { "type": "integer" }, + "lifetime": { "type": "integer" }, + "firstday": { "type": "string" }, + "weekdays": { "type": "array", + "items": { "$ref": "Global.Weekday" }, + "uniqueItems": true + }, + "priority": { "type": "integer" }, + "startmargin": { "type": "integer" }, + "endmargin": { "type": "integer" }, + "state": { "$ref": "PVR.TimerState" }, + "file": { "type": "string" }, + "directory": { "type": "string" } + } + }, + "PVR.Fields.Recording": { + "extends": "Item.Fields.Base", + "items": { "type": "string", + "enum": [ "title", "plot", "plotoutline", "genre", "playcount", + "resume", "channel", "starttime","endtime", "runtime", + "lifetime", "icon", "art", "streamurl", "file", + "directory" ] + } + }, + "PVR.Details.Recording": { + "extends": "Item.Details.Base", + "properties": { + "recordingid": { "$ref": "Library.Id", "required": true }, + "title": { "type": "string" }, + "plot": { "type": "string" }, + "plotoutline": { "type": "string" }, + "genre": { "type": "string" }, + "playcount": { "type": "integer" }, + "resume": { "$ref": "Video.Resume" }, + "channel": { "type": "string" }, + "starttime": { "type": "string" }, + "endtime": { "type": "string" }, + "runtime": { "type": "integer" }, + "lifetime": { "type": "integer" }, + "icon": { "type": "string" }, + "art": { "$ref": "Media.Artwork" }, + "streamurl": { "type": "string" }, + "file": { "type": "string" }, + "directory": { "type": "string" } + } + }, "Textures.Details.Size": { "type": "object", "properties": { |