Flussi adattiviAdaptive streaming

Questo articolo descrive come aggiungere la riproduzione di contenuti multimediali in flussi adattivi alle app UWP (Universal Windows Platform).This article describes how to add playback of adaptive streaming multimedia content to a Universal Windows Platform (UWP) app. Questa funzionalità supporta la riproduzione dei contenuti HTTP Live streaming (HLS) e Dynamic Streaming over HTTP (DASH).This feature supports playback of Http Live Streaming (HLS) and Dynamic Streaming over HTTP (DASH) content. A partire da Windows 10, versione 1803, Smooth Streaming è supportato da AdaptiveMediaSource.Starting with Windows 10, version 1803, Smooth Streaming is supported by AdaptiveMediaSource.

Per un elenco dei tag del protocollo HLS supportati, vedi Supporto di tag HLS.For a list of supported HLS protocol tags, see HLS tag support.

Per un elenco dei profili DASH supportati, vedere supporto del profilo Dash.For a list of supported DASH profiles, see DASH profile support.

Nota

Il codice in questo articolo è stato adattato dall'esempio di flusso adattivo UWP.The code in this article was adapted from the UWP Adaptive streaming sample.

Flusso adattivo semplice con MediaPlayer e MediaPlayerElementSimple adaptive streaming with MediaPlayer and MediaPlayerElement

Per riprodurre flussi adattivi di contenuti multimediali in un'app UWP, crea un oggetto Uri che punta a un file manifesto DASH o HLS.To play adaptive streaming media in a UWP app, create a Uri object pointing to a DASH or HLS manifest file. Creare un'istanza della classe MediaPlayer .Create an instance of the MediaPlayer class. Chiama MediaSource.CreateFromUri per creare un nuovo oggetto MediaSource e impostalo sulla proprietà Source di MediaPlayer.Call MediaSource.CreateFromUri to create a new MediaSource object and then set that to the Source property of the MediaPlayer. Chiama Play per avviare la riproduzione del contenuto multimediale.Call Play to start playback of the media content.

MediaPlayer _mediaPlayer;
System.Uri manifestUri = new Uri("http://amssamples.streaming.mediaservices.windows.net/49b57c87-f5f3-48b3-ba22-c55cfdffa9cb/Sintel.ism/manifest(format=m3u8-aapl)");
_mediaPlayer = new MediaPlayer();
_mediaPlayer.Source = MediaSource.CreateFromUri(manifestUri);
_mediaPlayer.Play();

L'esempio precedente riprodurrà l'audio del contenuto multimediale, ma non eseguirà automaticamente il rendering del contenuto nell'interfaccia utente.The above example will play the audio of the media content but it doesn't automatically render the content in your UI. La maggior parte delle app che riproducono contenuto video eseguirà il rendering del contenuto in una pagina XAML.Most apps that play video content will want to render the content in a XAML page. A questo scopo, aggiungi un controllo MediaPlayerElement alla tua pagina XAML.To do this, add a MediaPlayerElement control to your XAML page.

<MediaPlayerElement x:Name="mediaPlayerElement" HorizontalAlignment="Stretch" AreTransportControlsEnabled="True"/>

Chiama MediaSource.CreateFromUri per creare un oggetto MediaSource dall'URI di un file manifesto DASH o HLS.Call MediaSource.CreateFromUri to create a MediaSource from the URI of a DASH or HLS manifest file. Imposta quindi la proprietà Source di MediaPlayerElement.Then set the Source property of the MediaPlayerElement. Il controllo MediaPlayerElement creerà automaticamente un nuovo oggetto MediaPlayer per il contenuto.The MediaPlayerElement will automatically create a new MediaPlayer object for the content. Puoi chiamare Play su MediaPlayer per avviare la riproduzione del contenuto.You can call Play on the MediaPlayer to start playback of the content.

System.Uri manifestUri = new Uri("http://amssamples.streaming.mediaservices.windows.net/49b57c87-f5f3-48b3-ba22-c55cfdffa9cb/Sintel.ism/manifest(format=m3u8-aapl)");
mediaPlayerElement.Source = MediaSource.CreateFromUri(manifestUri);
mediaPlayerElement.MediaPlayer.Play();

Nota

A partire da Windows 10 versione 1607, è consigliabile usare la classe MediaPlayer per la riproduzione di elementi multimediali.Starting with Windows 10, version 1607, it is recommended that you use the MediaPlayer class to play media items. MediaPlayerElement è un controllo XAML leggero usato per il rendering del contenuto di un MediaPlayer in una pagina XAML.The MediaPlayerElement is a lightweight XAML control that is used to render the content of a MediaPlayer in a XAML page. Il controllo MediaElement continua a essere supportato per la compatibilità con le versioni precedenti.The MediaElement control continues to be supported for backwards compatibility. Per altre informazioni sull'uso di MediaPlayer e MediaPlayerElement per riprodurre contenuto multimediale, vedi Riprodurre audio e video con MediaPlayer.For more information about using MediaPlayer and MediaPlayerElement to play media content, see Play audio and video with MediaPlayer. Per informazioni sull'uso di MediaSource e delle API correlate per la gestione di contenuto multimediale, vedi Elementi multimediali, playlist e tracce.For information about using MediaSource and related APIs to work with media content, see Media items, playlists, and tracks.

Flusso adattivo con AdaptiveMediaSourceAdaptive streaming with AdaptiveMediaSource

Se l'app richiede funzionalità di streaming adattivo più avanzate, ad esempio la fornitura di intestazioni HTTP personalizzate, il monitoraggio delle velocità in bit correnti di download e riproduzione o la regolazione dei rapporti che determinano quando il sistema passa alla velocità in bit del flusso adattivo, usare l'oggetto AdaptiveMediaSource .If your app requires more advanced adaptive streaming features, such as providing custom HTTP headers, monitoring the current download and playback bitrates, or adjusting the ratios that determine when the system switches bitrates of the adaptive stream, use the AdaptiveMediaSource object.

Le API per il flusso adattivo si trovano nello spazio dei nomi Windows.Media.Streaming.Adaptive.The adaptive streaming APIs are found in the Windows.Media.Streaming.Adaptive namespace. Gli esempi in questo articolo usano le API degli spazi dei nomi seguenti.The examples in this article use APIs from the following namespaces.

using Windows.Media.Streaming.Adaptive;
using System.Threading.Tasks;
using Windows.Storage.Streams;
using Windows.Media.Playback;
using Windows.Media.Core;

Inizializzare un AdaptiveMediaSource da un URI.Initialize an AdaptiveMediaSource from a URI.

Inizializza AdaptiveMediaSource con l'URI di un file manifesto di flusso adattivo chiamando CreateFromUriAsync.Initialize the AdaptiveMediaSource with the URI of an adaptive streaming manifest file by calling CreateFromUriAsync. Il valore AdaptiveMediaSourceCreationStatus restituito da questo metodo consente di verificare se l'origine del supporto è stata creata correttamente.The AdaptiveMediaSourceCreationStatus value returned from this method lets you know if the media source was created successfully. In tal caso, è possibile impostare l'oggetto come origine del flusso per il MediaPlayer creando un oggetto MediaSource chiamando MediaSource. CreateFromAdaptiveMediaSourcee quindi assegnandogli la proprietà di origine di Media Player.If so, you can set the object as the stream source for your MediaPlayer by creating a MediaSource object by calling MediaSource.CreateFromAdaptiveMediaSource, and then assigning it to the media player's Source property. In questo esempio viene eseguita una query sulla proprietà AvailableBitrates per determinare la velocità in bit massima supportata per questo flusso, quindi il valore viene impostato come velocità in bit iniziale.In this example, the AvailableBitrates property is queried to determine the maximum supported bitrate for this stream, and then that value is set as the inital bitrate. Questo esempio registra anche i gestori per i diversi eventi AdaptiveMediaSource descritti più avanti in questo articolo.This example also registers handlers for the several AdaptiveMediaSource events that are discussed later in this article.

async private void InitializeAdaptiveMediaSource(System.Uri uri)
{
    AdaptiveMediaSourceCreationResult result = await AdaptiveMediaSource.CreateFromUriAsync(uri);

    if (result.Status == AdaptiveMediaSourceCreationStatus.Success)
    {
        ams = result.MediaSource;
        mediaPlayerElement.SetMediaPlayer(new MediaPlayer());
        mediaPlayerElement.MediaPlayer.Source = MediaSource.CreateFromAdaptiveMediaSource(ams);
        mediaPlayerElement.MediaPlayer.Play();


        ams.InitialBitrate = ams.AvailableBitrates.Max<uint>();

        //Register for download requests
        ams.DownloadRequested += DownloadRequested;

        //Register for download failure and completion events
        ams.DownloadCompleted += DownloadCompleted;
        ams.DownloadFailed += DownloadFailed;

        //Register for bitrate change events
        ams.DownloadBitrateChanged += DownloadBitrateChanged;
        ams.PlaybackBitrateChanged += PlaybackBitrateChanged;

        //Register for diagnostic event
        ams.Diagnostics.DiagnosticAvailable += DiagnosticAvailable;
    }
    else
    {
        // Handle failure to create the adaptive media source
        MyLogMessageFunction($"Adaptive source creation failed: {uri} - {result.ExtendedError}");
    }
}

Inizializzare un AdaptiveMediaSource usando HttpClientInitialize an AdaptiveMediaSource using HttpClient

Se hai bisogno di impostare intestazioni HTTP personalizzate per ottenere il file manifesto, puoi creare un oggetto HttpClient, impostare le intestazioni desiderate e quindi passare l'oggetto nell'overload di CreateFromUriAsync.If you need to set custom HTTP headers for getting the manifest file, you can create an HttpClient object, set the desired headers, and then pass the object into the overload of CreateFromUriAsync.

httpClient = new Windows.Web.Http.HttpClient();
httpClient.DefaultRequestHeaders.TryAppendWithoutValidation("X-CustomHeader", "This is a custom header");
AdaptiveMediaSourceCreationResult result = await AdaptiveMediaSource.CreateFromUriAsync(manifestUri, httpClient);

L'evento DownloadRequested viene generato quando il sistema è in procinto di recuperare una risorsa dal server.The DownloadRequested event is raised when the system is about to retrieve a resource from the server. L'oggetto AdaptiveMediaSourceDownloadRequestedEventArgs passato al gestore eventi espone le proprietà che forniscono informazioni sulla risorsa richiesta, come il tipo e l'URI della risorsa.The AdaptiveMediaSourceDownloadRequestedEventArgs passed into the event handler exposes properties that provide information about the resource being requested such as the type and URI of the resource.

Modificare le proprietà delle richieste di risorse usando l'evento DownloadRequestedModify resource request properties using the DownloadRequested event

Puoi usare il gestore dell'evento DownloadRequested per modificare la richiesta di risorsa aggiornando le proprietà dell'oggetto AdaptiveMediaSourceDownloadResult fornito dagli argomenti dell'evento.You can use the DownloadRequested event handler to modify the resource request by updating the properties of the AdaptiveMediaSourceDownloadResult object provided by the event args. Nell'esempio seguente l'URI da cui verrà recuperata la risorsa viene modificato aggiornando le proprietà ResourceUri dell'oggetto risultato.In the example below, the URI from which the resource will be retrieved is modified by updating the ResourceUri properties of the result object. È inoltre possibile riscrivere l'offset e la lunghezza dell'intervallo di byte per i segmenti di supporto o, come illustrato nell'esempio seguente, modificare l'URI della risorsa per scaricare la risorsa completa e impostare la lunghezza e l'offset dell'intervallo di byte su null.You can also rewrite the byte range offset and length for media segments or, as shown the example below, change the resource URI to download the full resource and set the byte range offset and length to null.

È possibile eseguire l'override del contenuto della risorsa richiesta impostando le proprietà buffer o InputStream dell'oggetto risultato.You can override the content of the requested resource by setting the Buffer or InputStream properties of the result object. Nell'esempio seguente il contenuto della risorsa del manifesto viene sostituito impostando la proprietà Buffer.In the example below, the contents of the manifest resource are replaced by setting the Buffer property. Si noti che se si aggiorna la richiesta di risorse con i dati ottenuti in modo asincrono, ad esempio il recupero di dati da un server remoto o l'autenticazione utente asincrona, è necessario chiamare AdaptiveMediaSourceDownloadRequestedEventArgs. getrinvio per ottenere un rinvio e quindi chiamare complete al termine dell'operazione per segnalare al sistema che l'operazione di richiesta di download può continuare.Note that if you are updating the resource request with data that is obtained asynchronously, such as retrieving data from a remote server or asynchronous user authentication, you must call AdaptiveMediaSourceDownloadRequestedEventArgs.GetDeferral to get a deferral and then call Complete when the operation is complete to signal the system that the download request operation can continue.

    private async void DownloadRequested(AdaptiveMediaSource sender, AdaptiveMediaSourceDownloadRequestedEventArgs args)
    {

        // rewrite key URIs to replace http:// with https://
        if (args.ResourceType == AdaptiveMediaSourceResourceType.Key)
        {
            string originalUri = args.ResourceUri.ToString();
            string secureUri = originalUri.Replace("http:", "https:");

            // override the URI by setting property on the result sub object
            args.Result.ResourceUri = new Uri(secureUri);
        }

        if (args.ResourceType == AdaptiveMediaSourceResourceType.Manifest)
        {
            AdaptiveMediaSourceDownloadRequestedDeferral deferral = args.GetDeferral();
            args.Result.Buffer = await CreateMyCustomManifest(args.ResourceUri);
            deferral.Complete();
        }

        if (args.ResourceType == AdaptiveMediaSourceResourceType.MediaSegment)
        {
            var resourceUri = args.ResourceUri.ToString() + "?range=" + 
                args.ResourceByteRangeOffset + "-" + (args.ResourceByteRangeLength - 1);

            // override the URI by setting a property on the result sub object
            args.Result.ResourceUri = new Uri(resourceUri);

            // clear the byte range properties on the result sub object
            args.Result.ResourceByteRangeOffset = null;
            args.Result.ResourceByteRangeLength = null;
        }
    }

Usare gli eventi a velocità in bit per gestire e rispondere alle modifiche della velocità in bitUse bitrate events to manage and respond to bitrate changes

L'oggetto AdaptiveMediaSource fornisce gli eventi che ti permettono di rispondere quando cambiano le velocità in bit del download o della riproduzione.The AdaptiveMediaSource object provides events that allow you to react when the download or playback bitrates change. In questo esempio le velocità in bit correnti vengono semplicemente aggiornate nell'interfaccia utente.In this example, the current bitrates are simply updated in the UI. Tieni presente che puoi modificare i rapporti che determinano quando il sistema scambia le velocità in bit del flusso adattivo.Note that you can modify the ratios that determine when the system switches bitrates of the adaptive stream. Per ulteriori informazioni, vedere la proprietà AdvancedSettings .For more information, see the AdvancedSettings property.

private async void DownloadBitrateChanged(AdaptiveMediaSource sender, AdaptiveMediaSourceDownloadBitrateChangedEventArgs args)
{
    await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, new DispatchedHandler(() =>
    {
        txtDownloadBitrate.Text = args.NewValue.ToString();
    }));
}

private async void PlaybackBitrateChanged(AdaptiveMediaSource sender, AdaptiveMediaSourcePlaybackBitrateChangedEventArgs args)
{
    await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, new DispatchedHandler(() =>
    {
        txtPlaybackBitrate.Text = args.NewValue.ToString();
    }));
}

Gestisci eventi di completamento del download ed erroriHandle download completion and failure events

L'oggetto AdaptiveMediaSource genera l'evento DownloadFailed quando il download di una risorsa richiesta ha esito negativo.The AdaptiveMediaSource object raises the DownloadFailed event when the download of a requested resource fails. È possibile usare questo evento per aggiornare l'interfaccia utente in risposta al problema.You can use this event to update your UI in response to the failure. È anche possibile usare l'evento per registrare informazioni statistiche sull'operazione di download e sull'errore.You can also use the event to log statistical information about the download operation and the failure.

L'oggetto AdaptiveMediaSourceDownloadFailedEventArgs passato nel gestore eventi contiene i metadati relativi al download di risorse non riusciti, ad esempio il tipo di risorsa, l'URI della risorsa e la posizione all'interno del flusso in cui si è verificato l'errore.The AdaptiveMediaSourceDownloadFailedEventArgs object passed into the event handler contains metadata about the failed resource download, such as the resource type, the URI of the resource, and the position within the stream where the failure occurred. Il RequestId ottiene un identificatore univoco generato dal sistema per la richiesta che può essere usato per correlare le informazioni sullo stato relative a una singola richiesta tra più eventi.The RequestId gets a system-generated unique identifier for the request that can be use to correlate status information about an individual request across multiple events.

La proprietà Statistics restituisce un oggetto AdaptiveMediaSourceDownloadStatistics che fornisce informazioni dettagliate sul numero di byte ricevuti al momento dell'evento e sulla tempistica di varie attività cardine nell'operazione di download.The Statistics property returns a AdaptiveMediaSourceDownloadStatistics object which provides detailed information about the number of bytes received at the time of the event and the timing of various milestones in the download operation. È possibile registrare queste informazioni per identificare i problemi di prestazioni nell'implementazione del flusso adattivo.You can log this information in order identify perfomance issues in your adaptive streaming implementation.

private void DownloadFailed(AdaptiveMediaSource sender, AdaptiveMediaSourceDownloadFailedEventArgs args)
{
    var statistics = args.Statistics;

    MyLogMessageFunction("download failed for: " + args.ResourceType + 
     " - " + args.ResourceUri +
     " – Error:" + args.ExtendedError.HResult +
     " - RequestId" + args.RequestId + 
     " – Position:" + args.Position +
     " - Duration:" + args.ResourceDuration +
     " - ContentType:" + args.ResourceContentType +
     " - TimeToHeadersReceived:" + statistics.TimeToHeadersReceived + 
     " - TimeToFirstByteReceived:" + statistics.TimeToFirstByteReceived + 
     " - TimeToLastByteReceived:" + statistics.TimeToLastByteReceived +
     " - ContentBytesReceivedCount:" + statistics.ContentBytesReceivedCount);

}

L'evento DownloadCompleted si verifica quando viene completato il download di una risorsa e provdes dati simili all'evento DownloadFailed .The DownloadCompleted event occurs when a resource download completes and provdes similar data to the DownloadFailed event. Ancora una volta, viene fornito un RequestId per correlare gli eventi per una singola richiesta.Once again, a RequestId is provided for correlating events for a single request. Viene inoltre fornito un oggetto AdaptiveMediaSourceDownloadStatistics per abilitare la registrazione delle statistiche di download.Also, an AdaptiveMediaSourceDownloadStatistics object is provided to enable logging of download stats.

private void DownloadCompleted(AdaptiveMediaSource sender, AdaptiveMediaSourceDownloadCompletedEventArgs args)
{
    var statistics = args.Statistics;

    MyLogMessageFunction("download completed for: " + args.ResourceType + " - " +
     args.ResourceUri +
     " – RequestId:" + args.RequestId +
     " – Position:" + args.Position +
     " - Duration:" + args.ResourceDuration +
     " - ContentType:" + args.ResourceContentType +
     " - TimeToHeadersReceived:" + statistics.TimeToHeadersReceived + 
     " - TimeToFirstByteReceived:" + statistics.TimeToFirstByteReceived + 
     " - TimeToLastByteReceived:" + statistics.TimeToLastByteReceived +
     " - ContentBytesReceivedCount:" + statistics.ContentBytesReceivedCount);

}

Raccogliere dati di telemetria del flusso adattivo con AdaptiveMediaSourceDiagnosticsGather adaptive streaming telemetry data with AdaptiveMediaSourceDiagnostics

AdaptiveMediaSource espone una proprietà di diagnostica che restituisce un oggetto AdaptiveMediaSourceDiagnostics .The AdaptiveMediaSource exposes a Diagnostics property which returns an AdaptiveMediaSourceDiagnostics object. Utilizzare questo oggetto per eseguire la registrazione per l'evento DiagnosticAvailable .Use this object to register for the DiagnosticAvailable event. Questo evento deve essere usato per la raccolta di dati di telemetria e non deve essere usato per modificare il comportamento dell'app in fase di esecuzione.This event is intended to be used for telemetry collection and should not be used to modify app behavior at runtime. Questo evento diagnostico viene generato per diversi motivi.This diagnostic event is raised for many different reasons. Controllare la proprietà DiagnosticType dell'oggetto AdaptiveMediaSourceDiagnosticAvailableEventArgs passato nell'evento per determinare il motivo per cui è stato generato l'evento.Check the DiagnosticType property of the AdaptiveMediaSourceDiagnosticAvailableEventArgs object passed into the event to determine the reason that the event was raised. I motivi potenziali includono errori di accesso alla risorsa richiesta ed errori durante l'analisi del file manifesto di streaming.Potential reasons include errors accessing the requested resource and errors parsing the streaming manifest file. Per un elenco delle situazioni in cui è possibile attivare un evento di diagnostica, vedere AdaptiveMediaSourceDiagnosticType.For a list of situations that can trigger a diagnostic event, see AdaptiveMediaSourceDiagnosticType. Analogamente agli argomenti per altri eventi di streaming adattivo, AdaptiveMediaSourceDiagnosticAvailableEventArgs fornisce un RequestId appropriato per la correlazione delle informazioni di richiesta tra eventi diversi.Like the arguments for other adaptive streaming events, the AdaptiveMediaSourceDiagnosticAvailableEventArgs provides a RequestId propery for correlating request information between different events.

private void DiagnosticAvailable(AdaptiveMediaSourceDiagnostics sender, AdaptiveMediaSourceDiagnosticAvailableEventArgs args)
{
    MySendTelemetryFunction(args.RequestId, args.Position,
                            args.DiagnosticType, args.SegmentId,
                            args.ResourceType, args.ResourceUri,
                            args.ResourceDuration, args.ResourceContentType,
                            args.ResourceByteRangeOffset,
                            args.ResourceByteRangeLength, 
                            args.Bitrate,
                            args.ExtendedError);

}

Rinvia l'associazione del contenuto di streaming adattivo per gli elementi in un elenco di riproduzione usando MediaBinderDefer binding of adaptive streaming content for items in a playback list by using MediaBinder

La classe MediaBinder consente di rinviare l'associazione di contenuto multimediale in un MediaPlaybackList.The MediaBinder class allows you to defer binding of media content in a MediaPlaybackList. A partire da Windows 10, versione 1703, è possibile fornire un AdaptiveMediaSource come contenuto associato.Starting with Windows 10, version 1703, you can supply an AdaptiveMediaSource as bound content. Il processo di associazione posticipata di un'origine supporto adattiva è in gran parte analogo al binding di altri tipi di supporto, descritto in elementi multimediali, playlist e tracce.The process for deferred binding of an adaptive media source is largely the same as binding other types of media, which is described in Media items, playlists, and tracks.

Creare un'istanza di MediaBinder , impostare una stringa di token definita dall'app per identificare il contenuto da associare e registrarsi per l'evento di associazione .Create a MediaBinder instance, set an app-defined Token string to identify the content to be bound, and register for the Binding event. Creare un MediaSource dal Binder chiamando MediaSource. CreateFromMediaBinder.Create a MediaSource from the Binder by calling MediaSource.CreateFromMediaBinder. Quindi, creare un MediaPlaybackItem da MediaSource e aggiungerlo all'elenco di riproduzione.Then, create a MediaPlaybackItem from the MediaSource and add it to the playback list.

_mediaPlaybackList = new MediaPlaybackList();

var binder = new MediaBinder();
binder.Token = "MyBindingToken1";
binder.Binding += Binder_Binding;
_mediaPlaybackList.Items.Add(new MediaPlaybackItem(MediaSource.CreateFromMediaBinder(binder)));

binder = new MediaBinder();
binder.Token = "MyBindingToken2";
binder.Binding += Binder_Binding;
_mediaPlaybackList.Items.Add(new MediaPlaybackItem(MediaSource.CreateFromMediaBinder(binder)));

_mediaPlayer = new MediaPlayer();
_mediaPlayer.Source = _mediaPlaybackList;
mediaPlayerElement.SetMediaPlayer(_mediaPlayer);

Nel gestore dell'evento Binding usare la stringa del token per identificare il contenuto da associare, quindi creare l'origine del supporto adattivo chiamando uno degli overload di createFromStreamAsync o CreateFromUriAsync.In the Binding event handler, use the token string to identify the content to be bound and then create the adaptive media source by calling one of the overloads of CreateFromStreamAsync or CreateFromUriAsync. Poiché si tratta di metodi asincroni, è innanzitutto necessario chiamare il metodo MediaBindingEventArgs. Getdifferiment per indicare al sistema di attendere il completamento dell'operazione prima di continuare.Because these are asynchronous methods, you should first call the MediaBindingEventArgs.GetDeferral method to instruct the system to wait for your operation to complete before continuing. Impostare l'origine del supporto adattivo come contenuto associato chiamando SetAdaptiveMediaSource.Set the adaptive media source as the bound content by calling SetAdaptiveMediaSource. Infine, chiamare rinvio. complete al termine dell'operazione per indicare al sistema di continuare.Finally, call Deferral.Complete after your operation is complete to instruct the system to continue.

private async void Binder_Binding_AdaptiveMediaSource(MediaBinder sender, MediaBindingEventArgs args)
{
    var deferral = args.GetDeferral();

    var contentUri = new Uri($"http://contoso.com/media/{args.MediaBinder.Token}");
    AdaptiveMediaSourceCreationResult result = await AdaptiveMediaSource.CreateFromUriAsync(contentUri);

    if (result.MediaSource != null)
    {
        args.SetAdaptiveMediaSource(result.MediaSource);
    }
    args.SetUri(contentUri);

    deferral.Complete();
}

Se si desidera registrare i gestori eventi per l'origine del supporto adattivo associato, è possibile eseguire questa operazione nel gestore per l'evento CurrentItemChanged di MediaPlaybackList.If you want to register event handlers for the bound adaptive media source, you can do this in the handler for the CurrentItemChanged event of the MediaPlaybackList. La proprietà CurrentMediaPlaybackItemChangedEventArgs. NewItem contiene il nuovo MediaPlaybackItem attualmente in esecuzione nell'elenco.The CurrentMediaPlaybackItemChangedEventArgs.NewItem property contains the new currently playing MediaPlaybackItem in the list. Ottenere un'istanza di AdaptiveMediaSource che rappresenta il nuovo elemento accedendo alla proprietà source di MediaPlaybackItem e quindi alla proprietà AdaptiveMediaSource dell'origine multimediale.Get an instance of the AdaptiveMediaSource representing the new item by accessing the Source property of the MediaPlaybackItem and then the AdaptiveMediaSource property of the media source. Questa proprietà sarà null se il nuovo elemento di riproduzione non è un AdaptiveMediaSource, pertanto è necessario verificare il valore null prima di tentare di registrare i gestori per gli eventi dell'oggetto.This property will be null if the new playback item is not an AdaptiveMediaSource, so you should test for null before attempting to register handlers for any of the object's events.

private void AMSMediaPlaybackList_CurrentItemChanged(MediaPlaybackList sender, CurrentMediaPlaybackItemChangedEventArgs args)
{
    if (!(args.NewItem is null))
    {
        var ams = args.NewItem.Source.AdaptiveMediaSource;
        if (!(ams is null))
        {
            ams.PlaybackBitrateChanged += Ams_PlaybackBitrateChanged;
        }
    }
}