探索 FFmpeg Basics 音视频技术(23): 先进的技术点

这个系列文章我们来介绍一位海外工程师如何探索 FFmpeg Basics 音视频技术,对于想要开始学习音视频技术的朋友,这些文章是份不错的入门资料,这是第 23 篇:FFmpeg  先进的技术点。

—— 来自公众号“关键帧Keyframe”的分享

1、加入音频和视频文件

有几种方法可以加入媒体文件,它们在下表中描述:

类型描述针对音频针对视频
级联编码文件一个接一个;第一个结束,第二个开始
合并将所有音频流编码为一个,例如两个单声道到一个立体声
混合将两个或更多音频通道编码为一个,音量可以调节
多路复用 (mux)将两个或更多文件编码为一个,例如一个音频和一个视频文件,如果存在更多相同类型的流,则由用户选择
覆盖 / 画中画 (PiP)两个或更多视频一次显示在另一个旁边或一个在另一个之上

2、连接与 shell 命令

媒体文件连接的先决条件:

特殊文件格式连接只能是某些文件格式:
音频 – MP3(第二个文件的头部将消失),未压缩的如 WAV, PCM 等,视频 – MPEG-1, MPEG-2 TS, DV
格式的一致性所有连接的文件都是相同的格式,这意味着可以连接两个 MP3 文件,但一个 MP3 和一个 WAV 文件不能连接
流的一致性所有连接文件:
– 包含相同数量的每种类型的流。
– 音频流使用相同的编解码器、采样率和通道布局
– 视频流使用相同的分辨率

为符合此要求,通常需要转换输入文件,使用 -q 1或类似选项以保持初始质量,详细信息请参阅 格式间转换。

在 Windows 上,可以使用带有 /B标志的复制命令来指示二进制模式,在文件之间必须是一个加号。连接 N 个文件的复制命令的一般形式是:

copy /B file1+file2+...+fileN-1+fileN outputFile

例如,连接文件 videoclip1.mpg和 videoclip2.mpg到文件 video.mpg,可以使用以下命令:

copy /B videoclip1.mpg+videoclip2.mpg video.mpg

在 Linux、Unix 和 OS X 上,可以使用 cat命令,形式如下:cat file1 file2 > file3,因此可以修改前面的例子:

cat videoclip1.mpg videoclip2.mpg > video.mpg

3、使用 concat 协议进行连接

另一种选择是使用 concat 协议,其先决条件与复制命令类似。例如,要使用该协议修改前面的例子,可以使用以下命令:

ffmpeg -i concat:"videoclip1.mpg|videoclip2.mpg" -c copy video.mpg

4、使用 concat 滤镜进行连接

用于音频和视频拼接的特殊滤镜是 concat 滤镜,描述如下:

描述连接音频和视频文件一个接一个。该滤镜适用于同步视频和音频流的片段(文件),所有片段必须具有相同数量的每种类型的流,例如 1 个音频和 1 个视频,或 2 个音频和 1 个视频等
语法concat=a=a_streams:v=v_streams:n=segments[:unsafe]
所有参数都是可选的
参数描述
a输出音频流的数量,默认值为 0
n段数,默认值为 2
unsafe激活安全模式,如果设置,连接将不会因不同格式的片段而失败
v输出视频流的数量,默认值为 1

适当筛选结果的先决条件:

  • 所有段必须从时间戳 0 开始。
  • 相应的流必须在所有段中使用相同的参数,特别是视频大小。
  • 建议使用相同的帧速率,否则输出将使用可变帧速率。

concat滤镜可以连接各种格式,一些示例如下:

ffmpeg -i input1.avi -i input2.avi -filter_complex concat output.avi
ffmpeg -i input1.avi -i input2.avi -filter_complex concat output.mp4
ffmpeg -i input1.avi -i input2.mp4 -filter_complex concat output.webm
ffmpeg -i input1.avi -i input2.mp4 -i input3.mkv -filter_complex ^ concat=n=3 output.flv
ffmpeg -i input1.avi -i input2.avi -i input3.avi -i input4.avi ^ -filter_complex concat=n=4 output.mp4
ffmpeg -i 1.avi -vf movie=2.avi[a];[in][a]concat a.mp4

5、其他类型的拼接技术

  • 音频合并(多个流到一个多声道流) – 在 数字音频 一章中介绍
  • 将几个音频文件混合到一个 – 在 数字音频 一章中有描述
  • 多路复用 – 在 “FFmpeg 基本介绍” 一章中介绍了媒体流的选择
  • overlay – 在 overlay – 画中画 章节里面有具体的描述。

6、移除 logo

一些视频包含公司标志,通常位于左上角,常见示例是录制的电视节目。FFmpeg 包含两个特殊滤镜以去除徽标,虽然最终效果并不总是完美,但在许多情况下这种去除 logo 的技术还是可以接受的。

7、delogo 滤镜

描述通过对周围像素的简单插值来隐藏电视台的标志。用户设置一个覆盖该徽标的矩形,它通常会消失(但在某些情况下,标识更明显)。滤镜接受参数作为字符串形式的 “x:y:w:h:band” 或以 “:” 分隔的键 = 值对列表
语法delogo=x=0:y=0:w=width:h=height[:t=band:show={0,1}]
方括号中的参数是可选的,显示为 0 或 1
参数描述
x, y标志的左上角坐标
w, h标志的宽度和高度
band 或 t标志矩形的模糊边缘厚度,默认值为 4
show定位参数,默认值为 0。如果设置为 1,屏幕上会显示绿色矩形,帮助找到正确的 x、y、w 和 h 参数

例如,首先从下图所示的 800×600 像素视频的右上角移除标志,我们通过显示绿色矩形的显示选项来估计标志的位置:

ffmpeg -i eagles.mpg -vf delogo=x=700:y=0:w=100:h=50:t=3:show=1 nologo.mpg

现在我们可以精确地指定位置,标志的存在几乎不可见:

ffmpeg -i eagles.mpg -vf delogo=x=730:y=0:w=70:h=46:t=1 nologo.mpg
探索 FFmpeg Basics 音视频技术(23): 先进的技术点

8、抖动视频部分的固定

没有三脚架或车辆拍摄的视频的一些部分通常包括抖动 – 水平和垂直移动的小变化,在某些情况下可以使用去抖滤波器进行修正:

描述修正水平和垂直位移的小变化,当视频没有三脚架或移动车辆时有用
语法deshake=x:y:w:h:rx:ry:edge:blocksize:contrast:search:filename
所有参数都是可选的
参数描述
x, y, w, h矩形区域的坐标和大小,用于搜索运动向量。x 和 y 是左上角的坐标,w 是宽度,h 是高度。这些参数与 drawbox 滤镜具有相同的含义,可用于可视化边界框的位置。当物体在框架内同时运动时,运动矢量搜索可能会混淆摄像机的运动,这是很有用的。如果 x、y、w 和 h 都设为 -1,则使用整个框架。这允许在不指定运动矢量搜索的边界框的情况下设置后续选项。默认情况下,搜索整个框架。
rx, ry在 0 – 64 像素范围内指定 x 和 y 方向的最大运动范围,默认值为 16
edge指定如何生成像素以填充框架边缘的空白,值为 0 到 3 的整数:
0 – 在空白位置填充零
1 – 原始图像在空白位置
2 – 在空白位置挤压边值
3 – 镜像边缘在空白位置,默认值
blocksize指定用于运动搜索的块大小,值为 4 – 128 像素,默认值为 8
contrast指定块的对比度阈值。只有超过指定对比度的块(最黑和最亮像素之间的差异)才会被考虑。值来自 1 – 255 范围,默认值为 125
search指定搜索策略:
0 = 彻底搜索,默认值
1 = 不彻底搜索
filename如果包含,则将动作搜索的详细日志写入指定的文件

参数可以按默认顺序输入或以任何顺序指定名称:

ffmpeg -i travel.avi -vf deshake fixed_travel.avi
ffmpeg -i travel.avi -vf deshake=contrast=160 fixed.avi
ffmpeg -i travel.avi -vf deshake=blocksize=4:filename=log.txt fixed.avi

9、将颜色框添加到视频

使用 drawbox,我们可以在矩形区域找到精确的坐标,以在其中搜索运动矢量,它用于除雾滤镜。其他用途包括各种图表、方案等。

描述在输入的选定区域绘制指定颜色和指定大小的框
语法drawbox[=x:y:width:height:color:thickness]
参数描述
color, c标准颜色名称或十六进制值,格式为 0xRRGGBB[AA]
height, h框的高度,默认值为 0
thickness, t边框边缘的宽度(以像素为单位),默认值为 4
width, w框的宽度,默认值为 0
x, y框的左上角坐标,默认值为 0

例如,要在 SVGA 大小的输入上添加一个尺寸为 600×400 像素的黄色框,其位置为左侧 150 像素和顶部 0 像素,可以使用以下命令:

ffmpeg -i ship.avi -vf drawbox=x=150:w=600:h=400:c=yellow ship1.avi
探索 FFmpeg Basics 音视频技术(23): 先进的技术点

10、检测帧数

如果您需要知道视频文件中有多少帧,可以使用以下命令:

ffmpeg -i input.mpg -f null /dev/null

显示输出的最后两行是:

frame= 250 fps=0.0 q=0.0 Lsize= 0kB time=00:00:10.00 bitrate= 0.0kbits/s
video:16kB audio:0kB subtitle:0 global headers:0kB muxing overhead -100.000000%

帧数为 250,表示视频帧的总数,也可以从帧速率和持续时间计算得出,但结果并不总是准确。

11、检测广告、部分转换或损坏的编码

从电视、互联网等录制的较长视频可能包含带有广告、转场、不完整帧和其他不需要内容的短片。如果这些部分包含黑帧,则可以使用下表中描述的黑帧检测滤镜进行检测。

描述检测几乎全黑的视频部分,并输出包含检测到的黑场间隔的开始、结束和持续时间的行(以秒为单位)。如果日志级别设置为低于 AV_LOG_INFO值,则不显示行
语法blackdetect[=d=duration:pic_th=pbr_threshold:pix_th=px_threshold]

参数描述(所有参数都是可选的)

参数名称单位描述默认值
black_min_duration, d正浮点数,确定视频中黑帧的最小持续时间2.0
picture_black_ratio_th, pic_th浮点数(0 到 1.0 之间)例如,如果帧大小为 400×300(总共 12 万像素),有 12000 像素不是黑色,则此比例为 0.90.98
pixel_black_th, pix_th浮点数(0 到 1.0 之间)用于确定像素是否为黑色的阈值,计算公式为:
(绝对阈值 – 亮度最小值) / 亮度范围大小
0.1

例如,要从源 mptestsrc中检测黑帧,命令如下(控制台输出如下):

ffmpeg -f lavfi -i mptestsrc -vf blackdetect -f sdl 'test'
探索 FFmpeg Basics 音视频技术(23): 先进的技术点

12、使用黑帧滤镜进行检测

另一个用于检测黑帧的滤镜是黑帧滤镜,描述如下:

描述检测几乎为黑色的帧,并输出以下内容:
– 检测帧的帧数
– 黑色部分的百分比
– 如果已知则在文件中定位,否则为 -1
– 时间戳
语法blackframe[=amount:[threshold]]
所有参数都是可选的
参数
amount阈值下的像素百分比,默认值为 98
threshold认为是黑色的像素阈值,默认值为 32

blackdetect和 blackframe滤镜类似,但显示的信息不同。下图显示了使用与黑场检测滤镜相同的视频源的黑帧滤镜输出:

ffmpeg -f lavfi -i mptestsrc -vf blackframe -f sdl 'test'

13、选择特定帧进行输出

特殊的多媒体滤镜可以选择音频并启用视频选择,以精确指定哪些帧将被保留,哪些将从输出中排除。

描述通过评估每个输入帧的表达式来选择输出帧。如果表达式的值非零,则选择该帧,否则跳过该帧
语法select=expression
表达式的默认值为 1
参数描述
n从 0 开始的过滤帧的连续编号
selected_n从 0 开始的选择帧的序列号
prev_selected_n如果未定义,则为最后一个选择帧的序列号(NAN)
TB输入时间戳的时基
pts过滤后的视频帧的表示时间戳(以 TB 为单位);如果未定义,则为 NAN
t过滤后的视频帧的表示时间戳(以秒为单位);如果未定义,则为 NAN
prev_pts前一个过滤视频帧的表示时间戳;如果未定义,则为 NAN
prev_selected_pts上一个选择的视频帧的表示时间戳;如果未定义,则为 NAN
prev_selected_t上一个选择的视频帧的时间戳;如果未定义,则为 NAN
start_pts视频中第一个视频帧的时间戳;如果未定义,则为 NAN
start_t视频中第一个视频帧的时间;如果未定义,则为 NAN
pict_type(仅限视频)过滤帧的类型,可以是以下值之一:
I … 帧内预测帧,P … 前向预测帧,B … 双向预测帧,S … 切换帧,SI … 切换 I 帧,SP … 切换 P 帧,BI … 特殊帧内帧(不是关键帧,VC-1 视频编解码器)
interlace_type(仅限视频)帧的隔行类型,可以是以下值之一:
PROGRESSIVE, TOPFIRST, BOTTOMFIRST
PROGRESSIVE帧是逐行的(非隔行的)
TOPFIRST帧是顶场优先
BOTTOMFIRST帧是底场优先
key如果过滤后的帧是关键帧,则为 1,否则为 0
pos过滤帧在文件中的位置;如果信息不可用(例如合成视频)或没有意义,则为 -1
scene(仅限视频)0 到 1 之间的值,表示一个新的场景;低值表示当前帧引入新场景的概率低,而高值表示当前帧更可能是新场景
consumed_sample_n在当前帧之前选择的样本数量
samples_n当前帧中的样本数量
sample_rate输入采样率

由于 select 表达式的默认值为 1,以下两个示例使用的 select 滤镜将产生相同的结果 —— 所有帧都将被选择为输出(值为 0 则不会选择任何帧):

ffmpeg -i input.avi -vf select output.avi
ffmpeg -i input.avi -vf select=1 output.avi

要选择 20 到 25 秒的部分,可以使用以下命令:

ffmpeg -i input.avi -vf select="gte(t\,20)*lte(t\,25)" output.avi

若要选择仅帧内输出,可以使用以下命令:

ffmpeg -i input.avi -vf select="eq(pict_type\,I)" output.avi

14、通过改变纵横比来缩放输入

调整和伸缩视频章节描述了用于缩放视频帧的缩放滤镜。另一种方法是使用改变显示宽高比(DAR)和样本宽高比(SAR)的 setdar 和 setsar 滤镜,它们的关系用公式表示(关于宽高比的详细信息,请参阅词汇表):

描述setdar 滤镜设置显示纵横比,setsar 设置样本纵横比
语法setdar[=r=aspect_ratio[:max=number]]
setdar[=aspect_ratio[:number]]
参数描述
r, ratio纵横比,可以是浮点数或表达式,默认值为 0
max在将纵横比设置为有理数时,表示分子和分母的最大整数值,默认值为 100

使用 setdar 和 setsar 滤镜的示例:

ffplay -i input.avi -vf setdar=r=16/9
ffplay -i input.avi -vf setdar=16/9
ffplay -i input.avi -vf setsar=r=1.234
ffplay -i input.avi -vf setsar=1.234

15、屏幕抓取

为了将显示输出记录到视频文件中(例如创建教程),我们可以使用安装了 UScreenCapture 直接显示源过滤器的 dshow 输入设备,下载地址如下:

http://www.umediaserver.net/bin/UScreenCapture.zip

为了捕获整个屏幕内容,可以使用以下命令:

ffmpeg -f dshow -i video="UScreenCapture" -t 60 screen.mp4

如果我们想捕获特定的屏幕区域,必须使用 regedit Windows 工具来修改某些注册表项。更多信息可以在下载的 UScreenCapture.zip 包中的 README 文件中找到。

16、视频帧的详细信息

为了显示每个视频帧的信息,可以使用下表中描述的 showinfo 滤镜:

描述显示包含每个输入视频帧信息的行,数据采用键:值对的形式。该滤镜没有参数,应与 -report 选项一起使用
语法-vf showinfo
参数描述
n输入帧的序号,从 0 开始
pts输入帧的表示时间戳,以时间基为单位;时间基取决于过滤器输入
pts_time输入帧的表示时间戳,以秒为单位
pos输入流中帧的位置;如果信息不可用或没有意义(例如合成视频)
fmt像素格式名称
sar输入帧的采样宽高比,表示为分子 / 分母
s输入帧的大小,表示为宽 * 高
i隔行模式:P 表示逐行,T 表示顶场优先,B 表示底场优先
iskey如果经过滤波的帧是关键帧,则为 1,否则为 0
type输入帧的图像类型:I 代表 I 帧,P 代表 P 帧,B 代表 B 帧,? 表示未知类型(更多详细信息请参阅 AVPictureType 枚举的文档)
consumed_sample_n在当前帧之前选择的样本数量
samples_n当前帧中的样本数量
sample_rate输入采样率

例如,以下命令将生成包含前三行的打印信息:

ffmpeg -report -f lavfi -i testsrc -vf showinfo -t 10 showinfo.mpg

n:0 pts:0 pts_time:0 pos:-1 fmt:rgb24 sar:1/1 s:320x240 i:P iskey:1 type:I checksum:88C4D19A plane_checksum:[88C4D19A]
n:1 pts:1 pts_time:0.04 pos:-1 fmt:rgb24 sar:1/1 s:320x240 i:P iskey:1 type:I checksum:C4740AD1 plane_checksum:[C4740AD1]
n:2 pts:2 pts_time:0.08 pos:-1 fmt:rgb24 sar:1/1 s:320x240 i:P iskey:1 type:I checksum:B6DD3DEB plane_checksum:[B6DD3DEB]

17、音频频谱

为了使音频频谱可视化,可以使用下表中描述的 showspectrum 滤镜:

描述将音频输入转换为视频输出
语法showspectrum[=s=widthxheight[:slide=number]]
参数描述
size, s输出视频大小,默认为 640×480
slide设置频谱是否沿窗口滑动,默认值为 0

例如,以下命令创建音频频谱:

ffmpeg -i audio.mp3 -vf showspectrum audio_spectrum.mp4
探索 FFmpeg Basics 音视频技术(23): 先进的技术点

18、音频波形可视化

描述将输入音频转换为包含音频波表示的视频
语法showwaves[=n=number[:r=rate[:s=video_size]]]
参数描述
n在同一列中打印的样本数量;较大的值会降低帧速率,因此不能与速率参数结合使用
rate, r帧速率,默认为 25,不能与 n 参数组合使用
size, s视频大小,默认为 640×480

来自音频输入的波形可以通过下表中描述的 showwaves 滤镜进行可视化:

描述将输入音频转换为包含音频波表示的视频
语法showwaves[=n=number[:r=rate[:s=video_size]]]
参数描述
n在同一列中打印的样本数量;较大的值会降低帧速率,因此不能与速率参数结合使用
rate, r帧速率,默认为 25,不能与 n 参数组合使用
size, s视频大小,默认为 640×480

例如,要将 music.mp3文件中的波形可视化为 waves.mp4文件,可以使用以下命令:

ffmpeg -i music.mp3 -vf showwaves waves.mp4

19、语音合成

  • 没有 Windows 环境,下面的没测试,不过 AVFoundation 做这个相当简单,想了解 AVFounadtion 怎么实现的点击这里

通过包含 libflite 外部库,可以使用来自 Flite(Festival Lite)的语音合成,Flite 是一种小型可嵌入的 TTS(文本到语音)引擎。它由美国卡内基梅隆大学的 CMU Speech Group 开发。Flite 完全用 C 语言编写,重新实现了 Festival 架构的核心部分,以确保为每个系统设计的声音之间的兼容性。爱丁堡大学的 Festival 语音合成系统是构建语音合成系统的框架。有关 Flite 的更多详细信息,请访问 http://www.speech.cs.cmu.edu/flite

描述由于其大尺寸,使用未包含在官方 Windows 二进制文件中的 libflite 库来合成具有选定语音类型的人类语音
语法flite=”text”[:v=voice[:n=n_samples]]
flite=textfile=filename[:v=voice[:n=n_samples]]
参数描述
list_voices如果设置为 1,则显示可用语音列表
n, nb_samples每帧的最大采样数,默认值为 512
text演讲的源文本
textfile包含文本的文件名
v, voice可用的声音:女 – slt,男 – awb,kal,kal16,rms;默认语音为 kal,其采样率(频率)为 8000 Hz,其他语音使用 16000 Hz

由于 flite 库使 ffmpeg.exe 文件增加了 10 MB 以上,因此它不在官方二进制文件中。Windows 二进制文件可以从 http://ffmpeg.tv/flite.php 下载(Linux 和 OS X 用户可以编译它们)。要显示可用语音列表,可以使用以下命令:

ffmpeg -f lavfi -i flite=list_voices=1

要让计算机使用女性声音从 Message.txt文件中读取文本,命令如下:

ffplay -f lavfi -i flite=textfile=Message.txt:v=slt

例如,要将文本 “Happy New Year to all” 保存到 wish.wav文件中,可以使用以下命令:

ffmpeg -f lavfi -i flite=text="Happy New Year to all":v=kal16 wish.wav

如果我们想减慢讲话速度以获得更好的听力,可以使用以下命令:

ffmpeg -f lavfi -i flite=textfile=text.txt -af atempo=0.5 speech.mp3

20、一次将输出保存为多种格式

虽然从第一章中解释的命令语法可以清楚地看出,但也可以通过一个命令将处理结果保存为多种格式。例如,可以将 Flite 语音引擎的输出保存为 MP3、WAV 和 WMA 格式在一个命令中:

ffmpeg -f lavfi -i flite=textfile=speech.txt speech.mp3 speech.wav speech.wma

还可以组合音频和视频格式。如果为视频输入指定音频格式,则只包含音频流。下一个示例中的 clip.mp3文件只包含音频流:

ffmpeg -i clip.avi clip.flv clip.mov clip.mp3 clip.mp4 clip.webm
探索 FFmpeg Basics 音视频技术(23): 先进的技术点

21、额外的媒体输入到 filtergraph

默认情况下,在任何具有 -i 选项的过滤器之前指定输入文件,并且第一个输入在带有 [in] 链接标签的过滤器图中可用。如果我们想要过滤额外的文件,我们可以使用 amovie 源作为视频文件的音频和电影源,它们在下表中描述:

描述从媒体(电影)容器读取音频和/或视频流。必需的参数是媒体文件的文件名,可选的键 = 值对由冒号分隔
语法movie=video_name[:options]
amovie=audio_name[:options]
可用的键 = 值选项参数
f, format_name视频容器或输入设备的格式,如果未指定,则从扩展名确定或探测
loop按顺序读取数据流的次数,如果为 -1,则选择最佳视频(amovie 的音频)数据流
sp, seek_point查找点,以秒为单位;如果设置,则输入从给定时间开始
s, streams– 要选择的流,用 + 符号指定多个流,顺序很重要
– 特殊名称 dv(电影)和 da(amovie)指定默认(最佳)视频 / 音频流
– 第一章介绍了如何指定特定流的语法
si, stream_index要读取的流的索引,如果为 -1,则选择最佳流,这是默认值(不建议使用,首选 s 参数)

例如,要在输入视频上显示徽标,可以使用以下命令:

ffmpeg -i video.mpg -vf movie=logo.png[a];[in][a]overlay video1.mp4

例如,当 sp(seek_point)选项设置为 5 时,徽标将从开始 5 秒后显示:

ffmpeg -i video.mpg -vf movie=logo.png:sp=5[a];[in][a]overlay video1.mp4

音视频方向学习、求职,欢迎加入我们的星球

丰富的音视频知识、面试题、技术方案干货分享,还可以进行面试辅导

探索 FFmpeg Basics 音视频技术(23): 先进的技术点

版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。

(0)

相关推荐

发表回复

登录后才能评论