Kodi Community Forum
JSON-RPC (JSON Remote Procedure Call) interface protocol in development for XBMC - Printable Version

+- Kodi Community Forum (https://forum.kodi.tv)
+-- Forum: Development (https://forum.kodi.tv/forumdisplay.php?fid=32)
+--- Forum: Kodi Application (https://forum.kodi.tv/forumdisplay.php?fid=93)
+---- Forum: JSON-RPC (https://forum.kodi.tv/forumdisplay.php?fid=174)
+---- Thread: JSON-RPC (JSON Remote Procedure Call) interface protocol in development for XBMC (/showthread.php?tid=68263)



- jasonvp - 2011-09-22

Hi Guys,

Do you intend to merge AudioLibrary and VideoLibrary into Library like you did with AudioPlayer, VideoPlayer and PicturePlayer into Player?


Cheers
Jason


- Montellese - 2011-09-22

jasonvp Wrote:Do you intend to merge AudioLibrary and VideoLibrary into Library like you did with AudioPlayer, VideoPlayer and PicturePlayer into Player?

A while ago (actually several months) we have discussed re-organizing AudioLibrary and VideoLibrary but back then what we wanted to do wasn't possible yet. After I implemented some additional JSON schema features it would actually be possible but I haven't started working on it yet so there's no way to tell when it will happen. There are two different approaches. One provides a single MediaLibrary and the other still provides a VideoLibrary and a AudioLibrary but with generalized methods.


- topfs2 - 2011-09-22

jasonvp Wrote:Hi Guys,

Do you intend to merge AudioLibrary and VideoLibrary into Library like you did with AudioPlayer, VideoPlayer and PicturePlayer into Player?


Cheers
Jason

I think this is a great idea and one we want to do. I personally vote on waiting until core is using a unified library also (which is discussed quite a bit in other threads). Why I suggest waiting is I think it will be real hard to be future proof with the creation of the interface without wrapping an actual interface.

I have planned on trying to find some time during the autumn to help firnsy with the unification, atleast in a PoC way. Many benefits could come out of a more general library.


- grywnn - 2011-09-22

Like Tolriq i'm using infolabels as a convenient way to quickly get all info about the currently playing item.
This is now overly complicated imho because you first need a Player.getActivePlayers, feed the result into Player.getProperties, and feed the playlist id in playlist.getItems. Three requests that can't be batched since they rely on the output of the previous one (or am i missing something here?)
A convenience method would be nice Smile

And, @Montellese: Any more big changes in the near future? Is it safe to update clients yet?

BTW love working with the new playlist namespace!!


- Montellese - 2011-09-22

grywnn Wrote:Like Tolriq i'm using infolabels as a convenient way to quickly get all info about the currently playing item.
This is now overly complicated imho because you first need a Player.getActivePlayers, feed the result into Player.getProperties, and feed the playlist id in playlist.getItems. Three requests that can't be batched since they rely on the output of the previous one (or am i missing something here?)
A convenience method would be nice Smile
We are planning on adding either a method to the Player namespace or a property to Player.GetProperties to retrieve the currently playing item without having to call Playlist.GetItems. You will still have to call Player.GetActivePlayers() but after that you'll only need one call.
What you need to consider is that (partly already now and) in the future there may be multiple items playing at the same time. You can e.g. play a slideshow and a music playlist at the same time. That's why we provide Player.GetActivePlayers(). In such a case the InfoLabels won't suffice to provide you with all the information.

grywnn Wrote:And, @Montellese: Any more big changes in the near future? Is it safe to update clients yet?
I think the biggest part is done. I'll probably add some new properties here and there and like I said some way to easier retrieve the currently playing item(s).

grywnn Wrote:BTW love working with the new playlist namespace!!
Glad to hear that Big Grin


- grywnn - 2011-09-22

Bug?
If i start playback of an .mp3 through Player.Open ... {"item":{"file": "..."}} the item doesn't show up in any playlist.

Code:
{"jsonrpc": "2.0", "method": "Player.getProperties", "params": {"playerid":0,"properties":["playlistid","position","time","type"]}, "id": "1"}
{
    "id": "1",
    "jsonrpc": "2.0",
    "result": {
        "playlistid": 0,
        "position": -1,
        "time": {
            "hours": 0,
            "milliseconds": 484,
            "minutes": 0,
            "seconds": 4
        },
        "type": "audio"
    }
}

The player is playing, but playlist 0 is empty.


- Montellese - 2011-09-22

Yeah that's the same problem as when you start playing a movie/episode/song from recentlyadded in xbmc GUI. Single items currently bypass the playlist and are played directly in the player. That's another reason why I want to add a way to directly retrieve the currently playing item of a player because I could work around that problem for now.

So this is not really a jsonrpc bug but a problem within xbmc and how it handles playback of single items.


- grywnn - 2011-09-22

OK this makes some sense, since the playlist isn't destroyed this way.
I still remember the times when you spend 2 hours creating the ultimate party playlist in early versions of winamp, and then early in the evening some DAU double clicked on one of his favorite .mp3 and... byebye playlist Smile


- Montellese - 2011-09-22

Well neither of those is the behaviour we really want. IMO every item that is played by an XBMC player should be part of a playlist (even if it's a one-item-playlist). But as you said starting playback of a new item should not destroy an existing playlist.

For future versions I/we are aiming for a playlist management system which allows the manual/automatic creation/destruction of playlists. So in your case starting playback of a new item would create a new playlist and start playing that one while still maintaining the old playlist for further use. But xbmc does not support this kind of playlist management yet so we'll have to wait till it does.


- grywnn - 2011-09-22

ACK.
A one-item playlist that's created on the fly would be my choice too.


- mzanetti - 2011-09-22

Hi, I'm trying to adapt my remote control app to the new API but I have some weird problem with Player.Open():

This starts the playback of playlist 0, but it plays the song at position 0 instead of 4 (Responds with "OK"):
Code:
{ "id" : 43, "jsonrpc" : "2.0", "method" : "Player.Open", "params" : { "item" : { "position" : 4 }, "item" : { "playlistid" : 0 } } }

While this does not work at all (I can't really see the difference as the order shouldn't matter)
Code:
{ "id" : 43, "jsonrpc" : "2.0", "method" : "Player.Open", "params" : { "item" : { "playlistid" : 0 }, "item" : { "position" : 4 } } }

It gives this error:
Code:
{"error":{"code":-32602,"data":{"method":"Player.Open","stack":{"message":"Received value does not match any of the union type definitions","name":"item","type":"object"}},"message":"Invalid params."},"id":43,"jsonrpc":"2.0"}

EDIT: Just wondering, what are the advantages of wrapping everything in items? In my opinion this makes the API harder to use and more fail-prone. For example I have to take care that I always use "map.insertMulti()" instead of "map.insert()" and it makes it harder to parse as you need to cycle over all items instead of just accessing "playlistid" and "position".


- Montellese - 2011-09-22

mzanetti Wrote:Hi, I'm trying to adapt my remote control app to the new API but I have some weird problem with Player.Open():

This starts the playback of playlist 0, but it plays the song at position 0 instead of 4 (Responds with "OK"):
Code:
{ "id" : 43, "jsonrpc" : "2.0", "method" : "Player.Open", "params" : { "item" : { "position" : 4 }, "item" : { "playlistid" : 0 } } }

While this does not work at all (I can't really see the difference as the order shouldn't matter)
Code:
{ "id" : 43, "jsonrpc" : "2.0", "method" : "Player.Open", "params" : { "item" : { "playlistid" : 0 }, "item" : { "position" : 4 } } }

It gives this error:
Code:
{"error":{"code":-32602,"data":{"method":"Player.Open","stack":{"message":"Received value does not match any of the union type definitions","name":"item","type":"object"}},"message":"Invalid params."},"id":43,"jsonrpc":"2.0"}
The JSON code you posted is not valid JSON. You can't have two properties (in your case "item") of an object (in your case "params") with the same name. Actually that's not true, it's valid JSON but the second definition of "item" will overwrite the first definition of "item". This is why in the first request you posted you loose the information of "position": 4 and in the second request you loose the "playlistid": 0 information. Because "playlistid" is a required parameter (while "position" is not) it fails in the second request.

The request must look like
Code:
{ "id" : 43, "jsonrpc" : "2.0", "method" : "Player.Open", "params" : { "item" : { "playlistid" : 0, "position" : 4 } } }

mzanetti Wrote:EDIT: Just wondering, what are the advantages of wrapping everything in items? In my opinion this makes the API harder to use and more fail-prone.
The reason why some of those parameters like in Player.Open are wrapped inside an extra JSON object (in that case "item") is because JSON Schema and JSON Service Description otherwise don't allow having "overloaded methods". That means we would have to provide multiple methods Player.OpenPlaylist, Player.OpenFile, Player.OpenDirectory, Player.OpenSlideshow, Player.OpenMovie, Player.OpenAlbum and so on. This means that we will have to implement the Player.OpenFoo method multiple times (with quite some duplicate code) and everytime a new media item is supported, we have to add another method (instead of just adding another parameter as it is now). Having multiple Player.OpenFoo implementations makes the code more difficult to maintain and therefore more fail-prone on XBMC's side.

mzanetti Wrote:For example I have to take care that I always use "map.insertMulti()" instead of "map.insert()" and it makes it harder to parse as you need to cycle over all items instead of just accessing "playlistid" and "position".
Why do you need to cycle over all the items? There can only be one "item" object in the "params" object of Player.Open. In our JSON library/environment we can just do jsonObject["params"]["item"]["playlistid"] and jsonObject["params"]["item"]["position"] and if we make itemObject = jsonObject["params"]["item"] we can do itemObject["playlistid"] and itemObject["position"] without any problem.


- mzanetti - 2011-09-22

Oooops, true... I messed it up... Of course this renders my other statement about the more complex API wrong.

Anyways, the reason why I got it wrong was because it was the only way I could Playlist.Add() get to work.

For example this works:
Code:
{ "id" : 216, "jsonrpc" : "2.0", "method" : "Playlist.Add", "params" : { "item" : { "artistid" : 1 }, "item" : { "albumid" : 1 }, "playlistid" : 0 } }
while this doesn't
Code:
{ "id" : 216, "jsonrpc" : "2.0", "method" : "Playlist.Add", "params" : { "item" : { "artistid" : 1, "albumid" : 1 }, "playlistid" : 0 } }

Thats why I assumed the Player.Open() would be the same. Anyways, is this correct for Playlist.Add or did I mess up again?

Thanks!


- Montellese - 2011-09-23

mzanetti Wrote:Oooops, true... I messed it up... Of course this renders my other statement about the more complex API wrong.

Anyways, the reason why I got it wrong was because it was the only way I could Playlist.Add() get to work.

For example this works:
Code:
{ "id" : 216, "jsonrpc" : "2.0", "method" : "Playlist.Add", "params" : { "item" : { "artistid" : 1 }, "item" : { "albumid" : 1 }, "playlistid" : 0 } }
Well it doesn't work in the sense that it will add all items from album 1 AND from artist 1. It will only add items from album 1 because the second "item" overwrites the first one.

mzanetti Wrote:while this doesn't
Code:
{ "id" : 216, "jsonrpc" : "2.0", "method" : "Playlist.Add", "params" : { "item" : { "artistid" : 1, "albumid" : 1 }, "playlistid" : 0 } }
The "item" parameter of Playlist.Add does only allow to contain a single propertie i.e. EITHER "artistid" OR "albumid" OR "songid" OR "movieid" OR ...

I might write a more detailed description about the "union type" feature of JSON schema which we use in our JSONRPC.Introspect. In short if you see something like this in introspect:
PHP Code:
"type": [
  { 
"type""object""properties": { "artistid": { "$ref""Library.Id""required"true } } },
  { 
"type""object""properties": { "albumid": { "$ref""Library.Id""required"true } } },
  ...

it means that you can either provide an object which contains a property "artistid" OR you can provide an object which contains a property "albumid" OR ... BUT you MUST NOT provide an object which contains more than one of those properties. The fact that the "type" is defined as an array of possible JSON schemas means that those JSON schemas exclude each other and only one of them can be valid for a specific JSON object.


- grywnn - 2011-09-23

2 small things concerning Playlist.Add with item type "directory":
- When i add a (music album) directory to a playlist, the order of items seems to be reversed.
- Can we have a recursive option with directories?

I can open tickets for these two things if needed.