FFmpeg 删除检测静音检测到的确切持续时间的静音
FFmpeg remove silence with exact duration detected by detect silence
我有一个音频文件,它有一些静音,我用 ffmpeg detectsilence 检测到它,然后尝试用 removesilence 删除,但是有一些奇怪的行为。具体来说:
1) 基于 ffprobe 的文件基本信息 show_streams
Input #0, mp3, from 'my_file.mp3':
Metadata:
encoder : Lavf58.64.100
Duration: 00:00:25.22, start: 0.046042, bitrate: 32 kb/s
Stream #0:0: Audio: mp3, 24000 Hz, mono, fltp, 32 kb/s
2) 使用 detetsilence
ffmpeg -i my_file.mp3 -af silencedetect=noise=-50dB:d=0.2 -f null -
我得到这个结果
[mp3float @ 000001ee50074280] overread, skip -7 enddists: -1 -1
[silencedetect @ 000001ee5008a1c0] silence_start: 6.21417
[silencedetect @ 000001ee5008a1c0] silence_end: 6.91712 | silence_duration: 0.702958
[silencedetect @ 000001ee5008a1c0] silence_start: 16.44
[silencedetect @ 000001ee5008a1c0] silence_end: 17.1547 | silence_duration: 0.714708
[mp3float @ 000001ee50074280] overread, skip -10 enddists: -3 -3
[mp3float @ 000001ee50074280] overread, skip -5 enddists: -4 -4
[silencedetect @ 000001ee5008a1c0] silence_start: 24.4501
size=N/A time=00:00:25.17 bitrate=N/A speed=1.32e+03x
video:0kB audio:1180kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
[silencedetect @ 000001ee5008a1c0] silence_end: 25.176 | silence_duration: 0.725917
这也符合基于 Adobe Audition 的值和分数
目前一切顺利。
3) 现在,基于一些计算(基于应用程序关于音频最终持续时间的逻辑),我试图用“ 0.725917 秒的持续时间。为此,基于 ffmpeg 文档 (https://ffmpeg.org/ffmpeg-filters.html#silencedetect)
Trim all silence encountered from beginning to end where there is more
than 1 second of silence in audio:
silenceremove=stop_periods=-1:stop_duration=1:stop_threshold=-90dB
我运行这个命令
ffmpeg -i my_file.mp3 -af silenceremove=stop_periods=-1:stop_threshold=-50dB:stop_duration=0.72 result1.mp3
所以,我预计它应该只删除持续时间为“0.725917”的静音(上图中的最后一个),但是它正在删除从 16.44 秒开始持续时间为“0.714708”的静音.请看下面的对比:
4) 运行 使用相同选项在 result1.mp3 上检测沉默会给出更奇怪的结果
ffmpeg -i result1.mp3 -af silencedetect=noise=-50dB:d=0.2 -f null -
结果
[mp3float @ 0000017723404280] overread, skip -5 enddists: -4 -4
[silencedetect @ 0000017723419540] silence_start: 6.21417
[silencedetect @ 0000017723419540] silence_end: 6.92462 | silence_duration: 0.710458
[mp3float @ 0000017723404280] overread, skip -7 enddists: -6 -6
[mp3float @ 0000017723404280] overread, skip -7 enddists: -2 -2
[mp3float @ 0000017723404280] overread, skip -6 enddists: -1 -1
Last message repeated 1 times
[silencedetect @ 0000017723419540] silence_start: 23.7308
size=N/A time=00:00:24.45 bitrate=N/A speed=1.33e+03x
video:0kB audio:1146kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
[silencedetect @ 0000017723419540] silence_end: 24.456 | silence_duration: 0.725167
所以,结果是:
- 通过命令删除超过“0.72 秒”的静默,“0.714708”秒的静默被移除和 - 保持“0.725917”秒的静默原样(嗯,实际上改变了一点 - 根据第 3 点)
- 从“6.21417”开始且持续时间为“0.702958”秒的第一个静默突然变成了“0.710458”秒
- 从“24.4501”开始的第三个静音(现在从 23.7308 开始 - 显然是因为第二个静音已被删除)并且持续时间为“0.725917”,现在突然变成“0.725167”(这个是差别不大,但为什么即使删除其他静音,此静音的持续时间也应该完全改变)。
相应的预期结果是:
- 只应删除符合所提供条件 (stop_duration=0.72) 的静音。在这个具体的例子中只有最后一个,但通常任何符合长度条件的沉默 - 与其定位无关(开始,结束或中间)
- 其他沉默应该保持与之前相同的确切持续时间
FFMpeg: 4.2.4-1ubuntu0.1, Ubuntu: 20.04.2
一些尝试和结果,同时使用 ffmpeg 选项
a)
ffmpeg -i my_file.mp3 -af silenceremove=stop_periods=-1:stop_threshold=-50dB:stop_duration=0.72:detection=peak tmp1.mp3
结果:
第一和第二个沉默被移除,第三个沉默的持续时间保持完全相同
b)
ffmpeg -i my_file.mp3 -af silenceremove=stop_periods=-1:stop_threshold=-50dB:stop_duration=0.71 tmp_0.71.mp3
结果:
第一和第二个沉默被移除,第三个沉默仍然存在,但持续时间变为“0.72075”s
c)
ffmpeg -i my_file.mp3 -af silenceremove=stop_periods=-1:stop_threshold=-50dB:stop_duration=0.7 tmp_0.7.mp3
结果:
所有 3 个沉默都被移除
d) 边缘情况
此命令仍然会删除第二个静音(此后第一个静音变为与点 #4 完全相同,最后一个静音变为“0.721375”)
ffmpeg -i my_file.mp3 -af silenceremove=stop_periods=-1:stop_threshold=-50dB:stop_duration=0.72335499999 tmp_0.72335499999.mp3
但是这一个,再次没有消除任何沉默:
ffmpeg -i my_file.mp3 -af silenceremove=stop_periods=-1:stop_threshold=-50dB:stop_duration=0.723355 tmp_0.723355.mp3
e) window 参数大小写 0.03
ffmpeg -i my_file.mp3 -af silenceremove=stop_periods=-1:stop_threshold=-50dB:stop_duration=0.72:window=0.03 window_0.03.mp3
不移除任何静音,但检测静音
ffmpeg -i window_0.03.mp3 -af silencedetect=noise=-50dB:d=0.2 -f null -
给出此结果(与 result1.mp3 中的沉默比较 - 从 #4 点开始)
[mp3float @ 000001c5c8824280] overread, skip -5 enddists: -4 -4
[silencedetect @ 000001c5c883a040] silence_start: 6.21417
[silencedetect @ 000001c5c883a040] silence_end: 6.92462 | silence_duration: 0.710458
[mp3float @ 000001c5c8824280] overread, skip -7 enddists: -6 -6
[mp3float @ 000001c5c8824280] overread, skip -7 enddists: -2 -2
[silencedetect @ 000001c5c883a040] silence_start: 16.4424
[silencedetect @ 000001c5c883a040] silence_end: 17.1555 | silence_duration: 0.713167
[mp3float @ 000001c5c8824280] overread, skip -6 enddists: -1 -1
Last message repeated 1 times
[silencedetect @ 000001c5c883a040] silence_start: 24.4508
size=N/A time=00:00:25.17 bitrate=N/A speed=1.24e+03x
video:0kB audio:1180kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
[silencedetect @ 000001c5c883a040] silence_end: 25.176 | silence_duration: 0.725167
f) window 例 0.01
ffmpeg -i my_file.mp3 -af silenceremove=stop_periods=-1:stop_threshold=-50dB:stop_duration=0.72:window=0.01 window_0.01.mp3
去除第一和第二静默,使用相同参数检测静默有以下结果
[mp3float @ 000001ea631d4280] overread, skip -5 enddists: -4 -4
Last message repeated 1 times
[mp3float @ 000001ea631d4280] overread, skip -7 enddists: -2 -2
[mp3float @ 000001ea631d4280] overread, skip -6 enddists: -1 -1
Last message repeated 1 times
[silencedetect @ 000001ea631ea1c0] silence_start: 23.0108
size=N/A time=00:00:23.73 bitrate=N/A speed=1.2e+03x
video:0kB audio:1113kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
[silencedetect @ 000001ea631ea1c0] silence_end: 23.736 | silence_duration: 0.725167
非常感谢任何想法、想法和观点。
您正遭受两件事的困扰:
- 您正在转换回 mp3(有损格式),这导致 result1.mp3 被重新编码并变得与完美剪辑略有不同。解决此问题的方法是使用 .wav(一种无损格式)。
- silenceremove 函数正在使用 window,您需要将其设置为 0 才能逐个采样。
ffmpeg -i my_file.mp3 my_file.wav
ffmpeg -i my_file.wav -af silencedetect=noise=-50dB:d=0.2 -f null -
ffmpeg -i my_file.wav -af silenceremove=stop_periods=-1:stop_threshold=-50dB:stop_duration=0.72:window=0 result1.wav
ffmpeg -i result1.wav -af silencedetect=noise=-50dB:d=0.2 -f null -
最后一行的最终输出。我认为这是一个可靠的解决方案,因为静音开始和持续时间与剪辑前的值完美匹配:
[silencedetect @ 0x5570a855b400] silence_start: 6.21417
[silencedetect @ 0x5570a855b400] silence_end: 6.91712 | silence_duration: 0.702958
[silencedetect @ 0x5570a855b400] silence_start: 16.44
[silencedetect @ 0x5570a855b400] silence_end: 17.1547 | silence_duration: 0.714708
size=N/A time=00:00:24.45 bitrate=N/A speed=4.49e+03x
如果需要,您可以将其重新编码为 .mp3。
我有一个音频文件,它有一些静音,我用 ffmpeg detectsilence 检测到它,然后尝试用 removesilence 删除,但是有一些奇怪的行为。具体来说:
1) 基于 ffprobe 的文件基本信息 show_streams
Input #0, mp3, from 'my_file.mp3':
Metadata:
encoder : Lavf58.64.100
Duration: 00:00:25.22, start: 0.046042, bitrate: 32 kb/s
Stream #0:0: Audio: mp3, 24000 Hz, mono, fltp, 32 kb/s
2) 使用 detetsilence
ffmpeg -i my_file.mp3 -af silencedetect=noise=-50dB:d=0.2 -f null -
我得到这个结果
[mp3float @ 000001ee50074280] overread, skip -7 enddists: -1 -1
[silencedetect @ 000001ee5008a1c0] silence_start: 6.21417
[silencedetect @ 000001ee5008a1c0] silence_end: 6.91712 | silence_duration: 0.702958
[silencedetect @ 000001ee5008a1c0] silence_start: 16.44
[silencedetect @ 000001ee5008a1c0] silence_end: 17.1547 | silence_duration: 0.714708
[mp3float @ 000001ee50074280] overread, skip -10 enddists: -3 -3
[mp3float @ 000001ee50074280] overread, skip -5 enddists: -4 -4
[silencedetect @ 000001ee5008a1c0] silence_start: 24.4501
size=N/A time=00:00:25.17 bitrate=N/A speed=1.32e+03x
video:0kB audio:1180kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
[silencedetect @ 000001ee5008a1c0] silence_end: 25.176 | silence_duration: 0.725917
这也符合基于 Adobe Audition 的值和分数
目前一切顺利。
3) 现在,基于一些计算(基于应用程序关于音频最终持续时间的逻辑),我试图用“ 0.725917 秒的持续时间。为此,基于 ffmpeg 文档 (https://ffmpeg.org/ffmpeg-filters.html#silencedetect)
Trim all silence encountered from beginning to end where there is more than 1 second of silence in audio: silenceremove=stop_periods=-1:stop_duration=1:stop_threshold=-90dB
我运行这个命令
ffmpeg -i my_file.mp3 -af silenceremove=stop_periods=-1:stop_threshold=-50dB:stop_duration=0.72 result1.mp3
所以,我预计它应该只删除持续时间为“0.725917”的静音(上图中的最后一个),但是它正在删除从 16.44 秒开始持续时间为“0.714708”的静音.请看下面的对比:
4) 运行 使用相同选项在 result1.mp3 上检测沉默会给出更奇怪的结果
ffmpeg -i result1.mp3 -af silencedetect=noise=-50dB:d=0.2 -f null -
结果
[mp3float @ 0000017723404280] overread, skip -5 enddists: -4 -4
[silencedetect @ 0000017723419540] silence_start: 6.21417
[silencedetect @ 0000017723419540] silence_end: 6.92462 | silence_duration: 0.710458
[mp3float @ 0000017723404280] overread, skip -7 enddists: -6 -6
[mp3float @ 0000017723404280] overread, skip -7 enddists: -2 -2
[mp3float @ 0000017723404280] overread, skip -6 enddists: -1 -1
Last message repeated 1 times
[silencedetect @ 0000017723419540] silence_start: 23.7308
size=N/A time=00:00:24.45 bitrate=N/A speed=1.33e+03x
video:0kB audio:1146kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
[silencedetect @ 0000017723419540] silence_end: 24.456 | silence_duration: 0.725167
所以,结果是:
- 通过命令删除超过“0.72 秒”的静默,“0.714708”秒的静默被移除和 - 保持“0.725917”秒的静默原样(嗯,实际上改变了一点 - 根据第 3 点)
- 从“6.21417”开始且持续时间为“0.702958”秒的第一个静默突然变成了“0.710458”秒
- 从“24.4501”开始的第三个静音(现在从 23.7308 开始 - 显然是因为第二个静音已被删除)并且持续时间为“0.725917”,现在突然变成“0.725167”(这个是差别不大,但为什么即使删除其他静音,此静音的持续时间也应该完全改变)。
相应的预期结果是:
- 只应删除符合所提供条件 (stop_duration=0.72) 的静音。在这个具体的例子中只有最后一个,但通常任何符合长度条件的沉默 - 与其定位无关(开始,结束或中间)
- 其他沉默应该保持与之前相同的确切持续时间
FFMpeg: 4.2.4-1ubuntu0.1, Ubuntu: 20.04.2
一些尝试和结果,同时使用 ffmpeg 选项
a)
ffmpeg -i my_file.mp3 -af silenceremove=stop_periods=-1:stop_threshold=-50dB:stop_duration=0.72:detection=peak tmp1.mp3
结果: 第一和第二个沉默被移除,第三个沉默的持续时间保持完全相同
b)
ffmpeg -i my_file.mp3 -af silenceremove=stop_periods=-1:stop_threshold=-50dB:stop_duration=0.71 tmp_0.71.mp3
结果: 第一和第二个沉默被移除,第三个沉默仍然存在,但持续时间变为“0.72075”s
c)
ffmpeg -i my_file.mp3 -af silenceremove=stop_periods=-1:stop_threshold=-50dB:stop_duration=0.7 tmp_0.7.mp3
结果: 所有 3 个沉默都被移除
d) 边缘情况
此命令仍然会删除第二个静音(此后第一个静音变为与点 #4 完全相同,最后一个静音变为“0.721375”)
ffmpeg -i my_file.mp3 -af silenceremove=stop_periods=-1:stop_threshold=-50dB:stop_duration=0.72335499999 tmp_0.72335499999.mp3
但是这一个,再次没有消除任何沉默:
ffmpeg -i my_file.mp3 -af silenceremove=stop_periods=-1:stop_threshold=-50dB:stop_duration=0.723355 tmp_0.723355.mp3
e) window 参数大小写 0.03
ffmpeg -i my_file.mp3 -af silenceremove=stop_periods=-1:stop_threshold=-50dB:stop_duration=0.72:window=0.03 window_0.03.mp3
不移除任何静音,但检测静音
ffmpeg -i window_0.03.mp3 -af silencedetect=noise=-50dB:d=0.2 -f null -
给出此结果(与 result1.mp3 中的沉默比较 - 从 #4 点开始)
[mp3float @ 000001c5c8824280] overread, skip -5 enddists: -4 -4
[silencedetect @ 000001c5c883a040] silence_start: 6.21417
[silencedetect @ 000001c5c883a040] silence_end: 6.92462 | silence_duration: 0.710458
[mp3float @ 000001c5c8824280] overread, skip -7 enddists: -6 -6
[mp3float @ 000001c5c8824280] overread, skip -7 enddists: -2 -2
[silencedetect @ 000001c5c883a040] silence_start: 16.4424
[silencedetect @ 000001c5c883a040] silence_end: 17.1555 | silence_duration: 0.713167
[mp3float @ 000001c5c8824280] overread, skip -6 enddists: -1 -1
Last message repeated 1 times
[silencedetect @ 000001c5c883a040] silence_start: 24.4508
size=N/A time=00:00:25.17 bitrate=N/A speed=1.24e+03x
video:0kB audio:1180kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
[silencedetect @ 000001c5c883a040] silence_end: 25.176 | silence_duration: 0.725167
f) window 例 0.01
ffmpeg -i my_file.mp3 -af silenceremove=stop_periods=-1:stop_threshold=-50dB:stop_duration=0.72:window=0.01 window_0.01.mp3
去除第一和第二静默,使用相同参数检测静默有以下结果
[mp3float @ 000001ea631d4280] overread, skip -5 enddists: -4 -4
Last message repeated 1 times
[mp3float @ 000001ea631d4280] overread, skip -7 enddists: -2 -2
[mp3float @ 000001ea631d4280] overread, skip -6 enddists: -1 -1
Last message repeated 1 times
[silencedetect @ 000001ea631ea1c0] silence_start: 23.0108
size=N/A time=00:00:23.73 bitrate=N/A speed=1.2e+03x
video:0kB audio:1113kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
[silencedetect @ 000001ea631ea1c0] silence_end: 23.736 | silence_duration: 0.725167
非常感谢任何想法、想法和观点。
您正遭受两件事的困扰:
- 您正在转换回 mp3(有损格式),这导致 result1.mp3 被重新编码并变得与完美剪辑略有不同。解决此问题的方法是使用 .wav(一种无损格式)。
- silenceremove 函数正在使用 window,您需要将其设置为 0 才能逐个采样。
ffmpeg -i my_file.mp3 my_file.wav
ffmpeg -i my_file.wav -af silencedetect=noise=-50dB:d=0.2 -f null -
ffmpeg -i my_file.wav -af silenceremove=stop_periods=-1:stop_threshold=-50dB:stop_duration=0.72:window=0 result1.wav
ffmpeg -i result1.wav -af silencedetect=noise=-50dB:d=0.2 -f null -
最后一行的最终输出。我认为这是一个可靠的解决方案,因为静音开始和持续时间与剪辑前的值完美匹配:
[silencedetect @ 0x5570a855b400] silence_start: 6.21417
[silencedetect @ 0x5570a855b400] silence_end: 6.91712 | silence_duration: 0.702958
[silencedetect @ 0x5570a855b400] silence_start: 16.44
[silencedetect @ 0x5570a855b400] silence_end: 17.1547 | silence_duration: 0.714708
size=N/A time=00:00:24.45 bitrate=N/A speed=4.49e+03x
如果需要,您可以将其重新编码为 .mp3。