ExoPlayer memainkan sebagian besar live stream adaptif siap pakai tanpa konfigurasi khusus apa pun. Lihat halaman Format yang Didukung untuk mengetahui detail selengkapnya.
Live stream adaptif menawarkan jendela media yang tersedia yang diperbarui dalam interval reguler untuk berpindah dengan real-time saat ini. Artinya, posisi pemutaran akan selalu berada di jendela ini, dalam sebagian besar kasus dekat dengan real-time saat ini saat streaming sedang dihasilkan. Perbedaan antara real-time saat ini dan posisi pemutaran disebut offset live.
Mendeteksi dan memantau pemutaran live
Setiap kali periode live diperbarui, instance Player.Listener
yang terdaftar akan menerima peristiwa onTimelineChanged
. Anda dapat mengambil detail tentang
pemutaran live saat ini dengan membuat kueri berbagai metode Player
dan Timeline.Window
, seperti yang tercantum di bawah ini dan ditunjukkan dalam gambar berikut.
Player.isCurrentWindowLive
menunjukkan apakah item media yang sedang diputar adalah live stream. Nilai ini akan tetap bernilai benar meskipun live stream telah berakhir.Player.isCurrentWindowDynamic
menunjukkan apakah item media yang sedang diputar masih diperbarui. Hal ini biasanya berlaku untuk live stream yang belum berakhir. Perhatikan bahwa tanda ini juga berlaku untuk non-live stream dalam beberapa kasus.Player.getCurrentLiveOffset
menampilkan offset antara real time saat ini dan posisi pemutaran (jika tersedia).Player.getDuration
menampilkan panjang periode aktif saat ini.Player.getCurrentPosition
menampilkan posisi pemutaran relatif terhadap awal jendela live.Player.getCurrentMediaItem
menampilkan item media saat ini, denganMediaItem.liveConfiguration
berisi penggantian yang disediakan aplikasi untuk parameter penyesuaian live offset dan penyesuaian live offset target.Player.getCurrentTimeline
menampilkan struktur media saat ini dalamTimeline
.Timeline.Window
saat ini dapat diambil dariTimeline
menggunakanPlayer.getCurrentWindowIndex
danTimeline.getWindow
. DalamWindow
:Window.liveConfiguration
berisi parameter penyesuaian live offset target dan penyesuaian live offset. Nilai ini didasarkan pada informasi di media dan penggantian apa pun yang disediakan aplikasi yang ditetapkan diMediaItem.liveConfiguration
.Window.windowStartTimeMs
adalah waktu sejak Unix Epoch saat jendela live dimulai.Window.getCurrentUnixTimeMs
adalah waktu sejak Unix Epoch saat ini secara real-time. Nilai ini dapat dikoreksi oleh perbedaan jam yang diketahui antara server dan klien.Window.getDefaultPositionMs
adalah posisi di jendela live tempat pemain akan memulai pemutaran secara default.
Mencari di live stream
Anda dapat mencari ke mana saja dalam jendela yang aktif menggunakan Player.seekTo
. Posisi
cari yang diteruskan relatif terhadap awal jendela aktif. Misalnya, seekTo(0)
akan mencari ke awal jendela aktif. Pemain 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 tepi live. 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. Hal ini berarti posisi akan tampak
melompat mundur setiap kali jendela aktif diperbarui. Jika Anda memerlukan perilaku
yang berbeda, misalnya menampilkan waktu Unix atau offset live saat ini, Anda dapat
melakukan fork PlayerControlView
dan mengubahnya sesuai dengan 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):
- Nilai per
MediaItem
yang diteruskan keMediaItem.Builder.setLiveConfiguration
. - Nilai default global ditetapkan pada
DefaultMediaSourceFactory
. - Nilai 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 langsung 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 berada di bawah offset ini selama pemutaran.maxOffsetMs
: Offset live maksimum yang diizinkan. Bahkan saat menyesuaikan offset dengan kondisi jaringan saat ini, pemutar tidak akan mencoba melampaui offset ini selama pemutaran.minPlaybackSpeed
: Kecepatan pemutaran minimum yang dapat digunakan pemain untuk mundur saat mencoba mencapai offset live target.maxPlaybackSpeed
: Kecepatan pemutaran maksimum yang dapat digunakan pemutar untuk mengejar ketertinggalan saat mencoba mencapai offset live target.
Penyesuaian kecepatan pemutaran
Saat memutar live stream berlatensi rendah, ExoPlayer menyesuaikan offset live dengan sedikit mengubah kecepatan pemutaran. Pemutar akan mencoba mencocokkan offset langsung target yang disediakan oleh media atau aplikasi, tetapi juga akan mencoba bereaksi terhadap perubahan kondisi jaringan. Misalnya, jika buffering ulang terjadi selama pemutaran, pemain akan sedikit memperlambat pemutaran untuk menjauh dari tepi live. Jika jaringan kemudian menjadi cukup stabil untuk mendukung pemutaran lebih dekat ke live edge lagi, pemutar akan mempercepat pemutaran untuk kembali ke offset live target.
Jika penyesuaian kecepatan pemutaran otomatis tidak diinginkan, Anda dapat menonaktifkannya dengan
menyetel properti minPlaybackSpeed
dan maxPlaybackSpeed
ke 1.0f
.
Demikian pula, fitur ini dapat diaktifkan untuk live stream non-latensi rendah dengan menetapkannya secara eksplisit ke nilai selain 1.0f
. Lihat bagian konfigurasi di atas untuk mengetahui detail selengkapnya tentang cara menetapkan properti ini.
Menyesuaikan algoritma penyesuaian kecepatan pemutaran
Jika penyesuaian kecepatan diaktifkan, LivePlaybackSpeedControl
akan menentukan
penyesuaian apa yang dibuat. Anda dapat menerapkan LivePlaybackSpeedControl
kustom, atau menyesuaikan implementasi default, yaitu
DefaultLivePlaybackSpeedControl
. Dalam kedua kasus tersebut, instance dapat disetel 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:
fallbackMinPlaybackSpeed
danfallbackMaxPlaybackSpeed
: Kecepatan pemutaran minimum dan maksimum yang dapat digunakan untuk penyesuaian jika media atauMediaItem
yang disediakan aplikasi tidak menentukan batas.proportionalControlFactor
: Mengontrol seberapa lancar penyesuaian kecepatan. Nilai yang tinggi membuat penyesuaian lebih tiba-tiba dan reaktif, tetapi juga lebih mungkin didengar. Nilai yang lebih kecil menghasilkan transisi yang lebih lancar antar-kecepatan, tetapi akan tetapi menjadi lebih lambat.targetLiveOffsetIncrementOnRebufferMs
: Nilai ini ditambahkan ke offset live target setiap kali rebuffer terjadi, untuk melanjutkan dengan lebih hati-hati. Fitur ini dapat dinonaktifkan dengan menyetel nilai ke 0.minPossibleLiveOffsetSmoothingFactor
: Faktor penghalusan eksponensial yang digunakan untuk melacak offset live minimum yang memungkinkan berdasarkan media yang saat ini di-buffer. Nilai yang sangat dekat dengan 1 berarti estimasi lebih berhati-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 lebih tinggi mengalami buffering ulang.
BehindLiveWindowException dan ERROR_CODE_bawa_LIVE_WINDOW
Posisi pemutaran mungkin berada di belakang jendela live, misalnya jika pemutar
dijeda atau buffering untuk jangka waktu yang cukup lama. Jika hal ini terjadi,
pemutaran akan gagal dan pengecualian dengan kode error
ERROR_CODE_BEHIND_LIVE_WINDOW
akan dilaporkan melalui
Player.Listener.onPlayerError
. Kode aplikasi mungkin ingin menangani error
tersebut dengan melanjutkan pemutaran pada posisi default. PlayerActivity
aplikasi demo contoh 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 } }