Piles réseau

ExoPlayer est couramment utilisé pour diffuser des contenus multimédias en streaming sur Internet. Compatible plusieurs piles réseau pour effectuer ses requêtes réseau sous-jacentes. À vous de choisir de la pile réseau peut avoir un impact significatif sur les performances de streaming.

Cette page explique comment configurer ExoPlayer pour utiliser votre pile réseau de les options disponibles, et fournit des conseils sur la façon de choisir une pile réseau pour votre application et explique comment activer la mise en cache pour les diffusions médias.

Configurer ExoPlayer pour utiliser une pile réseau spécifique

ExoPlayer charge les données via les composants DataSource, qu'il obtient à partir de Instances DataSource.Factory injectées à partir du code de l'application.

Si votre application a uniquement besoin de lire du contenu http(s), sélectionnez un réseau la pile est aussi simple que de mettre à jour les instances DataSource.Factory que votre l'application injecte pour être des instances de HttpDataSource.Factory. correspondant à la pile réseau que vous souhaitez utiliser. Si votre application doit lire du contenu autre que http(s), 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 votre pile réseau préférée. La couche DefaultDataSource.Factory prend en charge pour les sources autres que HTTP(S), telles que les fichiers locaux.

L'exemple suivant montre comment créer une ExoPlayer qui utilisera Cronet et prennent également en charge la lecture de contenu autre que 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();

Piles réseau compatibles

ExoPlayer est directement compatible avec HttpEngine, Cronet, OkHttp et les protocoles la pile réseau par défaut intégrée. ExoPlayer peut également être étendu pour prendre en charge autre pile réseau qui fonctionne sur Android.

Moteur HTTP

HttpEngine est la pile réseau par défaut recommandée sur Android à partir de l'API 34 (ou S extensions 7). Dans la plupart des cas, il utilise la pile réseau Cronet en interne, prenant en charge HTTP, HTTP/2 et HTTP/3 sur les protocoles QUIC.

ExoPlayer est compatible avec HttpEngine avec son HttpEngineDataSource.Factory. Vous pouvez injectez cette fabrique de sources de données comme décrit dans la section Configurer ExoPlayer pour utiliser un pile réseau spécifique.

Cronet

Cronet est la Pile réseau Chromium mise à la disposition des applications Android en tant que bibliothèque. Cronet prend de multiples technologies qui réduisent la latence et augmentent le débit des requêtes réseau nécessaires au fonctionnement de votre application, y compris générés par ExoPlayer. Compatibilité native avec les protocoles HTTP, HTTP/2 et HTTP/3 via QUIC protocoles. Cronet est utilisé par certaines des plus grandes applications de streaming au monde, y compris YouTube.

ExoPlayer est compatible avec Cronet via son Bibliothèque Cronet : Consultez le 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 services Cronet sous-jacents implémentations:

  1. Services Google Play:nous vous recommandons d'utiliser cette implémentation dans la plupart des et le retour à la pile réseau intégrée d'Android. (DefaultHttpDataSource) si les services Google Play ne sont pas disponibles.
  2. Cronet Embedded:ce type de création peut être un bon choix si un grand pourcentage de vos utilisateurs vous trouvez dans des marchés où les services Google Play ne sont pas disponibles pour tous les utilisateurs, ou si vous contrôler la version exacte de l'implémentation Cronet utilisée. La le principal inconvénient de Cronet Embedded est qu'il ajoute environ 8 Mo à votre application.
  3. Remplacement Cronet:l'implémentation de remplacement des implémentations Cronet API Cronet en tant que wrapper pour la pile réseau intégrée à Android. Il doit ne peuvent pas être utilisés avec ExoPlayer, car l'utilisation de la pile réseau intégrée d'Android directement (en utilisant DefaultHttpDataSource) est plus efficace.

OkHttp

OkHttp est une autre pile réseau moderne est largement utilisé par de nombreuses applications Android populaires. Il est compatible avec HTTP et HTTP/2, mais n'est pas encore compatible avec HTTP/3 via QUIC.

ExoPlayer prend en charge OkHttp via son Bibliothèque OkHttp. Consultez le 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 dans le l'application. Il est semblable à Cronet Embedded, mais OkHttp est considérablement en ajoutant moins de 1 Mo à votre application.

Pile réseau intégrée à Android

ExoPlayer prend en charge 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 le l'appareil sous-jacent. Sur la plupart des appareils, seul HTTP est pris en charge (c'est-à-dire HTTP/2 et HTTP/3 sur QUIC ne sont pas acceptés).

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. Cronet d'ExoPlayer et Pour illustrer cette procédure, les bibliothèques OkHttp sont de bons exemples.

Lors de l'intégration avec une pile réseau Java pure, il est recommandé d'implémenter un DataSourceContractTest pour vérifier que votre implémentation de HttpDataSource se comporte correctement. OkHttpDataSourceContractTest de la bibliothèque OkHttp est 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
Moteur HTTP HTTP
HTTP/2
HTTP/3 sur QUIC
Aucune Disponible uniquement sur l'API 34 ou les extensions S 7
Cronet (services Google Play) HTTP
HTTP/2
HTTP/3 sur QUIC
Faible
(< 100 Ko)
Nécessite les services Google Play. Version de Cronet mise à jour automatiquement
Cronet (intégré) HTTP
HTTP/2
HTTP/3 sur QUIC
Grande
(~8 Mo)
Version Cronet contrôlée par le développeur de l'application
Cronet (création de remplacement) HTTP
(selon l'appareil)
Faible
(< 100 Ko)
Non recommandé pour ExoPlayer
OkHttp HTTP
HTTP/2
Faible
(< 1 Mo)
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 de streaming. En particulier, lors de la diffusion en streaming d'un contenu multimédia adaptatif distribué à l'aide d'un réseau de diffusion de contenu (CDN), il existe des cas l'utilisation de ces protocoles peut permettre aux CDN de fonctionner beaucoup plus efficacement. Pour cette raison, HttpEngine et Cronet sont compatibles avec HTTP/2 et HTTP/3 par rapport à QUIC (et la compatibilité d'OkHttp avec HTTP/2), est un avantage majeur à l'aide de la pile réseau intégrée à Android, à condition que les serveurs sur lesquels le contenu est hébergé prennent également en charge ces protocoles.

Si vous envisagez d'utiliser le streaming multimédia de façon isolée, nous vous recommandons d'utiliser HttpEngine ou Cronet fournie par les services Google Play en revenant à DefaultHttpDataSource si les services Google Play ne sont pas disponibles. Cette recommandation est pertinente trouver un juste équilibre entre la possibilité d'utiliser HTTP/2 et HTTP/3 via QUIC sur la plupart des appareils, et en évitant une augmentation significative de la taille de l'APK. Il existe des exceptions recommandation. Si les services Google Play sont susceptibles d'être indisponibles sur une part significative des appareils qui exécuteront votre application, l'utilisation de Cronet Embedded ou OkHttp peut être plus appropriée. L'utilisation de la la pile réseau peut être acceptable si la taille de l'APK est une préoccupation critique ou si le streaming n'est qu'une partie mineure du fonctionnement de votre application.

Au-delà du simple contenu multimédia, il est généralement recommandé de choisir une seule pile réseau pour l'ensemble du réseautage effectué par votre application. Cela permet aux ressources (tels que les sockets) afin de pouvoir les mettre en commun et les partager efficacement entre ExoPlayer et composants d'application.

Parce que votre appli aura très probablement besoin d'effectuer un réseautage non lié à la lecture multimédia, votre choix de pile réseau doit au final tenir compte de notre les recommandations ci-dessus concernant la diffusion de contenus multimédias de façon isolée, les exigences les autres composants qui effectuent la mise en réseau, ainsi que leur importance relative pour votre l'application.

Mise en cache des contenus multimédias

ExoPlayer permet de mettre en cache les octets chargés sur le disque pour éviter tout chargement répété les mêmes octets du réseau. Ceci est utile lorsque vous revenez en arrière dans l'état actuel ou répéter le même élément.

La mise en cache nécessite une instance SimpleCache pointant vers un 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();