RSS - Ian's Blog RSS - All content RSS - The Media Center Show Subscribe via iTunes  Subscribe with Zune Twitter
mControl for Windows
 Media Center

Writing A Yougle Source

   OK, although this isn't about GENERAL Media Center development and is more of a self-serving plug, I'm going to go ahead anyway and show you how to write a plugin for Yougle.

    I get a lot of requests for particular video, audio and (to a lesser extent) picture sources. What many people don't know is that Yougle is extendible - 3rd party developers can write their own sources to add more content to Yougle.

   So I'm going to show you the basics of creating the Yougle source to allow you to browse the Media Center Show podcasts.

 

   Development of a Yougle source must be done on a Windows Vista installation that has Media Center included - you can use any .NET language, but our example with use C#, the language Yougle Vista itself was written in.

   You also need to have Yougle itself installed.

   Finally, create a new Class Library in the .NET language of your choice.

   Now you need to tell Visual Studio that your program is going to be using some of the classes defined by the Yougle Vista application. You can do this by looking in the ClassWizard, finding the 'References' section, right clicking and choosing 'Add Reference...'.

   The trickiest part of the whole process is coming up. For some reason that I'm sure makes a lot of sense but I don't understand myself, the "References" list in Visual Studio is NOT loaded from the set of assemblies you have in your Global Assembly Cache - they are instead loaded from a completely different location. There are a couple of methods you can use to resolve this particular issue, but the method found here - http://www.devtopics.com/adding-assemblies-to-the-visual-studio-add-reference-dialog/ - isn't bad. You can use this to point to the folder where you have installed Yougle Vista - or, if you can not find the Yougle Vista DLL, you can download it from http://www.push-a-button.com.au/community/index.php?action=tpmod;dl=item47 and put it wherever you like.

 

   OK - now this is done, and we need to start actually writing our code.

   It just so happens that there's an example project and example code on my website at http://www.push-a-button.com.au/community/index.php?topic=92.0 - this gives you the complete sample code for the Flickr picture source. So copy all of this code and paste it into your application.

   A Yougle Source is basically just a single class - based on the YougleSource class - that you customise to load data from your own provider. There are a couple of functions we need to override to do this properly...

 

public class MediaCenterShowVid : YougleSource
    {

        public MediaCenterShowVid()
        {
             //Set up all of the details of this source - description, name, picture etc.
        }

        public override bool Load()
        {
             //Load all of the basic category, filter & sort information for the sliders at the top of the screen
        }

        public override bool GetMedia(int page)
        {            
            //Get a list of media (pictures, videos, audio streams etc.)
        }

        public override string Play(string URL)
        {
            //If required, take the URL discovered in the GetMedia call and convert it into something that we can actually download
        }
    }

   And that's it - override those 4 functions, and you're away!

   So how do we do this in the case of the Media Center Show? Well it's actually pretty easy when you get right down to it. Let's do these in order...

   The Constructor

   Nothing too shocking here, really - you use the Load function to set all of the major information about your source, so that Yougle knows what to show in the list of sources.

        public MediaCenterShowPodcast()
        {
             //Set up all of the details of this source - description, name, picture etc.

            _Name = "The Media Center Show";                                    //The name of the source
            _Description = "Watch Ian Dixon's Media Center Show";       //The description of the source
            _Type = YougleSourceType.audio;                                       //The type of media available (picture,video or audio)
            _Rating = YougleSourceRating.children;                              //The maximum audience rating
            _ImageURL = "http://thedigitallifestyle.com/images/albumcoversmall.png";
                                                                                                    //A URL for an image to use  

        }

 

   The Load Function

   This function is responsible for loading all of the information that appears in the 'pivot bar' at the top of the screen - your sort orders, filters, channels and categories.

   There are TWO pivot bars in Yougle Vista. The top one is called the CATEGORY bar. Each category has one or more OPTIONS to choose from, which are shown on the lower pivot bar.

   As an example, 'Sort' can be a category - with options being 'by popularity', 'by date', 'by views' etc.

   Where there are multiple categories, they work and are reset in a left-to-right manner. For example, let's say the first category was 'sort', the second was 'period' and the third was 'category'. In this case, you can effectively 'add' these three options together (eg. sort="By Popularity", period="Today" and Category="Animals") to create more complex queries - in this case, 'Show Me All Of The Animal Videos That Were Popular Today".

   However, when you change a category value, all of the categories to the RIGHT of that one are reset. For example, if you had the earlier example and changed "period" to "week", the Category would reset to "All".

 

   Anyway, all of this isn't particularly relevant to us, since we will be getting all of our information from the Media Center Show RSS feeds - and there is only one real sorting option, which is "By Date".

        public override bool Load()
        {
             //Load all of the basic category information for the top of the screen

             //There is only really one sort order - By Date. Add it.
            YougleCategorySet Cat = new YougleCategorySet();
            Cat.Name = "sort";
            Cat.Options.Add(new YougleOption("by date", ""));
            Categories.Add(Cat);
            
            return true;           
        }

   Why bother adding anything at all? Well, Media Center is a troublesome beast some times, and you MUST have at least ONE option in every list - so you have to have at least one category, and each category must have at least one option - or your source will crash.

   The GetMedia Function

   This function is the core of Yougle Vista - it gets the media we want to offer to the user. In this case, it will be offering the users the 40 most recent Media Center shows.

   Each media item is stored in a "YougleMovie" object (yes, I really should have gotten around to renaming this, but it was originally a video-only product), and each YougleMovie object has some basic attributes, such as name, thumbnail image, description and one or more URLs.

   Let's start the function...

        public override bool GetMedia(int page)
        {            
            Movies.Clear();            //ALWAYS do this

   Now, we are getting all of our information from an RSS feed from FeedBurner. ( http://feeds.feedburner.com/TheDigitalLifestyleVideoShow ) - so the very first thing we need to do is actually download the thing...

            HttpWebRequest Request = (HttpWebRequest)WebRequest.Create("http://feeds.feedburner.com/TheMediaCenterShowPodcast");
            HttpWebResponse Response = (HttpWebResponse)Request.GetResponse();
            TextReader Rdr = new StreamReader(Response.GetResponseStream());
            String Content = Rdr.ReadToEnd();
  

   This code downloads the current feed from Feedburner, and loads it into a String called 'Content'.

   RSS feeds are simply XML documents, so we should be able to happily load this feed into a XMLDocument object...

            XmlDocument Doc = new XmlDocument();
            Doc.LoadXml(Content);

            XmlNodeList Items = Doc.GetElementsByTagName("item");

            foreach (XmlNode Vid in Items)
            {
                YougleMovie Movie = new YougleMovie();

                Movie.Name = Vid.Attributes["title"].Value;
                Movie.Description = Vid.Attributes["pubDate"].Value;
                Movie.Thumbnail = http://thedigitallifestyle.com/images/albumcoversmall.png";

   OK - now we have a small issue. We aren't given a DIRECT link to the video in it's own tag. Instead, it's embedded inside the Description tag. On the plus side though, it's the only ".mp3" file in the whole text. So perhaps with a regular expression, we can track it down. ( I use Expresso from Ultrapico, which is an excellent program for creating and debugging .NET style regular expressions, which are slightly different to the Unix/PERL style ones you may be familliar with - get it from http://www.ultrapico.com/Expresso.htm ).

   So the regex that finds the 'mp3' file in the description will be something like...

   http://thedigitallifestyle.com/audio/([^"]*?)"

   Which means we can now use that regex to find the MP3 file. 

undefinedhttp://thedigitallifestyle.com/audio/

                Match Mch = Rg.Match(Vid.Attributes["Description"].Value);
                if (Mch.Success == true) Movie.URLs.Add(new YougleMovieURL(Mch.Groups[1].Value, "video/wmv", true));
               
                Movies.Add(Movie);
            } 

    Of course, it would be much more efficient to create the actual Regex OUTSIDE the 'while' loop, to stop it needing to be created again and again. I've added it there simply because we are doing this step-by-step.

   And finally for the GetMedia function, we return a value. We can return either TRUE or FALSE, with 'True' meaning that there is more content waiting to be downloaded (note how the GetMedia function is passed a 'page' parameter? This is so you can download media in seperate 'pages', the same way you view them on a web page). Since we only have access to a single RSS feed and can't move through it, there won't be any more pages to come - so we return FALSE.

            return false;

        }

 

       The Play Function

   The play function is basically there to help speed up the process of locating your media. Quite often, the direct link to the actual video file (the downloadable file, or the actual streaming address) isn't quite as straight forward as it could be. For example, YouTube don't actually publish the location of the .FLV files for their videos - they need to be sourced using special techniques or 3rd party tools ( such as http://www.keepvid.com ) to find the file.

   It would take WAY too long to track down all of these direct links as part of the LoadMedia function, so the Play function is called immediately before Yougle is ready to play or download your video.

   If we were writing the Media Center Show video source, we could end up having a more difficult job to do here - because we may have to get a link to the web page on either YouTube or MSN Soapbox for the episode. To translate that into a actual URL to either the video file (avi, flv, wmv or asx) would take a little more work. (Luckily, Ian always offers a Direct Download option too, so it should be easy to write a video downloader!)

   In this case, we have a situation where we have the actual MP3 file for Media Player to use, so this is really easy.

        public override string Play(string URL)
        {
            //Rebuild the original URL...

            String UR = "http://thedigitallifestyle.com/audio/" + URL;

            //'UR' now contains the actual address to the actual MP3 file, which Media Center will play...
            return UR;
        }


   We could have just stored the full URL in our YougleMovie object and simply not overridden this member at all, but I wanted to show you how it works, for possible future projects.

 

 And we are pretty much done!

 If you have a site you want to work with, but you're having trouble getting direct links to the video or audio files (pictures are usually easy), you'll find that there are a number of websites that have the handy ability to translate web page URL's into video URL's...

   http://max.subfighter.com/flv/downloader.php

   http://www.keepvid.com

 

   


Posted Feb 08 2008, 07:25 AM by IgnoranceIsBliss

Comments

Ian's Digital Lifestyle wrote Want to add more content to Yougle?
on 02-08-2008 9:14 AM
..

Yougle is a great addin for Media Center that enable you to watch user generated content via the 10 foot...

Brian wrote re: Writing A Yougle Source
on 02-08-2008 11:15 PM
..

Can you talk a little more about the last paragraph.  For example, would you pass keepvid.com the URL and let it find the video URL for you?  Then, pass this back into the source?

IgnoranceIsBliss wrote re: Writing A Yougle Source
on 02-09-2008 2:38 AM
..

Ahh, there's not too much extra to say - but yes, as you can see from KeepVid and the max.subfighter.com links, these pages allow you to send the URL of the video web page and get back the actual link to the FLV file.

Internally, these two pages use AJAX scripts - so if you spend a little time looking at the Javascript, you can figure out the magic web page to use in order to get the URL of the FLV files.

It just so happens that Yougle already has built-in support for keepvid. If you actually return the URL "keepvid://<provider>/<target url>" it will internally use KeepVid to figure out the path to the video files.

[You must be signed in to comment]

(c) Ian Dixon 2009