ExoPlayer se usa comúnmente para transmitir contenido multimedia por Internet. Admite o en varias pilas de red para realizar las solicitudes de red subyacentes. Tu elección de la pila de red puede tener un impacto significativo en el rendimiento de la transmisión.
En esta página, se describe cómo configurar ExoPlayer para usar tu pila de red opción, enumera las opciones disponibles, proporciona orientación sobre cómo elegir una pila de red para tu app y explica cómo habilitar el almacenamiento en caché para las transmisiones medios de comunicación.
Cómo configurar ExoPlayer para usar una pila de red específica
ExoPlayer carga datos a través de componentes DataSource
, que obtiene de
Instancias DataSource.Factory
que se insertan desde el código de la app.
Si tu app solo necesita reproducir contenido http(s), selecciona una red
es tan simple como actualizar cualquier instancia de DataSource.Factory
que
La app inserta como instancias de HttpDataSource.Factory
.
que corresponda a la pila de red que quieres usar. Si tu app también
necesita reproducir contenido que no sea http(s), como archivos locales, usar
DefaultDataSource.Factory
:
Kotlin
DefaultDataSource.Factory( ... /* baseDataSourceFactory= */ PreferredHttpDataSource.Factory(...))
Java
new DefaultDataSource.Factory( ... /* baseDataSourceFactory= */ new PreferredHttpDataSource.Factory(...));
En este ejemplo, PreferredHttpDataSource.Factory
es la fábrica que corresponde a tu
en la pila de red preferida. La capa DefaultDataSource.Factory
agrega compatibilidad.
para fuentes que no son HTTP, como archivos locales.
En el siguiente ejemplo, se muestra cómo compilar un ExoPlayer
que use Cronet
pila de red y también admitir la reproducción de contenido que no sea HTTP(S).
Kotlin
// Given a CronetEngine and Executor, build a CronetDataSource.Factory. val cronetDataSourceFactory = CronetDataSource.Factory(cronetEngine, executor) // Wrap the CronetDataSource.Factory in a DefaultDataSource.Factory, which adds // in support for requesting data from other sources (such as files, resources, // etc). val dataSourceFactory = DefaultDataSource.Factory(context, /* baseDataSourceFactory= */ cronetDataSourceFactory) // Inject the DefaultDataSource.Factory when creating the player. val player = ExoPlayer.Builder(context) .setMediaSourceFactory( DefaultMediaSourceFactory(context).setDataSourceFactory(dataSourceFactory) ) .build()
Java
// Given a CronetEngine and Executor, build a CronetDataSource.Factory. CronetDataSource.Factory cronetDataSourceFactory = new CronetDataSource.Factory(cronetEngine, executor); // Wrap the CronetDataSource.Factory in a DefaultDataSource.Factory, which adds // in support for requesting data from other sources (such as files, resources, // etc). DefaultDataSource.Factory dataSourceFactory = new DefaultDataSource.Factory( context, /* baseDataSourceFactory= */ cronetDataSourceFactory); // Inject the DefaultDataSource.Factory when creating the player. ExoPlayer player = new ExoPlayer.Builder(context) .setMediaSourceFactory( new DefaultMediaSourceFactory(context).setDataSourceFactory(dataSourceFactory)) .build();
Pilas de red compatibles
ExoPlayer brinda compatibilidad directa con HttpEngine, Cronet, OkHttp y Android una pila de red predeterminada integrada. ExoPlayer también se puede extender para admitir cualquier y otra pila de red que funcione en Android.
HttpEngine
HttpEngine es la pila de red predeterminada recomendada en Android a partir del nivel de API 34 (o S extensiones 7). En la mayoría de los casos, usa la pila de red de Cronet de forma interna. que admite HTTP, HTTP/2 y HTTP/3 a través de protocolos QUIC.
ExoPlayer admite HttpEngine con su HttpEngineDataSource.Factory
. Puedes
inyecta esta fábrica de fuente de datos como se describe en Cómo configurar ExoPlayer para usar un
una pila de red específica.
Cronet
Cronet es el La pila de red de Chromium está disponible como biblioteca para las apps para Android. Cronet toma de aprovechar múltiples tecnologías que reducen la latencia y aumentan la de procesamiento de las solicitudes de red que tu app necesita para funcionar, incluidas las de ExoPlayer. Es compatible de forma nativa con HTTP, HTTP/2 y HTTP/3 a través de QUIC. protocolos. Cronet es usado por algunas de las apps de streaming más grandes del mundo, incluido YouTube.
ExoPlayer admite Cronet a través de su
Biblioteca Cronet.
Consulta la README.md
de la biblioteca para obtener instrucciones detalladas sobre cómo usarla
que la modifica. Ten en cuenta que la biblioteca Cronet puede usar tres Cronet subyacentes
implementaciones:
- Servicios de Google Play: Recomendamos usar esta implementación en la mayoría de
y recurrir a la pila de red integrada de Android
(
DefaultHttpDataSource
) si los Servicios de Google Play no están disponibles. - Cronet Embed: puede ser una buena opción si un gran porcentaje de tus usuarios están en mercados donde los Servicios de Google Play no están ampliamente disponibles o si quiere controlar la versión exacta de la implementación de Cronet que se utiliza. El Una gran desventaja de Cronet Embedded es que agrega aproximadamente 8 MB a tu app.
- Resguardo de Cronet: La implementación de resguardo de Cronet implementa
La API de Cronet como wrapper de la pila de red integrada de Android. Debe
no debe usarse con ExoPlayer, ya que usar la pila de red integrada de Android
directamente (mediante
DefaultHttpDataSource
) es más eficiente.
OkHttp
OkHttp es otra pila de red moderna que se usa ampliamente en muchas apps de Android populares. Admite HTTP y HTTP/2, pero aún no es compatible con HTTP/3 a través de QUIC.
ExoPlayer admite OkHttp a través de su
Biblioteca OkHttp.
Consulta la README.md
de la biblioteca para obtener instrucciones detalladas sobre cómo usarla
que la modifica. Cuando se usa la biblioteca OkHttp, la pila de red está incorporada en el
. Esto es similar a Cronet Embedded, pero OkHttp es
más pequeña, lo que agregará menos de 1 MB a tu app.
Pila de red integrada de Android
ExoPlayer admite el uso de la pila de red integrada de Android con
DefaultHttpDataSource
y DefaultHttpDataSource.Factory
, que son parte de
la biblioteca principal de ExoPlayer.
La implementación exacta de la pila de red depende del software que se ejecute en el dispositivo subyacente. En la mayoría de los dispositivos, solo se admite HTTP (es decir, no se admiten HTTP/2 ni HTTP/3 a través de QUIC).
Otras pilas de red
Las apps también pueden integrar otras pilas de red con ExoPlayer.
Para ello, implementa un HttpDataSource
que una la pila de red.
junto con un HttpDataSource.Factory
correspondiente. Cronet de ExoPlayer y
Las bibliotecas OkHttp son buenos ejemplos de cómo hacerlo.
Cuando se realiza la integración con una pila de red pura de Java, se recomienda implementar una
DataSourceContractTest
para verificar que tu implementación de HttpDataSource
se comporte correctamente. OkHttpDataSourceContractTest
de la biblioteca OkHttp es una
un buen ejemplo de cómo hacerlo.
Cómo elegir una pila de red
En la siguiente tabla, se describen los pros y los contras de las pilas de red que admiten ExoPlayer
Pila de red | Protocolos | Impacto del tamaño de APK | Notas |
---|---|---|---|
HttpEngine | HTTP HTTP/2 HTTP/3 a través de QUIC |
Ninguno | Solo disponible en el nivel de API 34 o S extensiones 7 |
Cronet (Servicios de Google Play) | HTTP HTTP/2 HTTP/3 a través de QUIC |
Pequeño (<100 KB) |
Requiere los Servicios de Google Play. Actualización automática de la versión de Cronet |
Cronet (incorporado) | HTTP HTTP/2 HTTP/3 a través de QUIC |
Grande (~8 MB) |
El desarrollador de la app controla la versión de Cronet |
Cronet (resguardo) | HTTP (varía según el dispositivo) |
Pequeño (<100 KB) |
No se recomienda para ExoPlayer |
OkHttp | HTTP HTTP/2 |
Pequeño (<1 MB) |
|
Pila de red integrada | HTTP (varía según el dispositivo) |
Ninguno | La implementación varía según el dispositivo |
Los protocolos HTTP/2 y HTTP/3 a través de QUIC pueden mejorar significativamente los medios y el rendimiento de la transmisión. En particular, cuando se transmite contenido multimedia adaptable distribuida mediante una red de distribución de contenido (CDN), existen casos de qué uso de estos protocolos permite que las CDN funcionen de forma mucho más eficiente. Por este motivo, la compatibilidad de HttpEngine y Cronet con HTTP/2 y HTTP/3 sobre QUIC (y la compatibilidad de OkHttp con HTTP/2), es un beneficio importante en comparación con con la pila de red incorporada de Android, siempre que los servidores en los que el contenido alojado también es compatible con estos protocolos.
Cuando se considera la transmisión de contenido multimedia de forma aislada, recomendamos el uso de HttpEngine o
Cronet proporcionada por los Servicios de Google Play volverá a DefaultHttpDataSource
si los Servicios de Google Play no están disponibles. Esta recomendación tiene una buena falta
Equilibrio entre habilitar el uso de HTTP/2 y HTTP/3 a través de QUIC en la mayoría de los dispositivos y
lo que evita un aumento significativo en el tamaño del APK. Existen excepciones
recomendación. En los casos en los que es probable que los Servicios de Google Play no estén disponibles
en una fracción significativa
de los dispositivos que ejecutan tu app
puede ser más adecuado utilizar Cronet Embedded u OkHttp. Uso de la función
la pila de red puede ser aceptable si el tamaño del APK es una preocupación importante
la transmisión es solo una parte menor de la funcionalidad de la app.
Más allá de solo los medios, es una buena idea elegir una sola pila de red para todas las redes que realiza tu app. Esto permite que los recursos (como sockets) para agrupar y compartir de manera eficiente entre ExoPlayer y otros componentes de la aplicación.
Porque es probable que tu app necesite establecer redes de contactos para la reproducción de contenido multimedia, la pila de red que elijas recomendaciones anteriores para la transmisión de contenido multimedia aislada, los requisitos de cualquier otros componentes que realizan redes y su importancia relativa para .
Almacenamiento en caché de contenido multimedia
ExoPlayer admite el almacenamiento en caché de bytes cargados en el disco para evitar la carga repetida los mismos bytes de la red. Esto es útil cuando se retrocede en el modo multimedia o repetir el mismo elemento.
El almacenamiento en caché requiere una instancia SimpleCache
que apunte a una caché dedicada
y un CacheDataSource.Factory
:
Kotlin
// Note: This should be a singleton in your app. val databaseProvider = StandaloneDatabaseProvider(context) // An on-the-fly cache should evict media when reaching a maximum disk space limit. val cache = SimpleCache( downloadDirectory, LeastRecentlyUsedCacheEvictor(maxBytes), databaseProvider) // Configure the DataSource.Factory with the cache and factory for the desired HTTP stack. val cacheDataSourceFactory = CacheDataSource.Factory() .setCache(cache) .setUpstreamDataSourceFactory(httpDataSourceFactory) // Inject the DefaultDataSource.Factory when creating the player. val player = ExoPlayer.Builder(context) .setMediaSourceFactory( DefaultMediaSourceFactory(context).setDataSourceFactory(cacheDataSourceFactory)) .build()
Java
// Note: This should be a singleton in your app. DatabaseProvider databaseProvider = new StandaloneDatabaseProvider(context); // An on-the-fly cache should evict media when reaching a maximum disk space limit. Cache cache = new SimpleCache( downloadDirectory, new LeastRecentlyUsedCacheEvictor(maxBytes), databaseProvider); // Configure the DataSource.Factory with the cache and factory for the desired HTTP stack. DataSource.Factory cacheDataSourceFactory = new CacheDataSource.Factory() .setCache(cache) .setUpstreamDataSourceFactory(httpDataSourceFactory); // Inject the DefaultDataSource.Factory when creating the player. ExoPlayer player = new ExoPlayer.Builder(context) .setMediaSourceFactory( new DefaultMediaSourceFactory(context).setDataSourceFactory(cacheDataSourceFactory)) .build();