使用 ffmpeg 连接音频文件会导致错误的总持续时间
Concatenating audio files with ffmpeg results in a wrong total duration
“总持续时间错误”是指总持续时间与音频文件的各个持续时间之和不同。
sum_duration_files != 持续时间(文件串联)
特别是我用这个命令连接了 2 个 OGG 音频文件
ffmpeg -safe 0 -loglevel quiet \
-f concat -segment_time_metadata 1 -i {m3u_file_name} \
-vf select=concatdec_select \
-af aselect=concatdec_select,aresample=async=1 \
{ogg_file_name}
我得到以下内容
# Output of: ffprobe <FILE>.ogg
======== files_in
Input #0, ogg, from 'f1.ogg':
Duration: 00:00:04.32, start: 0.000000, bitrate: 28 kb/s
Stream #0:0: Audio: opus, 48000 Hz, mono, fltp
Input #0, ogg, from 'f2.ogg':
Duration: 00:00:00.70, start: 0.000000, bitrate: 68 kb/s
Stream #0:0: Audio: vorbis, 44100 Hz, mono, fltp, 160 kb/s
Metadata:
ENCODER : Lavc57.107.100 libvorbis
音符时长:4.32 和 0.7 秒
这是输出文件。
========== files out (concatenate of files_in)
Input #0, ogg, from 'f_concat_v1.ogg':
Duration: 00:00:04.61, start: 0.000000, bitrate: 61 kb/s
Stream #0:0: Audio: vorbis, 48000 Hz, mono, fltp, 80 kb/s
Metadata:
ENCODER : Lavc57.107.100 libvorbis
时长:4.61 秒
因为 4.61 秒 != 4.32 + 0.7 秒我有问题。
我不知道为什么会这样,但我知道如何在我的特定情况下避免这个问题。
我的情况:
我正在混合(连接)由一个来源生成的不同音频文件和我生成的静音文件。
最初我用
生成了静默文件
# x is a float from python
ffmpeg -f lavfi -i anullsrc=r=44100:cl=mono -t {x:2.1f} -q:a 9 -acodec libvorbis silence-{x:2.1f}.ogg
试图解决我的问题 re-created 与我混音的音频具有相同参数的静音,即(48Khz 的单声道):
ffmpeg -f lavfi -i anullsrc=r=48000:cl=mono -t {x:2.1f} -c:a libvorbis silence-{x:2.1f}.ogg
现在 ffprobe
显示了预期的结果。
========== files out (concatenate of files_in)
Input #0, ogg, from 'f_concat_v2.ogg':
Duration: 00:00:05.02, start: 0.000000, bitrate: 56 kb/s
Stream #0:0: Audio: vorbis, 48000 Hz, mono, fltp, 80 kb/s
Metadata:
ENCODER : Lavc57.107.100 libvorbis
持续时间:5.02 = 4.32 + 0.70
如果您想避免在将静音与其他声音连接时出现问题,请使用与您要混合的声音相同的参数(mono/stereo 和 Hz)创建静音
==== 2022-03-08 更新
使用@kesh 提供的信息,我使用
重新创建了静默的 ogg 文件
ffmpeg -f lavfi -i anullsrc=r=48000:cl=mono -t 5.8 -c:a libopus silence-5.8.ogg
现在
ffmpeg -safe 0 -f concat -segment_time_metadata 1
-i {m3u_file_name}
-vf select=concatdec_select
-af aselect=concatdec_select,aresample=async=1 {ogg_file_name}
不再(多次)抛出此错误。
[opus @ 0x558b2c245400] Error parsing the packet header.
Error while decoding stream #0:0: Invalid data found when processing input
我必须说这个错误并没有(对我)造成任何问题,因为输出是我所期望的,但现在没有它我感觉好多了。
这里的问题是对这些文件使用了错误的串联方法。正如 FFmpeg wiki article 所建议的那样,file-level 串联 (-f concat
) 要求列表中的所有文件具有完全相同的编解码器参数。在您的情况下,只有频道数 (mono
) 和样本格式 (flt
) 在它们之间是通用的。另一方面,编解码器(opus
vs. vorbis
)和采样率(48000
vs. 44100
)不同。
-f concat
获取第一组参数并使用它运行。在您的情况下,它对所有文件使用 48000 S/s。虽然第二个文件是 44100 S/s,但它假定为 48k(因此播放速度会比现在快)。我不知道编解码器的差异如何在输出中发挥作用。
因此,标准方法是使用 -filter_complex concat=a=1:v=1:n=2
这些文件作为单独的输入。
出于好奇,你听过 wrong-duration 输出文件了吗? [编辑:没关系,你的 self-answer 表明其中之一是无声轨道]
“总持续时间错误”是指总持续时间与音频文件的各个持续时间之和不同。
sum_duration_files != 持续时间(文件串联)
特别是我用这个命令连接了 2 个 OGG 音频文件
ffmpeg -safe 0 -loglevel quiet \
-f concat -segment_time_metadata 1 -i {m3u_file_name} \
-vf select=concatdec_select \
-af aselect=concatdec_select,aresample=async=1 \
{ogg_file_name}
我得到以下内容
# Output of: ffprobe <FILE>.ogg
======== files_in
Input #0, ogg, from 'f1.ogg':
Duration: 00:00:04.32, start: 0.000000, bitrate: 28 kb/s
Stream #0:0: Audio: opus, 48000 Hz, mono, fltp
Input #0, ogg, from 'f2.ogg':
Duration: 00:00:00.70, start: 0.000000, bitrate: 68 kb/s
Stream #0:0: Audio: vorbis, 44100 Hz, mono, fltp, 160 kb/s
Metadata:
ENCODER : Lavc57.107.100 libvorbis
音符时长:4.32 和 0.7 秒
这是输出文件。
========== files out (concatenate of files_in)
Input #0, ogg, from 'f_concat_v1.ogg':
Duration: 00:00:04.61, start: 0.000000, bitrate: 61 kb/s
Stream #0:0: Audio: vorbis, 48000 Hz, mono, fltp, 80 kb/s
Metadata:
ENCODER : Lavc57.107.100 libvorbis
时长:4.61 秒
因为 4.61 秒 != 4.32 + 0.7 秒我有问题。
我不知道为什么会这样,但我知道如何在我的特定情况下避免这个问题。
我的情况: 我正在混合(连接)由一个来源生成的不同音频文件和我生成的静音文件。
最初我用
生成了静默文件# x is a float from python
ffmpeg -f lavfi -i anullsrc=r=44100:cl=mono -t {x:2.1f} -q:a 9 -acodec libvorbis silence-{x:2.1f}.ogg
试图解决我的问题 re-created 与我混音的音频具有相同参数的静音,即(48Khz 的单声道):
ffmpeg -f lavfi -i anullsrc=r=48000:cl=mono -t {x:2.1f} -c:a libvorbis silence-{x:2.1f}.ogg
现在 ffprobe
显示了预期的结果。
========== files out (concatenate of files_in)
Input #0, ogg, from 'f_concat_v2.ogg':
Duration: 00:00:05.02, start: 0.000000, bitrate: 56 kb/s
Stream #0:0: Audio: vorbis, 48000 Hz, mono, fltp, 80 kb/s
Metadata:
ENCODER : Lavc57.107.100 libvorbis
持续时间:5.02 = 4.32 + 0.70
如果您想避免在将静音与其他声音连接时出现问题,请使用与您要混合的声音相同的参数(mono/stereo 和 Hz)创建静音
==== 2022-03-08 更新
使用@kesh 提供的信息,我使用
重新创建了静默的 ogg 文件ffmpeg -f lavfi -i anullsrc=r=48000:cl=mono -t 5.8 -c:a libopus silence-5.8.ogg
现在
ffmpeg -safe 0 -f concat -segment_time_metadata 1
-i {m3u_file_name}
-vf select=concatdec_select
-af aselect=concatdec_select,aresample=async=1 {ogg_file_name}
不再(多次)抛出此错误。
[opus @ 0x558b2c245400] Error parsing the packet header.
Error while decoding stream #0:0: Invalid data found when processing input
我必须说这个错误并没有(对我)造成任何问题,因为输出是我所期望的,但现在没有它我感觉好多了。
这里的问题是对这些文件使用了错误的串联方法。正如 FFmpeg wiki article 所建议的那样,file-level 串联 (-f concat
) 要求列表中的所有文件具有完全相同的编解码器参数。在您的情况下,只有频道数 (mono
) 和样本格式 (flt
) 在它们之间是通用的。另一方面,编解码器(opus
vs. vorbis
)和采样率(48000
vs. 44100
)不同。
-f concat
获取第一组参数并使用它运行。在您的情况下,它对所有文件使用 48000 S/s。虽然第二个文件是 44100 S/s,但它假定为 48k(因此播放速度会比现在快)。我不知道编解码器的差异如何在输出中发挥作用。
因此,标准方法是使用 -filter_complex concat=a=1:v=1:n=2
这些文件作为单独的输入。
出于好奇,你听过 wrong-duration 输出文件了吗? [编辑:没关系,你的 self-answer 表明其中之一是无声轨道]