Catatan, untuk pertanyaan di bawah ini: Semua aset bersifat lokal di perangkat - tidak ada streaming jaringan yang berlangsung. Video berisi trek audio.
Saya sedang mengerjakan aplikasi iOS yang membutuhkan pemutaran file video dengan penundaan minimum untuk memulai klip video yang dimaksud. Sayangnya kami tidak tahu klip video spesifik apa berikutnya sampai kami benar-benar perlu memulainya. Khususnya: Ketika satu klip video diputar, kita akan tahu apa set berikutnya dari (kira-kira) 10 klip video itu, tapi kita tidak tahu persisnya yang mana, sampai tiba saatnya untuk 'segera' memutar klip berikutnya.
Apa yang telah saya lakukan untuk melihat penundaan awal yang sebenarnya adalah memanggil addBoundaryTimeObserverForTimes
pemutar video, dengan jangka waktu satu milidetik untuk melihat kapan video benar-benar mulai diputar, dan saya mengambil perbedaan dari stempel waktu itu dengan tempat pertama di kode yang menunjukkan aset mana yang akan mulai dimainkan.
Dari apa yang saya lihat sejauh ini, saya telah menemukan bahwa menggunakan kombinasi AVAsset
pemuatan, dan kemudian membuat AVPlayerItem
dari itu setelah siap, dan kemudian menunggu AVPlayerStatusReadyToPlay
sebelum saya memanggil permainan, cenderung memakan waktu antara 1 dan 3 detik untuk memulai klip.
Sejak itu saya beralih ke apa yang menurut saya kira-kira setara: menelepon [AVPlayerItem playerItemWithURL:]
dan menunggu untuk AVPlayerItemStatusReadyToPlay
bermain. Performa yang hampir sama.
Satu hal yang saya amati adalah bahwa pemuatan item AVPlayer pertama lebih lambat daripada yang lain. Tampaknya salah satu idenya adalah melakukan pra-penerbangan AVPlayer dengan aset pendek / kosong sebelum mencoba memutar video pertama mungkin merupakan praktik umum yang baik. [ Start lambat untuk AVAudioPlayer saat pertama kali suara dimainkan
Saya ingin menurunkan waktu mulai video sebanyak mungkin, dan memiliki beberapa ide untuk bereksperimen, tetapi membutuhkan beberapa panduan dari siapa pun yang mungkin dapat membantu.
Pembaruan: ide 7, di bawah, saat diterapkan menghasilkan waktu peralihan sekitar 500 ms. Ini adalah peningkatan, tetapi alangkah baiknya untuk mendapatkan ini lebih cepat.
Ide 1: Gunakan N AVPlayers (tidak berfungsi)
Menggunakan ~ 10 AVPPlayer
objek dan memulai-dan-menghentikan semua ~ 10 klip, dan setelah kita tahu mana yang benar-benar kita butuhkan, beralihlah ke, dan batalkan jeda yang benar AVPlayer
, dan mulai dari awal lagi untuk siklus berikutnya.
Saya tidak berpikir ini berfungsi, karena saya telah membaca kira-kira ada batas 4 aktif AVPlayer's
di iOS. Ada seseorang yang menanyakan hal ini di StackOverflow di sini, dan mengetahui tentang 4 batas AVPlayer: peralihan cepat antar-video-menggunakan-avfoundation
Ide 2: Gunakan AVQueuePlayer (tidak berfungsi)
Saya tidak percaya bahwa mendorong 10 AVPlayerItems
ke dalam AVQueuePlayer
akan memuat sebelumnya semuanya untuk awal yang mulus. AVQueuePlayer
adalah antrean, dan menurut saya itu hanya membuat video berikutnya dalam antrean siap untuk segera diputar. Saya tidak tahu mana dari ~ 10 video yang ingin kami putar, sampai saatnya untuk memulainya. ios-avplayer-video-pramuat
Ide 3: Muat, Putar, dan simpan AVPlayerItems
di latar belakang (belum 100% yakin - tapi belum terlihat bagus)
Saya melihat apakah ada manfaat untuk memuat dan memutar detik pertama dari setiap klip video di latar belakang (menekan keluaran video dan audio), dan menyimpan referensi untuk masing-masing AVPlayerItem
, dan ketika kita tahu item mana yang perlu diputar nyata, tukar yang satu itu, dan tukar latar belakang AVPlayer dengan yang aktif. Bilas dan Ulangi.
Teorinya adalah bahwa lagu yang baru diputar AVPlayer/AVPlayerItem
mungkin masih memiliki beberapa sumber daya yang disiapkan yang akan membuat pemutaran berikutnya lebih cepat. Sejauh ini, saya belum melihat manfaat dari ini, tetapi saya mungkin tidak memiliki AVPlayerLayer
penyiapan dengan benar untuk latar belakang. Saya ragu ini benar-benar akan meningkatkan hal-hal dari apa yang saya lihat.
Ide 4: Gunakan format file yang berbeda - mungkin yang lebih cepat dimuat?
Saat ini saya menggunakan format H.264 .m4v (video-MPEG4). H.264 memiliki banyak opsi codec yang berbeda, jadi ada kemungkinan beberapa opsi lebih cepat dicari daripada yang lain. Saya telah menemukan bahwa menggunakan pengaturan yang lebih canggih yang membuat ukuran file lebih kecil meningkatkan waktu pencarian, tetapi belum menemukan opsi yang sebaliknya.
Ide 5: Kombinasi format video lossless + AVQueuePlayer
Jika ada format video yang cepat dimuat, tetapi mungkin ukuran filenya tidak masuk akal, salah satu ide mungkin untuk mempersiapkan 10 detik pertama dari setiap klip video dengan versi yang membengkak tetapi lebih cepat memuat, tetapi mundur itu dengan aset yang dikodekan dalam H.264. Gunakan AVQueuePlayer, dan tambahkan 10 detik pertama dalam format file yang tidak terkompresi, dan ikuti dengan yang ada di H.264 yang mendapatkan waktu persiapan / pramuat hingga 10 detik. Jadi saya akan mendapatkan 'yang terbaik' dari kedua dunia: waktu mulai yang cepat, tetapi juga mendapatkan keuntungan dari format yang lebih ringkas.
Ide 6: Gunakan AVPlayer non-standar / tulis milik saya / gunakan milik orang lain
Mengingat kebutuhan saya, mungkin saya tidak dapat menggunakan AVPlayer, tetapi harus menggunakan AVAssetReader, dan memecahkan kode beberapa detik pertama (mungkin menulis file mentah ke disk), dan ketika sampai pada pemutaran, gunakan format mentah untuk memainkannya kembali dengan cepat. Sepertinya proyek besar bagi saya, dan jika saya melakukannya dengan cara yang naif, tidak jelas / tidak mungkin untuk bekerja lebih baik. Setiap bingkai video yang didekodekan dan tidak dikompresi berukuran 2,25 MB. Berbicara secara naif - jika kita menggunakan ~ 30 fps untuk video, saya akan mendapatkan ~ 60 MB / s persyaratan baca-dari-disk, yang mungkin tidak mungkin / mendorongnya. Jelas kami harus melakukan beberapa tingkat kompresi gambar (mungkin format kompresi openGL / es asli melalui PVRTC) ... tapi itu agak gila. Mungkin ada perpustakaan di luar sana yang bisa saya gunakan?
Ide 7: Gabungkan semuanya menjadi satu aset film, dan seekToTime
Satu ide yang mungkin lebih mudah daripada beberapa ide di atas, adalah menggabungkan semuanya ke dalam satu film, dan menggunakan seekToTime. Masalahnya adalah kita akan melompat-lompat di sekitar tempat itu. Pada dasarnya akses acak ke dalam film. Saya pikir ini mungkin benar-benar berhasil: avplayer-movie-playing-lag-in-ios5
Pendekatan mana yang menurut Anda paling baik? Sejauh ini, saya belum membuat banyak kemajuan dalam hal mengurangi lag.