《FFmpeg Basics》中文版-23- 先进的技术点
写在前面
如果您对音视频技术感兴趣,可以订阅我的专题:音视频专辑
也可以关注我的简书账户: 张芳涛,我后期会发布更多的音视频以及图像处理方面的文章。
正文
加入音频和视频文件
有几种加入媒体文件,它们在表格中描述:
类型 | 描述 | 针对音频 | 针对视频 |
---|---|---|---|
级联 | 编码文件一个接一个; 第一个结束,第二个开始 | Yes | Yes |
合并 | 将所有音频流编码为一个,例如2个单声道到1个立体声 | Yes | No |
混合 | 将2个或更多音频通道编码为1,音量可以调节 | Yes | No |
多路复用 (mux) | 将2个或更多文件编码为1,例如1个音频和1个视频文件,如果存在更多相同类型的流,则选择是在用户 | Yes | Yes |
覆盖/画中画 (PiP) | 2个或更多视频一次显示在另一个旁边或一个在另一个之上 | No | Yes |
连接与shell命令
媒体文件连接的先决条件
特殊文件格式 | 连接只能是某些文件格式: 音频- MP3(第2个文件的头将消失),未压缩的像WAV, PCM,等视频- MPEG-1, MPEG-2 TS, DV |
---|---|
格式的一致性 | 所有连接的文件都是相同的格式,这意味着可以加入2个MP3文件,但1个带有1个WAV的MP3不能 |
流的一致性 | 所有连接文件: - 包含相同数量的每种类型的流。 - 音频流使用相同的编解码器,采样率和通道布局 - 视频流使用相同的分辨率 |
为符合此要求,通常需要转换输入文件,使用-q 1或类似选项来保持初始质量,详细信息请参阅格式间转换 |
在Windows上,我们可以使用带有/B标志的复制命令来指示二进制模式,在文件之间必须是一个加号。连接N文件的复制命令的一般形式是:
copy /B file1+file2+...+fileN-1+fileN outputFile
例如,连接文件videoclip1。mpg和videoclip2。mpg到文件视频。mpg,我们可以使用以下命令:
copy /B videoclip1.mpg+videoclip2.mpg video.mpg
在Linux、Unix和OS X上,我们可以在表单中使用cat命令:cat file1 files2 > file3,因此我们可以修改前面的例子:
cat videoclip1.mpg videoclip2.mpg > video.mpg
链接concat协议
另一种选择是使用concat协议,先决条件类似于复制命令。例如,要使用该协议修改前面的示例,我们可以使用以下命令:
ffmpeg -i concat:"videoclip1.mpg|videoclip2.mpg" -c copy video.mpg
我的测试命令:
ffmpeg -i concat:"/Users/zhangfangtao/Desktop/test.mp4|/Users/zhangfangtao/Desktop/test2.mp4" -c copy /Users/zhangfangtao/Desktop/test3.mp4
- 显示效果:
生成了一个新的视频,不过我感觉这个视频和test1没有什么差别。
连接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 filter
可以加入各种格式,有些例子是: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 f -i 1.avi -vf movie=2.avi[a];[in][a]concat a.mp4
我的测试命令如下:
ffmpeg -i /Users/zhangfangtao/Desktop/test.mp4 -i /Users/zhangfangtao/Desktop/test3.mp4 -filter_complex concat /Users/zhangfangtao/Desktop/test4.mp4
- 显示效果:
生成了一个视频,里面包含前两段的是视频内容,不过,有效时长只是第一段视频的长度。后面有种无效的感觉。。。。
其他类型的拼接技术
- 音频合并(多个流到1个多声道流) - 在数字音频一章中介绍
- 将几个音频文件混合到1 - 在数字音频一章中有描述
- 多路复用 - 在“FFmpeg基本介绍”一章中介绍了媒体流的选择
- overlay-在overlay-画中画章节里面有具体的描述。
移除掉logo
一些视频包含公司标志,通常位于左上角,常见示例是录制电视节目。 FFmpeg包含2个特殊滤镜以去除徽标,而最终效果并不总是完美,不过在许多情况下这种移除logo的技术还是可以接受的。
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 or t | 该标志矩形的模糊边缘厚度,默认值为4 |
show | 定位的参数,默认值为0,如果设置为1,屏幕上的绿色矩形显示为帮助查找正确的x、y、w和h参数 |
例如,我们首先从下图所示的800x600像素大小视频的右上角移除一个标志,我们通过显示一个绿色矩形的显示选项来估计logo的位置:
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
我的测试命令如下(没有t
参数,我这边不识别这个,报错):
ffmpeg -i /Users/zhangfangtao/Desktop/ornage.jpeg -vf "delogo=x=15:y=678:w=218:h=20:show=1" /Users/zhangfangtao/Desktop/ornage2.jpeg
-
显示效果(有没有看到一个绿色的框):
有没有看到一个绿色的框ffmpeg -i /Users/zhangfangtao/Desktop/ornage.jpeg -vf "delogo=x=10:y=700:w=300:h=35" /Users/zhangfangtao/Desktop/ornage3.jpeg
-
显示效果(水印没了):
抖动视频部分的固定
没有三脚架或车辆拍摄的视频的一些部分通常包括抖动 - 水平和垂直移动的小变化,在某些情况下可以使用去抖滤波器进行修正:
描述 | 修正水平和垂直位移的小变化,当视频没有三脚架或移动车辆时有用 |
---|---|
语法 | 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
我的测试命令:
ffmpeg -i /Users/zhangfangtao/Desktop/1527143197.mp4 -vf deshake /Users/zhangfangtao/Desktop/1527143198.mp4
ffmpeg -i /Users/zhangfangtao/Desktop/1527143197.mp4 -vf deshake=contrast=160 /Users/zhangfangtao/Desktop/1527143199.mp4
ffmpeg -i /Users/zhangfangtao/Desktop/1527143197.mp4 -vf deshake=blocksize=4:filename=/Users/zhangfangtao/Desktop/log.txt /Users/zhangfangtao/Desktop/1527143200.mp4
- 显示效果:其实,我并没有看出来什么效果。。。可能我用手机拍的抖得太厉害了。。。
第三条指令打印出来的txt信息截图如下:
将颜色框添加到视频
使用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大小的输入上添加一个尺寸为600x400像素的黄色框,其大小为左侧150像素和顶部0像素,我们可以使用以下命令:
ffmpeg -i ship.avi -vf drawbox=x=150:w=600:h=400:c=yellow ship1.avi
我的测试命令:
ffmpeg -i /Users/zhangfangtao/Desktop/test.mp4 -vf drawbox=x=150:w=600:h=400:c=yellow /Users/zhangfangtao/Desktop/test3.mp4
- 显示效果
检测帧数
如果您需要知道有多少帧包含您的视频文件,您可以使用以下命令:
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,表示视频帧的总数,也可以从帧速率和持续时间计算,但结果并不总是准确。
我的测试命如下:
ffmpeg -i /Users/zhangfangtao/Desktop/test.mp4 -f null /dev/null
- 显示效果如下:
检测广告,部分转换或损坏的编码
从电视,互联网等录制的较长视频可以包含带有广告,转场,不完整帧和其他不需要内容的短片。 如果此部分包含黑色框架,则可以使用表中描述的黑色检测过滤器检测它们。
Description | 检测几乎全黑的视频部分,并输出包含检测到的黑色间隔的开始,结束和持续时间的行,以秒为单位表示。 如果日志级别设置为低于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之间 | 例如,如果帧大小为400x300(总共12万像素),12000像素不是黑色,那么这个比例是0.9 | 0.98 |
pixel_black_th, pix_th | 浮点数在0到1.0之间 | Treshold设置像素为黑色,它等于表达式: (absolute_threshold–luminance_minimum_value) luminance_range_size) |
0.1 |
例如,要从源mptestsrc中检测黑帧,命令是(控制台输出如下):
ffmpeg -f lavfi -i mptestsrc -vf blackdetect -f sdl 'test'
我的测试命令:
ffmpeg -f lavfi -i mptestsrc -vf blackdetect -f sdl 'test'
*显示效果:
用黑帧过滤器进行检测
检测黑帧的另一个过滤器是表中描述的黑帧过滤器:
描述 | 检测几乎为黑色的帧,并输出包含: - 检测帧的帧数 - 黑色部分的百分比 - 如果已知则在文件中定位,否则为-1 - 时间戳 |
---|---|
语法 | blackframe[=amount:[treshold]] 所有的参数都是可选的 |
参数 | |
amount | 在阈值下的像素百分比,默认值为98 |
threshold | 下面是被认为是黑色的像素,默认值是32 |
过滤器blackdetect
和blackframe
类似,但每个显示不同的信息。 图像上显示使用与黑检测滤镜相同的视频源的黑帧滤镜输出:
ffmpeg -f lavfi -i mptestsrc -vf blackframe -f sdl 'test'
我的测试命令如下:
ffmpeg -f lavfi -i mptestsrc -vf blackframe -f sdl 'test'
- 显示效果:
只选择指定的帧进行输出
特殊的多媒体过滤器可以选择音频并选择视频启用,以精确指定哪些帧将保留,哪些从输出中排除。
描述 | 选择输出帧,对每个输入帧评估表达式,如果表达式的值不为零,则选择帧,否则跳过帧 |
---|---|
语法 | select=expression expression默认值是1 |
可用的参数 | |
n | 从0开始的过滤帧的连续编号 |
selected_n | 所选帧的序号,从0开始 |
prev_selected_n | 如果未定义,则最后一个选定帧的序列号为NAN |
TB | 输入时间戳的时基 |
pts | 如果NAN未定义,那么经过滤波的视频帧的PTS(表示时间戳)以TB为单位表示 |
t | 如果NAN未定义,则滤波的视频帧的PTS以秒表示 |
prev_pts | 先前过滤的视频帧的PTS,如果未定义则为NAN |
prev_selected_pts | 如果NAN未定义,则最后一个先前过滤的视频帧的PTS |
prev_selected_t | 如果NAN未定义,则最后选择的最后一个视频帧的PTS |
start_pts | 如果NAN未定义,视频中第一个视频帧的PTS |
start_t | 如果NAN未定义,第一个视频帧的时间在视频中 |
pict_type (只局限在视频中) |
过滤帧的类型,可以采用以下值之一: I ...帧内预测帧, P ... 前向预测帧, B ...双向预测帧, S ...交换帧,SI ...切换I帧,SP ...切换P帧,BI ...特殊帧内帧,不是关键帧(VC-1视频编解码器) |
interlace_type (只局限在视频中) |
帧间型,可采用下列值之一: PROGRESSIVE, TOPFIRST, BOTTOMFIRST |
PROGRESSIVE | 帧是渐进的(不是交错的) |
TOPFIRST | 帧是top-field-first |
BOTTOMFIRST | 帧是bottom-field-first |
key | 如果经过筛选的帧是一个关键帧,否则为0 |
pos | 如果信息不可用(例如合成视频),在过滤帧的文件中位置为-1 |
scene (仅局限于视频) |
0和1之间的值表示一个新的场景;低值反映了当前帧引入新场景的低概率,而更高的值意味着当前帧更可能是一个 |
consumed_sample_n | 在当前帧之前选择的样本数目 |
samples_n | 当前帧中的样本数目 |
sample_rate | 输入采样率 |
由于select表达式的默认值为1,因此选择过滤器使用的接下来的两个示例会产生相同的结果 - 所有帧将被选择为输出(值如果是0将不会选择任何内容):
ffmpeg -i input.avi -vf select output.avi
ffmpeg -i input.avi -vf select=1 output.avi
我的测试命令如下:
ffmpeg -i /Users/zhangfangtao/Desktop/test.mp4 -vf select /Users/zhangfangtao/Desktop/test3.mp4
ffmpeg -i /Users/zhangfangtao/Desktop/test.mp4 -vf select=1 /Users/zhangfangtao/Desktop/test3.mp4
ffmpeg -i /Users/zhangfangtao/Desktop/test.mp4 -vf select=0 /Users/zhangfangtao/Desktop/test3.mp4
- 实现效果,前两个命令生成的是和原来一样的视频,最后一个命令,只有音频信息,没有界面。
要选择20到25秒的部分,我们可以使用以下命令:
ffmpeg -i input.avi -vf select="gte(t\,20)*lte(t\,25)" output.avi
我的测试命令如下:
ffmpeg -i /Users/zhangfangtao/Desktop/test.mp4 -vf select="gte\(t\,20\)*lte\(t\,25\)" /Users/zhangfangtao/Desktop/test3.mp4
- 实现效果:
时间的限制不是太准确,,,还是从头给我播放到了最后。。。
若要选择帧内仅为输出,我们可以使用以下命令:
ffmpeg -i input.avi -vf select="eq(pict_type\,I)" output.avi
我的测试命令如下:
ffmpeg -i /Users/zhangfangtao/Desktop/test.mp4 -vf select="eq\(pict_type\,I\)" /Users/zhangfangtao/Desktop/test3.mp4
- 实现的结果:
视频长短没有变,但是视频的大小几乎减少了一半。而且视频少了很多细节。
通过改变纵横比来缩放输入
调整和伸缩视频章节描述了缩放视频帧的缩放过滤器。 另一种方法是使用改变显示宽高比DAR和样本宽高比SAR的setdar和setsar滤波器,它们的关系用公式表示(关于宽高比的细节在词汇表中):
DAR = width/height * SAR
描述 | 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
我的测试命令如下:
ffplay -i /Users/zhangfangtao/Desktop/test.mp4 -vf setdar=r=16/9
ffplay -i /Users/zhangfangtao/Desktop/test.mp4 -vf setdar=16/9
ffplay -i /Users/zhangfangtao/Desktop/test.mp4 -vf setsar=r=1.234
ffplay -i /Users/zhangfangtao/Desktop/test.mp4 -vf setsar=1.234
- 显示效果如下:
屏幕抓取
为了将显示输出记录到视频文件中,例如创建一个教程,我们可以使用安装了UScreenCapture直接显示源过滤器的dshow输入设备,下面是下载地址。
http://www.umediaserver.net/bin/UScreenCapture.zip
为了抓取全屏内容,我们可以使用以下命令:
ffmpeg -f dshow -i video="UScreenCapture" -t 60 screen.mp4
如果我们想抓取一个特定的屏幕区域。我们必须使用regedit Windows工具来修改某些注册表项,相信信息在downloaded UScreenCapture.zip文件里面的README文件里面。
因为我用的MAC电脑,所以我的录屏命令如下:
ffmpeg -f avfoundation -r 30 -i "1:0" -t 20 /Users/zhangfangtao/Desktop/test2.mp4
- 显示效果如下:
视频帧的详细信息
为了显示每个视频帧的信息,我们可以使用表格中描述的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枚举的文档) |
checksum | 输入帧的所有平面的Adler-32校验和(十六进制) |
plane_checksum | 输入帧的每个平面的Adler-32校验和(十六进制),表示形式为[c0 c1 c2 c3] |
例如,下一个命令会生成下面打印的信息,其中包括前三行:
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]
我的测试命令如下:
ffmpeg -report -f lavfi -i testsrc -vf showinfo -t 10 /Users/zhangfangtao/Desktop/test.mp4
- 显示效果:
音频频谱
为了使音频频谱可视化,我们可以使用表中描述的示波器滤波器:
描述 | 将音频输入转换为视频输出 |
---|---|
语法 | showspectrum[=s=widthxheight[:slide=number]] |
参数的描述 | |
size, s | 输出视频大小,默认值为640x480 |
slide | 设置频谱是否沿窗口滑动,默认值为0 |
例如,下面的图片显示了该命令创建的声谱:
ffmpeg -i audio.mp3 -vf showspectrum audio_spectrum.mp4
我的测试命令如下:
ffmpeg -i /Users/zhangfangtao/Desktop/DYZDJ.mp3 -lavfi showspectrum /Users/zhangfangtao/Desktop/test3.mp4
-
效果图
音频波形可视化
描述 | 将输入音频转换为包含音频波表示的视频 |
---|---|
语法 | showwaves[=n=number[:r=rate[:s=video_size]]] |
参数的描述 | |
n | 打印在同一列上的样本数量越大,数值越大会降低帧速率,因此不能与速率参数结合使用 |
rate, r | 帧速率,默认值为25,不能与n参数组合使用 |
size, s | 视频大小,默认值是640x480 |
来自音频输入的波形可以通过表格中描述的showwaves滤波器进行可视化:
描述 | 将输入音频转换为包含音频波表示的视频 |
---|---|
语法 | showwaves[=n=number[:r=rate[:s=video_size]]] |
参数的描述 | |
n | 打印在同一列上的样本数量越大,数值越大会降低帧速率,因此不能与速率参数结合使用 |
rate, r | 帧速率,默认值为25,不能与n参数组合使用 |
size, s | 视频大小,默认值是640x480 |
例如,要将music.mp3文件中的波形可视化为waves.mp4文件,我们可以使用以下命令:
ffmpeg -i music.mp3 -vf showwaves waves.mp4
我的测试命令:
ffmpeg -i /Users/zhangfangtao/Desktop/NWDSL.mp3 -lavfi showwaves /Users/zhangfangtao/Desktop/test3.mp4
- 显示效果如图:
语音合成
- 没有Windows环境,下面的没测试,不过AVFoundation做这个相当简单,想了解AVFounadtion怎么实现的点击这里
通过包含libflite外部库,人声可以与来自Flite(Festival Lite)(一种小型可嵌入TTS(文本到语音)引擎)的flite音频源合成。 它由美国卡内基梅隆大学CMU Speech Group开发。 Flite完全用C语言编写,重新实现了音乐节体系结构的核心部分,以实现为每个系统设计的声音之间的兼容性。 爱丁堡大学的节日语音合成系统是构建语音合成系统的框架。 有关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库增加了10 MB以上的ffmpeg.exe文件,因此它不在官方二进制文件中,而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
一次将输出保存为多种格式
虽然从第一章中解释的命令语法可以清楚看出,但我们可以通过一个命令将处理结果保存为多种格式,例如我们可以将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
额外的媒体输入到filtergraph
默认情况下,在任何具有-i选项的过滤器之前指定输入文件,并且第一个输入在带有[in]链接标签的过滤器图中可用。 如果我们想要过滤额外的文件,我们可以使用amovie来源作为视频文件的音频和电影来源,它们在表格中描述:描述 | 从媒体(电影)容器读取音频和/或视频流。 必需参数是媒体文件的文件名,可选键=值对由冒号分隔 |
---|---|
语法 | movie=video_name[:options] amovie=audio_name[:options] |
Available key = 值选项参数中的值对 | |
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
我的测试命令:
ffmpeg -i /Users/zhangfangtao/Desktop/test.mp4 -vf "movie=/Users/zhangfangtao/Desktop/fruit.jpg[a];[in][a]overlay" /Users/zhangfangtao/Desktop/test3.mp4
*显示效果(logo太大了,把视频盖住了):
例如,sp(seek_point)选项设置为5时,徽标将从开始5秒后显示:
ffmpeg -i video.mpg -vf movie=logo.png:sp=5[a];[in][a]overlay video1.mp4
我的测试命令:
ffmpeg -i /Users/zhangfangtao/Desktop/001.mp4 -vf "movie=/Users/zhangfangtao/Desktop/fruit.jpg:sp=0[a];[in][a]overlay" /Users/zhangfangtao/Desktop/test3.mp4
- 报错: