Кодирование FFMPEG в MPEG-DASH - или WebM с кластерами ключевого кадра - для API MediaSource
Сейчас я отправляю видеоролик в Chrome, чтобы играть через API MediaSource.
Как я понимаю, MediaSource поддерживает только файлы MP4, закодированные с помощью MPEG-DASH, или файлы WebM, у которых есть кластеры, начинающиеся с ключевых кадров (в противном случае возникает ошибка: сегмент мультимедиа не начинался с ключевого кадра).
Есть ли способ кодирования в форматах MPEG-DASH или keyframed WebM с FFMPEG в режиме реального времени?
Edit:
Я просто попробовал его с ffmpeg ... -f webm -vcodec vp8 -g 1
, чтобы каждый фрейм был ключевым фреймом. Не идеальное решение. Однако он работает с MediaStream. Любой способ синхронизировать сегменты с ключевыми кадрами в WebM, поэтому не каждый кадр должен быть ключевым кадром?
Справочные вопросы по WebM/MP4 и MediaSource:
Источник мультимедиа Api не работает для настраиваемого веб файла (версия для Chrome 23.0.1271.97 м)
API MediaSource и mp4
Ответы
Ответ 1
В настоящий момент FFMPEG не поддерживает кодирование DASH. Вы можете сегментировать с FFMPEG (https://www.ffmpeg.org/ffmpeg-formats.html#segment_002c-stream_005fsegment_002c-ssegment), но я рекомендую комбинировать FFMPEG и MP4Box. Используйте FFMPEG для перекодирования вашего видео в реальном времени, а затем MP4Box для сегментации и создания индекса .mpd.
MP4Box входит в состав GPAC (http://gpac.wp.mines-telecom.fr/).
Вот пример использования h264:
ffmpeg -threads 4 -f v4l2 -i /dev/video0 -acodec libfaac -ar 44100 -ab 128k -ac 2 -vcodec libx264 -r 30 -s 1280x720 -f mp4 -y "$movie" > temp1.mp4 && MP4Box -dash 10000 -frag 1000 -rap "$movie"
Если вам нужен VP8 (WebM), используйте: -vcodec libvpx
и -f webm
или -f ts
.
Ответ 2
Чтобы добиться сверхнизкой задержки и избежать необходимости сегментировать видео, вы можете продолжить использование WebM с помощью
ffmpeg ... -f webm -vcodec vp8 -g 1 ...
Это гарантирует, что каждый кадр является ключевым кадром (путем установки группы изображений в 1).
Edit:
Другим пользователям повезло:
ffmpeg ... \
-f mp4 \
-reset_timestamps 1 \
-movflags empty_moov+default_base_moof+frag_keyframe \
-probesize 200000
Пожалуйста, смотрите вопросы о габбарме:
Примечание. Если у вас нет ключевых кадров на входном видео, вам может потребоваться установить:
-frag_duration 100000
... вместо +frag_keyframe
.
Ответ 3
Я столкнулся с той же ситуацией при попытке воспроизвести записанный файл .webm с помощью MediaRecorder API, используя Расширения источника мультимедиа (MSE). Записи Chrome (51) неверны, Firefox (46) выглядит нормально.
Чтобы заставить его работать, вы должны исправить реплики в файле .webm:
Надеюсь, это помогло кому-то. Было сложно загружать любую информацию без ключевого слова DASH (я не использую DASH, только ту же базовую технологию - MSE):)
Ответ 4
Чтобы каждый кластер в вашем WebM начинался с ключевого кадра, попробуйте что-то вроде этого:
ffmpeg \
[...inputs] \
-vcodec libvpx \
-keyint_min 60 \
-g 60 \
-vb 4000k \
-f webm \
-cluster_size_limit 10M \
-cluster_time_limit 2100 \
[...output]
В принципе, как реализовано, каждый ключевой кадр должен находиться в начале кластера, но обратный не соответствует действительности. То есть, на ключевом фрейме будет новый кластер, но в новом кластере не обязательно будет ключевой кадр. Чтобы обойти эту проблему, мы просто устанавливаем размер кластера на нечто большее, чего мы никогда не ударим.
В этом примере у нас будет ключевой кадр каждые 2 секунды, а ограничение времени кластера - 2,1 секунды, поэтому мы никогда его не ударим. Битрейт составляет 4 Мбит, а ограничение размера кластера - 10 М. Не уверен, что это бит или байт, но это не имеет значения, поскольку мы никогда не ударим его, поскольку я установил его намного больше, чем это должно быть.