Tenga en cuenta que para la siguiente pregunta: Todos los activos son locales en el dispositivo; no se está realizando ninguna transmisión de red. Los videos contienen pistas de audio.
Estoy trabajando en una aplicación de iOS que requiere reproducir archivos de video con un retraso mínimo para iniciar el videoclip en cuestión. Desafortunadamente, no sabemos qué videoclip específico es el siguiente hasta que realmente necesitamos iniciarlo. Específicamente: cuando se reproduce un videoclip, sabremos cuál es el siguiente conjunto de (aproximadamente) 10 videoclips, pero no sabemos cuál es exactamente, hasta que llegue el momento de reproducir "inmediatamente" el siguiente clip.
Lo que he hecho para ver los retrasos de inicio reales es llamar addBoundaryTimeObserverForTimes
al reproductor de video, con un período de tiempo de un milisegundo para ver cuándo comenzó a reproducirse el video, y tomo la diferencia de esa marca de tiempo con el primer lugar en el código que indica qué activo comenzar a jugar.
Por lo que he visto hasta ahora, he descubierto que usar la combinación de AVAsset
cargar, y luego crear una a AVPlayerItem
partir de eso una vez que está lista, y luego esperar AVPlayerStatusReadyToPlay
antes de llamar a play, tiende a tomar entre 1 y 3 segundos para iniciar la acortar.
Desde entonces, cambié a lo que creo que es aproximadamente equivalente: llamar [AVPlayerItem playerItemWithURL:]
y esperar para AVPlayerItemStatusReadyToPlay
jugar. Aproximadamente el mismo rendimiento.
Una cosa que estoy observando es que la carga del primer elemento de AVPlayer es más lenta que el resto. Parece que una idea es realizar un vuelo previo del AVPlayer con un activo corto / vacío antes de intentar reproducir el primer video. Podría ser una buena práctica general. [ Inicio lento para AVAudioPlayer la primera vez que se reproduce un sonido
Me encantaría reducir los tiempos de inicio del video tanto como sea posible y tener algunas ideas de cosas con las que experimentar, pero me gustaría recibir orientación de cualquier persona que pueda ayudar.
Actualización: la idea 7, a continuación, según se implementa, produce tiempos de conmutación de alrededor de 500 ms. Esto es una mejora, pero sería bueno hacerlo aún más rápido.
Idea 1: use N AVPlayers (no funcionará)
Usando ~ 10 AVPPlayer
objetos e inicie y pause los ~ 10 clips, y una vez que sepamos cuál necesitamos realmente, cambiemos y cancelemos la pausa del correcto AVPlayer
, y comience de nuevo para el siguiente ciclo.
No creo que esto funcione, porque he leído que hay aproximadamente un límite de 4 activos AVPlayer's
en iOS. Alguien preguntó sobre esto en StackOverflow aquí y descubrió el límite de 4 AVPlayer: cambio rápido entre videos usando avfoundation
Idea 2: use AVQueuePlayer (no funcionará)
No creo que meter 10 AVPlayerItems
en un AVQueuePlayer
precargarlos todos para comenzar sin problemas. AVQueuePlayer
es una cola, y creo que en realidad solo hace que el siguiente video de la cola esté listo para su reproducción inmediata. No sé cuál de ~ 10 videos queremos reproducir, hasta que sea el momento de comenzar con ese. ios-avplayer-video-preloading
Idea 3: cargar, reproducir y retener AVPlayerItems
en segundo plano (todavía no estoy 100% seguro, pero no se ve bien)
Estoy viendo si hay algún beneficio para cargar y reproducir el primer segundo de cada clip de video en segundo plano (suprimir la salida de video y audio), y mantener una referencia a cada uno AVPlayerItem
, y cuando sepamos qué elemento debe reproducirse real, cámbielo y cambie el AVPlayer de fondo por el activo. Enjuague y repita.
La teoría sería que los reproducidos recientemente AVPlayer/AVPlayerItem
pueden contener algunos recursos preparados que harían más rápida la reproducción posterior. Hasta ahora, no he visto beneficios de esto, pero es posible que no tenga la AVPlayerLayer
configuración correcta para el fondo. Dudo que esto realmente mejore las cosas de lo que he visto.
Idea 4: utilice un formato de archivo diferente, ¿tal vez uno que sea más rápido de cargar?
Actualmente estoy usando el formato H.264 de .m4v (video-MPEG4). H.264 tiene muchas opciones de códec diferentes, por lo que es posible que algunas opciones sean más rápidas de buscar que otras. Descubrí que el uso de configuraciones más avanzadas que hacen que el tamaño del archivo sea más pequeño aumenta el tiempo de búsqueda, pero no he encontrado ninguna opción que vaya al revés.
Idea 5: combinación de formato de video sin pérdida + AVQueuePlayer
Si hay un formato de video que se carga rápidamente, pero tal vez donde el tamaño del archivo es una locura, una idea podría ser preparar previamente los primeros 10 segundos de cada clip de video con una versión que esté hinchada pero que se cargue más rápido, pero al revés eso con un activo que está codificado en H.264. Use un AVQueuePlayer y agregue los primeros 10 segundos en el formato de archivo sin comprimir, y continúe con uno que esté en H.264 que obtenga hasta 10 segundos de tiempo de preparación / precarga. Así que obtendría "lo mejor" de ambos mundos: tiempos de inicio rápidos, pero también se beneficia de un formato más compacto.
Idea 6: use un AVPlayer no estándar / escriba el mío / use el de otra persona
Dadas mis necesidades, tal vez no pueda usar AVPlayer, pero tengo que recurrir a AVAssetReader y decodificar los primeros segundos (posiblemente escribir un archivo sin procesar en el disco), y cuando se trata de reproducción, hacer uso del formato sin procesar para reproducirlo. volver rápido. Me parece un gran proyecto, y si lo hago de una manera ingenua, no está claro / es poco probable que funcione mejor. Cada cuadro de video decodificado y sin comprimir es de 2.25 MB. Hablando ingenuamente, si elegimos ~ 30 fps para el video, terminaría con un requisito de lectura desde el disco de ~ 60 MB / s, lo que probablemente sea imposible / presionarlo. Obviamente, tendríamos que hacer algún nivel de compresión de imagen (quizás formatos de compresión nativos openGL / es a través de PVRTC) ... pero eso es una locura. ¿Quizás hay una biblioteca que pueda usar?
Idea 7: combine todo en un solo recurso de película y busque a tiempo
Una idea que podría ser más fácil que algunas de las anteriores es combinar todo en una sola película y usar seekToTime. Lo que pasa es que estaríamos saltando por todos lados. Acceso esencialmente aleatorio a la película. Creo que esto puede funcionar bien: avplayer-movie-playing-lag-in-ios5
¿Qué enfoque crees que sería mejor? Hasta ahora, no he avanzado mucho en términos de reducir el retraso.