ExoPlayer wird häufig für das Streaming von Medien über das Internet verwendet. Unterstützt mehrere Netzwerkstacks zum Senden der zugrunde liegenden Netzwerkanfragen erstellen. Sie haben die Wahl. des Netzwerk-Stacks kann sich erheblich auf die Streamingleistung auswirken.
Auf dieser Seite wird beschrieben, wie Sie ExoPlayer für die Verwendung Ihres Netzwerkstapels von Auswahl, listet die verfügbaren Optionen auf, bietet einige Hinweise zur Auswahl einen Netzwerk-Stack für Ihre App. Außerdem wird erläutert, wie Sie Caching für gestreamte Medien.
ExoPlayer für die Verwendung eines bestimmten Netzwerkstacks konfigurieren
ExoPlayer lädt Daten über DataSource
-Komponenten, die er aus DataSource.Factory
-Instanzen erhält, die über den App-Code eingefügt werden.
Wenn Ihre App nur HTTP(S)-Inhalte wiedergeben muss, wählen Sie ein Netzwerk aus.
Stack ist so einfach wie das Aktualisieren aller DataSource.Factory
-Instanzen,
App wird als Instanzen von HttpDataSource.Factory
eingefügt
das dem Netzwerk-Stack entspricht, das Sie verwenden möchten. Wenn in Ihrer App auch nicht-http(s)-Inhalte wie lokale Dateien wiedergegeben werden müssen, verwenden Sie DefaultDataSource.Factory
:
Kotlin
DefaultDataSource.Factory( ... /* baseDataSourceFactory= */ PreferredHttpDataSource.Factory(...))
Java
new DefaultDataSource.Factory( ... /* baseDataSourceFactory= */ new PreferredHttpDataSource.Factory(...));
In diesem Beispiel ist PreferredHttpDataSource.Factory
die Fabrik, die Ihrem bevorzugten Netzwerkstack entspricht. Die DefaultDataSource.Factory
-Ebene unterstützt auch Nicht-HTTP(S)-Quellen wie lokale Dateien.
Das folgende Beispiel zeigt, wie eine ExoPlayer
erstellt wird, die den Cronet-Netzwerkstack verwendet und auch die Wiedergabe von Inhalten ohne HTTP(S) unterstützt.
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();
Unterstützte Netzwerkstacks
ExoPlayer bietet direkte Unterstützung für HttpEngine, Cronet, OkHttp und den integrierten Standardnetzwerkstack von Android. ExoPlayer kann auch so erweitert werden, anderen Netzwerk-Stacks unter Android.
HttpEngine
HttpEngine ist der empfohlene Standardnetzwerk-Stack unter Android ab API 34 (oder S Erweiterungen 7). In den meisten Fällen wird intern der Cronet-Netzwerkstack verwendet, der HTTP, HTTP/2 und HTTP/3 über QUIC-Protokolle unterstützt.
ExoPlayer unterstützt HttpEngine mit seiner HttpEngineDataSource.Factory
. Du kannst diese Datenquellenfabrik wie unter ExoPlayer für die Verwendung eines bestimmten Netzwerkstacks konfigurieren beschrieben einschleusen.
Cronett
Cronet ist das Chromium-Netzwerkstack, der Android-Apps als Bibliothek zur Verfügung gestellt wird. Cronet nimmt der Vorteile mehrerer Technologien, die die Latenz reduzieren und Durchsatz der Netzwerkanfragen, die Ihre Anwendung verarbeiten muss, einschließlich derjenigen, von ExoPlayer entwickelt. Es unterstützt nativ die Protokolle HTTP, HTTP/2 und HTTP/3 über QUIC. Cronet wird von einigen der weltweit größten Streaming-Apps verwendet, einschließlich YouTube.
ExoPlayer unterstützt Cronet über seine
Cronet-Bibliothek
Eine ausführliche Anleitung zur Verwendung finden Sie in der README.md
der Bibliothek. Beachten Sie, dass die Cronet-Bibliothek drei zugrunde liegende Cronet-
Implementierungen:
- Google Play-Dienste:Wir empfehlen diese Implementierung in den meisten
und auf den integrierten Android-Netzwerkstack zurückgreifen,
(
DefaultHttpDataSource
) wenn die Google Play-Dienste nicht verfügbar sind. - Eingebettetes Cronett:Diese Option eignet sich gut, wenn ein großer Teil der Nutzer sich in Märkten befinden, in denen die Google Play-Dienste nicht allgemein verfügbar sind, oder wenn Sie die genaue Version der verwendeten Cronet-Implementierung steuern möchten. Die Der große Nachteil von Cronet Embedded besteht darin, dass es für Ihre App.
- Cronet-Fallback:Die Fallback-Implementierung von Cronet implementiert
Cronet-API als Wrapper für den integrierten Android-Netzwerkstack Sie sollte nicht mit ExoPlayer verwendet werden, da die direkte Verwendung des integrierten Netzwerkstacks von Android (über
DefaultHttpDataSource
) effizienter ist.
OkHttp
OkHttp ist ein weiterer moderner Netzwerkstack, der von vielen beliebten Android-Apps verwendet wird. Es unterstützt HTTP und HTTP/2, aber noch nicht HTTP/3 über QUIC.
ExoPlayer unterstützt OkHttp über
OkHttp-Bibliothek.
Eine ausführliche Anleitung zur Verwendung findest du in der README.md
der Bibliothek
. Bei Verwendung der OkHttp-Bibliothek ist der Netzwerkstack in die App eingebettet. Das ist ähnlich wie bei Cronet Embedded. OkHttp ist jedoch deutlich kleiner und erhöht die Größe Ihrer App um weniger als 1 MB.
Integrierter Android-Netzwerkstack
ExoPlayer unterstützt die Verwendung des integrierten Netzwerkstacks von Android mit DefaultHttpDataSource
und DefaultHttpDataSource.Factory
, die Teil der ExoPlayer-Kernbibliothek sind.
Die genaue Implementierung des Netzwerk-Stacks hängt von der Software ab, die auf dem zugrunde liegendes Gerät. Auf den meisten Geräten wird nur HTTP unterstützt, d. h. HTTP/2 und HTTP/3 über QUIC werden nicht unterstützt.
Andere Netzwerkstapel
Apps können auch andere Netzwerkstacks in ExoPlayer einbinden.
Implementieren Sie dazu einen HttpDataSource
, der den Netzwerkstack umschließt, zusammen mit einem entsprechenden HttpDataSource.Factory
. Cronet und
OkHttp-Bibliotheken sind gute Beispiele dafür.
Bei der Integration mit einem reinen Java-Netzwerk-Stack empfiehlt es sich, eine
DataSourceContractTest
, um zu prüfen, ob Ihre HttpDataSource
-Implementierung
nicht ordnungsgemäß funktioniert. OkHttpDataSourceContractTest
in der OkHttp-Bibliothek ist ein
ein gutes Beispiel dafür.
Netzwerkstack auswählen
In der folgenden Tabelle sind die Vor- und Nachteile der von den ExoPlayer
Netzwerkstapel | Protokolle | Auswirkungen der APK-Größe | Hinweise |
---|---|---|---|
HttpEngine | HTTP HTTP/2 HTTP/3 über QUIC |
Keine | Nur mit API 34 oder S-Erweiterungen 7 verfügbar |
Cronet (Google Play-Dienste) | HTTP HTTP/2 HTTP/3 über QUIC |
Klein (< 100 KB) |
Erfordert die Google Play-Dienste. Cronet-Version wird automatisch aktualisiert |
Cronet (eingebettet) | HTTP HTTP/2 HTTP/3 über QUIC |
Groß (ca. 8 MB) |
Vom App-Entwickler gesteuerte Cronet-Version |
Cronet (Fallback) | HTTP (variiert je nach Gerät) |
Klein (< 100 KB) |
Nicht für ExoPlayer empfohlen |
OkHttp | HTTP HTTP/2 |
Klein (< 1 MB) |
|
Integrierter Netzwerkstack | HTTP (variiert je nach Gerät) |
Keine | Die Implementierung variiert je nach Gerät |
Die Protokolle HTTP/2 und HTTP/3 im Vergleich zu QUIC können Medien erheblich verbessern. und Streaming-Leistung zu verbessern. Insbesondere beim Streaming adaptiver Medien, die über ein Content Delivery Network (CDN) verteilt werden, können diese Protokolle dazu beitragen, dass CDNs viel effizienter arbeiten. Aus diesem Grund unterstützen HttpEngine und Cronet sowohl HTTP/2 als auch HTTP/3 gegenüber QUIC (und der HTTP/2-Unterstützung von OkHttp) unter Verwendung des integrierten Android-Netzwerkstapels, vorausgesetzt, die Server, auf denen der gehosteten Content auch diese Protokolle unterstützen.
Wenn Sie Medien-Streaming isoliert betrachten, empfehlen wir die Verwendung von HttpEngine oder
Von Google Play-Diensten bereitgestelltes Cronet verwendet DefaultHttpDataSource
wenn die Google Play-Dienste nicht verfügbar sind. Diese Empfehlung ist gut
zwischen der Aktivierung von HTTP/2 und HTTP/3 über QUIC auf den meisten Geräten
wodurch eine deutliche
Vergrößerung des APK vermieden wird. Hiervon ausgenommen sind
Empfehlung. Wenn die Google Play-Dienste auf einem erheblichen Teil der Geräte, auf denen Ihre App ausgeführt wird, wahrscheinlich nicht verfügbar sind, ist die Verwendung von Cronet Embedded oder OkHttp möglicherweise besser geeignet. Mit der integrierten
Der Netzwerk-Stack kann akzeptabel sein, wenn die APK-Größe wichtig ist
Streaming ist nur ein kleiner Teil der Funktionalität Ihrer App.
Abgesehen von Medien ist es normalerweise eine gute Idee, einen einzigen Netzwerkstack für alle Netzwerkfunktionen Ihrer App auszuwählen. So können Ressourcen (z. B. Sockets) effizient zwischen ExoPlayer und anderen App-Komponenten gemeinsam genutzt werden.
Da Ihre App höchstwahrscheinlich ein Netzwerk ausführen muss, bei der Medienwiedergabe, sollte Ihre Wahl des Netzwerk-Stacks letztendlich unsere die oben genannten Empfehlungen für Medien-Streaming, die Anforderungen jedes einzelnen andere Komponenten, die Netzwerke nutzen, und deren relative Bedeutung für Ihre
Medien im Cache speichern
ExoPlayer unterstützt das Caching geladener Byte auf dem Laufwerk, um ein wiederholtes Laden zu verhindern dieselben Bytes aus dem Netzwerk entfernt. Das ist nützlich, wenn Sie in den aktuellen Medien zurückspulen oder denselben Artikel wiederholen möchten.
Für das Caching ist eine SimpleCache
-Instanz erforderlich, die auf einen dedizierten Cache verweist
Verzeichnis und ein 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();