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. Le choix de la pile réseau peut avoir un impact significatif sur les performances de streaming.

Cette page explique comment configurer ExoPlayer pour qu'il utilise la pile réseau de votre choix, liste les options disponibles, fournit des conseils pour choisir une pile réseau pour votre application et explique comment activer le cache pour les contenus multimédias en streaming.

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

ExoPlayer charge les données via des 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), 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 également 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 les sources autres que http(s), telles que les fichiers locaux.

L'exemple suivant montre comment créer un ExoPlayer qui utilisera la pile réseau Cronet et prend également en charge la lecture de contenu non 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 toute autre pile réseau fonctionnant sur Android.

HttpEngine

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 les protocoles HTTP, HTTP/2 et HTTP/3 sur 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 exploite plusieurs 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 celles effectuées 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 pour l'activer. 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 cas et de revenir à la pile réseau intégrée d'Android (DefaultHttpDataSource) si les services Google Play ne sont pas disponibles.
  2. Cronet Embedded: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 largement utilisée par de nombreuses applications Android populaires. Il est compatible avec HTTP et HTTP/2, mais n'est pas encore compatible avec HTTP/3 sur QUIC.

ExoPlayer est compatible avec OkHttp via sa bibliothèque OkHttp. Consultez la page 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 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 une HttpDataSource qui encapsule la pile réseau, ainsi qu'une HttpDataSource.Factory correspondante. Cronet d'ExoPlayer et Pour illustrer cette procédure, les bibliothèques OkHttp sont de bons exemples.

Lors de l'intégration à une pile réseau Java pure, il est recommandé d'implémenter un DataSourceContractTest pour vérifier que votre implémentation 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 de 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
Petit
(<100 Ko)
Nécessite les services Google Play. Mise à jour automatique de la version de Cronet
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)
Petite
(<100 Ko)
Non recommandé pour ExoPlayer
OkHttp HTTP
HTTP/2
Petite
(<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 multimédia. 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 de diffuser des contenus multimédias de manière isolée, nous vous recommandons d'utiliser HttpEngine ou Cronet fournis par les services Google Play, en revenant à DefaultHttpDataSource si les services Google Play ne sont pas disponibles. Cette recommandation établit un bon équilibre entre l'activation de l'utilisation de HTTP/2 et HTTP/3 sur QUIC sur la plupart des appareils, et l'évitement d'une augmentation significative de la taille de l'APK. Il existe des exceptions à cette recommandation. Dans les cas où les services Google Play sont susceptibles d'être indisponibles sur une partie importante des appareils exécutant votre application, l'utilisation de Cronet Embedded ou d'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.

Étant donné que votre application devra probablement effectuer des opérations de mise en réseau non liées à la lecture multimédia, votre choix de pile réseau doit tenir compte de nos recommandations ci-dessus pour le streaming multimédia en isolation, des exigences de tous les autres composants effectuant des opérations de mise en réseau et de leur importance relative pour votre application.

Mettre 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();