- Memperbaiki "Traffic HTTP cleartext tidak diizinkan" error
- Memperbaiki "SSLHandshakeException", "CertPathValidatorException" dan "ERR_CERT_AUTHORITY_INVALID" error
- Mengapa beberapa file media tidak dapat dicari?
- Mengapa pencarian yang tidak akurat di beberapa file MP3?
- Mengapa 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 diputar dengan tidak benar?
- Mengapa beberapa streaming gagal dengan kode respons HTTP 301 atau 302?
- Mengapa beberapa streaming gagal dengan InvalidInputFormatException?
- Mengapa setPlaybackParameters tidak berfungsi dengan baik di beberapa perangkat?
- Apa yang dimaksud dengan "Pemutar diakses di rangkaian pesan yang salah" error tersebut?
- Bagaimana cara memperbaiki "Baris status tidak terduga: ICY 200 OK"?
- Bagaimana cara menanyakan apakah streaming yang sedang diputar adalah live stream?
- Bagaimana cara agar audio tetap diputar saat aplikasi saya berada di latar belakang?
- Mengapa ExoPlayer mendukung konten saya, tetapi library ExoPlayer tidak mendukungnya?
- Mengapa konten gagal diputar, tetapi tidak ada error yang muncul?
- Bagaimana cara mendapatkan library decoding untuk dimuat dan digunakan untuk pemutaran?
- Dapatkah saya memutar video YouTube secara langsung dengan ExoPlayer?
- Pemutaran video tersendat
- Error lint API tidak stabil
Memperbaiki "Traffic HTTP Cleartext tidak diizinkan" kesalahan
Error ini akan terjadi jika aplikasi Anda meminta traffic HTTP cleartext (yaitu,
http://
, bukan https://
) saat Konfigurasi Keamanan Jaringannya melakukan
tidak mengizinkannya. Jika aplikasi Anda menargetkan Android 9 (API level 28) atau yang lebih baru, cleartext
Traffic HTTP dinonaktifkan oleh konfigurasi default.
Jika aplikasi Anda perlu bekerja dengan traffic HTTP cleartext, maka Anda perlu menggunakan
Konfigurasi Keamanan Jaringan yang mengizinkannya. Lihat
dokumentasi keamanan jaringan
untuk mengetahui detailnya. Untuk mengaktifkan semua traffic HTTP cleartext, cukup tambahkan
android:usesCleartextTraffic="true"
ke elemen application
aplikasi Anda
AndroidManifest.xml
.
Aplikasi demo ExoPlayer menggunakan Konfigurasi Keamanan Jaringan default, sehingga {i>password<i} tidak memungkinkan lalu lintas HTTP cleartext. Anda dapat mengaktifkannya dengan mengikuti petunjuk di atas.
Memperbaiki "SSLHandshakeException", "CertPathValidatorException" dan "ERR_CERT_AUTHORITY_INVALID" kesalahan
SSLHandshakeException
, CertPathValidatorException
, dan
ERR_CERT_AUTHORITY_INVALID
semua menunjukkan masalah dengan SSL server
CA {i>root<i}. Error ini tidak spesifik untuk ExoPlayer. Lihat
Dokumentasi SSL Android
untuk mengetahui detail selengkapnya.
Mengapa beberapa file media tidak dapat dicari?
Secara default, ExoPlayer tidak mendukung pencarian di media di mana satu-satunya metode untuk melakukan operasi pencarian yang akurat adalah pemain memindai dan mengindeks keseluruhan file. ExoPlayer menganggap file tersebut sebagai tidak dapat dicari. Media paling modern format kontainer mencakup metadata untuk pencarian (seperti indeks sampel), memiliki algoritma pencarian yang didefinisikan dengan baik (misalnya, pencarian dua bagian terinterpolasi untuk Ogg), atau menunjukkan bahwa kecepatan bit konten mereka konstan. Operasi pencarian yang efisien adalah dan didukung oleh ExoPlayer dalam kasus ini.
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, seperti yang dijelaskan di sini.
Mengapa pencarian tidak akurat di beberapa file MP3?
File MP3 dengan kecepatan bit variabel (VBR) pada dasarnya tidak cocok untuk kasus penggunaan yang memerlukan pencarian persis. Ada dua alasan untuk ini:
- Untuk pencarian persis, format container idealnya akan memberikan pemetaan waktu-ke-byte di {i>header<i}. Pemetaan ini memungkinkan pemain memetakan yang diminta ke offset byte terkait, dan mulai meminta, mengurai dan memutar media dari offset tersebut. {i>Header<i} yang tersedia untuk menentukan pemetaan ini dalam MP3 (seperti {i>header <i}XING) sering kali tidak akurat.
- Untuk format penampung yang tidak memberikan pemetaan waktu hingga byte yang tepat (atau pemetaan waktu-ke-byte), masih mungkin untuk melakukan cari apakah penampung menyertakan stempel waktu sampel absolut dalam aliran data. Di beberapa dalam hal ini, pemain dapat memetakan waktu pencarian ke prediksi offset byte, mulai meminta media dari offset tersebut, mengurai stempel waktu sampel absolut, dan secara efektif melakukan penelusuran biner terpandu ke media sampai menemukan sampel yang tepat. Sayangnya MP3 tidak menyertakan stempel waktu sampel absolut dalam aliran data, sehingga pendekatan ini tidak sebaik mungkin.
Karena alasan ini, satu-satunya cara untuk melakukan pencarian
yang tepat ke dalam file MP3 VBR adalah
memindai seluruh file dan secara manual
membuat pemetaan {i>time-to-byte<i} di
web. Strategi ini dapat diaktifkan dengan menggunakan FLAG_ENABLE_INDEX_SEEKING
,
yang dapat ditetapkan di DefaultExtractorsFactory
menggunakan
setMp3ExtractorFlags
. Perhatikan bahwa itu tidak diskalakan dengan
baik untuk file MP3 besar,
terutama jika pengguna mencoba mencari cara mendekati akhir streaming
setelah memulai pemutaran, yang mengharuskan pemutar menunggu hingga video selesai didownload
dan mengindeks seluruh aliran sebelum melakukan pencarian. Di ExoPlayer, kami
memutuskan untuk mengoptimalkan
kecepatan daripada akurasi dan
Oleh karena itu, FLAG_ENABLE_INDEX_SEEKING
dinonaktifkan secara default.
Jika Anda mengontrol media yang sedang diputar, sebaiknya Anda menggunakan yang sesuai, seperti MP4. Tidak ada kasus penggunaan yang kami ketahui di mana MP3 adalah pilihan format media terbaik.
Mengapa pencarian di video saya lambat?
Saat pemutar mencari posisi pemutaran baru dalam video, pemutar perlu melakukan dua hal:
- Memuat data yang sesuai dengan posisi pemutaran baru ke buffer (tindakan ini mungkin tidak diperlukan jika data ini sudah di-buffer).
- Hapus dekoder video dan mulai decoding dari I-frame (frame utama) sebelum posisi pemutaran baru, karena pengkodean intra-frame yang digunakan oleh sebagian besar video format kompresi yang berbeda. Untuk memastikan pencariannya akurat (yaitu, pemutaran dimulai tepat di posisi pencarian), semua frame di antara I-frame sebelumnya dan posisi pencarian harus didekode dan segera dibuang (tanpa ditampilkan di layar).
Latensi yang diperkenalkan oleh (1) dapat dimitigasi dengan meningkatkan jumlah data yang di-buffer di 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 encoding ulang video
memiliki I-frame yang lebih sering (yang akan menghasilkan file {i>output<i} yang lebih besar).
Mengapa beberapa file MPEG-TS gagal diputar?
Beberapa file MPEG-TS tidak berisi pemisah unit akses (AUD). Secara {i>default<i}, 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 keyframe yang dipertimbangkan oleh ExoPlayer.
ExoPlayer akan tampak terjebak dalam status buffering ketika diminta untuk memainkan
File MPEG-TS yang tidak memiliki keyframe AUD atau IDR. Jika Anda perlu
memutar file tersebut,
Anda dapat melakukannya menggunakan FLAG_DETECT_ACCESS_UNITS
dan
FLAG_ALLOW_NON_IDR_KEYFRAMES
. Tanda ini dapat ditetapkan pada
DefaultExtractorsFactory
menggunakan setTsExtractorFlags
atau di
DefaultHlsExtractorFactory
menggunakan
konstruktor.
Penggunaan FLAG_DETECT_ACCESS_UNITS
tidak memiliki efek samping selain
mahal secara komputasi dibandingkan dengan deteksi batas {i>frame<i} berbasis AUD. Penggunaan
FLAG_ALLOW_NON_IDR_KEYFRAMES
dapat mengakibatkan kerusakan visual sementara pada
ketika memutar beberapa file MPEG-TS.
Mengapa subtitel tidak ditemukan di beberapa file MPEG-TS?
Beberapa file MPEG-TS menyertakan trek CEA-608 tetapi tidak menyatakannya dalam
metadata container, sehingga ExoPlayer tidak dapat mendeteksinya. Anda dapat secara manual
menentukan trek subtitle dengan memberikan daftar
format subtitel ke DefaultExtractorsFactory
, termasuk aksesibilitas
saluran 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 diputar dengan tidak benar?
Beberapa file MP4/FMP4 berisi daftar edit yang menulis ulang {i>timeline<i} media dengan melewati, memindahkan, atau mengulangi daftar contoh. ExoPlayer memiliki dukungan parsial untuk menerapkan daftar edit. Misalnya, fungsi ini dapat menunda atau mengulangi grup sampel memulai contoh sinkronisasi, tetapi tidak memotong sampel audio atau pre-roll media untuk pengeditan yang tidak dimulai pada contoh sinkronisasi.
Jika Anda melihat ada bagian media yang
tiba-tiba hilang atau berulang,
coba setel Mp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS
atau
FragmentedMp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS
, yang akan menyebabkan
ekstraktor untuk mengabaikan
daftar edit sepenuhnya. Layanan ini dapat disetel pada
DefaultExtractorsFactory
menggunakan setMp4ExtractorFlags
atau
setFragmentedMp4ExtractorFlags
.
Mengapa beberapa streaming gagal dengan kode respons HTTP 301 atau 302?
Kode respons HTTP 301 dan 302 keduanya menunjukkan pengalihan. Deskripsi singkat dapat ditemukan di Wikipedia. Ketika ExoPlayer membuat permintaan dan menerima dengan kode status 301 atau 302, respons tersebut biasanya akan mengikuti pengalihan dan memulai pemutaran seperti biasa. Satu kasus di mana hal ini tidak terjadi secara default untuk pengalihan lintas protokol. Pengalihan lintas protokol adalah pengalihan yang mengalihkan dari HTTPS ke HTTP atau sebaliknya (atau yang jarang, antara pasangan ). 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-nya 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
hingga https://second.com/test.mp3
. Keduanya adalah
HTTPS, sehingga ini bukan pengalihan lintas protokol. Pengalihan kedua adalah dari
https://second.com/test.mp3
hingga http://third.com/test.mp3
. Pengalihan ini
dari HTTPS ke HTTP dan begitu juga
sebagai pengalihan lintas protokol. ExoPlayer tidak akan
ikuti 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. Pelajari cara memilih dan mengonfigurasi stack jaringan
di sini.
Mengapa beberapa streaming gagal dengan KnownInputFormatException?
Pertanyaan ini berkaitan dengan kegagalan pemutaran dalam format 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 DASH (mpd), HLS (m3u8), atau SmoothStreaming (ism, isml)
konten, tetapi pemutar mencoba memutarnya sebagai streaming progresif. Untuk memutar
streaming, Anda harus bergantung pada modul ExoPlayer masing-masing. Dalam kasus di mana
URI aliran data tidak diakhiri dengan ekstensi file standar, Anda juga bisa meneruskan
MimeTypes.APPLICATION_MPD
, MimeTypes.APPLICATION_M3U8
, atau
MimeTypes.APPLICATION_SS
ke setMimeType
dari MediaItem.Builder
untuk secara eksplisit
menentukan jenis streaming.
Penyebab kedua yang kurang umum adalah ExoPlayer tidak mendukung container format media yang Anda coba putar. Dalam hal ini, kegagalannya adalah berfungsi sebagaimana mestinya, namun jangan ragu untuk mengirimkan permintaan fitur ke Issue Tracker, termasuk detail format penampung dan streaming uji coba. Telusuri permintaan fitur yang sudah ada sebelum mengirimkan yang baru.
Mengapa setPlaybackParameters tidak berfungsi dengan baik di beberapa perangkat?
Saat menjalankan build debug aplikasi di Android M dan yang lebih lama, Anda dapat
mengalami kinerja yang putus-putus, artefak
yang dapat didengar, dan pemanfaatan CPU yang tinggi saat
menggunakan setPlaybackParameters
API. Hal ini karena pengoptimalan
untuk API ini dinonaktifkan untuk build debug yang berjalan pada
untuk semua versi Android.
Penting untuk diperhatikan bahwa masalah ini hanya memengaruhi build debug. Tidak akan memengaruhi build rilis, yang pengoptimalannya selalu diaktifkan. Oleh karena itu, rilis yang diberikan ke pengguna akhir tidak akan terpengaruh oleh masalah ini.
Apa yang dimaksud dengan "Pemutar diakses di thread yang salah" {i>error <i}yang dimaksud?
Lihat Catatan tentang rangkaian pesan di halaman memulai.
Bagaimana cara memperbaiki "Unexpected status line: ICY 200 OK"?
Masalah ini dapat terjadi jika respons server menyertakan baris status ICY, dan bukan yang sesuai dengan HTTP. Baris status ICY tidak digunakan lagi dan tidak boleh digunakan, jadi jika Anda mengontrol server, Anda harus memperbaruinya untuk memberikan respons yang sesuai dengan HTTP. Jika Anda tidak dapat melakukannya, gunakan Library OkHttp ExoPlayer akan menyelesaikan masalah, karena dapat menangani ICY baris status dengan benar.
Bagaimana cara menanyakan apakah streaming yang sedang diputar merupakan live stream?
Anda dapat membuat kueri metode isCurrentWindowLive
pemutar. Selain itu, Anda
dapat memeriksa isCurrentWindowDynamic
untuk mengetahui apakah jendela bersifat dinamis
(yaitu, masih diperbarui dari waktu ke waktu).
Bagaimana cara terus memutar audio saat aplikasi saya berada di latar belakang?
Ikuti langkah-langkah berikut untuk memastikan pemutaran audio yang berkelanjutan saat aplikasi Anda berada latar belakang:
- Anda harus memiliki layanan latar depan yang berjalan. Hal ini mencegah sistem mulai dari menghentikan proses Anda hingga membebaskan sumber daya.
- Anda harus menyimpan
WifiLock
danWakeLock
. Hal ini memastikan bahwa menjaga agar 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 itu segera setelah audio tidak lagi diputar.
Mengapa ExoPlayer mendukung konten saya, tetapi library ExoPlayer tidak mendukungnya?
Mungkin saja konten yang Anda coba putar tidak CORS diaktifkan. Framework Cast mengharuskan konten diaktifkan dengan CORS di untuk memutarnya.
Mengapa konten gagal diputar, tetapi tidak ada error yang muncul?
Mungkin saja perangkat yang Anda gunakan
untuk memutar konten tidak
mendukung format sampel media tertentu. Hal ini dapat dikonfirmasi
dengan mudah dengan menambahkan
EventLogger
sebagai pemroses pemutar Anda, dan mencari garis
mirip dengan yang ini di Logcat:
[ ] Track:x, id=x, mimeType=mime/type, ... , supported=NO_UNSUPPORTED_TYPE
NO_UNSUPPORTED_TYPE
berarti perangkat tidak dapat mendekode media
contoh format yang ditentukan oleh mimeType
. Lihat Format media Android
dokumentasi untuk mendapatkan informasi tentang format contoh yang didukung. Bagaimana cara agar
library decoding untuk dimuat dan digunakan untuk pemutaran? mungkin juga berguna.
Bagaimana cara mendapatkan library decoding untuk dimuat dan digunakan untuk pemutaran?
- Sebagian besar library decoder memiliki langkah manual untuk memeriksa dan membangun dependensinya, jadi pastikan Anda telah mengikuti langkah-langkah yang ada di README untuk {i>library<i} yang relevan. Misalnya, untuk library FFmpeg ExoPlayer, Anda harus mengikuti di libraries/decoder_ffmpeg/README.md, termasuk meneruskan flag konfigurasi guna mengaktifkan decoder untuk format apa pun yang ingin Anda putar.
- Untuk library yang memiliki kode native, pastikan Anda menggunakan
Android NDK seperti yang ditentukan dalam README, dan periksa
error yang muncul selama konfigurasi dan build. Anda akan melihat
.so
muncul di subdirektorilibs
pada jalur library untuk masing-masing arsitektur yang didukung setelah mengikuti langkah-langkah di README. - Untuk mencoba pemutaran menggunakan library di aplikasi demo, lihat mengaktifkan decoder paket. Lihat README untuk perpustakaan untuk petunjuk tentang cara menggunakan library dari aplikasi Anda sendiri.
- Jika menggunakan
DefaultRenderersFactory
, Anda akan melihat tingkat info baris log seperti "Loaded FfmpegAudioRenderer" di Logcat saat decoder dimuat. Jika tidak ada, pastikan aplikasi memiliki dependensi pada library decoding. - Jika Anda melihat log tingkat peringatan dari
LibraryLoader
di Logcat, ini adalah menunjukkan bahwa pemuatan komponen native library gagal. Jika ini terjadi, periksa apakah Anda telah mengikuti langkah-langkah di README library dengan benar dan tidak ada error yang dihasilkan saat mengikuti petunjuk.
Jika Anda masih mengalami masalah saat menggunakan library decoding, periksa Issue tracker media3 untuk masalah terbaru yang relevan. Jika Anda perlu mengajukan masalah baru dan berkaitan dengan membangun bagian native library, harap menyertakan output baris perintah lengkap dari menjalankan instruksi README, untuk membantu kita mendiagnosis masalah.
Dapatkah saya memutar video YouTube secara langsung dengan ExoPlayer?
Tidak, ExoPlayer tidak dapat memutar video dari YouTube, seperti URL formulir
https://www.youtube.com/watch?v=...
. Sebagai gantinya, Anda harus menggunakan
API Pemutar IFrame,
yang merupakan cara resmi untuk
memutar video YouTube di Android.
Pemutaran video tersendat
Perangkat mungkin tidak dapat memecahkan kode konten dengan cukup cepat jika, misalnya, kecepatan bit atau resolusi konten melebihi kemampuan perangkat. Anda mungkin memerlukan menggunakan konten berkualitas lebih rendah untuk memperoleh performa yang baik di perangkat tersebut.
Jika video tersendat di perangkat yang menjalankan versi Android mulai dari Android 6.0 (level API 23) hingga dan termasuk Android 11 (level API 30), terutama saat memutar konten yang dilindungi DRM atau dengan kecepatan frame tinggi, Anda dapat mencoba mengaktifkan antrean buffer asinkron.
Error lint API tidak stabil
Media3 menjamin kompatibilitas biner untuk subset platform API. Tujuan
bagian yang tidak menjamin kompatibilitas biner ditandai dengan
@UnstableApi
Untuk memperjelas perbedaan ini, penggunaan data dari ketidakstabilan
Simbol API menghasilkan error lint kecuali jika dianotasi dengan @OptIn
.
Anotasi @UnstableApi
tidak menyiratkan apa pun tentang kualitas atau performa API, hanya fakta bahwa API tidak "dibekukan API".
Anda memiliki dua pilihan untuk menangani error lint API yang tidak stabil:
- Beralihlah untuk menggunakan API stabil yang mencapai hasil yang sama.
- Terus gunakan API yang tidak stabil dan anotasikan penggunaan dengan
@OptIn
, sebagai yang akan ditampilkan.
Menambahkan anotasi @OptIn
Android Studio dapat membantu Anda menambahkan anotasi:
Anda juga dapat menganotasi secara manual situs penggunaan tertentu di Kotlin:
import androidx.annotation.OptIn
import androidx.media3.common.util.UnstableApi
@OptIn(UnstableApi::class)
fun functionUsingUnstableApi() { ... }
Dan juga di 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 bisa diikutsertakan dengan menyembunyikan error lint tertentu dalam
File lint.xml
:
<?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. Penting
penting untuk menggunakan
anotasi androidx.annotation.OptIn
.