Ağ yığınları

ExoPlayer, internet üzerinden medya akışı için yaygın olarak kullanılır. Temel ağ isteklerini yapmak için birden fazla ağ yığınını destekler. Seçtiğiniz ağ yığını, akış performansını önemli ölçüde etkileyebilir.

Bu sayfada, ExoPlayer'ı tercih ettiğiniz ağ yığınını kullanacak şekilde nasıl yapılandıracağınız açıklanmakta, mevcut seçenekler listelenmekte, uygulamanız için ağ yığını seçme konusunda bazı bilgiler verilmekte ve akışla aktarılan medya için önbelleğe almanın nasıl etkinleştirileceği açıklanmaktadır.

ExoPlayer'ı belirli bir ağ yığınını kullanacak şekilde yapılandırma

ExoPlayer, uygulama kodundan eklenen DataSource.Factory örneklerinden aldığı DataSource bileşenleri aracılığıyla veri yükler.

Uygulamanızın yalnızca http(s) içerik oynatması gerekiyorsa ağ yığını seçmek, uygulamanızın eklediği tüm DataSource.Factory örneklerini, kullanmak istediğiniz ağ yığınına karşılık gelen HttpDataSource.Factory örnekleri olacak şekilde güncellemek kadar basittir. Uygulamanızın yerel dosyalar gibi HTTP(S) olmayan içerikleri de oynatması gerekiyorsa DefaultDataSource.Factory kullanın:

Kotlin

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

Java

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

Bu örnekte PreferredHttpDataSource.Factory, tercih ettiğiniz ağ yığınına karşılık gelen fabrikadır. DefaultDataSource.Factory katmanı, yerel dosyalar gibi HTTP(S) olmayan kaynaklar için destek ekler.

Aşağıdaki örnekte, Cronet ağ yığınını kullanan ve HTTP(S) olmayan içeriklerin oynatılmasını da destekleyen bir ExoPlayer öğesinin nasıl oluşturulacağı gösterilmektedir.

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();

Desteklenen ağ yığınları

ExoPlayer; HttpEngine, Cronet, OkHttp ve Android'in yerleşik varsayılan ağ yığını için doğrudan destek sağlar. ExoPlayer, Android'de çalışan diğer ağ yığınlarını destekleyecek şekilde de genişletilebilir.

HttpEngine

HttpEngine, API 34'ten (veya S uzantıları 7) itibaren Android'de önerilen varsayılan ağ yığınıdır. Çoğu durumda, dahili olarak Cronet ağ yığınını kullanır ve QUIC protokolleri üzerinden HTTP, HTTP/2 ve HTTP/3'ü destekler.

ExoPlayer, HttpEngineDataSource.Factory ile HttpEngine'i destekler. Bu veri kaynağı fabrikasını, ExoPlayer'ı belirli bir ağ yığınını kullanacak şekilde yapılandırma bölümünde açıklandığı gibi ekleyebilirsiniz.

Cronet

Cronet, Android uygulamalarına kitaplık olarak sunulan Chromium ağ yığınıdır. Cronet, uygulamanızın çalışması için gereken ağ isteklerinin (ExoPlayer tarafından yapılanlar dahil) gecikmesini azaltan ve işleme hızını artıran birden fazla teknolojiden yararlanır. QUIC protokolleri üzerinden HTTP, HTTP/2 ve HTTP/3'ü yerel olarak destekler. Cronet, YouTube dahil olmak üzere dünyanın en büyük yayın uygulamalarından bazıları tarafından kullanılır.

ExoPlayer, Cronet kitaplığı aracılığıyla Cronet'i destekler. Kitaplığın nasıl kullanılacağına ilişkin ayrıntılı talimatlar için README.md sayfasını inceleyin. Cronet kitaplığının üç temel Cronet uygulamasını kullanabildiğini unutmayın:

  1. Google Play Hizmetleri: Çoğu durumda bu uygulamayı kullanmanızı ve Google Play Hizmetleri kullanılamıyorsa Android'in yerleşik ağ yığınına (DefaultHttpDataSource) geri dönmenizi öneririz.
  2. Cronet Embedded: Kullanıcılarınızın büyük bir kısmı Google Play Hizmetleri'nin yaygın olarak kullanılamadığı pazarlardaysa veya kullanılan Cronet uygulamasının tam sürümünü kontrol etmek istiyorsanız iyi bir seçim olabilir. Yerleşik Cronet'in en büyük dezavantajı, uygulamanıza yaklaşık 8 MB eklemesidir.
  3. Cronet Fallback: Cronet'in yedek uygulaması, Cronet'in API'sini Android'in yerleşik ağ yığınının etrafında bir sarmalayıcı olarak uygular. Android'in yerleşik ağ yığınını doğrudan kullanmak (DefaultHttpDataSource kullanarak) daha verimli olduğundan ExoPlayer ile kullanılmamalıdır.

OkHttp

OkHttp, birçok popüler Android uygulamasında yaygın olarak kullanılan başka bir modern ağ yığınıdır. HTTP ve HTTP/2'yi destekler ancak QUIC üzerinden HTTP/3'ü henüz desteklemez.

ExoPlayer, OkHttp kitaplığı aracılığıyla OkHttp'yi destekler. Kitaplığın nasıl kullanılacağına ilişkin ayrıntılı talimatlar için README.md sayfasına bakın. OkHttp kitaplığı kullanılırken ağ yığını uygulamaya yerleştirilir. Bu, Cronet Embedded'a benzer ancak OkHttp çok daha küçüktür ve uygulamanıza 1 MB'tan daha az yer kaplar.

Android'in yerleşik ağ yığını

ExoPlayer, temel ExoPlayer kitaplığının bir parçası olan DefaultHttpDataSource ve DefaultHttpDataSource.Factory ile Android'in yerleşik ağ yığınının kullanılmasını destekler.

Ağ yığınının tam olarak nasıl uygulanacağı, temel cihazda çalışan yazılıma bağlıdır. Çoğu cihazda yalnızca HTTP desteklenir (yani QUIC üzerinden HTTP/2 ve HTTP/3 desteklenmez).

Diğer ağ yığınları

Uygulamalar, diğer ağ yığınlarını da ExoPlayer ile entegre edebilir. Bunu yapmak için ağ yığınını sarmalayan bir HttpDataSource ve buna karşılık gelen bir HttpDataSource.Factory uygulayın. ExoPlayer'ın Cronet ve OkHttp kitaplıkları, bunun nasıl yapılacağına dair iyi örneklerdir.

Saf Java ağ yığınıyla entegrasyon yaparken HttpDataSource uygulamanızın doğru şekilde davrandığını kontrol etmek için bir DataSourceContractTest uygulamanız önerilir. OkHttpDataSourceContractTest, bunun nasıl yapılacağına dair iyi bir örnektir.

Ağ yığını seçme

Aşağıdaki tabloda, ExoPlayer tarafından desteklenen ağ yığınlarının avantajları ve dezavantajları açıklanmaktadır.

Ağ yığını Protokoller APK boyutuna etkisi Notlar
HttpEngine HTTP
HTTP/2
QUIC üzerinden HTTP/3
Yok Yalnızca API 34 veya S Extensions 7'de kullanılabilir
Cronet (Google Play Hizmetleri) HTTP
HTTP/2
QUIC üzerinden HTTP/3
Küçük
(<100 KB)
Google Play Hizmetleri gerekir. Cronet sürümü otomatik olarak güncellenir
Cronet (Yerleşik) HTTP
HTTP/2
QUIC üzerinden HTTP/3
Büyük
(~8 MB)
Cronet sürümü, uygulama geliştirici tarafından kontrol edilir
Cronet (Yedek) HTTP
(cihaza göre değişir)
Küçük
(<100 KB)
ExoPlayer için önerilmez
OkHttp HTTP
HTTP/2
Küçük
(<1 MB)
Yerleşik ağ yığını HTTP
(cihaza göre değişir)
Yok Uygulama cihaza göre değişir

QUIC üzerinden HTTP/2 ve HTTP/3 protokolleri, medya akışı performansını önemli ölçüde artırabilir. Özellikle bir içerik dağıtım ağı (CDN) kullanılarak dağıtılan uyarlanabilir medya akışı yapılırken bu protokollerin kullanılması, CDN'lerin çok daha verimli çalışmasını sağlayabilir. Bu nedenle, HttpEngine ve Cronet'in QUIC üzerinden hem HTTP/2 hem de HTTP/3'ü (ve OkHttp'nin HTTP/2'yi) desteklemesi, içeriğin barındırıldığı sunucuların da bu protokolleri desteklemesi koşuluyla Android'in yerleşik ağ yığınını kullanmaya kıyasla büyük bir avantajdır.

Yalnızca medya akışı için Google Play Hizmetleri tarafından sağlanan HttpEngine veya Cronet'i kullanmanızı öneririz. Google Play Hizmetleri kullanılamıyorsa DefaultHttpDataSource kullanabilirsiniz. Bu öneri, çoğu cihazda QUIC üzerinden HTTP/2 ve HTTP/3 kullanımını etkinleştirme ile APK boyutunda önemli bir artıştan kaçınma arasında iyi bir denge sağlar. Bu önerinin istisnaları vardır. Google Play Hizmetleri'nin, uygulamanızı çalıştıracak cihazların önemli bir kısmında kullanılamayabileceği durumlarda Cronet Embedded veya OkHttp kullanmak daha uygun olabilir. APK boyutu kritik bir sorunsa veya medya akışı uygulamanızın işlevinin yalnızca küçük bir parçasıysa yerleşik ağ yığınının kullanımı kabul edilebilir.

Yalnızca medya için değil, uygulamanız tarafından gerçekleştirilen tüm ağ işlemleri için tek bir ağ yığını seçmek genellikle iyi bir fikirdir. Bu sayede kaynaklar (ör. soketler) verimli bir şekilde toplanabilir ve ExoPlayer ile diğer uygulama bileşenleri arasında paylaşılabilir.

Uygulamanızın büyük olasılıkla medya oynatmayla ilgili olmayan ağ işlemleri gerçekleştirmesi gerekeceğinden, ağ yığını seçiminizde yukarıdaki medya akışıyla ilgili önerilerimiz, ağ işlemleri gerçekleştiren diğer bileşenlerin gereksinimleri ve bunların uygulamanız açısından önemi dikkate alınmalıdır.

Medya önbelleğe alınıyor

ExoPlayer, aynı baytların ağdan tekrar tekrar yüklenmesini önlemek için yüklenen baytların diske önbelleğe alınmasını destekler. Bu, mevcut medyada geri gitmek veya aynı öğeyi tekrarlamak istediğinizde kullanışlıdır.

Önbelleğe alma için özel bir önbellek dizinine işaret eden bir SimpleCache örneği ve bir CacheDataSource.Factory gerekir:

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();