Wednesday, April 13, 2016

ASP.Net C# Retrieving a list of videos from a YouTube playlist

Recently when working on my favorites page, as I was typing up my favorite songs and linking them to YouTube, I thought it would be pretty nice to just tap in to my "Favorites" list directly in YouTube. A quick Google search lead me to this Stack Overflow article:

http://stackoverflow.com/questions/34143202/get-all-videos-from-channel-youtube-api-v3-c-sharp

So building off of a couple of the answers in this article, I've put together a functional example using C# to show how to connect to the YouTube Data API.

For this example we'll be using the following NuGet package:

Google.Apis.YouTube.v3 Client Library

If you need to generate your own YouTube Data API key, you can visit the Google Developer Console and use the API Manager.

ASPX Page
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="default.aspx.cs" Inherits="Web.youtube._default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <!-- title -->
    <title>YouTube Demo</title>
 
    <!-- bootstrap -->
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" />
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>

    <!-- styles -->
    <style>
        body { margin: 25px !important; }
        .video { margin-top: 25px; }
        .video .title { font-weight: normal; white-space: nowrap; overflow: hidden; }
        .video .thumbnail img { width: 192px; height: 144px; }
    </style>
</head>

<body>
    <form id="form1" runat="server">
        <div class="container">
            <div class="col-lg-12">
                <h1>YouTube Demo</h1>
            </div>
            
            <!-- placeholder where we will render the results -->
            <asp:PlaceHolder ID="pnlVideos" runat="server" />

            <div class="col-lg-12" style="padding-top: 10px">
                <asp:Label ID="lblMessage" Font-Bold="true" ForeColor="Red" ClientIDMode="Static" runat="server" />
            </div>
        </div>

        <!-- template to help build each video container -->
        <asp:Literal ID="lblTemplate" Visible="false" runat="server">
            <div class="video col-lg-4">
                <div class="title">
                    <a href="{Url}" target="_blank">
                        {Title}
                    </a>
                </div>

                <div class="thumbnail">
                    <a title="{ToolTip}" href="{Url}" target="_blank">
                        <img title="{ToolTip}" src="{Image}" alt="" />
                    </a>
                </div>
            </div>
        </asp:Literal>
    </form>
</body>
</html>

Code-Behind
using Google.Apis.Services;
using Google.Apis.YouTube.v3;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace Web.youtube
{
    public partial class _default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            try
            {
                // initialize call to the youtube service
                var YouTubeService = new YouTubeService(new BaseClientService.Initializer() { ApiKey = "YourApiKey" });

                // indicate the parts we need for the request
                var ChannelListRequest = YouTubeService.Channels.List("contentDetails");

                // indicate the username for the channel you are requesting
                ChannelListRequest.ForUsername = "UserNameOfChannelYouAreRequesting";
                
                // execute the request and get the response
                var ListResponse = ChannelListRequest.Execute();

                // iterate through the results
                foreach (var channel in ListResponse.Items)
                {
                    // indicate the list you are requesting
                    // if your favorites list is unlisted you will need to explicitly set this value
                    // var ListId = channel.ContentDetails.RelatedPlaylists.Favorites;
                    var ListId = "YouTubeListId";

                    // the page token will be used if the results span multiple pages
                    var PageToken = "";

                    // iterate until there is no more data
                    while (PageToken != null)
                    {
                        // indicate the parts we need for the request
                        var PlaylistRequest = YouTubeService.PlaylistItems.List("snippet");

                        // playlist request properties
                        PlaylistRequest.PlaylistId = ListId;
                        PlaylistRequest.MaxResults = 50;
                        PlaylistRequest.PageToken = PageToken;

                        // execute the request and get the response
                        var PlaylistResponse = PlaylistRequest.Execute();

                        // iterate through the results
                        foreach (var Video in PlaylistResponse.Items)
                        {
                            // variables
                            string Template = lblTemplate.Text;
                            string VideoId = Video.Snippet.ResourceId.VideoId;
                            string Title = Video.Snippet.Title;
                            string Url = string.Format("https://www.youtube.com/watch?v={0}", VideoId);
                            string Image = Video.Snippet.Thumbnails.High.Url;

                            // replace placeholders
                            Template = Template.Replace("{VideoId}", VideoId);
                            Template = Template.Replace("{Title}", Title);
                            Template = Template.Replace("{Url}", Url);
                            Template = Template.Replace("{Image}", Image);
                            Template = Template.Replace("{ToolTip}", HttpUtility.HtmlEncode(Title));

                            // add to videos panel
                            pnlVideos.Controls.Add(new LiteralControl(Template));
                        }

                        // get the next page token
                        PageToken = PlaylistResponse.NextPageToken;
                    }
                }
            }
            catch (Exception ex)
            {
                lblMessage.Text = ex.Message;
            }
        }
    }
}

Click here to see a fully functional demo.

Matt Pavey is a Microsoft Certified software developer who specializes in ASP.Net, VB.Net, C#, AJAX, LINQ, XML, XSL, Web Services, SQL, jQuery, and more. Follow on Twitter @matthewpavey

5 comments:

  1. Thanks for the useful example, it was really useful for me
    is there a way that I can "code listen" when the video ended playing ??

    ReplyDelete
  2. Yes, you can definitely do that using the YouTube player API. Take a look at this StackOverflow article:

    http://stackoverflow.com/a/11726088/7009060

    ReplyDelete
  3. Hi. Thanks for the example, but a question. Locally testing the application runs normally, but when publishing always occurs error.
    I already researched the possible reason for the error and could not come up with any solution.
    http://modelo07.websafebusiness.com.br/testes.aspx This is the link from where is the page that I use Google.Apis.YouTube. I removed the try to appear all the error. If you can help me, thank you.

    ReplyDelete
    Replies
    1. Hi, it looks like this code only works for playlists that are set to "Public" or "Unlisted", but will not work for "Private" playlists. When I set my playlist to "Public" on YouTube, and wait a few minutes, then the code works again.

      http://pavey.azurewebsites.net/youtube/

      I think if you use OAuth authentication you might be able to get the videos from a private list, but I do not have a working example of that one, although it looks like there are several examples on the YouTube API developer page and Stackoverflow.

      Thanks!

      Delete