Medya indiriliyor

ExoPlayer, çevrimdışı oynatma için medya indirme işlevi sağlar. Çoğu zaman durumlarda, uygulamanız belirli bir tarayıcıdayken bile indirmelerin devam etmesi arka plan. Uygulamanız bu kullanım alanlarında DownloadService ve indirmeleri eklemek, kaldırmak ve kontrol etmek için hizmete komutlar gönderin. İlgili içeriği oluşturmak için kullanılan dahil olan ana sınıfları aşağıdaki şemada görebilirsiniz.

Medya indirme sınıflar. Ok yönleri veri akışını gösterir.

  • DownloadService: DownloadManager öğesini sarmalar ve komutları buna yönlendirir. İlgili içeriği oluşturmak için kullanılan hizmet, uygulama etkinken bile DownloadManager uygulamasının çalışmaya devam etmesine olanak tanır. görebilirsiniz.
  • DownloadManager: Birden fazla indirme işlemini, bunların yüklenmesini (ve depolamasını) yönetir DownloadIndex ile başlayan (ve - arasındaki) indirme işlemlerini başlatır ve durdurur. ağ bağlantısı gibi gereksinimlere göre değişir. yönetici, normalde bir e-postadan indirilen verileri HttpDataSource ve Cache bölümüne yazabilirsiniz.
  • DownloadIndex: İndirilenlerin durumu değişmez.

DownloadService Oluşturma

Bir DownloadService oluşturmak için, alt sınıflandırmayı yapın ve soyut yöntemler:

  • getDownloadManager(): Kullanılacak DownloadManager değerini döndürür.
  • getScheduler(): İsteğe bağlı bir Scheduler döndürür. Bu, hizmeti kullanılabilir. ExoPlayer şu uygulamaları sağlar:
    • PlatformScheduler, jobScheduler'ı kullanıyor (Minimum API 21'dir). Görüntüleyin Uygulama izni gereksinimleri için PlatformScheduler Javadocs'a gidin.
    • WorkManager kullanan WorkManagerScheduler.
  • getForegroundNotification(): ön planda çalışıyor. Tekliflerinizi otomatikleştirmek ve optimize etmek için oluşturmak için DownloadNotificationHelper.buildProgressNotification bildirimi varsayılan stilde sunar.

Son olarak, AndroidManifest.xml dosyanızda hizmeti tanımlayın:

<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC"/>
<application>
  <service android:name="com.myapp.MyDownloadService"
      android:exported="false"
      android:foregroundServiceType="dataSync">
    <!-- This is needed for Scheduler -->
    <intent-filter>
      <action android:name="androidx.media3.exoplayer.downloadService.action.RESTART"/>
      <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
  </service>
</application>

ExoPlayer'da DemoDownloadService ve AndroidManifest.xml dillerine bakın demo uygulaması.

İndirme Yöneticisi Oluşturma

Aşağıdaki kod snippet'i bir DownloadManager örneğinin nasıl çıkarılacağını gösterir. Bu değer, DownloadService içinde getDownloadManager() tarafından iade edilebilir:

Kotlin

// Note: This should be a singleton in your app.
val databaseProvider = StandaloneDatabaseProvider(context)

// A download cache should not evict media, so should use a NoopCacheEvictor.
val downloadCache = SimpleCache(downloadDirectory, NoOpCacheEvictor(), databaseProvider)

// Create a factory for reading the data from the network.
val dataSourceFactory = DefaultHttpDataSource.Factory()

// Choose an executor for downloading data. Using Runnable::run will cause each download task to
// download data on its own thread. Passing an executor that uses multiple threads will speed up
// download tasks that can be split into smaller parts for parallel execution. Applications that
// already have an executor for background downloads may wish to reuse their existing executor.
val downloadExecutor = Executor(Runnable::run)

// Create the download manager.
val downloadManager =
  DownloadManager(context, databaseProvider, downloadCache, dataSourceFactory, downloadExecutor)

// Optionally, properties can be assigned to configure the download manager.
downloadManager.requirements = requirements
downloadManager.maxParallelDownloads = 3

Java

// Note: This should be a singleton in your app.
databaseProvider = new StandaloneDatabaseProvider(context);

// A download cache should not evict media, so should use a NoopCacheEvictor.
downloadCache = new SimpleCache(downloadDirectory, new NoOpCacheEvictor(), databaseProvider);

// Create a factory for reading the data from the network.
dataSourceFactory = new DefaultHttpDataSource.Factory();

// Choose an executor for downloading data. Using Runnable::run will cause each download task to
// download data on its own thread. Passing an executor that uses multiple threads will speed up
// download tasks that can be split into smaller parts for parallel execution. Applications that
// already have an executor for background downloads may wish to reuse their existing executor.
Executor downloadExecutor = Runnable::run;

// Create the download manager.
downloadManager =
    new DownloadManager(
        context, databaseProvider, downloadCache, dataSourceFactory, downloadExecutor);

// Optionally, setters can be called to configure the download manager.
downloadManager.setRequirements(requirements);
downloadManager.setMaxParallelDownloads(3);

Somut bir örnek için demo uygulamasında DemoUtil bağlantısına bakın.

İndirilen dosya ekleme

İndirme eklemek için bir DownloadRequest oluşturun ve DownloadService. Uyarlanabilir akışlarda DownloadHelper özelliğini kullanarak şuna yardımcı olabilirsiniz: bir DownloadRequest oluşturun. Aşağıdakiler örnekte, bir indirme isteğinin nasıl oluşturulacağı gösterilmektedir:

Kotlin

val downloadRequest = DownloadRequest.Builder(contentId, contentUri).build()

Java

DownloadRequest downloadRequest = new DownloadRequest.Builder(contentId, contentUri).build();

Bu örnekte contentId, içerik için benzersiz bir tanımlayıcıdır. Basit durumlarda contentUri genellikle contentId olarak kullanılabilir ancak uygulamaları ücretsiz olarak kullanabilirsiniz bir kimlik şeması seçin. DownloadRequest.Builder adlı dokümanda ayrıca şunlar da var: sağlayabilirsiniz. Örneğin, setKeySetId ve setData şu amaçlarla kullanılabilir: DRM'yi ve uygulamanın indirme işlemiyle ilişkilendirmek istediği özel verileri ayarlayabilirsiniz. tıklayın. İçeriğin MIME türü setMimeType kullanılarak da belirtilebilir. kullanabilirsiniz.contentUri

İstek, oluşturulduktan sonra DownloadService uygulamasına gönderilebilir. indir:

Kotlin

DownloadService.sendAddDownload(
  context,
  MyDownloadService::class.java,
  downloadRequest,
  /* foreground= */ false
)

Java

DownloadService.sendAddDownload(
    context, MyDownloadService.class, downloadRequest, /* foreground= */ false);

Bu örnekte MyDownloadService, uygulamanın DownloadService alt sınıfı ve foreground parametresi, hizmetin ön plan. Uygulamanız zaten ön plandaysa foreground parametresi normalde false olarak ayarlanmalıdır, çünkü DownloadService yapabileceği iş olduğunu belirlerse kendisini ön plana çıkarabilir.

İndirilenler kaldırılıyor

İndirilen bir öğeyi kaldırmak için DownloadService API'sine bir kaldırma komutu gönderebilirsiniz. Burada contentId, kaldırılacak indirme işlemini tanımlar:

Kotlin

DownloadService.sendRemoveDownload(
  context,
  MyDownloadService::class.java,
  contentId,
  /* foreground= */ false
)

Java

DownloadService.sendRemoveDownload(
    context, MyDownloadService.class, contentId, /* foreground= */ false);

Ayrıca, indirilen tüm verileri şununla de kaldırabilirsiniz: DownloadService.sendRemoveAllDownloads

İndirme işlemlerini başlatma ve durdurma

İndirme işlemi ancak dört koşul karşılanırsa gerçekleşir:

  • İndirme işleminin bir durdurma nedeni yok.
  • İndirme işlemleri duraklatılmaz.
  • Devam etmek için indirme koşulları karşılanır. Gereksinimler izin verilen ağ türlerinin ve cihazın izin verilen ağ boşta veya şarj cihazına bağlı olmamalıdır.
  • Maksimum paralel indirme sayısı aşılmıyor.

Bu koşulların hepsi, e-postanıza komutlar gönderilerek DownloadService

İndirmeyi durdurma nedenlerini ayarlama ve temizleme

İndirmelerden birinin veya tüm indirme işlemlerinin durdurulması için bir neden belirlemek mümkündür:

Kotlin

// Set the stop reason for a single download.
DownloadService.sendSetStopReason(
  context,
  MyDownloadService::class.java,
  contentId,
  stopReason,
  /* foreground= */ false
)

// Clear the stop reason for a single download.
DownloadService.sendSetStopReason(
  context,
  MyDownloadService::class.java,
  contentId,
  Download.STOP_REASON_NONE,
  /* foreground= */ false
)

Java

// Set the stop reason for a single download.
DownloadService.sendSetStopReason(
    context, MyDownloadService.class, contentId, stopReason, /* foreground= */ false);

// Clear the stop reason for a single download.
DownloadService.sendSetStopReason(
    context,
    MyDownloadService.class,
    contentId,
    Download.STOP_REASON_NONE,
    /* foreground= */ false);

stopReason, sıfır dışında herhangi bir değer olabilir (Download.STOP_REASON_NONE = 0 özel bir değerdir, yani indirme işleminin durmadığı anlamına gelir). Aşağıdakileri içeren uygulamalar: birden fazla neden, indirmeleri durdurmak için farklı değerler kullanabilir hakkında daha fazla bilgi edinin. Tümü için durdurma nedenini ayarlama ve temizleme indirme işleminin işleyiş şekli, bir bağlantının durdurma nedenini ayarlamak ve tek indirme işlemi uygulanır. Tek indirme işlemi, contentId değerinin null olarak ayarlanması gerekir.

Bir indirmenin durma nedeni sıfır dışında bir nedeni varsa, o indirme işlemi Download.STATE_STOPPED durumu. Durdurma nedenleri DownloadIndex ve başvuru işlemi sonlandırılıp işlem sonlandırıldığında tutulur. yeniden başlatıldı.

Tüm indirmeler duraklatılıyor ve devam ettiriliyor

Tüm indirme işlemleri aşağıdaki şekilde duraklatılabilir ve devam ettirilebilir:

Kotlin

// Pause all downloads.
DownloadService.sendPauseDownloads(
  context,
  MyDownloadService::class.java,
  /* foreground= */ false
)

// Resume all downloads.
DownloadService.sendResumeDownloads(
  context,
  MyDownloadService::class.java,
  /* foreground= */ false
)

Java

// Pause all downloads.
DownloadService.sendPauseDownloads(context, MyDownloadService.class, /* foreground= */ false);

// Resume all downloads.
DownloadService.sendResumeDownloads(context, MyDownloadService.class, /* foreground= */ false);

Duraklatılan indirme işlemleri Download.STATE_QUEUED durumunda olur. Durdurma nedenleri ayarlamanın aksine bu yaklaşım, herhangi bir durumu devam ettirmez. anlamına gelir. Yalnızca DownloadManager öğesinin çalışma zamanı durumunu etkiler.

İndirmelerin devam etmesi için gereksinimleri ayarlama

Requirements, şunlar için karşılanması gereken kısıtlamaları belirtmek amacıyla kullanılabilir: devam etmek için indirme işlemleri. Koşullar, telefon araması yapılarak ayarlanabilir. DownloadManager oluştururken DownloadManager.setRequirements() (geçerli olduğu gibi) yukarıdaki örneğe bakın. Ayrıca bir komut göndererek dinamik olarak değiştirilebilirler. DownloadService:

Kotlin

// Set the download requirements.
DownloadService.sendSetRequirements(
  context, MyDownloadService::class.java, requirements, /* foreground= */ false)

Java

// Set the download requirements.
DownloadService.sendSetRequirements(
  context,
  MyDownloadService.class,
  requirements,
  /* foreground= */ false);

Koşullar karşılanmadığı için indirme işlemi devam edemezse Download.STATE_QUEUED durumunda olur. Karşılanmayan DownloadManager.getNotMetRequirements() gereksinimleri.

Maksimum paralel indirme sayısını ayarlama

Maksimum paralel indirme sayısı, şunu çağırarak ayarlanabilir: DownloadManager.setMaxParallelDownloads() Bu, normal şartlarda yukarıdaki örnekte olduğu gibi DownloadManager oluşturun.

Maksimum paralel indirme sayısı olduğu için indirme işlemi devam edemediğinde devam ediyor ve Download.STATE_QUEUED durumunda olacak.

İndirilenleri sorgulama

DownloadManager öğesinin DownloadIndex öğesi, tüm durumların durumu için sorgulanabilir indirme sayısı (tamamlananlar veya başarısız olanlar dahil). DownloadIndex DownloadManager.getDownloadIndex() numaralı telefon aranarak elde edilebilir. Bir imleç tüm indirmelerdeki yinelemeler daha sonra DownloadIndex.getDownloads() Alternatif olarak, tek bir indirme işleminin durumu DownloadIndex.getDownload() numarası çağrılarak sorgulanabilir.

DownloadManager, DownloadManager.getCurrentDownloads() sağlar. yalnızca mevcut (tamamlanmamış veya başarısız) indirmelerin durumunu döndürür. Bu yöntemi, sayfada görüntülenen bildirimleri ve diğer kullanıcı arayüzü bileşenlerini güncellemek mevcut indirmelerin ilerlemesi ve durumu

İndirilenler dinleniyor

Şu an olduğunda bilgi almak için DownloadManager uygulamasına bir dinleyici ekleyebilirsiniz indirmelerin durumu değişir:

Kotlin

downloadManager.addListener(
  object : DownloadManager.Listener { // Override methods of interest here.
  }
)

Java

downloadManager.addListener(
    new DownloadManager.Listener() {
      // Override methods of interest here.
    });

DownloadManagerListener için demo uygulamanın DownloadTracker sınıfında bakın somut bir örnek verelim.

İndirilen içerik oynatılıyor

İndirilen içeriği oynatmak çevrimiçi içerik oynatmaya benzer, ancak bunun dışında veriler ağ üzerinden değil, indirilen Cache kaynağından okunur.

İndirilen içeriği oynatmak için aynı dili kullanarak bir CacheDataSource.Factory oluşturun İndirme için kullanılan Cache örneği ve bunu şuraya ekleme: Oynatıcıyı oluştururken DefaultMediaSourceFactory:

Kotlin

// Create a read-only cache data source factory using the download cache.
val cacheDataSourceFactory: DataSource.Factory =
  CacheDataSource.Factory()
    .setCache(downloadCache)
    .setUpstreamDataSourceFactory(httpDataSourceFactory)
    .setCacheWriteDataSinkFactory(null) // Disable writing.

val player =
  ExoPlayer.Builder(context)
    .setMediaSourceFactory(
      DefaultMediaSourceFactory(context).setDataSourceFactory(cacheDataSourceFactory)
    )
    .build()

Java

// Create a read-only cache data source factory using the download cache.
DataSource.Factory cacheDataSourceFactory =
    new CacheDataSource.Factory()
        .setCache(downloadCache)
        .setUpstreamDataSourceFactory(httpDataSourceFactory)
        .setCacheWriteDataSinkFactory(null); // Disable writing.

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

Aynı oynatıcı örneği, indirilmemiş içeriği oynatmak için de kullanılacaksa bu durumda CacheDataSource.Factory yönergesini, salt okunur olarak yapılandırarak oynatma sırasında da indirilmesini sağlar.

Oynatıcı CacheDataSource.Factory ile yapılandırıldıktan sonra şunları yapar: oynatma için indirilen içeriğe erişebilecekleri anlamına gelir. Ardından, indirdiğiniz içerik ilgili MediaItem öğesini oyuncuya iletmek kadar basit. MediaItem Download.request.toMediaItem kullanılarak bir Download'den elde edilebilir veya DownloadRequest.toMediaItem kullanarak doğrudan bir DownloadRequest üzerinden.

MediaSource yapılandırması

Yukarıdaki örnek, indirme önbelleğindeki tüm oynatmaların MediaItem sn. Ayrıca, indirme önbelleğini şunun için de kullanılabilir hale getirebilirsiniz: Doğrudan oynatıcıya iletilebilecek ayrı MediaSource örnekleri:

Kotlin

val mediaSource =
  ProgressiveMediaSource.Factory(cacheDataSourceFactory)
    .createMediaSource(MediaItem.fromUri(contentUri))
player.setMediaSource(mediaSource)
player.prepare()

Java

ProgressiveMediaSource mediaSource =
    new ProgressiveMediaSource.Factory(cacheDataSourceFactory)
        .createMediaSource(MediaItem.fromUri(contentUri));
player.setMediaSource(mediaSource);
player.prepare();

Uyarlanabilir akışları indirme ve oynatma

Uyarlanabilir akışlar (ör.DASH, SmoothStreaming ve HLS) normalde birden fazla içerik içerir. medya parçaları. Genellikle içerikte aynı içeriğe sahip birden fazla parça bulunur. farklı kalitelerde (ör. SD, HD ve 4K video kanalları). Ayrıca ekip üyeleri için de aynı türde birden fazla parça (ör. birden fazla parça ses parçaları için) girin.

Akış oynatmalarında, parça seçici ile ve parça çalınır. Benzer şekilde, indirme işlemi için bir DownloadHelper kullanılabilir. parçaların indirileceğini seçin. Tipik DownloadHelper kullanımı şu adımları izler:

  1. DownloadHelper.forMediaItem özelliklerinden birini kullanarak DownloadHelper oluşturun yöntemlerine göz atın. Yardımcıyı hazırlayın ve geri aranmayı bekleyin.

    Kotlin

    val downloadHelper =
     DownloadHelper.forMediaItem(
       context,
       MediaItem.fromUri(contentUri),
       DefaultRenderersFactory(context),
       dataSourceFactory
     )
    downloadHelper.prepare(callback)
    

    Java

    DownloadHelper downloadHelper =
       DownloadHelper.forMediaItem(
           context,
           MediaItem.fromUri(contentUri),
           new DefaultRenderersFactory(context),
           dataSourceFactory);
    downloadHelper.prepare(callback);
    
  2. İsteğe bağlı olarak, getMappedTrackInfo kullanarak varsayılan seçili parçaları inceleyin ve getTrackSelections ve clearTrackSelections kullanarak ayarlamalar yapın, replaceTrackSelections ve addTrackSelection.
  3. Seçili parçalar için bir DownloadRequest oluşturmak üzere şu numarayı arayın: getDownloadRequest. İstek, DownloadService cihazınıza iletilebilir. indirilen dosyayı yukarıda açıklandığı gibi ekleyin.
  4. release() kullanarak yardımcıyı bırakın.

İndirilen uyarlanabilir içeriğin oynatılabilmesi için oynatıcının yapılandırılması ve ilgili MediaItem öğesini yukarıda açıklandığı şekilde iletmeniz gerekir.

MediaItem oluşturulurken MediaItem.localConfiguration.streamKeys şöyle olmalıdır: DownloadRequest listesindekilerle eşleşecek şekilde ayarlandı. Böylece oyuncu yalnızca indirilen parçaların alt kümesini çalabilir. Kullanım oluşturmak için Download.request.toMediaItem ve DownloadRequest.toMediaItem MediaItem sizin için bu konuyla ilgilenecek.