Транскодирование fMP4 в HLS при записи на iOS с использованием FFmpeg

TL;DR

Я хочу преобразовать фрагменты fMP4 в сегменты TS (для HLS), поскольку фрагменты пишутся с использованием FFmpeg на устройстве iOS.

Зачем?

Я пытаюсь добиться прямой загрузки на iOS, сохраняя при этом плавную копию HD локально.

Что я пробовал

  1. Подвижной AVAssetWriters, где каждый пишет в течение 8 секунд, затем объединяет MP4 вместе через FFmpeg.

    Что пошло не так - иногда в аудио и видео появляются блики. Я определил 3 причины для этого.

    1) Заполняющие кадры для аудио, записанные кодером AAC, создающие промежутки.

    2) Поскольку видеокадры имеют длину 33,33 мс, а аудиокадры - 0,022 мс, они могут не располагаться в конце файла.

    3) Отсутствие кодировки с точностью до кадра присутствует в Mac OS, но недоступно для iOS. Подробности здесь

  2. FFmpeg - мультиплексирование большого MP4-файла только с видео с необработанным аудио в сегменты TS. Работа была основана на Kickflip SDK

    Что пошло не так - время от времени будет загружаться только аудиофайл, без какого-либо видео. Никогда не смог воспроизвести это собственными силами, но это очень расстроило наших пользователей, когда они не записали то, что, по их мнению, они сделали. Были также проблемы с точным поиском в последних сегментах, почти как сегменты TS были неправильно отмечены по времени.

О чем я сейчас думаю

В этом году (2016) Apple продвигала fMP4 на WWDC, и до этого я почти ничего не изучал. Поскольку файл fMP4 можно читать и воспроизводить во время его записи, я подумал, что FFmpeg сможет перекодировать файл так же, как он записывается, пока мы откладываем отправку байтов в FFmpeg до тех пор, пока каждый фрагмент внутри файл закончен.

Тем не менее, я недостаточно знаком с FFmpeg C API, я использовал его только кратко в попытке № 2.

Что мне нужно от тебя

  1. Это возможное решение? Кто-нибудь достаточно знаком с fMP4, чтобы знать, смогу ли я на самом деле это сделать?
  2. Как я узнаю, что AVFoundation закончил писать фрагмент в файле, чтобы я мог передать его в FFmpeg?
  3. Как я могу взять данные из файла на диске, порцию за раз, передать их в FFmpeg и заставить его выплевывать сегменты TS?

1 ответ

Строго говоря, вам не нужно перекодировать fmp4, если он содержит h264+aac, вам просто нужно переупаковать данные примера в TS. (с помощью ffmpeg -codec copy или gpac)

Wrt. Выравнивание (1.2) Полагаю, все зависит от настроек вашего кодера (частота кадров, частота дискретизации и размер GOP). Конечно, можно убедиться, что аудио и видео выровнены точно по границам фрагмента (см., Например: эту таблицу). Если вы ориентируетесь на iOS, я бы порекомендовал использовать протокол HLS версии 3 (или 4), чтобы обеспечить более точное представление времени. Это также позволяет вам передавать аудио и видео отдельно (без мультиплексирования).

Я считаю, что ffmpeg должен быть способен выдвигать живой поток fmp4 (т. Е. Использовать длительный HTTP POST), но для воспроизведения требуется исходное программное обеспечение, чтобы сделать что-то значимое с ним (т. Е. Поток в HLS).

Другие вопросы по тегам