Stosy sieciowe

ExoPlayer zwykle służy do strumieniowego przesyłania multimediów w internecie. Obsługuje kilka stosów sieciowych do wysyłania bazowych żądań sieciowych. Wybór należy do Ciebie może mieć duży wpływ na wydajność strumieniowania.

Na tej stronie opisujemy, jak skonfigurować ExoPlayer do korzystania ze stosu sieciowego wybór, wymienia dostępne opcje, podaje wskazówki dotyczące wyboru stos sieciowy na potrzeby aplikacji i wyjaśni, jak włączyć buforowanie w przypadku danych przesyłanych strumieniowo. multimediów.

Konfigurowanie rozszerzenia ExoPlayer tak, aby używał określonego stosu sieciowego

ExoPlayer wczytuje dane za pomocą komponentów DataSource, które pozyskuje z DataSource.Factory instancje wstrzykiwane z kodu aplikacji.

Jeśli aplikacja ma odtwarzać tylko treści http(s), wybierz sieć Aby utworzyć stos, wystarczy zaktualizować instancje DataSource.Factory aplikacja wstrzykuje się, aby pełnić rolę instancji HttpDataSource.Factory odpowiadający stosowi sieci, którego chcesz użyć. Jeśli Twoja aplikacja również musi odtwarzać treści inne niż HTTP, takie jak pliki lokalne, DefaultDataSource.Factory:

Kotlin

DefaultDataSource.Factory(
  ...
  /* baseDataSourceFactory= */ PreferredHttpDataSource.Factory(...))

Java

new DefaultDataSource.Factory(
    ...
    /* baseDataSourceFactory= */ new PreferredHttpDataSource.Factory(...));

W tym przykładzie PreferredHttpDataSource.Factory to fabryka odpowiadająca Twojemu preferowanym stosem sieciowym. Warstwa DefaultDataSource.Factory udostępnia dodatkowe funkcje dla źródeł innych niż HTTP, takich jak pliki lokalne.

Ten przykład pokazuje, jak utworzyć obiekt ExoPlayer, który będzie używał Cronet stosunkowo dużo czasu, a także obsługiwać odtwarzanie treści innych niż 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();

Obsługiwane stosy sieci

ExoPlayer zapewnia bezpośrednią obsługę HttpEngine, Cronet, OkHttp i z wbudowanym, domyślnym stosem sieciowym. ExoPlayer można też rozszerzyć, aby obsługiwały z innym stosem sieciowym działającym na Androidzie.

silnik HTTp

HttpEngine, to zalecany domyślny stos sieciowy na Androidzie z interfejsu API 34 (lub S) rozszerzenia 7). W większości przypadków korzysta on z wewnętrznego stosu sieci Cronet, obsługujące HTTP, HTTP/2 i HTTP/3 za pomocą protokołów QUIC.

ExoPlayer obsługuje mechanizm HttpEngine za pomocą interfejsu HttpEngineDataSource.Factory. Dostępne opcje wstrzyknij tę fabrykę źródła danych zgodnie z opisem w sekcji Konfigurowanie oprogramowania ExoPlayer pod kątem użycia konkretnego stosu sieciowego.

Cronety

Cronet to Stos sieciowy Chromium udostępniony aplikacjom na Androida jako biblioteka. Trójka wykorzystują liczne technologie, które zmniejszają opóźnienie i zwiększają związane z przepustowością żądań sieciowych, które musi działać aplikacja. Dotyczy to firmy ExoPlayer. Natywnie obsługuje protokół HTTP, HTTP/2 i HTTP/3 przez QUIC protokoły API. Z Cronnetu korzystają jedne z największych na świecie aplikacji do odtwarzania strumieniowego, w tym również z YouTube.

ExoPlayer obsługuje rozszerzenie Cronet za pomocą Biblioteka aplikacji Cronet. Szczegółowe instrukcje korzystania z usługi znajdziesz w dokumencie README.md biblioteki. . Pamiętaj, że biblioteka Cronet może korzystać z 3 podstawowych funkcji Cronet implementacji:

  1. Usługi Google Play: zalecamy korzystanie z tej implementacji w większości i korzystania z wbudowanego stosu sieciowego Androida (DefaultHttpDataSource), jeśli Usługi Google Play są niedostępne.
  2. Wbudowany Cronet: może być dobrym rozwiązaniem, jeśli duży odsetek użytkowników znajdują się na rynkach, na których Usługi Google Play nie są powszechnie dostępne, lub jeśli chcesz kontrolować dokładną wersję używanej implementacji Cronet. Główną wadą technologii Cronet Embedded jest to, że zajmuje ona około 8 MB do aplikacji.
  3. Kreacja zastępcza Cronet: implementacja kreacji zastępczej zaimplementowanej przez Cronet Interfejs API Cronet jako otoka wbudowanego stosu sieciowego Androida. Powinna nie powinna być używana z ExoPlayer, ponieważ korzysta z wbudowanego stosu sieciowego Androida bezpośrednio (za pomocą funkcji DefaultHttpDataSource) jest bardziej efektywne.

OkHttp

OkHttp to kolejny nowoczesny stos sieciowy, jest powszechnie stosowany w wielu popularnych aplikacjach na Androida. Obsługuje HTTP HTTP/2, ale nie obsługuje jeszcze HTTP/3 przez QUIC.

ExoPlayer obsługuje protokół OkHttp przez Biblioteka OHttp. Szczegółowe instrukcje korzystania z usługi znajdziesz w dokumencie README.md biblioteki. . W przypadku korzystania z biblioteki OkHttp stos sieciowy jest osadzony w sekcji . Jest to podobne do Cronet Embedded, ale OkHttp jest znacznie mniejsze niż 1 MB do aplikacji.

Wbudowany stos sieciowy Androida

ExoPlayer obsługuje wbudowany stos sieciowy Androida z DefaultHttpDataSource i DefaultHttpDataSource.Factory, które są częścią w głównej bibliotece ExoPlayer.

Dokładna implementacja stosu sieciowego zależy od oprogramowania działającego na na danym urządzeniu. Na większości urządzeń obsługiwany jest tylko protokół HTTP (czyli HTTP/2 i HTTP/3 przez QUIC nie są obsługiwane).

Inne stosy sieci

Z platformą ExoPlayer aplikacje mogą też integrować inne stosy sieciowe. Aby to zrobić, zaimplementuj obiekt HttpDataSource, który opakowuje stos sieciowy. razem z odpowiednimi wartościami HttpDataSource.Factory. Cronety ExoPlayer Dobrymi przykładami są biblioteki OkHttp.

Przy integracji ze stosem sieciowym opartym na czystej Javie warto zastosować DataSourceContractTest, aby sprawdzić, czy implementacja HttpDataSource Google będzie działać prawidłowo. OkHttpDataSourceContractTest w bibliotece OkHttp to jak to zrobić.

Wybieranie stosu sieci

W tej tabeli opisujemy zalety i wady stosów sieciowych obsługiwanych przez ExoPlayer,

Stos sieci Protokoły Wpływ rozmiaru pliku APK Uwagi
silnik HTTp HTTP
HTTP/2
HTTP/3 przez QUIC
Brak Dostępna tylko w przypadku interfejsu API 34 i rozszerzeń S 7
Cronet (Usługi Google Play) HTTP
HTTP/2
HTTP/3 przez QUIC
Mały
(< 100 KB)
Wymaga Usług Google Play. Wersja Cronet aktualizowana automatycznie
Cronet (wbudowany) HTTP
HTTP/2
HTTP/3 przez QUIC
Duży
(ok. 8 MB)
Wersja Cronet kontrolowana przez dewelopera aplikacji
Cronet (zastępcza) HTTP
(zależy od urządzenia)
Mały
(< 100 KB)
Niezalecane w przypadku ExoPlayer
OkHttp HTTP
HTTP/2
Mały
(< 1 MB)
Wbudowany stos sieciowy HTTP
(zależy od urządzenia)
Brak Implementacja różni się w zależności od urządzenia

Protokoły HTTP/2 i HTTP/3 z protokołami QUIC mogą znacznie poprawić jakość multimediów wydajność strumieniowania. W szczególności w przypadku strumieniowego przesyłania multimediów adaptacyjnych, które są rozpowszechnianych za pomocą sieci dystrybucji treści (CDN), zdarzają się przypadki Dzięki tym protokołom sieci CDN mogą działać znacznie efektywniej. Z tego powodu platformy HttpEngine i Cronet obsługują zarówno protokół HTTP/2, jak i HTTP/3. w porównaniu z QUIC (i obsługą HTTP/2 przez OkHttp), to duża zaleta w porównaniu z wbudowany stos sieciowy Androida, udostępniał serwery, na których , które również są hostowane, obsługują te protokoły.

Jeśli rozważasz oddzielne strumieniowanie multimediów, zalecamy użycie biblioteki HttpEngine lub Cronet świadczony przez Usługi Google Play (od DefaultHttpDataSource) jeśli Usługi Google Play są niedostępne. Ta rekomendacja jest bardzo dobra równowagi między włączeniem obsługi HTTP/2 i HTTP/3 przez QUIC na większości urządzeń oraz aby uniknąć znacznego zwiększenia rozmiaru pliku APK. Istnieją wyjątki od tej reguły. zalecenie. Gdy Usługi Google Play mogą być niedostępne na znacznej części urządzeń, na których będzie działać Twoja aplikacja, bardziej odpowiednie może być użycie aplikacji Cronet Embedded lub OkHttp. Korzystanie z wbudowanych funkcji stos sieciowy może być akceptowalny, jeśli rozmiar pliku APK stanowi poważny problem lub jeśli multimedia strumieniowanie to tylko niewielką część funkcjonalności aplikacji.

Oprócz multimediów zwykle dobrze jest też wybrać jeden stos sieciowy dla wszystkich sieci wykorzystywanych przez aplikację. Dzięki temu zasoby (np. gniazdek) w celu efektywnego łączenia i współdzielenia między ExoPlayer i innymi komponentów aplikacji.

Ponieważ aplikacja najprawdopodobniej będzie musiała wykonywać czynności sieciowe niezwiązane z siecią. podczas odtwarzania multimediów, wybrany stos sieciowy powinien wziąć pod uwagę powyżej zaleceń dotyczących niezależnego strumieniowania multimediów, inne elementy obsługujące sieci oraz ich znaczenie w stosunku do Twojej .

Buforowanie multimediów

ExoPlayer obsługuje buforowanie wczytane bajty na dysk, aby zapobiec wielokrotnemu ładowaniu takie same bajty z sieci. Jest to przydatne przy przewijaniu wstecz w bieżącym okresie lub powtarzanie tego samego elementu.

Buforowanie wymaga, aby instancja SimpleCache wskazywała dedykowaną pamięć podręczną i 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();