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