Ağ yığınları

ExoPlayer genellikle internet üzerinden medya akışı için kullanılır. Temel ağ isteklerini yapmak için birden fazla ağ yığınını destekler. Ağ yığını seçiminiz, akış performansını önemli ölçüde etkileyebilir.

Bu sayfada; seçtiğiniz ağ yığınınızı kullanmak için ExoPlayer'ı nasıl yapılandıracağınız özetlenmiş, mevcut seçenekler listelenmiştir. Uygulamanız için ağ yığını seçimi ile ilgili yol gösterici bilgiler ve akışlı 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, verileri DataSource bileşenler aracılığıyla yükler. Bu bileşenleri, uygulama kodundan yerleştirilen DataSource.Factory örnekten edinir.

Uygulamanızın yalnızca http(s) içeriği oynatması gerekiyorsa bir ağ yığını seçmek, uygulamanızın yerleştirdiği 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 öğesini kullanın:

Kotlin

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

Java

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

Bu örnekte PreferredHttpDataSource.Factory, tercih ettiğiniz ağ yığınına karşılık gelen fabrikadır. DefaultDataSource.Factory katmanı, yerel dosyalar gibi http olmayan kaynakları destekler.

Aşağıdaki örnekte, Cronet ağ yığınını kullanacak ve http olmayan içeriğin oynatılmasını destekleyecek 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; Cronet, OkHttp ve Android'in yerleşik 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.

Cronet

Cronet, Android uygulamalarında kitaplık olarak kullanıma sunulan Chromium ağ yığınıdır. Cronet, ExoPlayer tarafından yapılanlar da dahil olmak üzere uygulamanızın çalışması gereken ağ isteklerinin işleme hızını artıran ve gecikmeyi azaltan birçok teknolojiden yararlanır. Yerel olarak QUIC protokolleri üzerinden HTTP, HTTP/2 ve HTTP/3'ü destekler. Cronet, YouTube da 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. Nasıl kullanılacağıyla ilgili ayrıntılı talimatlar için kitaplığın README.md sayfasına bakın. 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ını (DefaultHttpDataSource) kullanmanızı öneririz.
  2. Yerleşik Kronet: Kullanıcılarınızın büyük bir yüzdesi 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. Cronet Embedded'ın en önemli dezavantajı uygulamanıza yaklaşık 8 MB eklemesidir.
  3. Cronet Yedek: Cronet'in yedek uygulaması, Chrome'un API'sini Android'in yerleşik ağ yığınının etrafına bir sarmalayıcı olarak uygular. Android'in yerleşik ağ yığınını doğrudan (DefaultHttpDataSource kullanarak) kullanmak daha verimli olduğundan ExoPlayer ile kullanılmamalıdır.

OkHttp

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

ExoPlayer, OkHttp kitaplığı aracılığıyla OkHttp'yi destekler. Nasıl kullanılacağıyla ilgili ayrıntılı talimatlar için kitaplığın README.md sayfasına bakın. OkHttp kitaplığını kullanırken ağ yığını uygulamanın içine yerleştirilir. Bu, Cronet Embedded'a benzer ancak OkHttp çok daha küçüktür ve uygulamanıza 1 MB'ın altında ekleme yapar.

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ımını destekler.

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

Diğer ağ yığınları

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

Sadece Java ağ yığınıyla entegrasyon yaparken HttpDataSource uygulamanızın doğru çalışıp çalışmadığını kontrol etmek için DataSourceContractTest uygulamak iyi bir fikirdir. OkHttp kitaplığındaki OkHttpDataSourceContractTest, bunun nasıl yapılacağını gösteren iyi bir örnektir.

Ağ yığını seçme

Aşağıdaki tabloda, ExoPlayer tarafından desteklenen ağ yığınlarının artıları ve eksileri özetlenmiştir.

Ağ yığını Protokoller APK boyutu etkisi Notlar
Cronet (Google Play Hizmetleri) QUIC üzerinden HTTP
HTTP/2
HTTP/3
Küçük
(<100 KB)
Google Play Hizmetleri gerekir. Cronet sürümü otomatik olarak güncellenir
Cronet (Katıştırılmış) QUIC üzerinden HTTP
HTTP/2
HTTP/3
Büyük
(~8 MB)
Uygulama geliştirici tarafından kontrol edilen Cronet sürümü
Cronet (Yedek) HTTP
(cihaza göre değişiklik gösterir)
Küçük
(<100 KB)
ExoPlayer için önerilmez
OkHttp HTTP
HTTP/2
Küçük
(<1 MB)
Kotlin çalışma zamanı gerektirir
Yerleşik ağ yığını HTTP
(cihaza göre değişiklik gösterir)
Yok Uygulama cihaza göre değişir

QUIC protokolleri üzerinden HTTP/2 ve HTTP/3, medya akışı performansını önemli ölçüde iyileştirebilir. Özellikle, bir içerik dağıtım ağı (CDN) kullanılarak dağıtılan uyarlanabilir medya akışı sırasında, bu protokollerin kullanımının CDN'lerin çok daha verimli bir şekilde çalışmasına olanak tanıdığı durumlar vardır. Bu nedenle, içeriğin barındırıldığı sunucuların da bu protokolleri desteklemesi koşuluyla, Cronet'in QUIC üzerinden hem HTTP/2 hem de HTTP/3 desteği (ve OkHttp'nin HTTP/2 desteği), Android'in yerleşik ağ yığınını kullanmaya kıyasla önemli bir avantajıdır.

Medya akışını ayrı olarak değerlendirirken, Google Play Hizmetleri tarafından sağlanan Cronet'i kullanmanızı (Google Play Hizmetleri kullanılamıyorsa) DefaultHttpDataSource olarak belirlemenizi öneririz. 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şlevselliğinin yalnızca küçük bir parçasıysa yerleşik ağ yığınının kullanımı kabul edilebilir.

Uygulamanızın medya olarak gerçekleştirdiği tüm ağ iletişimi için tek bir ağ yığını seçmek iyi bir fikirdir. Bu, kaynakların (yuvalar gibi) verimli bir şekilde havuza alınmasına ve ExoPlayer ile diğer uygulama bileşenleri arasında paylaşılmasına olanak tanır.

Uygulamanızın büyük olasılıkla medya oynatmayla ilgili olmayan ağ iletişimi gerçekleştirmesi gerekeceğinden, ağ yığını seçiminiz nihayetinde yukarıda izole medya akışı ile ilgili önerilerimizi, ağ iletişimi gerçekleştiren diğer bileşenlerin gereksinimlerini ve bunların uygulamanız için görece önemini hesaba katmalıdır.

Medya önbelleğe alınıyor

ExoPlayer, aynı baytların ağdan sürekli olarak yüklenmesini önlemek için yüklü baytların diske önbelleğe alınmasını destekler. Bu, mevcut medyada geri sarılırken veya aynı öğeyi tekrarlarken işe yarar.

Önbelleğe alma, özel bir önbellek dizinine ve CacheDataSource.Factory öğesine işaret eden bir SimpleCache örneği gerektirir:

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