Cara mengurangi penundaan mulai AVPlayer iOS

115

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 addBoundaryTimeObserverForTimespemutar 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 AVAssetpemuatan, dan kemudian membuat AVPlayerItemdari itu setelah siap, dan kemudian menunggu AVPlayerStatusReadyToPlaysebelum 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 AVPlayerItemStatusReadyToPlaybermain. 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 AVPPlayerobjek 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'sdi 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 AVPlayerItemske dalam AVQueuePlayerakan memuat sebelumnya semuanya untuk awal yang mulus. AVQueuePlayeradalah 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 AVPlayerItemsdi 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/AVPlayerItemmungkin 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 AVPlayerLayerpenyiapan 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.

Bernt Habermeier
sumber
Untuk apa nilainya, saya akan menggunakan Ide 7. Ini masih lambat, tetapi tidak sepelan opsi lainnya. Pertanyaan berikutnya yang saya miliki adalah - apakah opsi codec, resolusi, dan frekuensi key-frame berdampak pada waktu seekto?
Bernt Habermeier
Terlambat bermain game, tetapi mungkin ada baiknya mengganti video secepat mungkin (yaitu segera setelah yang baru mulai diputar) dan membuat profil aplikasi untuk melihat di mana ia menghabiskan sebagian besar waktu CPU-nya.
tc.
1
Hampir setahun kemudian, apa yang pernah Anda temukan dengan ini?
lnafziger
1
Saya pergi dengan opsi 7, dan sampai di suatu tempat antara pencarian 300ms dan 500ms. Satu hal yang saya temukan adalah bahwa semakin bagus opsi mp4 codec, semakin lambat seekTo tersebut. Ada beberapa opsi kompresi video yang memungkinkan kompresi lebih baik dan menjaga kualitas video, tetapi mematikan waktu decoding.
Bernt Habermeier
2
Itu adalah permintaan yang terdengar masuk akal, tetapi sebenarnya untuk mengimplementasikan opsi 7, ada terlalu banyak aspek dalam implementasi untuk dikirim. Pertimbangkan: (a) Buat rantai alat untuk menggabungkan aset video, (b) pastikan Anda melacak offset segmen video, (c) offset pencarian saat ada permintaan untuk memutar klip tertentu, (d) gunakan addPeriodicTimeObserverForInterval untuk memeriksa jika Anda menjalankan klip video dan bereaksi sesuai (gunakan metode ini vs. addBoundaryTimeObserverForTimes single-shot karena saya telah menemukan yang terakhir terkadang tidak memicu ... secara keseluruhan, ini tidak cocok untuk menempelkan kode.
Bernt Habermeier

Jawaban:

4

Untuk iOS 10.x dan yang lebih baru untuk mengurangi penundaan mulai AVPlayer yang saya atur: avplayer.automaticallyWaitsToMinimizeStalling = false; dan itu sepertinya memperbaikinya untuk saya. Ini bisa memiliki konsekuensi lain, tetapi saya belum mencapai itu.

Saya mendapatkan ide untuk itu dari: https://stackoverflow.com/a/50598525/9620547

grizzb.dll
sumber
Saya mendapat pengurangan penundaan selama 6-7 detik. Tapi saya punya pertanyaan di sini, apakah itu akan berdampak pada kinerja aplikasi?
kalpa
@kalpa Kami telah menggunakan kode ini dalam aplikasi produksi selama lebih dari setahun tanpa efek negatif yang terlihat. Kami kebanyakan memutar file audio 20-60 menit ke pendengar di AS di mana cakupan data seluler umumnya cepat. Kasus penggunaan Anda mungkin berbeda.
grizzb
Terimakasih atas infonya. @grizzb
kalpa
1

Aset mungkin tidak siap setelah Anda membuatnya, mungkin melakukan penghitungan seperti durasi film, pastikan untuk memuat semua metadata film dalam file.

nova
sumber
1

Anda harus mencoba opsi # 7 terlebih dahulu, hanya untuk melihat apakah Anda dapat membuatnya berfungsi. Saya menduga bahwa itu tidak akan benar-benar berfungsi untuk kebutuhan Anda karena waktu pencarian kemungkinan tidak akan cukup cepat untuk memberi Anda peralihan yang mulus di antara klip. Jika Anda mencobanya dan gagal, maka saya akan menyarankan Anda melakukan opsi 4/6 dan lihat pustaka iOS saya yang dirancang khusus untuk tujuan ini, cukup lakukan pencarian cepat di Google di AVAnimator untuk mengetahui lebih lanjut. Perpustakaan saya memungkinkan untuk menerapkan loop tanpa batas dan beralih dari satu klip ke klip lainnya, sangat cepat karena video harus diterjemahkan ke dalam file terlebih dahulu. Dalam kasus Anda, semua 10 klip video akan diterjemahkan menjadi file sebelum Anda mulai, tetapi kemudian beralih di antara mereka akan cepat.

MoDJ
sumber
Bagaimana dengan bagian audio dari video tersebut? Saya membutuhkan video dan audio untuk disinkronkan.
Bernt Habermeier
Ya, audio sudah ditangani dengan sinkronisasi yang sangat erat antara trek audio dan klip video. Lihat contoh proyek xcode. Semuanya sudah diterapkan, Anda hanya perlu mengunduh dan mencobanya.
MoDJ
Apakah ada kemungkinan untuk memutar video jaringan menggunakan AVAnimator?
Richard Topchii
Tidak, ini berfungsi pada file lokal, streaming video jaringan adalah hal yang sama sekali berbeda.
MoDJ
0

Tanpa melakukan hal seperti ini sebelumnya, berdasarkan pemikiran dan pengalaman Anda, saya akan mencoba kombinasi 7 dan 1: Preload satu AVPlayer dengan beberapa detik pertama dari 10 video tindak lanjut. Maka, melewatkan kemungkinan besar akan lebih cepat dan lebih dapat diandalkan karena lebih sedikit data. Saat Anda memainkan bagian yang dipilih, Anda memiliki cukup waktu untuk mempersiapkan AVPlayer untuk sisa video tindak lanjut yang dipilih di latar belakang. Saat permulaan selesai, Anda beralih ke AVPlayer yang telah disiapkan. Jadi secara total, Anda pada waktu tertentu memiliki maksimal 2 AVPlayer yang dimuat.

Tentu saja saya tidak tahu apakah peralihan dapat dilakukan dengan sangat lancar sehingga tidak mengganggu pemutaran.

(Akan menambahkan ini sebagai komentar jika saya bisa.)

Terbaik, Peter

ilmiacs
sumber
Saya tidak menemukan manfaat memuat 10 aset secara seri pada satu AVPlayer. Selanjutnya, saya tidak mengerti saran Anda, karena saya melihat opsi (1) dan (7) saling eksklusif. Opsi 7 menggabungkan semua aset video menjadi satu aset - sehingga hanya ada satu aset untuk periode pemuatan. Inilah yang saya lakukan hari ini, dan untuk manfaatnya, saya mendapatkan kira-kira penundaan 500 ms pada waktu mulai / putar yang sebenarnya. Perlu dicatat bahwa SeekTo selesai lebih cepat daripada pemutaran bingkai pertama yang sebenarnya, jadi untuk waktu mulai yang sebenarnya, saya mengukur kapan bingkai pertama benar-benar diputar melalui panggilan balik berwaktu.
Bernt Habermeier
Hanya untuk memperjelas ide saya: Ide saya adalah membagi aset menjadi dua bagian: beberapa detik pertama dan sisanya. Sekarang Anda telah membuat dua aset dari satu. 10 permulaan Anda akan bergabung dan menggunakan lewati dan saat bermain permulaan Anda akan memuat sisanya. Ini kemudian terdiri dari saran 8 yang menambah daftar Anda.
ilmiacs
Tapi seperti yang saya pahami dari komentar terakhir Anda, sementara itu Anda mendorong penelitian lebih lanjut yang bagus, dan solusi 7 juga tidak berhasil. Sepertinya AV pada dasarnya tetap menghalangi jalan Anda dan satu-satunya cara bagi Anda untuk pergi mungkin adalah dengan menggunakan teknologi di bawahnya, yaitu Core Media, untuk mendapatkan lebih banyak kendali atas aset Anda. Peter.
ilmiacs
Oh, saya mengerti ide Anda lebih baik sekarang. Terima kasih. Akan menarik untuk menyelidiki jika Anda mendapatkan waktu pencarian yang cepat untuk klip video pendek. Saya belum mencobanya, tetapi akan layak dipertimbangkan. Mengenai penggunaan media inti - Saya belum menemukan materi referensi yang bagus tentang API tersebut. Apakah Anda memiliki sumber daya yang bagus yang dapat Anda tunjukkan?
Bernt Habermeier
Tidak maaf. Seperti yang saya katakan, saya bukan ahli AV atau Core Media. Baca saja Pertanyaan Anda dan dapatkan beberapa ide bagaimana saya secara pribadi akan melanjutkan dan ingin membagikannya. Peter
ilmiacs
0

Jika saya memahami masalah Anda dengan benar, tampaknya Anda memiliki satu video berkelanjutan yang perlu Anda muat trek audio-nya dalam waktu singkat.

Jika itu masalahnya, saya sarankan untuk melihat ke BASS . BASS adalah pustaka audio yang sangat mirip dengan AVPlayer yang memberi Anda (relatif) akses mudah ke API tingkat rendah dari kerangka AudioUnits di iOS. Apa artinya bagi Anda? Ini berarti bahwa dengan sedikit manipulasi buffer (Anda bahkan mungkin tidak membutuhkannya, tergantung seberapa kecil Anda menginginkan penundaan tersebut), Anda dapat mulai memutar musik secara instan.

Batasan bagaimanapun meluas ke video, seperti yang saya katakan, ini adalah perpustakaan audio sehingga manipulasi video apa pun masih harus dilakukan dengan AVPlayer. Namun menggunakan -seekToTime:toleranfeBefore:toleranceAfter:Anda harus dapat mencapai pencarian cepat dalam video selama Anda melakukan preroll dengan semua opsi yang diperlukan.

Jika Anda menyinkronkan di beberapa perangkat (yang mungkin disarankan oleh aplikasi Anda) tinggalkan komentar dan saya akan dengan senang hati mengedit jawaban saya.

PS: BASS mungkin terlihat menakutkan pada awalnya karena formatnya seperti C, tetapi sangat mudah digunakan untuk apa adanya.

keledai
sumber
-2

Berikut adalah beberapa properti dan metode yang disediakan oleh kelas AVAsset yang dapat membantu:

- (void)_pu_setCachedDuration:(id)arg1;
- (id)pu_cachedDuration; 
- (struct
 { 
   long long x1; 
   int x2;
   unsigned int x3; 
   long long x4; 
})pu_duration;
- (void)pu_loadDurationWithCompletionHandler:(id /* block */)arg1;
James Bush
sumber