Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Ez a cikk bemutatja, hogyan adhat hozzá adaptív streamelési multimédiás tartalmak lejátszását egy WinUI-alkalmazáshoz. Ez a funkció támogatja a HTTP-alapú élő streamelés (HLS) és a dinamikus streamelés HTTP-n (DASH) keresztüli lejátszását.
A Windows 10 1803-es verziójától kezdve a Smooth Streaminget az AdaptiveMediaSource támogatja. Vegye figyelembe, hogy a Smooth Streaming esetében csak a H264 és WVC1 kodekek támogatottak. Más jegyzéktípusokra nem vonatkozik ez a korlátozás.
A támogatott HLS-protokollcímkék listáját a HLS-címkék támogatásával kapcsolatban találja.
A támogatott DASH-profilok listáját a DASH-profilok támogatásával kapcsolatban találja.
Megjegyzés:
A cikkben szereplő kód az Adaptív streamelési mintából lett adaptálva.
Egyszerű adaptív streamelés a MediaPlayer és a MediaPlayerElement használatával
Ha adaptív streamelési adathordozót szeretne lejátszani egy WinUI-alkalmazásban, hozzon létre egy URI-objektumot , amely EGY DASH- vagy HLS-jegyzékfájlra mutat. Hozza létre a MediaPlayer-osztály egy példányát. A MediaSource.CreateFromUri meghívásával hozzon létre egy új MediaSource-objektumot, majd állítsa be a MediaPlayerForrás tulajdonságára. Hívja fel a Lejátszást a médiatartalom lejátszásának elindításához.
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();
A fenti példa lejátssza a médiatartalom hangját, de nem jeleníti meg automatikusan a tartalmat a felhasználói felületen. A videótartalmat lejátszó alkalmazások többsége egy XAML-lapon szeretné megjeleníteni a tartalmat. Ehhez vegyen fel egy MediaPlayerElement-vezérlőt az XAML-lapra.
<MediaPlayerElement x:Name="mediaPlayerElement" HorizontalAlignment="Stretch" AreTransportControlsEnabled="True"/>
A MediaSource.CreateFromUri meghívásával hozzon létre egy MediaSource-t egy DASH- vagy HLS-jegyzékfájl URI-jából. Ezután állítsa be a MediaPlayerElement Forrás tulajdonságát. A MediaPlayerElement automatikusan létrehoz egy új MediaPlayer-objektumot a tartalomhoz. A tartalom lejátszását a Play meghívásával kezdheti el a MediaPlayer használatával.
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();
Adaptív streamelés az AdaptiveMediaSource-nal
Ha az alkalmazás speciális adaptív streamelési funkciókat igényel, például egyéni HTTP-fejléceket biztosít, figyeli az aktuális letöltési és lejátszási bitrátákat, vagy módosítja azokat az arányokat, amelyek meghatározzák, hogy a rendszer mikor váltja át az adaptív stream bitrátáit, használja az AdaptiveMediaSource objektumot.
Egy URI-ból AdaptiveMediaSource inicializálása.
Inicializálja az AdaptiveMediaSource-t egy adaptív streamelési jegyzékfájl URI-jával a CreateFromUriAsync meghívásával. Az ebből a metódusból visszaadott AdaptiveMediaSourceCreationStatus értékből megtudhatja, hogy a médiaforrás sikeresen létrejött-e. Ha igen, beállíthatja az objektumot a MediaPlayer streamforrásaként, ha létrehoz egy MediaSource objektumot a MediaSource.CreateFromAdaptiveMediaSource meghívásával, majd hozzárendeli azt a médialejátszó Forrás tulajdonságához. Ebben a példában az AvailableBitrates tulajdonság lekérdezve határozza meg a stream maximális támogatott sávszélességét, majd ezt az értéket állítja be a kezdeti bitrátaként. Ez a példa a cikk későbbi részében tárgyalt számos AdaptiveMediaSource-esemény kezelőit is regisztrálja.
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}");
}
}
AdaptiveMediaSource inicializálása a HttpClient használatával
Ha egyéni HTTP-fejléceket kell beállítania a jegyzékfájl lekéréséhez, létrehozhat egy HttpClient-objektumot , beállíthatja a kívánt fejléceket, majd átadhatja az objektumot a CreateFromUriAsync túlterhelésének.
httpClient = new Windows.Web.Http.HttpClient();
httpClient.DefaultRequestHeaders.TryAppendWithoutValidation("X-CustomHeader", "This is a custom header");
AdaptiveMediaSourceCreationResult result = await AdaptiveMediaSource.CreateFromUriAsync(manifestUri, httpClient);
A DownloadRequested esemény akkor jön létre, amikor a rendszer le szeretne kérni egy erőforrást a kiszolgálóról. Az eseménykezelőnek átadott AdaptiveMediaSourceDownloadRequestedEventArgs olyan tulajdonságokat tesz elérhetővé, amelyek információt nyújtanak a kért erőforrásról, például az erőforrás típusáról és URI-járól.
Erőforrás-kérelem tulajdonságainak módosítása a DownloadRequested esemény használatával
A DownloadRequested eseménykezelővel módosíthatja az erőforrás-kérést az esemény args által biztosított AdaptiveMediaSourceDownloadResult objektum tulajdonságainak frissítésével. Az alábbi példában az erőforrás lekéréséhez használt URI az eredményobjektum ResourceUri-tulajdonságainak frissítésével módosul. A médiaszegmensek bájttartomány-eltolását és hosszát is átírhatja, vagy az alábbi példában látható módon módosíthatja az erőforrás URI-jának módosítását a teljes erőforrás letöltéséhez, és a bájttartomány eltolását és hosszát null értékre állíthatja.
A kért erőforrás tartalmát felülbírálhatja az eredményobjektum Puffer - vagy InputStream-tulajdonságainak beállításával. Az alábbi példában a jegyzék-erőforrás tartalmát a Puffer tulajdonság beállításával helyettesítjük. Vegye figyelembe, hogy ha az erőforrás-kérést az aszinkron módon beszerzett adatokkal frissíti, például távoli kiszolgálóról vagy aszinkron felhasználói hitelesítésből származó adatokat, az AdaptiveMediaSourceDownloadRequestedEventArgs.GetDeferral meghívásával lekérheti a halasztást, majd ha a művelet befejeződött, a rendszer jelezheti, hogy a letöltési kérelem művelete folytatódhat.
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;
}
}
A bitrátaesemények használata a változások kezelésére és azokra való reagálásra
Az AdaptiveMediaSource objektum olyan eseményeket biztosít, amelyek lehetővé teszik, hogy reagáljon a letöltési vagy lejátszási bitráták változásakor. Ebben a példában az aktuális bitráták egyszerűen frissülnek a felhasználói felületen. Vegye figyelembe, hogy módosíthatja azokat az arányokat, amelyek meghatározzák, hogy a rendszer mikor váltja át az adaptív stream bitrátáit. További információ: AdvancedSettings tulajdonság.
private void DownloadBitrateChanged(AdaptiveMediaSource sender, AdaptiveMediaSourceDownloadBitrateChangedEventArgs args)
{
DispatcherQueue.TryEnqueue(() =>
{
tbDownloadBitrate.Text = args.NewValue.ToString();
});
}
private void PlaybackBitrateChanged(AdaptiveMediaSource sender, AdaptiveMediaSourcePlaybackBitrateChangedEventArgs args)
{
DispatcherQueue.TryEnqueue(() =>
{
tbPlaybackBitrate.Text = args.NewValue.ToString();
});
}
Letöltési befejezési és hibaesemények kezelése
Az AdaptiveMediaSource objektum akkor aktiválja a DownloadFailed eseményt , ha a kért erőforrás letöltése meghiúsul. Az esemény használatával frissítheti a felhasználói felületet a hibára válaszul. Az esemény használatával statisztikai adatokat is naplózhat a letöltési műveletről és a hibáról.
Az eseménykezelőnek átadott AdaptiveMediaSourceDownloadFailedEventArgs objektum metaadatokat tartalmaz a sikertelen erőforrás-letöltésről, például az erőforrás típusáról, az erőforrás URI-járól és a stream azon pozíciójáról, ahol a hiba történt. A RequestId egy rendszer által generált egyedi azonosítót kap a kéréshez, amely felhasználható az egyes kérések állapotadatainak korrelálására több esemény között.
A Statistics tulajdonság egy AdaptiveMediaSourceDownloadStatistics objektumot ad vissza, amely részletes információkat nyújt az esemény időpontjában fogadott bájtok számáról és a letöltési művelet különböző mérföldköveinek időzítéséről. Ezeket az adatokat naplózhatja az adaptív streamelési implementáció teljesítményproblémáinak azonosítása érdekében.
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);
}
A DownloadCompleted esemény akkor következik be, amikor egy erőforrás letöltése befejeződik, és hasonló adatokat szolgáltat a DownloadFailed eseményhez. Ismét meg van adva egy RequestId , amely egyetlen kérelem eseményeinek korrelációját biztosítja. Emellett egy AdaptiveMediaSourceDownloadStatistics objektum is rendelkezésre áll a letöltési statisztikák naplózásának engedélyezéséhez.
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);
}
Adaptív streamelési telemetriai adatok gyűjtése az AdaptiveMediaSourceDiagnostics használatával
Az AdaptiveMediaSource egy Diagnosztikai tulajdonságot tesz elérhetővé, amely egy AdaptiveMediaSourceDiagnostics objektumot ad vissza. Ezzel az objektummal regisztrálhat a DiagnosticAvailable eseményre. Ez az esemény telemetriagyűjtésre szolgál, és nem használható az alkalmazások futásidőben történő viselkedésének módosítására. Ez a diagnosztikai esemény számos különböző okból merül fel. Ellenőrizze az eseménybe átadott DiagnosticType tulajdonságát az AdaptiveMediaSourceDiagnosticAvailableEventArgs objektumnak az esemény létrehozásának okának megállapításához. A lehetséges okok közé tartoznak a kért erőforráshoz való hozzáféréssel kapcsolatos hibák, valamint a streamelési jegyzékfájl elemzésével kapcsolatos hibák. A diagnosztikai eseményeket kiváltó helyzetek listáját az AdaptiveMediaSourceDiagnosticType című témakörben találja. A többi adaptív streamelési esemény argumentumaihoz hasonlóan az AdaptiveMediaSourceDiagnosticAvailableEventArgs egy RequestId tulajdonságot is biztosít a különböző események közötti kérésadatok korrelálására.
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);
}
Adaptív streamelési tartalom kötésének elhalasztása egy lejátszási lista elemeihez a MediaBinder használatával
A MediaBinder osztály lehetővé teszi a médiatartalmak kötésének elhalasztását a MediaPlaybackListben. A Windows 10 1703-as verziójától kezdve egy AdaptiveMediaSource-t is megadhat kötött tartalomként. Az adaptív médiaforrás késleltetett kötésének folyamata nagyrészt megegyezik a médiaelemekben , lejátszási listákban és zeneszámokban leírt más típusú médiatartalmak kötésével.
Hozzon létre egy MediaBinder-példányt, állítson be egy alkalmazás által definiált jogkivonat-sztringet a kötendő tartalom azonosításához, és regisztráljon a kötési eseményre. Hozzon létre egy MediaSource-t a Binderből a MediaSource.CreateFromMediaBinder meghívásával. Ezután hozzon létre egy MediaPlaybackItemet a MediaSource-ból , és adja hozzá a lejátszási listához.
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);
A Kötés eseménykezelőben használja a token sztringet a kötendő tartalom azonosítására, majd hozza létre a médiaforrást adaptív módon a CreateFromStreamAsync vagy a CreateFromUriAsync egyik túlterhelésének a meghívásával. Mivel ezek aszinkron metódusok, először hívja meg a MediaBindingEventArgs.GetDeferral metódust, hogy utasítsa a rendszert, hogy várja meg a művelet befejezését a folytatás előtt. Állítsa be az adaptív médiaforrást kötött tartalomként a SetAdaptiveMediaSource meghívásával. Végül hívja meg a Deferral.Complete parancsot a művelet befejezése után, hogy utasítsa a rendszert a folytatásra.
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();
}
Ha eseménykezelőket szeretne regisztrálni a kötött adaptív médiaforráshoz, ezt a MediaPlaybackListCurrentItemChanged eseményének kezelőjében teheti meg. A CurrentMediaPlaybackItemChangedEventArgs.NewItem tulajdonság tartalmazza az új jelenleg lejátszott MediaPlaybackItemet a listában. Szerezze be az új elemet képviselő AdaptiveMediaSource példányt úgy, hogy először hozzáfér a Forrás tulajdonságához a MediaPlaybackItem-nél, majd a médiaforrás AdaptiveMediaSource tulajdonságához. Ez a tulajdonság null értékű lesz, ha az új lejátszási elem nem AdaptiveMediaSource, ezért az objektum eseményeinek kezelőinek regisztrálása előtt tesztelje a null értéket.
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;
}
}
}
Kapcsolódó témakörök
Windows developer