Compartir a través de


Crear, programar y administrar interrupciones multimedia

En este artículo se muestra cómo crear, programar y administrar las interrupciones multimedia en tu aplicación de reproducción de contenido multimedia. Las interrupciones multimedia se suelen usar para insertar anuncios de audio o vídeo en el contenido multimedia. A partir de Windows 10, versión 1607, puedes usar la clase MediaBreakManager para agregar interrupciones multimedia a cualquier elemento MediaPlaybackItem que reproduzcas con MediaPlayer de forma rápida y fácil.

Después de programar una o más interrupciones multimedia, el sistema reproducirá automáticamente tu contenido multimedia en el momento especificado durante la reproducción. MediaBreakManager proporciona eventos para que la aplicación pueda reaccionar cuando se inicien las interrupciones multimedia, cuando finalicen o cuando el usuario las omita. También puedes acceder a una MediaPlaybackSession para que tus interrupciones multimedia supervisen eventos como la descarga y el almacenamiento en búfer de actualizaciones de progreso.

Programar interrupciones multimedia

Cada objeto MediaPlaybackItem tiene su propio MediaBreakSchedule que usas para configurar las interrupciones multimedia que se reproducirán cuando lo haga el elemento. El primer paso para usar interrupciones multimedia en tu aplicación es crear un elemento MediaPlaybackItem para el contenido de reproducción principal.

MediaPlaybackItem moviePlaybackItem =
    new MediaPlaybackItem(MediaSource.CreateFromUri(new Uri("http://www.fabrikam.com/movie.mkv")));

Para obtener más información sobre cómo trabajar con MediaPlaybackItem, MediaPlaybackList y otras API de reproducción multimedia fundamentales, consulta Elementos multimedia, listas de reproducción y pistas.

El siguiente ejemplo muestra cómo agregar una interrupción de preprocesamiento a MediaPlaybackItem, lo que significa que el sistema reproducirá la interrupción multimedia antes de reproducir el elemento de reproducción al que pertenece la interrupción. Primero se crea una instancia de un nuevo objeto MediaBreak. En este ejemplo, se llama al constructor con MediaBreakInsertionMethod.Interrupt, lo que significa que el contenido principal se pondrá en pausa mientras se reproduce el contenido de la interrupción.

Luego, se crea un nuevo MediaPlaybackItem para el contenido que se reproducirá durante la interrupción, por ejemplo, un anuncio. La propiedad CanSkip de este elemento de reproducción se establece en false. Esto significa que el usuario no podrá omitir el elemento mediante los controles multimedia integrados. La aplicación todavía puede optar por omitir la adición mediante programación llamando a SkipCurrentBreak.

La propiedad PlaybackList de la interrupción multimedia es un elemento MediaPlaybackList que te permite reproducir varios elementos multimedia como una lista de reproducción. Agrega uno o más objetos MediaPlaybackItem de la colección de elementos de la lista para incluirlos en la lista de reproducción de la interrupción multimedia.

Por último, programa la interrupción multimedia mediante la propiedad BreakSchedule del elemento de reproducción de contenido principal. Especifica que la interrupción sea una interrupción de preprocesamiento asignándola a la propiedad PrerollBreak del objeto de programación.

MediaBreak preRollMediaBreak = new MediaBreak(MediaBreakInsertionMethod.Interrupt);
MediaPlaybackItem prerollAd = 
    new MediaPlaybackItem(MediaSource.CreateFromUri(new Uri("http://www.fabrikam.com/preroll_ad.mp4")));
prerollAd.CanSkip = false;
preRollMediaBreak.PlaybackList.Items.Add(prerollAd);

moviePlaybackItem.BreakSchedule.PrerollBreak = preRollMediaBreak;

Ahora puedes reproducir el elemento multimedia principal y se reproducirá la interrupción multimedia que creaste antes del contenido principal. Crea un nuevo objeto MediaPlayer y, opcionalmente, establece la propiedad AutoPlay en true para iniciar automáticamente la reproducción. Establece la propiedad Source de MediaPlayer en tu elemento de reproducción de contenido principal. No es necesario, pero puedes asignar MediaPlayer en un elemento MediaPlayerElement para representar el contenido multimedia en una página XAML. Para obtener más información sobre cómo usar MediaPlayer, consulta Reproducir audio y vídeo con MediaPlayer.

_mediaPlayer = new MediaPlayer();
_mediaPlayer.AutoPlay = true;
_mediaPlayer.Source = moviePlaybackItem;
mediaPlayerElement.SetMediaPlayer(_mediaPlayer);

Agrega una interrupción de postprocesamiento que se reproduce después de que el elemento MediaPlaybackItem que contiene el contenido principal finalice su reproducción, usando la misma técnica de la interrupción de preprocesamiento, salvo que asignes tu objeto MediaBreak a la propiedad PostrollBreak.

MediaBreak postrollMediaBreak = new MediaBreak(MediaBreakInsertionMethod.Interrupt);
MediaPlaybackItem postRollAd =
    new MediaPlaybackItem(MediaSource.CreateFromUri(new Uri("http://www.fabrikam.com/postroll_ad.mp4")));
postrollMediaBreak.PlaybackList.Items.Add(postRollAd);

moviePlaybackItem.BreakSchedule.PostrollBreak = postrollMediaBreak;

También puedes programar una o más interrupciones intermedias que se reproducen en un momento determinado dentro de la reproducción del contenido principal. En el siguiente ejemplo, MediaBreak se crea con la sobrecarga del constructor que acepta un objeto TimeSpan , que especifica el momento en la reproducción del elemento multimedia principal en el que se reproducirá la interrupción. De nuevo, MediaBreakInsertionMethod.Interrupt se especifica para indicar que la reproducción del contenido principal se pondrá en pausa mientras se reproduce la interrupción. La interrupción intermedia se agrega a la programación llamando a InsertMidrollBreak. Puedes obtener una lista de solo lectura de las interrupciones intermedias actuales en la programación accediendo a la propiedad MidrollBreaks.

MediaBreak midrollMediaBreak = new MediaBreak(MediaBreakInsertionMethod.Interrupt, TimeSpan.FromMinutes(10));
midrollMediaBreak.PlaybackList.Items.Add(
    new MediaPlaybackItem(MediaSource.CreateFromUri(new Uri("http://www.fabrikam.com/midroll_ad_1.mp4"))));
midrollMediaBreak.PlaybackList.Items.Add(
    new MediaPlaybackItem(MediaSource.CreateFromUri(new Uri("http://www.fabrikam.com/midroll_ad_2.mp4"))));
moviePlaybackItem.BreakSchedule.InsertMidrollBreak(midrollMediaBreak);

El siguiente ejemplo de interrupción intermedia mostrado usa el método de inserción MediaBreakInsertionMethod.Replace, lo que significa que el sistema seguirá procesando el contenido principal mientras se reproduce la interrupción. Esta opción la suelen usar las aplicaciones multimedia de streaming en vivo en las que no se quiere que el contenido se ponga en pausa y se pierda el streaming en vivo mientras se reproduce el anuncio.

Este ejemplo también usa una sobrecarga del constructor MediaPlaybackItem que acepta dos parámetros TimeSpan. El primer parámetro especifica el punto de partida dentro del elemento de interrupción multimedia en el que se iniciará la reproducción. El segundo parámetro especifica la duración de la reproducción del elemento de interrupción multimedia. Por tanto, en el siguiente ejemplo, MediaBreak empezará a reproducirse a los 20 minutos dentro del contenido principal. Durante la reproducción, el elemento multimedia se iniciará en 30 segundos desde el inicio del elemento de interrupción multimedia y se reproducirá durante 15 segundos antes de que el contenido multimedia principal reanude la reproducción.

midrollMediaBreak = new MediaBreak(MediaBreakInsertionMethod.Replace, TimeSpan.FromMinutes(20));
MediaPlaybackItem ad = 
    new MediaPlaybackItem(MediaSource.CreateFromUri(new Uri("http://www.fabrikam.com/midroll_ad_3.mp4")),
    TimeSpan.FromSeconds(30),
    TimeSpan.FromSeconds(15));
ad.CanSkip = false;
midrollMediaBreak.PlaybackList.Items.Add(ad);

Omitir interrupciones multimedia

Como se mencionó anteriormente en este artículo, la propiedad CanSkip de MediaPlaybackItem se puede establecer para impedir que el usuario omita el contenido con los controles integrados. Sin embargo, puedes llamar a SkipCurrentBreak desde el código en cualquier momento para omitir la interrupción actual.

private void SkipButton_Click(object sender, RoutedEventArgs e) => _mediaPlayer.BreakManager.SkipCurrentBreak();

Controlar eventos MediaBreak

Hay varios eventos relacionados con las interrupciones multimedia que se pueden registrar para poder tomar medidas basadas en el estado cambiante de las interrupciones multimedia.

_mediaPlayer.BreakManager.BreakStarted += BreakManager_BreakStarted;
_mediaPlayer.BreakManager.BreakEnded += BreakManager_BreakEnded;
_mediaPlayer.BreakManager.BreakSkipped += BreakManager_BreakSkipped;
_mediaPlayer.BreakManager.BreaksSeekedOver += BreakManager_BreaksSeekedOver;

BreakStarted se genera cuando se inicia una interrupción multimedia. Puedes actualizar la interfaz de usuario para que el usuario sepa que se está reproduciendo contenido de interrupción multimedia. En este ejemplo se usa MediaBreakStartedEventArgs pasado al controlador para obtener una referencia a la interrupción multimedia que se inició. La propiedad CurrentItemIndex se usa para determinar qué elemento multimedia se está reproduciendo en la lista de reproducción de la interrupción multimedia. A continuación, se actualiza la interfaz de usuario para mostrar al usuario el índice de anuncios actual y el número de anuncios restantes en la interrupción. Recuerda que las actualizaciones de la interfaz de usuario deben realizarse en el subproceso de interfaz de usuario, por lo que la llamada debe realizarse dentro de una llamada a RunAsync.

private async void BreakManager_BreakStarted(MediaBreakManager sender, MediaBreakStartedEventArgs args)
{
    MediaBreak currentBreak = sender.CurrentBreak;
    var currentIndex = currentBreak.PlaybackList.CurrentItemIndex;
    var itemCount = currentBreak.PlaybackList.Items.Count;

    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>            
        statusTextBlock.Text = $"Playing ad {currentIndex + 1} of {itemCount}");
}

BreakEnded se genera cuando haya finalizado la reproducción de todos los elementos multimedia de la interrupción o se hayan omitido. Puedes usar el controlador para este evento con el fin de actualizar la interfaz de usuario para indicar que ya no se está reproduciendo contenido de interrupción multimedia.

private async void BreakManager_BreakEnded(MediaBreakManager sender, MediaBreakEndedEventArgs args)
{
    // Update UI to show that the MediaBreak is no longer playing
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => statusTextBlock.Text = "");

    args.MediaBreak.CanStart = false;
}

El evento BreakSkipped se genera cuando el usuario presiona el botón Siguiente en la interfaz de usuario integrada durante la reproducción de un elemento para el que CanSkip sea true, o cuando omitas una interrupción en el código mediante una llamada a SkipCurrentBreak.

El siguiente ejemplo usa la propiedad Source de MediaPlayer para obtener una referencia al elemento multimedia para el contenido principal. La interrupción multimedia omitida pertenece a la programación de interrupción de este elemento. A continuación, el código comprueba si la interrupción multimedia omitida es la misma que la interrupción multimedia establecida en la propiedad PrerollBreak de la programación. Si es así, esto significa que la interrupción de preprocesamiento era la interrupción omitida y, en este caso, se crea y se programa una nueva interrupción intermedia para reproducirse durante 10 minutos en el contenido principal.

private async void BreakManager_BreakSkipped(MediaBreakManager sender, MediaBreakSkippedEventArgs args)
{
    // Update UI to show that the MediaBreak is no longer playing
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => statusTextBlock.Text = "");

    MediaPlaybackItem currentItem = _mediaPlayer.Source as MediaPlaybackItem;
    if(!(currentItem.BreakSchedule.PrerollBreak is  null) 
        && currentItem.BreakSchedule.PrerollBreak == args.MediaBreak)
    {
        MediaBreak mediaBreak = new MediaBreak(MediaBreakInsertionMethod.Interrupt, TimeSpan.FromMinutes(10));
        mediaBreak.PlaybackList.Items.Add(await GetAdPlaybackItem());
        currentItem.BreakSchedule.InsertMidrollBreak(mediaBreak);
    }
}

BreaksSeekedOver se genera cuando la posición de la reproducción del elemento multimedia principal sobrepasa el tiempo programado de una o más interrupciones multimedia. En el siguiente ejemplo se comprueba si se buscó más de una interrupción multimedia, si la posición de la reproducción se movió hacia adelante y si se movió hacia adelante menos de 10 minutos. Si es así, la primera interrupción que se buscó, obtenida a partir de la colección SeekedOverBreaks expuesta por los argumentos del evento, se reproduce inmediatamente con una llamada al método PlayBreak de MediaPlayer.BreakManager.

private void BreakManager_BreaksSeekedOver(MediaBreakManager sender, MediaBreakSeekedOverEventArgs args)
{
    if(args.SeekedOverBreaks.Count > 1
        && args.NewPosition.TotalMinutes > args.OldPosition.TotalMinutes
        && args.NewPosition.TotalMinutes - args.OldPosition.TotalMinutes < 10.0)
        _mediaPlayer.BreakManager.PlayBreak(args.SeekedOverBreaks[0]);
}

Acceso a la sesión de reproducción actual

El objeto MediaPlaybackSession usa la clase MediaPlayer para proporcionar datos y eventos relacionados con el contenido multimedia que se esté reproduciendo actualmente. MediaBreakManager también tiene una MediaPlaybackSession a la que puedes acceder para obtener datos y eventos específicamente relacionados con el contenido de la interrupción multimedia que se está reproduciendo. La información a la que puedes acceder desde la sesión de reproducción incluye el estado de reproducción actual, en reproducción o en pausa, y la posición de reproducción actual dentro del contenido. Puedes usar las propiedades NaturalVideoWidth y NaturalVideoHeight, y el elemento NaturalVideoSizeChanged para ajustar la interfaz de usuario de vídeo si el contenido de la interrupción multimedia tiene una relación de aspecto diferente a la del contenido principal. También puedes recibir eventos como BufferingStarted, BufferingEnded y DownloadProgressChanged, que pueden proporcionar una telemetría valiosa sobre el rendimiento de la aplicación.

En el siguiente ejemplo se registra un controlador para evento BufferingProgressChanged; en el controlador de eventos, actualiza la interfaz de usuario para mostrar el progreso de almacenamiento en búfer actual.

_mediaPlayer.BreakManager.PlaybackSession.BufferingProgressChanged += PlaybackSession_BufferingProgressChanged;
private async void PlaybackSession_BufferingProgressChanged(MediaPlaybackSession sender, object args)
{
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
        bufferingProgressBar.Value = sender.BufferingProgress);
}