ExoPlayer’s Buffering Strategy
ExoPlayer Version undersøgt: 2.9.6
Klasser, der implementerer grænsefladen LoadControl, definerer ExoPlayer’s bufferingstrategi. Bufferingstrategien besvarer spørgsmål som:
- skal vi indlæse flere mediedata?
- har vi nok mediedata til at starte afspilningen?
Bufferingstrategien er ikke ansvarlig for forvaltning af buffere eller downloading af mediedata (det er MediaSource) eller afspilning af mediedata (det er Renderer). Bufferingstrategien er agnostisk i forhold til det medieformat, der afspilles, og har kun en “rådgivende” rolle. Det kan lejlighedsvis ske, at ExoPlayer “spørger” LoadControl, om der skal indlæses nye mediedata, og ignorerer svaret (f.eks. hvis ExoPlayer allerede er i gang med at hente mediedata).
ExoPlayer leveres med en standardimplementering, DefaultLoadControl. Dette er en implementering af LoadControl-grænsefladen, der kan tilpasses.
DefaultLoadControl kan bruges til at konfigurere f.eks. :
- Hvor mange millisekunder (ms) mediedata ExoPlayer skal buffe, før afspilningen starter (benævnt bufferForPlaybackMs). ExoPlayer starter afspilningen, så snart den har mindst bufferForPlaybackMs mediedata, selv om ExoPlayer ikke buffer hele segmentet fuldt ud.
- Den mindste mængde af bufferede mediedata (i ms), før ExoPlayer begynder at indlæse flere data (betegnet minBufferMs).
- Den maksimale mængde mediedata (i ms), som ExoPlayer skal buffer, før den stopper for at indlæse mere (benævnt maxBufferMs).
- Hvor mange millisekunder mediedata ExoPlayer skal buffe, før den genstarter afspilningen efter en rebuffering-hændelse (benævnt bufferForPlaybackAfterRebufferMs).
DefaultLoadControl har standardværdier for hver af disse indstillinger. I v2.9.6, er disse værdier:
bufferForPlaybackMs |
|
minBufferMs |
|
maxBufferMs |
|
bufferForPlaybackAfterRebufferMs |
Hvorimod, værdierne varierer fra ExoPlayer-version til version. F.eks. er maxBufferMs for videostrømme mellem ExoPlayer v2.7.3 og v2.8.0 ændret fra 30 sekunder til 50 sekunder.
ExoPlayers modulære arkitektur giver dig også mulighed for at implementere din egen bufferingstrategi (der implementerer LoadControl-grænsefladen) og sætte den ind i ExoPlayer. Men det er et emne til et andet indlæg.
Sænkning af opstartstiden
I ExoPlayer er det nemt at konfigurere, hvor mange mediedata der er brug for, før afspilningen startes. I den første del af denne blogserie fremhævede vi vigtigheden af starttid som en QoE-metrik. En rapport, som Akamai offentliggjorde i 2016, viste, at “seerne vil begynde at forlade en video, hvis opstarten tager længere end to sekunder at begynde afspilningen, og for hvert ekstra sekunds forsinkelse forlader ca. yderligere 6 % af publikum den. med en forsinkelse på 10 sekunder har næsten halvdelen af publikum forladt den.”
ExoPlayer version 2.9.6 kræver som standard 2,5 sekunders mediedata buffered før afspilningen påbegyndes. Det er muligt at sænke opstartstiden ved at kræve, at færre data skal være buffered. På den ene side vil en sænkning af værdien for buffering af mediedata resultere i en sænkning af videoens opstartstid, men ulempen er, at dette også kan resultere i en forøgelse af rebuffering-metrikken ved opstart.
I den første del af denne blogserie har vi brugt et radardiagram til at visualisere virkningen af de forskellige kompromisser på de 5 QoE-metrikker. Diagrammet nedenfor viser virkningen af at sænke den krævede minimumsmængde af mediedata, før afspilningen påbegyndes.
Da standardværdien for bufferForPlaybackMs på 2,5 sekunder er en konservativ værdi, mener vi, at det er et godt valg at sænke den.
Diagrammet nedenfor viser virkningen på opstartstiden for en 3 Mbps-stream, når man varierer værdien af denne konfigurationsindstilling (der tages ikke hensyn til rundrejsetiden til serveren, og heller ikke til, om serveren skal hente indholdet et andet sted fra). På en 4 Mbps-forbindelse, der afspiller en 3 Mbps-stream, betyder konfigurationen af ExoPlayer til at starte afspilningen efter at have bufferet 1,5 s mediedata, at den teoretiske opstartstid vil være på 1,1 s i stedet for 1,9 s med standardkonfigurationen med buffering af 2,5 s mediedata.
Det næste afsnit handler om, hvordan ExoPlayer kan konfigureres for at sænke opstartstiden og den håndviftende latenstid. Hvis du ikke er bekendt med ExoPlayer, anbefaler vi, at du først følger Googles Codelabs om mediestreaming med ExoPlayer.
Konfigurering af DefaultLoadControl
Antaget, at du opretter din ExoPlayer-instans med standard LoadControl-implementeringen ved hjælp af følgende kode (eller lignende):
ExoPlayer player = ExoPlayerFactory.newSimpleInstance(
new DefaultRenderersFactory(this),
new DefaultTrackSelector(),
new DefaultLoadControl())
Du kan konfigurere DefaultLoadControl ved hjælp af en DefaultLoadControl.Builder:
/* Instantiér en DefaultLoadControl.Builder. */
DefaultLoadControl.Builder builder = new DefaultLoadControl.Builder();
/* Millisekunder af mediedata, der bufferes, før afspilningen starter eller genoptages. */
final long loadControlStartBufferMs = 1500;Konfigurer den nye DefaultLoadControl til at bruge vores indstilling for, hvor mange millisekunder mediedata der skal bufferes, før afspilningen starter eller genoptages efter en brugeraktionshændelse.
builder.setBufferDurationMs(
DefaultLoadControl.DEFAULT MAX BUFFER MS,
loadControlStartBufferMs,
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS);
/* Opbyg den faktiske DefaultLoadControl-instans */
DefaultLoadControl loadControl = builder.createDefaultLoadControl();
/* Instantiér ExoPlayer med vores konfigurerede DefaultLoadControl */
ExoPlayer player = ExoPlayerFactory.newSimpleInstance(
new DefaultRenderersFactory(this),
new DefaultTrackSelector(), loadControl);Lowering Rebuffering Metrics for VOD Content
Ud over at konfigurere indstillinger, der fører til lavere opstartstid, kan du konfigurere DefaultLoadControl til at fastsætte, hvor mange mediedata der skal buffer, hvilket kan påvirke rebuffering metrics for VOD-indhold.
ExoPlayer v2.9.6 vil som standard indlæse 50 sekunders mediedata i sin interne buffer, hvis den kan (indstillingen maxBufferMs). I tilfælde af VOD-indhold vil en forøgelse af denne værdi give afspilleren mere plads til at håndtere udsving i netværksbåndbredden og lavere rebuffermålinger; ulempen er, at det også vil øge hukommelsesforbruget af ExoPlayer. Det er vigtigt at holde hukommelsesforbruget lavt på low-end enheder. En anden ulempe er spildt båndbreddeforbrug, hvis afspilningen stopper for tidligt.
For at finde den værdi, der fungerer bedst for din opsætning af VOD-indhold, anbefaler vi at lave A/B-test med forskellige værdier af konfigurationsindstillingen for at finde den, der giver et godt kompromis mellem rebuffering-hastigheder og hukommelsesforbrug. Vi anbefaler at være forsigtig ved at øge værdien til f.eks, 60 sekunder i første omgang for at finde ud af, om det giver en væsentlig forskel for rebufferingmetrikker.
Konfigurering af DefaultLoadControl
Vi antager, at du opretter din ExoPlayer-instans med standardloadControl-implementeringen (som vist i det foregående afsnit om sænkning af opstartstiden - konfiguration af DefaultLoadControl).
Du kan konfigurere DefaultLoadControl ved hjælp af en DefaultLoadControl.Builder:
/* Instantier en DefaultLoadControl.Builder. */
DefaultLoadControl.Builder builder = new
DefaultLoadControl.Builder();
/* Maksimal mængde mediedata, der skal gemmes i buffer (i millisekunder). */
final long loadControlMaxBufferMs = 60000;
/*Konfigurer DefaultLoadControl til at bruge vores indstilling for, hvor mange
Millisekunder mediedata der skal gemmes i buffer. */
builder.setBufferDurationsMs(
DefaultLoadcontrol.DEFAULT MIN BUFFER MS,
loadControlMaxBufferMs,
/*For at reducere opstartstiden skal du også ændre linjen nedenfor */
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_MS,
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS);
/* Opbyg den egentlige DefaultLoadControl-instans */
DefaultLoadControl loadControl = builder.createDefaultLoadControl();
/* Instantiér ExoPlayer med vores konfigurerede DefaultLoadControl */
ExoPlayer player = ExoPlayerFactory.newSimpleInstance(
new DefaultRenderersFactory(this),
new DefaultTrackSelector(),
loadControl);Hvis minBufferMs og maxBufferMs har forskellige værdier, vil ExoPlayer have en burstet adfærd, der fylder bufferen op igen. ExoPlayer vil buffere, indtil bufferen er fyldt op med maxBufferMs mediedata, og derefter vente, indtil den falder til minBufferMs (gælder primært for VOD). Når bufferniveauet falder til under minBufferMs mediedata, vil ExoPlayer begynde at indlæse mediedata igen, indtil den har en buffer på maxBufferMs mediedata. En sådan burst-adfærd kan føre til problemer med rebuffering. Dette er standardadfærden i ExoPlayer v2.9.6 og tidligere, da disse værdier er forskellige. I v2.9.6 har minBufferMs en standardværdi på 15000 og maxBufferMs er 50000.
For yderligere at reducere chancerne for rebuffering anbefaler vi at opretholde en stor buffer i ExoPlayer til enhver tid ved at indstille minBufferMs til den samme værdi som maxBufferMs. ExoPlayer-holdet har udført eksperimenter og fundet ud af, at indstillingen af minBufferMs til samme værdi som maxBufferMs (og dermed ændring af bufferadfærden fra bursty til drip-stil) reducerede rebuffering-hændelser betydeligt, mens batteriforbruget kun steg en smule. Faktisk har ExoPlayer fra og med v2.10 for videoanvendelsestilfælde standard minBufferMs lig med maxBufferMs og indstillet til 50s.
Sådan konfigureres DefaultLoadControl ved hjælp af en DefaultLoadControl.Builder:
/* Instantiér en DefaultLoadControl.Builder. */
DefaultLoadControl.Builder builder = new
DefaultLoadControl.Builder();
/*Hvor mange millisekunder mediedata, der skal bufferes på et hvilket som helst tidspunkt. */
final long loadControlBufferMs = DefaultloadControl.MAX_BUFFER_MS; /* Dette er 50000 millisekunder i ExoPlayer 2.9.6 */
/* Konfigurer DefaultLoadControl til at bruge den samme værdi for */
builder.setBufferDurationMs(
loadControlBufferMs,
loadControlBufferMs,
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_MS,
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS);Summary
LoadControl er indgangspunktet til ExoPlayers bufferingstrategi. ExoPlayer leveres med en standard, men konfigurerbar implementering af LoadControl-grænsefladen, der bør være tilstrækkelig til de fleste anvendelsestilfælde.
Baseret på de hidtidige diskussioner er der nedenfor en hurtig opsummering af anbefalingerne:
- For at reducere opstartstiden skal du sænke værdien af bufferForPlaybackMs; effektivt sænker du den minimale mængde mediedata, der bufferes, før du starter afspilningen. Dette har den ulempe, at det potentielt øger antallet af rebuffering-hændelser.
- For at reducere rebuffering-metrikken for VOD-indhold skal du øge værdien af maxBufferMs; effektivt øge den maksimale mængde af mediedata, der bufferes. Husk dog, at det kan have en negativ indvirkning på low-end-enheder.
- For at reducere rebufferingmetrikken skal du indstille minBufferMs og maxBufferMs til den samme værdi. Dette vil ændre ExoPlayers opførsel fra en bursty til en drip-style buffering.
Vi vil gerne takke vores kolleger Christian Worm Mortensen og Laust Brock-Nannestad for feedback i forbindelse med skrivningen af dette indlæg.
I det næste blogindlæg vil vi se på ExoPlayers Bitrate Selection Strategy. Stay tuned!