ExoPlayer est couramment utilisé pour diffuser des contenus multimédias en streaming sur Internet. Il accepte plusieurs piles réseau pour effectuer ses requêtes réseau sous-jacentes. Le choix de la pile réseau peut avoir un impact significatif sur les performances des flux.
Cette page explique comment configurer ExoPlayer pour utiliser la pile réseau de votre choix, liste les options disponibles, fournit des conseils sur le choix d'une pile réseau pour votre application et explique comment activer la mise en cache pour les contenus multimédias diffusés en streaming.
Configurer ExoPlayer pour utiliser une pile réseau spécifique
ExoPlayer charge les données via les composants DataSource
, qu'il obtient à partir d'instances DataSource.Factory
injectées à partir du code de l'application.
Si votre application a uniquement besoin de lire du contenu HTTP, sélectionner une pile réseau est aussi simple que de mettre à jour les instances DataSource.Factory
injectées par votre application pour en faire des instances de HttpDataSource.Factory
correspondant à la pile réseau que vous souhaitez utiliser. Si votre application doit également lire du contenu autre que HTTP, comme des fichiers locaux, utilisez DefaultDataSource.Factory
:
Kotlin
DefaultDataSource.Factory( ... /* baseDataSourceFactory= */ PreferredHttpDataSource.Factory(...))
Java
new DefaultDataSource.Factory( ... /* baseDataSourceFactory= */ new PreferredHttpDataSource.Factory(...));
Dans cet exemple, PreferredHttpDataSource.Factory
est la fabrique correspondant à votre pile réseau préférée. La couche DefaultDataSource.Factory
prend en charge les sources autres que HTTP, telles que les fichiers locaux.
L'exemple suivant montre comment créer un ExoPlayer
qui utilise la pile réseau Cronet et prend également en charge la lecture de contenu autre que HTTP.
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();
Piles réseau compatibles
ExoPlayer est directement compatible avec Cronet, OkHttp et la pile réseau intégrée d'Android. ExoPlayer peut également être étendu pour prendre en charge toute autre pile réseau fonctionnant sur Android.
Cronet
Cronet est la pile réseau Chromium mise à la disposition des applications Android en tant que bibliothèque. Cronet tire parti de plusieurs technologies qui réduisent la latence et augmentent le débit des requêtes réseau dont votre application a besoin pour fonctionner, y compris celles effectuées par ExoPlayer. En natif, il est compatible avec les protocoles HTTP, HTTP/2 et HTTP/3 via les protocoles QUIC. Cronet est utilisé par certaines des plus grandes applications de streaming au monde, y compris YouTube.
ExoPlayer est compatible avec Cronet via sa bibliothèque Cronet.
Consultez le fichier README.md
de la bibliothèque pour obtenir des instructions détaillées sur son utilisation. Notez que la bibliothèque Cronet peut utiliser trois implémentations Cronet sous-jacentes:
- Services Google Play:nous vous recommandons d'utiliser cette implémentation dans la plupart des cas et de revenir à la pile réseau intégrée à Android (
DefaultHttpDataSource
) si les services Google Play ne sont pas disponibles. - Cronet intégré:peut être un bon choix si un grand pourcentage de vos utilisateurs se trouvent sur des marchés où les services Google Play ne sont pas largement disponibles ou si vous souhaitez contrôler la version exacte de l'implémentation Cronet utilisée. Le principal inconvénient de Cronet Embedded est qu'il ajoute environ 8 Mo à votre application.
- Cronet de remplacement:l'implémentation de remplacement de Cronet implémente l'API de Cronet en tant que wrapper autour de la pile réseau intégrée à Android. Il ne doit pas être utilisé avec ExoPlayer, car il est plus efficace d'utiliser directement la pile réseau intégrée d'Android (en utilisant
DefaultHttpDataSource
).
OkHttp
OkHttp est une autre pile réseau moderne largement utilisée par de nombreuses applications Android populaires. Il est compatible avec HTTP et HTTP/2, mais pas encore avec HTTP/3 sur QUIC.
ExoPlayer est compatible avec OkHttp via sa bibliothèque OkHttp.
Consultez le fichier README.md
de la bibliothèque pour obtenir des instructions détaillées sur son utilisation. Lorsque vous utilisez la bibliothèque OkHttp, la pile réseau est intégrée à l'application. Cette méthode est semblable à Cronet Embedded, mais OkHttp est considérablement plus petite, ajoutant moins de 1 Mo à votre application.
Pile réseau intégrée à Android
ExoPlayer est compatible avec l'utilisation de la pile réseau intégrée d'Android avec DefaultHttpDataSource
et DefaultHttpDataSource.Factory
, qui font partie de la bibliothèque principale d'ExoPlayer.
L'implémentation exacte de la pile réseau dépend du logiciel exécuté sur l'appareil sous-jacent. Sur la plupart des appareils (depuis 2021), seul HTTP est pris en charge (HTTP/2 et HTTP/3 sur QUIC ne le sont pas).
Autres piles réseau
Les applications peuvent également intégrer d'autres piles réseau avec ExoPlayer.
Pour ce faire, implémentez un HttpDataSource
qui encapsule la pile réseau avec un HttpDataSource.Factory
correspondant. Les bibliothèques Cronet et OkHttp d'ExoPlayer sont de bons exemples de la façon de procéder.
Lors de l'intégration à une pile réseau en Java pur, il est recommandé d'implémenter un DataSourceContractTest
pour vérifier que votre implémentation de HttpDataSource
se comporte correctement. OkHttpDataSourceContractTest
dans la bibliothèque OkHttp est un bon exemple de la façon de procéder.
Choisir une pile réseau
Le tableau suivant présente les avantages et les inconvénients des piles réseau compatibles avec ExoPlayer.
Pile réseau | Protocoles | Impact sur la taille de l'APK | Notes |
---|---|---|---|
Cronet (services Google Play) | HTTP HTTP/2 HTTP/3 sur QUIC |
Petite (< 100 Ko) |
Nécessite les services Google Play. Mise à jour automatique de la version Cronet |
Cronet (intégré) | HTTP HTTP/2 HTTP/3 sur QUIC |
Grand (~8 Mo) |
Version Cronet contrôlée par le développeur de l'application |
Cronet (valeur de remplacement) | HTTP (selon l'appareil) |
Petite (< 100 Ko) |
Non recommandé pour ExoPlayer |
OkHttp | HTTP HTTP/2 |
Petit (< 1 Mo) |
Nécessite un environnement d'exécution Kotlin |
Pile réseau intégrée | HTTP (selon l'appareil) |
Aucune | L'implémentation varie selon l'appareil |
Les protocoles HTTP/2 et HTTP/3 sur QUIC peuvent améliorer considérablement les performances du streaming multimédia. En particulier, lors de la diffusion de contenus multimédias adaptatifs distribués à l'aide d'un réseau de distribution de contenu (CDN), l'utilisation de ces protocoles permet parfois aux CDN de fonctionner beaucoup plus efficacement. Pour cette raison, la compatibilité de Cronet avec HTTP/2 et HTTP/3 via QUIC (et la compatibilité d'OkHttp avec HTTP/2) est un avantage majeur par rapport à l'utilisation de la pile réseau intégrée d'Android, à condition que les serveurs sur lesquels le contenu est hébergé soient également compatibles avec ces protocoles.
Lorsque vous envisagez de diffuser des contenus multimédias de manière isolée, nous vous recommandons d'utiliser Cronet fourni par les services Google Play, en revenant à DefaultHttpDataSource
si les services Google Play ne sont pas disponibles. Cette recommandation offre un bon compromis entre l'activation de HTTP/2 et du HTTP/3 sur la plupart des appareils via QUIC, tout en évitant une augmentation significative de la taille de l'APK. Il existe des exceptions à cette recommandation. Dans les cas où les services Google Play risquent d'être indisponibles sur une part significative des appareils qui exécutent votre application, il peut être plus approprié d'utiliser Cronet Embedded ou OkHttp. L'utilisation de la pile réseau intégrée peut être acceptable si la taille de l'APK est un problème critique ou si le streaming multimédia ne constitue qu'une partie mineure des fonctionnalités de votre application.
Au-delà des contenus multimédias, il est généralement judicieux de choisir une seule pile réseau pour toute la mise en réseau effectuée par votre application. Cela permet de mettre efficacement en commun et à partager des ressources (telles que les sockets) entre ExoPlayer et les autres composants de l'application.
Étant donné que votre application devra probablement être mise en réseau sans être liée à la lecture de contenus multimédias, votre choix de pile réseau doit au final tenir compte de nos recommandations ci-dessus pour le streaming multimédia de manière isolée, des exigences de tous les autres composants qui assurent la mise en réseau et de leur importance relative pour votre application.
Mise en cache du contenu multimédia
ExoPlayer prend en charge la mise en cache des octets chargés sur le disque pour empêcher le chargement répété des mêmes octets depuis le réseau. Cela est utile lorsque vous revenez en arrière dans le contenu multimédia actuel ou lorsque vous répétez le même élément.
La mise en cache nécessite une instance SimpleCache
pointant vers un répertoire de cache dédié et 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();