- Memperbaiki error "Traffic HTTP Cleartext tidak diizinkan"
- Memperbaiki error "SSLHandshakeException", "CertPathValidatorException", dan "ERR_CERT_AUTHORITY_INVALID"
- Mengapa beberapa file media tidak dapat dicari?
- Mengapa mencari tidak akurat dalam beberapa file MP3?
- Mengapa proses pencarian di video saya lambat?
- Mengapa beberapa file MPEG-TS gagal diputar?
- Mengapa subtitel tidak ditemukan di beberapa file MPEG-TS?
- Mengapa beberapa file MP4/FMP4 tidak diputar dengan benar?
- Mengapa beberapa streaming gagal dengan kode respons HTTP 301 atau 302?
- Mengapa beberapa streaming gagal dengan UnknownInputFormatException?
- Mengapa setPlaybackParameters tidak berfungsi dengan benar di beberapa perangkat?
- Apa yang dimaksud dengan error "Pemutar diakses di thread yang salah"?
- Bagaimana cara memperbaiki "Unexpected status line: ICY 200 OK"?
- Bagaimana cara menanyakan apakah streaming yang diputar adalah live stream?
- Bagaimana cara agar audio tetap diputar saat aplikasi berada di latar belakang?
- Mengapa ExoPlayer mendukung konten saya, tetapi library Cast ExoPlayer tidak?
- Mengapa konten gagal diputar, tetapi tidak ada error yang muncul?
- Bagaimana cara mendapatkan library decoding untuk dimuat dan digunakan untuk pemutaran?
- Bisakah saya memutar video YouTube langsung dengan ExoPlayer?
- Pemutaran video tersendat
- Error lint API yang tidak stabil
Memperbaiki error "Lalu lintas HTTP Cleartext tidak diizinkan"
Error ini akan terjadi jika aplikasi Anda meminta traffic HTTP cleartext (yaitu,
http://
, bukan https://
) saat Konfigurasi Keamanan Jaringannya
tidak mengizinkannya. Jika aplikasi Anda menargetkan Android 9 (API level 28) atau yang lebih baru, traffic HTTP cleartext dinonaktifkan oleh konfigurasi default.
Jika aplikasi Anda perlu bekerja dengan traffic HTTP cleartext, Anda harus menggunakan
Konfigurasi Keamanan Jaringan yang mengizinkannya. Lihat
dokumentasi keamanan jaringan
Android untuk mengetahui detailnya. Untuk mengaktifkan semua traffic HTTP cleartext, cukup tambahkan
android:usesCleartextTraffic="true"
ke elemen application
dari
AndroidManifest.xml
aplikasi Anda.
Aplikasi demo ExoPlayer menggunakan Konfigurasi Keamanan Jaringan default, sehingga tidak mengizinkan traffic HTTP cleartext. Anda dapat mengaktifkannya menggunakan petunjuk di atas.
Memperbaiki error "SSLHandshakeException", "CertPathValidatorException", dan "ERR_CERT_AUTHORITY_INVALID"
SSLHandshakeException
, CertPathValidatorException
, dan
ERR_CERT_AUTHORITY_INVALID
semuanya menunjukkan masalah dengan sertifikat SSL
server. Error ini tidak khusus ExoPlayer. Lihat dokumentasi SSL Android untuk detail selengkapnya.
Mengapa beberapa file media tidak dapat dicari?
Secara default, ExoPlayer tidak mendukung pencarian di media yang satu-satunya metode untuk melakukan operasi pencarian yang akurat adalah agar pemain memindai dan mengindeks seluruh file. ExoPlayer menganggap file seperti itu sebagai tidak dapat dicari. Sebagian besar format penampung media modern menyertakan metadata untuk pencarian (seperti indeks sampel), memiliki algoritma pencarian yang terdefinisi dengan baik (misalnya, penelusuran pembagian terinterpolasi untuk Ogg), atau menunjukkan bahwa kontennya memiliki kecepatan bit yang konstan. Operasi pencarian yang efisien dapat dilakukan dan didukung oleh ExoPlayer.
Jika Anda memerlukan pencarian tetapi memiliki media yang tidak dapat dicari, sebaiknya konversi konten Anda untuk menggunakan format penampung yang lebih sesuai. Untuk file MP3, ADTS, dan AMR, Anda juga dapat mengaktifkan pencarian dengan asumsi bahwa file tersebut memiliki kecepatan bit yang konstan, seperti yang dijelaskan di sini.
Mengapa pencarian tidak akurat dalam beberapa file MP3?
File MP3 dengan kecepatan bit variabel (VBR) pada dasarnya tidak sesuai untuk kasus penggunaan yang memerlukan pencarian persis. Ada dua alasan untuk ini:
- Untuk pencarian persis, format container idealnya akan menyediakan pemetaan waktu-ke-byte yang tepat dalam header. Pemetaan ini memungkinkan pemutar memetakan waktu pencarian yang diminta ke offset byte yang sesuai, dan mulai meminta, mengurai, dan memutar media dari offset tersebut. Header yang tersedia untuk menentukan pemetaan ini dalam MP3 (seperti header XING), sayangnya, sering kali tidak tepat.
- Untuk format penampung yang tidak menyediakan pemetaan waktu-ke-byte yang tepat (atau pemetaan waktu-ke-byte sama sekali), pencarian yang tepat masih dapat dilakukan jika penampung menyertakan stempel waktu contoh absolut dalam aliran data. Dalam hal ini, pemain dapat memetakan waktu pencarian untuk mengetahui tebakan terbaik dari offset byte yang sesuai, mulai meminta media dari offset tersebut, mengurai stempel waktu sampel absolut pertama, dan secara efektif melakukan penelusuran biner terpandu ke dalam media hingga menemukan contoh yang tepat. Sayangnya, MP3 tidak menyertakan stempel waktu contoh absolut dalam streaming, sehingga pendekatan ini tidak memungkinkan.
Oleh karena itu, satu-satunya cara untuk melakukan pencarian yang tepat ke file MP3 VBR adalah
dengan memindai seluruh file dan secara manual membuat pemetaan waktu-ke-byte di
pemutar. Strategi ini dapat diaktifkan menggunakan FLAG_ENABLE_INDEX_SEEKING
,
yang dapat ditetapkan pada DefaultExtractorsFactory
menggunakan
setMp3ExtractorFlags
. Perlu diperhatikan bahwa proses ini tidak diskalakan dengan baik untuk file MP3 yang besar,
terutama jika pengguna mencoba berusaha mendekati akhir streaming tidak lama
setelah memulai pemutaran, yang mengharuskan pemutar untuk menunggu hingga selesai didownload
dan mengindeks seluruh streaming sebelum melakukan pencarian. Di ExoPlayer, kami
memutuskan untuk mengoptimalkan kecepatan melebihi akurasi dalam hal ini, dan
FLAG_ENABLE_INDEX_SEEKING
dinonaktifkan secara default.
Jika Anda mengontrol media yang sedang diputar, sebaiknya gunakan format container yang lebih sesuai, seperti MP4. Tidak ada kasus penggunaan yang kami sadari di mana MP3 adalah pilihan format media terbaik.
Mengapa proses pencarian di video saya lambat?
Saat pemutar mencari posisi pemutaran baru dalam video, pemutar harus melakukan dua hal:
- Muat data yang sesuai dengan posisi pemutaran baru ke dalam buffer (tindakan ini mungkin tidak diperlukan jika data ini sudah di-buffer).
- Hapus dekoder video dan mulai decoding dari I-frame (keyframe) sebelum posisi pemutaran yang baru, karena coding intra-frame yang digunakan oleh sebagian besar format kompresi video. Untuk memastikan pencarian akurat (yaitu, pemutaran dimulai persis pada posisi pencarian), semua frame di antara I-frame sebelumnya dan posisi pencarian harus didekode dan segera dihapus (tanpa ditampilkan di layar).
Latensi yang diperkenalkan oleh (1) dapat dimitigasi dengan meningkatkan jumlah data yang di-buffer dalam memori oleh pemutar, atau melakukan pra-cache data ke disk.
Latensi yang diperkenalkan oleh (2) dapat dimitigasi dengan mengurangi akurasi
pencarian menggunakan ExoPlayer.setSeekParameters
, atau mengenkode ulang video
agar memiliki I-frame yang lebih sering (yang akan menghasilkan file output yang lebih besar).
Mengapa beberapa file MPEG-TS gagal diputar?
Beberapa file MPEG-TS tidak berisi pembatas unit akses (AUD). Secara default, ExoPlayer mengandalkan AUD untuk mendeteksi batas frame dengan murah. Demikian pula, beberapa file MPEG-TS tidak berisi keyframe IDR. Secara default, ini adalah satu-satunya jenis frame utama yang dipertimbangkan oleh ExoPlayer.
ExoPlayer akan tampak terjebak dalam status buffering saat diminta untuk memutar
file MPEG-TS yang tidak memiliki keyframe AUD atau IDR. Jika perlu memutar file tersebut,
Anda dapat melakukannya menggunakan FLAG_DETECT_ACCESS_UNITS
dan
FLAG_ALLOW_NON_IDR_KEYFRAMES
. Flag ini dapat ditetapkan pada
DefaultExtractorsFactory
menggunakan setTsExtractorFlags
atau pada
DefaultHlsExtractorFactory
menggunakan
konstruktor.
Penggunaan FLAG_DETECT_ACCESS_UNITS
tidak memiliki efek samping selain
mahal secara komputasi dibandingkan deteksi batas frame berbasis AUD. Penggunaan
FLAG_ALLOW_NON_IDR_KEYFRAMES
dapat mengakibatkan kerusakan visual sementara saat
awal pemutaran dan segera setelah pencarian saat memutar beberapa file MPEG-TS.
Mengapa subtitel tidak ditemukan di beberapa file MPEG-TS?
Beberapa file MPEG-TS menyertakan jalur CEA-608, tetapi tidak mendeklarasikannya dalam
metadata container, sehingga ExoPlayer tidak dapat mendeteksinya. Anda dapat menentukan
trek subtitel secara manual dengan memberikan daftar format subtitel
yang diharapkan ke DefaultExtractorsFactory
, termasuk saluran aksesibilitas
yang dapat digunakan untuk mengidentifikasinya dalam streaming MPEG-TS:
Kotlin
val extractorsFactory = DefaultExtractorsFactory() .setTsSubtitleFormats( listOf( Format.Builder() .setSampleMimeType(MimeTypes.APPLICATION_CEA608) .setAccessibilityChannel(accessibilityChannel) // Set other subtitle format info, such as language. .build() ) ) val player: Player = ExoPlayer.Builder(context, DefaultMediaSourceFactory(context, extractorsFactory)).build()
Java
DefaultExtractorsFactory extractorsFactory = new DefaultExtractorsFactory() .setTsSubtitleFormats( ImmutableList.of( new Format.Builder() .setSampleMimeType(MimeTypes.APPLICATION_CEA608) .setAccessibilityChannel(accessibilityChannel) // Set other subtitle format info, such as language. .build())); Player player = new ExoPlayer.Builder(context, new DefaultMediaSourceFactory(context, extractorsFactory)) .build();
Mengapa beberapa file MP4/FMP4 tidak diputar dengan benar?
Beberapa file MP4/FMP4 berisi daftar edit yang menulis ulang linimasa media dengan melewati, memindahkan, atau mengulangi daftar sampel. ExoPlayer memiliki dukungan parsial untuk menerapkan daftar edit. Misalnya, layanan ini dapat menunda atau mengulangi grup sampel yang dimulai pada sampel sinkronisasi, tetapi tidak memotong sampel audio atau media pre-roll untuk pengeditan yang tidak dimulai pada sampel sinkronisasi.
Jika Anda melihat bahwa ada bagian media yang hilang atau berulang secara tidak terduga,
coba setel Mp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS
atau
FragmentedMp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS
, yang akan menyebabkan
ekstraktor mengabaikan daftar edit sepenuhnya. Ini dapat ditetapkan pada
DefaultExtractorsFactory
menggunakan setMp4ExtractorFlags
atau
setFragmentedMp4ExtractorFlags
.
Mengapa beberapa streaming gagal dengan kode respons HTTP 301 atau 302?
Kode respons HTTP 301 dan 302 menunjukkan pengalihan. Deskripsi singkat dapat ditemukan di Wikipedia. Saat ExoPlayer membuat permintaan dan menerima respons dengan kode status 301 atau 302, ExoPlayer biasanya akan mengikuti pengalihan dan memulai pemutaran seperti biasa. Satu kasus di mana hal ini tidak terjadi secara default adalah untuk pengalihan lintas protokol. Pengalihan lintas protokol adalah pengalihan dari HTTPS ke HTTP atau sebaliknya (atau yang jarang terjadi, di antara pasangan protokol lain). Anda dapat menguji apakah URL menyebabkan pengalihan lintas protokol menggunakan alat command line wget sebagai berikut:
wget "https://yourserver.com/test.mp3" 2>&1 | grep Location
Output akan terlihat seperti ini:
Location: https://second.com/test.mp3 [following]
Location: http://third.com/test.mp3 [following]
Dalam contoh ini, ada dua pengalihan. Pengalihan pertama adalah dari
https://yourserver.com/test.mp3
ke https://second.com/test.mp3
. Keduanya adalah
HTTPS, sehingga bukan pengalihan lintas protokol. Pengalihan kedua adalah dari
https://second.com/test.mp3
ke http://third.com/test.mp3
. Ini akan mengalihkan
dari HTTPS ke HTTP, dan begitu juga pengalihan lintas protokol. ExoPlayer tidak akan
mengikuti pengalihan ini dalam konfigurasi defaultnya, yang berarti pemutaran akan gagal.
Jika perlu, Anda dapat mengonfigurasi ExoPlayer untuk mengikuti pengalihan lintas protokol
saat membuat instance DefaultHttpDataSource.Factory
yang digunakan di
aplikasi Anda. Pelajari cara memilih dan mengonfigurasi stack jaringan
di sini.
Mengapa beberapa streaming gagal dengan UnknownInputFormatException?
Pertanyaan ini berkaitan dengan kegagalan pemutaran dalam bentuk berikut:
UnrecognizedInputFormatException: None of the available extractors
(MatroskaExtractor, FragmentedMp4Extractor, ...) could read the stream.
Ada dua kemungkinan penyebab kegagalan ini. Penyebab yang paling umum adalah
Anda mencoba memutar konten DASH (mpd), HLS (m3u8), atau SmoothStreaming (ism, isml),
tetapi pemutar mencoba memutarnya sebagai streaming progresif. Untuk memutar streaming
tersebut, Anda harus bergantung pada modul ExoPlayer masing-masing. Jika URI streaming tidak diakhiri dengan ekstensi file standar, Anda juga dapat meneruskan MimeTypes.APPLICATION_MPD
, MimeTypes.APPLICATION_M3U8
, atau MimeTypes.APPLICATION_SS
ke setMimeType
dari MediaItem.Builder
untuk menentukan jenis aliran data secara eksplisit.
Penyebab kedua yang kurang umum adalah ExoPlayer tidak mendukung format container media yang Anda coba putar. Dalam hal ini, kegagalan tersebut berfungsi sebagaimana mestinya. Namun, jangan ragu untuk mengirimkan permintaan fitur ke Issue Tracker kami, termasuk detail format penampung dan streaming pengujian. Telusuri permintaan fitur yang ada sebelum mengirimkan permintaan baru.
Mengapa setPlaybackParameters tidak berfungsi dengan baik di beberapa perangkat?
Saat menjalankan build debug aplikasi di Android M dan yang lebih lama, Anda mungkin
akan mengalami performa putus-putus, artefak terdengar, dan pemakaian CPU yang tinggi saat
menggunakan setPlaybackParameters
API. Hal ini karena pengoptimalan
yang penting bagi API ini dinonaktifkan untuk build debug yang berjalan pada
versi Android ini.
Penting untuk diperhatikan bahwa masalah ini hanya memengaruhi build debug. Hal ini tidak memengaruhi build rilis, yang pengoptimalannya selalu diaktifkan. Oleh karena itu, rilis yang Anda berikan kepada pengguna akhir tidak akan terpengaruh oleh masalah ini.
Apa yang dimaksud dengan error "Pemutar diakses di thread yang salah"?
Lihat Catatan tentang threading di halaman memulai.
Bagaimana cara memperbaiki "Baris status tak terduga: ICY 200 OK"?
Masalah ini dapat terjadi jika respons server menyertakan baris status ICY, bukan yang mematuhi HTTP. Baris status ICY tidak digunakan lagi dan tidak boleh digunakan. Jadi, jika mengontrol server, Anda harus mengupdatenya untuk memberikan respons yang sesuai dengan HTTP. Jika Anda tidak dapat melakukannya, penggunaan library OkHttp ExoPlayer akan menyelesaikan masalah ini, karena dapat menangani baris status ICY dengan benar.
Bagaimana cara menanyakan apakah streaming yang diputar adalah live stream?
Anda dapat membuat kueri metode isCurrentWindowLive
pemain. Selain itu, Anda
dapat memeriksa isCurrentWindowDynamic
untuk mengetahui apakah jendela bersifat dinamis
(yaitu, masih diperbarui dari waktu ke waktu).
Bagaimana cara agar audio tetap diputar saat aplikasi saya berjalan di latar belakang?
Ikuti langkah-langkah berikut untuk memastikan pemutaran audio yang berkelanjutan saat aplikasi berada di latar belakang:
- Anda harus memiliki layanan latar depan yang berjalan. Hal ini mencegah sistem memutuskan proses Anda untuk membebaskan sumber daya.
- Anda harus menyimpan
WifiLock
danWakeLock
. Hal ini memastikan bahwa sistem menjaga radio Wi-Fi dan CPU tetap aktif. Hal ini dapat dengan mudah dilakukan jika menggunakanExoPlayer
dengan memanggilsetWakeMode
, yang akan otomatis mendapatkan dan melepaskan kunci yang diperlukan pada waktu yang tepat.
Anda harus melepaskan kunci (jika tidak menggunakan setWakeMode
) dan menghentikan
layanan segera setelah audio tidak lagi diputar.
Mengapa ExoPlayer mendukung konten saya tetapi library Cast ExoPlayer tidak?
Ada kemungkinan konten yang Anda coba putar tidak diaktifkan CORS. Framework Cast mengharuskan konten diaktifkan CORS agar dapat memutarnya.
Mengapa konten gagal diputar, tetapi tidak ada error yang muncul?
Ada kemungkinan bahwa perangkat tempat Anda memutar konten tidak
mendukung format sampel media tertentu. Hal ini dapat dikonfirmasi dengan mudah dengan menambahkan
EventLogger
sebagai pemroses ke pemutar Anda, dan mencari baris
yang serupa dengan yang ada di Logcat:
[ ] Track:x, id=x, mimeType=mime/type, ... , supported=NO_UNSUPPORTED_TYPE
NO_UNSUPPORTED_TYPE
berarti bahwa perangkat tidak dapat mendekode format
sampel media yang ditentukan oleh mimeType
. Lihat Dokumentasi format
media Android untuk mengetahui informasi tentang format contoh yang didukung. Bagaimana cara agar library decoding
dimuat dan digunakan untuk pemutaran? juga dapat berguna.
Bagaimana cara memuat library decoding dan digunakan untuk pemutaran?
- Sebagian besar library decoder memiliki langkah manual untuk memeriksa dan mem-build dependensi. Jadi, pastikan Anda telah mengikuti langkah-langkah di README untuk library yang relevan. Misalnya, untuk library FFmpeg ExoPlayer, Anda harus mengikuti petunjuk di libraries/decoder_ffmpeg/README.md, termasuk meneruskan flag konfigurasi untuk mengaktifkan dekoder untuk setiap format yang ingin Anda putar.
- Untuk library yang memiliki kode native, pastikan Anda menggunakan versi Android NDK yang benar
seperti yang ditetapkan dalam README, dan cari apakah ada
error yang muncul selama konfigurasi dan proses build. Anda akan melihat file
.so
muncul di subdirektorilibs
dari jalur library untuk setiap arsitektur yang didukung setelah mengikuti langkah-langkah di README. - Untuk mencoba pemutaran menggunakan library di aplikasi demo, lihat mengaktifkan dekoder yang dipaketkan. Lihat README untuk library guna mengetahui petunjuk cara menggunakan library dari aplikasi Anda.
- Jika menggunakan
DefaultRenderersFactory
, Anda akan melihat baris log level info seperti "Loaded FfmpegAudioRenderer" di Logcat saat decoder dimuat. Jika nilai ini tidak ada, pastikan aplikasi memiliki dependensi pada library decoding. - Jika Anda melihat log level peringatan dari
LibraryLoader
di Logcat, ini menunjukkan bahwa pemuatan komponen native library gagal. Jika hal ini terjadi, pastikan Anda telah mengikuti langkah-langkah di README library dengan benar dan tidak ada error yang muncul saat mengikuti petunjuk.
Jika Anda masih mengalami masalah saat menggunakan library decoding, periksa issue tracker Media3 untuk menemukan masalah terbaru yang relevan. Jika Anda perlu mengajukan masalah baru dan terkait dengan build bagian native library, sertakan output command line lengkap dari menjalankan petunjuk README untuk membantu kami mendiagnosis masalah.
Bisakah saya memutar video YouTube langsung dengan ExoPlayer?
Tidak, ExoPlayer tidak dapat memutar video dari YouTube, seperti URL dengan format
https://www.youtube.com/watch?v=...
. Sebagai gantinya, sebaiknya gunakan YouTube
IFrame Player API,
yang merupakan cara resmi untuk memutar video YouTube di Android.
Pemutaran video tersendat
Perangkat mungkin tidak dapat mendekode konten dengan cukup cepat jika, misalnya, kecepatan bit atau resolusi konten melebihi kemampuan perangkat. Anda mungkin perlu menggunakan konten berkualitas lebih rendah untuk mendapatkan performa yang baik di perangkat tersebut.
Jika Anda mengalami video yang tersendat pada perangkat yang menjalankan versi Android dari Android 6.0 (API level 23) hingga dan termasuk Android 11 (API level 30), terutama saat memutar konten yang dilindungi DRM atau konten dengan kecepatan frame tinggi, Anda dapat mencoba mengaktifkan antrean buffer asinkron.
Error lint API tidak stabil
Media3 menjamin kompatibilitas biner untuk subset platform API. Bagian
yang tidak menjamin kompatibilitas biner ditandai dengan
@UnstableApi
. Untuk memperjelas perbedaan ini, penggunaan simbol API
yang tidak stabil akan menghasilkan error lint kecuali jika dianotasi dengan @OptIn
.
Anotasi @UnstableApi
tidak menyiratkan apa pun terkait kualitas atau performa API, hanya fakta bahwa anotasi tidak berstatus "API-frozen".
Anda memiliki dua pilihan untuk menangani error lint API yang tidak stabil:
- Beralihlah untuk menggunakan API stabil yang memberikan hasil sama.
- Terus gunakan API yang tidak stabil dan anotasikan penggunaan dengan
@OptIn
, seperti yang ditunjukkan nanti.
Menambahkan anotasi @OptIn
Android Studio dapat membantu Anda menambahkan anotasi:
Anda juga dapat menganotasi situs penggunaan tertentu di Kotlin secara manual:
import androidx.annotation.OptIn
import androidx.media3.common.util.UnstableApi
@OptIn(UnstableApi::class)
fun functionUsingUnstableApi() { ... }
Dan juga pada Java:
import androidx.annotation.OptIn;
import androidx.media3.common.util.UnstableApi;
@OptIn(markerClass = UnstableApi.class)
private void methodUsingUnstableApis() { ... }
Seluruh paket dapat diikutsertakan dengan menambahkan file package-info.java
:
@OptIn(markerClass = UnstableApi.class)
package name.of.your.package;
import androidx.annotation.OptIn;
import androidx.media3.common.util.UnstableApi;
Seluruh project dapat diikutsertakan dengan menyembunyikan error lint tertentu dalam
file lint.xml
-nya:
<?xml version="1.0" encoding="utf-8"?>
<lint>
<issue id="UnsafeOptInUsageError">
<option name="opt-in" value="androidx.media3.common.util.UnstableApi" />
</issue>
</lint>
Ada juga anotasi kotlin.OptIn
yang tidak boleh digunakan. Anotasi
androidx.annotation.OptIn
harus digunakan.