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:

Michael Nabil

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 ??

March 15, 2017 at 3:44 AM

Matt Pavey

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

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

March 15, 2017 at 3:56 PM

ANTI MORRE NOIS VEVI

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.

April 11, 2018 at 9:49 AM

Matt Pavey

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!

April 11, 2018 at 10:46 AM

ANTI MORRE NOIS VEVI

Thanks, I'll try.

Thanks!

April 11, 2018 at 10:49 AM