Stack di rete

ExoPlayer viene comunemente utilizzato per lo streaming di contenuti multimediali su Internet. Supporta più stack di rete per effettuare le richieste di rete sottostanti. A te la scelta dello stack di rete può avere un impatto significativo sulle prestazioni dei flussi di dati.

Questa pagina illustra come configurare ExoPlayer per l'utilizzo dello stack di rete di scelta, elenca le opzioni disponibili, fornisce alcune indicazioni su come scegliere uno stack di rete per la tua app e spiega come abilitare la memorizzazione nella cache per i flussi di dati contenuti multimediali.

Configurare ExoPlayer per l'utilizzo di uno stack di rete specifico

ExoPlayer carica i dati attraverso i componenti DataSource, che ottiene da DataSource.Factory istanze inserite dal codice dell'app.

Se la tua app deve riprodurre soltanto contenuti http, seleziona una rete è semplice: aggiorna tutte le istanze DataSource.Factory l'app viene inserita in istanze di HttpDataSource.Factory che corrisponde allo stack di rete che vuoi usare. Se la tua app deve riprodurre contenuti non HTTP, ad esempio file locali, utilizza DefaultDataSource.Factory:

Kotlin

DefaultDataSource.Factory(
  ...
  /* baseDataSourceFactory= */ PreferredHttpDataSource.Factory(...))

Java

new DefaultDataSource.Factory(
    ...
    /* baseDataSourceFactory= */ new PreferredHttpDataSource.Factory(...));

In questo esempio, PreferredHttpDataSource.Factory è la fabbrica corrispondente il tuo stack di rete preferito. Il livello DefaultDataSource.Factory aggiunge il supporto per le origini non http(s), come i file locali.

L'esempio seguente mostra come creare un ExoPlayer che utilizzerà il parametro lo stack di rete e la riproduzione di contenuti non 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();

Stack di rete supportati

ExoPlayer fornisce supporto diretto per HttpEngine, Cronet, OkHttp e stack di rete predefinito integrato. ExoPlayer può essere esteso anche per supportare qualsiasi altro stack di rete compatibile con Android.

HttpEngine

HttpEngine è lo stack di rete predefinito consigliato su Android dall'API 34 (o estensioni 7). Nella maggior parte dei casi, utilizza internamente lo stack di rete Cronet, supportando i protocolli HTTP, HTTP/2 e HTTP/3 su QUIC.

ExoPlayer supporta HttpEngine con il suo HttpEngineDataSource.Factory. Puoi inserire il valore di fabbrica dell'origine dati come descritto in Configurare ExoPlayer per l'utilizzo di un'immagine stack di rete specifico.

Cronet

Cronet è il Stack di rete di Chromium reso disponibile per le app per Android come raccolta. Cronet prende sfruttare molteplici tecnologie che riducono la latenza delle richieste di rete necessarie per il funzionamento dell'app, incluse quelle creato da ExoPlayer. Supporta in modo nativo HTTP, HTTP/2 e HTTP/3 su QUIC protocolli. Cronet è utilizzato da alcune delle più grandi app di streaming al mondo, incluso YouTube.

ExoPlayer supporta Cronet tramite Libreria di corone. Per istruzioni dettagliate su come utilizzare, consulta le README.md della libreria li annotino. Tieni presente che la libreria Cronet è in grado di utilizzare tre elementi Cronet sottostanti implementazioni:

  1. Google Play Services: consigliamo di utilizzare questa implementazione nella maggior parte di Android, facendo ricorso allo stack di rete integrato di Android (DefaultHttpDataSource) se Google Play Services non è disponibile.
  2. Clona incorporata: può essere una buona scelta se un'ampia percentuale di utenti si trovano in mercati in cui Google Play Services non è ampiamente disponibile, oppure se l'utente vuoi controllare la versione esatta dell'implementazione Cronet in uso. La lo svantaggio principale di Cronet Embedded è che aggiunge circa 8 MB a la tua app.
  3. Cronet Fallback: l'implementazione di riserva di Cronet implementa L'API di Cronet come wrapper attorno allo stack di rete integrato di Android. Dovrebbe non può essere utilizzata con ExoPlayer, poiché utilizza lo stack di rete integrato di Android direttamente (utilizzando DefaultHttpDataSource) è più efficiente.

OkHttp

OkHttp è un altro moderno stack di rete che è ampiamente usato da molte app Android popolari. Supporta HTTP e HTTP/2, ma non supporta ancora HTTP/3 tramite QUIC.

ExoPlayer supporta OkHttp tramite la sua Libreria OkHttp. Per istruzioni dettagliate su come utilizzare, consulta le README.md della libreria li annotino. Quando si utilizza la libreria OkHttp, lo stack di rete è incorporato dell'app. È simile a Cronet Embedded, ma OkHttp è significativamente di dimensioni inferiori, aggiungendo meno di 1 MB alla tua app.

Stack di rete integrato di Android

ExoPlayer supporta l'uso dello stack di rete integrato di Android con DefaultHttpDataSource e DefaultHttpDataSource.Factory, che fanno parte di la libreria di base ExoPlayer.

L'esatta implementazione dello stack di rete dipende dal software in esecuzione il dispositivo sottostante. Sulla maggior parte dei dispositivi è supportato solo il protocollo HTTP (ovvero HTTP/2 e HTTP/3 su QUIC non sono supportati).

Altri stack di rete

Le app possono inoltre integrare altri stack di rete con ExoPlayer. Per farlo, implementa un'HttpDataSource che esegue il wrapping dello stack di rete, insieme a un HttpDataSource.Factory corrispondente. Cronet di ExoPlayer e Le librerie OkHttp sono buoni esempi di come eseguire questa operazione.

Durante l'integrazione con uno stack di rete Java puro, è consigliabile implementare un DataSourceContractTest per verificare che l'implementazione di HttpDataSource si comporta correttamente. OkHttpDataSourceContractTest nella libreria OkHttp è un buon esempio di come fare.

Scelta di uno stack di rete

La seguente tabella illustra i pro e i contro degli stack di rete supportati ExoPlayer.

Stack di rete Protocolli Impatto sulle dimensioni degli APK Note
HttpEngine HTTP
HTTP/2
HTTP/3 tramite QUIC
Nessuno Disponibile solo su API 34 o S Extensions 7
Cronet (Google Play Services) HTTP
HTTP/2
HTTP/3 tramite QUIC
Piccolo
(<100 kB)
Richiede Google Play Services. Versione Cronet aggiornata automaticamente
Cronet (incorporato) HTTP
HTTP/2
HTTP/3 tramite QUIC
Grande
(~8 MB)
Versione di Cronet controllata dallo sviluppatore di app
Cronet (di riserva) HTTP
(varia in base al dispositivo)
Piccolo
(<100 kB)
Sconsigliato per ExoPlayer
OkHttp HTTP
HTTP/2
Piccolo
(<1 MB)
Stack di rete integrato HTTP
(varia in base al dispositivo)
Nessuno L'implementazione varia in base al dispositivo

I protocolli HTTP/2 e HTTP/3 su QUIC possono migliorare significativamente i contenuti multimediali le prestazioni dei flussi di dati. In particolare, quando riproduci in streaming contenuti multimediali adattivi distribuiti tramite una rete di distribuzione dei contenuti (CDN), esistono casi quale uso di questi protocolli può consentire alle reti CDN di funzionare in modo molto più efficiente. Per questo motivo, il supporto di HttpEngine e Cronet sia per HTTP/2 che per HTTP/3 rispetto a QUIC (e il supporto di OkHttp per HTTP/2), è un vantaggio importante rispetto usando lo stack di rete integrato di Android, a condizione che i server su cui anche i contenuti in hosting supportano questi protocolli.

Quando si considera lo streaming di contenuti multimediali in modo isolato, consigliamo di utilizzare HttpEngine o Cronet fornito da Google Play Services di riserva DefaultHttpDataSource se Google Play Services non è disponibile. Questo consiglio ha un impatto positivo equilibrio tra l'abilitazione dell'uso di HTTP/2 e HTTP/3 tramite QUIC sulla maggior parte dei dispositivi e evitando un aumento significativo delle dimensioni degli APK. Ci sono delle eccezioni il nostro consiglio. Per i casi in cui è probabile che Google Play Services non sia disponibile su una parte significativa di dispositivi che eseguiranno la tua app, potrebbe essere più appropriato usare Cronet Embedded o OkHttp. L'utilizzo della tecnologia lo stack di rete può essere accettabile se le dimensioni dell'APK rappresentano un problema critico, o se i contenuti multimediali lo streaming è solo una parte minima delle funzionalità della tua app.

Al di là dei soli contenuti multimediali, in genere è una buona idea scegliere un unico stack di rete per tutte le risorse di networking eseguite dalla tua app. Ciò permette alle risorse (come i socket) per essere in pool e condivisi in modo efficiente tra ExoPlayer e altri componenti dell'app.

Perché la tua app molto probabilmente dovrà eseguire networking non correlati alla riproduzione di contenuti multimediali, la scelta dello stack di rete dovrebbe infine tenere conto dei nostri di cui sopra per lo streaming di contenuti multimediali in modo isolato, i requisiti di altri componenti che eseguono il networking e la loro importanza relativa dell'app.

Memorizzazione nella cache dei contenuti multimediali

ExoPlayer supporta la memorizzazione nella cache dei byte caricati su disco per evitare il caricamento ripetuto gli stessi byte dalla rete. È utile quando si cerca di nuovo contenuti multimediali o la ripetizione dello stesso elemento.

La memorizzazione nella cache richiede un'istanza SimpleCache che rimandi a una cache dedicata e 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();