Ürün Haberleri
Medya oynatmayı geliştirme: Media3 ile önceden yükleme özelliğinin tanıtımı - 1. Bölüm
Okuma süresi: 8 dakika
Günümüzün medya odaklı uygulamalarında, sorunsuz ve kesintisiz bir oynatma deneyimi sunmak, keyifli bir kullanıcı deneyimi için çok önemlidir. Kullanıcılar, videolarının anında başlamasını ve sorunsuz bir şekilde, duraklamadan oynatılmasını bekler.
Temel zorluk gecikmedir. Geleneksel olarak, bir video oynatıcı yalnızca kullanıcı oynatılacak bir öğe seçtikten sonra çalışmaya başlar (bağlanma, indirme, ayrıştırma, arabelleğe alma). Bu tepkisel yaklaşım, günümüzün kısa video bağlamında yavaş kalıyor. Çözüm, proaktif olmaktır. Kullanıcının sıradaki videosunun ne olacağını tahmin etmemiz ve içeriği önceden hazırlamamız gerekiyor. Ön yüklemenin özü budur.
Önceden yüklemenin temel avantajları şunlardır:
- 🚀 Daha hızlı oynatma başlangıcı: Videolar hazır olduğundan öğeler arasında daha hızlı geçiş yapılır ve oynatma daha hızlı başlar.
- 📉 Daha az arabelleğe alma: Veriler proaktif olarak yüklendiğinden oynatma işleminin duraklaması (ör. ağdaki aksaklıklar nedeniyle) çok daha az olasıdır.
- ✨ Daha sorunsuz bir kullanıcı deneyimi: Daha hızlı başlatma ve daha az arabelleğe alma, kullanıcıların keyif alacağı daha akıcı ve sorunsuz bir etkileşim sağlar.
Üç bölümden oluşan bu seride, Media3'ün bileşenleri (ön) yüklemeye yönelik güçlü yardımcı programlarını tanıtacak ve ayrıntılı olarak inceleyeceğiz.
- 1. bölümde temelleri ele alacağız: Media3'te bulunan farklı önceden yükleme stratejilerini anlama, PreloadConfiguration'ı etkinleştirme ve DefaultPreloadManager'ı ayarlama, uygulamanızın öğeleri önceden yüklemesini sağlama. Bu blogun sonunda, yapılandırdığınız sıralama ve süreyle medya öğelerini önceden yükleyip oynatabileceksiniz.
- 2. Bölüm'de DefaultPreloadManager'ın daha ileri düzey konularına değineceğiz: analizler için dinleyicileri kullanma, DefaultPreloadManager ve ExoPlayer'ın kayan pencere kalıbı ve özel paylaşılan bileşenleri gibi üretime hazır en iyi uygulamaları keşfetme.
- 3. bölümde, DefaultPreloadManager ile disk önbelleğe alma konusunu ayrıntılı olarak ele alacağız.
Önceden yükleme özelliği imdadınıza yetişir. 🦸♀️
Önceden yüklemenin temelinde basit bir fikir yatar: Medya içeriğini ihtiyaç duymadan önce yükleyin. Kullanıcı bir sonraki videoya kaydırdığında videonun ilk segmentleri zaten indirilmiş ve kullanıma hazır olur.
Bunu bir restorana benzetebiliriz. Yoğun bir mutfakta soğan doğramak için sipariş beklenmez. 🧅 Hazırlık çalışmalarını önceden yaparlar. Önceden yükleme, video oynatıcınız için hazırlık çalışmasıdır.
Ön yükleme etkinleştirildiğinde, oynatma arabelleği bir sonraki öğeye ulaşmadan önce kullanıcının sonraki öğeye atlaması durumunda katılma gecikmesini en aza indirmeye yardımcı olabilir. Bir sonraki pencerenin ilk dönemi hazırlanır ve video, ses ve metin örnekleri arabelleğe alınır. Önceden yüklenen dönem daha sonra arabelleğe alınmış örneklerle birlikte oynatıcıya sıraya alınır. Bu örnekler hemen kullanılabilir ve oluşturma için codec'e aktarılmaya hazırdır.
Media3'te önceden yükleme için iki temel API vardır ve her biri farklı kullanım alanlarına uygundur. Doğru API'yi seçmek ilk adımdır.
1. PreloadConfiguration ile oynatma listesi öğelerini önceden yükleme
Bu basit yaklaşım, oynatma sırasının tahmin edilebilir olduğu (ör. bir dizi bölüm) oynatma listeleri gibi doğrusal ve sıralı medya için kullanışlıdır. ExoPlayer'ın playlist API'lerini kullanarak oynatıcıya medya öğelerinin tam listesini verir ve oynatıcı için PreloadConfiguration'ı ayarlarsınız. Ardından, oynatıcı, yapılandırıldığı şekilde sıradaki öğeleri otomatik olarak önceden yükler. Bu API, oynatma arabelleği sonraki öğeyle zaten çakışmadan önce kullanıcının sonraki öğeye atlaması durumunda katılma gecikmesini optimize etmeye çalışır.
Ön yükleme yalnızca devam eden oynatma için medya yüklenmediğinde başlatılır. Bu sayede, ön yüklemenin birincil oynatma ile bant genişliği için rekabet etmesi önlenir.
Önceden yükleme yapmanız gerekip gerekmediğinden hâlâ emin değilseniz bu API, denemek için harika ve kolay bir seçenektir.
player.preloadConfiguration =
PreloadConfiguration(/* targetPreloadDurationUs= */ 5_000_000L)Yukarıdaki PreloadConfiguration ile oynatıcı, oynatma listesindeki bir sonraki öğe için beş saniyelik medyayı önceden yüklemeye çalışır.
Etkinleştirildikten sonra oynatma listesi önceden yükleme özelliği, PreloadConfiguration.DEFAULT simgesi kullanılarak tekrar devre dışı bırakılabilir:
player.preloadConfiguration = PreloadConfiguration.DEFAULT
2. Dinamik listeleri PreloadManager ile önceden yükleme
"Sonraki" öğenin kullanıcı etkileşimiyle belirlendiği dikey feed'ler veya bantlar gibi dinamik kullanıcı arayüzleri için PreloadManager API uygundur. Bu, Media3 ExoPlayer kitaplığında proaktif olarak önceden yükleme yapmak için özel olarak tasarlanmış yeni, güçlü ve bağımsız bir bileşendir. Bu API, olası MediaSource'ların bir koleksiyonunu yönetir, bunları kullanıcının mevcut konumuna yakınlığa göre önceliklendirir ve önceden yüklenecek içerikler üzerinde ayrıntılı kontrol sunar. Bu özellik, kısa videoların dinamik feed'leri gibi karmaşık senaryolar için uygundur.
PreloadManager'ınızı ayarlama
DefaultPreloadManager, PreloadManager'ın kanonik uygulamasıdır.
DefaultPreloadManager oluşturucusu hem DefaultPreloadManager'ı hem de önceden yüklenmiş içeriğini oynatacak tüm ExoPlayer örneklerini oluşturabilir. DefaultPreloadManager oluşturmak için TargetPreloadStatusControl iletmeniz gerekir. Önceden yükleme yöneticisi, bir öğe için ne kadar yükleme yapılması gerektiğini öğrenmek üzere bu öğeyi sorgulayabilir. Aşağıdaki bölümde TargetPreloadStatusControl örneğini açıklayıp tanımlayacağız.
val preloadManagerBuilder = DefaultPreloadManager.Builder(context, targetPreloadStatusControl) val preloadManager = val preloadManagerBuilder.build() // Build ExoPlayer with DefaultPreloadManager.Builder val player = preloadManagerBuilder.buildExoPlayer()
Hem ExoPlayer hem de DefaultPreloadManager için aynı oluşturucuyu kullanmak gerekir. Bu, bileşenlerin doğru şekilde paylaşılmasını sağlar.
İşte bu kadar! Artık talimat almaya hazır bir yöneticiniz var.
TargetPreloadStatusControl ile Süreyi ve Sıralamayı Yapılandırma
Örneğin, 10 saniyelik bir videoyu önceden yüklemek istiyorsanız ne yapmanız gerekir? Medya öğelerinizin karuseldeki konumunu belirtebilirsiniz. DefaultPreloadManager, öğeleri yüklemeye kullanıcının şu anda oynattığı öğeye ne kadar yakın olduğuna göre öncelik verir.
Öğenin ne kadar süre önceden yükleneceğini kontrol etmek istiyorsanız DefaultPreloadManager.PreloadStatus ile döndürdüğünüz değeri kullanabilirsiniz.
Örneğin,
- "A" öğesi en yüksek önceliğe sahip. 5 saniyelik video yükleniyor.
- "B" öğesi orta öncelikli ancak öğeye ulaştığınızda 3 saniyelik video yükleniyor.
- "C" öğesi daha düşük öncelikli olduğundan yalnızca parçalar yüklenir.
- "D" öğesi daha da düşük öncelikli olduğundan yalnızca hazırlık yapın.
- Diğer öğeler çok uzakta. Hiçbir şeyi önceden yüklemeyin.
Bu ayrıntılı kontrol, kaynak kullanımınızı optimize etmenize yardımcı olabilir. Bu da sorunsuz oynatma için önerilir.
import androidx.media3.exoplayer.DefaultPreloadManager.PreloadStatus
class MyTargetPreloadStatusControl(
currentPlayingIndex: Int = C.INDEX_UNSET
) : TargetPreloadStatusControl<Int,PreloadStatus> {
// The app is responsible for updating this based on UI state
override fun getTargetPreloadStatus(index: Int): PreloadStatus? {
val distance = index - currentPlayingIndex
// Adjacent items (Next): preload 5 seconds
if (distance == 1) {
// Return a PreloadStatus that is labelled by STAGE_SPECIFIED_RANGE_LOADED and suggest loading // 5000ms from the default start position
return PreloadStatus.specifiedRangeLoaded(5000L)
}
// Adjacent items (Previous): preload 3 seconds
else if (distance == -1) {
// Return a PreloadStatus that is labelled by STAGE_SPECIFIED_RANGE_LOADED //and suggest loading 3000ms from the default start position
return PreloadStatus.specifiedRangeLoaded(3000L)
}
// Items two positions away: just select tracks
else if (distance) == 2) {
// Return a PreloadStatus that is labelled by STAGE_TRACKS_SELECTED
return PreloadStatus.TRACKS_SELECTED
}
// Items four positions away: just select prepare
else if (abs(distance) <= 4) {
// Return a PreloadStatus that is labelled by STAGE_SOURCE_PREPARED
return PreloadStatus.SOURCE_PREPARED
}
// All other items are too far away
return null
}
}İpucu: PreloadManager hem önceki hem de sonraki öğeleri önceden yükleyebilir. PreloadConfiguration ise yalnızca sonraki öğeleri önceden yükler.
Önceden Yükleme Öğelerini Yönetme
Yöneticinizi oluşturduktan sonra, üzerinde çalışmasını istediğiniz görevleri söylemeye başlayabilirsiniz. Kullanıcınız bir feed'de gezinirken yaklaşan videoları belirleyip yöneticiye eklersiniz. PreloadManager ile etkileşim, kullanıcı arayüzünüz ile ön yükleme motoru arasındaki duruma dayalı bir görüşmedir.
1. Medya öğeleri ekleme
Feed'inizi doldururken yöneticinin izlemesi gereken medyayı belirtmeniz gerekir. Başlangıçta, önceden yüklemek istediğiniz listenin tamamını ekleyebilirsiniz. Daha sonra, gerektiğinde listeye tek tek öğeler eklemeye devam edebilirsiniz. Önceden yükleme listesindeki öğeler üzerinde tam kontrol sahibi olduğunuz için yöneticiye eklenen ve yöneticiden kaldırılan öğeleri de yönetmeniz gerekir.
val initialMediaItems = pullMediaItemsFromService(/* count= */ 20)
for (index in 0 until initialMediaItems.size) {
preloadManager.add(
initialMediaItems.get(index),index)
)
}Yönetici, bu aşamadan sonra arka planda MediaItem için veri getirmeye başlar.
Ekleme işleminden sonra yöneticiden yeni listesini yeniden değerlendirmesini isteyin (bir öğe ekleme/ kaldırma gibi bir şeyin değiştiğini veya kullanıcının yeni bir öğe oynamaya geçtiğini belirtin).
preloadManager.invalidate()
2. Öğe Alma ve Oynatma
Burada ana oynatma mantığı devreye girer. Kullanıcı bu videoyu oynatmaya karar verdiğinde yeni bir MediaSource oluşturmanız gerekmez. Bunun yerine, PreloadManager'dan önceden hazırladığı yanıtı vermesini istersiniz. MediaItem'ı kullanarak Preload Manager'dan MediaSource'u alabilirsiniz.
PreloadManager'dan alınan öğe null ise mediaItem henüz önceden yüklenmemiş veya PreloadManager'a eklenmemiştir. Bu nedenle, mediaItem'ı doğrudan ayarlamayı seçersiniz.
// When a media item is about to display on the screen
val mediaSource = preloadManager.getMediaSource(mediaItem)
if (mediaSource!= null) {
player.setMediaSource(mediaSource)
} else {
// If mediaSource is null, that mediaItem hasn't been added yet.
// So, send it directly to the player.
player.setMediaItem(mediaItem)
}
player.prepare()
// When the media item is displaying at the center of the screen
player.play()PreloadManager'dan alınan MediaSource'u hazırlayarak, önceden yüklemeden oynatmaya sorunsuz bir şekilde geçiş yapabilir ve zaten bellekte bulunan verileri kullanabilirsiniz. Bu sayede, başlangıç süresi daha hızlı olur.
3. Mevcut dizini kullanıcı arayüzüyle senkronize tutma
Feed'imiz / listemiz dinamik olabileceğinden, PreloadManager'ı mevcut oynatma dizininiz hakkında bilgilendirmeniz önemlidir. Böylece, önceden yükleme için her zaman mevcut dizininize en yakın öğelere öncelik verebilir.
preloadManager.setCurrentPlayingIndex(currentIndex) // Need to call invalidate() to update the priorities preloadManager.invalidate()
4. Öğe Kaldırma
Yöneticinin verimli çalışmaya devam etmesi için artık izlemesi gerekmeyen öğeleri (ör. kullanıcının mevcut konumundan çok uzakta olan öğeler) kaldırmanız gerekir.
// When an item is too far from the current playing index preloadManager.remove(mediaItem)
Tüm öğeleri tek seferde temizlemeniz gerekiyorsa preloadManager.reset() numaralı telefonu arayabilirsiniz.
5. Release the Manager
PreloadManager'a artık ihtiyacınız olmadığında (ör. kullanıcı arayüzünüz yok edildiğinde) kaynaklarını boşaltmak için PreloadManager'ı serbest bırakmanız gerekir. Bunu yapmak için en uygun yer, Player'ın kaynaklarını yayınladığınız yerdir. Daha fazla ön yükleme yapmanız gerekmiyorsa oyuncu oynamaya devam edebileceğinden, oyuncudan önce yöneticinin serbest bırakılması önerilir.
// In your Activity's onDestroy() or Composable's onDispose preloadManager.release()
Demo zamanı
Canlı olarak nasıl çalıştığını görün 👍
Aşağıdaki demoda, PreloadManager'ın etkisini görüyoruz. Sağ tarafta yükleme süreleri daha hızlıyken sol tarafta mevcut deneyim gösteriliyor. Ayrıca, demo için kod örneğini de görüntüleyebilirsiniz. (Bonus: Her videonun başlatma gecikmesini de gösterir.)
Sırada ne var?
1. Bölümün sonuna geldik. Artık dinamik ön yükleme sistemi oluşturmak için gerekli araçlara sahipsiniz. ExoPlayer'da bir oynatma listesinin sonraki öğesini önceden yüklemek için PreloadConfiguration simgesini kullanabilir veya DefaultPreloadManager oluşturup öğeleri anında ekleyip kaldırabilir, hedef önceden yükleme durumunu yapılandırabilir ve önceden yüklenen içeriği oynatma için doğru şekilde alabilirsiniz.
2. Bölüm'de DefaultPreloadManager konusunu daha ayrıntılı olarak ele alacağız. Ön yükleme etkinliklerini nasıl dinleyeceğinizi, bellek sorunlarını önlemek için kayan pencere kullanma gibi en iyi uygulamaları ve ExoPlayer ile DefaultPreloadManager'ın özel paylaşılan bileşenlerinin nasıl çalıştığını inceleyeceğiz.
Paylaşmak istediğiniz geri bildiriminiz var mı? Görüşlerinizi öğrenmekten memnuniyet duyarız.
Bizi takip etmeye devam edin ve uygulamanızı hızlandırın. 🚀
Okumaya devam edin
-
Ürün Haberleri
Media3 ile medya önceden yükleme hakkındaki üç bölümlük serimizin ikinci bölümüne hoş geldiniz. Bu seri, Android uygulamalarınızda yüksek düzeyde duyarlı ve düşük gecikmeli medya deneyimleri oluşturma sürecinde size yol göstermek için tasarlanmıştır.
Mayuri Khinvasara Khabya • Okuma süresi: 9 dakika
-
Ürün Haberleri
Google I/O, her yıl Android geliştirme de dahil olmak üzere ekosistemler ve ürünlerle ilgili yeni duyurular ve kaynaklar sunar. Geliştirme süreci yapay zeka ve aracı destekli araçlara doğru kayarken Android için nasıl geliştirme yapmaya karar verirseniz verin sizi daha iyi desteklemek için tekliflerimizi genişlettik.
Simona Milanovic • Okuma süresi: 2 dakika
-
Ürün Haberleri
Google I/O 2026'da, Android ekosistemindeki en son gelişmelerin, geliştirme verimliliğini en üst düzeye çıkarırken uygulamanızın kalitesini artırmanıza nasıl yardımcı olabileceğini gösterdik.
Ataul Munim • Okuma süresi: 3 dk.
Gelişmelerden haberdar olun
Android geliştirmeyle ilgili en son analizleri her hafta gelen kutunuza alın.