(2013-06-18, 07:53)Montellese Wrote: When the JSON-RPC (and probably also the Python) API got support for Playlist there were no mixed playlists in XBMC. Every playlist could either contain only video files, only music files or only pictures. In the meantime this has changed a bit in XBMC itself to support videos during a slideshow (but not the other way around AFAIK) but the APIs haven't been adjusted yet.
Last time I tried video playback during a slideshow there were still a lot of quirks and odd things happening so maybe it's safer to wait until the feature is more stable before supporting it in an API that allows applications outside of XBMC to mess around with the playlist etc.
Hi Montellese,
Thanks for your note and explanation. As you describe, when I investigated further I found that json-rpc seems to be ok playing a picture / video slideshow via Player.Open (under Gotham with Tolriq's fix…but not in Frodo) so long as it has a picture playlist that contains both file types.
I've verified by starting a slideshow from the GUI which generates a picture playlist containing both videos and photos. Then I stop the slideshow, and switch to json-rpc. From json-rpc, I can access the playlist the GUI created via Playlist.GetItems and I can start it again using Player.Open.
The difference then currently seems to be that json-rpc prohibits adding videos to a picture playlist. Another interesting side-effect of this situation is the way the Player.Open "directory" method handles various situations:
* Using Player.Open "directory" method with "media" = "video" loads only the videos into the video playlist (as expected).
* Using the Player.Open "directory" method with "media" = "pictures" loads only the pictures into the pictures playlist.
* Using the Player.Open "directory" method with "media" = "files" or "media" = "programs" loads all the files into the video playlist, but the video player (of course) skips over the images.
If the "media" = "files" method where to instead default to the "pictures" playlist instead of the "video" playlist, or if the PlayList.Add were to accept an explicit Add request with a video file (and perhaps optionally it's media type as video) I think the result would be a user experience that mirrored the GUI.
I hear you on the remote access concern, but there is currently no other way to build apps that combine picture+video slideshow capabilities--and I think there are some really interesting things that can be done in this area. One solution to the remote concern might be to add the capabilities to the Python Addon interface...but my sense is that json-rpc is currently richer and being more actively developed.
From my cursory glance it seems like a change to the PLAYLIST_PICTURE case in CPlaylistOperations::Add would be what's needed? I have a strong interest in this video+picture slideshow capability, but I'm sure there are other implications I may not be aware of that folks who're actively working on the codebase might share? I'd love to hear what people think about enhancing the capabilities of the interfaces to mirror the GUI. I'm happy to help if pointed in the right direction.
https://github.com/xbmc/xbmc/blob/c78ba0...ations.cpp
Code:
JSONRPC_STATUS CPlaylistOperations::Add(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
{
int playlist = GetPlaylist(parameterObject["playlistid"]);
CFileItemList list;
CVariant params = parameterObject;
if (!CheckMediaParameter(playlist, parameterObject))
return InvalidParams;
CGUIWindowSlideShow *slideshow = NULL;
switch (playlist)
{
case PLAYLIST_VIDEO:
case PLAYLIST_MUSIC:
if (playlist == PLAYLIST_VIDEO)
params["item"]["media"] = "video";
else if (playlist == PLAYLIST_MUSIC)
params["item"]["media"] = "music";
if (!FillFileItemList(params["item"], list))
return InvalidParams;
CApplicationMessenger::Get().PlayListPlayerAdd(playlist, list);
break;
case PLAYLIST_PICTURE:
slideshow = (CGUIWindowSlideShow*)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
if (!slideshow)
return FailedToExecute;
if (!parameterObject["item"].isMember("media"))
params["item"]["media"] = "pictures";
if (!FillFileItemList(params["item"], list))
return InvalidParams;
for (int index = 0; index < list.Size(); index++)
{
CPictureInfoTag picture = CPictureInfoTag();
if (!picture.Load(list[index]->GetPath()))
continue;
*list[index]->GetPictureInfoTag() = picture;
slideshow->Add(list[index].get());
}
break;
}
NotifyAll();
return ACK;
}