Subir un video a Youtube desde .NET

La semana pasada estuve investigando sobre cómo subir videos a una cuenta de Youtube desde .NET. Básicamente lo único que necesito es un nuevo proyecto en Google Developers y el siguiente código:

using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using Google.Apis.Upload;
using Google.Apis.YouTube.v3;
using Google.Apis.YouTube.v3.Data;
using System;
using System.IO;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
namespace UploadVideoYoutube
{
    internal class Program
    {
        static void Main(string[] args)
        {
            //1. Nuget packages:
            //Install-Package Google.Apis -Version 1.8.1
            //Install-Package Google.Apis.YouTube.v3
            //Uninstall-Package Microsoft.Bcl.Async -Force
            //(Removing 'Microsoft.Bcl.Async 1.0.16' from UploadVideoYoutube)
            //Install-Package Microsoft.Bcl.Async -Version 1.0.166-beta -Pre
            try
            {
                //2. Get credentials and upload the file
                Upload().Wait();
            }
            catch (AggregateException ex)
            {
                foreach (var exception in ex.InnerExceptions)
                {
                    Console.WriteLine(exception.Message);
                }
            }
            Console.ReadLine();
        }
        private static async Task Upload()
        {
            //2.1 Get credentials
            UserCredential credentials;
            //2.1.1 Use https://console.developers.google.com/ to get the json file (Credential section)
            using (var stream = new FileStream("client_secrets.json", FileMode.Open, FileAccess.Read))
            {
                credentials = await GoogleWebAuthorizationBroker.AuthorizeAsync(
                    GoogleClientSecrets.Load(stream).Secrets,
                    new[] { YouTubeService.Scope.YoutubeUpload },
                    "user",
                    CancellationToken.None);
            }
            //2.2 Create a YoutubeService instance using our credentials
            var youtubeService = new YouTubeService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credentials,
                ApplicationName = Assembly.GetExecutingAssembly().GetName().Name
            });
            //2.3 Create a video object
            var video = new Video()
            {
                Id = "myIdVeo",
                Status = new VideoStatus
                {
                    PrivacyStatus = "private"
                },
                Snippet = new VideoSnippet
                {
                    Title = "Testing Api from .NET",
                    Description = "Testing description",
                    Tags = new string[] { "myTag1", "myTag2" }
                }
            };
            var filePath = @"[FILE_PATH]";
            //2.4 Read and insert the video in youtubeService
            using (var fileStream = new FileStream(filePath, FileMode.Open))
            {
                var videosInsertRequest = youtubeService.Videos.Insert(video, "snippet,status", fileStream, "video/*");
                videosInsertRequest.ProgressChanged += ProgressChanged;
                videosInsertRequest.ResponseReceived += ResponseReceived;
                //2.4.1 Wait for the upload process
                await videosInsertRequest.UploadAsync();
            }
        }
        static void ProgressChanged(IUploadProgress progress)
        {
            switch (progress.Status)
            {
                case UploadStatus.Starting:
                    Console.WriteLine("Start uploading");
                    break;
                case UploadStatus.Uploading:
                    Console.WriteLine("{0} bytes sent.", progress.BytesSent);
                    break;
                case UploadStatus.Completed:
                    Console.WriteLine("Upload completed!");
                    break;
                case UploadStatus.Failed:
                    Console.WriteLine("An error prevented the upload from completing.n{0}", progress.Exception);
                    break;
            }
        }
        static void ResponseReceived(Video video)
        {
            Console.WriteLine("Video '{0}' was successfully uploaded.", video.Snippet.Title);
        }
    }
}

Lo primero que necesitamos son las librerías Google.Apis y Google.Apis.YouTube.v3. En el momento que se escribió este post, existían algunas incompatibilidades con las últimas versiones y dependencias asociadas, pero es posible hacer funcionar el ejemplo con las versiones y paquetes mencionados en los comentarios. Debido a que el proceso se llama de manera asíncrona, se ha creado un método llamado Upload donde llevamos a cabo todos los pasos:

  1. Recuperamos las credenciales de la cuenta de Youtube: Una vez que hemos creado el proyecto en Google Developers seremos capaces de utilizar las APIs que Google pone a disposición del desarrollador. Es necesario comprobar que la Api YouTube Data API v3 está habilitada:
    Google Developers Apis
    Por otro lado, debemos crear un nuevo Client ID usando OAuth para poder recuperar el archivo JSON con las credenciales necesarias para la conexión:
    Create new Client ID
    La primera vez que se ejecuta el ejemplo, se abrirá una ventana del navegador pidiendo el acceso a la cuenta de Google asociada a Youtube.

    Para evitar errores es importante rellenar el apartado Consent screen del proyecto, al menos el nombre del proyecto y el email asociado
  2. Se crea una instancia de YoutubeService con las credenciales obtenidas.
  3. Creamos un objeto del tipo Video y añadimos algunas de las propiedades disponibles, como el tipo de acceso (private o public), título, descripción, tags, etcétera.
  4. Recuperamos el vídeo en local que queremos subir y lo insertamos en el listado Videos de YoutubeService. También se han asociado dos handlers a los eventos ProgressChange y ResponseReceived para ser conscientes del progreso de la operación.
  5. Subimos el fichero a través de UploadSync y esperamos la confirmación a través de la consola.

Para comprobar el resultado desde Youtube, basta con acceder a la siguiente URL: https://www.youtube.com/user/[USER_NAME]/videos

Result upload video Youtube

Espero que sea de utilidad.

¡Saludos!