Jetpack Media3, video ve ses dosyalarının oynatılması için temel işlevleri özetleyen bir Player arayüzü tanımlar. ExoPlayer, Media3'teki bu arayüzün varsayılan uygulamasıdır. Çoğu oynatma kullanım alanını kapsayan kapsamlı bir özellik seti sunduğu ve sahip olabileceğiniz ek kullanım alanlarını işlemek için özelleştirilebildiği için ExoPlayer'ı kullanmanızı öneririz. ExoPlayer ayrıca cihaz ve işletim sistemi parçalanmasını soyutlayarak kodunuzun Android ekosisteminin tamamında tutarlı bir şekilde çalışmasını sağlar. ExoPlayer'da şunlar bulunur:
- Oynatma listeleri desteği
- Çeşitli aşamalı ve uyarlanabilir akış biçimleri için destek
- Hem istemci taraflı hem de sunucu taraflı reklam ekleme desteği
- DRM korumalı oynatma desteği
Bu sayfada, oynatma uygulaması oluşturmayla ilgili bazı temel adımlar açıklanmaktadır. Daha fazla bilgi için Media3 ExoPlayer ile ilgili tam kılavuzlarımıza göz atabilirsiniz.
Başlarken
Başlamak için Jetpack Media3'ün ExoPlayer, UI ve Common modüllerine bağımlılık ekleyin:
Kotlin
implementation("androidx.media3:media3-exoplayer:1.11.0")
implementation("androidx.media3:media3-ui:1.11.0")
implementation("androidx.media3:media3-common:1.11.0")
Modern
implementation "androidx.media3:media3-exoplayer:1.11.0"
implementation "androidx.media3:media3-ui:1.11.0"
implementation "androidx.media3:media3-common:1.11.0"
Kullanım alanınıza bağlı olarak, DASH biçimindeki akışları oynatmak için Media3'ten exoplayer-dash gibi ek modüllere de ihtiyacınız olabilir.
1.11.0 yerine tercih ettiğiniz kitaplık sürümünü kullandığınızdan emin olun. En son sürümü görmek için sürüm notlarına göz atabilirsiniz.
Medya oynatıcı oluşturma
Media3 ile Player
arayüzünün ExoPlayer dahil edilen uygulamasını kullanabilir veya kendi özel uygulamanızı oluşturabilirsiniz.
ExoPlayer oluşturma
ExoPlayer örneği oluşturmanın en basit yolu şöyledir:
Kotlin
val player = ExoPlayer.Builder(context).build()
Java
ExoPlayer player = new ExoPlayer.Builder(context).build();
Medya oynatıcınızı, bulunduğu Activity, Fragment veya Service'nin onCreate() yaşam döngüsü yönteminde oluşturabilirsiniz.
Builder bölümünde, ilgilenebileceğiniz çeşitli özelleştirme seçenekleri bulunur. Örneğin:
setAudioAttributes()ses odağı işlemeyi yapılandırmak için- Ses çıkışı cihazının bağlantısı kesildiğinde oynatma davranışını yapılandırmak için
setHandleAudioBecomingNoisy() - Parça seçimini yapılandırmak için
setTrackSelector()
Media3, uygulamanızın düzen dosyasına ekleyebileceğiniz bir PlayerView kullanıcı arayüzü bileşeni sağlar. Bu bileşen, oynatma kontrolleri için PlayerControlView, altyazıları göstermek için SubtitleView ve videoyu oluşturmak için Surface öğesini kapsar.
Oynatıcıyı hazırlama
setMediaItem() ve addMediaItem() gibi yöntemlerle oynatmak için oynatma listesine medya öğeleri ekleyin. Ardından, medya yüklemeye başlamak ve gerekli kaynakları edinmek için prepare() numarasını arayın.
Bu adımları uygulama ön plana gelmeden önce gerçekleştirmemelisiniz. Oynatıcınız Activity veya Fragment durumundaysa bu, oynatıcıyı API düzeyi 24 ve üzeri sürümlerde onStart() yaşam döngüsü yönteminde, API düzeyi 23 ve önceki sürümlerde ise onResume() yaşam döngüsü yönteminde hazırlamak anlamına gelir. Service içinde bulunan bir oyuncu için onCreate() içinde hazırlık yapabilirsiniz. Yaşam döngüsü yöntemlerinin nasıl uygulanacağına dair bir örnek için Exoplayer codelab'ini inceleyin.
Oynatıcıyı kontrol etme
Oynatıcı hazırlandıktan sonra, oynatıcıda aşağıdaki gibi yöntemleri çağırarak oynatmayı kontrol edebilirsiniz:
- Oynatmayı başlatmak ve duraklatmak için
play()vepause() seekTo(): Geçerli medya öğesinde belirli bir konuma gitmek için- Oynatma listesinde gezinmek için
seekToNextMediaItem()veseekToPreviousMediaItem()tuşlarını kullanın.
PlayerView veya PlayerControlView gibi kullanıcı arayüzü bileşenleri, bir oynatıcıya bağlandığında buna göre güncellenir.
Oyuncuyu serbest bırakma
Oynatma, video kod çözücüler gibi sınırlı sayıda bulunan kaynaklar gerektirebilir. Bu nedenle, oynatıcıya artık ihtiyaç duyulmadığında kaynakları serbest bırakmak için oynatıcınızda release() işlevini çağırmanız önemlidir.
Oynatıcınız Activity veya Fragment durumundaysa oynatıcıyı API düzeyi 24 ve üzeri sürümlerde onStop() yaşam döngüsü yönteminde, API düzeyi 23 ve önceki sürümlerde ise onPause() yönteminde yayınlayın. Service takımında bulunan bir oyuncuyu onDestroy() takımına transfer edebilirsiniz. Yaşam döngüsü yöntemlerinin nasıl uygulanacağına dair bir örnek için Exoplayer codelab'ine bakın.
Medya oturumuyla oynatmayı yönetme
Android'de medya oturumları, süreç sınırları içinde bir medya oynatıcıyla etkileşim kurmak için standartlaştırılmış bir yol sağlar. Bir medya oturumunu oynatıcınıza bağlamak, medya oynatmanızı harici olarak tanıtmanıza ve harici kaynaklardan oynatma komutları almanıza olanak tanır. Örneğin, mobil ve büyük ekranlı cihazlarda sistem medya kontrolleriyle entegrasyon için bu özellik kullanılabilir.
Medya oturumlarını kullanmak için Media3 Session modülüne bağımlılık ekleyin:
Kotlin
implementation("androidx.media3:media3-session:1.11.0")
Modern
implementation "androidx.media3:media3-session:1.11.0"
Medya oturumu oluşturma
Bir oynatıcıyı aşağıdaki şekilde başlattıktan sonra MediaSession oluşturabilirsiniz:
Kotlin
val player = ExoPlayer.Builder(context).build()
val mediaSession = MediaSession.Builder(context, player).build()
Java
ExoPlayer player = new ExoPlayer.Builder(context).build();
MediaSession mediaSession = new MediaSession.Builder(context, player).build();
Media3, Player durumunu MediaSession durumuyla otomatik olarak senkronize eder. Bu özellik, Player, ExoPlayer, CastPlayer veya özel bir uygulama dahil olmak üzere tüm Player uygulamalarıyla çalışır.
Diğer istemcilere kontrol izni verme
İstemci uygulamaları, medya oturumunuzun oynatılmasını kontrol etmek için medya kumandası uygulayabilir. Bu istekleri almak için MediaSession oluştururken bir geri arama nesnesi ayarlayın.
Bir kumanda medya oturumunuza bağlanmak üzereyken onConnect()
yöntemi çağrılır. İsteği kabul edip etmeyeceğinize veya reddedeceğinize karar vermek için sağlanan ControllerInfo simgesini kullanabilirsiniz. Bunun bir örneğini Media3
Session demo uygulamasında görebilirsiniz.
Bağlandıktan sonra bir denetleyici, oturuma oynatma komutları gönderebilir. Oturum daha sonra bu komutları oynatıcıya devreder. Player arayüzünde tanımlanan oynatma ve oynatma listesi komutları, oturum tarafından otomatik olarak işlenir.
Diğer geri çağırma yöntemleri, örneğin özel oynatma komutları ve oynatma listesini değiştirme isteklerini işlemenize olanak tanır. Bu geri çağırmalar da benzer şekilde ControllerInfo nesnesi içerir. Böylece, erişim denetimini istek bazında belirleyebilirsiniz.
Medya dosyalarını arka planda oynatma
Uygulamanız ön planda değilken medyayı oynatmaya devam etmek için (ör. kullanıcı uygulamanızı açmamış olsa bile müzik, sesli kitap veya podcast oynatmak için) Player ve MediaSession, ön plan hizmeti içinde kapsüllenmelidir. Media3, bu amaçla MediaSessionService arayüzünü sağlar.
MediaSessionService uygulama
MediaSessionService sınıfını genişleten bir sınıf oluşturun ve onCreate() yaşam döngüsü yönteminde MediaSession öğenizi örnekleyin.
Kotlin
class PlaybackService : MediaSessionService() {
private var mediaSession: MediaSession? = null
// Create your Player and MediaSession in the onCreate lifecycle event
override fun onCreate() {
super.onCreate()
val player = ExoPlayer.Builder(this).build()
mediaSession = MediaSession.Builder(this, player).build()
}
// Remember to release the player and media session in onDestroy
override fun onDestroy() {
mediaSession?.run {
player.release()
release()
mediaSession = null
}
super.onDestroy()
}
}
Java
public class PlaybackService extends MediaSessionService {
private MediaSession mediaSession = null;
@Override
public void onCreate() {
super.onCreate();
ExoPlayer player = new ExoPlayer.Builder(this).build();
mediaSession = new MediaSession.Builder(this, player).build();
}
@Override
public void onDestroy() {
mediaSession.getPlayer().release();
mediaSession.release();
mediaSession = null;
super.onDestroy();
}
}
Manifest dosyanızda Service sınıfınızı MediaSessionService
amaç filtresiyle bildirin ve ön plan hizmeti çalıştırmak için FOREGROUND_SERVICE iznini isteyin:
<service
android:name=".PlaybackService"
android:foregroundServiceType="mediaPlayback"
android:exported="true">
<intent-filter>
<action android:name="androidx.media3.session.MediaSessionService"/>
</intent-filter>
</service>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
Son olarak, oluşturduğunuz sınıfta onGetSession() yöntemini geçersiz kılarak medya oturumunuza istemci erişimini kontrol edin. Bağlantı isteğini kabul etmek için MediaSession, isteği reddetmek için null değerini döndürün.
Kotlin
// This example always accepts the connection request
override fun onGetSession(
controllerInfo: MediaSession.ControllerInfo
): MediaSession? = mediaSession
Java
@Override
public MediaSession onGetSession(MediaSession.ControllerInfo controllerInfo) {
// This example always accepts the connection request
return mediaSession;
}
Kullanıcı arayüzünüze bağlanma
Medya oturumunuz artık oynatıcı kullanıcı arayüzünüzün bulunduğu Service veya Activity'dan ayrı bir Fragment'da olduğundan, bunları birbirine bağlamak için MediaController kullanabilirsiniz.
Kullanıcı arayüzünüzle Activity veya Fragment onStart() yönteminde, MediaSession için bir SessionToken oluşturun, ardından MediaController oluşturmak için
SessionToken'yi kullanın. MediaController oluşturma işlemi eşzamansız olarak gerçekleşir.
Kotlin
override fun onStart() {
val sessionToken = SessionToken(this, ComponentName(this, PlaybackService::class.java))
val controllerFuture = MediaController.Builder(this, sessionToken).buildAsync()
controllerFuture.addListener(
{
// Call controllerFuture.get() to retrieve the MediaController.
// MediaController implements the Player interface, so it can be
// attached to the PlayerView UI component.
playerView.setPlayer(controllerFuture.get())
},
MoreExecutors.directExecutor()
)
}
Java
@Override
public void onStart() {
SessionToken sessionToken =
new SessionToken(this, new ComponentName(this, PlaybackService.class));
ListenableFuture<MediaController> controllerFuture =
new MediaController.Builder(this, sessionToken).buildAsync();
controllerFuture.addListener(() -> {
// Call controllerFuture.get() to retrieve the MediaController.
// MediaController implements the Player interface, so it can be
// attached to the PlayerView UI component.
playerView.setPlayer(controllerFuture.get());
}, MoreExecutors.directExecutor())
}
MediaController, Player arayüzünü uyguladığından oynatmayı kontrol etmek için play() ve pause() gibi aynı yöntemleri kullanabilirsiniz. Diğer bileşenlere benzer şekilde, MediaController öğesi Activity öğesinin onStop() yaşam döngüsü yönteminde artık gerekli olmadığında MediaController.releaseFuture() çağrılarak serbest bırakılmalıdır.
Bildirim yayınlama
Ön plan hizmetlerinin, etkin durumdayken bildirim yayınlaması gerekir. A
MediaSessionService, MediaNotification şeklinde MediaStyle bildirimi otomatik olarak oluşturur. Özel bir bildirim sağlamak için MediaNotification.Provider ile DefaultMediaNotificationProvider.Builder oluşturun veya sağlayıcı arayüzünün özel bir uygulamasını oluşturun. setMediaNotificationProvider ile sağlayıcınızı MediaSession'nize ekleyin.
İçerik kitaplığınızın reklamını yapma
MediaLibraryService, istemci uygulamalarının uygulamanız tarafından sağlanan medya içeriğine göz atmasına izin vererek MediaSessionService üzerine kurulur. İstemci uygulamaları, MediaLibraryService ile etkileşim kurmak için MediaBrowser uygular.
MediaLibraryService uygulamak, MediaSessionService uygulamaya benzer. Tek fark, onGetSession() içinde MediaSession yerine MediaLibrarySession döndürmeniz gerektiğidir. MediaSession.Callback ile karşılaştırıldığında MediaLibrarySession.Callback, tarayıcı istemcisinin kitaplık hizmetiniz tarafından sunulan içerikte gezinmesine olanak tanıyan ek yöntemler içerir.
MediaSessionService'ya benzer şekilde, manifest'inizde MediaLibraryService'ı tanımlayın ve ön plan hizmeti çalıştırmak için FOREGROUND_SERVICE iznini isteyin:
<service
android:name=".PlaybackService"
android:foregroundServiceType="mediaPlayback"
android:exported="true">
<intent-filter>
<action android:name="androidx.media3.session.MediaLibraryService"/>
<action android:name="android.media.browse.MediaBrowserService"/>
</intent-filter>
</service>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
Yukarıdaki örnekte hem MediaLibraryService hem de geriye dönük uyumluluk için eski MediaBrowserService'a yönelik bir intent filtresi yer almaktadır. Ek intent filtresi, MediaBrowserCompat API'sini kullanan istemci uygulamalarının Service'nizi tanımasını sağlar.
MediaLibrarySession, içerik kitaplığınızı tek bir kök MediaItem ile ağaç yapısında yayınlamanıza olanak tanır. Ağaçtaki her MediaItem düğümünün istediğiniz sayıda alt MediaItem düğümü olabilir. İstemci uygulamasının isteğine bağlı olarak farklı bir kök veya farklı bir ağaç sunabilirsiniz. Örneğin, önerilen medya öğelerinin listesini arayan bir istemciye döndürdüğünüz ağaç yalnızca kök MediaItem ve tek bir düzeyde alt MediaItem düğümlerini içerebilirken farklı bir istemci uygulamasına döndürdüğünüz ağaç, daha eksiksiz bir içerik kitaplığını temsil edebilir.
MediaLibrarySession oluşturma
MediaLibrarySession, içeriklere göz atma API'leri eklemek için MediaSession API'sini genişletir. MediaSession geri çağırma ile karşılaştırıldığında, MediaLibrarySession
geri çağırma aşağıdaki gibi yöntemler ekler:
onGetLibraryRoot(), istemci bir içerik ağacınınMediaItemkökünü istediğindeMediaItemiçerik ağacındaki alt öğeleri istediğindeonGetChildren()onGetSearchResult()Bir istemci, belirli bir sorgu için içerik ağacından arama sonuçları istediğinde
İlgili geri çağırma yöntemleri, bir istemci uygulamasının ilgilendiği içerik ağacı türüyle ilgili ek sinyaller içeren bir LibraryParams nesnesi içerecektir.