Crear miniaturas (thumbnails) de un asset de Microsoft Azure Media Services

Cuando trabajamos con media una característica muy importante con la que debemos contar es la creación de miniaturas o thumbnails. Gracias a estas capturas de puntos concretos del video seremos capaces de reconocer el contenido de una forma más rápida y elegante. Dentro de Microsoft Azure Media Services podemos crear estas imagenes a través del procesador Windows Azure Media Encoder, utilizado también para el encoding de archivos:

using Microsoft.WindowsAzure.MediaServices.Client;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Thumbnails
{
    class Program
    {
        static void Main(string[] args)
        {
            //0. Constants
            const string AssetName = "Frozen-mp4-Source";
            const string AccountName = "[ACCOUNT_NAME]";
            const string AccountKey = "[ACCOUNT_KEY]";

            //1. Nuget: Install-Package windowsazure.mediaservices
            //2. Nuget: Install-Package windowsazure.mediaservices.extensions

            //3. Create context
            var _context = new CloudMediaContext(AccountName, AccountKey);

            //4. Get asset
            var asset = (from a in _context.Assets
                         where a.Name == AssetName
                         select a).FirstOrDefault();

            //5. Get thumbnail configuration from a XML file
            var ThumbnailConfig = File.ReadAllText("Thumbnail_Configuration.xml");

            //6. Get the processor
            var processor = _context.MediaProcessors.GetLatestMediaProcessorByName(MediaProcessorNames.WindowsAzureMediaEncoder);

            //7. Create a job
            var job = _context.Jobs.Create("Thumbnail job");

            //8. Create a task
            ITask task = job.Tasks.AddNew("Thumbnail task",
                processor,
                //MediaEncoderTaskPresetStrings.Thumbnails,
                ThumbnailConfig,
                TaskOptions.None);

            //9. Add the input asset
            task.InputAssets.Add(asset);

            //10. Define the output asset name
            task.OutputAssets.AddNew(string.Format("{0} Thumbnails", AssetName), AssetCreationOptions.None);

            //11. Wait for the result
            job.Submit();

            var jobTask = job.GetExecutionProgressTask(CancellationToken.None);
            jobTask.Wait();

            //12. Get the primary jpge file
            var output = job.OutputMediaAssets[0];

            //13. Create an access policy
            var accessPolicy = _context.AccessPolicies.Create("Read Policy", TimeSpan.FromDays(10), AccessPermissions.Read);

            //14. Create a locator
            var locator = _context.Locators.CreateSasLocator(output, accessPolicy);

            //15. Select the primary file
            var primaryFile = (from a in output.AssetFiles
                               where a.IsPrimary == true
                               select a).FirstOrDefault();

            //16. Build a URL
            Console.WriteLine("Thumbnail locator:n{0}/{1}{2}n", locator.BaseUri, primaryFile.Name, locator.ContentAccessComponent);
            Console.ReadLine();

        }
    }
}
  1. Como constantes necesitamos el nombre del asset y las credenciales de la cuenta.
  2. Instalamos windowsazure.mediaservices via Nuget.
  3. En este ejemplo hacemos uso también de Windows Azure Media Services .NET SDK Extensions.
  4. Creamos el contexto para acceder a nuestra cuenta.
  5. Recuperamos el asset del cual queremos generar las miniaturas.
  6. Existen dos formas de configurar las miniaturas: utilizando el preset por defecto (queda comentado en el código anterior como MediaEncoderTaskPresetStrings.Thumbnails en la creación de la tarea) o bien haciendo uso del siguiente XML con los valores personalizados:
    <?xml version="1.0" encoding="utf-8"?>
    <Thumbnail Size="30%,*" Type="Jpeg" Filename="{OriginalFilename}_{ThumbnailIndex}.{DefaultExtension}">
      <Time Value="0:3:19"/>
    </Thumbnail>

    Utilizamos el atributo Size para indicar el ancho de la imagen y un asterisco para que mantenga el aspect ratio. También podemos elegir el formato de la imagen a través del atributo Type e incluso utilizar un patrón para el nombre del archivo a través de Filename. Por último, hacemos uso del elemento Time donde podemos elegir el punto del vídeo de donde queremos tomar la imagen, en este ejemplo en el minuto 3 segundo 19. También es posible generar más de una captura utilizando Value, Step, Stop si quisiéramos varias muestras. Podéis encontrar más información acerca de la configuración en el siguiente enlace.

  7. Recuperamos el procesador Windows Azure Media Encoder
  8. Creamos el job.
  9. Creamos la tarea pasándole el procesador, la configuración del XML y el tipo de tarea.
  10. Añadimos el asset del vídeo dentro de InputAssets.
  11. Creamos un asset de salida que contendrá el resultado, en este caso la miniatura.
  12. Lanzamos el job y esperamos a que finalice.
  13. Recuperamos el asset que tiene el resultado a través de job.OutputMediaAssets[0].
  14. Creamos una política de acceso de sólo lectura.
  15. Generamos un locator de tipo Sas para el asset. Si quieres saber más sobre publicación puedes echar un vistazo al post Publicar assets desde Windows Azure Media Services .NET SDK.
  16. Si hemos generado varias miniaturas de un vídeo, una de ellas debe ser la principal. Para seleccionarla podemos utilizar la propiedad IsPrimary.
  17. Por último, construimos la URL para acceder a la imagen.

Si lanzamos la aplicación, el resultado será parecido al siguiente:

Console locator thumbnail

Copiamos la URL resultante en el navegador para comprobar que la miniatura se ha generado correctamente:

Frozen thumbnail

Espero que sea de utilidad.

¡Saludos!