1

У меня есть видео файл .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 ответ1

1

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

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

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


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

ffmpeg -r 29 -i <input> …

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