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:
- 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. - 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.
- 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();