FFMpeg y HLS, los videos deben cargarse en su totalidad antes de comenzar a reproducirse

Estoy usando ffmpeg para generar una lista segmentada de archivos para transmitirlos a una aplicación de iOS. La lista de archivos se genera bien, pero cuando llega el momento de reproducirlos, el video debe descargarse en su totalidad antes de que comience la reproducción. Este comportamiento parece ser el caso en iOS, Safari y VLC.

¿Alguien sabe por qué sucede esto y cómo puedo mejorar el rendimiento de la reproducción? Tengo control total sobre cómo se graban los archivos en iOS, así como también cómo se procesan. Aquí hay una secuencia de muestra:

http://www.bytesizecreations.com/storie-test/hls.m3u8

Aquí están mis comandos ffmpeg para generar los segmentos del archivo:

ffmpeg -i joined.ts -flags -global_header -vcodec copy -acodec copy -map 0 -f segment -segment_time 2 -segment_list hls.m3u8 -segment_list_size 999999 -segment_format mpegts out%03d.ts
Here is the output of ffprobe on the file:

  libavutil      54.  7.100 / 54.  7.100
  libavcodec     56.  1.100 / 56.  1.100
  libavformat    56.  4.101 / 56.  4.101
  libavdevice    56.  0.100 / 56.  0.100
  libavfilter     5.  1.100 /  5.  1.100
  libavresample   2.  1.  0 /  2.  1.  0
  libswscale      3.  0.100 /  3.  0.100
  libswresample   1.  1.100 /  1.  1.100
  libpostproc    53.  0.100 / 53.  0.100
Input #0, mpegts, from 'joined.ts':
  Duration: 00:00:07.96, start: 1.441667, bitrate: 3899 kb/s
  Program 1 
    Metadata:
      service_name    : Service01
      service_provider: FFmpeg
    Stream #0:0[0x100]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p, 1280x720, 24 fps, 24 tbr, 90k tbn, 180k tbc
    Stream #0:1[0x101](und): Audio: aac ([15][0][0][0] / 0x000F), 44100 Hz, stereo, f
Lamentablemente, no estoy particularmente familiarizado con FFMPEG; sin embargo, en términos generales, un archivo debe cargar ciertos metadatos para ser un archivo que se pueda transmitir. Si estos datos no se cargan por adelantado, la descarga deberá finalizar antes de que el archivo se pueda reproducir. A veces se le llama cosas como "Descarga progresiva". Estoy seguro de que alguien más puede darle una respuesta más exacta para FFMPEG, pero espero que esa dirección pueda ayudarlo mientras tanto.

Respuestas (2)

Entonces, después de mucha investigación, resulta que este es el comportamiento deseado para el componente AVPlayer de Apple. Básicamente, mi Internet es tan lento aquí donde vivo, el componente espera hasta que el video se haya descargado por completo antes de comenzar a reproducirse. La mejor y más recomendada forma de evitar esto es generar secuencias alternativas para el video antes de intentar reproducirlo. Aquí hay documentación sobre el formato m3u8 y las pautas de transmisión de HLS:

https://developer.apple.com/library/ios/documentation/networkinginternet/conceptual/streamingmediaguide/Introduction/Introduction.html

Seguí lo anterior y generé dos flujos adicionales del original: 200 kbps, 400 kbps y la reproducción ahora comienza casi de inmediato. Su millaje puede variar dependiendo de la velocidad de su conexión a Internet.

Alternativamente, si no tiene que usar algo como HLS, puede usar archivos mp4 simples. Asegúrese de que estén -faststarthabilitados si está procesando el archivo con ffmpeg.

Actualización: para simplificar esto para otros desarrolladores, he lanzado un SDK que puede cargar sus archivos mov o mp4 en un servicio en la nube y convertir el archivo en una transmisión compatible con HLS. El SDK se puede instalar a través de Cocoapods y puede acceder a la documentación y al marco aquí:

https://github.com/Storie/StorieCloudSDK

es -movflags +faststartpara mp4

La solución más simple es usar -movflags +faststart en su comando mientras transcodifica el archivo de video. Moverá todos los metadatos al principio del archivo que se va a reproducir. Espero que esto ayude.