ExoPlayer’s Buffering Strategy

ExoPlayer Version Investigated: 2.9.6

A LoadControl interfészt implementáló osztályok határozzák meg az ExoPlayer pufferelési stratégiáját. A pufferelési stratégia olyan kérdésekre ad választ, mint:

  • Még több médiaadatot kell betöltenünk?
  • Elég médiaadatunk van a lejátszás megkezdéséhez?

A pufferelési stratégia nem felelős a pufferek kezeléséért vagy a médiaadatok letöltéséért (ez a MediaSource), vagy a médiaadatok lejátszásáért (ez a Renderer). A pufferelési stratégia agnosztikus a lejátszott médiaformátumtól, és csak “tanácsadó” szerepe van. Alkalmanként előfordulhat, hogy az ExoPlayer “megkérdezi” a LoadControlt, hogy új médiaadatokat kell-e betölteni, és figyelmen kívül hagyja a választ (pl. az ExoPlayer már a médiaadatok letöltésének folyamatában van).

Az ExoPlayer alapértelmezett implementációval, a DefaultLoadControlnal érkezik. Ez a LoadControl interfész testreszabható implementációja.

AzDefaultLoadControl segítségével beállítható pl. :

  • Hány milliszekundum (ms) médiaadatot puffereljen az ExoPlayer a lejátszás megkezdése előtt (a továbbiakban: bufferForPlaybackMs). Az ExoPlayer akkor is megkezdi a lejátszást, ha legalább bufferForPlaybackMs médiaadattal rendelkezik, még akkor is, ha az ExoPlayer nem pufferelte le teljesen a teljes szegmenst.
  • A pufferelt médiaadatok minimális mennyisége (ms-ban), mielőtt az ExoPlayer további adatok betöltését kezdi meg (a továbbiakban minBufferMs).
  • A médiaadatok maximális mennyisége (ms-ban), amelyet az ExoPlayernek pufferelnie kell, mielőtt megáll további adatok betöltésére (a továbbiakban maxBufferMs).
  • Hány milliszekundumnyi médiaadatot kell pufferelnie az ExoPlayernek, mielőtt újraindítja a lejátszást egy újrapufferelési esemény után (a továbbiakban bufferForPlaybackAfterRebufferMs).

Az

DefaultLoadControl alapértelmezett értékeket tartalmaz minden ilyen beállításhoz. A v2.9.6-ban ezek az értékek a következők:

.

bufferForPlaybackMs

minBufferMs

maxBufferMs

bufferForPlaybackAfterRebufferMs

However, az értékek ExoPlayer-verzióról verzióra változnak. Például az ExoPlayer v2.7.3 és v2.8.0 között a videostreamek maxBufferMs értéke 30 másodpercről 50 másodpercre változott.

Az ExoPlayer moduláris felépítése azt is lehetővé teszi, hogy saját (a LoadControl interfészt megvalósító) pufferelési stratégiát implementáljon, és azt az ExoPlayerhez csatlakoztassa. De ez egy másik bejegyzés témája.

Az indítási idő csökkentése

Az ExoPlayerben könnyen beállítható, hogy mennyi médiaadat szükséges a lejátszás megkezdése előtt. E blogsorozat első részében rávilágítottunk az indítási idő mint QoE-mérőszám fontosságára. Az Akamai 2016-ban közzétett jelentése szerint “a nézők elkezdik elhagyni a videót, ha a lejátszás megkezdése két másodpercnél tovább tart, és minden további másodperc késedelem esetén a nézők további nagyjából 6%-a távozik. 10 másodperces késedelem esetén a nézők közel fele távozott.”

Az ExoPlayer 2.9.6-os verziója alapértelmezés szerint 2,5 másodpercnyi médiaadatot igényel pufferelve a lejátszás megkezdése előtt. Lehetőség van az indítási idő csökkentésére azáltal, hogy kevesebb adatot kell pufferelni. A médiaadat-pufferelés értékének csökkentése egyrészt a videó indítási idejének csökkenését eredményezné, azonban a hátránya az, hogy ez az indításkori pufferelési metrikák növekedését is eredményezheti.

E blogsorozat első részében radardiagramot használtunk a különböző kompromisszumok 5 QoE-metrikára gyakorolt hatásának szemléltetésére. Az alábbi diagram a lejátszás megkezdése előtt minimálisan szükséges médiaadatmennyiség csökkentésének hatását mutatja.

enhancing one.pngMivel a bufferForPlaybackMs alapértelmezett 2,5 másodperces értéke konzervatív érték, úgy véljük, hogy jó választás az érték csökkentése.

A lenti grafikon azt mutatja, hogy milyen hatással van egy 3 Mbps sebességű adatfolyam indítási idejére, ha ennek a konfigurációs opciónak az értékét változtatjuk (nem vesszük figyelembe a kiszolgálóhoz való körutazási időt, sem azt, hogy a kiszolgálónak máshonnan kell-e lekérnie a tartalmat). Például egy 3 Mbps-os streamet lejátszó 4 Mbps-os kapcsolat esetén, ha az ExoPlayert úgy konfiguráljuk, hogy a lejátszás 1,5s médiaadat pufferelése után kezdődjön, az elméleti indítási idő 1,1s lesz, a 2,5s médiaadat pufferelését biztosító alapértelmezett konfiguráció 1,9s helyett.

enhancing two.pngA következő szakasz arról szól, hogyan konfigurálhatjuk az ExoPlayert az indítási idő és a kézzel integető késleltetés csökkentése érdekében. Ha nem ismeri az ExoPlayert, javasoljuk, hogy először kövesse a Google Codelabs on Media streaming with ExoPlayer című cikkét.

A DefaultLoadControl konfigurálása

Tételezzük fel, hogy az ExoPlayer példányt az alapértelmezett LoadControl implementációval hozza létre a következő (vagy hasonló) kóddal:

ExoPlayer player = ExoPlayerFactory.newSimpleInstance(
new DefaultRenderersFactory(this),
new DefaultTrackSelector(),
new DefaultLoadControl())

A DefaultLoadControlt egy DefaultLoadControl.Builder segítségével konfigurálhatja:

/* Instanciate a DefaultLoadControl.Builder. */
DefaultLoadControl.Builder builder = new DefaultLoadControl.Builder();
/* A lejátszás megkezdése vagy folytatása előtt pufferelt médiaadatok milliszekunduma. */
final long loadControlStartBufferMs = 1500;

Konfiguráljuk az új DefaultLoadControlt, hogy a mi beállításunkat használja arra vonatkozóan, hogy hány milliszekundumnyi médiaadatot kell pufferelni a lejátszás megkezdése vagy folytatása előtt egy felhasználói műveleti esemény után.

builder.setBufferDurationMs(
DefaultLoadControl.DEFAULT MAX BUFFER MS,
loadControlStartBufferMs,
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS);
/* A tényleges DefaultLoadControl példány létrehozása */
DefaultLoadControl loadControl = builder.createDefaultLoadControl();
/* Az ExoPlayer instanciálása a konfigurált DefaultLoadControl-unkkal */
ExoPlayer player = ExoPlayerFactory.newSimpleInstance(
new DefaultRenderersFactory(this),
new DefaultTrackSelector(), loadControl);

VOD-tartalmak újrapufferelési mérőszámainak csökkentése

Az alacsonyabb indítási időt eredményező beállítások konfigurálásán kívül a DefaultLoadControlt úgy is beállíthatja, hogy meghatározza, mennyi médiaadatot kell pufferelni, ami hatással lehet a VOD-tartalmak újrapufferelési mérőszámaira.

AzExoPlayer v2.9.6 alapértelmezés szerint 50 másodperc médiaadatot tölt be a belső pufferébe, ha képes rá (a maxBufferMs beállítás). VOD-tartalmak esetén ennek az értéknek a növelése nagyobb teret ad a lejátszónak a hálózati sávszélesség ingadozásainak kezelésére és alacsonyabb rebufferelési mérőszámokat eredményez; hátránya, hogy az ExoPlayer memóriahasználatát is növeli. A memóriahasználat alacsony szinten tartása fontos a kis teljesítményű eszközökön. Egy másik hátránya az elpazarolt sávszélesség-használat, ha a lejátszás idő előtt leáll.

A VOD-tartalmak beállításához legjobban megfelelő érték megtalálásához javasoljuk, hogy végezzen A/B-tesztelést a konfigurációs opció különböző értékeivel, hogy megtalálja azt, amelyik jó kompromisszumot biztosít az újrapufferelési arányok és a memóriahasználat között. Javasoljuk, hogy legyünk konzervatívak, és növeljük az értéket például a következő értékre, 60 másodpercet, hogy kiderüljön, hogy ez lényeges különbséget jelent-e az újrapufferelési mérőszámok tekintetében.

A DefaultLoadControl konfigurálása

Feltételezzük, hogy az ExoPlayer-példányt az alapértelmezett LoadControl implementációval hozza létre (amint azt az Indítási idő csökkentése – A DefaultLoadControl konfigurálása című előző szakaszban bemutattuk).

A DefaultLoadControlt egy DefaultLoadControl.Builder segítségével konfigurálhatja:

/* Instanciate a DefaultLoadControl.Builder. */
DefaultLoadControl.Builder builder = new
DefaultLoadControl.Builder();
/* A pufferelendő médiaadatok maximális mennyisége (milliszekundumban). */
final long loadControlMaxBufferMs = 60000;
/*Konfiguráljuk a DefaultLoadControlt úgy, hogy a mi beállításunkat használja, hogy hány
Milliszekundumnyi médiaadatot kell pufferelni. */
builder.setBufferDurationsMs(
DefaultLoadcontrol.DEFAULT MIN BUFFER MS,
loadControlMaxBufferMs,
/*Az indítási idő csökkentése érdekében módosítsuk az alábbi sort is */
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_MS,
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS);
/* A tényleges DefaultLoadControl példány felépítése */
DefaultLoadControl loadControl = builder.createDefaultLoadControl();
/* Az ExoPlayer instanciálása a konfigurált DefaultLoadControl-unkkal */
ExoPlayer player = ExoPlayerFactory.newSimpleInstance(
new DefaultRenderersFactory(this),
new DefaultTrackSelector(),
loadControl);

Ha a minBufferMs és maxBufferMs értékek eltérnek, akkor az ExoPlayer bursty viselkedéssel tölti újra a puffert. Az ExoPlayer addig pufferel, amíg meg nem tölti a pufferét maxBufferMs médiaadatokkal, majd megvárja, amíg az a minBufferMs értékre csökken (főként VOD esetén alkalmazható). Amint a puffer szintje a minBufferMs médiaadatszint alá csökken, az ExoPlayer újra elkezdi a médiaadatok betöltését, amíg a puffer maxBufferMs médiaadatot nem ér. Az ilyen bursty viselkedés rebuffering problémákhoz vezethet. Ez az ExoPlayer v2.9.6 és korábbi verzióiban ez az alapértelmezett viselkedés, mivel ezek az értékek eltérnek. A v2.9.6-ban a minBufferMs alapértelmezett értéke 15000, a maxBufferMs pedig 50000.

Az újrapufferelési esélyek további csökkentése érdekében javasoljuk, hogy az ExoPlayerben mindig nagy puffert tartson fenn, a minBufferMs értékét a maxBufferMs értékével azonos értékre állítva. Az ExoPlayer csapata kísérleteket végzett, és azt tapasztalta, hogy a minBufferMs beállítása a maxBufferMs értékével azonos értékre (és így a pufferelési viselkedés megváltoztatása bursty-ről drip-style-ra) jelentősen csökkentette az újrapufferelési eseményeket, miközben csak kis mértékben növelte az akkumulátorhasználatot. Valójában a v2.10-től kezdve az ExoPlayer a videó felhasználási esethez az alapértelmezett minBufferMs egyenlő a maxBufferMs értékkel és 50s-re van állítva.

How to configure the DefaultLoadControl using a DefaultLoadControl.Builder:

/* Instantiate a DefaultLoadControl.Builder. */
DefaultLoadControl.Builder builder = new
DefaultLoadControl.Builder();
/*Hány milliszekundumnyi médiaadatot kell bármikor pufferelni. */
final long loadControlBufferMs = DefaultloadControl.MAX_BUFFER_MS; /* Ez az ExoPlayer 2.9.6-ban 50000 milliszekundum */
/* A DefaultLoadControl konfigurálása, hogy ugyanazt az értéket használja */
builder.setBufferDurationMs(
loadControlBufferMs,
loadControlBufferMs,
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_MS,
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS);

Summary

A LoadControl az ExoPlayer pufferelési stratégiájának belépési pontja. Az ExoPlayer a LoadControl interfész alapértelmezett, de konfigurálható implementációjával érkezik, amely a legtöbb felhasználási esethez elegendőnek kell lennie.

Az eddigi megbeszélések alapján az alábbiakban röviden összefoglaljuk az ajánlásokat:

  1. Az indítási idő csökkentése érdekében csökkentse a bufferForPlaybackMs értékét; gyakorlatilag csökkentse a lejátszás megkezdése előtt pufferelt médiaadatok minimális mennyiségét. Ez azzal a hátránnyal jár, hogy potenciálisan növeli az újrapufferelési események számát.
  2. A VOD-tartalmak újrapufferelési metrikájának csökkentéséhez növelje a maxBufferMs értékét; gyakorlatilag növelje a pufferelt médiaadatok maximális mennyiségét. Ne feledje azonban, hogy ez negatívan befolyásolhatja a kis teljesítményű eszközöket.
  3. Az újrapufferelési metrikák csökkentéséhez állítsa a minBufferMs és a maxBufferMs értékét ugyanarra az értékre. Ez megváltoztatja az ExoPlayer viselkedését a bursty-ről a drip-style pufferelésre.

Köszönjük kollégáinknak, Christian Worm Mortensennek és Laust Brock-Nannestadnak a visszajelzéseket a bejegyzés megírásához.

A következő blogbejegyzésben az ExoPlayer bitrátaválasztási stratégiáját fogjuk megvizsgálni. Maradjanak velünk!

Vélemény, hozzászólás?

Az e-mail-címet nem tesszük közzé.