From LinuxMCE
Revision as of 01:41, 9 April 2008 by Aaron.b (Talk | contribs)

Jump to: navigation, search

As of April 7 there is a new plugin mechanism for adding new types of media sources, like YouTube and Shoutcast. Previously, the media plugins, like xine plugin, mythtv plugin, slim server plugin, vlc plugin, etc. had the ability to register with Media_Plugin as being capable of playing the standard types of media already in the system (video files, mp3's, etc.). But all the content that shows up under Media, Video and Media, Audio is a catalog of the files on the hard drives that the UpdateMedia utility was able to catalog. The plugins could not add new content to appear in the media browser; they could only register as being able to media that was already there.

I created a plugin called "YouTube_Plugin" which code is in the svn src directory. This plugin is just a stub to show how the new system works. It's not functional. To use it, in the admin site go to Advanced, Configuration, Devices, choose the Core/DCERouter, and then create device, and pick the YouTube_Plugin device template. Then compile the you tube plugin with make clean so, and put the .so in the /usr/pluto/bin directory and reload the router.

Here is what changed in the code to make this work and what needs to be implemented in the youtube plugin.

The new plugin has a new device data called "Media Catalog". This needs to be set to a \n delimited list of media sources that the plugin will add to the catalog. For example, you tube now has: 5,you_tube_video,YouTube. The first digit is the PK_MediaType from the MediaType table (5=Stored Video). Next is a text string to describe the source. This must be globally unique and not contain any special characters and must start with a letter, not a number. Last is the description that the user should see in the media browser on the 'source' tab.

So if the field had this: 5,you_tube_video1,YouTube #1 5,you_tube_video2,YouTube #2 4,you_tube_audio,YouTube Tunes

then in the media browser under media, video would be two new sources: "YouTube #1 and YouTube #2", and under media, audio would be one new source "YouTube Tunes".

The change to make this appear in the media browser is in src/OrbiterGen/DesignObj_Generator.cpp in DesignObj_Generator::GetArrayValues, in case ARRAY_Media_Filter_Source_CONST where there's a sql select for DEVICEDATA_Media_Catalog_CONST.

The YouTube_Plugin needs the same things as any other plugin that registers to play media. Create the DCE Device. Add the extra base class public MediaHandlerBase, implement the required functions CreateMediaStream, StartMedia, StopMedia. Now there are 2 more required functions you need to implement only if you are going to be adding media to the media browser dynamically: PopulateDataGrid and GetExtendedAttributes.

As always the Register function needs to the media plugin and call RegisterMediaPlugin. The change to media plugin is that it now adds into m_mapMediaCatalog the token (you_tube_video) and pointer to the plugin that implements it. The function Media_Plugin::AttributesBrowser in Media_Plugin/Media_Plugin_Grids.cpp populates the media browser grid. Now, because OrbiterGen added the new sources to the orbiter's source group with the appropriate id's, sPK_Sources is no longer purely a string of numbers like "4,5" but can also include "5,4,you_tube_video". The line if( sPK_MediaSource[0]>'9' ) handles the case where there's a non-numeric source and calls the plugins PopulateDataGrid function.

You must implement that function to provide the content you want to appear in the media browser. This function must return quickly, less than 1 second. Otherwise the user experience will be sluggish and the framework will see the media plugin has stopped responding and automatically kill it. All incoming commands are expected to be processed in less than 15 seconds or else a device is considered "dead". So, in the example of YouTube video, it is expected the plugin will query asynchronously to get a list of videos to populate with the list. Another option, which hasn't been really flushed out yet, is that the plugin can return an indication that it will get the media list asynchronously, and the user will see a 'please wait' on the GUI, and then when the plugin has finished getting the content it will show the grid.

In the plugin you can add 3 types of entries to the media browser: 1) a folder which the user can drill down into, 2) a file the user can play immediately, like youtube or shoutcast, or 3) a file that has to be downloaded asynchronously and you'll tell the user when he can start playing it.

To add a folder, which could be something like genres, do something like this:

FileBrowserInfo *pFileBrowserInfo = new FileBrowserInfo("B 1-sub folder","!e," + sToken + ",URL2 for sub folder",100,StringUtils::SQLDateTime("2008-02-10")); pFileBrowserInfo->m_PK_Picture = 100; pMediaListGrid->m_listFileBrowserInfo.push_back(pFileBrowserInfo);

The first parameter to FileBrowserInfo is the human readable text that will appear on the media browser. Next is the id for the media file, which should be in the format !e,token,url