Getting Started With The YouTube API in C#

Share |
by Rob 4. August 2010 10:23

I recently had to provide a code solution that retrieved a YouTube user’s favourite videos and displays them to a web page. Clicking on any one of this list of videos would then open that video in a new page ready to play. Luckily Google has set up an easy to use YouTube API for .NET we can use.

You can download the source files for this solution here.

Google Developer Key and API DLLs

Before we start there are a couple of things we need to do. To access Google’s API we need a developer key. To sign up for a developer key go to http://code.google.com/apis/youtube/dashboard and follow the instructions. Once we have out key we need to get the Google API DLL’s to reference in our solution. We can do this one of 2 ways:

  1. 1. Download and install the Google Data SDK and retrieve the DLL’s from the YouTube sample by going to http://code.google.com/p/google-gdata/downloads/list
  2. 2. Just get the DLL’s required by browsing the Bin folder of the YouTube sample here http://code.google.com/p/google-gdata/source/browse/trunk/clients/cs/samples/YouTubeSample/?r=570#YouTubeSample/Bin.

 

The DLL’s are included in the source files in my test solution so alternatively you can just download this.

The Code

I have separated the solution into 3 projects, the web application and 2 class libraries. We’ll start with our BusinessObject class library.

VideoExtracted.cs

namespace BusinessObject
{
    public class VideoExtracted
    {
        public string VideoId { get; set; }
        public string Title { get; set; }
        public string Thumbnail { get; set; }
        public string Description { get; set; }
    }
}

This is a wrapper for the video information we want returned from the YouTube API.

YouTubePlayer.cs

namespace BusinessObject
{
    /// <summary>
    /// Wrapper for all the settings for the You Tube embedded player
    /// </summary>
    public class YouTubePlayer
    {
        public YouTubePlayer()
        {
            LoadRelatedVideos = 1;
            AutoPlay = 0;
            Loop = 0;
            EnableJavaScriptAPI = 0;
            PlayerAPIId = string.Empty;
            DisableKeyboard = 0;
            EnhancedGenieMenu = 0;
            Border = 0;
            PrimaryBorderColor = "#FFFFFF";
            SecondaryBorderColor = "#FFFFFF";
            SecondsFromStart = 0;
            FullScreen = 1;
            HD = 0;
            ShowSearchBox = 0;
            ShowVideoInfo = 0;
            VideoAnnotations = 3;
        }

        /// <summary>
        /// Values: 0 or 1. Default is 1. Sets whether the player should load related videos once playback of the initial video starts. 
        /// Related videos are displayed in the "genie menu" when the menu button is pressed. 
        /// The player search functionality will be disabled if rel is set to 0.
        /// </summary>
        /// <value>0 or 1</value>
        public int LoadRelatedVideos { get; set; }

        /// <summary>
        /// Values: 0 or 1. Default is 0. Sets whether or not the initial video will autoplay when the player loads.
        /// </summary>
        /// <value>0 or 1</value>
        public int AutoPlay { get; set; }

        /// <summary>
        /// Values: 0 or 1. Default is 0. In the case of a single video player, a setting of 1 will cause the player to play the initial video again 
        /// and again. In the case of a playlist player (or custom player), the player will play the entire playlist and then start again at the first video.
        /// </summary>
        /// <value>0 or 1</value>
        public int Loop { get; set; }

        /// <summary>
        /// Values: 0 or 1. Default is 0. Setting this to 1 will enable the Javascript API. For more information on the Javascript API 
        /// and how to use it, see the JavaScript API documentation.
        /// </summary>
        /// <see cref="http://code.google.com/apis/youtube/js_api_reference.html"/>
        /// <value>0 or 1</value>
        public int EnableJavaScriptAPI { get; set; }

        /// <summary>
        /// Value can be any alphanumeric string. This setting is used in conjunction with the JavaScript API. See the JavaScript API documentation for details.
        /// </summary>
        /// <see cref="http://code.google.com/apis/youtube/js_api_reference.html"/>
        /// <value>The player API id (any alphanumeric string)</value>
        public string PlayerAPIId { get; set; }

        /// <summary>
        /// Values: 0 or 1. Default is 0. Setting to 1 will disable the player keyboard controls. Keyboard controls are as follows: 
        /// Spacebar: Play / Pause 
        /// Arrow Left: Restart current video 
        /// Arrow Right: Jump ahead 10% in the current video 
        /// Arrow Up: Volume up 
        /// Arrow Down: Volume Down
        /// </summary>
        /// <value>0 or 1</value>
        public int DisableKeyboard { get; set; }

        /// <summary>
        /// Values: 0 or 1. Default is 0. Setting to 1 enables the "Enhanced Genie Menu". This behavior causes the genie menu (if present) to appear 
        /// when the user's mouse enters the video display area, as opposed to only appearing when the menu button is pressed.
        /// </summary>
        /// <value>0 or 1</value>
        public int EnhancedGenieMenu { get; set; }

        /// <summary>
        /// Values: 0 or 1. Default is 0. Setting to 1 enables a border around the entire video player. The border's primary color can be set via 
        /// the color1 (PrimaryBorderColor) parameter, and a secondary color can be set by the color2 (SecondaryBorderColor) parameter.
        /// </summary>
        /// <value>0 or 1</value>
        public int Border { get; set; }

        /// <summary>
        /// Values: Any RGB value in hexadecimal format. This is the primary border color.
        /// </summary>
        /// <value>RGB value in hexadecimal format</value>
        public string PrimaryBorderColor { get; set; }

        /// <summary>
        /// Values: Any RGB value in hexadecimal format. This is the video control bar background color and secondary border color.
        /// </summary>
        /// <value>RGB value in hexadecimal format</value>
        public string SecondaryBorderColor { get; set; }

        /// <summary>
        /// Values: A positive integer. This parameter causes the player to begin playing the video at the given number of seconds from the start of the video. 
        /// Similar to the seekTo function, the player will look for the closest keyframe to the time you specify. 
        /// This means sometimes the play head may seek to just before the requested time, usually no more than ~2 seconds.
        /// </summary>
        /// <value>A positive integer</value>
        public int SecondsFromStart { get; set; }

        /// <summary>
        /// Values: 0 or 1. Default is 0. Setting to 1 enables the fullscreen button. This has no effect on the Chromeless Player. 
        /// Note that you must include some extra arguments to your embed code for this to work. The param allowfullscreen of the below example enable fullscreen functionality:
        /// </summary>
        /// <value>0 or 1</value>
        // <object width="425" height="344">
        // <param name="movie" value="http://www.youtube.com/v/u1zgFlCw8Aw&fs=1"</param>
        // <param name="allowFullScreen" value="true"></param>
        // <embed src="http://www.youtube.com/v/u1zgFlCw8Aw&fs=1"
        // type="application/x-shockwave-flash"
        // allowfullscreen="true"
        // width="425" height="344">
        // </embed>
        // </object>
        public int FullScreen { get; set; }

        /// <summary>
        /// Values: 0 or 1. Default is 0. Setting to 1 enables HD playback by default. This has no effect on the Chromeless Player. 
        /// This also has no effect if an HD version of the video is not available. If you enable this option, keep in mind that users with a 
        /// slower connection may have an sub-optimal experience unless they turn off HD. You should ensure your player is large enough to 
        /// display the video in its native resolution.
        /// </summary>
        /// <value>0 or 1</value>
        public int HD { get; set; }

        /// <summary>
        /// Values: 0 or 1. Default is 1. Setting to 0 disables the search box from displaying when the video is minimized. 
        /// If the rel (LoadRelatedVideos) parameter is set to 0 then the search box will also be disabled, regardless of the value of showsearch.
        /// </summary>
        /// <value>0 or 1</value>
        public int ShowSearchBox { get; set; }

        /// <summary>
        /// Values: 0 or 1. Default is 1. Setting to 0 causes the player to not display information like the video title and rating before the video starts playing.
        /// </summary>
        /// <value>0 or 1</value>
        public int ShowVideoInfo { get; set; }

        /// <summary>
        /// Values: 1 or 3. Default is 1. Setting to 1 will cause video annotations to be shown by default, whereas setting to 3 will cause video annotation to not be shown by default.
        /// </summary>
        /// <value>1 or 3</value>
        public int VideoAnnotations { get; set; }
    }
}

 

This is a wrapper for embedding our YouTube player – we’ll need this later on.

 

Now we need to create our Common class library. The Google DLLs need to be referenced in this library. I add them to the web application bin folder and reference them from there as we will also need them referenced in the web application, but you can store them wherever you wish.

GlobalConstants.cs

I always have a class with stongly-typed items for use in my solution contained in this file.

namespace Common
{
    /// <summary>
    /// Global constants for the solution
    /// </summary>
    public class GlobalConstants
    {
        #region GoogleAPI
        /// <summary>
        /// Constants required to use the Google API
        /// </summary>
        public class GoogleAPI
        {
            public const string YouTubeAccountName = "tross200sx";
            /// <summary>
            /// YouTube player width
            /// </summary>
            public const string YouTubePlayerWidth = "425";
            /// <summary>
            /// YouTube player height
            /// </summary>
            public const string YouTubePlayerHeight = "355";
            /// <summary>
            /// Google API Developer Key - your developer key
            /// </summary>
            public const string DeveloperKey = "your developer key";
            /// <summary>
            /// http://gdata.youtube.com - required for Authsub
            /// </summary>
            public const string YouTubeScope = "http://gdata.youtube.com";
            /// <summary>
            /// http://gdata.youtube.com/feeds/api/videos/ - used to get Video object
            /// </summary>
            public const string VideoEntryURL = YouTubeScope + "/feeds/api/videos/";
        }
        #endregion

        #region Links
        /// <summary>
        /// Page links
        /// </summary>
        public class Links
        {
            /// <summary>
            /// Default.aspx
            /// </summary>
            public const string Default = "/Default.aspx";
            /// <summary>
            /// ViewVideo.aspx?vid=
            /// </summary>
            public const string ViewVideo = "/ViewVideo.aspx?" + Querystring.Video + "=";
        }
        #endregion

        #region Querystring
        /// <summary>
        /// Querystring identifiers
        /// </summary>
        public class Querystring
        {
            /// <summary>
            /// vid
            /// </summary>
            public const string Video = "vid";
        }
        #endregion
    }
}

You will need to put your own developer key into this class, and you may also wish to change the YouTube account name.

GoogleAPI.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BusinessObject;
using Google.YouTube;

namespace Common
{
    public class GoogleAPI
    {
        protected IList<Video> Videos = new List<Video>();

        /// <summary>
        /// Gets a YouTube request object.
        /// </summary>
        /// <returns>YouTubeRequest</returns>
        public YouTubeRequest GetYouTubeRequestObject()
        {
            var youTubeRequestSettings = new YouTubeRequestSettings(GlobalConstants.GoogleAPI.YouTubeAccountName, string.Empty, GlobalConstants.GoogleAPI.DeveloperKey);
            return new YouTubeRequest(youTubeRequestSettings);
        }

        /// <summary>
        /// Gets favourite videos by user name.
        /// </summary>
        /// <param name="username">The username.</param>
        /// <returns>IEnumerable VideoExtracted</returns>
        public IEnumerable<Video> GetFavouriteVideosByUserName(string username)
        {
            var feed = GetYouTubeRequestObject().GetFavoriteFeed(username);
            return feed.Entries;
        }

        /// <summary>
        /// Gets the favourite videos by user name_ list.
        /// </summary>
        /// <param name="username">The username.</param>
        /// <returns></returns>
        public IList<Video> GetFavouriteVideosByUserName_List(string username)
        {
            return GetFavouriteVideosByUserName(username).ToList();
        }

        /// <summary>
        /// Gets the favourite videos extracted by user name_ list.
        /// </summary>
        /// <param name="username">The username.</param>
        /// <returns></returns>
        public IList<VideoExtracted> GetFavouriteVideosExtractedByUserName_List(string username)
        {
            return ExtractYouTubeVideoList(GetFavouriteVideosByUserName_List(username));
        }

        /// <summary>
        /// Extracts you tube video.
        /// </summary>
        /// <param name="video">The video.</param>
        /// <returns></returns>
        public VideoExtracted ExtractYouTubeVideo(Video video)
        {
            var videoExtracted = new VideoExtracted
                                     {
                                         VideoId = video.VideoId, 
                                         Title = video.Title, 
                                         Description = video.Description
                                     };

            if (video.Thumbnails.Count > 0)
                videoExtracted.Thumbnail = "<img src=\"" + video.Thumbnails[0].Url + "\" alt=\"" + videoExtracted.Title + "\" />";

            return videoExtracted;
        }

        /// <summary>
        /// Extracts you tube video list.
        /// </summary>
        /// <param name="videoList">The video list.</param>
        /// <returns></returns>
        public IList<VideoExtracted> ExtractYouTubeVideoList(IList<Video> videoList)
        {
            return videoList.Select(ExtractYouTubeVideo).ToList();
        }

        /// <summary>
        /// Gets the embedded player HTML using default settings.
        /// </summary>
        /// <param name="videoId">The video id.</param>
        /// <example>
        /// <code>
        /// div_to_hold_player.InnerHtml = googleAPI.GetEmbeddedPlayerHTML(video_id)
        /// </code>
        /// </example>
        /// <returns>html string for inserting embedded player</returns>
        public string GetEmbeddedPlayerHTML(string videoId)
        {
            return GetPlayerCode(videoId + EncodePlayerSettingsFromYouTubePlayerObjectToQueryString(new YouTubePlayer()));
        }

        /// <summary>
        /// Encodes the player settings from you tube player object to query string.
        /// </summary>
        /// <param name="player">The YouTubePlayer.</param>
        /// <returns>string (encoded querystring)</returns>
        private static string EncodePlayerSettingsFromYouTubePlayerObjectToQueryString(YouTubePlayer player)
        {
            var sb = new StringBuilder();

            sb.Append("?rel=" + player.LoadRelatedVideos);

            if (player.AutoPlay == 1) 
                sb.Append("&autoplay=" + player.AutoPlay);

            if (player.Loop == 1) 
                sb.Append("&loop=" + player.Loop);

            if (player.EnableJavaScriptAPI == 1) 
                sb.Append("&enablejsapi=" + player.EnableJavaScriptAPI);
            
            sb.Append("&playerapiid=" + player.PlayerAPIId);

            if (player.DisableKeyboard == 1) 
                sb.Append("&disablekb=" + player.DisableKeyboard);

            if (player.EnhancedGenieMenu == 1) 
                sb.Append("&egm=" + player.EnhancedGenieMenu);

            if (player.Border == 1) 
                sb.Append("&border=" + player.Border);

            if (!string.IsNullOrEmpty(player.PrimaryBorderColor)) 
                sb.Append("&color1=" + player.PrimaryBorderColor);

            if (!string.IsNullOrEmpty(player.SecondaryBorderColor)) 
                sb.Append("&color2=" + player.SecondaryBorderColor);

            if (player.SecondsFromStart > 0) 
                sb.Append("&start=" + player.SecondsFromStart);

            if (player.FullScreen == 1) 
                sb.Append("&fs=" + player.FullScreen);

            if (player.HD == 1) 
                sb.Append("&hd=" + player.HD);

            if (player.ShowSearchBox == 0) 
                sb.Append("&showsearch=" + player.ShowSearchBox);

            if (player.ShowVideoInfo == 0) 
                sb.Append("&showinfo=" + player.ShowVideoInfo);

            if (player.VideoAnnotations == 3) 
                sb.Append("&iv_load_policy=" + player.VideoAnnotations);

            return sb.ToString();
        }

        /// <summary>
        /// Gets the player code.
        /// </summary>
        /// <param name="videoURL">The video URL.</param>
        /// <returns></returns>
        private static string GetPlayerCode(string videoURL)
        {
            var sb = new StringBuilder();

            sb.Append("<object width=\"" + GlobalConstants.GoogleAPI.YouTubePlayerWidth + "\" height=\"" + GlobalConstants.GoogleAPI.YouTubePlayerHeight + "\">");
            sb.Append("<param name=\"movie\" value=\"http://www.youtube.com/v/" + videoURL + "\"></param>");
            sb.Append("<param name=\"allowFullScreen\" value=\"true\"></param>");
            sb.Append("<embed src=\"http://www.youtube.com/v/" + videoURL + "\" type=\"application/x-shockwave-flash\" width=\"" 
                + GlobalConstants.GoogleAPI.YouTubePlayerWidth + "\" height=\"" 
                + GlobalConstants.GoogleAPI.YouTubePlayerHeight + "\" allowfullscreen=\"true\"></embed>");
            sb.Append("</object>");

            return sb.ToString();
        }

        /// <summary>
        /// Gets the video using video id.
        /// </summary>
        /// <param name="videoId">The video id.</param>
        /// <returns>Video object</returns>
        public Video GetVideoUsingVideoId(string videoId)
        {
            var videoEntryUrl = new Uri(GlobalConstants.GoogleAPI.VideoEntryURL + videoId);

            try
            {
                return GetYouTubeRequestObject().Retrieve<Video>(videoEntryUrl);
            }
            catch (Exception)
            {
                return null;
            }
        }
    }
}

 

I won’t go into too much detail here as the process is really quite simple. We have to build a YouTubeRequestObject which we then use to call different methods in the YouTube API. In this case we are using the GetFavoriteFeed() and Retrieve<Google.YouTube.Video>() methods to return the data we need.

 

And now on to the web application. To display our favourite feed videos we need to create an instance of the GoogleAPI in our Page_Load section and call the GetFavouriteVideosExtractedByUserName_List() method. I will bind the returned data to a repeater to keep things simple.

Default.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="YouTube.Default" %>
<%@ Import Namespace="Common" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>YouTube test</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Repeater ID="VideoRepeater" runat="server">
            <ItemTemplate>
            <p>
                <a href="<%=GlobalConstants.Links.ViewVideo %><%#DataBinder.Eval(Container.DataItem, "VideoId")%>">
                    <%#DataBinder.Eval(Container.DataItem, "Thumbnail")%>
                </a>
                <br />
                <a href="<%=GlobalConstants.Links.ViewVideo %><%#DataBinder.Eval(Container.DataItem, "VideoId")%>">
                    <%#DataBinder.Eval(Container.DataItem, "Title")%>
                </a>
            </p>
            </ItemTemplate>
        </asp:Repeater>
    </div>
    </form>
</body>
</html>

I’m binding the title and YouTube thumbnail for display and wrapping both in anchor tags. these anchors point to our YouTube player page with the VideoId of the YouTube video in the querystring.

Default.aspx.cs

using System;
using System.Web.UI;
using Common;

namespace YouTube
{
    public partial class Default : Page
    {
        /// <summary>
        /// Handles the Load event of the Page control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected void Page_Load(object sender, EventArgs e)
        {
            var googleAPI = new GoogleAPI();

            VideoRepeater.DataSource = googleAPI.GetFavouriteVideosExtractedByUserName_List(GlobalConstants.GoogleAPI.YouTubeAccountName);
            VideoRepeater.DataBind();
        }
    }
}

Now we have our video list from our favourite feed displaying nicely, it’s time to create a page to play the videos. To do this I pass the video id of the YouTube video in the querystring and use this to get the video from a YouTube API call to get the video information (title, description, etc.)

To display the player on the page we need to use the standard object and embed HTML tags. This HTML is set up in the GetPlayerCode() method in the GoogleAPI.cs class.

We have lots of options when displaying a video, all of which are covered in our YouTubePlayer class in the BusinessObject class library. Any options we want to include are added on tot he querysting of the video url we use in our embed HTML statement. Have a run through the code and it should all make sense. Leaving the settings as they are is fine – the video will work as you would expect – but it’s useful to have the wrapper available should you want to change any of the settings.

ViewVideo.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ViewVideo.aspx.cs" Inherits="YouTube.ViewVideo" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>YouTube Player Test</title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <h2><asp:Literal ID="VideoTitle" runat="server"></asp:Literal></h2><br />
        
            <p><asp:Literal ID="VideoDescription" runat="server"></asp:Literal></p>

            <div id="thevideo" runat="server"></div>
        </div>
    </form>
</body>
</html>

 

A very simple page that has 2 literals for the YouTube video title and description, and a div into which we will inject our embed HTML statement.

ViewVideo.aspx.cs

using System;
using System.Web.UI;
using Common;

namespace YouTube
{
    public partial class ViewVideo : Page
    {
        /// <summary>
        /// Handles the Load event of the Page control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected void Page_Load(object sender, EventArgs e)
        {
            var googleAPI = new GoogleAPI();

            var vidId = Request.QueryString[GlobalConstants.Querystring.Video];

            thevideo.InnerHtml = googleAPI.GetEmbeddedPlayerHTML(vidId);

            var youTubeVideo = googleAPI.GetVideoUsingVideoId(vidId);

            VideoTitle.Text = youTubeVideo.Title;
            VideoDescription.Text = ReplaceLineBreakWithBR(youTubeVideo.Description);
        }

        /// <summary>
        /// Replaces the line break with BR.
        /// </summary>
        /// <param name="s">The s.</param>
        /// <returns></returns>
        public static string ReplaceLineBreakWithBR(string s)
        {
            return s.Replace("\r\n", "<br />").Replace("\n", "<br />");
        }
    }
}

 

I have added a ReplaceLineBreakWithBR() method here to make any line breaks HTML breaks as the YouTube video description uses newline characters and these won’t display on our page.

Conclusion

That’s all there is to it. There are loads more methods the Google API allows but hopefully if you’re just getting started this will ease your way in to the process!

Share |

Contact   |   Archive   |   Log in

Powered by BlogEngine.NET 1.6.1.0