Ü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 oynatılmasını bekler.
Temel zorluk gecikmedir. Geleneksel olarak, bir video oynatıcı çalışmaya (bağlanma, indirme, ayrıştırma, arabelleğe alma) yalnızca kullanıcı oynatılacak bir öğe seçtikten sonra başlar. 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 gerekir. Önceden 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 kullanıcı deneyimi: Daha hızlı başlatma ve daha az arabelleğe alma sayesinde kullanıcılar daha akıcı ve sorunsuz bir etkileşim deneyimi yaşar.
Üç 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: analiz 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 imdadınıza yetişir. 🦸♀️
Önceden yüklemenin temelinde basit bir fikir yatar: Medya içeriklerini ihtiyaç duymadan önce yükleyin. Kullanıcı bir sonraki videoya geçtiğinde videonun ilk segmentleri indirilmiş ve kullanıma hazır olur.
Bunu bir restoran gibi düşünebilirsiniz. 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ı sıradaki öğeleri yapılandırıldığı şekilde 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 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, oynatma listesi önceden yüklemeyi devre dışı bırakmak için PreloadConfiguration.DEFAULT kullanılarak tekrar kapatılabilir:
player.preloadConfiguration = PreloadConfiguration.DEFAULT
2. PreloadManager ile dinamik listeleri ö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. 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 standart 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. Bu kontrol, önceden yükleme yöneticisinin bir öğe için ne kadar yükleme yapacağını öğrenmek üzere sorgulayabileceği bir kontrol olur. 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 kullanıcının şu anda oynattığı öğeye ne kadar yakın olduğuna göre yüklemeye öncelik verir.
Öğenin ne kadar süreyle önceden yükleneceğini kontrol etmek istiyorsanız DefaultPreloadManager.PreloadStatus ile döndürdüğünüz değeri belirtebilirsiniz.
Örneğin,
- "A" öğesi en yüksek önceliğe sahip. 5 saniyelik video yükleyin.
- "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 konuları söyleyebilirsiniz. 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 izlemesi gereken medya hakkında yöneticinizi bilgilendirmeniz gerekir. Başlangıç aşamasındaysanız önceden yüklemek istediğiniz listenin tamamını ekleyebilirsiniz. Daha sonra, gerektiğinde listeye tek bir öğe eklemeye devam edebilirsiniz. Ön yükleme listesindeki öğeler üzerinde tam kontrol sahibi olursunuz. Bu nedenle, 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 oynatmaya geçtiğini belirtin).
preloadManager.invalidate()
2. Öğe Alma ve Oynatma
Ana oynatma mantığı burada 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 bellekteki verileri kullanabilirsiniz. Başlangıç süresini hızlandıran faktör budur.
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 gerekirse 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 menajeri serbest bırakmanız ö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 sağ tarafta görüyoruz. Bu tarafta yükleme süreleri daha hızlıdır. Sol tarafta ise mevcut deneyim gösterilmektedir. Ayrıca, demoya ait kod örneğini de görüntüleyebilirsiniz. (Bonus: Her video için 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 gereken 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ümde, 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 bir geri bildiriminiz var mı? Görüşlerinizi öğrenmekten memnuniyet duyarız.
Bizi takip etmeye devam edin ve uygulamanızı hızlandırmaya başlayı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
Android Emulator ile çeşitli cihaz etkileşimlerini test etmek artık her zamankinden daha kolay.
Steven Jenkins • Okuma süresi: 2 dakika
-
Ürün Haberleri
Her geliştiricinin yapay zeka iş akışı ve ihtiyaçları benzersizdir. Bu nedenle, yapay zekanın geliştirme sürecinize nasıl yardımcı olacağını seçebilmeniz önemlidir. Ocak ayında, Android Studio'daki yapay zeka işlevlerine güç katmak için yerel veya uzak bir yapay zeka modeli seçme özelliğini kullanıma sunduk.
Matthew Warner • Okuma süresi: 2 dakika
Gelişmelerden haberdar olun
Android geliştirmeyle ilgili en son analizleri her hafta gelen kutunuza alın.