[Windows 10] HTTP Live Streaming

Film Role-02Introducción

En el desarrollo de nuestras Apps hay ciertos contenidos que los usuarios aprecian especialmente. Entre el contenido destacado contamos con el multimedia.

HTTP Live Streaming o HLS es un protocolo de streaming de contenido multimedia que consiste en segmentar en diferentes archivos pequeños, cada uno de ellos en diferentes tamaños y calidades para permitir difundir el contenido con una tasa adaptativa dependiendo de la calidad de la conexión.

HTTP Live Streaming

Hasta ahora podíamos implementar HLS en nuestras Apps utilizando componentes de terceros como por ejemplo Windows Phone Streaming Media o Player Framework.

Con la llegada de Windows 10 contamos con lo necesario para trabajar con contenido multimedia adaptativo gracias a la clase AdaptiveMediaSource.

Crearemos un nuevo proyecto UAP:

Nueva App UAP

Nueva App UAP

Añadimos las carpetas Views, ViewModels y Services además de las clases base necesarias para implementar el patrón MVVM de la misma forma que vimos en este artículo.

Nuestro objetivo en este ejemplo será analizar todo lo necesario para realizar streaming adaptativo de contenido multimedia utilizando las nuevas APIs disponibles en Windows 10.

Comenzamos diseñando nuestra interfaz. El reproductor será un control de tipo MediaElement:

<MediaElement />

Control que soporta reproducción de audio y video ante múltiples formatos. Añadiremos también un botón para lanzar la reproducción:

<Button
     Grid.Row="1"
     HorizontalAlignment="Center"
     Content="Play"/>

El resultado:

Nuestra interfaz

Nuestra interfaz

Al pulsar el botón lanzaremos un comando en la ViewModel:

private ICommand _playCommand;

public ICommand PlayCommand
{
     get { return _playCommand = _playCommand ?? new DelegateCommandAsync(PlayCommandExecute); }
}

private async Task PlayCommandExecute()
{

}

Quedando la definición del botón de la siguiente forma:

<Button
     Grid.Row="1"
     HorizontalAlignment="Center"
     Content="Play"
     Command="{Binding PlayCommand}"/>

El comando se encargará de acceder a contenido multimedia adapatativo:

var hlsUri = new Uri(HlsUrl);
var hlsSource = await AdaptiveMediaSource.CreateFromUriAsync(hlsUri);

La clase AdaptiveMediaSource nos permite trabajar con una fuente de streaming adaptativo. Utilizamos CreateFromUriAsync, método asíncrono que nos permite crear una instancia de AdaptiveMediaSource desde una Uri, es decir, trabajando directamente con una Url.

NOTA: Tenemos la posibilidad de obtener la instancia de AdaptiveMediaSource trabajando con Streams utilizando el método CreateFromStreamAsync.

El resultado obtenido es una instancia de la clase AdaptiveMediaSourceCreationResult que contiene información imprescindible relacionada con el estado, conexión y contenido de la fuente de streaming adaptativo:

  • HttpResponseMessage: Contiene la respuesta de la petición Http realizada para acceder al contenido multimedia. Útil para obtener información sobretodo en caso de errores.
  • MediaSource: Instancia de la clase AdaptiveMediaSource  que representa el contenido multimedia.
  • Status: Valor contemplado en enumeración que nos indica el estado de la creación de  MediaSource.

Crearemos una propiedad pública para enlazar contenido obtenido:

private AdaptiveMediaSource _mediaSource;  

public AdaptiveMediaSource MediaSource
{
     get { return _mediaSource; }
     set
     {
          _mediaSource = value;
          RaisePropertyChanged();
     }
}

Siempre antes, utilizaremos la propiedad Status para verificar que todo ha ido sin problemas:

if (hlsSource.Status == AdaptiveMediaSourceCreationStatus.Success)
{
     MediaSource = hlsSource.MediaSource;
}

Llegados a este punto, solo tenemos que asignar el contenido obtenido de la fuente de streaming multimedia adapatativo a nuestro control MediaElement.

Creando un Behavior

A pesar de tener una propiedad Source, la asignación de AdaptiveMediaSource al MediaElement se realiza utilizando el método SetMediaStreamSource del MediaElement, ¿cómo podemos enlazarlo directamente?

Crearemos un Behavior para ello. Añadiremos la referencia a Extensions SDK:

Behaviors SDK

Behaviors SDK

En nuestro proyecto, dentro de la carpeta Behaviors, crearemos una nueva clase que heredará de IBehavior:

public class MediaStreamSourceBehavior : DependencyObject, IBehavior
{
     public void Attach(DependencyObject associatedObject)
     {
         var control = associatedObject as MediaElement;
         if (control == null)
             throw new ArgumentException(
                 "MediaStreamSourceBehavior can be attached only to MediaElement.");

         AssociatedObject = associatedObject;
     }

     public void Detach()
     {
         AssociatedObject = null;
     }
}

Realizamos la implementación de la interfaz IBehavior asociando el Behavior al elemento MediaElement. A continuación, crearemos una nueva propiedad de dependencia de tipo AdaptiveMediaSource a la que bindearemos la propiedad MediaSource que creamos previamente en nuestra ViewModel:

public AdaptiveMediaSource Media
{
     get { return (AdaptiveMediaSource)GetValue(MediaProperty); }
     set { SetValue(MediaProperty, value); }
}

public static readonly DependencyProperty MediaProperty =
            DependencyProperty.Register("Media",
            typeof(AdaptiveMediaSource),
            typeof(MediaStreamSourceBehavior),
            new PropertyMetadata(null, OnMediaChanged));

private static void OnMediaChanged(object sender,
DependencyPropertyChangedEventArgs e)
{
     var behavior = sender as MediaStreamSourceBehavior;
     if (behavior.AssociatedObject == null || e.NewValue == null) return;

     var mediaElement = behavior.AssociatedObject as MediaElement;
     if (mediaElement != null)
          mediaElement.SetMediaStreamSource((AdaptiveMediaSource)e.NewValue);
}

Al asignar el valor de la propiedad de depencia creada, utilizaremos el método SetMediaStreamSource del control MediaElement para asignar la fuente.

Solo nos queda utilizar el Behavior en nuestra interfaz de usuario. Añadimos los namespaces necesarios:

xmlns:i="using:Microsoft.Xaml.Interactivity"
xmlns:behaviors="using:HlsPlayer.Behaviors"

Utilizamos el Behavior con nuestro control MediaElement bindeando la fuente de streaming:

<MediaElement
     AutoPlay="True">
     <i:Interaction.Behaviors>
           <behaviors:MediaStreamSourceBehavior
                Media="{Binding MediaSource}"/>
     </i:Interaction.Behaviors>
</MediaElement>

Al ejecutar la Aplicación y pulsar el botón Play:

HTTP Live Streaming (HLS) en WIndows 10

HTTP Live Streaming (HLS) en WIndows 10

Comienza la reproducción del streaming adaptativo de contenido multimedia.

Podéis descargar el ejemplo realizado a continuación:

También podéis acceder al código fuente directamente en GitHub:

Ver GitHub

Recordar que cualquier tipo de duda o sugerencia la podéis dejar en los comentarios de la entrada.

Más información

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s