FFMpeg и HLS, видео должны загрузиться полностью, прежде чем они начнут воспроизводиться.

Я использую ffmpeg для создания сегментированного списка файлов для их потоковой передачи в приложение iOS. Список файлов создается нормально, но когда приходит время их воспроизводить, видео необходимо загрузить полностью, прежде чем начнется воспроизведение. Похоже, такое поведение имеет место в iOS, Safari и VLC.

Кто-нибудь знает, почему это происходит и как я могу улучшить производительность воспроизведения? У меня есть полный контроль над тем, как файлы записываются в iOS, а также над тем, как они обрабатываются. Вот пример потока:

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

Вот мои команды ffmpeg для создания сегментов из файла:

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
К сожалению, я не особенно знаком с FFMPEG, однако, вообще говоря, файл должен предварительно загружать определенные метаданные, чтобы быть потоковым файлом. Если эти данные не загружены вперед, то загрузка должна быть завершена до того, как файл можно будет воспроизвести. Иногда это называют «прогрессивной загрузкой». Я уверен, что кто-то еще может дать вам более точный ответ для FFMPEG, но, надеюсь, это направление может помочь вам в промежутке времени.

Ответы (2)

Итак, после долгих исследований выяснилось, что это желаемое поведение для компонента Apple AVPlayer. По сути, мой Интернет настолько медленный здесь, где я живу, компонент ждет, пока видео полностью загрузится, прежде чем начать воспроизведение. Лучший и рекомендуемый способ обойти это — создать альтернативные потоки для видео, прежде чем пытаться его воспроизвести. Вот документация по формату m3u8 и рекомендациям по потоковой передаче HLS:

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

Я последовал вышеизложенному и сгенерировал два дополнительных потока из оригинала: 200kbps, 400kbps, и теперь воспроизведение начинается почти сразу. Ваш пробег может варьироваться в зависимости от скорости вашего интернет-соединения.

В качестве альтернативы, если вам не нужно использовать что-то вроде HLS, вы можете использовать обычные файлы mp4. Убедитесь, что они -faststartвключены, если вы обрабатываете файл с помощью ffmpeg.

Обновление: чтобы упростить это для других разработчиков, я выпустил SDK, который может загружать файлы mov или mp4 в облачный сервис и преобразовывать файл в поток, совместимый с HLS. SDK можно установить через Cocoapods, и вы можете получить доступ к документации и фреймворку здесь:

https://github.com/Storie/StorieCloudSDK

Это -movflags +faststartдля мп4.

Самое простое решение - использовать -movflags +faststart в вашей команде при перекодировании видеофайла. Он переместит все метаданные в начало воспроизводимого файла. Надеюсь это поможет.