ExoPlayerin puskurointistrategia
ExoPlayer-versio tutkittu: 2.9.6
Luokat, jotka toteuttavat LoadControl-rajapinnan, määrittelevät ExoPlayerin puskurointistrategian. Puskurointistrategia vastaa seuraavanlaisiin kysymyksiin:
- Tarvitseeko meidän ladata lisää mediatietoa?
- Onko meillä tarpeeksi mediatietoa toiston aloittamiseen?
Puskurointistrategia ei ole vastuussa puskureiden hallinnasta tai mediatiedon lataamisesta (se on MediaSource) tai mediatiedon toistamisesta (se on Renderer). Puskurointistrategia on riippumaton toistettavasta mediaformaatista, ja sillä on vain ”neuvoa-antava” rooli. Toisinaan voi käydä niin, että ExoPlayer ”kysyy” LoadControlilta, pitäisikö uutta mediatietoa ladata, ja jättää vastauksen huomiotta (esim. ExoPlayer on jo lataamassa mediatietoa).
ExoPlayerillä on oletustoteutus, DefaultLoadControl. Tämä on LoadControl-rajapinnan muokattavissa oleva toteutus.
DefaultLoadControlin avulla voidaan määrittää esimerkiksi :
- Kuinka monta millisekuntia (ms) mediatietoa ExoPlayerin tulisi puskuroida ennen toiston aloittamista (kutsutaan nimellä bufferForPlaybackMs). ExoPlayer aloittaa toiston heti, kun sillä on vähintään bufferForPlaybackMs mediadataa, vaikka ExoPlayer ei olisikaan puskuroinut koko segmenttiä kokonaan.
- Puskuroidun mediadatan vähimmäismäärä (millisekunteina), ennen kuin ExoPlayer alkaa ladata lisää dataa (kutsutaan minBufferMs).
- Mediatietojen enimmäismäärä (ms:ssä), joka ExoPlayerin pitäisi puskuroida, ennen kuin se pysähtyy lataamaan lisää (kutsutaan maxBufferMs).
- Miten monta millisekuntia mediatietoja ExoPlayerin pitäisi puskuroida, ennen kuin se aloittaa toiston uudelleen puskurointitapahtuman jälkeen (kutsutaan bufferForPlaybackAfterRebufferMs).
DefaultLoadControlilla on oletusarvot jokaiselle näistä asetuksista. V2.9:ssä.6 nämä arvot ovat:
bufferForPlaybackMs |
|
minBufferMs |
|
maxBufferMs |
|
bufferForPlaybackAfterRebufferMs |
Mutta, arvot vaihtelevat ExoPlayer-versiosta toiseen. Esimerkiksi ExoPlayer v2.7.3:n ja v2.8.0:n välillä videovirtojen maxBufferMs on muuttunut 30 sekunnista 50 sekuntiin.
ExoPlayerin modulaarinen arkkitehtuuri mahdollistaa myös oman puskurointistrategian toteuttamisen (joka toteuttaa LoadControl-rajapinnan) ja sen liittämisen ExoPlayeriin. Mutta se on toisen postauksen aihe.
Käynnistysajan alentaminen
ExoPlayerissä on helppo määrittää, kuinka paljon mediatietoa tarvitaan ennen toiston aloittamista. Tämän blogisarjan ensimmäisessä osassa korostimme käynnistymisajan merkitystä QoE-mittarina. Akamain vuonna 2016 julkaisemassa raportissa todettiin, että ”katsojat alkavat hylätä videon, jos käynnistys kestää yli kaksi sekuntia ennen toiston aloittamista, ja jokaista lisäsekuntia pidemmällä viiveellä noin 6 % katsojista lähtee pois. 10 sekunnin viiveellä lähes puolet katsojista on lähtenyt pois.”
ExoPlayerin versiossa 2.9.6 edellytetään, että oletusarvoisesti mediatietoa puskuroidaan 2,5 sekunnin verran, ennen kuin toisto aloitetaan. Käynnistysaikaa on mahdollista alentaa vaatimalla vähemmän puskuroitua dataa. Toisaalta mediadatan puskurointiarvon alentaminen johtaisi videon käynnistymisaikaa alentavaan vaikutukseen, mutta huonona puolena on kuitenkin se, että tämä saattaa johtaa myös uudelleenpuskurointimetriikan kasvuun käynnistyksen aikana.
Tämän blogisarjan ensimmäisessä osassa käytimme tutkakaaviota visualisoidaksemme erilaisten kompromissien vaikutuksen viiteen QoE-metriikkaan. Alla olevassa kaaviossa on esitetty vaikutus, joka aiheutuu siitä, että mediadatan vähimmäismäärää, joka vaaditaan ennen toiston aloittamista, alennetaan.
Koska bufferForPlaybackMs:n oletusarvo 2,5 sekuntia on konservatiivinen arvo, uskomme, että sen alentaminen on hyvä valinta.
Alhaalla olevassa kaaviossa näytetään vaikutus 3 Mbps:n nopeudella toimivan stream-virran käynnistymisaikaan, kun tämän konfigurointivaihtoehdon arvoa varioidaan (siinä ei oteta huomioon edestakaisen matkan kestoaikaa palvelimelle eikä sitäkään, joutuuko palvelimella noutamaan sisällön muualta). Esimerkiksi 4 Mbps:n yhteydellä, joka toistaa 3 Mbps:n streamia, ExoPlayerin konfigurointi aloittamaan toisto 1,5 sekunnin mediadatan puskuroinnin jälkeen tarkoittaa, että teoreettinen käynnistymisaika on 1,1 sekuntia sen sijaan, että se olisi 1,9 sekuntia, kun oletuskonfiguraatio puskuroi 2,5 sekunnin mediadatan.
Seuraavassa osiossa kerrotaan siitä, miten ExoPlayer voidaan konfiguroida niin, että se pienentää käynnistymisaikaa ja käden heilautusviivettä. Jos ExoPlayer ei ole sinulle tuttu, suosittelemme, että seuraat ensin Googlen Codelabs on Media streaming with ExoPlayer.
DefaultLoadControlin konfigurointi
Edellyttäen, että luot ExoPlayer-instanssin oletusarvoisella LoadControl-toteutuksella seuraavalla koodilla (tai vastaavalla):
ExoPlayer player = ExoPlayerFactory.newSimpleInstance(
new DefaultRenderersFactory(this),
new DefaultTrackSelector(),
new DefaultLoadControl())
Voit konfiguroida DefaultLoadControlin DefaultLoadControl.Builderin avulla:
/* Instantioi DefaultLoadControl.Builder. */
DefaultLoadControl.Builder builder = new DefaultLoadControl.Builder();
/* Millisekuntia mediatietoa puskuroidaan ennen toiston aloittamista tai jatkamista. */
final long loadControlStartBufferMs = 1500;
Konfiguroi uusi DefaultLoadControl käyttämään asetustamme sille, kuinka monta Millisekuntia mediatietoa on puskuroitava, ennen kuin toisto alkaa tai jatkuu käyttäjän toimintatapahtuman jälkeen.
builder.setBufferDurationMs(
DefaultLoadControl.DEFAULT MAX BUFFER MS,
loadControlStartBufferMs,
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS);
/* Rakenna varsinainen DefaultLoadControl-instanssi */
DefaultLoadControl loadControl = builder.createDefaultLoadControl();
/* Instantioi ExoPlayer konfiguroidulla DefaultLoadControlilla */
ExoPlayer player = ExoPlayerFactory.newSimpleInstance(
new DefaultRenderersFactory(this),
new DefaultTrackSelector(), loadControl);
VOD-sisällön uudelleenpuskurointimittareiden pienentäminen
Vähemmän käynnistymisaikaan johtavien asetusten määrittämisen lisäksi voit määrittää DefaultLoadControlilla, kuinka paljon mediatietoa puskuroidaan, mikä voi vaikuttaa VOD-sisällön uudelleenpuskurointimittareihin.
ExoPlayer v2.9.6 lataa oletusarvoisesti 50 sekunnin mediatiedot sisäiseen puskuriinsa, jos se voi (maxBufferMs-asetus). VOD-sisällön tapauksessa tämän arvon kasvattaminen antaa soittimelle enemmän tilaa käsitellä verkon kaistanleveyden vaihteluita ja pienentää rebufferointimittareita; haittapuolena on, että se lisää myös ExoPlayerin muistinkäyttöä. Muistinkäytön pitäminen alhaisena on tärkeää heikkolaatuisissa laitteissa. Toinen haittapuoli on kaistanleveyden hukkakäyttö, jos toisto pysähtyy ennenaikaisesti.
VOD-sisällön kokoonpanoosi parhaiten sopivan arvon löytämiseksi suosittelemme A/B-testien tekemistä konfigurointivaihtoehdon eri arvoilla, jotta löydetään arvo, joka antaa hyvän kompromissin rebufferointimäärän ja muistinkäytön välillä. Suosittelemme olemaan konservatiivisia ja nostamaan arvoa esim, 60 sekuntia aluksi sen selvittämiseksi, saadaanko sillä aikaan olennainen ero rebufferointimittareissa.
DefaultLoadControlin konfigurointi
Oletamme, että luot ExoPlayer-instanssin oletusarvoisella LoadControl-toteutuksella (kuten edellisessä kohdassa Käynnistysajan pienentäminen – DefaultLoadControlin konfigurointi on esitetty).
Voit määrittää DefaultLoadControlin käyttämällä DefaultLoadControl.Builder:
/* Instantioi DefaultLoadControl.Builder. */
DefaultLoadControl.Builder builder = new
DefaultLoadControl.Builder();
/* Puskuroitavan mediatiedon enimmäismäärä (millisekunteina). */
final long loadControlMaxBufferMs = 60000;
/*Konfiguroi DefaultLoadControl käyttämään asettamaamme asetusta siitä, kuinka monta
millisekuntia mediadataa puskuroidaan. */
builder.setBufferDurationsMs(
DefaultLoadcontrol.DEFAULT MIN BUFFER MS,
loadControlMaxBufferMs,
/* Käynnistysajan lyhentämiseksi muuta myös alla olevaa riviä */
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_MS,
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS);
/* Rakenna varsinainen DefaultLoadControl-instanssi */
DefaultLoadControl loadControl = builder.createDefaultLoadControl();
/* Instantioi ExoPlayer konfiguroidulla DefaultLoadControlilla */
ExoPlayer player = ExoPlayerFactory.newSimpleInstance(
new DefaultRenderersFactory(this),
new DefaultTrackSelector(),
loadControl);
Tapauksessa, jossa minBufferMs ja maxBufferMs ovat eri arvoja, ExoPlayer käyttäytyy pursuilevasti puskurin täyttämisessä. ExoPlayer puskuroi, kunnes se täyttää puskurinsa maxBufferMs:llä mediatiedolla, ja odottaa sitten, kunnes se pienenee minBufferMs:ään (koskee lähinnä VOD:ia). Kun puskuritaso laskee alle minBufferMs:n mediatietojen määrän, ExoPlayer alkaa ladata mediatietoja uudelleen, kunnes sillä on puskurissa maxBufferMs:n verran mediatietoja. Tällainen puskuroiva käyttäytyminen voi johtaa rebufferointiongelmiin. Tämä on oletuskäyttäytyminen ExoPlayer v2.9.6:ssa ja sitä edeltävissä versioissa, koska nämä arvot poikkeavat toisistaan. V2.9.6:ssa minBufferMs:n oletusarvo on 15000 ja maxBufferMs:n 50000.
Vähentääksesi entisestään uudelleenpuskurointimahdollisuuksia suosittelemme pitämään ExoPlayerissä aina suurta puskuria asettamalla minBufferMs:n samaksi arvoksi kuin maxBufferMs. ExoPlayer-tiimi on tehnyt kokeita ja havainnut, että minBufferMs:n asettaminen samaan arvoon kuin maxBufferMs (ja siten puskurointikäyttäytymisen muuttaminen bursty-käyttäytymisestä drip-tyyliseksi) vähensi merkittävästi rebufferointitapahtumia ja lisäsi samalla vain hieman akun käyttöä. Itse asiassa v2.10:stä alkaen ExoPlayerissä on videon käyttötapausta varten oletusarvo minBufferMs, joka on yhtä suuri kuin maxBufferMs ja asetettu arvoon 50s.
Miten konfiguroidaan DefaultLoadControl käyttäen DefaultLoadControl.Builderia:
/* Instantioi DefaultLoadControl.Builder. */
DefaultLoadControl.Builder builder = new
DefaultLoadControl.Builder();
/*Miten monta millisekuntia mediatietoa puskuroidaan milloinkin. */
final long loadControlBufferMs = DefaultloadControl.MAX_BUFFER_MS; /* Tämä on 50000 millisekuntia ExoPlayer 2.9.6:ssa */
/* Määritä DefaultLoadControl käyttämään samaa arvoa */
builderille.setBufferDurationMs(
loadControlBufferMs,
loadControlBufferMs,
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_MS,
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS);
Summary
LoadControl on ExoPlayerin puskurointistrategian aloituspiste. ExoPlayerin mukana tulee LoadControl-rajapinnan oletustoteutus, joka on kuitenkin konfiguroitavissa ja jonka pitäisi riittää useimpiin käyttötapauksiin.
Tähänastisten keskustelujen perusteella alla on lyhyt yhteenveto suosituksista:
- Käynnistymisaikaa lyhentääksesi alenna bufferForPlaybackMs:n arvoa; alenna siis käytännössä mediatiedon vähimmäismäärää, joka puskuroidaan, ennen kuin toisto alkaa. Tämän haittapuolena on mahdollinen uudelleenpuskurointitapahtumien määrän lisääntyminen.
- Vod-sisällön uudelleenpuskurointimittareiden vähentämiseksi nosta maxBufferMs:n arvoa; käytännössä lisää puskuroidun mediatiedon enimmäismäärää. Pidä kuitenkin mielessä, että tämä voi vaikuttaa negatiivisesti low-end-laitteisiin.
- Vähentääksesi uudelleenpuskurointimetriikoita aseta minBufferMs ja maxBufferMs samaan arvoon. Tämä muuttaa ExoPlayerin käyttäytymistä purskuvasta puskuroinnista tippuvaan puskurointiin.
Haluamme kiittää kollegojamme Christian Worm Mortensenia ja Laust Brock-Nannestadia palautteesta tämän postauksen kirjoittamisessa.
Seuraavassa blogikirjoituksessa tarkastelemme ExoPlayerin Bitrate-valintastrategiaa. Pysy kuulolla!