×
Namespaces

Variants
Actions
(Difference between revisions)

How to parse YouTube API response

From Nokia Developer Wiki
Jump to: navigation, search
kiran10182 (Talk | contribs)
m (Kiran10182 - - Introduction)
hamishwillee (Talk | contribs)
m (Hamishwillee - Bot update - Fix metadata)
Line 6: Line 6:
 
|devices= Nokia Lumia 820,920 <!-- Devices tested against - e.g. ''devices=Nokia 6131 NFC, Nokia C7-00'') -->
 
|devices= Nokia Lumia 820,920 <!-- Devices tested against - e.g. ''devices=Nokia 6131 NFC, Nokia C7-00'') -->
 
|sdk= [http://www.microsoft.com/en-us/download/details.aspx?id=35471 Windows Phone SDK 8.0] <!-- SDK(s) built and tested against (e.g. [http://linktosdkdownload/ Qt SDK 1.1.4]) -->
 
|sdk= [http://www.microsoft.com/en-us/download/details.aspx?id=35471 Windows Phone SDK 8.0] <!-- SDK(s) built and tested against (e.g. [http://linktosdkdownload/ Qt SDK 1.1.4]) -->
|platform= Windows Phone 7.5 and later
+
|dependencies= [https://developers.google.com/youtube/2.0/reference YouTube API] <!-- Any other/external dependencies e.g.: Google Maps Api v1.0 -->
|dependencies=[https://developers.google.com/youtube/2.0/reference YouTube API] <!-- Any other/external dependencies e.g.: Google Maps Api v1.0 -->
+
 
|signing= Self-Signed<!-- Signing requirements - empty or one of: Self-Signed, DevCert, Manufacturer -->
 
|signing= Self-Signed<!-- Signing requirements - empty or one of: Self-Signed, DevCert, Manufacturer -->
 
|capabilities= ID_CAP_NETWORKING<!-- Capabilities required by the article/code example (e.g. Location, NetworkServices. -->
 
|capabilities= ID_CAP_NETWORKING<!-- Capabilities required by the article/code example (e.g. Location, NetworkServices. -->
|keywords= YouTube Videos<!-- APIs, classes and methods (e.g. QSystemScreenSaver, QList, CBase -->
 
 
|language= <!-- Language category code for non-English topics - e.g. Lang-Chinese -->
 
|language= <!-- Language category code for non-English topics - e.g. Lang-Chinese -->
 
|translated-by= <!-- [[User:XXXX]] -->
 
|translated-by= <!-- [[User:XXXX]] -->
Line 22: Line 20:
 
|author= [[User:Somnathbanik]]
 
|author= [[User:Somnathbanik]]
 
<!-- The following are not in current metadata -->
 
<!-- The following are not in current metadata -->
 +
|keywords= YouTube Videos<!-- APIs, classes and methods (e.g. QSystemScreenSaver, QList, CBase -->
 +
|platform= Windows Phone 7.5 and later
 
|devicecompatability= <!-- Compatible devices e.g.: All* (must have internal GPS) -->
 
|devicecompatability= <!-- Compatible devices e.g.: All* (must have internal GPS) -->
 
}}
 
}}
Line 46: Line 46:
  
 
===Adding UI controls on application page===
 
===Adding UI controls on application page===
We have created two sections in the panorama view, one where we display TopRated, MostPopular, MostShared, RecentlyFeatured, TopFavorites, MostViewed and the other section where user can search for a particular video and display the list. Let’s open the '''MainPage.xaml''' file and paste the below code to create the UI.
+
We have created two sections in the panorama view, one where we display TopRated, MostPopular, MostShared, RecentlyFeatured, TopFavorites, MostViewed and the other section where user can search for a particular video and display the list. Let’s open the '''MainPage.xaml''' file and paste the below code to create the UI.
 
<code xml>
 
<code xml>
 
<Grid x:Name="LayoutRoot" Background="Transparent">
 
<Grid x:Name="LayoutRoot" Background="Transparent">
Line 65: Line 65:
 
                                 </Rectangle.Fill>
 
                                 </Rectangle.Fill>
 
                             </Rectangle>
 
                             </Rectangle>
                                 <Image Name="img_TopRated" Tap="Rectangle_Tap" Height="358" Width="358" Stretch="UniformToFill" Margin="12,-358,12,0"></Image>
+
                                 <Image Name="img_TopRated" Tap="Rectangle_Tap" Height="358" Width="358" Stretch="UniformToFill" Margin="12,-358,12,0"></Image>
 
                                 <Rectangle Height="100" Width="358" Margin="12,-100,12,0" Opacity="0.7" >
 
                                 <Rectangle Height="100" Width="358" Margin="12,-100,12,0" Opacity="0.7" >
 
                                     <Rectangle.Fill  >
 
                                     <Rectangle.Fill  >
Line 169: Line 169:
 
                             <DataTemplate>
 
                             <DataTemplate>
 
                                 <StackPanel Name="stackPanelSongs" Orientation="Horizontal" Margin="0,12,0,17" >
 
                                 <StackPanel Name="stackPanelSongs" Orientation="Horizontal" Margin="0,12,0,17" >
                                     <Image Source="{Binding Image}" Stretch="UniformToFill" Height="100" Width="100"  VerticalAlignment="Top" Margin="0,0,0,0"/>
+
                                     <Image Source="{Binding Image}" Stretch="UniformToFill" Height="100" Width="100"  VerticalAlignment="Top" Margin="0,0,0,0"/>
                                     <StackPanel Width="345" Height="90" Margin="0,0,0,0" >
+
                                     <StackPanel Width="345" Height="90" Margin="0,0,0,0" >
                                         <TextBlock Name="SongTitle" Text="{Binding Title}"  TextWrapping="NoWrap" Margin="12,0,0,0"    FontFamily="Segoe WP Semibold" FontSize="28" Foreground="#efd584" />
+
                                         <TextBlock Name="SongTitle" Text="{Binding Title}"  TextWrapping="NoWrap" Margin="12,0,0,0"    FontFamily="Segoe WP Semibold" FontSize="28" Foreground="#efd584" />
                                         <TextBlock Text="{Binding Description}" TextWrapping="NoWrap" Margin="12,0,0,0" Style="{StaticResource PhoneTextSubtleStyle}" Foreground="Peru" />
+
                                         <TextBlock Text="{Binding Description}" TextWrapping="NoWrap" Margin="12,0,0,0" Style="{StaticResource PhoneTextSubtleStyle}" Foreground="Peru" />
 
                                     </StackPanel>
 
                                     </StackPanel>
 
                                 </StackPanel>
 
                                 </StackPanel>
Line 202: Line 202:
 
The {{Icode|ConnectToYouTube()}} method parse the YouTube video listing API and calls the respective event handler to display the video list on to the UI. Till here is very straight forward as these are REST APIs and returns response in XML format. To know the API used in this example please see '''YouTubeData.cs''' file.
 
The {{Icode|ConnectToYouTube()}} method parse the YouTube video listing API and calls the respective event handler to display the video list on to the UI. Till here is very straight forward as these are REST APIs and returns response in XML format. To know the API used in this example please see '''YouTubeData.cs''' file.
  
* Once user clicks on a particular video item we take the video id and call {{Icode|GetVideoUrl()}} method which then put a API request and gets percent encoding data as response.
+
* Once user clicks on a particular video item we take the video id and call {{Icode|GetVideoUrl()}} method which then put a API request and gets percent encoding data as response.
 
<code csharp>
 
<code csharp>
 
   public void GetVideoUrl(string avideoId)
 
   public void GetVideoUrl(string avideoId)
Line 214: Line 214:
 
</code>
 
</code>
  
We use [http://msdn.microsoft.com/en-us/library/system.web.httputility.aspx HttpUtility] class to decode the response and brings to a regular text base format. We search for the string '''&url_encoded_fmt_stream_map=''' in the response and take out the data from its start to end. This response has many information about the particular video including all its file type and formats. We are interested on Baseline MP4 format which has a tag '''itag=18'''. Now search for the tag '''itag=18''' and get the respective parameters. See [https://en.wikipedia.org/wiki/YouTube Wikipedia] to know all supported format by YouTube and there tags. You may come across to a situation where you find two '''itag=18''' in the response and '''s''' or '''sig''' in place of '''signature''' parameter. All you need to do is to handle these conditions to get the required parameters. In this example we have checked these scenarios in '''VideoUrl.cs''' file and called {{Icode|OnVideoUrlLoaded}} event with the final video URL which then play the video on default player in '''MainPage.xaml.cs'''  file.  
+
We use [http://msdn.microsoft.com/en-us/library/system.web.httputility.aspx HttpUtility] class to decode the response and brings to a regular text base format. We search for the string '''&url_encoded_fmt_stream_map=''' in the response and take out the data from its start to end. This response has many information about the particular video including all its file type and formats. We are interested on Baseline MP4 format which has a tag '''itag=18'''. Now search for the tag '''itag=18''' and get the respective parameters. See [https://en.wikipedia.org/wiki/YouTube Wikipedia] to know all supported format by YouTube and there tags. You may come across to a situation where you find two '''itag=18''' in the response and '''s''' or '''sig''' in place of '''signature''' parameter. All you need to do is to handle these conditions to get the required parameters. In this example we have checked these scenarios in '''VideoUrl.cs''' file and called {{Icode|OnVideoUrlLoaded}} event with the final video URL which then play the video on default player in '''MainPage.xaml.cs'''  file.  
 
  <code csharp>
 
  <code csharp>
 
void IVideo_OnVideoUrlLoaded(object sender, VideoUrlArgs e)
 
void IVideo_OnVideoUrlLoaded(object sender, VideoUrlArgs e)
Line 224: Line 224:
 
         }
 
         }
 
</code>
 
</code>
The same concept is applied to YouTube video search also, where you can search a video from YouTube and play it.
+
The same concept is applied to YouTube video search also, where you can search a video from YouTube and play it.
To keep the article in sort I haven’t put the complete source code here. Please download the source code for better understanding.
+
To keep the article in sort I haven’t put the complete source code here. Please download the source code for better understanding.
  
 
==Summary==
 
==Summary==

Revision as of 02:31, 26 July 2013

This article demonstrates how to use YouTube standard and search APIs to play videos on Windows Phone.

WP Metro Icon Web.png
SignpostIcon XAML 40.png
WP Metro Icon WP8.png
SignpostIcon WP7 70px.png
Article Metadata
Code ExampleTested with
Devices(s): Nokia Lumia 820,920
Compatibility
Platform(s): Windows Phone 7.5 and later
Windows Phone 8
Windows Phone 7.5
Dependencies: YouTube API
Platform Security
Signing Required: Self-Signed
Capabilities: ID_CAP_NETWORKING
Article
Keywords: YouTube Videos
Created: somnathbanik (23 Jul 2014)
Last edited: hamishwillee (26 Jul 2013)

Contents

Introduction

The idea of writing this article came from the inspiration when I saw many queries on how to play YouTube videos on Windows Phone. There is nothing hard to play a streaming video on Windows Phone, as the default player takes care of it seamlessly. You can refer to this article to know more about how to play streaming video on Windows Phone default player. The tricks that we need to use is to get the video URL from YouTube API response. YouTube provides a text based percent encoding response of a particular video id which is not always in the same format. To decode the video URL from the percent encoding response, I have used a basic string parsing technique which you can find in VideoUrl.cs file.

Implementation

Create a standard Windows Phone Project

Let’s create a standard Windows Phone Application Project

  • Launch Visual Studio
  • Click on File
  • Click on New Project
  • Select Windows Phone Panorama App (Visual C# Template)
  • Add Name and Location of the project
  • Click OK to create the project.

Adding UI controls on application page

We have created two sections in the panorama view, one where we display TopRated, MostPopular, MostShared, RecentlyFeatured, TopFavorites, MostViewed and the other section where user can search for a particular video and display the list. Let’s open the MainPage.xaml file and paste the below code to create the UI.

<Grid x:Name="LayoutRoot" Background="Transparent">
<!--Panorama control-->
<controls:Panorama Title="YouTube Demo">
<controls:Panorama.Background >
<ImageBrush ImageSource="PanoramaBackground.png" Opacity="0.2"/>
</controls:Panorama.Background>
<!--Panorama item one-->
<controls:PanoramaItem Header="Videos" Orientation="Horizontal" >
<Grid x:Name="gridFirstItems" >
<StackPanel x:Name="mainStackPanel" Orientation="Horizontal" VerticalAlignment="Top" HorizontalAlignment="Left">
<StackPanel Name="bigImage" Orientation="Horizontal" >
<StackPanel Orientation="Vertical">
<Rectangle Height="358" Width="358" Margin="12,0,12,0" Tap="Rectangle_Tap" >
<Rectangle.Fill>
<SolidColorBrush Color="{StaticResource PhoneAccentColor}" />
</Rectangle.Fill>
</Rectangle>
<Image Name="img_TopRated" Tap="Rectangle_Tap" Height="358" Width="358" Stretch="UniformToFill" Margin="12,-358,12,0"></Image>
<Rectangle Height="100" Width="358" Margin="12,-100,12,0" Opacity="0.7" >
<Rectangle.Fill >
<SolidColorBrush Color="{StaticResource PhoneBackgroundColor}" />
</Rectangle.Fill>
</Rectangle>
<TextBlock Text="Top rated" Style="{StaticResource PhoneTextTitle1Style}" Foreground="{StaticResource PhoneForegroundBrush}" Margin="18,-100,12,0" />
</StackPanel>
</StackPanel>
<StackPanel Name="smallImages" Margin="0,0,0,0" Orientation="Vertical">
<StackPanel Name="firstRow" Orientation="Horizontal">
<StackPanel Orientation="Vertical">
<Rectangle Height="173" Width="173" Margin="0,0,12,0" Tap="Rectangle_Tap_1">
<Rectangle.Fill>
<SolidColorBrush Color="{StaticResource PhoneAccentColor}" />
</Rectangle.Fill>
</Rectangle>
<Image Name="img_MostPopular" Tap="Rectangle_Tap_1" Height="173" Width="173" Stretch="UniformToFill" Margin="0,-173,12,0"></Image>
<Rectangle Height="50" Width="173" Margin="0,-50,12,0" Opacity="0.7" >
<Rectangle.Fill>
<SolidColorBrush Color="{StaticResource PhoneBackgroundColor}" />
</Rectangle.Fill>
</Rectangle>
<TextBlock Text="Most popular" Style="{StaticResource PhoneTextTitle3Style}" Foreground="{StaticResource PhoneForegroundBrush}" Margin="6,-50,12,0" />
</StackPanel>
<StackPanel Orientation="Vertical">
<Rectangle Height="173" Width="173" Margin="0,0,12,0" Tap="Rectangle_Tap_2">
<Rectangle.Fill>
<SolidColorBrush Color="{StaticResource PhoneAccentColor}" />
</Rectangle.Fill>
</Rectangle>
<Image Name="img_MostShared" Tap="Rectangle_Tap_2" Height="173" Width="173" Stretch="UniformToFill" Margin="0,-173,12,0"></Image>
<Rectangle Height="50" Width="173" Margin="0,-50,12,0" Opacity="0.7" >
<Rectangle.Fill>
<SolidColorBrush Color="{StaticResource PhoneBackgroundColor}" />
</Rectangle.Fill>
</Rectangle>
<TextBlock Text="Most shared" Style="{StaticResource PhoneTextTitle3Style}" Foreground="{StaticResource PhoneForegroundBrush}" Margin="6,-50,12,0" />
</StackPanel>
<StackPanel Orientation="Vertical">
<Rectangle Height="173" Width="173" Margin="0,0,12,0" Tap="Rectangle_Tap_3">
<Rectangle.Fill>
<SolidColorBrush Color="{StaticResource PhoneAccentColor}" />
</Rectangle.Fill>
</Rectangle>
<Image Name="img_TopFavorites" Tap="Rectangle_Tap_3" Height="173" Width="173" Stretch="UniformToFill" Margin="0,-173,12,0"></Image>
<Rectangle Height="50" Width="173" Margin="0,-50,12,0" Opacity="0.7" >
<Rectangle.Fill>
<SolidColorBrush Color="{StaticResource PhoneBackgroundColor}" />
</Rectangle.Fill>
</Rectangle>
<TextBlock Text="Top favorites" Style="{StaticResource PhoneTextTitle3Style}" Foreground="{StaticResource PhoneForegroundBrush}" Margin="6,-50,12,0" />
</StackPanel>
</StackPanel>
<StackPanel Name="secondRow" Orientation="Horizontal" Margin="0,12,12,0">
<StackPanel Orientation="Vertical">
<Rectangle Height="173" Width="358" Margin="0,0,12,0" Tap="Rectangle_Tap_4">
<Rectangle.Fill>
<SolidColorBrush Color="{StaticResource PhoneAccentColor}" />
</Rectangle.Fill>
</Rectangle>
<Image Name="img_RecentlyFeatured" Tap="Rectangle_Tap_4" Height="173" Width="358" Stretch="UniformToFill" Margin="0,-173,12,0"></Image>
<Rectangle Height="50" Width="358" Margin="0,-50,12,0" Opacity="0.7" >
<Rectangle.Fill>
<SolidColorBrush Color="{StaticResource PhoneBackgroundColor}" />
</Rectangle.Fill>
</Rectangle>
<TextBlock Text="Recently featured" Style="{StaticResource PhoneTextTitle3Style}" Foreground="{StaticResource PhoneForegroundBrush}" Margin="6,-50,12,0" />
</StackPanel>
<StackPanel Orientation="Vertical">
<Rectangle Height="173" Width="173" Margin="0,0,12,0" Tap="Rectangle_Tap_5">
<Rectangle.Fill>
<SolidColorBrush Color="{StaticResource PhoneAccentColor}" />
</Rectangle.Fill>
</Rectangle>
<Image Name="img_MostViewed" Tap="Rectangle_Tap_5" Height="173" Width="173" Stretch="UniformToFill" Margin="0,-173,12,0"></Image>
<Rectangle Height="50" Width="173" Margin="0,-50,12,0" Opacity="0.7" >
<Rectangle.Fill>
<SolidColorBrush Color="{StaticResource PhoneBackgroundColor}" />
</Rectangle.Fill>
</Rectangle>
<TextBlock Text="Most viewed" Style="{StaticResource PhoneTextTitle3Style}" Foreground="{StaticResource PhoneForegroundBrush}" Margin="6,-50,12,0" />
</StackPanel>
</StackPanel>
</StackPanel>
</StackPanel> <!-- main stack panel-->
</Grid>
</controls:PanoramaItem>
<!--Panorama item two-->
<!--Use 'Orientation="Horizontal"' to enable a panel that lays out horizontally-->
<controls:PanoramaItem Header="Search Video">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Width="450" Grid.Row="0">
<TextBox Name="txt_video" TextWrapping="NoWrap" Height="72" Width="300"></TextBox>
<Button Content="Search" Click="Button_Click" ></Button>
</StackPanel>
<ListBox x:Name="ListBoxSearchVideo" Height="421" Grid.Row="1" Margin="12,0,12,0" SelectionChanged="ListBoxSearchVideo_SelectionChanged" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Name="stackPanelSongs" Orientation="Horizontal" Margin="0,12,0,17" >
<Image Source="{Binding Image}" Stretch="UniformToFill" Height="100" Width="100" VerticalAlignment="Top" Margin="0,0,0,0"/>
<StackPanel Width="345" Height="90" Margin="0,0,0,0" >
<TextBlock Name="SongTitle" Text="{Binding Title}" TextWrapping="NoWrap" Margin="12,0,0,0" FontFamily="Segoe WP Semibold" FontSize="28" Foreground="#efd584" />
<TextBlock Text="{Binding Description}" TextWrapping="NoWrap" Margin="12,0,0,0" Style="{StaticResource PhoneTextSubtleStyle}" Foreground="Peru" />
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</controls:PanoramaItem>
</controls:Panorama>
</Grid>

Adding code behind

  • Initialize the events in the MainPage.xaml.cs
private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
IYouTubeEvents ITube = new YouTubeData();
ITube.OnMostPopularLoaded += new MostPopular(ITube_OnMostPopularLoaded);
ITube.OnMostSharedLoaded += new MostShared(ITube_OnMostSharedLoaded);
ITube.OnMostViewedLoaded += new MostViewed(ITube_OnMostViewedLoaded);
ITube.OnRecentlyFeaturedLoaded += new RecentlyFeatured(ITube_OnRecentlyFeaturedLoaded);
ITube.OnTopFavoritesLoaded += new TopFavorites(ITube_OnTopFavoritesLoaded);
ITube.OnTopRatedLoaded +=new TopRated(ITube_OnTopRatedLoaded);
ITube.ConnectToYouTube();
}

The ConnectToYouTube() method parse the YouTube video listing API and calls the respective event handler to display the video list on to the UI. Till here is very straight forward as these are REST APIs and returns response in XML format. To know the API used in this example please see YouTubeData.cs file.

  • Once user clicks on a particular video item we take the video id and call GetVideoUrl() method which then put a API request and gets percent encoding data as response.
  public void GetVideoUrl(string avideoId)
{
string VideoRequest = "http://www.youtube.com/get_video_info?&video_id=" + avideoId + "&el=detailpage&ps=default&eurl=&gl=US&hl=en";
// string VideoRequest = "http://www.youtube.com/get_video_info?video_id=" + avideoId;
WebClient xmlClient = new WebClient();
xmlClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(DownloadStringCompleted_GetVideoUrl);
xmlClient.DownloadStringAsync(new Uri(VideoRequest, UriKind.RelativeOrAbsolute));
}

We use HttpUtility class to decode the response and brings to a regular text base format. We search for the string &url_encoded_fmt_stream_map= in the response and take out the data from its start to end. This response has many information about the particular video including all its file type and formats. We are interested on Baseline MP4 format which has a tag itag=18. Now search for the tag itag=18 and get the respective parameters. See Wikipedia to know all supported format by YouTube and there tags. You may come across to a situation where you find two itag=18 in the response and s or sig in place of signature parameter. All you need to do is to handle these conditions to get the required parameters. In this example we have checked these scenarios in VideoUrl.cs file and called OnVideoUrlLoaded event with the final video URL which then play the video on default player in MainPage.xaml.cs file.

void IVideo_OnVideoUrlLoaded(object sender, VideoUrlArgs e)
{
string str = e.StrVideoUrl;
MediaPlayerLauncher media = new MediaPlayerLauncher();
media.Media = new Uri(str, UriKind.RelativeOrAbsolute);
media.Show();
}

The same concept is applied to YouTube video search also, where you can search a video from YouTube and play it. To keep the article in sort I haven’t put the complete source code here. Please download the source code for better understanding.

Summary

Using this example you can call other YouTube APIs and get the video played. I couldn’t find any library to parse percent encoding data, so used a very basic logic to parse it as a string component. If you find any better way of parsing percent encoding data feel free to share it with us.

Source Code

546 page views in the last 30 days.
×