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 in modo che utilizzi lo stack di rete scelto, elenca le opzioni disponibili, fornisce alcune indicazioni su come scegliere uno stack di rete per la tua app e spiega come attivare la memorizzazione nella cache per i contenuti multimediali in streaming.
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 solo contenuti http(s), selezionare uno stack di rete è semplice come aggiornare le eventuali istanze DataSource.Factory
iniettate dall'app in modo che siano istanze di HttpDataSource.Factory
corrispondente allo stack di rete che vuoi utilizzare. 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 factory corrispondente allo stack di rete preferito. Il livello DefaultDataSource.Factory
aggiunge il supporto per le origini non http(s), ad esempio i file locali.
L'esempio seguente mostra come creare un ExoPlayer
che utilizzi lo stack di rete Cronet e supporti anche la riproduzione di contenuti 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();
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 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 i protocolli HTTP, HTTP/2 e HTTP/3 su QUIC. Cronet è utilizzato da alcune delle più grandi app di streaming al mondo, incluso YouTube.
ExoPlayer supporta Cronet tramite la sua
libreria Cronet.
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 implementazioni di Cronet di base:
- 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. - Cronet incorporato: può essere una buona scelta se una percentuale elevata dei tuoi utenti si trova in mercati in cui Google Play Services non è ampiamente disponibile o se vuoi controllare la versione esatta dell'implementazione di 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. Non deve essere utilizzato con ExoPlayer, poiché l'utilizzo diretto dello stack di rete integrato di Android (tramite
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.
Consulta la pagina README.md
della libreria per istruzioni dettagliate su come utilizzarla. Quando utilizzi la libreria OkHttp, lo stack di rete è incorporato nell'app. È simile a Cronet Embedded, ma OkHttp è molto più piccolo e aggiunge meno di 1 MB all'app.
Lo 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 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 avvolga lo stack di rete insieme a un HttpDataSource.Factory
corrispondente. Cronet di ExoPlayer e
Le librerie OkHttp sono buoni esempi di come eseguire questa operazione.
Quando esegui l'integrazione con uno stack di rete Java puro, è buona norma implementare un
DataSourceContractTest
per verificare che l'implementazione di HttpDataSource
si comporti correttamente. OkHttpDataSourceContractTest
nella libreria OkHttp è un buon esempio di come eseguire questa operazione.
Scegliere 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 su 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. La versione di Cronet è stata aggiornata automaticamente |
Cronet (incorporato) | HTTP HTTP/2 HTTP/3 tramite QUIC |
Grande (circa 8 MB) |
Versione di Cronet controllata dallo sviluppatore dell'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 su QUIC (e il supporto di OkHttp per HTTP/2) è un vantaggio significativo rispetto all'utilizzo dello stack di rete integrato di Android, a condizione che i server su cui sono ospitati i contenuti supportino anche 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. Esistono eccezioni a questo
consiglio. Nei casi in cui è probabile che Google Play Services non sia disponibile su una parte significativa dei dispositivi su cui verrà eseguita la tua app, l'utilizzo di Cronet Embedded o OkHttp potrebbe essere più appropriato. L'utilizzo dello stack di rete integrato può essere accettabile se le dimensioni dell'APK sono un problema critico o se lo streaming di contenuti multimediali è solo una parte secondaria della 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.
Poiché è molto probabile che la tua app debba eseguire operazioni di rete non correlate alla riproduzione dei contenuti multimediali, la scelta dello stack di rete deve tenere conto dei nostri consigli riportati sopra per lo streaming di contenuti multimediali in isolamento, dei requisiti di eventuali altri componenti che eseguono operazioni di rete e della loro importanza relativa per la tua app.
Memorizzazione nella cache dei contenuti multimediali
ExoPlayer supporta la memorizzazione nella cache dei byte caricati sul disco per evitare di caricare ripetutamente gli stessi byte dalla rete. Questa opzione è utile per tornare indietro nel media corrente o ripetere lo stesso elemento.
La memorizzazione nella cache richiede un'istanza SimpleCache
che punti a una directory della 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();