Özelleştirme

ExoPlayer kitaplığının temelini Player arayüzü oluşturur. Player üst düzey medya oynatıcı işlevleri sunar. arabelleğe alma, oynatma, duraklatma ve sarma. Varsayılan uygulama ExoPlayer birkaç varsayımda bulunacak şekilde tasarlanmış (ve dolayısıyla oynatılan medyanın türü, nasıl ve nerede depolandığı ile oluşturulur. Doğrudan medyanın yüklenmesini ve oluşturulmasını uygulamak yerine, ExoPlayer uygulamaları, bu iş için yerleştirilen bileşenlere yetki verir Bir oynatıcı oluşturulduğunda veya oynatıcıya yeni medya kaynakları aktarıldığında. Tüm ExoPlayer uygulamalarında ortak bileşenler şunlardır:

  • Oynatılacak medyayı tanımlayan, medyayı yükleyen veMediaSource buradan okunabilir. MediaSource örneği oluşturuldu oyuncunun içinden bir MediaSource.Factory ile MediaItem kazandı. Ayrıca medya kaynağına dayalı oynatma listesi API'si kullanılarak doğrudan oynatıcıya iletilmelidir.
  • MediaItem öğesini MediaSource öğesine dönüştüren MediaSource.Factory örneği. İlgili içeriği oluşturmak için kullanılan Oynatıcı oluşturulduğunda MediaSource.Factory yerleştirilir.
  • Medyanın bağımsız bileşenlerini oluşturan Renderer örnek. Bunlar: oynatıcı oluşturulduğunda eklenir.
  • MediaSource tarafından sağlanacak parçaları seçen bir TrackSelector tükettiğini gösterir.Renderer TrackSelector yerleştirildi oynatıcı oluşturulduğunda.
  • MediaSource öğesinin ne zaman daha fazla medyayı arabelleğe alacağını kontrol eden bir LoadControl ve arabelleğe aldığına dikkat edin. Oyuncu şunları yaptığında bir LoadControl yerleştirilir: oluşturuldu.
  • Canlı yayın sırasında oynatma hızını kontrol eden bir LivePlaybackSpeedControl oynatma sayısını artırır. CEVAP Oynatıcı oluşturulduğunda LivePlaybackSpeedControl yerleştirilir.

Oynatıcı parçalarını uygulayan bileşenleri yerleştirme kavramı kitaplıktaki tüm özellikleri içerir. Varsayılan olarak kullanılan bazı bileşenler, işler için daha fazla yerleştirilen bileşenlere yetki verir. Bu sayede birçok uygulamaların, tüm alt bileşenlerin kendi uygulamalarındaki yapılandırılmış olması gerekir.

Oynatıcı özelleştirme

Bileşen ekleyerek oynatıcıyı özelleştirmenin yaygın örneklerinden bazıları bakın.

Ağ yığınını yapılandırma

ExoPlayer tarafından kullanılan ağ yığınını özelleştirme ile ilgili bir sayfamız var.

Ağdan yüklenen verileri önbelleğe alma

Şu konular için kılavuzlara bakın: anında önbelleğe alma ve medyayı indirir.

Sunucu etkileşimlerini özelleştirme

Bazı uygulamalar HTTP isteklerine ve yanıtlarına müdahale etmek isteyebilir. Birlikte çalıştığınız özel istek başlıkları ekleyin, sunucunun yanıt başlıklarını okuyun, talepleri URI'lar vb. başlık olarak kullanılacak bir jeton kullanmanız gerekir.

Aşağıdaki örnekte, bu davranışların DefaultMediaSourceFactory öğesine özel bir DataSource.Factory ekleniyor:

Kotlin

val dataSourceFactory =
  DataSource.Factory {
    val dataSource = httpDataSourceFactory.createDataSource()
    // Set a custom authentication request header.
    dataSource.setRequestProperty("Header", "Value")
    dataSource
  }
val player =
  ExoPlayer.Builder(context)
    .setMediaSourceFactory(
      DefaultMediaSourceFactory(context).setDataSourceFactory(dataSourceFactory)
    )
    .build()

Java

DataSource.Factory dataSourceFactory =
    () -> {
      HttpDataSource dataSource = httpDataSourceFactory.createDataSource();
      // Set a custom authentication request header.
      dataSource.setRequestProperty("Header", "Value");
      return dataSource;
    };

ExoPlayer player =
    new ExoPlayer.Builder(context)
        .setMediaSourceFactory(
            new DefaultMediaSourceFactory(context).setDataSourceFactory(dataSourceFactory))
        .build();

Yukarıdaki kod snippet'inde, yerleştirilen HttpDataSource öğesi üst bilgiyi içerir Her HTTP isteğinde "Header: Value". Bu davranış her cihaz için sabit bir HTTP kaynağıyla etkileşim kurmanız gerekir.

Daha ayrıntılı bir yaklaşım için, tek bir etiket kullanarak tam zamanında davranış ResolvingDataSource Aşağıdaki kod snippet'i bir HTTP kaynağıyla etkileşimde bulunmadan hemen önce üstbilgilerini isteyin:

Kotlin

val dataSourceFactory: DataSource.Factory =
  ResolvingDataSource.Factory(httpDataSourceFactory) { dataSpec: DataSpec ->
    // Provide just-in-time request headers.
    dataSpec.withRequestHeaders(getCustomHeaders(dataSpec.uri))
  }

Java

    DataSource.Factory dataSourceFactory =
        new ResolvingDataSource.Factory(
            httpDataSourceFactory,
            // Provide just-in-time request headers.
            dataSpec -> dataSpec.withRequestHeaders(getCustomHeaders(dataSpec.uri)));

Ayrıca, şunları gerçekleştirmek için bir ResolvingDataSource kullanabilirsiniz: aşağıdaki snippet'te gösterildiği gibi URI'nın tam zamanında değiştirilmesi:

Kotlin

val dataSourceFactory: DataSource.Factory =
  ResolvingDataSource.Factory(httpDataSourceFactory) { dataSpec: DataSpec ->
    // Provide just-in-time URI resolution logic.
    dataSpec.withUri(resolveUri(dataSpec.uri))
  }

Java

DataSource.Factory dataSourceFactory =
    new ResolvingDataSource.Factory(
        httpDataSourceFactory,
        // Provide just-in-time URI resolution logic.
        dataSpec -> dataSpec.withUri(resolveUri(dataSpec.uri)));

Hata işlemeyi özelleştirme

Özel bir LoadErrorHandlingPolicy kullanmak, uygulamaların nasıl tepki verdiğini gösterir. Örneğin, bir uygulama başarısız olmak tekrar denemek yerine geri alma mantığını oynatıcının her yeniden deneme arasında ne kadar bekleyeceğini kontrol eder. Aşağıdaki snippet özel geri yükleme mantığının nasıl uygulanacağını gösterir:

Kotlin

val loadErrorHandlingPolicy: LoadErrorHandlingPolicy =
  object : DefaultLoadErrorHandlingPolicy() {
    override fun getRetryDelayMsFor(loadErrorInfo: LoadErrorInfo): Long {
      // Implement custom back-off logic here.
      return 0
    }
  }
val player =
  ExoPlayer.Builder(context)
    .setMediaSourceFactory(
      DefaultMediaSourceFactory(context).setLoadErrorHandlingPolicy(loadErrorHandlingPolicy)
    )
    .build()

Java

LoadErrorHandlingPolicy loadErrorHandlingPolicy =
    new DefaultLoadErrorHandlingPolicy() {
      @Override
      public long getRetryDelayMsFor(LoadErrorInfo loadErrorInfo) {
        // Implement custom back-off logic here.
        return 0;
      }
    };

ExoPlayer player =
    new ExoPlayer.Builder(context)
        .setMediaSourceFactory(
            new DefaultMediaSourceFactory(context)
                .setLoadErrorHandlingPolicy(loadErrorHandlingPolicy))
        .build();

LoadErrorInfo bağımsız değişkeni, başarısız yükleme hakkında daha fazla bilgi içerir. hata türüne veya başarısız isteğe göre mantığı özelleştirin.

Ayıklayıcı işaretlerini özelleştirme

Ayıklayıcı işaretleri, tek tek biçimlerin ayıklanma şeklini özelleştirmek için kullanılabilir bu teknolojiden faydalanabilirsiniz. Bunlar, DefaultExtractorsFactory DefaultMediaSourceFactory sağlanana kadar. Aşağıdaki örnekte bir flag özelliği başarılı MP3 akışları için dizine dayalı aramayı mümkün kılan bir özelliktir.

Kotlin

val extractorsFactory =
  DefaultExtractorsFactory().setMp3ExtractorFlags(Mp3Extractor.FLAG_ENABLE_INDEX_SEEKING)
val player =
  ExoPlayer.Builder(context)
    .setMediaSourceFactory(DefaultMediaSourceFactory(context, extractorsFactory))
    .build()

Java

DefaultExtractorsFactory extractorsFactory =
    new DefaultExtractorsFactory().setMp3ExtractorFlags(Mp3Extractor.FLAG_ENABLE_INDEX_SEEKING);

ExoPlayer player =
    new ExoPlayer.Builder(context)
        .setMediaSourceFactory(new DefaultMediaSourceFactory(context, extractorsFactory))
        .build();

Sabit bit hızında sarma özelliğini etkinleştirme

MP3, ADTS ve AMR akışları için yaklaşık sarma özelliğini kullanarak FLAG_ENABLE_CONSTANT_BITRATE_SEEKING flag'leriyle sabit bit hızı varsayımı. Bu flag'ler, DefaultExtractorsFactory.setXyzExtractorFlags yöntemini çağırın. Alıcı: destekleyen tüm ayıklayıcılar için sabit bit hızı arama özelliğini etkinleştirmeli, DefaultExtractorsFactory.setConstantBitrateSeekingEnabled

Kotlin

val extractorsFactory = DefaultExtractorsFactory().setConstantBitrateSeekingEnabled(true)

Java

DefaultExtractorsFactory extractorsFactory =
    new DefaultExtractorsFactory().setConstantBitrateSeekingEnabled(true);

Daha sonra ExtractorsFactory, DefaultMediaSourceFactory aracılığıyla şu şekilde eklenebilir: yukarıda ayıklayıcı işaretlerini özelleştirmek için açıklanmıştır.

Eşzamansız arabellek sırasına almayı etkinleştirme

Eşzamansız arabellek sırası, ExoPlayer'ın oluşturma işlevindeki bir iyileştirmedir ve MediaCodec örneklerini eşzamansız modda çalıştıran ardışık düzen kod çözmeyi ve verilerin oluşturulmasını planlamak için ek iş parçacıkları kullanır. Etkinleştirme atlanan kareleri ve ses kesintilerini azaltabilir.

Android 12 çalıştıran cihazlarda eşzamansız arabellek sıraya alma özelliği varsayılan olarak etkindir (API düzeyi 31) ve sonraki sürümlerde çalışır. Android 6.0 (API düzeyi 23) sürümünden itibaren manuel olarak etkinleştirilebilir. Özelliğin düştüğünü gördüğünüz belirli cihazlar için bu özelliği etkinleştirebilirsiniz. özellikle DRM korumalı veya yüksek kare hızında oynatırken kareler veya seste düşüşler içerik.

En basit şekilde, bir DefaultRenderersFactory oynatıcı şu şekildedir:

Kotlin

val renderersFactory = 
  DefaultRenderersFactory(context).forceEnableMediaCodecAsynchronousQueueing()
val exoPlayer = ExoPlayer.Builder(context, renderersFactory).build()

Java

DefaultRenderersFactory renderersFactory =
    new DefaultRenderersFactory(context).forceEnableMediaCodecAsynchronousQueueing();
ExoPlayer exoPlayer = new ExoPlayer.Builder(context, renderersFactory).build();

Oluşturucuları doğrudan örnekliyorsanız AsynchronousMediaCodecAdapter.Factory - MediaCodecVideoRenderer ve MediaCodecAudioRenderer oluşturucu.

ForwardingPlayer ile yöntem çağrılarına müdahale etme

Bir Player örneğinin davranışının bazılarını içine sarmalayarak özelleştirebilirsiniz. yapmak için ForwardingPlayer alt sınıfını ve geçersiz kılma yöntemlerini şu:

  • Parametrelere, yetkili Player kullanıcısına iletmeden önce erişin.
  • Döndürmeden önce yetki verilen Player kullanıcısının döndürülen değerine erişin.
  • Yöntemi tamamen tekrar uygulayın.

ForwardingPlayer yöntemlerini geçersiz kılarken uygulama tutarlılığı ve Player ile uyumludur özellikle de etkili bir şekilde çalışması amaçlanan yöntemlerle benzer ya da alakalı davranış olabilir. Örnek:

  • Her "oynatma" işlemini geçersiz kılmak istiyorsanız işlemi için hem ForwardingPlayer.play ve ForwardingPlayer.setPlayWhenReady, çünkü arayanlar, bu yöntemlerin davranışının playWhenReady = true.
  • İleri sarma değerini değiştirmek isterseniz ileri sarmayı değiştirmek isterseniz Özelleştirilmiş cihazınızla bir arama gerçekleştirmek için ForwardingPlayer.seekForward ve ForwardingPlayer.getSeekForwardIncrement değerini raporlamak için doğru özelleştirilmiş artışı arayan kişiye geri söyler.
  • Bir oyuncunun hangi Player.Commands reklamı yapacağını kontrol etmek istiyorsanız için hem Player.getAvailableCommands() hem de örneğin geçersiz kılınması gerekir. Player.isCommandAvailable() ve ayrıca şunları dinleyin: Bildirim almak için Player.Listener.onAvailableCommandsChanged() geri arama temeldeki oynatıcıdan gelen değişiklikleri gösterebilir.

MediaSource'u özelleştirme

Yukarıdaki örneklerde, tüm reklam öğelerinin oynatılması sırasında kullanılmak üzere Oynatıcıya MediaItem nesne aktarılır. Hassas özelleştirme, Ayrıca, özelleştirilmiş bileşenleri kendi bileşenlerine MediaSource örnek (doğrudan oynatıcıya iletilebilir). Örnek Aşağıda, özel bir değer kullanmak için ProgressiveMediaSource öğesinin nasıl özelleştirileceği gösterilmektedir DataSource.Factory, ExtractorsFactory ve LoadErrorHandlingPolicy:

Kotlin

val mediaSource =
  ProgressiveMediaSource.Factory(customDataSourceFactory, customExtractorsFactory)
    .setLoadErrorHandlingPolicy(customLoadErrorHandlingPolicy)
    .createMediaSource(MediaItem.fromUri(streamUri))

Java

ProgressiveMediaSource mediaSource =
    new ProgressiveMediaSource.Factory(customDataSourceFactory, customExtractorsFactory)
        .setLoadErrorHandlingPolicy(customLoadErrorHandlingPolicy)
        .createMediaSource(MediaItem.fromUri(streamUri));

Özel bileşenler oluşturma

Kitaplık, üst kısımda listelenen bileşenlerin varsayılan uygulamalarını sağlar bakın. ExoPlayer bu bileşenleri kullanabilir ancak standart dışı davranışlar ise özel uygulamalar için de oluşturulabilir. gereklidir. Özel uygulamalar için bazı kullanım alanları şunlardır:

  • Renderer – Belirli bir öğeyi işlemek için özel bir Renderer tarafından sağlanan varsayılan uygulamaların desteklediği medya türü kitaplığını açar.
  • TrackSelector – Özel bir TrackSelector uygulandığında uygulama bir MediaSource tarafından sunulan kanalların izleme ve mevcut Renderer öğelerinin her biri tarafından tüketilmek üzere seçilmiştir.
  • LoadControl – Özel bir LoadControl uygulandığında uygulama geliştiricinin arabelleğe alma politikasını değiştirmesini isteyin.
  • Extractor: Şu anda desteklenmeyen bir kapsayıcı biçimini desteklemeniz gerekiyorsa kitaplığı tarafından desteklendiğinde, özel bir Extractor sınıfı uygulamanız önerilir.
  • MediaSource – Özel MediaSource sınıfı uygulamak görüntüleyicilere yayınlayacağınız medya örneklerini özel yöntem veya özel MediaSource birleştirme uygulamak istiyorsanız gösterir.
  • MediaSource.Factory – Özel MediaSource.Factory uygulama uygulamanın, bir MediaSource oluşturulma biçimini özelleştirmesine izin verir MediaItem ile başlayan fiyatlarla!
  • DataSource – ExoPlayer'ın yukarı akış paketi halihazırda Farklı kullanım alanları için DataSource uygulamaları. Birlikte çalıştığınız Verileri başka bir yöntemle yüklemek için kendi DataSource sınıfınızı uygulayın: özel bir protokolden, özel bir HTTP yığınından veya özel bir kalıcı ağdan önbellek.

Özel bileşenler oluştururken aşağıdakileri öneririz:

  • Bir özel bileşenin etkinlikleri uygulamaya geri bildirmesi gerekiyorsa mevcut ExoPlayer bileşenleriyle aynı modeli kullanarak bunu yapmanızı sağlar: EventDispatcher sınıfların kullanıldığı veya bir Handler bileşenin oluşturucusu için bir dinleyici olarak ayarlanır.
  • Özel bileşenlerin mevcut ExoPlayer ile aynı modeli kullanmasını önerdik Bu bileşenler, oynatma sırasında uygulama tarafından yeniden yapılandırmaya olanak tanır. Bunu yapmak için özel bileşenler PlayerMessage.Target uygulayabilir ve handleMessage yöntemindeki yapılandırma değişiklikleri. Uygulama kodu ExoPlayer'ın createMessage yöntemini çağırarak yapılandırma değişikliklerini iletin, mesajı yapılandırıp PlayerMessage.send. Oynatma dizisinde teslim edilecek mesajları gönderme ve bu politikaların, yürütülen diğer işlemlerle uyumlu olarak yürütülmesini sağlar. birkaç değişiklik gösterir.