Аудиовизуальный контент теряет синхронизацию

276
Darkmoor

У меня есть .mp4видеофайл, полученный с несжатого видео, .aviснятого с веб-камеры emgu. Emgu videoWriterустановлен 30fpsдаже на реальное видео fps, возможно, ниже, например 29fps. Команда, которая используется для сжатия .avi:

Команда сжатия:

fmpeg -i uncompresedvideo.avi -v quiet -stats -nostdin -c:v libx264 -crf 1 -preset veryfast -maxrate 500k -bufsize 1835k vid.mp4 

Выход сжатия видео:

ffmpeg version N-82060-g0cfd6cc Copyright (c) 2000-2016 the FFmpeg developers built with gcc 5.4.0 (GCC) configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-dxva2 --enable-libmfx --enable-nvenc --enable-avisynth --enable-bzlib --enable-libebur128 --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libfreetype --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenh264 --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-libzimg --enable-lzma --enable-decklink --enable-zlib libavutil 55. 32.100 / 55. 32.100 libavcodec 57. 63.103 / 57. 63.103 libavformat 57. 52.100 / 57. 52.100 libavdevice 57. 0.102 / 57. 0.102 libavfilter 6. 64.100 / 6. 64.100 libswscale 4. 1.100 / 4. 1.100 libswresample 2. 2.100 / 2. 2.100 libpostproc 54. 0.100 / 54. 0.100 Input #0, avi, from 'C:\....\uncompresedvideo.avi': Metadata: encoder : Lavf56.36.100 Duration: 00:02:50.27, start: 0.000000, bitrate: 110597 kb/s Stream #0:0: Video: rawvideo (I420 / 0x30323449), yuv420p, 640x480, 110613 kb/s, 30 fps, 30 tbr, 30 tbn, 30 tbc [libx264 @ 0000000002636460] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 AVX2 LZCNT BMI2 [libx264 @ 0000000002636460] profile High, level 3.0 [libx264 @ 0000000002636460] 264 - core 148 r2721 72d53ab - H.264/MPEG-4 AVC codec - Copyleft 2003-2016 - http://www.videolan.org/x264.html - options: cabac=1 ref=1 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=2 psy=1 psy_rd=1.00:0.00 mixed_ref=0 me_range=16 chroma_me=1 trellis=0 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=0 threads=6 lookahead_threads=2 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=1 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=10 rc=crf mbtree=1 crf=1.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 vbv_maxrate=500 vbv_bufsize=1835 crf_max=0.0 nal_hrd=none filler=0 ip_ratio=1.40 aq=1:1.00 Output #0, mp4, to 'C:\....\vid.mp4': Metadata: encoder : Lavf57.52.100 Stream #0:0: Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv420p, 640x480, q=-1--1, 30 fps, 15360 tbn, 30 tbc Metadata: encoder : Lavc57.63.103 libx264 Side data: cpb: bitrate max/min/avg: 500000/0/0 buffer size: 1835000 vbv_delay: -1 Stream mapping: Stream #0:0 -> #0:0 (rawvideo (native) -> h264 (libx264))  

В дополнение к этой видеозаписи у меня есть .wavфайл, который пришел с другого устройства. Я пытаюсь синхронизировать их с содержимым с помощью следующей команды:

ffmpeg.exe -i vid.mp4 -r 30 -i audio.wav -ar 16000 -map 0:0 -map 1:0 -vcodec copy -acodec aac -shortest output.mp4 

Вывод команды синхронизации:

ffmpeg version N-82060-g0cfd6cc Copyright (c) 2000-2016 the FFmpeg developers built with gcc 5.4.0 (GCC) configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-dxva2 --enable-libmfx --enable-nvenc --enable-avisynth --enable-bzlib --enable-libebur128 --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libfreetype --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenh264 --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-libzimg --enable-lzma --enable-decklink --enable-zlib libavutil 55. 32.100 / 55. 32.100 libavcodec 57. 63.103 / 57. 63.103 libavformat 57. 52.100 / 57. 52.100 libavdevice 57. 0.102 / 57. 0.102 libavfilter 6. 64.100 / 6. 64.100 libswscale 4. 1.100 / 4. 1.100 libswresample 2. 2.100 / 2. 2.100 libpostproc 54. 0.100 / 54. 0.100 Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'audio.mp4': Metadata: major_brand : isom minor_version : 512 compatible_brands: isomiso2avc1mp41 encoder : Lavf57.52.100 Duration: 00:02:50.27, start: 0.000000, bitrate: 507 kb/s Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 640x480, 504 kb/s, 30 fps, 30 tbr, 15360 tbn, 60 tbc (default) Metadata: handler_name : VideoHandler Guessed Channel Layout for Input Stream #1.0 : mono Input #1, wav, from 'audio.wav': Duration: 00:02:52.29, bitrate: 512 kb/s Stream #1:0: Audio: pcm_f32le ([3][0][0][0] / 0x0003), 16000 Hz, mono, flt, 512 kb/s Output #0, mp4, to 'output.mp4': Metadata: major_brand : isom minor_version : 512 compatible_brands: isomiso2avc1mp41 encoder : Lavf57.52.100 Stream #0:0(und): Video: h264 (High) ([33][0][0][0] / 0x0021), yuv420p, 640x480, q=2-31, 504 kb/s, 30 fps, 30 tbr, 15360 tbn, 15360 tbc (default) Metadata: handler_name : VideoHandler Stream #0:1: Audio: aac (LC) ([64][0][0][0] / 0x0040), 16000 Hz, mono, fltp, 69 kb/s Metadata: encoder : Lavc57.63.103 aac Stream mapping: Stream #0:0 -> #0:0 (copy) Stream #1:0 -> #0:1 (pcm_f32le (native) -> aac (native)) Press [q] to stop, [?] for help frame= 5108 fps=1316 q=-1.0 Lsize= 11735kB time=00:02:52.28 bitrate= 558.0kbits/s speed=44.4x video:10486kB audio:1151kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.836344% [aac @ 00000000026977c0] Qavg: 65093.531 

Я хотел бы отметить, что и аудио, и видео имеют общее начало. В то время как аудиовизуальный контент имеет хорошую синхронизацию в начале, синхронизация теряется в конце записи. Не могли бы вы сделать предложение о том, что происходит?

Ваша помощь высоко ценится, спасибо.

1
@slhck да, я сделал рефакторинг и предоставил более подробную информацию о текущей ситуации. Таким образом, я подумал, что было бы лучше начать это с попрошайничества, предлагая другую точку зрения, и это поможет другим понять больше. Я надеюсь, что это не большая проблема. Darkmoor 7 лет назад 0
@slhck Я думаю, у меня есть причина моей проблемы. Сжатое видео не имеет постоянного `fps` на протяжении всей записи. Могу ли я спросить, возможно ли преобразовать видео с непостоянным fps в постоянное с помощью `ffmpeg`? Darkmoor 7 лет назад 0
Использование параметра `-r` в команде сжатия с` fps` ниже, чем у фактического, обеспечит ли видео с постоянной частотой кадров `.mp4` видео? Darkmoor 7 лет назад 0
Я не уверен, недавно не сталкивался с видео с переменной частотой кадров. У вас есть образец? Вы пробовали опцию `force-crf`? slhck 7 лет назад 0
@slhck извините за задержку. Я проверил, чтобы сжать видео с опцией `force-crf`, но не сработало. Могу ли я спросить, есть ли возможная опция для аудио `.wav`, которая не всегда имеет постоянную частоту дискретизации? Darkmoor 7 лет назад 0
@slhck спасибо за ответ. Я хотел бы сделать последнюю попытку, поэтому, пожалуйста, позвольте мне спросить следующее. Как описано в вопросе, реальное `fps` потока отличается от сохраненного через` opencv`. Можно ли изменить `fps` во время сжатия или после? Также возможно ли это для файла `.wav`? Еще раз спасибо! Darkmoor 7 лет назад 0
Я написал более подробный ответ ниже. Опять же, просмотр некоторых примеров поможет в устранении неполадок, но, как я понимаю вашу проблему сейчас, кажется, что это невозможно исправить. slhck 7 лет назад 0

1 ответ на вопрос

1
slhck

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

Таким образом, читая этот файл AVI (или любой впоследствии сжатый файл MP4), ffmpeg будет предполагать, что это видео с постоянной частотой кадров. Это приводит к «нарастанию» асинхронности с течением времени, поскольку временные метки в AVI / MP4 имеют постоянные смещения. ffmpeg не может исправить это за вас, потому что введенные временные метки уже неверны. Другими словами, я предполагаю, что videoWriterвы ссылаетесь на создание видео с постоянной частотой кадров с переменной частотой кадров, что создает неправильные временные метки. Не зная, когда или как изменилась частота кадров, вы не сможете исправить временные метки.

Единственным вариантом будет повторное создание видеопотока с веб-камеры с контейнером, который поддерживает переменную частоту кадров (например, MKV или MP4 / MOV). Затем любое последующее преобразование может синхронизировать контент с аудиопотоком. Но так как этот веб-канал, вероятно, в прямом эфире, вернуться назад невозможно. Кроме того, я не думаю, что для OpenCV videoWriterвозможно также выводить переменную частоту кадров (но я не эксперт в этом).


Примечание. Эту проблему было бы легче устранить, если исходное видео было закодировано с неправильной постоянной частотой кадров. Затем можно заставить ffmpeg принять другую частоту кадров для входного видео, эффективно удаляя исходные временные метки и генерируя новые, предполагая постоянную частоту кадров. Например, если преобразование вашего видео привело к созданию видео со скоростью 30 кадров в секунду, но исходный вход составлял 29 кадров в секунду, сделайте следующее:

ffmpeg -r 29 -i <input> … 

Похожие вопросы