Netzwerkstacks

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:

  1. 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.
  2. 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.
  3. 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();