Транскодирование fMP4 в HLS при записи на iOS с использованием FFmpeg
TL; DR
Я хочу преобразовать фрагменты fMP4 в сегменты TS (для HLS), поскольку фрагменты записываются с использованием FFmpeg на устройстве iOS.
Почему?
Я пытаюсь добиться живой загрузки на iOS, сохраняя при этом бесшовную копию HD на локальном компьютере.
Что я пробовал
-
Подсказка AVAssetWriter
, где каждая запись выполняется в течение 8 секунд, затем объединяет MP4 вместе через FFmpeg.
Что пошло не так.. Время от времени появляются звуки и видео. Я определил 3 причины для этого.
1) Прикрепление кадров для аудио, записанных кодировщиком AAC, создающим промежутки.
2) Поскольку видеокадры имеют длину 33,33 мс, а звуковые кадры - 0,022 мс, возможно, что они не выстроены в конце файла.
3) Отсутствие точной кодировки кадра присутствует в Mac OS, но недоступно для iOS Подробности здесь
-
FFmpeg мультиплексирует большой видеофайл MP4 с необработанным звуком в сегменты TS. Работа была основана на Kickflip SDK
Что пошло не так.. Время от времени будет загружен только аудиофайл без видео. Никогда не смог воспроизвести его в доме, но это было очень неприятно для наших пользователей, когда они не записывали то, что, по их мнению, они делали. Были также проблемы с точным поиском конечных сегментов, почти так же, как сегменты TS были неправильно отмечены отметкой времени.
То, что я сейчас думаю
Apple в этом году подталкивала fMP4 на WWDC (2016 год), и до этого я не задумывался над этим. Поскольку файл fMP4 можно прочитать и воспроизвести во время его написания, я подумал, что FFmpeg может перекодировать файл так же, как он записывается, если мы не отправляем байты в FFmpeg, пока каждый фрагмент внутри файл завершен.
Однако, я недостаточно знаком с API FFmpeg C, я использовал его только в попытке # 2.
Что мне нужно от вас
- Это приемлемое решение? Является ли кто-нибудь достаточно знакомым с fMP4, чтобы знать, могу ли я на самом деле выполнить это?
- Как я узнаю, что
AVFoundation
закончил писать фрагмент внутри файла, чтобы я мог его перенести в FFmpeg?
- Как я могу взять данные из файла на диске, кусок за раз, передать его в FFmpeg и вытолкнуть сегменты TS?
Ответы
Ответ 1
Строго говоря, вам не нужно перекодировать fmp4, если он содержит h264 + aac, вам просто нужно переупаковать образцы данных в виде TS. (используя ffmpeg -codec copy
или gpac)
Wrt. alignment (1.2) Я полагаю, все это зависит от настроек вашего кодировщика (частота кадров, частота дискретизации и размер GOP). Конечно, можно убедиться, что аудио и видео выравниваются точно на границах фрагмента (см. например: эта таблица). Если вы ориентируетесь на iOS, я бы рекомендовал использовать протокол HLS версии 3 (или 4), позволяющий более точно отображать время. Это также позволяет передавать аудио и видео отдельно (не мультиплексировано).
Я считаю, что ffmpeg должен быть способен нажимать живой поток fmp4 (т.е. используя длительный HTTP POST), но для воспроизведения требуется исходное программное обеспечение сделать что-то значимое с ним (т.е. поток в HLS).