Créer, planifier et gérer des coupures de médias

Cet article vous explique comment créer, planifier et gérer des coupures de médias dans votre application de lecture de contenu multimédia. Les coupures de médias sont généralement utilisées pour insérer des publicités audio ou vidéo dans du contenu multimédia. À compter de Windows 10, version 1607, vous pouvez utiliser la classe MediaBreakManager pour ajouter rapidement et facilement des sauts multimédias à n’importe quel objet MediaPlaybackItem que vous lisez avec un MediaPlayer.

Une fois que vous avez planifié une ou plusieurs coupures de médias, le système lit automatiquement votre contenu multimédia à l’intervalle spécifié durant la lecture. L’objet MediaBreakManager génère des événements de manière à ce que votre application puisse réagir au démarrage et à l’arrêt des coupures de médias, ou lorsqu’elles sont ignorées par l’utilisateur. Vous pouvez également accéder à un objet MediaPlaybackSession associé à vos coupures de médias afin de surveiller les événements tels que les mises à jour de l’avancement des téléchargements et de la mise en mémoire tampon.

Planifier des coupures de médias

Chaque objet MediaPlaybackItem présente son propre MediaBreakSchedule, que vous utilisez pour configurer les interruptions de média activées lors de la lecture de l’élément. La première étape pour l’utilisation de pauses multimédias dans votre application consiste à créer un objet MediaPlaybackItem pour votre main lire du contenu.

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

Pour plus d’informations sur l’utilisation de MediaPlaybackItem, MediaPlaybackList et d’autres API de lecture de contenu multimédia, consultez la section Lecture de contenu multimédia avec MediaSource.

L’exemple suivant illustre l’ajout d’une coupure de preroll à MediaPlaybackItem, ce qui signifie que le système lira la coupure de médias avant de lire l’élément de lecture auquel elle appartient. Dans un premier temps, un nouvel objet MediaBreak est instancié. Dans cet exemple, le constructeur est appelé avec MediaBreakInsertionMethod.Interrupt, ce qui signifie que le contenu main est suspendu pendant la lecture du contenu d’arrêt.

Ensuite, un nouvel élément MediaPlaybackItem est créé pour le contenu à lire pendant la coupure, tel qu’une publicité. La propriété CanSkip de cet élément de lecture est définie sur false. Ici, l’utilisateur ne pourra pas ignorer l’élément à l’aide des contrôles multimédias intégrés. Votre application peut toujours choisir d’ignorer l’ajout par programmation en appelant SkipCurrentBreak.

La propriété PlaybackList de la coupure de média est un élément MediaPlaybackList, qui vous permet de lire plusieurs éléments multimédias en tant que playlist. Ajoutez un ou plusieurs objets MediaPlaybackItem de la collection Items de la liste afin de les inclure dans la playlist de la coupure de média.

Enfin, planifiez la coupure multimédia à l’aide de la propriété BreakSchedule de l’élément de lecture de contenu main. Définissez la coupure en tant qu’objet de preroll en l’affectant à la propriété PrerollBreak de l’objet de planification.

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;

Maintenant que vous pouvez lire l’élément multimédia principal, et la coupure de média créée sera lue avant le contenu principal. Créez un objet MediaPlayer et définissez éventuellement la propriété Lecture automatique sur true pour démarrer la lecture automatiquement. Définissez la propriété Source de MediaPlayer sur l’élément de lecture de votre contenu principal. Cela n’est pas obligatoire, mais vous pouvez affecter l’objet MediaPlayer à un MediaPlayerElement afin d’afficher le contenu multimédia sur une page XAML. Pour plus d’informations sur l’utilisation de MediaPlayer, consultez la section Lire du contenu audio et vidéo avec MediaPlayer.

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

Ajoutez une coupure de postroll à lire après la fin de la lecture de l’objet MediaPlaybackItem contenant votre contenu principal, en appliquant une technique identique à celle employée avec une coupure de preroll. Ici seulement, vous affectez votre objet MediaBreak à la propriété 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;

Vous pouvez également planifier une ou plusieurs coupures de midroll à lire à des intervalles spécifiques durant la lecture du contenu principal. Dans l’exemple suivant, l’objet MediaBreak est créé avec la surcharge du constructeur qui accepte un objet TimeSpan, qui spécifie l’intervalle d’activation de la coupure durant la lecture de l’élément multimédia principal. Là encore, MediaBreakInsertionMethod.Interrupt est définie pour indiquer que la lecture du contenu principal est interrompue pendant l’activation de la coupure. Le saut midroll est ajouté à la planification en appelant InsertMidrollBreak. Vous pouvez récupérer une liste en lecture seule des coupures de midroll actives dans la planification, en accédant à la propriété 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);

L’exemple de saut de midroll suivant montre utilise la méthode d’insertion MediaBreakInsertionMethod.Replace, ce qui signifie que le système continuera à traiter le contenu main pendant la lecture de l’arrêt. Cette option est généralement utilisée par les applications de diffusion de contenu multimédia en continu au sein desquelles le contenu n’est pas interrompu et déplacé derrière le flux en direct pendant la lecture de la publicité.

Cet exemple utilise également une surcharge du constructeur MediaPlaybackItem qui accepte deux paramètres TimeSpan. Le premier paramètre spécifie le point de départ de la lecture au sein de l’élément de coupure de média. Le second paramètre spécifie la durée pendant laquelle l’élément de coupure de média sera lu. Ainsi, dans l’exemple suivant, l’objet MediaBreak démarrera 20 minutes après le démarrage du contenu principal. La lecture de l’élément multimédia démarre 30 secondes après le début de l’élément de coupure de média et s’arrête 15 secondes avant la reprise de la lecture du contenu multimédia principal.

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);

Ignorer les coupures de médias

Comme indiqué précédemment dans cet article, la propriété CanSkip d’un élément MediaPlaybackItem peut être définie pour empêcher l’utilisateur d’ignorer le contenu avec les contrôles intégrés. Toutefois, vous pouvez appeler SkipCurrentBreak à tout moment à partir de votre code pour ignorer l’arrêt actuel.

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

Gérer les événements MediaBreak

Plusieurs des événements associés aux coupures de médias peuvent être enregistrés, de manière à ce que vous puissiez agir en fonction de l’évolution de l’état des coupures de média.

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

BreakStarted est déclenché lorsqu’un arrêt multimédia démarre. Vous voudrez peut-être mettre à jour votre interface utilisateur afin d’indiquer à l’utilisateur que la coupure de média est en cours de lecture. Cet exemple utilise l’objet MediaBreakStartedEventArgs transmis au gestionnaire pour récupérer une référence à la coupure de média démarrée. Ensuite, la propriété CurrentItemIndex est utilisée pour identifier l’élément multimédia en cours de lecture de la playlist de la coupure de média. Ensuite, l’interface utilisateur est mise à jour afin d’indiquer à l’utilisateur l’index des publicités et le nombre de publicités restant dans la coupure. N’oubliez pas que les mises à jour de l’interface utilisateur doivent être effectuées sur le thread d’interface utilisateur. Dès lors, l’appel doit être effectué dans un appel à 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 est déclenché lorsque tous les éléments multimédias de la coupure ont été lus ou ignorés. Vous pouvez utiliser le gestionnaire de cet événement pour mettre à jour l’interface utilisateur afin d’indiquer que le contenu de la coupure de média n’est plus en cours de lecture.

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;
}

L’événement BreakSkipped est déclenché lorsque l’utilisateur appuie sur le bouton Suivant dans l’interface utilisateur durant la lecture d’un élément pour lequel l’objet CanSkip est défini sur true,ou lorsque vous ignorez une coupure dans votre code en appelant SkipCurrentBreak.

L’exemple suivant utilise la propriété Source de l’objet MediaPlayer afin d’obtenir une référence à l’élément multimédia pour le contenu principal. La coupure de média ignorée appartient à la planification des coupures de cet élément. Ensuite, le code vérifie si l’arrêt multimédia qui a été ignoré est identique à celui défini sur la propriété PrerollBreak de la planification. Si tel est le cas, cela signifie que la coupure de preroll est bien celle qui a été ignorée. Le cas échéant, une nouvelle coupure de midroll est créée, et sa lecture est planifiée 10 minutes après le démarrage du contenu 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 est déclenché lorsque la position de lecture de l’élément multimédia main passe au-dessus de l’heure planifiée pour une ou plusieurs interruptions de média. L’exemple suivant détecte si une ou plusieurs coupures de média ont été recherchées, si la position de lecture a été avancée et si elle a été avancée de moins de 10 minutes. Le cas échéant, la première coupure recherchée, récupérée de la collection SeekedOverBreaks exposée par les arguments d’événement, est lue immédiatement avec un appel à la méthode 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]);
}

Accéder à la session de lecture active

L’objet MediaPlaybackSession utilise la classe MediaPlayer pour fournir des données et des événements associés au contenu multimédia en cours de lecture. L’objet MediaBreakManager présente également un élément MediaPlaybackSession auquel vous accédez pour récupérer les données et les événements spécifiquement associés au contenu de la coupure de média en cours de lecture. Parmi les informations pouvant être obtenues de la session de lecture, vous trouverez l’état de lecture actif (en lecture ou en pause), ainsi que la position de lecture au sein du contenu. Vous pouvez utiliser les propriétés NaturalVideoWidth et NaturalVideoHeight et NaturalVideoSizeChanged pour ajuster l’interface utilisateur de votre vidéo si le contenu de l’arrêt multimédia a des proportions différentes de celles de votre contenu main. Vous pouvez également recevoir des événements tels que BufferingStarted, BufferingEnded et DownloadProgressChanged, qui peuvent fournir des données précieuses de télémétrie relatives aux performances de votre application.

Dans l’exemple suivant, un gestionnaire est enregistré pour l’événement BufferingProgressChanged ; dans le gestionnaire d’événement, il met à jour l’interface utilisateur en fonction de l’avancement de la mise en mémoire tampon.

_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);
}