Estrategia de almacenamiento en búfer de ExoPlayer

Versión de ExoPlayer investigada: 2.9.6

Las clases que implementan la interfaz LoadControl definen la estrategia de almacenamiento en búfer de ExoPlayer. La estrategia de almacenamiento en búfer responde a preguntas como:

  • ¿Necesitamos cargar más datos de los medios de comunicación?
  • ¿Tenemos suficientes datos de los medios de comunicación para iniciar la reproducción?

La estrategia de almacenamiento en búfer no es responsable de la gestión de los búferes o la descarga de los datos de los medios de comunicación (que es el MediaSource), o la reproducción de los datos de los medios de comunicación (que es el Renderer). La estrategia de almacenamiento en búfer es agnóstica al formato de los medios que se reproducen y sólo tiene un papel «consultivo». Ocasionalmente puede ocurrir que ExoPlayer «pregunte» al LoadControl si se deben cargar nuevos datos multimedia, e ignore la respuesta (por ejemplo, ExoPlayer ya está en proceso de descarga de datos multimedia).

ExoPlayer viene con una implementación por defecto, DefaultLoadControl. Se trata de una implementación personalizable de la interfaz LoadControl.

DefaultLoadControl puede utilizarse para configurar, por ejemplo :

  • Cuántos milisegundos (ms) de datos multimedia debe almacenar ExoPlayer en el búfer antes de iniciar la reproducción (denominado bufferForPlaybackMs). ExoPlayer iniciará la reproducción tan pronto como tenga al menos bufferForPlaybackMs de datos de medios, incluso si ExoPlayer no almacenó completamente el segmento completo en el buffer.
  • La cantidad mínima de datos de medios almacenados en el buffer (en ms) antes de que ExoPlayer comience a cargar más datos (referido como minBufferMs).
  • La cantidad máxima de datos multimedia (en ms) que ExoPlayer debe almacenar en el búfer antes de detenerse para cargar más (referido como maxBufferMs).
  • Cuántos milisegundos de datos multimedia debe almacenar ExoPlayer en el búfer antes de reiniciar la reproducción después de un evento de rebuffering (referido como bufferForPlaybackAfterRebufferMs).

DefaultLoadControl tiene valores por defecto para cada uno de estos ajustes. En la v2.9.6, estos valores son:

bufferForPlaybackMs

minBufferMs

maxBufferMs

bufferForPlaybackAfterRebufferMs

Sin embargo, los valores varían de una versión de ExoPlayer a otra. Por ejemplo, entre ExoPlayer v2.7.3 y v2.8.0, el maxBufferMs para los flujos de vídeo ha cambiado de 30 a 50 segundos.

La arquitectura modular de ExoPlayer también le permite implementar su propia estrategia de almacenamiento en búfer (que implementa la interfaz LoadControl) y conectarla a ExoPlayer. Pero ese es un tema para otro post.

Bajando el tiempo de inicio

En ExoPlayer, es fácil configurar cuántos datos multimedia se necesitan antes de iniciar la reproducción. En la primera parte de esta serie de blogs, destacamos la importancia del tiempo de inicio como métrica de QoE. Un informe que Akamai publicó en 2016 descubrió que «los espectadores comenzarán a abandonar un vídeo si el inicio tarda más de dos segundos en comenzar a reproducirse y por cada segundo adicional de retraso, aproximadamente un 6% adicional de la audiencia se va. con un retraso de 10 segundos, casi la mitad de la audiencia se ha ido».

La versión 2.9.6 de ExoPlayer requiere por defecto 2,5 segundos de datos de los medios en el buffer antes de iniciar la reproducción. Es posible bajar el tiempo de inicio requiriendo menos datos en el buffer. Por un lado, la reducción del valor del búfer de datos de los medios de comunicación daría lugar a la reducción del tiempo de inicio de vídeo, sin embargo, el inconveniente es que esto también podría resultar en el aumento de las métricas de rebote en el inicio.

En la primera parte de esta serie de blogs, hemos utilizado un gráfico de radar para visualizar el impacto de las diferentes compensaciones en las 5 métricas de QoE. El siguiente gráfico muestra el impacto de reducir la cantidad mínima requerida de datos multimedia antes de iniciar la reproducción.

mejorando uno.pngComo el valor por defecto de bufferForPlaybackMs de 2,5 segundos es un valor conservador, creemos que es una buena opción bajarlo.

El gráfico siguiente muestra el impacto en el tiempo de inicio para un flujo de 3 Mbps cuando se varía el valor de esta opción de configuración (sin tener en cuenta el tiempo de ida y vuelta al servidor, ni si el servidor tiene que buscar el contenido desde otro lugar). Por ejemplo, en una conexión de 4 Mbps que reproduce un flujo de 3 Mbps, configurar ExoPlayer para que inicie la reproducción después de almacenar en el búfer 1,5s de datos multimedia significa que el tiempo de inicio teórico será de 1,1s, en lugar de los 1,9s con la configuración por defecto de almacenar en el búfer 2,5s de datos multimedia.

mejorando dos.pngLa siguiente sección habla de cómo configurar ExoPlayer para reducir el tiempo de inicio y la latencia de la mano. Si no estás familiarizado con ExoPlayer, te recomendamos que primero sigas los Codelabs de Google sobre Media streaming with ExoPlayer.

Configurar el DefaultLoadControl

Suponiendo que creas tu instancia de ExoPlayer con la implementación de LoadControl por defecto usando el siguiente código (o similar):

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

Puedes configurar el DefaultLoadControl utilizando un DefaultLoadControl.Builder:

/* Instanciar un DefaultLoadControl.Builder. */
DefaultLoadControl.Builder = new DefaultLoadControl.Builder();
/* Milisegundos de datos multimedia almacenados en el buffer antes de que se inicie o reanude la reproducción. */
final long loadControlStartBufferMs = 1500;

Configura el nuevo DefaultLoadControl para que utilice nuestra configuración de cuántos milisegundos de datos multimedia deben almacenarse en el búfer antes de que se inicie o reanude la reproducción tras un evento de acción del usuario.

builder.setBufferDurationMs(
DefaultLoadControl.DEFAULT MAX BUFFER MS,
loadControlStartBufferMs,
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS);
/* Construye la instancia real de DefaultLoadControl */
DefaultLoadControl loadControl = builder.createDefaultLoadControl();
/* Instanciar ExoPlayer con nuestro DefaultLoadControl configurado */
ExoPlayer player = ExoPlayerFactory.newSimpleInstance(
new DefaultRenderersFactory(this),
new DefaultTrackSelector(), loadControl);

Disminución de las métricas de rebufo para el contenido VOD

Además de configurar los ajustes que conducen a un menor tiempo de inicio, puede configurar el DefaultLoadControl para establecer la cantidad de datos de los medios de comunicación para el búfer, lo que puede afectar a las métricas de rebufo para el contenido VOD.

ExoPlayer v2.9.6 cargará por defecto 50 segundos de datos multimedia en su buffer interno si puede (el ajuste maxBufferMs). En el caso del contenido VOD, el aumento de este valor dará al reproductor más espacio para manejar las fluctuaciones en el ancho de banda de la red y las métricas de rebote más bajas; la desventaja es que también aumentará el uso de la memoria de ExoPlayer. Mantener el uso de la memoria bajo es importante en los dispositivos de gama baja. Otra desventaja es el uso de ancho de banda desperdiciado en caso de que la reproducción se detenga prematuramente.

Para encontrar el valor que funciona mejor para su configuración de contenido VOD, recomendamos hacer pruebas A/B con varios valores de la opción de configuración para encontrar el que da un buen equilibrio entre las tasas de rebuffering y el uso de la memoria. Recomendamos ser conservador aumentando el valor a, por ejemplo 60 segundos inicialmente para averiguar si proporciona una diferencia material para las métricas de rebuffering.

Configuración del DefaultLoadControl

Suponemos que usted crea su instancia de ExoPlayer con la implementación del LoadControl por defecto (como se muestra en la sección anterior sobre la reducción del tiempo de inicio – Configuración del DefaultLoadControl).

Puedes configurar el DefaultLoadControl utilizando un DefaultLoadControl.Builder:

/* Instanciar un DefaultLoadControl.Builder. */
DefaultLoadControl.Builder = new
DefaultLoadControl.Builder();
/* Cantidad máxima de datos multimedia a almacenar en el búfer (en milisegundos). */
final long loadControlMaxBufferMs = 60000;
/*Configurar el DefaultLoadControl para que utilice nuestra configuración de cuántos
Milisegundos de datos multimedia debe almacenar en el búfer. */
builder.setBufferDurationsMs(
DefaultLoadcontrol.DEFAULT MIN BUFFER MS,
loadControlMaxBufferMs,
/*Para reducir el tiempo de arranque, también hay que cambiar la línea de abajo */
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_MS,
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS);
/* Construye la instancia real de DefaultLoadControl */
DefaultLoadControl loadControl = builder.createDefaultLoadControl();
/* Instanciar ExoPlayer con nuestro DefaultLoadControl configurado */
ExoPlayer player = ExoPlayerFactory.newSimpleInstance(
new DefaultRenderersFactory(this),
new DefaultTrackSelector(),
loadControl);

En caso de que minBufferMs y maxBufferMs tengan valores diferentes, ExoPlayer tendrá un comportamiento bursty rellenando el buffer. ExoPlayer rellenará el buffer hasta que llene su buffer con maxBufferMs de datos multimedia, luego esperará hasta que disminuya a minBufferMs (principalmente aplicable a VOD). Una vez que el nivel del búfer caiga por debajo de minBufferMs de datos multimedia, ExoPlayer comenzará a cargar datos multimedia de nuevo hasta que tenga un búfer con un valor de maxBufferMs de datos multimedia. Este comportamiento de ráfaga puede dar lugar a problemas de rebote. Este es el comportamiento por defecto en ExoPlayer v2.9.6 y anteriores, ya que estos valores difieren. En la versión 2.9.6, minBufferMs tiene un valor predeterminado de 15000 y maxBufferMs es de 50000.

Para reducir aún más las posibilidades de rebufo, recomendamos mantener un búfer grande en ExoPlayer en todo momento, estableciendo minBufferMs al mismo valor que maxBufferMs. El equipo de ExoPlayer ha llevado a cabo experimentos y ha comprobado que establecer minBufferMs al mismo valor que maxBufferMs (y, por lo tanto, cambiar el comportamiento del búfer de ráfaga a estilo de goteo) redujo significativamente los eventos de rebuffering, a la vez que aumentó sólo ligeramente el uso de la batería. De hecho, a partir de la v2.10, ExoPlayer tiene para el caso de uso de vídeo el minBufferMs por defecto igual a maxBufferMs y establecido en 50s.

Cómo configurar el DefaultLoadControl usando un DefaultLoadControl.Builder:

/* Instanciar un DefaultLoadControl.Builder. */
DefaultLoadControl.Builder = new
DefaultLoadControl.Builder();
/*Cuántos milisegundos de datos multimedia hay que almacenar en el buffer en cada momento. */
final long loadControlBufferMs = DefaultloadControl.MAX_BUFFER_MS; /* Esto es 50000 milisegundos en ExoPlayer 2.9.6 */
/* Configurar el DefaultLoadControl para utilizar el mismo valor para */
builder.setBufferDurationMs(
loadControlBufferMs,
loadControlBufferMs,
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_MS,
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS);

Summary

LoadControl es el punto de entrada a la estrategia de buffering de ExoPlayer. ExoPlayer viene con una implementación predeterminada, aunque configurable, de la interfaz LoadControl que debería ser suficiente para la mayoría de los casos de uso.

En base a lo discutido hasta ahora, a continuación se presenta un resumen rápido de las recomendaciones:

  1. Para reducir el tiempo de inicio, disminuya el valor de bufferForPlaybackMs; efectivamente, disminuyendo la cantidad mínima de datos multimedia almacenados en el buffer antes de comenzar la reproducción. Esto tiene la desventaja de aumentar potencialmente el número de eventos de rebuffering.
  2. Para reducir las métricas de rebuffering para el contenido VOD, aumentar el valor de maxBufferMs; aumentando efectivamente la cantidad máxima de datos de los medios de comunicación en el buffer. Sin embargo, tenga en cuenta que puede afectar negativamente a los dispositivos de gama baja.
  3. Para reducir las métricas de rebuffering, establezca minBufferMs y maxBufferMs al mismo valor. Esto cambiará el comportamiento de ExoPlayer de un buffering de ráfaga a uno de goteo.

Nos gustaría agradecer a nuestros colegas Christian Worm Mortensen y Laust Brock-Nannestad por sus comentarios al escribir esta entrada.

En la próxima entrada del blog, veremos la estrategia de selección de bitrate de ExoPlayer. Esté atento a ello.

Deja una respuesta

Tu dirección de correo electrónico no será publicada.