Ok! I admit it! I posted some incorrect information from one of my previous blog posts to “Dynamically Output A List of YouTube Video’s In ASP.NET”. I stupidly said: “The RSS feed is not structured in a nice enough format to output all the information you may need with ease.” I must have been drunk when I wrote that. As you can see from a sample of their RSS feed below I was wrong:
<entry>
<id>http://gdata.youtube.com/feeds/api/videos/R6r2ckeIpic</id>
<published>2009-05-31T17:01:12.000Z</published>
<updated>2009-06-01T01:22:11.000Z</updated>
<category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='bike'/>
<category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='Podcast'/>
<category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='Pedrosa'/>
<category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='motorcycles'/>
<category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='Honda+RC212V'/>
<category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='speed'/>
<category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='Suzuki+GSV-R800'/>
<category scheme='http://schemas.google.com/g/2005#kind' term='http://gdata.youtube.com/schemas/2007#video'/>
<category scheme='http://gdata.youtube.com/schemas/2007/categories.cat' term='Sports' label='Sport'/>
<category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='Rossi'/>
<category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='motorcycle+road+racing'/>
<category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='motograndprix'/>
<category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='Yamaha+YZR+M1'/>
<category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='Mugello'/>
<category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='Italy'/>
<category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='Stoner'/>
<category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='Ducati+Desmosedici+GP8'/>
<category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='MotoGP'/>
<category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='Lorenzo'/>
<title type='text'>MotoGP action from Mugello 2009</title>
<content type='text'>The best of the action from the Gran Premio D&#180;Italia Alice, the fifth round of the 2009 motogp World Championship.</content>
<link rel='alternate' type='text/html' href='http://www.youtube.com/watch?v=R6r2ckeIpic'/>
<link rel='http://gdata.youtube.com/schemas/2007#video.responses' type='application/atom+xml' href='http://gdata.youtube.com/feeds/api/videos/R6r2ckeIpic/responses'/>
<link rel='http://gdata.youtube.com/schemas/2007#video.related' type='application/atom+xml' href='http://gdata.youtube.com/feeds/api/videos/R6r2ckeIpic/related'/>
<link rel='self' type='application/atom+xml' href='http://gdata.youtube.com/feeds/api/users/motogp/uploads/R6r2ckeIpic'/>
<author>
<name>MotoGP</name>
<uri>http://gdata.youtube.com/feeds/api/users/motogp</uri>
</author>
<gd:comments>
<gd:feedLink href='http://gdata.youtube.com/feeds/api/videos/R6r2ckeIpic/comments' countHint='24'/>
</gd:comments>
<media:group>
<media:category label='Sport' scheme='http://gdata.youtube.com/schemas/2007/categories.cat'>Sports</media:category>
<media:description type='plain'>The best of the action from the Gran Premio D&#180;Italia Alice, the fifth round of the 2009 motogp World Championship.</media:description>
<media:keywords>MotoGP, Italy, Mugello, Podcast, Stoner, Pedrosa, Rossi, Lorenzo, Yamaha+YZR+M1, Ducati+Desmosedici+GP8, Honda+RC212V, Suzuki+GSV-R800, motorcycle+road+racing, motograndprix, motorcycles, bike, speed</media:keywords>
<media:player url='http://www.youtube.com/watch?v=R6r2ckeIpic'/>
<media:thumbnail url='http://i.ytimg.com/vi/R6r2ckeIpic/2.jpg' height='90' width='120' time='00:00:38.500'/>
<media:thumbnail url='http://i.ytimg.com/vi/R6r2ckeIpic/1.jpg' height='90' width='120' time='00:00:19.250'/>
<media:thumbnail url='http://i.ytimg.com/vi/R6r2ckeIpic/3.jpg' height='90' width='120' time='00:00:57.750'/>
<media:thumbnail url='http://i.ytimg.com/vi/R6r2ckeIpic/0.jpg' height='240' width='320' time='00:00:38.500'/>
<media:title type='plain'>MotoGP action from Mugello 2009</media:title>
<yt:duration seconds='77'/>
</media:group>
<yt:noembed/>
<gd:rating average='4.862069' max='5' min='1' numRaters='29' rel='http://schemas.google.com/g/2005#overall'/>
<yt:statistics favoriteCount='10' viewCount='1055'/>
</entry>
<entry>
...
</entry>
<entry>
...
</entry>
Each “entry” element within the RSS feed represents a YouTube video. You are able to extrapolate all the important information about each movie such as Average Score, View Count, Thumbnail Images, Video Description, etc. Really useful stuff!
You may be thinking: Why should I use an RSS feed to retrieve the video information rather than using the YouTube API? Well, using a YouTube API is definitely the easier and most straight-forward method. But what you should be aware that the API only works from .NET 2.0 onwards. There isn’t a YouTube API for .NET 1.1. Unfortunately, I only found this out when I tried to implement the API into one of my .NET 1.1 client sites.
The code I have written below, reads the YouTube RSS feed and stores the information in a DataTable.
private void GetYouTubeData(string YouTubeUrl)
{
//Create DataTable to store specific YouTube information
DataTable dtYouTubeVideoData = new DataTable();
dtYouTubeVideoData.Columns.Add("YouTubeID");
dtYouTubeVideoData.Columns.Add("Title");
dtYouTubeVideoData.Columns.Add("Description");
dtYouTubeVideoData.Columns.Add("ImageUrl");
dtYouTubeVideoData.Columns.Add("AverageRatings");
dtYouTubeVideoData.Columns.Add("ViewCount");
DataRow drYouTubeVideoData;
//Link to YouTube RSS feed
XmlTextReader rssReader = new XmlTextReader(YouTubeUrl);
XmlDocument xmlDoc = new XmlDocument();
//Download the XML (via the XmlTextReader)
xmlDoc.Load(rssReader);
//Select all nodes starting with "entry"
XmlNodeList xmlNodeList = xmlDoc.GetElementsByTagName("entry");
//For each "entry" element found
foreach (XmlNode node in xmlNodeList)
{
drYouTubeVideoData = dtYouTubeVideoData.NewRow();
//Create a new document, to search through the inner contents
XmlDocument innerXmlDocument = new XmlDocument();
innerXmlDocument.LoadXml(node.OuterXml);
// Get movie ID
drYouTubeVideoData["YouTubeID"] = innerXmlDocument.GetElementsByTagName("id")[0].InnerText.Replace("http://gdata.youtube.com/feeds/api/videos/", "");
// Get movie title
drYouTubeVideoData["Title"] = innerXmlDocument.GetElementsByTagName("title")[0].InnerText;
//Get movie description
drYouTubeVideoData["Description"] = innerXmlDocument.GetElementsByTagName("content")[0].InnerText;
//Get the thumbnails
XmlNodeList mediaTumbnail = innerXmlDocument.GetElementsByTagName("media:thumbnail");
//Iterate through each thumbnail and only get one thumbnail per <entry>.
foreach (XmlNode thumbnailNode in mediaTumbnail)
{
if (thumbnailNode.Attributes["height"].Value == "90" && thumbnailNode.Attributes["url"].Value.EndsWith("1.jpg"))
{
drYouTubeVideoData["ImageUrl"] = thumbnailNode.Attributes["url"].Value;
}
}
//Get movie rating
XmlNodeList ratings = innerXmlDocument.GetElementsByTagName("gd:rating");
foreach (XmlNode ratingsNode in ratings)
{
drYouTubeVideoData["AverageRatings"] = ratingsNode.Attributes["average"].Value;
}
//Get Statistics
XmlNodeList statistics = innerXmlDocument.GetElementsByTagName("yt:statistics");
foreach (XmlNode statisticsNode in statistics)
{
drYouTubeVideoData["ViewCount"] = statisticsNode.Attributes["viewCount"].Value;
}
dtYouTubeVideoData.Rows.Add(drYouTubeVideoData);
}
rssReader.Close();
//Bind YouTube data to repeater
repVideoList.DataSource = dtYouTubeVideoData;
repVideoList.DataBind();
}