目录
一、准备:
二、简单尝试
三、常用语法
1、帮助查询
2、过滤链
3、map用法
4、覆盖
5、叠加水印
6、设置帧率
7、设置码率
8、控制输出文件大小
9、设置分辨率
10、裁剪
11、填充
12、翻转
13、旋转
14、模糊
15、锐化
16、添加Logo
17、添加文本
18、图片支持
19、添加字幕subtitles
20、视频颤抖、色彩平衡
21、设置音频视频播放速度
22、马赛克视频
23、指定时间段处理:
24、视频合并:
方法一:FFmpeg concat 协议
方法二:FFmpeg concat 分离器
方法三:Mencoder 连接文件并重建索引
方法四:使用 FFmpeg concat 过滤器重新编码(有损)
音视频轨道合并:
25、视频截取
26、其他
官方文档:https://ffmpeg.org/ffmpeg.html
注:ffplay与ffmpeg语法类似,只是一个是实时播放,一个是生成输出文件。
源视频:https://cloud-clip-out.oss-cn-hangzhou.aliyuncs.com/video/9fbda264-99ad-49c3-8a07-654e685f6c31/13e000a4-0950-482b-b396-a1ad20d994a5.mp4?=1553594411
查看视频信息:
ffmpeg -i test.mp4
ffmpeg version 4.1.2-tessus https://evermeet.cx/ffmpeg/ Copyright (c) 2000-2019 the FFmpeg developers
built with Apple LLVM version 10.0.0 (clang-1000.11.45.5)
configuration: --cc=/usr/bin/clang --prefix=/opt/ffmpeg --extra-version=tessus --enable-avisynth --enable-fontconfig --enable-gpl --enable-libaom --enable-libass --enable-libbluray --enable-libfreetype --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libmysofa --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopus --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-libzimg --enable-libzmq --enable-libzvbi --enable-version3 --pkg-config-flags=--static --disable-ffplay
libavutil 56. 22.100 / 56. 22.100
libavcodec 58. 35.100 / 58. 35.100
libavformat 58. 20.100 / 58. 20.100
libavdevice 58. 5.100 / 58. 5.100
libavfilter 7. 40.101 / 7. 40.101
libswscale 5. 3.100 / 5. 3.100
libswresample 3. 3.100 / 3. 3.100
libpostproc 55. 3.100 / 55. 3.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'test2.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf57.83.100
Duration: 00:00:14.68, start: 0.000000, bitrate: 1175 kb/s
Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 1041 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s (default)
Metadata:
handler_name : SoundHandler
At least one output file must be specified
视频文件截图
fmpeg -i test.mp4 -y -f image2 -t 0.001 -s 352x240 a.jpg
ffmpeg -i test.mp4 -vframes 30 -y -f gif a.gif
ffmpeg -i test.mp4 -y -f image2 -ss 8 -t 0.001 -s 350x240 test.jpg
-ss后跟的时间单位为秒
视频格式转换
ffmpeg -y -i test.mp4 -bitexact -vcodec h264 -b:v 128k -r 15 -s 176x144 -acodec aac -ac 1 -ar 48000 -aq 2 -b:a 128k -vol 512 -f 3gp test.3gp
转换文件为3GP格式
-vol 512 音量大小 256 为普通
-aq 音频质量
-ar 频率
-b:v 视频码率
-r fps 设置帧频 缺省25
-b:a 音频码率
•可用的bit流 :ffmpeg -bsfs
•可用的编解码器:ffmpeg -codecs
•可用的解码器:ffmpeg -decoders
•可用的编码器:ffmpeg -encoders
•可用的过滤器:ffmpeg -filters
•可用的视频格式:ffmpeg -formats
•可用的声道布局:ffmpeg -layouts
•可用的license:ffmpeg -L
•可用的像素格式:ffmpeg -pix_fmts
•可用的协议:ffmpeg -protocals
-h, -?, -help, --help [arg]
显示帮助。可以指定可选参数来打印关于特定项目的帮助。如果没有指定参数,则只显示基本(非高级)工具选项。
arg的可能值是:
long
除基本工具选项外,还打印高级工具选项。
full
打印完整的选项列表,包括编码器,解码器,解复用器,复用器,滤波器等的共享和专用选项。
decoder=decoder_name
打印有关名为decoder_name的解码器的详细信息。使用-decoders选项可以获得所有解码器的列表。
encoder=encoder_name
打印有关名为encoder_name的编码器的详细信息。使用-encoders选项可以获取所有编码器的列表。
demuxer=demuxer_name
打印有关名为demuxer_name的分流器的详细信息。使用-formats选项可以获得所有分路器和复用器的列表。
muxer=muxer_name
打印有关名为muxer_name的复用器的详细信息。使用-formats选项可以获得所有muxers和demuxers的列表。
filter=filter_name
打印有关过滤器名称filter_name的详细信息。使用-filters选项可以获取所有过滤器的列表。
示例:
#查看是否支持webp格式:
ffmpeg -formats|grep webp
首先,我们来根据源视频生成一个左右对称的视频。
ffmpeg -i test.mp4 -t 10 -vf pad=2*iw output.mp4
ffmpeg -i test.mp4 -t 10 -vf hflip output2.mp4
ffmpeg -i output.mp4 -i output2.mp4 -filter_complex overlay=w compare.mp4
上面的写法比较复杂,我们可以换一种简单的写法,如下:
ffmpeg -i test.mp4 -t 10 -vf "split [a][b]; [a]pad=2*iw[1]; [b]hflip[2]; [1][2]overlay=w " compare.mp4 -y
具体执行步骤如下:
F1: split过滤器创建两个输入文件的拷贝并标记为[a],[b]
F2: [a]作为pad过滤器的输入,pad过滤器产生2倍宽度并输出到[1].
F3: [b]作为hflip过滤器的输入,vflip过滤器水平翻转视频并输出到[2].
F4: 用overlay过滤器把 [2]覆盖到[1]的旁边.
用来获取指定的音视频轨道。
-map file_number:stream_type[:stream_number]
这有一些特别流符号的说明:
1、-map 0 选择第一个文件的所有流
2、-map i:v 从文件序号i(index)中获取所有视频流, -map i:a 获取所有音频流,-map i:s 获取所有字幕流等等。
3、特殊参数-an,-vn,-sn分别排除所有的音频,视频,字幕流。
注意:文件序号和流序号从0开始计数。
示例: 生成一个有双声道的视频
ffmpeg -i test2.mp4 -i test.mp4 -map 0 -map 1:a:0 twoaudiotest.mp4 -y
更多参考:
语法:overlay[=x[:y]
所有的参数都是可选,默认值都是0
W H 为第一个输入源的宽和高, w h 为第二个输入源的宽和高。
其他尝试
ffmpeg -i test.mp4 -t 10 -vf "split [a][b]; [a]pad=2*iw[1]; [b]hflip[2]; [1][2]overlay=W-w:H-h/2 " compare.mp4 -y
ffmpeg -i test.mp4 -t 10 -vf "split [a][b]; [a]pad=2*iw[1]; [b]hflip[2]; [1][2]overlay=W-w:h/2-H " compare.mp4 -y
ffmpeg -i test.mp4 -vf "movie=a.jpg[wm];[in][wm]overlay=5:5[out]" cover.mp4 -y
1、用 -r 参数设置帧率
ffmpeg –i input –r fps output
2、用fps filter设置帧率
ffmpeg -i clip.mpg -vf fps=fps=25 clip.webm
帧率的预定义值:
例如设置码率为29.97fps,下面三种方式具有相同的结果:
ffmpeg -i input.avi -r 29.97 output.mpg
ffmpeg -i input.avi -r 30000/1001 output.mpg
ffmpeg -i input.avi -r netsc output.mpg
使用–b 参数
ffmpeg -i film.avi -b 1.5M film.mp4
音频:-b:a 视频: - b:v
如:设置视频码率为1500kbps
ffmpeg -i input.avi -b:v 1500k output.mp4
-fs (file size首字母缩写)
ffmpeg -i input.avi -fs 1024K output.mp4
计算输出文件大小
(视频码率+音频码率) * 时长 /8 = 文件大小K (小b换算成大B)
用-s参数设置视频分辨率,参数值w x h,w宽度单位是像素,h高度单位是像素
ffmpeg -i test.mp4 -s 640x480 output.avi
预定义值:
或者使用Scale filter
Scale filter的优点是可以使用一些额外的参数
语法:
Scale=width:height[:interl={1|-1}]
下表列出了常用的额外参数
Scale可用的参数 |
|
iw or in_w |
输入宽度 |
ih or in_h |
输入高度 |
ow or out_w |
输出宽度 |
oh or out_h |
输出高度 |
•示例:
•下面两条命令有相同效果
ffmpeg -i input.mpg -s 320x240 output.mp4
ffmpeg -i input.mpg -vf scale=320:240 output.mp4
•对输入视频成比例缩放,改变为源视频一半大小
ffmpeg -i test.mp4 -vf scale=iw/2:ih/2:-1 output.avi
•改变为原视频的90%大小:
ffmpeg -i input.mpg -vf scale=iw*0.9:ih*0.9 output.mp4
•在未知视频的分辨率时,保证调整的分辨率与源视频有相同的横纵比。
•宽度固定400,高度成比例:
ffmpeg -i input.avi -vf scale=400:400/a
ffmpeg -i input.avi -vf scale=400:-1
•相反地,高度固定300,宽度成比例:
ffmpeg -i input.avi -vf scale=-1:300
ffmpeg -i input.avi -vf scale=300*a:300
裁剪视频crop filter
从输入文件中选取你想要的矩形区域到输出文件中,常见用来去视频黑边。
语法:crop:ow[:oh[:x[:y:[:keep_aspect]]]]
查看说明:ffmpeg -h filter=crop
参数示例:
示例:
•裁剪输入视频的左三分之一,中间三分之一,右三分之一:
ffmpeg -i input -vf crop=iw/3:ih :0:0 output
ffmpeg -i input -vf crop=iw/3:ih :iw/3:0 output
ffmpeg -i input -vf crop=iw/3:ih :iw/3*2:0 output
•裁剪帧的中心
•当我们想裁剪区域在帧的中间时,裁剪filter可以跳过输入x和y值,他们的默认值是
Xdefault = ( input width - output width)/2
Ydefault = ( input height - output height)/2
ffmpeg -i input_file -v crop=w:h output_file
•裁剪中间一半区域:
ffmpeg -i test.mp4 -vf crop=iw/2:ih/2 output.avi
•画一个方框,长放大成两倍,剪切方框里面的内容,放到右侧。
ffplay -i test.mp4 -vf "split[a][b];[a]drawbox=x=(iw-300)/2:(ih-300)/2:w=300:h=300:c=yellow[A];[A]pad=2*iw[C];[b]crop=300:300:(iw-300)/2:(ih-300)/2[B];[C][B]overlay=3*W/4:(H-300)/2"
•cropdetect filter 自动检测黑边区域
ffplay test.mp4 -vf cropdetect
[Parsed_cropdetect_0 @ 0x7fe6774b7c80] x1:0 x2:1279 y1:0 y2:719 w:1280 h:720 x:0 y:0 pts:180224 t:14.080000 crop=1280:720:0:0
•然后用检测到的值来裁剪视频
ffplay test.mp4 -vf "crop=1280:720:0:0"
填充视频(pad)
在视频帧上增加一快额外额区域,经常用在播放的时候显示不同的横纵比
语法:pad=width[:height:[:x[:y:[:color]]]]
示例:
•用30个像素粉色包围视频
ffmpeg -i test.jpg -vf pad=iw+60:ih+60:30:30:pink framed_photo.jpg
•20:9
ffmpeg -i test2.mp4 -vf "pad=ih*20/9:ih :(ow-iw)/2:0:black" test-20-9.mp4
•去掉黑边
ffplay test-20-9.mp4 -vf cropdetect
ffplay test-20-9.mp4 -vf crop=1280:720:160:0
•测试展现4:3-->16:9
ffplay -f mp4 -i test2.mp4 -vf "pad=ih*30/9:ih:(ow-iw)/2:0:pink"
•16:9-->4:3
ffplay test2.mp4 -vf "pad=iw:iw*3/4:0:(oh-ih)/2:pink"
•水平翻转语法: -vf hflip
ffplay -i test.mp4 -vf hflip
•垂直翻转语法:-vf vflip
ffplay -i test.mp4 -vf vflip
语法:transpose={0,1,2,3}
•0:逆时针旋转90°然后垂直翻转
•1:顺时针旋转90°
•2:逆时针旋转90°
•3:顺时针旋转90°然后水平翻转
请注意,transpose filter的0和3值对视频同时提供两种操作-----旋转和垂直翻转。这意味着0有两种filter的效果
•下面的两条命令具有相同的效果:
ffplay -i test2.mp4 -vf transpose=0
ffplay -i test2.mp4 -vf transpose=2,vflip
•补充: 在一个画面中看对比
ffplay -i test2.mp4 -vf "split[a][b];[a]pad=iw:iw+ih[A];[b]transpose=0[B];[A][B]overlay=0:H-W"
•同样地,使用3值也能够取代两个过滤器,比如下面的命令:
ffplay -i test2.mp4 -vf transpose=3
ffplay -i test2.mp4 -vf transpose=1,vflip
•语法:boxblur=luma_r:luma_p[:chroma_r:chram_p[:alpha_r:alpha_p]]
ffplay -i test2.mp4 -vf boxblur=1:10:4:10
•注意:luma_r和alpha_r半径取值范围是0~min(w,h)/2, chroma_r半径的取值范围是0~min(cw/ch)/2
Luma:亮度。Chroma:色彩度,r:半径 p:强度应用多少次filter
•语法:-vf unsharp=l_msize_x:l_msize_y:l_amount:c_msize_x:c_msize_y:c_amount
•所有的参数是可选的,默认值是5:5:1.0:5:5:0.0
•l_msize_x:水平亮度矩阵,取值范围3-13,默认值为5
•l_msize_y:垂直亮度矩阵,取值范围3-13,默认值为5
•l_amount:亮度强度,取值范围-2.0-5.0,负数为模糊效果,默认值1.0
•c_msize_x:水平色彩矩阵,取值范围3-13,默认值5
•c_msize_y:垂直色彩矩阵,取值范围3-13,默认值5
•c_amount:色彩强度,取值范围-2.0-5.0,负数为模糊效果,默认值0.0
•使用默认值,亮度矩阵为5x5和亮度值为1.0
ffmpeg -i test2.mp4 -vf unsharp output.mp4
ffplay -i test2.mp4 -vf unsharp
•高斯模糊效果(比较强的模糊):
ffplay -i test2.mp4 -vf unsharp=13:13:-2
•Logo在左上角
// 截取8秒时候的缩略图
ffmpeg -i test.mp4 -y -f image2 -ss 8 -t 0.001 -s 350x240 logo.jpg
ffmpeg -i test.mp4 -i logo.jpg -filter_complex overlay logo.mp4
•右上角:
ffmpeg -i pair.mp4 -i logo.png -filter_complex overlay=W-w pair2.mp4
•左下角:
ffmpeg -i pair.mp4 -i logo.png -filter_complex overlay=0:H-h pair2.mp4
•右下角:
ffmpeg -i pair.mp4 -i logo.png -filter_complex overlay=W-w:H-h pair2.mp4
•Logo动态移动
•2秒后logo从左到右移动:
ffplay -i test.mp4 -vf "movie=logo.jpg[logo];[in][logo]overlay=x='if(gte(t\,2)\,((t-2)*480)-w\,NAN)':y=0"
•2秒后logo从左到右移动后停止在左上角
ffplay -i test2.mp4 -vf "movie=logo.jpg[logo];[in][logo]overlay=x='if(gte(((t-2)*80)-w\,W)\,0\,((t-2)*80)-w)':y=0"
•每隔10秒交替出现logo。
ffmpeg -y -t 60 -i test2.mp4 -i logo.jpg -i smpte.png -filter_complex "overlay
=x=if(lt(mod(t\,20)\,10)\,10\,NAN ):y=10,overlay=x=if(gt(mod(t\,20)\,10)\,W-w-10\,NAN ) :y=10" overlay.mp4
#说明:
#1.T大于2,(t-2)*80-w w是logo的宽度。80是移动的速度
#2.同理1
#3.对20取模,如果模小于10显示左边,大于10显示右边
•删除logo,只是模糊化处理那一块。
查看帮助:ffmpeg -h filter=delogo
语法:-vf delogo=x:y:w:h[:show]
x:y 离左上角的坐标
w:h logo的宽和高
t: 矩形边缘的厚度默认值4
show:若设置为1有一个绿色的矩形,默认值0.
举例:
ffplay -i logo.mp4 -vf "delogo=1:1:350:240:0"
语法:
drawtext=fontfile=font_f:text=text1[:p3=v3[:p4=v4[…]]]
常用的参数值
•x:离左上角的横坐标
•y: 离左上角的纵坐标
•fontcolor:字体颜色
•fontsize:字体大小
•text:文本内容
•textfile:文本文件
•t:时间戳,单位秒
•n:帧数开始位置为0
•draw/enable:控制文件显示,若值为0不显示,1显示,可以使用函数
示例:
•在左上角添加Welcome文字
ffplay -f lavfi -i color=c=white -vf "drawtext=fontfile=arial.ttf:text=Welcome"
•在中央添加Good day
ffplay -f lavfi -i color=c=white -vf drawtext="fontfile=arial.ttf:text='Goodday':x=(w-tw)/2:y=(h-th)/2"
•设置字体颜色和大小
ffplay -f lavfi -i color=c=white -vf drawtext="fontfile=arial.ttf:text='Happy Holidays':x=(w-tw)/2:y=(h-th)/2:fontcolor=green:fontsize=30"
•动态文本
•用 t (时间秒)变量实现动态文本
•1、顶部水平滚动
ffplay -i test.mp4 -vf drawtext="fontfile=arial.ttf:text='Dynamic RTL text':x=w-t*50:fontcolor=darkorange:fontsize=30"
•2、底部水平滚动
ffplay -i test.mp4 -vf drawtext="fontfile=arial.ttf:textfile=textfile.txt:x=w-t*50:y=h-th:fontcolor=darkorange:fontsize=30"
•3、垂直从下往上滚动
ffplay test2.mp4 -vf drawtext="textfile=textfile.txt:fontfile=arial.ttf:x=(w-tw)/2:y=h-t*100:fontcolor=white:fontsize=30"
•在右上角显示当前时间 localtime
ffplay test2.mp4 -vf drawtext="fontfile=arial.ttf:x=w-tw:fontcolor=white:fontsize=30:text='%{localtime\:%Y/%m/%d %H\\\\\:%M\\\\\:%S}'"
•每隔3秒显示一次当前时间
ffplay test2.mp4 -vf drawtext="fontfile=arial.ttf:x=w-tw:fontcolor=white:fontsize=30:text='%{localtime\:%H\\\\\:%M\\\\\:%S}':enable=lt(mod(t\,3)\,1)"
图片支持:
查看是否支持webp格式:
ffmpeg -formats|grep webp
FFmpeg支持绝大多数图片处理, 除LJPEG(无损JPEG)之外,其他都能被解码,除了EXR,PIC,PTX之外,所有的都能被编码。
•截取一张图片使用 –ss(seek from start)参数.
ffmpeg -i test.mp4 -ss 00:00:05 -t 0.0001 -f image2 image.jpg -y
ffmpeg -i test.mp4 -ss 00:00:05 -t 0.0001 -f webp image.webp
•图片类型转换
ffmpeg -i image.jpg -vcodec libwebp image2.webp
•从视频中生成GIF图片
ffmpeg -i test.mp4 -t 10 -pix_fmt rgb24 test.gif
•转换视频为图片(每帧一张图)
ffmpeg -i test.mp4 frame%4d.jpg
•图片转换为视频
ffmpeg -f image -i frame%4d.jpg -r 25 video.mp4
-r 25 表示定义帧率为25,这样输出的视频就是每秒播放25帧
•每隔一秒截一张图
ffmpeg -i test.mp4 -f image2 -vf fps=fps=1 out%d.png
•每隔20秒截一张图
ffmpeg -i test2.mp4 -f image2 -vf fps=fps=1/20 out%d.png
•多张截图合并到一个文件里(2x3) 每隔一千帧(秒数=1000/fps25)即40s截一张图
ffmpeg -i test2.mp4 -frames 5 -vf "select=not(mod(n\,60)),scale=320:240,tile=2x3" out.png
# select=not(mod(n\,1000)),select(expr) 如果expr=0丢弃。
•裁剪
ffmpeg -f lavfi -i rgbtestsrc -vf crop=150:150 crop_rg.png -y
•填充
•ffmpeg -f lavfi -i smptebars -vf pad=360:280:20:20:orange pad_smpte.jpg
•和视频一样图片同样能翻转,旋转和覆盖
•翻转
ffmpeg -i orange.jpg -vf hflip orange_hfilp.jpg
ffmpeg -i orange.jpg -vf vflip orange_vfilp.jpg
•旋转
ffmpeg -i image.png -vf transpose=1 image_rotated.png
•覆盖
ffmpeg -f lavfi -i rgbtestsrc -s 400x300 rgb.png
ffmpeg -f lavfi -i smptebars smpte.png
ffmpeg -i rgb.png -i smpte.png -filter_complex "overlay=(W-w)/2:(H-h)/2" rgb_smpte.png
语法 –vf subtitles=file
ffplay -i test2.mp4 -vf subtitles=test.srt
•视频颤抖
ffplay test.mp4 -vf "crop=in_w/2:in_h/2:(in_w-out_w)/2+((in_w-out_w)/2)*sin(n/10):(in_h-out_h)/2 +((in_h-out_h)/2)*sin(n/7)"
•色彩平衡
ffplay -i test.mp4 -vf curves=vintage
•色彩变幻
ffplay -i test.mp4 -vf hue="H=2*PI*t: s=sin(2*PI*t)+1"
•彩色转换黑白
ffplay -i test.mp4 -vf lutyuv="u=128:v=128"
•3倍视频播放视频
ffplay -i test2.mp4 -vf setpts=PTS/3
•¾速度播放视频
ffplay -i test2.mp4 -vf "setpts=PTS/(3/4)"
•2倍速度播放音频
ffplay -i test2.mp4 -af atempo=2
•PTS帧之间的间隔时间
ffplay -i test2.mp4 -af atempo=3 -vf setpts=PTS/3
•用多个输入文件创建一个马赛克视频:
ffmpeg -i test.mp4 -i test2.mp4 -i output.avi -i test.3gp -filter_complex "nullsrc=size=640x480 [base]; [0:v] setpts=PTS-STARTPTS, scale=320x240 [upperleft]; [1:v] setpts=PTS-STARTPTS, scale=320x240 [upperright]; [2:v] setpts=PTS-STARTPTS, scale=320x240 [lowerleft]; [3:v] setpts=PTS-STARTPTS, scale=320x240 [lowerright]; [base][upperleft] overlay=shortest=1 [tmp1]; [tmp1][upperright] overlay=shortest=1:x=320 [tmp2]; [tmp2][lowerleft] overlay=shortest=1:y=240 [tmp3]; [tmp3][lowerright] overlay=shortest=1:x=320:y=240" -c:v libx264 output.mkv
说明:
4个视频并排显示.
1.产生一个空的640x480的背景视频
2.产生4个大小为320x240的文件。
3.挨个覆盖到背景视频上,并已最短的视频文件为结束标志。
gte 等表达式 介绍见:FFmpeg 表达式(Expression Evaluation)
1、指定时间段显示图片:
(gte(t\,5) * (lte(t\,8)) 大于等于5秒,小于等于8秒之前处理。
ffplay -i test2.mp4 -vf "movie=logo.jpg[logo];[in][logo]overlay=x='if((gte(t\,5) * (lte(t\,8)))\,((t-5)*80)-w\,NAN)':y=0"
2、指定时间段显示滚定文字:
中文注意字体要支持
ffplay -i test2.mp4 -vf drawtext="fontfile=Songti.ttc:text='指定时间段内才能看见':x='if((gte(t\,5) * (lte(t\,10)))\,w-t*50\,NAN)':fontcolor=darkorange:fontsize=30"
官网地址: http://trac.ffmpeg.org/wiki/Concatenate
对于 MPEG 格式的视频,可以直接连接:
ffmpeg -i "concat:test.mp4|test2.mp4" -c copy contact.mp4
对于非 MPEG 格式容器,但是是 MPEG 编码器(H.264、DivX、XviD、MPEG4、MPEG2、AAC、MP2、MP3 等),可以包装进 TS 格式的容器再合并。在新浪视频,有很多视频使用 H.264 编码器,可以采用这个方法
ffmpeg -i test.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts input1.ts
ffmpeg -i test2.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts input2.ts
ffmpeg -i "concat:input1.ts|input2.ts" -c copy -bsf:a aac_adtstoasc -movflags +faststart contact.mp4 -y
保存 QuickTime/MP4 格式容器的时候,建议加上 -movflags +faststart。这样分享文件给别人的时候可以边下边看。
注:先转换成相同格式,在进行合并。
ffmpeg -y -i test.mp4 -bitexact -vcodec h264 -b:v 128k -r 15 -s 176x144 -acodec aac -ac 1 -ar 48000 -aq 2 -b:a 128k -vol 512 -f 3gp test.3gp
这种方法成功率很高,也是最好的,但是需要 FFmpeg 1.1 以上版本。
先创建一个文本文件filelist.txt:
file 'test.3gp'
file 'test2.3gp'
然后:ffmpeg -f concat -i filelist.txt -c copy contact.mp4 -y
注意:使用 FFmpeg concat 分离器时,如果文件名有奇怪的字符,要在 filelist.txt 中转义。
这种方法只对很少的视频格式生效。幸运的是,新浪视频使用的 FLV 格式是可以这样连接的。对于没有使用 MPEG 编码器的视频(如 FLV1 编码器),可以尝试这种方法,或许能够成功。
mencoder -forceidx -of lavf -oac copy -ovc copy -o output.flv input1.flv input2.flv input3.flv
语法有点复杂,但是其实不难。这个方法可以合并不同编码器的视频片段,也可以作为其他方法失效的后备措施。
// 合并相近视频
ffmpeg -i test.mp4 -i test.mp4 \
-filter_complex "[0:v][0:a][1:v][1:a]concat=n=2:v=1:a=1[outv][outa]" \
-map "[outv]" -map "[outa]" contact.mp4 -y
如你所见,上面的命令合并了两个文件,FFmpeg concat 过滤器会重新编码它们。注意这是有损压缩。
[0:v][0:a][1:v][1:a]分别表示第一个输入文件的视频、音频、第二个输入文件的视频、音频。concat=n=2:v=1:a=1 表示有三个输入文件,输出一条视频流和一条音频流。[v] [a] 就是得到的视频流和音频流的名字,注意在 bash 等 shell 中需要用引号,防止通配符扩展。
提示
以上三种方法,在可能的情况下,最好使用第二种。第一种次之,第三种更次。第四种是后备方案,尽量避免。
规格不同的视频合并后可能会有无法预测的结果。
有些媒体需要先分离视频和音频,合并完成后再封装回去。
对于 Packed B-Frames 的视频,如果封装成 MKV 格式的时候提示 Can't write packet with unknown timestamp,尝试在 FFmpeg 命令的 ffmpeg 后面加上 -fflags +genpts
以音频和视频长度长的为准。
ffmpeg -i test2.mp4 -i out2.wav -map 0:v:0 -map 1:a:0 all.mp4 -y
ffmpeg -i test2.mp4 -map 0:a -c:a copy test.mov
ffmpeg -i test.mp4 -i test.mov -map 1:a:0 -map 0:v:0 all2.mp4 -y
ffmpeg -i test.mp4 -i test.mov -map 1:a:0 -map 0:v:0 all2.mp4 -y
官网地址:http://trac.ffmpeg.org/wiki/Seeking
•截取00:00:03到00:00:06。
ffmpeg -i test.mp4 -vcodec copy -acodec copy -ss 00:00:03 -to 00:00:06 cut.mp4 -y
•参数解释:
-ss time_off set the start time offset 设置从视频的哪个时间点开始截取,上文从视频的第10s开始截取
-to 截到视频的哪个时间点结束。上文到视频的第15s结束。截出的视频共5s.
如果用-t 表示截取多长的时间如 上文-to 换位-t则是截取从视频的第10s开始,截取15s时长的视频。即截出来的视频共15s.
-vcodec copy表示使用跟原视频一样的视频编解码器。
-acodec copy表示使用跟原视频一样的音频编解码器。
-i 表示源视频文件
-y 表示如果输出文件已存在则覆盖。
-t 持续时间(输入/输出)
当用作输入选项时(在-i之前),限制从输入文件读取数据的持续时间。
当用作输出选项时(在输出url之前),在持续时间达到持续时间后停止输出。
持续时间必须是持续时间规范,请参阅ffmpeg-utils(1)手册中的(ffmpeg-utils)持续时间部分。
-to和-t是互斥的,-t优先。
•值得注意的是,ffmpeg 为了加速,会使用关键帧技术, 所以有时剪切出来的结果在起止时间上未必准确。 通常来说,把 -ss 选项放在 -i 之前,会使用关键帧技术; 把 -ss 选项放在 -i 之后,则不使用关键帧技术。 如果要使用关键帧技术又要保留时间戳,可以加上 -copyts 选项:
ffmpeg -ss 00:00:03 -i test.mp4 -to 00:00:06 -c copy -copyts cut.mp4
截取参数优化:
将-ss, -t 参数放在-i参数之前
ffmpeg -ss 10 -t 15 -i test.mp4 -codec copy cut.mp4
对输入文件执行seek操作,会seek到-ss设置的时间点前面的关键帧上,时间不精确,但是不会出现黑屏。
使用accurate_seek 剪切时间更加精确
ffmpeg -ss 10 -t 15 -accurate_seek -i test.mp4 -codec copy cut.mp4
PS:accurate_seek必须放在-i参数之前
如果编码格式采用的copy 最好加上 -avoid_negative_ts 1 参数
ffmpeg -ss 10 -t 15 -accurate_seek -i test.mp4 -codec copy -avoid_negative_ts 1 cut.mp4
不显示编译信息
ffmpeg -i test2.3gp -hide_banner 展示视频信息,但不展示执行文件编译信息
拆分视频、音频
ffmpeg -i test.mp4 -i test2.mp4 out1.mkv out2.wav -map 1:a -c:a copy out3.mov
多个取 最高分辨率的视频流 最高轨道的音频 最先发现的字幕。
音频拆分码率转换
ffmpeg -i test.mp4 -b:a 64k a.mp2 -b:a 128k b.mp2 -map 0:1 -map 0:1