oct*_*cto 7 audio sync delay ffmpeg aac
最近我使用 ffmpeg 进行了重新编码,在此过程中遇到了听不见但波形可见的音频不同步。
Mediainfo 显示相对于视频有6 毫秒的音频延迟:
Audio
ID : 2
Format : E-AC-3
Format/Info : Enhanced Audio Coding 3
Format settings, Endianness : Big
Codec ID : A_EAC3
Duration : 1 h 0 min
Bit rate mode : Constant
Bit rate : 640 kb/s
Channel(s) : 6 channels
Channel positions : Front: L C R, Side: L R, LFE
Sampling rate : 48.0 kHz
Frame rate : 187.500 FPS (256 SPF)
Compression mode : Lossy
Delay relative to video : 6 ms
Stream size : 276 MiB (7%)
Language : English
Service kind : Complete Main
Default : Yes
Forced : No
Run Code Online (Sandbox Code Playgroud)
这也可以通过查看 pts 和流开始时间来看出:
ffprobe -of compact -select_streams a:0 -show_frames -show_entries frame=pkt_pts,pkt_pts_time,pkt_dts,pkt_dts_time,best_effort_timestamp_time,pkt_duration,nb_samples %sourcemkv%
frame|pkt_pts=6|pkt_pts_time=0.006000|pkt_dts=6|pkt_dts_time=0.006000|best_effort_timestamp_time=0.006000|pkt_duration=32|nb_samples=1536
frame|pkt_pts=38|pkt_pts_time=0.038000|pkt_dts=38|pkt_dts_time=0.038000|best_effort_timestamp_time=0.038000|pkt_duration=32|nb_samples=1536
frame|pkt_pts=70|pkt_pts_time=0.070000|pkt_dts=70|pkt_dts_time=0.070000|best_effort_timestamp_time=0.070000|pkt_duration=32|nb_samples=1536
Run Code Online (Sandbox Code Playgroud)
此外,延迟是通过流start_time检查来检测的:
ffprobe -show_entries stream=codec_type,duration,start_time -of compact %sourcemkv%
stream|codec_type=video|start_time=0.000000|duration=N/A
stream|codec_type=audio|start_time=0.006000|duration=N/A
stream|codec_type=subtitle|start_time=0.000000|duration=3617.638000
Run Code Online (Sandbox Code Playgroud)
我选择仅使用这些标志(无时间戳操作)将 EAC3 转码为 AAC 并缩混为立体声:-acodec aac -b:a 160k -ac 2
我获得延迟结果的一种方法是使用以下命令重新编码:ffmpeg -i %sourcemkv% -vcodec libx264 -profile:v high -crf 23 -tune film -level 4.1 -acodec aac -b:a 160k -ac 2 re-encoded-with-aac.mkv
我通过检查与视频帧相对应的波形来检测延迟。延迟本身不太明显,因为我发现编码版本比原始版本晚了 15.333 毫秒,但根据通过 AvsPmod 中的以下 AviSynth+ 脚本进行的检查,它是存在的:
FFmpegSource2("re-encoded-with-aac.mkv", vtrack=-1, atrack=-1, cache=True, cachefile="", fpsnum=-1, fpsden=1, threads=-1, timecodes="", seekmode=1, overwrite=False, width=-1, height=-1, resizer="BICUBIC", colorspace="", rffmode=0, adjustdelay=-1, utf8=False, varprefix="")
ConvertToMono()
# Test if DelayAudio will sync it!
#AmplifydB(50.0)
#DelayAudio(-0.015333)
waveform( window=1, height=0.6)
Run Code Online (Sandbox Code Playgroud)
我将相同的脚本应用于原始脚本,并比较了某些视频帧的结果波形图:第139 帧的源 mkv 图与第 139 帧的 AAC 重新编码视频波形视图
可以看出,除非将 aDelayAudio(-0.015333)应用于重新编码AAC 音频流 - 它们不同步。值得庆幸的是,这种延迟在整个视频中始终存在!
重新混合的音频流具有start_time=0.000000第一个音频帧的 pts 0.000000。有点奇怪的是,尽管据报道原始音频相对于视频的已知延迟为 6 毫秒,但原始视频和使用 aac 流重新编码的视频之间的最终延迟为 0.5 毫秒15.333ms。我不知道这可能从何而来;也许它与输出音频帧的长度有关,每个音频帧的持续时间为21.333ms?!
我还尝试了以下实验:
实验1
%sourcemkv%。检测到 EAC3 音频流中的 6ms 延迟。提取此音频流。结果:通过上述检查方法判断,音频与原始音频同步。
实验2
结果:原始和结果之间的音频不同步
根据 Eugen 的回答,我在这个 VideoHelp 论坛线程上搜索并找到了有关编解码器相关静音(即编码开始时生成的延迟)的更多信息。然后我偶然发现了 Apple 的 QAAC 编码器及其允许修剪编码器特定延迟的选项之一,也在有关延迟的 VideoHelp 线程上建议:
--no-delay Compensate encoder delay by prepending 960 samples
of scilence, then trimming 3 AAC frames from
the beginning (and also tweak iTunSMPB).
This option is mainly intended for resolving
A/V sync issue of video.
Run Code Online (Sandbox Code Playgroud)
通过使用上述选项,我成功实现了使音频与原始音频保持同步的目标,我将在下面进行描述。我决定将此作为一个问题发布,因为主要问题是是否有一种方法可以缩混为 AAC,同时保持音频与源完美同步,我已经找到了一种方法来做到这一点。
AAC 缩混提取:
ffmpeg -i %sourcemkv% -vn -ac 2 -acodec pcm_f32le -f wav - | qaac -v 160 --delay 0.006 --no-delay - -o outw6ms.m4a
Run Code Online (Sandbox Code Playgroud)
该命令执行以下操作:
-ac 2pcm_f32le) - 这是必要的,以便缩混保留原始流的响度 --no-delay可以减少编码器特定延迟的标志-delay 0.006烘焙 6 毫秒静音的选项,因为原始版本相对于视频有一定的延迟(我可以忽略这一点,而是在 mkvmerge 中重新混合结果,并在那里明确指定音频流需要 6 毫秒延迟 - 我测试过这也可以工作)然后,我直接在 ffmpeg 中将生成的音频与转码后的视频重新混合:
ffmpeg -i encvideo.mkv -i outw6ms.m4a -codec copy -map 0:v -map 1:a result.mkv
Run Code Online (Sandbox Code Playgroud)
我在 AvsPMod 中尝试了结果waveform(),音频从开始到结束都与源完美同步。
所以最后我找到了一种保持原始音频相对于视频同步的方法。我会再等一段时间,直到接受这个答案,因为我想知道 ffmpeg 中可用的音频编码器是否允许这种具有此选项的行为。这似乎非常有用,并且是专门为此类事情而设计的。qaac--no-delay
| 归档时间: |
|
| 查看次数: |
9121 次 |
| 最近记录: |