2006-03-08, 02:13
this will probably be a pretty long post, but here's what i'm going to try to accomplish:
1) document what i think are the uses of a thin client/xml api
2) document what i would expect the api to look like that would support (1)
these will be my opinions, and i'm sure that there will be differences of opinions here.
for those of you who haven't, go take a look at http://www.sonos.com and look at that product. i'd like to get to that level of integration (but obviously using pdas or laptops for the remote unless someone's got a better idea [nokia 770 tablet?]). i want an xbox running xbmc to be able to be used as a 1) digital streamer for video and audio attached to a display device (likely to be controlled by a remote or a web ui); and 2) a headless (no display) streamer controlled by a web/thin/pda interface (to compete with sonos/slimbox). i want to be able to run a server app on my server and have it control multiple xboxes to have a synchronized playback effect (or even, keep tabs of what my inlaws have watched in the guest bedroom).
a lot of people are buying into the xbox running xbmc (check out avsforum). some of us are running 3, 4 or 10 xboxes in our houses. can you imagine the possibility of zoneing your xboxes? tracking what they play? a lot of this stuff is science fiction right now, but that's the dream as i have it... ramble off
what a thin client/xml api should support/what are the uses of a thin client/xml api
i would imagine that there are lots of things that people would like, but i'd recommend that we shoot for something like 90% coverage, so i'll define the features into three categories, must have, nice to have, code it yourself (aka. not gonna happen).
must have
- support audio files
- browse files
- view file info (either imdb/cd service or tag)
- manage playlist
- view the playlist (including files by name/tag info)
- add files to the playlist
- reorder the playlist
- clear the playlist
- shuffle/random the playlist
- get info on the currently playing item (including thumbnail)
- player controls
- play/pause toggle
- stop
- next track
- previous track
- fast forward
- rewind
nice to have
- support videos (since you'll have the osd for video, the display on the "remote" app
- multiple playlists support
- create/save
- load
- delete
- support pictures
- administration of the xbox (settings, resolutions, etc.)
write it yourself
- sending some random key combination to the ui
- rss (for crying out loud, who reads rss on their tv? there's no resolution for that).
- share manipulation (this is what the xml is for)
- other crap that i wouldn't use :d
so how do we support all this?
operations to support all that crap up there
(note that this is off the cuff, so don't beat me up if some of it is whack)
incoming command message types
there are two types of incoming command message types:
- get
- post
(and you thought it would be something special!
get commands are done via the query string. an example would be to simulate pressing play, why send a whole bunch of xml when you can say xbmcxml?command=play
on the back end, the code is a little ugly, but back end code is supposed to be ugly to make the front end easier (psuedocode):
post commands will take an xml in the body of the message. these will be useful for batch type operations, or operations where there is large sets of data coming across the wire. examples would be saving preferences, saving an entire playlist.
an example xml would be similar to that which is in the xml wiki, but (minus the <?xml ?> tag, would look something like this:
the post message type would be a request, made of 1 or more commands that had data associated to them. on the back end, the code becomes simpler (psuedocode [note the similarity to the code above]):
outgoing message types
all outgoing messages will have a similar structure:
say for play, the response would be (assuming play started):
let's say for a request to get a playlist's contents, the response might be:
let's say a request fails:
let's say there are three operations:
which (assuming everything went ok) would give you the response:
now, let's say that the same request as above is sent, but selectplaylist fails, then the response would be:
(there is now the question, if on a batch command, if one command fails, do the next commands get skipped? i'd say yes or maybe, depending on how robust you want the system).
but goofygrin, all you've talked to me about is how the messages/commands are sent.
right... let's talk about operations and messages.
operations
for right now, to do basic functionality:
- getcurrentlyplaying (that's more efficient than the current one! and includes all tag info/thumbfilename)
- getplaylistcontents (that's got more detail)
- additemtoplaylist
- additemstoplaylist (might be overloaded of the one above)
- removeitemfromplaylist
- shuffleplaylist
- moveplaylistitem
- clearplaylist
- play/pause toggle
- stop
- next
- previous
- ff
- reverse
- getbookmarks (optionally get subdirectory data as well, but malformed bookmarks will kill this)
- getfilesindirectory (with tag info, optionally all subdirectories)
- getthumbnail (since the file is off somewhere, what i did was filecopy to the q:\web directory to a temp file )
each one of these operations should be supported by an operationhandler class that implements ihandler and will be very modular.
messages
- request
- response
- command
- file type=file (or just file)
- file type=folder (or just folder)
- currentlyplayingdata
- playlist
- playlisttrack (might be the same as file, or might include file since playlisttrack includes the position)
- bookmark
the actual definition of the content of these messages is fairly simple and probably will change over time as features are added.
so if you're still with me, bravo! if you only read to the end, don't come to me asking questions later
1) document what i think are the uses of a thin client/xml api
2) document what i would expect the api to look like that would support (1)
these will be my opinions, and i'm sure that there will be differences of opinions here.
for those of you who haven't, go take a look at http://www.sonos.com and look at that product. i'd like to get to that level of integration (but obviously using pdas or laptops for the remote unless someone's got a better idea [nokia 770 tablet?]). i want an xbox running xbmc to be able to be used as a 1) digital streamer for video and audio attached to a display device (likely to be controlled by a remote or a web ui); and 2) a headless (no display) streamer controlled by a web/thin/pda interface (to compete with sonos/slimbox). i want to be able to run a server app on my server and have it control multiple xboxes to have a synchronized playback effect (or even, keep tabs of what my inlaws have watched in the guest bedroom).
a lot of people are buying into the xbox running xbmc (check out avsforum). some of us are running 3, 4 or 10 xboxes in our houses. can you imagine the possibility of zoneing your xboxes? tracking what they play? a lot of this stuff is science fiction right now, but that's the dream as i have it... ramble off
what a thin client/xml api should support/what are the uses of a thin client/xml api
i would imagine that there are lots of things that people would like, but i'd recommend that we shoot for something like 90% coverage, so i'll define the features into three categories, must have, nice to have, code it yourself (aka. not gonna happen).
must have
- support audio files
- browse files
- view file info (either imdb/cd service or tag)
- manage playlist
- view the playlist (including files by name/tag info)
- add files to the playlist
- reorder the playlist
- clear the playlist
- shuffle/random the playlist
- get info on the currently playing item (including thumbnail)
- player controls
- play/pause toggle
- stop
- next track
- previous track
- fast forward
- rewind
nice to have
- support videos (since you'll have the osd for video, the display on the "remote" app
- multiple playlists support
- create/save
- load
- delete
- support pictures
- administration of the xbox (settings, resolutions, etc.)
write it yourself
- sending some random key combination to the ui
- rss (for crying out loud, who reads rss on their tv? there's no resolution for that).
- share manipulation (this is what the xml is for)
- other crap that i wouldn't use :d
so how do we support all this?
operations to support all that crap up there
(note that this is off the cuff, so don't beat me up if some of it is whack)
incoming command message types
there are two types of incoming command message types:
- get
- post
(and you thought it would be something special!
get commands are done via the query string. an example would be to simulate pressing play, why send a whole bunch of xml when you can say xbmcxml?command=play
on the back end, the code is a little ugly, but back end code is supposed to be ugly to make the front end easier (psuedocode):
Quote:class requesthandler
{
public xml handlerequest( querystring querystring )
{
xml responsenode = new xml( "<response></response>" );
string commandname = querystring["command"];
icommand commandhandler = commandfactory.get( commandname );
responsenode.appendchild(
commandhandler.handlerequestcommand( querystring["parameters"] ) );
}
return responsenode;
}
}
class icommand
{
public xml handlerequestcommand( xmlnode node );
public xml handlerequestcommand( string parameters );
}
class commandfactory
{
public static icommand get( string commandname )
{
// look up in the command registry [xml] for the class/library that's the handler
// instantiate it
// return it
// this model allows for custom commands to be created
// and not have to be merged into the code
}
}
post commands will take an xml in the body of the message. these will be useful for batch type operations, or operations where there is large sets of data coming across the wire. examples would be saving preferences, saving an entire playlist.
an example xml would be similar to that which is in the xml wiki, but (minus the <?xml ?> tag, would look something like this:
Quote:<request>(or using cdatas in elements, depending on what is decided -- given that we're dealing with funny unicode in some places, it might be worth it to take the hit of cdata'ing the things like filenames/tag info)
<command name="saveplaylist" id="0">
<data>
<playlist name="my playlist">
<playlisttracks>
<track order="0" filename="1.mp3" />
<track order="1" filename="2.mp3" />
</playlisttracks>
</playlist>
</data>
</command>
<command name="selectplaylist" id="1">
<data>
<playlist name="my playlist" />
</data>
</command>
</request>
the post message type would be a request, made of 1 or more commands that had data associated to them. on the back end, the code becomes simpler (psuedocode [note the similarity to the code above]):
Quote:class requesthandler
{
public xml handlerequest( xml requestnode )
{
xml responsenode = new xml( "<response></response>" );
foreach(
xmlnode command in requestnode.selectnodes( "/request/command" ) )
{
string commandname = command.attributes["name"];
icommand commandhandler = commandfactory.get( commandname );
responsenode.appendchild(
commandhandler.handlerequestcommand( command ) );
}
return responsenode;
}
}
class icommand
{
public xml handlerequestcommand( xmlnode node );
public xml handlerequestcommand( string parameters );
}
class commandfactory
{
public static icommand get( string commandname )
{
// look up in the command registry [xml] for the class/library that's the handler
// instantiate it
// return it
// this model allows for custom commands to be created
// and not have to be merged into the xbmc code
}
}
outgoing message types
all outgoing messages will have a similar structure:
Quote:<response>
<command id="" status="" />
</response>
say for play, the response would be (assuming play started):
Quote:<response>
<command id="0" status="ok" />
</response>
let's say for a request to get a playlist's contents, the response might be:
Quote:<response>
<command id="0" status="ok">
<data>
<playlist name="my playlist">
<playlisttracks>
<track order="0">
<filename>1.mp3</filename>
<title>title</title>
<artist>artist</artist>
<albumarturl>albumart.jpg</albumarturl>
...
</track>
<track order="1">
<filename>2.mp3</filename>
<title>title</title>
<artist>artist</artist>
<albumarturl>albumart.jpg</albumarturl>
...
</track>
</playlisttracks>
</playlist>
</data>
</command>
</response>
let's say a request fails:
Quote:<response>
<command id="0" status="error" errorcode="12" message="out of disk space" />
</response>
let's say there are three operations:
Quote:<request>
<command name="saveplaylist" id="0">
<data>
<playlist name="my playlist">
<playlisttracks>
<track order="0" filename="1.mp3" />
<track order="1" filename="2.mp3" />
</playlisttracks>
</playlist>
</data>
</command>
<command name="selectplaylist" id="1">
<data>
<playlist name="my playlist" />
</data>
</command>
<command name="shuffleplaylist" id="2" />
<command name="play" id="3" />
</request>
which (assuming everything went ok) would give you the response:
Quote:<response>
<command id="0" status="ok" />
<command id="1" status="ok" />
<command id="2" status="ok" />
<command id="3" status="ok" />
</response>
now, let's say that the same request as above is sent, but selectplaylist fails, then the response would be:
Quote:<response>
<command id="0" status="ok" />
<command id="1" status="error" errorcode="12" message="playlist does not exist" />
<command id="2" status="skipped" />
<command id="3" status="skipped" />
</response>
(there is now the question, if on a batch command, if one command fails, do the next commands get skipped? i'd say yes or maybe, depending on how robust you want the system).
but goofygrin, all you've talked to me about is how the messages/commands are sent.
right... let's talk about operations and messages.
operations
for right now, to do basic functionality:
- getcurrentlyplaying (that's more efficient than the current one! and includes all tag info/thumbfilename)
- getplaylistcontents (that's got more detail)
- additemtoplaylist
- additemstoplaylist (might be overloaded of the one above)
- removeitemfromplaylist
- shuffleplaylist
- moveplaylistitem
- clearplaylist
- play/pause toggle
- stop
- next
- previous
- ff
- reverse
- getbookmarks (optionally get subdirectory data as well, but malformed bookmarks will kill this)
- getfilesindirectory (with tag info, optionally all subdirectories)
- getthumbnail (since the file is off somewhere, what i did was filecopy to the q:\web directory to a temp file )
each one of these operations should be supported by an operationhandler class that implements ihandler and will be very modular.
messages
- request
- response
- command
- file type=file (or just file)
- file type=folder (or just folder)
- currentlyplayingdata
- playlist
- playlisttrack (might be the same as file, or might include file since playlisttrack includes the position)
- bookmark
the actual definition of the content of these messages is fairly simple and probably will change over time as features are added.
so if you're still with me, bravo! if you only read to the end, don't come to me asking questions later