3

Я пытаюсь использовать FFmpeg для создания списка воспроизведения HLS, который содержит несколько звуковых воспроизведений, но я не могу синхронизировать аудио и видео дорожки. Вот сценарий:

  • Предположим, у меня есть 2 видео файла, каждый с 1 звуковой дорожкой
  • Я использую FFmpeg, чтобы объединить 2 видео в одно видео, например:

  • Извлеченная звуковая дорожка для каждого файла (транскодируется как .mp3)

  • Я хочу создать список воспроизведения HLS, где альтернативные звуковые дорожки - соответственно левый и правый аудио:

Проблема в том, что я не могу правильно синхронизировать звук с видео. Я попробовал пару команд ffmpeg, каждая наивная на своем уровне, и в лучшем случае я получаю синхронизированный поток на рабочем столе, но на мобильном телефоне (где воспроизведение обрабатывается собственным проигрывателем устройства), видео теряет синхронизацию со звуком очень быстро, как только я переключаюсь на другую видео дорожку.

Я использую ffmpeg 3.1.1.

Пример команды, которую я попробовал, начиная с относительно простой, где я отображаю звуковые дорожки на мультиплексор segmenter , а видео - на hls:

ffmpeg -i dual.mp4 -i audio_left.mp3 -i audio_right.mp3 \
-threads 0 -muxdelay 0 -y \
-map 0 -pix_fmt yuv420p -vsync 1 -async 1 -vcodec libx264 -r 29.97 -g 60 -refs 3 -f hls -hls_time 10 -hls_list_size 0 video/index.m3u8 \
-map 1 -acodec aac -strict experimental -async 1 -ar 44100 -ab 96k -f segment -segment_time 10 -segment_list_size 0 -segment_list_flags -cache -segment_format aac -segment_list audio1/audio1.m3u8 audio1/audio1%d.aac \
-map 2 -acodec aac -strict experimental -async 1 -ar 44100 -ab 96k -f segment -segment_time 10 -segment_list_size 0 -segment_list_flags -cache -segment_format aac -segment_list audio2/audio2.m3u8 audio2/audio2%d.aac 

Чтобы сложнее, например, вывести необработанный контейнер mpegts , а затем нарезать дорожки вверх:

ffmpeg -i dual_short.mp4 -i audio_left_short.mp3 -i audio_right_short.mp3 \
-threads 0 -muxdelay 0 -y \
-map 0:v -map 1 -map 2 -codec copy -pix_fmt yuv420p -vsync 1 -async 1 -shortest -f mpegts pipe:1 | ffmpeg-3.1.1 -i pipe:0 \
-map 0:0 -vcodec copy -r 29.97 -g 60 -refs 3 -bsf:v h264_mp4toannexb -f hls -hls_time 10 -hls_list_size 0 video/index.m3u8 \
-map 0:1 -f ssegment -segment_time 10 -segment_list_size 0 -segment_format aac -segment_list audio1/audio1.m3u8 audio1/audio1_%d.aac \
-map 0:2 -f ssegment -segment_time 10 -segment_list_size 0 -segment_format aac -segment_list audio2/audio2.m3u8 audio2/audio2_%d.aac

Я не эксперт по аудио / видео, поэтому я почти уверен, что в моих рассуждениях есть что-то принципиальное, поэтому я прошу вас, ребята, о помощи и руководстве. Особенно:

  • То, что я пытаюсь сделать здесь, неосуществимо? Еще один способ выразить это дано N звуковых дорожек, записанных синхронно с исходным видео, для создания списка воспроизведения HLS с аудио всегда синхронизированным по губам?
  • Является ли битрейт видео FPS & Audio причиной проблемы аудио / видео синхронизации? Есть ли даже корреляция?
  • Влияет ли разный уровень качества видео (например, битрейт) на синхронизацию?
  • Повлияет ли выбранный аудиоконтейнер (mp3 vs aac) на синхронизацию?
  • Должен ли я использовать одну команду с несколькими входами или работать с каждым потоком отдельно?

Как вы видите, я совсем растерялся. Я много занимался поиском в Интернете, смотрел выступление Apple "Эффективный HLS" на WWDC 2012, но информация о том, как создавать эффективные списки воспроизведения Multiple Audio Rendition, в Интернете, похоже, скудна.

Спасибо за любые указатели.

1 ответ1

4

Я нашел решение сам.

Проблема заключается в том, что мультиплексору segment необходимо просматривать некоторые опорные кадры, чтобы иметь возможность правильно нарезать аудио, поэтому отображение потоков по отдельности не будет работать.

Что будет работать, так это создать сегмент "beefy" .ts, который включает все аудио и видео файлы, а затем нарезать их соответствующим образом. Простой, но работающий пример:

ffmpeg-3.1.1 -i dual_short.mp4 -i audio_left_short.mp3 -i audio_right_short.mp3 \
    -threads 0 -muxdelay 0 -y \
    -map 0:v -map 1 -map 2 -pix_fmt yuv420p -movflags +faststart -r 29.97 -g 60 -refs 1 \
    -vcodec libx264 -acodec aac -profile:v baseline -level 30 -ar 44100 -ab 64k -f mpegts out.ts

# Perform 3 passes:
# 1. Generate the video.
ffmpeg-3.1.1 -i out.ts -threads 0 -muxdelay 0 -y -map 0:v   -vcodec copy  -f hls -hls_time 10 -hls_list_size 0 video/index.m3u8
# Generate Audio 1
ffmpeg-3.1.1 -i out.ts -threads 0 -muxdelay 0 -y -map 0:a:0 -codec copy -f segment -segment_time 10 -segment_list_size 0 -segment_list audio1/audio1.m3u8 -segment_format mpegts audio1/audio1_%d.aac
# Generate Audio 1
ffmpeg-3.1.1 -i out.ts -threads 0 -muxdelay 0 -y -map 0:a:1 -codec copy -f segment -segment_time 10 -segment_list_size 0 -segment_list audio2/audio2.m3u8 -segment_format mpegts audio2/audio2_%d.aac

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .