Subir contenido a Microsoft Azure Media Services usando .NET

El primer paso cuando trabajamos con Microsoft Azure Media Services es la ingesta. Como se explicó en la introdución a este servicio, desde el propio portal podemos subir contenido con un tamaño máximo de 200MB o bien copiar archivos existentes en una cuenta de Azure Storage. En este post me gustaría enseñaros cómo es posible realizar la subida a través del SDK de Azure Media Services.

Para este ejemplo, he creado una aplicación de consola y he instalado el SDK a través de Nuget:

PM> Install-Package windowsazure.mediaservices

En el método principal, he enumerado el proceso que debemos seguir para subir todo el contenido que esté incluido en una carpeta:

        static void Main(string[] args)
        {
            Debug("Upload assets to Azure Media Services");
            #region Constants
            const string folderPath = @"H:wow_trailers";
            const string accountName = "YOUR_ACCOUNT_NAME";
            const string accountKey = "YOUR_ACCOUNT_KEY";
            const string assetName = "WoW_Asset";
            #endregion
            //1. Nuget: Install-Package windowsazure.mediaservices
            //2.Connect to the media account
            CloudMediaContext _context = new CloudMediaContext(accountName, accountKey);
            //3.Create asset
            var asset = _context.Assets.Create(assetName, AssetCreationOptions.None);
            Debug(string.Format("Asset name: {0}", asset.Name));
            //4. Access policy
            var accessPolicy = _context.AccessPolicies.Create(asset.Name, TimeSpan.FromDays(10), AccessPermissions.Write | AccessPermissions.List);
            Debug(string.Format("Access policy - Duration: {0}", accessPolicy.Duration));
            //5. Locator
            var locator = _context.Locators.CreateLocator(LocatorType.Sas, asset, accessPolicy);            
            //6. BlobTransferClient
            var blobTransferClient = new BlobTransferClient
            {
                NumberOfConcurrentTransfers = 20,
                ParallelTransferThreadCount = 20
            };
            //7. TransferProgressChanged
            blobTransferClient.TransferProgressChanged += TransferProgressChanged;
            //8.Get files
            var files = Directory.EnumerateFiles(folderPath);
            //9. Preparing upload tasks
            var uploadTasks = new List<Task>();
            foreach (var file in files)
            {
                var assetFile = asset.AssetFiles.Create(Path.GetFileName(file));
                Debug(string.Format("Created asset for the file {0}", assetFile.Name));
                uploadTasks.Add(assetFile.UploadAsync(file, blobTransferClient, locator, CancellationToken.None));
            }
            //10. Wait
            Task.WaitAll(uploadTasks.ToArray());
            Debug("Done!", MessageType.Result);
            Console.ReadLine();
        }
  1. Una región con los datos necesarios para la subida (ubicación de los archivos, nombre de la cuenta, clave, nombre del asset).
  2. Instalamos el SDK a través de Nuget.
  3. Conectamos la aplicación con la cuenta de Azure Media Services que vamos a utilizar.
  4. Creamos el asset, que será el contenedor donde se almacenarán los archivos. Hablaremos de ello un poco más tarde.
  5. Definimos la política de acceso. En este caso, hemos decidido que el acceso a este contenido sólo estará disponible durante 10 días para la escritura y listado del contenido.
  6. Creamos un locator, el cual nos proporciona un punto de entrada a los archivos contenidos en el asset.
  7. Instanciamos un objeto del tipo BlobTransferClient, que será utilizado para la subida del contenido.
  8. Al objeto anterior, le asociamos un handler que nos aportará información sobre el estado de la subida.
  9. Recuperamos todos los archivos ubicados en la carpeta seleccionada.
  10. Creamos un listado de tareas y damos de alta una tarea por cada archivo, recorriendo el listado de los mismos en el foreach y creando un AssetFile por cada uno de ellos y la subida a través de UploadAsyn
  11. Una vez que ya tenemos todas las tareas que queremos ejecutar, utilizamos Wait.All pasándole la lista.

El código que se utiliza para el handler TransferProgressChanged es simplemente una trazas que nos avisa del porcentaje completado:

        static void TransferProgressChanged(object sender, BlobTransferProgressChangedEventArgs e)
        {
            Debug(string.Format("{0}% upload completed for {1}", e.ProgressPercentage, e.LocalFile), MessageType.Progress);
        }

Por otro lado, se ha creado un método llamado Debug donde lo único que hago es cambiar el color del texto mostrado por consola en función de un enumerable, que me indica si es Info, Progress o Result:

        static void Debug(string message, MessageType type = MessageType.Info)
        {
            switch (type)
            {
                case MessageType.Info:
                    Console.ForegroundColor = ConsoleColor.DarkGreen;
                    break;
                case MessageType.Progress:
                    Console.ForegroundColor = ConsoleColor.DarkYellow;
                    break;
                case MessageType.Result:
                    Console.ForegroundColor = ConsoleColor.DarkMagenta;
                    break;
                default:
                    break;
            }
            Console.WriteLine();
            Console.WriteLine(message);
        }

Cuando el proceso se haya completado podremos ver el resultado en el apartado CONTENT del portal:

Upload assets content portal

Desde aquí, no podemos comprobar cuántos archivos están incluídos dentro del asset y, además, si publicamos el contenido a través del botón PUBLISH sólamente nos devolverá una de las URLs disponibles. Sin embargo, si accedemos a la cuenta de Microsoft Azure Storage asociada, podemos comprobar que el asset se corresponde un con container y podemos listar el contenido a través del portal:

assets Storage containers

El nombre del container está compuesto por la palabra asset + el id del locator. Si accedemos a cualquiera de ellos, podremos ver los archivos que contiene un asset en concreto:

assetfiles

Un dato que debemos de tener en cuenta es que si tenemos varios archivos dentro de un asset no nos será posible utilizar la acción encode del portal sobre el mismo. Además, como comentaba, cuando hacemos uso de la acción publicar un asset que contiene varios archivos sólo se nos mostrará la URL de uno de ellos. Sin embargo, podemos construir el resto de URLs cambiando el nombre del archivo, como por ejemplo se ve en la siguiente URL:

https://gismedia.blob.core.windows.net/asset-9eaa68f6-adcf-4c57-800c-10c7e8cb04a3/Mists_of_Pandaria.mp4?sv=2012-02-12&sr=c&si=851c919d-0c13-4228-9e5b-1b8ca95fab72&sig=AOOUXluaeRmRkm%2F1Z9DOwh1Qcry4AJWTFZtkd%2Bf%2F8f8%3D&st=2014-08-13T07%3A38%3A07Z&se=2016-08-12T07%3A38%3A07Z

Para poder reproducir el archivo llamado Burning_Crusade.mp4 bastaría con modificar el nombre del archivo en la URL anterior:

https://gismedia.blob.core.windows.net/asset-9eaa68f6-adcf-4c57-800c-10c7e8cb04a3/Burning_Crusade.mp4?sv=2012-02-12&sr=c&si=851c919d-0c13-4228-9e5b-1b8ca95fab72&sig=AOOUXluaeRmRkm%2F1Z9DOwh1Qcry4AJWTFZtkd%2Bf%2F8f8%3D&st=2014-08-13T07%3A38%3A07Z&se=2016-08-12T07%3A38%3A07Z

Espero que sea de utilidad.

Happy clouding!