ExoPlayer wird häufig zum Streamen 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 sie von
DataSource.Factory
-Instanzen, die aus dem App-Code eingeschleust 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 Ihre App auch
Nicht-HTTP-Inhalte wie lokale Dateien abspielen 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 Factory, die Ihrem
bevorzugten Netzwerk-Stack an. Die Ebene DefaultDataSource.Factory
wird unterstützt
für Nicht-HTTP(S)-Quellen wie lokale Dateien.
Das folgende Beispiel zeigt, wie ein ExoPlayer
erstellt wird, der das Cronet-Modell verwendet
und die Wiedergabe von Nicht-HTTP-Inhalten unterstützen.
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 die Standard-Netzwerk-Stack integriert. 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). Meistens wird der Cronet-Netzwerkstack intern verwendet, die Protokolle HTTP, HTTP/2 und HTTP/3 über QUIC unterstützen.
ExoPlayer unterstützt HttpEngine mit der zugehörigen HttpEngineDataSource.Factory
. Sie können
Fügen Sie diese Datenquellen-Factory wie unter ExoPlayer für die Verwendung eines
eines bestimmten Netzwerk-Stacks.
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. Nativ unterstützt HTTP, HTTP/2 und HTTP/3 über QUIC Protokolle. 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 findest du 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 Prozentsatz Ihrer 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 Er sollte
nicht mit ExoPlayer verwendet werden, da der integrierte Android-Netzwerkstack verwendet wird
direkt (über
DefaultHttpDataSource
) ist effizienter.
OkHttp
OkHttp ist ein weiterer moderner Netzwerk-Stack, wird von vielen beliebten Android-Apps verwendet. Es unterstützt HTTP- und HTTP/2, unterstützt jedoch noch kein 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 wird der Netzwerkstack in die
Dies ähnelt Cronet Embedded, OkHttp ist jedoch erheblich
und Ihrer App unter 1 MB hinzufügen.
Integrierter Android-Netzwerkstack
ExoPlayer unterstützt die Verwendung des integrierten Android-Netzwerkstacks mit
DefaultHttpDataSource
und DefaultHttpDataSource.Factory
, die Teil von
der ExoPlayer-Kernbibliothek.
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 ein HttpDataSource
-Element, das den Netzwerk-Stack umschließt,
zusammen mit einem entsprechenden HttpDataSource.Factory
-Wert. 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 auf die APK-Größe | Hinweise |
---|---|---|---|
HttpEngine | HTTP HTTP/2 HTTP/3 über QUIC |
Keine | Nur verfügbar für API 34 oder S Extensions 7 |
Cronet (Google Play-Dienste) | HTTP HTTP/2 HTTP/3 über QUIC |
Klein (< 100 KB) |
Google Play-Dienste erforderlich. Cronet-Version wird automatisch aktualisiert |
Cronet (eingebettet) | HTTP HTTP/2 HTTP/3 über QUIC |
Groß (~8 MB) |
Vom App-Entwickler kontrollierte Cronet-Version |
Cronet (Fallback) | HTTP (je nach Gerät) |
Klein (< 100 KB) |
Nicht empfohlen für ExoPlayer |
OkHttp | HTTP HTTP/2 |
Klein (< 1 MB) |
|
Integrierter Netzwerk-Stack | HTTP (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. Das gilt insbesondere beim Streamen adaptiver Medien, die über ein Content Distribution Network (CDN) verbreitet werden, mit denen CDNs viel effizienter arbeiten können. 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 wahrscheinlich nicht verfügbar sind
auf einem erheblichen Teil der Geräte,
auf denen Ihre App ausgeführt wird,
Cronet Embedded oder OkHttp kann geeigneter sein. 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.
Neben den Medien empfiehlt es sich normalerweise, einen einzelnen Netzwerk-Stack zu wählen für das gesamte Netzwerk durch Ihre App. Dadurch können Ressourcen (z. B. Sockets) für ein effizientes Pooling und gemeinsame Nutzung zwischen ExoPlayer und anderen App-Komponenten.
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. Dies ist nützlich, wenn Sie im aktuellen oder dasselbe Element wiederholen.
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();