Woj*_*ech 3 audio video sync ffmpeg dv
几个月来我一直被这个问题困扰。我有 50 多盘 DV 磁带(来自和旧的 Sony 摄像机)要转换为更现代、更可用的格式(很可能是 H264)。我已经开始使用 DVGRAB 将文件拉到我的电脑(通过火线)。在那里我有两个选择:从 dv 磁带中提取 RAW 数据,生成一个多路复用文件,或者将其解复用并保存到 DVI 文件。
这就是问题开始的地方。将其保存为 DVI 文件会导致音频不同步。我认为这是 DVGRAB 的问题,所以我保存了 RAW 文件(正确同步)并想用 ffmpeg 处理它们。
事实证明,无论我如何解复用它,音频总是不同步。在您谈论采样频率之前 - 音频差异的长度绝对是随机的。一小时长的磁带最后可能会有 0.1 到 4 秒的音频延迟。
这是一个示例文件,我将其拆分为单独的音频和视频文件以检查差异。
# ffprobe -i ./video_conversion/13.dv
ffprobe version 2.8.4 Copyright (c) 2007-2015 the FFmpeg developers
built with gcc 5.3.0 (GCC)
configuration: --prefix=/usr --disable-debug --disable-static --disable-stripping --enable-avisynth --enable-avresample --enable-fontconfig --enable-gnutls --enable-gpl --enable-ladspa --enable-libass --enable-libbluray --enable-libdcadec --enable-libfreetype --enable-libfribidi --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libv4l2 --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-shared --enable-version3 --enable-x11grab
libavutil 54. 31.100 / 54. 31.100
libavcodec 56. 60.100 / 56. 60.100
libavformat 56. 40.101 / 56. 40.101
libavdevice 56. 4.100 / 56. 4.100
libavfilter 5. 40.101 / 5. 40.101
libavresample 2. 1. 0 / 2. 1. 0
libswscale 3. 1.101 / 3. 1.101
libswresample 1. 2.101 / 1. 2.101
libpostproc 53. 3.100 / 53. 3.100
[dv @ 0x864f2a0] Detected timecode is invalid
[dv @ 0x864f2a0] Estimating duration from bitrate, this may be inaccurate
Input #0, dv, from './video_conversion/13.dv':
Duration: 01:00:45.80, start: 0.000000, bitrate: 28800 kb/s
Stream #0:0: Video: dvvideo, yuv420p, 720x576 [SAR 16:15 DAR 4:3], 28800 kb/s, 25 fps, 25 tbr, 25 tbn, 25 tbc
Stream #0:1: Audio: pcm_s16le, 48000 Hz, stereo, s16, 1536 kb/s
# ffprobe -i ./video_conversion/tmp/13.mp4
ffprobe version 2.8.4 Copyright (c) 2007-2015 the FFmpeg developers
built with gcc 5.3.0 (GCC)
configuration: --prefix=/usr --disable-debug --disable-static --disable-stripping --enable-avisynth --enable-avresample --enable-fontconfig --enable-gnutls --enable-gpl --enable-ladspa --enable-libass --enable-libbluray --enable-libdcadec --enable-libfreetype --enable-libfribidi --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libv4l2 --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-shared --enable-version3 --enable-x11grab
libavutil 54. 31.100 / 54. 31.100
libavcodec 56. 60.100 / 56. 60.100
libavformat 56. 40.101 / 56. 40.101
libavdevice 56. 4.100 / 56. 4.100
libavfilter 5. 40.101 / 5. 40.101
libavresample 2. 1. 0 / 2. 1. 0
libswscale 3. 1.101 / 3. 1.101
libswresample 1. 2.101 / 1. 2.101
libpostproc 53. 3.100 / 53. 3.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from './video_conversion/tmp/13.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf56.40.101
Duration: 01:00:45.80, start: 0.000000, bitrate: 5685 kb/s
Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 720x576 [SAR 16:15 DAR 4:3], 5683 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc (default)
Metadata:
handler_name : VideoHandler
# ffprobe -i ./video_conversion/tmp/13.mp3
ffprobe version 2.8.4 Copyright (c) 2007-2015 the FFmpeg developers
built with gcc 5.3.0 (GCC)
configuration: --prefix=/usr --disable-debug --disable-static --disable-stripping --enable-avisynth --enable-avresample --enable-fontconfig --enable-gnutls --enable-gpl --enable-ladspa --enable-libass --enable-libbluray --enable-libdcadec --enable-libfreetype --enable-libfribidi --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libv4l2 --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-shared --enable-version3 --enable-x11grab
libavutil 54. 31.100 / 54. 31.100
libavcodec 56. 60.100 / 56. 60.100
libavformat 56. 40.101 / 56. 40.101
libavdevice 56. 4.100 / 56. 4.100
libavfilter 5. 40.101 / 5. 40.101
libavresample 2. 1. 0 / 2. 1. 0
libswscale 3. 1.101 / 3. 1.101
libswresample 1. 2.101 / 1. 2.101
libpostproc 53. 3.100 / 53. 3.100
[mp3 @ 0x954c2a0] Skipping 0 bytes of junk at 237.
Input #0, mp3, from './video_conversion/tmp/13.mp3':
Metadata:
encoder : Lavf56.40.101
Duration: 01:00:44.35, start: 0.023021, bitrate: 128 kb/s
Stream #0:0: Audio: mp3, 48000 Hz, stereo, s16p, 128 kb/s
Metadata:
encoder : Lavc56.60
Run Code Online (Sandbox Code Playgroud)
这个特殊的相差 1.448 秒。正如我所说,差异很大。
至于解决办法。我可以拉伸音频并将其与视频结合(我已经测试过),但我不能确定音频是否会在录音中间的某个地方同步。
我想我已经确定了这种行为的根源。每当我打开或关闭相机(至开始和停止录制)时,视频的启动速度都会比音频快一点。因此,磁带上的“片段”越多,这些差异加起来就越大。
我怎样才能解决这个问题?有没有办法用时间戳解复用音频和视频,以便转换后它们能正确加起来?或者无论如何要填补音频中的这些空白,以便两个流开始时的大小相同?
Gya*_*yan 11
以下是解决此问题的三种通配符尝试:
方法 1a使用系统时间作为时间戳
ffmpeg -use_wallclock_as_timestamps 1 -i input.dv \
-c:v libx264 -b:v 4000k -c:a aac -b:a 128k -fflags +genpts method1.ts
Run Code Online (Sandbox Code Playgroud)
方法 1b使用带有标记的重采样器在输入音频时间戳有间隙时注入静音
ffmpeg -i input.dv -c:v libx264 -b:v 4000k \
-af "aresample=async=1:first_pts=0" -c:a aac -b:a 128k -fflags +genpts method1.ts
Run Code Online (Sandbox Code Playgroud)
方法 2与虚拟音频合并
ffmpeg -i input.dv -f lavfi -i "aevalsrc=0:c=2:s=48000" \
-filter_complex "[0:a][1:a]amerge[a]" -map 0:v -map "[a]" -c:v libx264 -b:v 4000k -c:a aac -b:a 128k -ac 2 -shortest method2.ts
Run Code Online (Sandbox Code Playgroud)
方法三结合以上
ffmpeg -use_wallclock_as_timestamps 1 -i input.dv -f lavfi -use_wallclock_as_timestamps 1 -i "aevalsrc=0:c=2:s=48000" \
-filter_complex "[0:a][1:a]amerge[a]" -map 0:v -map "[a]" -c:v libx264 -b:v 4000k -c:a aac -b:a 128k -ac 2 -shortest method3.ts
Run Code Online (Sandbox Code Playgroud)
您可以通过插入-t N例如-t 2020 秒的测试,在短时间内测试它们中的每一个。
如果它们中的任何一个工作,我们就可以继续将输出包装为 MP4。
我终于解决了这个问题——虽然有点矫枉过正,但确实有效。
我意识到,如果我将 .dv 复制到任何其他容器,音频和视频显然不同步。然后我想将该文件从第 51 分钟开始剪切为 1 分钟片段(-ss 51:00 -t 60),它显然仍然不同步。
然而,当我在原始 .dv 上使用相同的剪辑(-ss 51:00 -t 60)时,它是同步的!所以我最终做的是编写一个脚本,每秒将 .dv 文件切成 1 秒的片段,并将其保存到单独的文件中(是的,每个 .dv 超过 3600 个文件)。无需编码,只需将副本流式传输到新容器 (avi)。然后我使用 -f concat 将这些小文件放入一个 avi 文件中,现在就同步了!任何间隙都听不见!剩下的就是将 H264 和 AAC 编码为 MP4。
我在我的家庭服务器上运行了这个脚本,花了几天时间处理 50 个 .dv 文件,但现在它已经完成了!
谢谢大家的帮助!我总体上了解了很多有关 ffmpeg 和 a/v 的知识。
| 归档时间: |
|
| 查看次数: |
28910 次 |
| 最近记录: |