在编码之前,ffmpeg
可以使用libavfilter
库中的滤镜处理原始音频和视频帧。几个链式滤镜形成一个滤镜集。ffmpeg
区分了两种类型的滤镜:简单的和复杂的。
简单的滤镜是那些仅有一个输入和输出的,两者都是相同类型的。它们可以简单地在解码和编码之间插入额外的步骤:
_________ ______________
| | | |
| decoded | | encoded data |
| frames |\ _ | packets |
|_________| \ /||______________|
\ __________ /
simple _\|| | / encoder
filtergraph | filtered |/
| frames |
|__________|
简单的滤镜被配置为每流过滤器选项(分别用于视频和音频的-vf
和-af
别名)。例如,一个简单的视频滤镜图可以如下所示:
_______ _____________ _______ ________
| | | | | | | |
| input | ---> | deinterlace | ---> | scale | ---> | output |
|_______| |_____________| |_______| |________|
复杂滤镜是不能简单描述为一个应用于一个流的线性处理链的图。例如,当图形有多个输入和/或输出时,或者当输出流类型与输入不同时,就会出现这种情况。它们可以用以下图表表示:
_________
| |
| input 0 |\ __________
|_________| \ | |
\ _________ /| output 0 |
\ | | / |__________|
_________ \| complex | /
| | | |/
| input 1 |---->| filter |\
|_________| | | \ __________
/| graph | \ | |
/ | | \| output 1 |
_________ / |_________| |__________|
| | /
| input 2 |/
|_________|
复杂滤镜配置为-filter_complex
选项。请注意,此选项是全局的,因为复杂的Filtergram本质上不能明确地与单个流或文件相关联。-lavfi
选项等价于-filter_complex
。复杂过滤器的一个简单例子是覆盖过滤器,它有两个视频输入和一个视频输出,其中一个视频覆盖在另一个视频上。它的音频对应是amix
滤镜。
定义复杂的滤镜,即具有任意数量的输入和/或输出。对于简单滤镜,具有一个输入和一个输出,类型相同-请参阅-filter
选项。
输入链接标签必须使用[file_index:stream_specifier]
语法(即,与-map
使用相同)来引用输入流。如果stream_specifier
匹配多个流,则将使用第一个流。未标记的输入将连接到匹配类型的第一个未使用的输入流。
输出链接标签使用-map
引用.未标记的输出被添加到第一个输出文件中。请注意,使用此选项,可以只使用lavfi
源,而不需要正常的输入文件。
例如,要在视频上覆盖图像
ffmpeg -i video.mkv -i image.png -filter_complex '[0:v][1:v]overlay[out]' -map'[out]' out.mkv
这里[0:v]
指的是第一输入文件中的第一视频流,其链接到overlay滤镜的第一(主)输入。类似地,第二输入中的第一视频流链接到overlay
滤镜的第二输入。
假设每个输入文件中只有一个视频流,我们可以省略输入标签,因此上面的内容相当于
ffmpeg -i video.mkv -i image.png -filter_complex 'overlay[out]' -map'[out]' out.mkv
此外,我们可以省略输出标签,滤镜的单个输出将自动添加到输出文件中,因此我们可以简单地写成:
ffmpeg -i video.mkv -i image.png -filter_complex 'overlay' out.mkv
使用lavfi
颜色源生成5秒纯红色视频:
ffmpeg -filter_complex 'color=c=red' -t 5 out.mkv
将一个视频叠加在另一个视频上。它需要两个输入,并有一个输出。第一个输入主视频,第2个视频是覆盖物。、
它接受以下参数,所接受选项的描述如下:
在主视频上设置覆盖视频的x和y坐标。对于这两个表达式,默认值为“0”
。如果表达式无效,则将其设置为一个巨大的值(意味着覆盖将不会显示在输出视频的可见区域内)。
设置输出视频的格式。它接受以下值:
force YUV420 output
force YUV422 output
force YUV444 output
force packed RGB output
force planar RGB output
automatically pick format
Default value is yuv420
.
The x, and y expressions can contain the following parameters:
主输入宽度和高度。
覆盖输入的宽度和高度。
举例:
在主视频右下角的10个像素处绘制覆盖:
overlay=main_w-overlay_w-10:main_h-overlay_h-10
使用命名选项,上面的示例如下:
overlay=x=main_w-overlay_w-10:y=main_h-overlay_h-10
在输入的左下角插入一个透明的png logo,使用ffmpeg工具的-filter_Complex选项:
ffmpeg -i input -i logo -filter_complex 'overlay=10:main_h-overlay_h-10' output
使用ffmpeg工具插入2个不同的透明PNG logo(第2个logo在右下角):
ffmpeg -i input -i logo1 -i logo2 -filter_complex 'overlay=x=10:y=H-h-10,overlay=x=W-w-10:y=H-h-10' output
从时间2开始,从屏幕的左侧到右顶部开始显示跑马灯效果覆盖:
overlay=x='if(gte(t,2), -w+(t-2)*20, NAN)':y=0
使用libswscale
库缩放(调整大小)输入视频。scale
滤镜通过改变输出采样宽高比,迫使输出显示宽高比与输入相同。如果输入图像格式不同于下一个滤镜所请求的格式,则scale
滤镜将输入转换为所请求的格式。
该滤镜接受以下选项,或libswscale scaler支持的任何选项。有关scaler选项的完整列表,请参见(FFmpeg-scaler)FFmpeg-scaler手册。
设置输出视频尺寸表达式。默认值是输入的尺寸。
w和h选项的值是包含以下常量的表达式:
输入的宽高
输入的宽高
指定输出的缩放后的宽高
输入样本高宽比
输入显示高宽比。根据(iw/ih)*sar
计算。
水平和垂直输入色度子采样值。例如,对于像素格式"yuv422p"
hsub
为2,vsub
为1。
水平和垂直输出色度子采样值。例如,对于像素格式"yuv422p"
hsub
为2,vsub
为1。
举例:
将输入视频缩放至200x100的大小
scale=w=200:h=100
这相当于:
scale=200:100
或者:
scale=200x100
指定输出大小的大小缩写:
scale=qcif
QCIF是常用的标准化图像格式,意为四分之一公共中间格式(Quarter Common Intermediate Format)。在H.323协议簇中,规定了视频采集设备的标准采集分辨率。CIF = 352×288
像素,规定了视频采集设备的标准采集分辨率。QCIF = 176×144
像素
其也可以写成:
scale=size=qcif
将输入扩大到2倍:
scale=w=2*iw:h=2*ih
如同下面:
scale=2*in_w:2*in_h
按强制隔行缩放比例缩放输入到2X:
scale=2*iw:2*ih:interl=1
将输入缩放到一半大小:
scale=w=iw/2:h=ih/2
增加宽度,并将高度设置为相同大小:
scale=3/2*iw:ow
Seek Greek harmony:
scale=iw:1/PHI*iw
scale=ih*PHI:ih
增加高度,并将宽度设置为高度的3/2:
scale=w=3/2*oh:h=3/5*ih
增大尺寸,使其尺寸成为色度子采样值的倍数:
scale="trunc(3/2*iw/hsub)*hsub:trunc(3/2*ih/vsub)*vsub"
将宽度增加到最大500像素,保持与输入相同的宽高比:
scale=w='min(500\, iw*3/2):h=-1'
通过合并scale和setsar制作像素正方形:
scale='trunc(ih*dar):ih',setsar=1/1
通过合并scale和setsar制作像素正方形,确保得到的分辨率均匀(某些编解码器需要):
scale='trunc(ih*dar/2)*2:trunc(ih/2)*2',setsar=1/1
使用libfreetype
库从视频顶部的指定文件中绘制文本字符串或文本。要启用此滤镜的编译,需要 --enable-libfreetype
配置ffmpeg。要启用默认字体回退和字体选项,需要使用--enable-libfontconfig
配置ffmpeg。要启用text_shaping
选项,您需要使用 --enable-libfribidi
配置ffmpeg。
它接受以下参数:
Used to draw a box around text using the background color.
The value must be either 1 (enable) or 0 (disable). The default value of box is 0.
用于使用背景颜色绘制围绕文本的框。该值必须为1(启用)或0(禁用)。框的默认值为0。
Set the width of the border to be drawn around the box using boxcolor. The default value of boxborderw is 0.
设置边框的宽度。boxborderw
的默认值为0。
The color to be used for drawing box around text.
For the syntax of this option, check the (ffmpeg-utils)"Color" section in the ffmpeg-utils manual.
The default value of boxcolor is "white".
用于在文本周围绘制框的颜色。对于此选项的语法,请参考FFmpeg-utils手册中的(FFmpeg-utils)“Color"部分。boxcolor的默认值为”白色
"。
Set the line spacing in pixels of the border to be drawn around the box using box.
The default value of line_spacing is 0.
Set the width of the border to be drawn around the text using bordercolor. The default value of borderw is 0.
设置要在文本周围绘制的边框宽度。borderw的默认值为0。
设置用于绘制文本周围边框的颜色。有关此选项的语法,请检查ffmpeg-utils手册中的(ffmpeg-utils)“color”部分。边框颜色的默认值是“black
”。
选择文本的展开方式。可以是none
、strftime(已弃用)或normal
(默认)。有关详细信息,请参见下面的文本扩展部分。
Set a start time for the count. Value is in microseconds. Only applied in the deprecated strftime expansion mode.
To emulate in normal expansion mode use the pts function,
supplying the start time (in seconds) as the second argument.
如果为true
,检查并修复text
坐标,以避免裁剪。
用于绘制字体的颜色。对于此选项的语法,请检查FFmpeg-utils手册中的(FFmpeg-utils)“Color"部分。fontcolor
的默认值为”black
"。
字符串,其展开方式与文本相同,以获得动态字体颜色值。默认情况下,此选项具有空值,且未处理。设置此选项时,它将覆盖fontcolor
选项。
用于绘制文本的字体系列。默认情况下没有。
要用于绘制文本的字体文件。必须包含路径。如果fontconfig
支持被禁用,此参数是必需的。
绘制应用alpha
混合的文本。值可以是介于0.0
和1.0
之间的数字。表达式也接受相同的变量x,y
。默认值为1
。请参阅fontcolor_expr
。
用于绘制文本的字体大小。fontsize
的默认值为16
。
如果设置为1,则尝试在绘制文本之前对文本进行形状改变(例如,反转右到左文本的顺序并连接阿拉伯字符)。否则,只需按给定的方式绘制文本即可。默认情况下1(如果支持)。
用于加载字体的标志。这些标志映射了libfreetype支持的相应标志,它们是以下值的组合:
default
no_scale
no_hinting
render
no_bitmap
vertical_layout
force_autohint
crop_bitmap
pedantic
ignore_global_advance_width
no_recurse
ignore_transform
monochrome
linear_design
no_autohint
默认值为"default"。有关详细信息,请查阅 FT_LOAD_* libfreetype flags.的文档。
绘制文本后面的阴影的颜色。对于此选项的语法,请检查FFmpeg-utils手册中的(FFmpeg-utils)“Color"部分。shadowcolor
的默认值为”black
"。
相对于文本的位置,文本阴影位置的x
和y
偏移。它们可以是正值,也可以是负值。两者的默认值都是“0
”。
n/frame_num
变量的起始帧编号。默认值为"0
"。
The size in number of spaces to use for rendering the tab. Default value is 4.
以“hh:mm:ss[:;.]ff
”格式设置初始时间码表示形式。它可以与文本参数一起使用,也可以不使用文本参数。必须指定timecode_rate
选项。
Set the timecode frame rate (timecode only). Value will be rounded to nearest integer.
Minimum value is "1". Drop-frame timecode is supported for frame rates 30 & 60.
设置时间码帧率(仅时间码)。值将四舍五入到最近的整数。最小值是"1
"。
If set to 1, the output of the timecode option will wrap around at 24 hours. Default is 0 (disabled).
要绘制的文本字符串。文本必须是UTF-8
编码字符的序列。如果没有使用参数textfile
指定文件,则此参数是必需的。
包含要绘制文本的文本文件。文本必须是utf-8
编码字符的序列.如果参数text
没有指定文本字符串,则此参数是必须的。如果同时指定了text
和textfile
,则会引发错误。
如果设置为1
,textfile
将在每个帧之前重新加载。确保原子地更新它,否则它可能被部分读取,甚至失败。
指定将在视频帧中绘制文本的偏移量的表达式。它们相对于输出图像的上/左
边界。x
和y
的默认值为“0
”。有关接受的常量和函数的列表,请参见下面。x
和y
的参数是包含下列常量和函数的表达式:
输入显示宽高比,与(w/h)*sar
相同。
输入样本宽高比。
水平和垂直色度子样本值。例如,对于像素格式“yuv422p
”,hsub
为2,vsub
为1。
每一行文字的高度。
输入高度
输入宽度
输入的帧数,从0
开始
返回包含在最小值和最大值之间的随机数
timestamp expressed in seconds, NAN if the input timestamp is unknown
时间戳以秒表示,如果输入时间戳为unknown
,则表示为NAN
,not a number
文本的高度
文本的宽度。
绘制文本的x
和y
偏移坐标。这些参数允许x
和y
表达式相互引用,因此您可以指定y=x/dar
。
当前帧的图片类型的一个字符描述。
当前数据包packet
在输入文件或流中的位置(以字节为单位,从输入的开始)。值为-1
表示此信息不可用。
当前数据包packet的持续时间,以秒为单位。
当前数据包 packet的大小(以字节为单位)。
用字体FreeSerif绘制“Test Text”,使用可选参数的默认值。
drawtext="fontfile=/usr/share/fonts/truetype/freefont/FreeSerif.ttf: text='Test Text'"
在位置x=100和y=50(从屏幕左上角开始计数)时,用FreeSerif 字体绘制“Test Text”,文本为黄色,周围有红色框。文本和框的不透明度均为20%。
drawtext="fontfile=/usr/share/fonts/truetype/freefont/FreeSerif.ttf: text='Test Text':\
x=100: y=50: fontsize=24: [email protected]: box=1: [email protected]"
请注意,如果参数列表中不使用空格,则不需要双引号。在视频帧的中心显示文本:
drawtext="fontsize=30:fontfile=FreeSerif.ttf:text='hello world':x=(w-text_w)/2:y=(h-text_h)/2"
在随机位置显示文本,每隔30秒切换到新位置:
drawtext="fontsize=30:fontfile=FreeSerif.ttf:text='hello world':x=if(eq(mod(t\,30)\,0)\,
rand(0\,(w-text_w))\,x):y=if(eq(mod(t\,30)\,0)\,rand(0\,(h-text_h))\,y)"
在视频帧的最后一行中显示从右向左滑动的文本行,
drawtext="fontsize=15:fontfile=FreeSerif.ttf:text=LONG_LINE:y=h-line_h:x=-50*t"
从视频帧底部显示文件CREDITS 的内容并向上滚动。
drawtext="fontsize=20:fontfile=FreeSerif.ttf:textfile=CREDITS:y=h-20*t"
在输入视频的中心绘制一个绿色字母"g"。将文字基线放置在屏幕高度的一半。
drawtext="fontsize=60:fontfile=FreeSerif.ttf:fontcolor=green:text=g:x=(w-max_glyph_w)/2:y=h/2-ascent"
每3秒显示文本1秒:
drawtext="fontfile=FreeSerif.ttf:fontcolor=white:x=100:y=x/dar:enable=lt(mod(t\,3)\,1):text='blink'"
使用fontconfig设置字体。请注意,冒号需要转义。
drawtext='fontfile=Linux Libertine O-40\:style=Semibold:text=FFmpeg'
打印实时编码的日期(参见strftime(3)):
drawtext='fontfile=FreeSans.ttf:text=%{localtime\:%a %b %d %Y}'
文本淡入淡出(出现/消失):
#!/bin/sh
DS=1.0 # display start
DE=10.0 # display end
FID=1.5 # fade in duration
FOD=5 # fade out duration
ffplay -f lavfi "color,drawtext=text=TEST:fontsize=50:fontfile=FreeSerif.ttf:fontcolor_expr=ff0000%
{eif\\\\: clip(255*(1*between(t\\, $DS + $FID\\, $DE - $FOD) + ((t - $DS)/$FID)*between(t\\, $DS\\, $DS + $FID)
+ (-(t - $DE)/$FOD)*between(t\\, $DE - $FOD\\, $DE) )\\, 0\\, 255) \\\\: x\\\\: 2 }"
水平对齐多个单独的文本。请注意,max_glyph_a和字体大小值包含在y偏移量中。
drawtext=fontfile=FreeSans.ttf:text=DOG:fontsize=24:x=10:y=20+24-max_glyph_a,
drawtext=fontfile=FreeSans.ttf:text=cow:fontsize=24:x=80:y=20+24-max_glyph_a
本文将持续更新,敬请关注
Github:https://github.com/AnJiaoDe
CSDN:https://blog.csdn.net/confusing_awakening
OpenCV入门教程:https://blog.csdn.net/confusing_awakening/article/details/113372425
ffmpeg入门教程:https://blog.csdn.net/confusing_awakening/article/details/102007792
微信公众号
QQ群