Nota: per la domanda seguente: Tutte le risorse sono locali sul dispositivo, non è in corso lo streaming di rete. I video contengono tracce audio.Come ridurre il ritardo di avvio di AVPlayer per iOS
Sto lavorando a un'applicazione iOS che richiede la riproduzione di file video con un ritardo minimo per avviare il video clip in questione. Sfortunatamente non sappiamo quale clip video specifico è il prossimo finché non avremo effettivamente bisogno di avviarlo. Nello specifico: quando viene riprodotto un video, sapremo quale sarà il prossimo set di (circa) 10 video clip, ma non sappiamo quale sia esattamente, fino a quando non verrà il momento di riprodurre "immediatamente" la clip successiva.
Quello che ho fatto per vedere i ritardi di avvio effettivi è chiamare addBoundaryTimeObserverForTimes
sul lettore video, con un periodo di tempo di un millisecondo per vedere quando il video ha effettivamente iniziato a suonare, e prendo la differenza di quel timestamp con il primo posto nel codice che indica quale risorsa iniziare a giocare.
Da quello che ho visto così-lontano, ho trovato che utilizzando la combinazione di AVAsset
carico, e quindi la creazione di un AVPlayerItem
da quella volta che è pronto, e quindi in attesa di AVPlayerStatusReadyToPlay
prima di chiamare il gioco, tende a prendere tra le 1 e 3 secondi per avviare la clip.
Da allora sono passato a quello che penso sia grosso modo equivalente: chiamando [AVPlayerItem playerItemWithURL:]
e aspettando il AVPlayerItemStatusReadyToPlay
per giocare. Circa le stesse prestazioni.
Una cosa che sto osservando è che il primo caricamento di AVPlayer è più lento del resto. Sembra che l'idea di pre-flight di AVPlayer con un asset breve/vuoto prima di provare a riprodurre il primo video potrebbe essere una buona pratica generale. [Slow start for AVAudioPlayer the first time a sound is played
Mi piacerebbe avere il tempo di avvio del video il più possibile, e avere alcune idee su cose da sperimentare, ma vorrei qualche consiglio da parte di chiunque fosse in grado di aiutare.
Aggiornamento: idea 7, di seguito, i tempi di commutazione dei rendimenti implementati di circa 500 ms. Questo è un miglioramento, ma sarebbe bello farlo ancora più velocemente.
Idea 1: Utilizzare N AVPlayers (non funziona)
Utilizzando ~ 10 AVPPlayer
oggetti e start-e-sospendere tutti ~ 10 clip, e una volta che sappiamo quale abbiamo veramente bisogno, interruttore per, e interrompere la corretta AVPlayer
, e ricominciare tutto da capo per il ciclo successivo.
Non penso che funzioni, perché ho letto che c'è approssimativamente un limite di 4 AVPlayer's
attivo in iOS. C'era qualcuno che chiedeva su questo su StackOverflow qui, e ha scoperto circa il limite 4 AVPlayer: fast-switching-between-videos-using-avfoundation
Idea 2: Utilizzare AVQueuePlayer (non funziona)
Non credo che spingendo 10 AVPlayerItems
in un AVQueuePlayer
li precaricherà tutti per un avvio senza interruzioni. AVQueuePlayer
è una coda, e penso che in realtà rende solo il prossimo video in coda pronto per la riproduzione immediata. Non so quale dei 10 video che vogliamo riprodurre, finché non è il momento di avviarlo.ios-avplayer-video-preloading
Idea 3: carico, gioco, e mantenere AVPlayerItems
in background (non al 100% ancora sicuro - ma non guardando bene)
sto guardando se c'è qualche beneficio per caricare e giocare il primo secondo di ogni clip video in background (sopprimere il video e l'uscita audio), e mantenere un riferimento a ogni AVPlayerItem
, e quando sappiamo quale elemento deve essere riprodotto per davvero, scambiare quello in, e scambiare lo sfondo AVPlayer con quello attivo. Risciacqua e ripeti.
La teoria sarebbe che i dischi suonati di recente AVPlayer/AVPlayerItem
possano ancora contenere risorse preparate che renderebbero più veloce la riproduzione successiva. Finora, non ho visto benefici da questo, ma potrei non avere l'installazione AVPlayerLayer
correttamente per lo sfondo. Dubito che questo migliorerà davvero le cose da quello che ho visto.
Idea 4: utilizzare un formato file diverso, forse uno più veloce da caricare?
Attualmente sto usando il formato H.264 di .m4v (video-MPEG4). H.264 ha molte diverse opzioni di codec, quindi è possibile che alcune opzioni siano più veloci da cercare rispetto ad altre. Ho scoperto che l'utilizzo di impostazioni più avanzate che riducono le dimensioni del file aumentano il tempo di ricerca, ma non hanno trovato alcuna opzione che vada diversamente.
Idea 5: Combinazione di formato video senza perdita di dati + AVQueuePlayer
Se v'è un formato video che è veloce da caricare, ma forse in cui la dimensione del file è folle, un'idea potrebbe essere quella di pre-preparare il i primi 10 secondi di ciascun video clip con una versione che è gonfia ma più veloce da caricare, ma a cui si aggiunge un asset codificato in H.264. Usa un AVQueuePlayer e aggiungi i primi 10 secondi nel formato di file non compresso, quindi segui uno di quelli in H.264 che richiede fino a 10 secondi di tempo di preparazione/preload. Quindi otterrei il "meglio" di entrambi i mondi: tempi di avvio rapidi, ma anche i vantaggi di un formato più compatto.
Idea 6: Utilizzare una non-standard AVPlayer/scrivere il mio/usare qualcun altro
Data la mia necessità, forse non posso usare AVPlayer, ma necessario ricorrere a AVAssetReader, e decodificare il primo pochi secondi (possibilmente scrivere file raw su disco) e, quando si tratta di riproduzione, utilizzare il formato raw per riprodurlo velocemente. Sembra un grande progetto per me, e se lo faccio in modo ingenuo, non è chiaro/improbabile che funzioni meglio. Ogni frame video decodificato e non compresso è 2,25 MB. In parole povere - se andiamo con ~ 30 fps per il video, finirei con un requisito di lettura da disco di ~ 60 MB/s, che è probabilmente impossibile/spingendolo. Ovviamente dovremmo fare un po 'di compressione delle immagini (magari i formati di compressione openGL/es nativi tramite PVRTC) ... ma è un po' strano. Forse c'è una biblioteca là fuori che posso usare?
Idea 7: unire il tutto in un singolo asset di film, e seekToTime
Un'idea che potrebbe essere più facile di quanto alcuni di quanto sopra, è quello di unire il tutto in un unico filmato, e utilizzare seekToTime. Il fatto è che salteremmo dappertutto. Accesso essenzialmente casuale al film. Penso che questo possa effettivamente funzionare a dovere: avplayer-movie-playing-lag-in-ios5
Quale approccio pensi sarebbe meglio? Finora, non ho fatto molti progressi in termini di riduzione del ritardo.
Per quello che vale, vado con Idea 7. È ancora lento, ma non così imprevedibilmente lento come le altre opzioni. La prossima domanda che ho è: le opzioni di codec, la risoluzione e la frequenza dei fotogrammi chiave hanno un impatto sulla ricerca del tempo? –
In ritardo, ma potrebbe valere la pena di cambiare video il più velocemente possibile (ad esempio immediatamente dopo che il nuovo inizia a suonare) e profilare l'app per vedere dove trascorre la maggior parte del tempo della CPU. –
Quasi un anno dopo, cosa hai mai scoperto con questo? – lnafziger