ExoPlayer memutar sebagian besar live stream adaptif secara langsung tanpa konfigurasi khusus. Lihat halaman Format yang Didukung untuk mengetahui detail selengkapnya.
Live stream adaptif menawarkan jendela media yang tersedia yang diperbarui secara berkala untuk mengikuti waktu real-time saat ini. Artinya, posisi pemutaran akan selalu berada di suatu tempat dalam jendela ini, dalam banyak kasus mendekati waktu real-time saat ini saat streaming diproduksi. Perbedaan antara real-time saat ini dan posisi pemutaran disebut offset live.
Mendeteksi dan memantau pemutaran live
Setiap kali jendela live diperbarui, instance Player.Listener yang terdaftar akan
menerima peristiwa onTimelineChanged. Anda dapat mengambil detail tentang pemutaran live saat ini dengan mengkueri berbagai metode Player dan Timeline.Window, seperti yang tercantum nanti dan ditunjukkan dalam gambar berikut.
Player.isCurrentWindowLivemenunjukkan apakah item media yang sedang diputar adalah livestream. Nilai ini tetap benar meskipun livestream telah berakhir.Player.isCurrentWindowDynamicmenunjukkan apakah item media yang sedang diputar masih diperbarui. Hal ini biasanya berlaku untuk livestream yang belum berakhir. Perhatikan bahwa flag ini juga berlaku untuk streaming non-live dalam beberapa kasus.Player.getCurrentLiveOffsetmenampilkan selisih antara waktu real-time saat ini dan posisi pemutaran (jika tersedia).Player.getDurationmenampilkan durasi jendela live saat ini.Player.getCurrentPositionmenampilkan posisi pemutaran yang relatif terhadap awal rentang waktu live.Player.getCurrentMediaItemmenampilkan item media saat ini, denganMediaItem.liveConfigurationberisi penggantian yang disediakan aplikasi untuk target offset live dan parameter penyesuaian offset live.Player.getCurrentTimelinemenampilkan struktur media saat ini dalamTimeline.Timeline.Windowsaat ini dapat diambil dariTimelinemenggunakanPlayer.getCurrentMediaItemIndexdanTimeline.getWindow. DalamWindow:Window.liveConfigurationberisi parameter penyesuaian offset live target dan offset live. Nilai ini didasarkan pada informasi di media dan penggantian yang disediakan aplikasi yang ditetapkan diMediaItem.liveConfiguration.Window.windowStartTimeMsadalah waktu sejak epoch Unix saat jendela live dimulai.Window.getCurrentUnixTimeMsadalah waktu sejak epoch Unix dari real-time saat ini. Nilai ini dapat dikoreksi oleh perbedaan jam yang diketahui antara server dan klien.Window.getDefaultPositionMsadalah posisi di jendela live tempat pemutar akan memulai pemutaran secara default.
Melakukan scrub di live stream
Anda dapat mencari ke mana saja dalam jendela live menggunakan Player.seekTo. Posisi pencarian yang diteruskan bersifat relatif terhadap awal rentang waktu live. Misalnya,
seekTo(0) akan mencari ke awal jendela live. Pemutar akan mencoba
mempertahankan offset live yang sama dengan posisi yang dicari setelah pencarian.
Jendela live juga memiliki posisi default tempat pemutaran seharusnya
dimulai. Posisi ini biasanya berada di dekat live edge. Anda dapat mencari
ke posisi default dengan memanggil Player.seekToDefaultPosition.
UI pemutaran live
Komponen UI default ExoPlayer menampilkan durasi jendela live dan
posisi pemutaran saat ini di dalamnya. Artinya, posisi akan tampak melompat
mundur setiap kali jendela live diperbarui. Jika Anda memerlukan perilaku yang berbeda,
misalnya menampilkan waktu epoch Unix atau offset live saat ini, Anda dapat melakukan fork
PlayerControlView dan mengubahnya sesuai kebutuhan.
Mengonfigurasi parameter pemutaran live
ExoPlayer menggunakan beberapa parameter untuk mengontrol offset posisi pemutaran dari live edge, dan rentang kecepatan pemutaran yang dapat digunakan untuk menyesuaikan offset ini.
ExoPlayer mendapatkan nilai untuk parameter ini dari tiga tempat, dalam urutan prioritas menurun (nilai pertama yang ditemukan akan digunakan):
- Per nilai
MediaItemyang diteruskan keMediaItem.Builder.setLiveConfiguration. - Nilai default global ditetapkan pada
DefaultMediaSourceFactory. - Nilai yang dibaca langsung dari media.
Kotlin
// Global settings. val player = ExoPlayer.Builder(context) .setMediaSourceFactory(DefaultMediaSourceFactory(context).setLiveTargetOffsetMs(5000)) .build() // Per MediaItem settings. val mediaItem = MediaItem.Builder() .setUri(mediaUri) .setLiveConfiguration( MediaItem.LiveConfiguration.Builder().setMaxPlaybackSpeed(1.02f).build() ) .build() player.setMediaItem(mediaItem)
Java
// Global settings. ExoPlayer player = new ExoPlayer.Builder(context) .setMediaSourceFactory( new DefaultMediaSourceFactory(context).setLiveTargetOffsetMs(5000)) .build(); // Per MediaItem settings. MediaItem mediaItem = new MediaItem.Builder() .setUri(mediaUri) .setLiveConfiguration( new MediaItem.LiveConfiguration.Builder().setMaxPlaybackSpeed(1.02f).build()) .build(); player.setMediaItem(mediaItem);
Nilai konfigurasi yang tersedia adalah:
targetOffsetMs: Offset live target. Pemutar akan mencoba mendekati offset live ini selama pemutaran jika memungkinkan.minOffsetMs: Offset live minimum yang diizinkan. Bahkan saat menyesuaikan offset dengan kondisi jaringan saat ini, pemutar tidak akan mencoba menurunkan offset ini selama pemutaran.maxOffsetMs: Selisih waktu live maksimum yang diizinkan. Meskipun menyesuaikan offset dengan kondisi jaringan saat ini, pemutar tidak akan mencoba melampaui offset ini selama pemutaran.minPlaybackSpeed: Kecepatan pemutaran minimum yang dapat digunakan pemutar untuk kembali saat mencoba mencapai target offset live.maxPlaybackSpeed: Kecepatan pemutaran maksimum yang dapat digunakan pemutar untuk mengejar ketertinggalan saat mencoba mencapai target offset live.
Penyesuaian kecepatan pemutaran
Saat memutar livestream berlatensi rendah, ExoPlayer menyesuaikan selisih waktu live dengan sedikit mengubah kecepatan pemutaran. Pemutar akan mencoba mencocokkan target offset live yang disediakan oleh media atau aplikasi, tetapi juga akan mencoba bereaksi terhadap perubahan kondisi jaringan. Misalnya, jika buffering ulang terjadi selama pemutaran, pemutar akan sedikit memperlambat pemutaran untuk menjauh dari live edge. Jika jaringan kemudian menjadi cukup stabil untuk mendukung pemutaran yang lebih dekat ke edge live lagi, pemutar akan mempercepat pemutaran untuk kembali ke offset live target.
Jika penyesuaian kecepatan pemutaran otomatis tidak diperlukan, penyesuaian ini dapat dinonaktifkan dengan
menyetel properti minPlaybackSpeed dan maxPlaybackSpeed ke 1.0f.
Demikian pula, fitur ini dapat diaktifkan untuk livestream tanpa latensi rendah dengan menetapkan nilai ini secara eksplisit ke nilai selain 1.0f. Lihat
bagian konfigurasi untuk mengetahui detail selengkapnya
tentang cara menetapkan properti ini.
Menyesuaikan algoritma penyesuaian kecepatan pemutaran
Jika penyesuaian kecepatan diaktifkan, LivePlaybackSpeedControl akan menentukan penyesuaian yang dilakukan. Anda dapat menerapkan LivePlaybackSpeedControl kustom, atau menyesuaikan penerapan default, yaitu DefaultLivePlaybackSpeedControl. Dalam kedua kasus tersebut, instance dapat ditetapkan saat
mem-build pemutar:
Kotlin
val player = ExoPlayer.Builder(context) .setLivePlaybackSpeedControl( DefaultLivePlaybackSpeedControl.Builder().setFallbackMaxPlaybackSpeed(1.04f).build() ) .build()
Java
ExoPlayer player = new ExoPlayer.Builder(context) .setLivePlaybackSpeedControl( new DefaultLivePlaybackSpeedControl.Builder() .setFallbackMaxPlaybackSpeed(1.04f) .build()) .build();
Parameter penyesuaian DefaultLivePlaybackSpeedControl yang relevan adalah:
fallbackMinPlaybackSpeeddanfallbackMaxPlaybackSpeed: Kecepatan pemutaran minimum dan maksimum yang dapat digunakan untuk penyesuaian jika media maupunMediaItemyang disediakan aplikasi tidak menentukan batas.proportionalControlFactor: Mengontrol seberapa mulus penyesuaian kecepatan. Nilai yang tinggi membuat penyesuaian lebih mendadak dan reaktif, tetapi juga lebih mungkin terdengar. Nilai yang lebih kecil menghasilkan transisi yang lebih mulus di antara kecepatan, dengan konsekuensi lebih lambat.targetLiveOffsetIncrementOnRebufferMs: Nilai ini ditambahkan ke target selisih waktu live setiap kali terjadi buffering ulang, untuk melanjutkan dengan lebih hati-hati. Fitur ini dapat dinonaktifkan dengan menetapkan nilai ke 0.minPossibleLiveOffsetSmoothingFactor: Faktor penghalusan eksponensial yang digunakan untuk melacak kemungkinan offset live minimum berdasarkan media yang saat ini di-buffer. Nilai yang sangat mendekati 1 berarti estimasi lebih hati-hati dan mungkin memerlukan waktu lebih lama untuk menyesuaikan dengan kondisi jaringan yang lebih baik, sedangkan nilai yang lebih rendah berarti estimasi akan menyesuaikan lebih cepat dengan risiko yang lebih tinggi untuk mengalami buffering ulang.
BehindLiveWindowException dan ERROR_CODE_BEHIND_LIVE_WINDOW
Posisi pemutaran mungkin tertinggal dari rentang waktu live, misalnya jika pemutar
dijeda atau melakukan buffering dalam jangka waktu yang cukup lama. Jika hal ini terjadi, pemutaran akan gagal dan pengecualian dengan kode error ERROR_CODE_BEHIND_LIVE_WINDOW akan dilaporkan menggunakan Player.Listener.onPlayerError. Anda mungkin ingin menangani error tersebut dengan melanjutkan
pemutaran di posisi default. PlayerActivity aplikasi demo
mencontohkan pendekatan ini.
Kotlin
override fun onPlayerError(error: PlaybackException) { if (error.errorCode == PlaybackException.ERROR_CODE_BEHIND_LIVE_WINDOW) { // Re-initialize player at the live edge. player.seekToDefaultPosition() player.prepare() } else { // Handle other errors } }
Java
@Override public void onPlayerError(PlaybackException error) { if (error.errorCode == PlaybackException.ERROR_CODE_BEHIND_LIVE_WINDOW) { // Re-initialize player at the live edge. player.seekToDefaultPosition(); player.prepare(); } else { // Handle other errors } }