İOS AVPlayer başlangıç ​​gecikmesi nasıl azaltılır


115

Aşağıdaki soru için not edin: Cihazdaki tüm varlıklar yereldir - ağ akışı gerçekleşmez. Videolar ses parçaları içeriyor.

Söz konusu video klibi başlatmak için video dosyalarını minimum gecikmeyle oynatmayı gerektiren bir iOS uygulaması üzerinde çalışıyorum. Maalesef, gerçekten başlatmamız gerekene kadar bir sonraki video klibin ne olduğunu bilmiyoruz. Spesifik olarak: Bir video klip oynatılırken, bir sonraki (kabaca) 10 video klip setinin ne olduğunu bileceğiz, ancak bir sonraki klibi 'hemen' oynatma zamanı gelene kadar tam olarak hangisinin olduğunu bilmiyoruz.

Gerçek başlatma gecikmelerine bakmak için yaptığım şey addBoundaryTimeObserverForTimes, videonun gerçekte ne zaman oynatılmaya başladığını görmek için bir milisaniyelik bir süre ile video oynatıcıyı aramak ve ilk sırada bu zaman damgasının farkını alıyorum hangi varlığın oynatılmaya başlanacağını gösteren kod.

Şimdiye kadar gördüğüm kadarıyla, AVAssetyükleme kombinasyonunu kullanmanın ve AVPlayerItemhazır olduğunda ondan bir tane oluşturmanın ve ardından AVPlayerStatusReadyToPlayoynamayı çağırmadan önce beklemenin , başlatmanın 1 ile 3 saniye arasında sürdüğünü buldum. klips.

O zamandan beri kabaca eşdeğer olduğunu düşündüğüm şeye geçtim: aramak [AVPlayerItem playerItemWithURL:]ve AVPlayerItemStatusReadyToPlayoynamak için beklemek . Kabaca aynı performans.

Gözlemlediğim bir şey, ilk AVPlayer öğe yüklemesinin diğerlerinden daha yavaş olmasıdır. İlk videoyu oynatmaya çalışmadan önce AVPlayer'ı kısa / boş bir varlık ile önceden uçurmak iyi bir genel uygulama olabilir gibi görünüyor. [ AVAudioPlayer için ilk ses çalındığında yavaş başlatma

Videonun başlama zamanlarını olabildiğince kısaltmayı ve denemek için bazı fikirlere sahip olmayı çok isterim, ancak yardımcı olabilecek herkesten biraz rehberlik almak isterim.

Güncelleme: aşağıdaki fikir 7, uygulandığı gibi yaklaşık 500 ms anahtarlama süreleri sağlar. Bu bir gelişme, ama bunu daha hızlı yapmak güzel olurdu.

Fikir 1: N AVPlayer kullanın (işe yaramaz)

~ 10 AVPPlayernesne kullanarak ve ~ 10 klibin tümünü başlatıp duraklatın ve hangisine gerçekten ihtiyacımız olduğunu öğrendikten sonra, doğru olana geçiş yapın, duraklatmayı kaldırın AVPlayerve bir sonraki döngü için baştan başlayın.

Bunun işe yaradığını düşünmüyorum, çünkü AVPlayer'siOS'ta kabaca 4 aktif sınırı olduğunu okudum . Burada StackOverflow'da bunu soran biri vardı ve 4 AVPlayer sınırını öğrendi: videolar arasında hızlı geçiş avfoundation kullanarak

Fikir 2: AVQueuePlayer'ı kullanın (çalışmaz)

Benim 10 shoving inanmıyorum AVPlayerItemsbir içine AVQueuePlayersorunsuz başlaması için hepsini önceden yükleyerek olacaktır. AVQueuePlayerbir kuyruk ve bence bu gerçekten yalnızca sıradaki bir sonraki videoyu anında oynatmaya hazır hale getiriyor. Başlama zamanı gelene kadar ~ 10 videodan hangisini oynatmak istediğimizi bilmiyorum. ios-avplayer-video-ön yükleme

Fikir 3: AVPlayerItemsArka planda yükleyin, oynatın ve saklayın (henüz% 100 emin değil - ama iyi görünmüyor)

Arka planda her video klibin ilk saniyesini yüklemek ve oynatmak (video ve ses çıkışını bastırmak) ve her birine bir referans tutmak AVPlayerItemve hangi öğenin oynatılması gerektiğini bildiğimizde herhangi bir fayda olup olmadığına bakıyorum. gerçek, onu içinde değiştirin ve arka plan AVPlayer'ı aktif olanla değiştirin. Durulayın ve Tekrarlayın.

Teori, yakın zamanda oynatılanların AVPlayer/AVPlayerItem, daha sonra oynatmayı daha hızlı hale getirecek bazı hazırlanmış kaynakları hala tutabileceğidir. Şimdiye kadar, bundan fayda görmedim, ancak AVPlayerLayerarka plan için doğru kurulum yapmamış olabilirim . Bunun gerçekten gördüklerimi iyileştireceğinden şüpheliyim.

Fikir 4: Farklı bir dosya biçimi kullanın - belki daha hızlı yüklenen bir biçim?

Şu anda .m4v'nin (video-MPEG4) H.264 biçimini kullanıyorum. H.264'ün birçok farklı codec seçeneği vardır, bu nedenle bazı seçeneklerin diğerlerinden daha hızlı aranması mümkündür. Dosya boyutunu küçülten daha gelişmiş ayarlar kullanmanın arama süresini artırdığını buldum, ancak tersine giden herhangi bir seçenek bulamadım.

Fikir 5: Kayıpsız video formatı + AVQueuePlayer kombinasyonu

Yüklemesi hızlı, ancak dosya boyutunun çılgın olduğu bir video formatı varsa, bir fikir, her video klibin ilk 10 saniyesini şişirilmiş ancak yüklenmesi daha hızlı, ancak daha hızlı bir sürümle önceden hazırlamak olabilir. H.264'te kodlanmış bir varlık ile bu kadar. Bir AVQueuePlayer kullanın ve sıkıştırılmamış dosya biçiminde ilk 10 saniyeyi ekleyin ve bunu 10 saniyeye kadar hazırlık / önyükleme süresi sağlayan H.264'te olan bir saniye ile takip edin. Böylece her iki dünyanın da 'en iyisini' elde ederim: hızlı başlangıç ​​zamanları, ancak daha kompakt bir formattan da yararlanır.

Fikir 6: Standart olmayan bir AVPlayer kullanın / kendiminkini yazın / başkasınınkini kullanın

İhtiyaçlarım göz önüne alındığında, belki AVPlayer'ı kullanamıyorum, ancak AVAssetReader'a başvurmam ve ilk birkaç saniyenin kodunu çözmem gerekiyor (muhtemelen ham dosyayı diske yazıyorum) ve oynatma söz konusu olduğunda, oynatmak için ham formattan yararlanın hızlı geri dön. Bana çok büyük bir proje gibi görünüyor ve bunu saf bir şekilde yaparsam, belirsiz / daha iyi çalışması bile olası değil. Her kodu çözülmüş ve sıkıştırılmamış video çerçevesi 2,25 MB'dir. Naif bir şekilde konuşursak - video için ~ 30 fps ile gidersek, ~ 60 MB / s diskten okuma gereksinimi ile sonuçlanırdım, ki bu muhtemelen imkansız / zorlama. Açıkçası, bir miktar görüntü sıkıştırma (belki de PVRTC aracılığıyla yerel openGL / es sıkıştırma formatları) yapmamız gerekir ... ama bu biraz çılgınca. Belki orada kullanabileceğim bir kütüphane vardır?

Fikir 7: Her şeyi tek bir film varlığında birleştirin ve seekToTime

Yukarıdakilerin bazılarından daha kolay olabilecek bir fikir, her şeyi tek bir filmde birleştirmek ve seekToTime kullanmaktır. Mesele şu ki, her yerde zıplıyor olacağız. Esasen filme rastgele erişim. Bunun gerçekten işe yarayacağını düşünüyorum: avplayer-movie-playing-lag-in-ios5

Sizce en iyi yaklaşım hangisi? Şimdiye kadar gecikmeyi azaltma konusunda o kadar ilerleme kaydetmedim.


Değeri ne olursa olsun, Fikir 7 ile gidiyorum. Hala yavaş, ancak diğer seçenekler kadar tahmin edilemeyecek kadar yavaş değil. Bir sonraki sorum şu: kodek seçenekleri, çözünürlük ve anahtar kare frekansı, zamanlama arayışı üzerinde bir etkiye sahip mi?
Bernt Habermeier

Oyuna geç, ancak videoları olabildiğince hızlı değiştirmeye (yani yenisi oynamaya başladıktan hemen sonra) ve CPU zamanının çoğunu nerede harcadığını görmek için uygulamanın profilini çıkarmaya değer olabilir.
tc.

1
Bundan neredeyse bir yıl sonra, bununla ne öğrendiniz?
lnafziger

1
7. seçenekle gittim ve 300 ms ile 500 ms arasında bir yere gittim. Bulduğum bir şey, mp4 kodek seçeneklerinin meraklısı, seekTo'nun daha yavaş olmasıdır. Daha iyi sıkıştırma sağlayan ve video kalitesini koruyan, ancak kod çözme süresini ortadan kaldıran bazı video sıkıştırma seçenekleri vardır.
Bernt Habermeier

2
Bu mantıklı bir istek, ancak gerçekten 7. seçeneği uygulamak için, uygulamada gönderilecek çok fazla özellik var. Şunları göz önünde bulundurun: (a) Video varlıklarını birleştirmek için bir araç zinciri oluşturun, (b) video segment ofsetlerini takip ettiğinizden emin olun, (c) belirli bir klibi oynatmak için bir istek geldiğinde ofsetleri arayın, (d) kontrol etmek için addPeriodicTimeObserverForInterval kullanın Bir video klibi bitirdiyseniz ve buna göre tepki verdiyseniz (bu yöntemi tek seferlik bir addBoundaryTimeObserverForTimes yerine kullanın çünkü ikincisinin bazen tetiklemediğini fark ettim ... genel olarak, bu kod yapıştırmaya
yetmiyor

Yanıtlar:


4

İOS 10.x ve üstü için AVPlayer başlatma gecikmesini azaltmak için ayarladım: avplayer.automaticallyWaitsToMinimizeStalling = false; ve bu benim için düzeltmiş gibi görünüyordu. Bunun başka sonuçları olabilir, ama henüz bunlara ulaşmadım.

Bunun fikrini şu adresten aldım: https://stackoverflow.com/a/50598525/9620547


Gecikmede 6-7 saniyelik azalma var. Ancak burada bir sorum var, uygulama performansını etkileyecek mi?
kalpa

@kalpa Bu kodu bir yıldan fazla bir süredir herhangi bir olumsuz etki olmaksızın bir üretim uygulamasında kullandık. Mobil veri kapsamının genellikle hızlı olduğu ABD'deki dinleyicilere çoğunlukla 20-60 dakikalık ses dosyalarını çalıyoruz. Kullanım durumunuz farklı olabilir.
grizzb

Bilgi için teşekkürler. @grizzb
kalpa

1

Varlık bir kez oluşturduğunuzda hazır olmayabilir, film süresi gibi hesaplamalar yapabilir, dosyada filmin tüm meta verilerini içerdiğinizden emin olun.


1

İlk önce 7. seçeneği denemelisiniz, sadece işe yarayıp yaramayacağını görmek için. Arama süresi, klipler arasında kesintisiz geçiş sağlayacak kadar hızlı olmayacağından, aslında ihtiyaçlarınız için işe yaramayacağından şüpheleniyorum. Bunu denerseniz ve başarısız olursa, 4/6 seçeneğini uygulamanızı ve bu amaç için özel olarak tasarlanmış iOS kitaplığıma bir göz atmanızı tavsiye ederim, daha fazlasını öğrenmek için AVAnimator'da hızlı bir google araması yapın. Kitaplığım kesintisiz döngüler oluşturmayı ve bir klipten diğerine geçiş yapmayı mümkün kılıyor, çok hızlı çünkü videonun elden önce bir dosyaya kodunun çözülmesi gerekiyor. Sizin durumunuzda, başlamadan önce 10 video klibin tamamı dosyalara çözülür, ancak daha sonra aralarında geçiş hızlı olur.


Videonun ses kısmı ne olacak? Senkronize edilecek video ve sese ihtiyacım var.
Bernt Habermeier

Evet, ses zaten ses parçası ve video klip arasında çok sıkı bir senkronizasyonla işleniyor. Örnek xcode projelerine bakın. Zaten hepsi uygulandı, sadece indirip denemeniz gerekiyor.
MoDJ

AVAnimator kullanarak ağ videosu oynatma imkanı var mı?
Richard Topchii

Hayır, yerel dosyalarda çalışır, ağ videosu akışı tamamen farklı bir şeydir.
MoDJ

0

Geçmişte böyle bir şey yapmadan, düşüncelerinize ve deneyimlerinize dayanarak 7 ve 1 kombinasyonunu deneyebilirdim: Bir AVPlayer'ı 10 takip videosunun ilk birkaç saniyesiyle önceden yükleyin. Daha az veri nedeniyle atlama, büyük olasılıkla daha hızlı ve daha güvenilir olacaktır. Seçili parçayı çalarken, AVPlayer'ı arka planda seçilen takip videosunun geri kalanı için hazırlamak için yeterli zamanınız var. Başlangıç ​​bittiğinde, hazırlanmış AVPlayer'a geçersiniz. Yani toplamda, herhangi bir zamanda maksimum 2 AVPlayer yüklüdür.

Elbette, geçişin oynatmayı rahatsız etmeyecek kadar sorunsuz yapılıp yapılamayacağını bilmiyorum.

(Yapabilseydim bunu bir yorum olarak eklerdim.)

En iyisi, Peter


Tek bir AVPlayer'a seri olarak 10 varlık yüklemenin bir yararı bulamadım. Ayrıca, (1) ve (7) numaralı seçenekleri birbirini dışlayan olarak gördüğüm için önerinizi anlamıyorum. Seçenek 7, tüm video varlıklarını tek bir varlıkta birleştirir - bu nedenle, yüklenecek yalnızca tek bir varlık vardır. Bugün yaptığım şey bu ve buna değer olan gerçek başlatma / oynatma sürelerinde kabaca 500 ms gecikme alıyorum. SeekTo'nun gerçek ilk karenin oynatılmasından daha hızlı tamamlandığını belirtmek gerekir, bu nedenle gerçek başlangıç ​​zamanları için, ilk karenin aslında zamanlanmış geri arama yoluyla ne zaman oynatıldığını ölçüyorum.
Bernt Habermeier

Sadece fikrimi açıklığa kavuşturmak için: Benim fikrim bir varlığı iki kısma ayırmaktı: ilk birkaç saniye ve geri kalanı. Şimdi bir üzerinden iki varlık yaptınız. Katılıp atlayacağınız 10 başlangıç ​​ve başlangıcı oynarken gerisini yüklersiniz. Bu daha sonra listenize eklenen 8 numaralı öneriyi içerir.
ilmiacs

Ancak son yorumunuzdan da anladığım gibi, bu arada araştırmayı daha ileriye götürdünüz, bu iyi bir şey ve çözüm 7 de işe yaramıyor. Görünüşe göre AV temelde yolunuzda kalıyor ve gitmenizin tek yolu, varlıklarınız üzerinde daha fazla kontrole sahip olmak için altındaki teknolojiyi, yani Core Media'yı kullanmaktır. Peter.
ilmiacs

Oh, fikrini şimdi daha iyi anlıyorum. Teşekkürler. Kısa video klipler için hızlı arama süreleri alıp almadığınızı araştırmak ilginç olacaktır. Henüz denemedim ama dikkate değer. Çekirdek medyanın kullanımıyla ilgili olarak - bu API hakkında iyi bir referans materyali bulamadım. Beni yönlendirebileceğin iyi bir kaynağın var mı?
Bernt Habermeier

Hayır üzgünüm. Dediğim gibi, ne AV ne de Core Media konusunda uzman değilim. Sadece Sorunuzu okuyun ve kişisel olarak nasıl ilerleyeceğim konusunda bazı fikirlerim oldu ve bunları paylaşmak istedim. Peter
ilmiacs

0

Sorununuzu doğru anladıysam, bir an önce ses kaydını yüklemeniz gereken kesintisiz bir videonuz olduğu anlaşılıyor.

Eğer durum buysa, BASS'a bakmanızı öneririm . BASS, iOS'taki AudioUnits çerçevesinin düşük seviyeli API'lerine (nispeten) kolay erişim sağlayan AVPlayer'a çok benzeyen bir ses kitaplığıdır. Senin için anlamı ne? Bu, küçük bir tampon manipülasyonu ile (buna ihtiyacınız olmayabilir, gecikmeyi ne kadar küçük istediğinize bağlıdır) anında müzik çalmaya başlayabileceğiniz anlamına gelir.

Bununla birlikte, sınırlamalar video için de geçerlidir, dediğim gibi, bu bir ses kitaplığıdır, bu nedenle herhangi bir video manipülasyonunun yine de AVPlayer ile yapılması gerekecektir. Ancak -seekToTime:toleranfeBefore:toleranceAfter:, gerekli tüm seçeneklere önceden göz attığınız sürece, sizi kullanmak videoda hızlı aramayı başarabilmelisiniz.

Birden fazla cihaz arasında senkronizasyon yapıyorsanız (uygulamanızın önerebileceği) sadece bir yorum bırakın ve cevabımı düzenlemekten memnuniyet duyarım.

Not: BASS, C benzeri formatı nedeniyle ilk bakışta ürkütücü görünebilir, ancak olduğu gibi kullanmak gerçekten çok kolay.


-2

AVAsset sınıfı tarafından sağlanan ve yardımcı olabilecek birkaç özellik ve yöntem şunlardır:

- (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;
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.