ExoPlayers buffringsstrategi
ExoPlayer-versionen undersökt: 2.9.6
Klasser som implementerar gränssnittet LoadControl definierar ExoPlayers buffringsstrategi. Bufferstrategin svarar på frågor som:
- måste vi ladda mer mediedata?
- Har vi tillräckligt med mediedata för att starta uppspelningen?
Bufferstrategin ansvarar inte för hantering av buffertar eller nedladdning av mediedata (det är MediaSource), eller uppspelning av mediedata (det är Renderer). Bufferstrategin är agnostisk i förhållande till det mediaformat som spelas upp och har endast en ”rådgivande” roll. Det kan ibland hända att ExoPlayer ”frågar” LoadControl om nya mediedata ska laddas och ignorerar svaret (t.ex. om ExoPlayer redan håller på att ladda ner mediedata).
ExoPlayer levereras med en standardimplementation, DefaultLoadControl. Detta är en anpassningsbar implementering av gränssnittet LoadControl.
DefaultLoadControl kan användas för att konfigurera t.ex. :
- Hur många millisekunder (ms) mediedata ExoPlayer ska buffra innan uppspelning påbörjas (benämns bufferForPlaybackMs). ExoPlayer startar uppspelningen så snart den har minst bufferForPlaybackMs mediedata, även om ExoPlayer inte buffrade hela segmentet fullt ut.
- Den minsta mängden buffrade mediedata (i ms) innan ExoPlayer börjar läsa in mer data (kallas minBufferMs).
- Den maximala mängden mediedata (i ms) som ExoPlayer ska buffra innan den slutar ladda mer (kallas maxBufferMs).
- Hur många millisekunder mediedata ExoPlayer ska buffra innan den startar uppspelningen på nytt efter en ombuffringshändelse (kallas bufferForPlaybackAfterRebufferMs).
DefaultLoadControl har standardvärden för var och en av dessa inställningar. I v2.9.6 är dessa värden:
bufferForPlaybackMs |
|
minBufferMs |
|
maxBufferMs |
|
bufferForPlaybackAfterRebufferMs |
Hur som helst, värdena varierar från ExoPlayer-version till version. Mellan ExoPlayer v2.7.3 och v2.8.0 har t.ex. maxBufferMs för videoströmmar ändrats från 30 sekunder till 50 sekunder.
ExoPlayers modulära arkitektur gör det också möjligt att implementera en egen buffringsstrategi (som implementerar gränssnittet LoadControl) och ansluta den till ExoPlayer. Men det är ett ämne för ett annat inlägg.
Sänka starttiden
I ExoPlayer är det enkelt att konfigurera hur mycket mediedata som behövs innan uppspelningen startar. I den första delen av den här bloggserien lyfte vi fram betydelsen av starttid som en QoE-mätare. I en rapport som Akamai publicerade 2016 konstaterades att ”tittarna börjar överge en video om det tar längre tid än två sekunder att starta uppspelningen och för varje ytterligare sekund av fördröjning lämnar ungefär ytterligare 6 % av publiken. med en fördröjning på 10 sekunder har nästan halva publiken lämnat”.
ExoPlayer version 2.9.6 kräver som standard 2,5 sekunders mediedata som buffras innan uppspelningen påbörjas. Det är möjligt att sänka starttiden genom att kräva att mindre data buffras. Å ena sidan skulle en sänkning av värdet för buffring av mediedata resultera i en sänkning av starttiden för video, men nackdelen är att detta också kan resultera i en ökning av mätvärdena för ombuffring vid start.
I den första delen av den här bloggserien har vi använt oss av ett radardiagram för att visualisera effekten av de olika kompromisserna på de fem mätvärdena för kvalitetsoförmåga. Diagrammet nedan visar effekten av att sänka den minsta mängd mediedata som krävs innan uppspelning påbörjas.
Med tanke på att standardvärdet för bufferForPlaybackMs på 2,5 sekunder är ett konservativt värde anser vi att det är ett bra val att sänka det.
Den nedanstående grafen visar påverkan på uppstartstiden för en 3 Mbps-ström när man varierar värdet för det här konfigurationsalternativet (utan att ta hänsyn till tur- och returtiden till servern, och inte heller till om servern måste hämta innehållet från annat håll). Till exempel, på en 4 Mbps-anslutning som spelar upp en 3 Mbps-ström, innebär konfigurering av ExoPlayer för att starta uppspelningen efter att ha buffrat 1,5s mediedata att den teoretiska starttiden blir 1,1s, i stället för 1,9s med standardkonfigurationen för buffring av 2,5s mediedata.
Nästkommande avsnitt handlar om hur ExoPlayer kan konfigureras för att sänka starttiden och handlänkningslatensiteten. Om du inte är bekant med ExoPlayer rekommenderar vi att du först följer Googles Codelabs on Media streaming with ExoPlayer.
Konfigurera DefaultLoadControl
Antag att du skapar din ExoPlayer-instans med standardimplementationen LoadControl med hjälp av följande kod (eller liknande):
ExoPlayer player = ExoPlayerFactory.newSimpleInstance(
new DefaultRenderersFactory(this),
new DefaultTrackSelector(),
new DefaultLoadControl())
Du kan konfigurera DefaultLoadControl med hjälp av en DefaultLoadControl.Builder:
/* Instantiera en DefaultLoadControl.Builder. */
DefaultLoadControl.Builder builder = new DefaultLoadControl.Builder();
/* Millisekunder av mediedata som buffras innan uppspelningen startar eller återupptas. */
final long loadControlStartBufferMs = 1500;Konfigurera den nya DefaultLoadControl så att den använder vår inställning för hur många millisekunder mediedata som måste buffras innan uppspelningen startar eller återupptas efter en användarhändelse.
builder.setBufferDurationMs(
DefaultLoadControl.DEFAULT MAX BUFFER MS,
loadControlStartBufferMs,
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS);
/* Bygger upp den faktiska instansen av DefaultLoadControl */
DefaultLoadControl loadControl = builder.createDefaultLoadControl();
/* Instantiera ExoPlayer med vår konfigurerade DefaultLoadControl */
ExoPlayer player = ExoPlayerFactory.newSimpleInstance(
new DefaultRenderersFactory(this),
new DefaultTrackSelector(), loadControl);Sänkning av mätvärden för ombuffring av VOD-innehåll
Bortsett från att konfigurera inställningar som leder till kortare starttid kan du konfigurera DefaultLoadControl för att fastställa hur mycket mediedata som ska buffertas, vilket kan påverka mätvärden för ombuffring av VOD-innehåll.
ExoPlayer v2.9.6 kommer som standard att ladda 50 sekunder mediedata i sin interna buffert om det går (inställningen maxBufferMs). När det gäller VOD-innehåll ger en ökning av det här värdet spelaren mer utrymme att hantera fluktuationer i nätverksbandbredden och lägre mätvärden för ombuffring; nackdelen är att det också ökar minnesanvändningen av ExoPlayer. Det är viktigt att hålla minnesanvändningen låg på enheter med låg kapacitet. En annan nackdel är slöseri med bandbredd om uppspelningen slutar i förtid.
För att hitta det värde som fungerar bäst för din inställning av VOD-innehåll rekommenderar vi att du gör A/B-tester med olika värden för konfigurationsalternativet för att hitta det som ger en bra kompromiss mellan rebuffering-frekvens och minnesanvändning. Vi rekommenderar att du är försiktig genom att öka värdet till t.ex, 60 sekunder inledningsvis för att ta reda på om det ger en väsentlig skillnad för mätvärdena för ombuffring.
Konfigurera DefaultLoadControl
Vi antar att du skapar din ExoPlayer-instans med standardimplementationen av LoadControl (enligt vad som visades i det föregående avsnittet om att sänka starttiden - konfigurera DefaultLoadControl).
Du kan konfigurera DefaultLoadControl med hjälp av en DefaultLoadControl.Builder:
/* Installera en DefaultLoadControl.Builder. */
DefaultLoadControl.Builder builder = new
DefaultLoadControl.Builder();
/* Maximalt antal mediedata att buffra (i millisekunder). */
final long loadControlMaxBufferMs = 60000;
/*Konfigurera DefaultLoadControl så att den använder vår inställning för hur många
millisekunder mediedata som ska buffras. */
builder.setBufferDurationsMs(
DefaultLoadcontrol.DEFAULT MIN BUFFER MS,
loadControlMaxBufferMs,
/*För att minska uppstartstiden ändrar du också raden nedan */
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_MS,
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS);
/* Bygg den egentliga instansen av DefaultLoadControl */
DefaultLoadControl loadControl = builder.createDefaultLoadControl();
/* Instantiera ExoPlayer med vår konfigurerade DefaultLoadControl */
ExoPlayer player = ExoPlayerFactory.newSimpleInstance(
new DefaultRenderersFactory(this),
new DefaultTrackSelector(),
loadControl);Om minBufferMs och maxBufferMs har olika värden kommer ExoPlayer att ha ett burstigt beteende som fyller på bufferten. ExoPlayer kommer att buffra tills bufferten fylls med maxBufferMs mediedata och sedan vänta tills den minskar till minBufferMs (gäller främst VOD). När buffertnivån sjunker under minBufferMs med mediedata kommer ExoPlayer att börja ladda mediedata igen tills den har en buffert värd maxBufferMs med mediedata. Ett sådant burstbeteende kan leda till problem med ombuffring. Detta är standardbeteendet i ExoPlayer v2.9.6 och tidigare, eftersom dessa värden skiljer sig åt. I v2.9.6 har minBufferMs ett standardvärde på 15000 och maxBufferMs är 50000.
För att ytterligare minska risken för ombuffring rekommenderar vi att du alltid behåller en stor buffert i ExoPlayer genom att ställa in minBufferMs till samma värde som maxBufferMs. ExoPlayer-teamet har gjort experiment och funnit att om man ställer in minBufferMs till samma värde som maxBufferMs (och därmed ändrar buffertbeteendet från bursty till drip-style) så minskar ombuffringen avsevärt, samtidigt som batterianvändningen bara ökar något. Faktum är att ExoPlayer från och med v2.10 har för videoanvändningsfallet standardvärdet minBufferMs som är lika med maxBufferMs och inställt på 50s.
Hur man konfigurerar DefaultLoadControl med hjälp av en DefaultLoadControl.Builder:
/* Instansiera en DefaultLoadControl.Builder. */
DefaultLoadControl.Builder builder = new
DefaultLoadControl.Builder();
/*Hur många millisekunder mediedata som ska buffras vid varje tidpunkt. */
final long loadControlBufferMs = DefaultloadControl.MAX_BUFFER_MS; /* Detta är 50000 millisekunder i ExoPlayer 2.9.6 */
/* Konfigurera DefaultLoadControl så att samma värde används för */
builder.setBufferDurationMs(
loadControlBufferMs,
loadControlBufferMs,
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_MS,
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS);Sammanfattning
LoadControl är ingångspunkten till ExoPlayers buffringsstrategi. ExoPlayer levereras med en standard, men konfigurerbar implementering av gränssnittet LoadControl som bör vara tillräcklig för de flesta användningsfall.
Baserat på diskussionerna hittills är nedan en snabb sammanfattning av rekommendationerna:
- För att minska uppstartstiden kan du sänka värdet på bufferForPlaybackMs; i praktiken sänker du den minsta mängden mediedata som buffras innan du startar uppspelningen. Detta har nackdelen att det potentiellt ökar antalet ombuffringshändelser.
- För att minska ombuffringsmätningarna för VOD-innehåll, öka värdet på maxBufferMs; i praktiken ökar den maximala mängden mediedata som buffras. Tänk dock på att det kan ha en negativ inverkan på enheter med låg kapacitet.
- För att minska antalet ombuffringar kan du ställa in minBufferMs och maxBufferMs till samma värde. Detta kommer att ändra ExoPlayers beteende från en bursty till en drip-style buffring.
Vi vill tacka våra kollegor Christian Worm Mortensen och Laust Brock-Nannestad för feedback vid skrivandet av det här inlägget.
I nästa blogginlägg kommer vi att titta på ExoPlayers strategi för val av bitrate. Håll ögonen öppna!