使用ffmpeg实现音频静音修剪

1 silenceremove介绍

本文主要介绍在 FFmpeg 命令中使用 silenceremove filter 进行音频静音的修剪。

1.1 start_x参数

参数名 说明 取值范围 默认值
start_periods 设置是否应在音频开头修剪音频。0 表示不应从一开始就修剪静音。当指定一个 0 值时,它会修剪音频直到找到非静音。通常,当从音频的开头修剪静音时,start_periods 将为 1,但它可以增加到更高的值,以将所有音频修剪到非静音周期的特定计数。 0 ~ 9000 0
start_duration 设置停止 修剪音频之前必须检测到的非静音 时长。通过加大该时长,可以将突发的噪音视为静音并进行修剪。(注意,一般使该值保持为 0,否则会有副作用。) 0 ~ INT32_MAX(注意:传参可用多种格式) 0
start_threshold 设置应将哪些样本值视为静音。对于数字音频,值 0 可能没问题,但对于从模拟信号录制的音频,可能希望增加该值以考虑背景噪音。可以以 dB 为单位指定("dB"附加到值后面)或幅度比(amplitude ratio, 比如 0.001 实际上等价于 -60dB)。 0 ~ DBL_MAX 0
start_silence 设置在修剪后保留的最大静音时长。默认值为 0,这等于修剪所有检测为静音的样本。 0 ~ INT32_MAX(注意:传参可用多种格式) 0
start_mode 指定多声道音频开始处检测静音结束 的模式。可以是 anyall。默认为 any, 表示对于任一声道被检测到非静音 的样本都将导致停止修剪静音。对于 all,则当所有通道都被检测为非静音时,才会导致停止修剪静音。 any/all any

start_periods 决定了其他参数是否有效。

时长(duration)格式见:the Time duration section

1.2 stop_x 参数

参数名 说明 取值范围 默认值
stop_periods 设置从音频结尾开始修剪静音的计数。要从文件中间删除静音则指定为负值。负值将值视为正值并且像 start_periods 那样重新开始处理,使其适用于消除音频中间的静音时间段。 -9000 ~ 9000 0
stop_duration 指定在不再复制(Copy,FFmpeg 内部处理模式分为裁剪(Trim)和复制(Copy)。)音频之前必须存在的静音时长。通过加大该时长,可以在音频中保留所需的静音。(注意,一般使该值保持为 0,否则会有副作用。) 0 ~ INT32_MAX(注意:传参可用多种格式) 0
stop_threshold 类似于 start_threshold,但用于从音频末尾修剪静音。 0 ~ DBL_MAX 0
stop_silence 类似于 start_silence 0 ~ INT32_MAX(注意:传参可用多种格式) 0
stop_mode 指定多声道音频结尾处检测静音结束 的模式。可以是 anyall。默认为 any, 表示对于任一声道被检测到非静音 的样本都将导致停止修剪。对于 all,则当所有通道都被检测为非静音时,才会导致停止修剪。 any/all any

stop_silence 决定了其他参数是否有效。

1.3 其他参数

参数名 说明 取值范围 默认值
detection 指定音量的计算方式。rms 表示使用均方根值(RMS)计算, peak 表示使用幅度值(amplitude)计算。 rms/peak rms
window 指定使用滑动窗口计算音量的窗口大小。单位为秒。由 detection 决定计算方式。 0 ~ 10 0.02

2 silenceremove使用

使用 Audition 之类的软件录制一段音频,然后将背景噪音用静音替换。

2.1 移除首部第一个静音段

ffmpeg -hide_banner -loglevel warning -i "Test.wav" -filter_complex "silenceremove=start_periods=1:start_duration=0.2:start_threshold=-50dB:detection=peak" -ar 44100 -ac 2 -b:a 96k "Test-RemoveSilence01_01.ogg" -y

参数说明:

  • start_periods=1: 移除首部第一个静音段
  • start_duration=0.2: 如果遇见超过 0.2 秒的非静音数据则停止移除。
  • start_threshold=-50dB: 音量不超过 -50dB 认为是静音。
  • detection=peak: 使用幅度值(amplitude)计算音量。

结果展示:

2.2 移除首部第一个静音段,但保留 0.5s 的静音

ffmpeg -hide_banner -loglevel warning -i "Test.wav" -filter_complex "silenceremove=start_periods=1:start_duration=0:start_threshold=-50dB:start_silence=0.5:detection=peak" -ar 44100 -ac 2 -b:a 96k "Test-RemoveSilence02_01.ogg" -y

参数说明:

  • start_periods=1: 移除首部第一个静音段
  • start_duration=0: 只要遇见静音就立即停止移除。
  • start_threshold=-50dB: 音量不超过 -50dB 认为是静音。
  • start_silence=0.5: 首部保留 0.5 秒的静音。
  • detection=peak: 使用幅度值(amplitude)计算音量。

2.3 移除首部前三个静音段

ffmpeg -hide_banner -loglevel warning -i "Test.wav" -filter_complex "silenceremove=start_periods=3:start_duration=0.38:start_threshold=-50dB:detection=peak" -ar 44100 -ac 2 -b:a 96k "Test-RemoveSilence03_01.ogg" -y

参数说明:

  • start_periods=3: 移除首部前三个静音段
  • start_duration=3.8: 如果遇见超过 0.38 秒的非静音数据则停止移除。注意不要设置过小,否则会快速消耗掉 start_periods
  • start_threshold=-50dB: 音量不超过 -50dB 认为是静音。
  • detection=peak: 使用幅度值(amplitude)计算音量。

2.4 移除尾部第一个静音段

直接使用 stop_periods 试验未成功。采取两次翻转的低效方式。首先翻转并移除首部(也就是翻转之前的尾部)静音,然后再翻转回来。

ffmpeg -hide_banner -loglevel warning -i "Test.wav" -filter_complex "areverse,silenceremove=start_periods=1:start_duration=0:start_threshold=-50dB:detection=peak,areverse" -ar 44100 -ac 2 "Test-RemoveSilence04_01.wav" -y

问题:areverse 版生成 ogg 文件有警告:[libvorbis @ 0x14f025400] Queue input is backward in time。Audition 打开也提示有错。原因暂未知。改为输出 wav 没问题。

参数说明:

  • areverse: 翻转音频。
  • 其他: 略。

结果展示:

如下代码设置 stop_periods1 不成功,-1 则文件中间的静音也被移除。

ffmpeg -hide_banner -loglevel warning -i "Test.wav" -filter_complex "silenceremove=stop_periods=-1:stop_duration=0:stop_threshold=-50dB:detection=peak" -ar 44100 -ac 2 -b:a 96k "Test-RemoveSilence04_02.ogg" -y

2.5 移除首部第一个和尾部第一个静音段

不使用 stop_periods 的原因同 4。

首先移除首部静音,翻转并再次移除首部(也就是翻转之前的尾部)静音,最后再翻转回来。

ffmpeg -hide_banner -loglevel warning -i "Test.wav" -filter_complex "silenceremove=start_periods=1:start_duration=0:start_threshold=-50dB:detection=peak,areverse,silenceremove=start_periods=1:start_duration=0:start_threshold=-50dB:detection=peak,areverse" -ar 44100 -ac 2 "Test-RemoveSilence05_01.wav" -y

问题:areverse 版生成 ogg 文件有警告:[libvorbis @ 0x14f025400] Queue input is backward in time。Audition 打开也提示有错。原因暂未知。改为输出 wav 没问题。

参数说明:

  • areverse: 翻转音频。
  • 其他: 略。

结果展示:

2.6 移除首尾和中间的静音段

ffmpeg -hide_banner -loglevel warning -i "Test.wav" -filter_complex "silenceremove=stop_periods=-1:stop_duration=0:stop_threshold=-50dB:detection=peak" -ar 44100 -ac 2 -b:a 96k "Test-RemoveSilence06_01.ogg" -y

参数说明:

  • stop_periods=-1: 移除首尾和中间的静音段。
  • 其他: 略。

结果展示:

不管是首尾还是中间的移除都不是很干净。改用如下参数:

ffmpeg -hide_banner -loglevel warning -i "Test.wav" -filter_complex "silenceremove=start_periods=1:start_duration=0:start_threshold=-50dB:stop_periods=-1:stop_duration=0:stop_threshold=-50dB:detection=peak" -ar 44100 -ac 2 -b:a 96k "Test-RemoveSilence06_02.ogg" -y

结果展示:

首尾和中间干净了,尾部依然不够干净。改用如下参数:

ffmpeg -hide_banner -loglevel warning -i "Test.wav" -filter_complex "silenceremove=start_periods=1:start_duration=0:start_threshold=-50dB:stop_periods=-1:stop_duration=0:stop_threshold=-50dB:detection=peak,areverse,silenceremove=start_periods=1:start_duration=0:start_threshold=-50dB:detection=peak,areverse" -ar 44100 -ac 2 "Test-RemoveSilence06_03.wav" -y

问题:areverse 版生成 ogg 文件有警告:[libvorbis @ 0x14f025400] Queue input is backward in time。Audition 打开也提示有错。原因暂未知。改为输出 wav 没问题。

首尾和中间依然干净,但尾部依然还是有一丝丝不干净,不过也勉强能够接受。

2.7 移除首尾和中间的静音段,并使得首部稍有静音

如果要在首尾保留 0.5 秒的静音:

ffmpeg -hide_banner -loglevel warning -i "Test.wav" -filter_complex "silenceremove=start_periods=1:start_duration=0:start_threshold=-50dB:start_silence=0.5:stop_periods=-1:stop_duration=0:stop_threshold=-50dB:detection=peak,areverse,silenceremove=start_periods=1:start_duration=0:start_threshold=-50dB:start_silence=0.5:detection=peak,areverse" -ar 44100 -ac 2 "Test-RemoveSilence07_01.wav" -y

问题:areverse 版生成 ogg 文件有警告:[libvorbis @ 0x14f025400] Queue input is backward in time。Audition 打开也提示有错。原因暂未知。改为输出 wav 没问题。

除了首部,中间也多了0.5 秒的静音,并且结尾处并不是很完美。

2.8 移除首尾和中间的静音段,并使得中间适当保留静音且首部稍有静音

中间的静音超过 1.5 秒则移除并且保留 1.5 秒;头部保留 0.5 秒静音;尾部不保留静音。第一次使用 silenceremove 会在首部保留 1.5 秒,第二次使用 silenceremove 能够将首部静音缩减为 0.5 秒。

ffmpeg -hide_banner -loglevel warning -i "Test.wav" -filter_complex "silenceremove=start_periods=1:start_duration=0:start_threshold=-50dB:start_silence=1.5:stop_periods=-1:stop_duration=0:stop_threshold=-50dB:stop_silence=1.5:detection=peak,silenceremove=start_periods=1:start_duration=0:start_threshold=-50dB:start_silence=0.5:detection=peak"  -ar 44100 -ac 2 "Test-RemoveSilence08_01.wav" -y

start_silencestop_silence 都需要设置为 1.5;

如果提供了 start_durationstop_duration 参数则需要设置为 0

除了尾部稍有不净,基本能达到目的。

该方法不适用 于首部保留静音比中间保留静音 的情况,也不适用于尾部稍微保留静音的情况。

3 FFmpeg介绍

FFmpeg项目由 Fabrice Bellard在2000年创立。到目前为止,FFmpeg项目的开发者仍然与VLC、MPV、dav1d、x264等多媒体开源项目有着广泛的重叠。Ffmpeg(FastForward Mpeg)是一款遵循GPL的开源软件,在音视频处理方面表现十分优秀,几乎囊括了现存所有的视音频格式的编码,解码、转码、混合、过滤及播放。作为最受欢迎的视频和图像处理软件,它被来自各行各业的不同公司所广泛使用。同时也是一款跨平台的软件,完美兼容Linux、Windows、Mac OSX等平台。其实它由3大部件组成,号称音视频处理工具三剑客:

  • Ffmpeg:由命令行组成,用于多媒体格式转换
  • Ffplay:基于ffmpeg开源代码库libraries做的多媒体播放器
  • Ffprobe:基于ffmpeg做的多媒体流分析器

Ffmpeg 应该是 FFmpeg 工具集中最核心的利器,支持多种多样的编码器、解码器、封装格式、滤镜功能。FFmpeg框架的基本组成包含AVFormat、AVCodec、AVFilter、AVDevice、AVUtil等模块库,结构图如下:

  • AVFormat--FFmpeg的封装模块

AVFormat中实现了目前多媒体领域中的绝大多数媒体封装格式,包括封装和解封装,如MP4、FLV、KV、TS等文件封装格式,RTMP、RTSP、MMS、HLS等网络协议封装格式。FFmpeg是否支持某种媒体封装格式,取决于编译时是否包含了该格式的封装库。根据实际需求,可进行媒体封装格式的扩展,增加自己定制的封装格式,即在AVFormat中增加自己的封装处理模块。

  • AVCodec--FFmpeg的编解码模块

AVCodec中实现了目前多媒体领域绝大多数常用的编解码格式,即支持编码,也支持解码。AVCodec除了支持MPEG4、AAC、MJPEG等自带的媒体编解码格式之外,还支持第三方的编解码器,如H.264(AVC)编码,需要使用x264编码器;H.265(HEVC)编码,需要使用x264编码器;MP3(mp3lame)编码,需要使用libmp3lame编码器。如果希望增加自己的编码格式,或者硬件编解码,则需要在AVCodec中增加相应的编解码模块。

  • AVFilter--FFmpeg的滤镜模块

AVFilter库提供了一个通用的音频、视频、字幕等滤镜处理框架。在AVFilter中,滤镜框架可以有多个输入和多个输出。

  • swresample--FFmpeg的音频转换计算模块

swresample模块提供了高级别的音频重采样API。例如允许操作音频采样、音频通道布局转换与布局调整。

  • swscale--FFmpeg的视频图像转换计算模块

swscale模块提供了高级别的图像转换API,例如它允许进行图像缩放和像素格式转换,常见于将图像从1080p转换成720p或者480p等的缩放,或者将图像数据从YUV420p转换成YUYV,或者YUV转RGB等图像格式转换。

4 FFmpeg常用参数

4.1 能力集列表

  • -formats:列出支持的文件格式。
  • -codecs:列出支持的编解码器。
  • -decoders:列出支持的解码器。
  • -encoders:列出支持的编码器。
  • -protocols:列出支持的协议。
  • -bsfs:列出支持的比特流过滤器。
  • -filters:列出支持的滤镜。
  • -pix_fmts:列出支持的图像采样格式。
  • -sample_fmts:列出支持的声音采样格式。

4.2 常用输入选项

  • -i filename:指定输入文件名。
  • -f fmt:强制设定文件格式,需使用能力集列表中的名称(缺省是根据扩展名选择的)。
  • -ss hh:mm:ss[.xxx]:设定输入文件的起始时间点,启动后将跳转到此时间点然后开始读取数据。

对于输入,以下选项通常是自动识别的,但也可以强制设定。

  • -c codec:指定解码器,需使用能力集列表中的名称。
  • -acodec codec:指定声音的解码器,需使用能力集列表中的名称。
  • -vcodec codec:指定视频的解码器,需使用能力集列表中的名称。
  • -b:v bitrate:设定视频流的比特率,整数,单位bps。
  • -r fps:设定视频流的帧率,整数,单位fps。
  • -s WxH : 设定视频的画面大小。也可以通过挂载画面缩放滤镜实现。
  • -pix_fmt format:设定视频流的图像格式(如RGB还是YUV)。
  • -ar sample rate:设定音频流的采样率,整数,单位Hz。
  • -ab bitrate:设定音频流的比特率,整数,单位bps。
  • -ac channels:设置音频流的声道数目。

4.3 常用输出选项

  • -f fmt:强制设定文件格式,需使用能力集列表中的名称(缺省是根据扩展名选择的)。
  • -c codec:指定编码器,需使用能力集列表中的名称(编码器设定为"copy"表示不进行编解码)。
  • -acodec codec:指定声音的编码器,需使用能力集列表中的名称(编码器设定为"copy"表示不进行编解码)。
  • -vcodec codec:指定视频的编码器,需使用能力集列表中的名称(编解码器设定为"copy"表示不进行编解码)。
  • -r fps:设定视频编码器的帧率,整数,单位fps。
  • -pix_fmt format:设置视频编码器使用的图像格式(如RGB还是YUV)。
  • -ar sample rate:设定音频编码器的采样率,整数,单位Hz。
  • -b bitrate:设定音视频编码器输出的比特率,整数,单位bps。
  • -ab bitrate:设定音频编码器输出的比特率,整数,单位bps。
  • -ac channels:设置音频编码器的声道数目。
  • -an 忽略任何音频流。
  • -vn 忽略任何视频流。
  • -t hh:mm:ss[.xxx]:设定输出文件的时间长度。
  • -to hh:mm:ss[.xxx]:如果没有设定输出文件的时间长度的画可以设定终止时间点。

4.4 ffmpeg流标识

FFMPEG的某些选项可以对一个特定的媒体流起作用,这种情况下需要在选项后面增加一个流标识。流标识允许以下几种格式:

  • 流序号。譬如":1"表示第二个流。
  • 流类型。譬如":a"表示音频流,流类型可以和流序号合并使用,譬如":a:1"表示第二个音频流。
  • 节目。节目和流序号可以合并使用。
  • 流标识。流标识是一个内部标识号。

假如要设定第二个音频流为copy,则需要指定-codec:a:1 copy

4.5 ffmpeg音频选项

  • -aframes:等价于frames:a,输出选项,用于指定输出的音频帧数目。
  • -aq:等价于q:a,老版本为qscale:a,用于设定音频质量。
  • -atag:等价于tag:a,用于设定音频流的标签。
  • -af:等价于filter:a,用于设定一个声音的后处理过滤链,其参数为一个描述声音后处理链的字符串。

4.6 ffmpeg视频选项

  • -vframes:等价于frames:v,输出选项,用于指定输出的视频帧数目。
  • -aspect:设置宽高比,如4:3、16:9、1.3333、1.7777等。
  • -bits_per_raw_sample:设置每个像素点的比特数。
  • -vstats:产生video统计信息。
  • -vf:等价于filter:v,用于设定一个图像的后处理过滤链,其参数为一个描述图像后处理链的字符串。
  • -vtag:等价于tag:v,用于设定视频流的标签。
  • -force_fps:强制设定视频帧率。
  • -force_key_frames:显式控制关键帧的插入,参数为字符串,可以是一个时间戳,也可以是一个 "expr:"前缀的表达式。如"-force_key_frames 0:05:00"、"-force_key_frames expr:gte(t,n_forced*5)"

4.7 ffmpeg滤镜选项

-filter_simple 添加简单滤镜

-filter_complex FILTER 添加复杂滤镜

4.8 ffmpeg高级选项

  • -re:要求按照既定速率处理输入数据,这个速率即是输入文件的帧率。
  • -map:指定输出文件的流映射关系。例如 "-map 1:0 -map 1:1"要求将第二个输入文件的第一个流和第二个流写入到输出文件。如果没有-map选项,ffmpeg采用缺省的映射关系。

4.9 ffprobe参数

简单的说,ffprobe 是一个多媒体流分析工具。它从多媒体流中收集信息,并且以人类和机器可读的形式打印出来。它可以用来检测多媒体流的容器类型,以及每一个多媒体流的格式和类型。它可以作为一个独立的应用来使用,也可以结合文本过滤器执行更复杂的处理。

  • -f format 强制使用某种格式
  • -sexagesimal 时间单元格式化 HOURS:MM:SS.MICROSECONDS
  • -pretty 格式美化
  • -print_format format 格式化(可选值: default, compact, csv, flat, ini, json, xml)
  • -of format -print_format别名
  • -select_streams stream_specifier 选择指定流
  • -sections 打印节的结构和信息
  • -show_data 显示包数据
  • -show_data_hash 显示包数据哈希值
  • -show_error 显示文件探测/检测错误
  • -show_format 显示格式或者容器信息
  • -show_frames 显示帧信息
  • -show_format_entry entry 根据格式/容器信息显示指定entry
  • -show_packets 显示包信息
  • -show_programs 显示程序信息
  • -show_streams 显示流信息
  • -show_chapters 显示章节信息
  • -count_frames 统计每个流的帧数
  • -count_packets 统计每个流的包数
  • -show_program_version 显示ffprobe版本
  • -show_library_versions show library versions
  • -show_versions show program and library versions
  • -show_pixel_formats 显示像素格式
  • -show_private_data show private data
  • -private same as show_private_data
  • -bitexact force bitexact output
  • -read_intervals read_intervals set read intervals
  • -default generic catch all option

4.10 ffplayer参数

  • -x 强制设置视频显示窗口的宽度
  • -y 强制设置视频显示窗口的高度
  • -S 设置视频显示的宽高
  • -fs 强制全屏显示
  • -an 屏蔽音频
  • -vn 屏蔽视频
  • -Sn 屏蔽字幕
  • -ss 根据设置的秒进行定位拖动
  • -t 设置播放视频/音频长度
  • -Bytes 设置定位拖动的策略,0为不可拖动,1为可拖动,-1为自动
  • -Nodisp 关闭图形化显示窗口
  • -f 强制使用设置的格式进行解析
  • -window_title 设置显示窗口的标题
  • -af 设置音频的滤镜
  • -Codec 强制使用设置的codec进行解码
  • -autorotate 自动旋转视频
  • -ast 设置将要播放的音频流
  • -vst 设置将要播放的视频流
  • -sst 设置将要播放的字幕流
  • -Stats 输出多媒体播放状态
  • -Fast 非标准化规范的多媒体兼容优化
  • -sync 音视频同步设置可设置根据音频视频进行参考,视频时间参考,或者外部扩展时间进行参考
  • -autoexit 多媒体播放完毕自动退出ffplay,ffplay默认播放完毕不退出播放器
  • -exitonkeydown 当有按键按下事件产生时退出ffplay
  • -exitonmousedown 当有鼠标按键事件产生时退出ffplay
  • -loop 设置多媒体文件循环播放次数
  • -framedrop 当CPU资 源占用过高时,自动丢帧
  • -infbuf 设置无极限的播放器buffer,这个选项常见于实时流媒体播放场景
  • -vf 视频滤镜设置
  • -acodec 强制使用设置的音频解码器
  • -vcodec 强制使用设置的视频解码器
  • -scodec 强制使用设置的字幕解码器
相关推荐
嘟嘟实验室8 小时前
微信小程序xr-frame透明视频实现
微信小程序·ffmpeg·音视频·xr
泰勒朗斯12 小时前
如何编译Opencv +ffmpeg linux 明明安装了ffmpeg但是opencv就是找不到
linux·opencv·ffmpeg
-Mr_X-18 小时前
windows下srs流媒体服务器使用ffmpeg推流
ffmpeg
dvlinker19 小时前
C++开源项目 VLC 源代码的交叉编译以及库的裁剪方法详解
ffmpeg·mingw-w64·msys2·cygwin·开源vlc·vlc编译·vlc裁剪
因我你好久不见1 天前
springboot java ffmpeg 视频压缩、提取视频帧图片、获取视频分辨率
java·spring boot·ffmpeg
cuijiecheng20182 天前
音视频入门基础:MPEG2-TS专题(21)——FFmpeg源码中,获取TS流的视频信息的实现
ffmpeg·音视频
cuijiecheng20182 天前
音视频入门基础:AAC专题(13)——FFmpeg源码中,获取ADTS格式的AAC裸流音频信息的实现
ffmpeg·音视频·aac
流氓也是种气质 _Cookie2 天前
uniapp blob格式转换为video .mp4文件使用ffmpeg工具
ffmpeg·uni-app
网络安全queen2 天前
网络安全-企业环境渗透2-wordpress任意文件读&&FFmpeg任意文件读
安全·web安全·ffmpeg
yerennuo2 天前
FFmpeg库之ffmpeg
qt·ffmpeg