- FFMPEG 视频
- 新版本命令
- m3u8视频合并
- 视频格式转换
- 合并视频
- 常用命令如下
- 其他指令
- 参数说明
- 腾讯视频qlv转mp4
- 文件转换
FFMPEG 视频
https://teddysun.com/486.html
ffmpeg官网
英伟达CUDA驱动
调用显卡
查询ffmpeg是否支持cuda
- -hwaccel cuvid:指定使用cuvid硬件加速
- -c:v h264_cuvid:使用h264_cuvid进行视频解码
- -c:v h264_nvenc:使用h264_nvenc进行视频编码
- -vf scale_npp=1280:-1:指定输出视频的宽高,注意,这里和软解码时使用的-vf scale=x:x不一样
测试命令
| 1
 | ffmpeg -hwaccel cuvid -c:v h264_cuvid -i 0.mp4 -c:v h264_nvenc -y 00.mp4
 | 
将当前目录下的0.mp4转成00.mp4
| 1
 | ffmpeg -hwaccel cuvid -c:v h264_cuvid -i 0.mp4 -c:v h264_nvenc -r 15 -b 500k -y 00.mp4
 | 
将当前目录下的0.mp4转成00.mp4,并指定输出帧率为15(-r 15),比特率为500k(-b 500k)
| 1
 | ffmpeg -hwaccel cuvid -c:v h264_cuvid -i <input> -c:v h264_nvenc -b:v 2048k -vf scale_npp=1280:-1 -y <output>
 | 
多显卡 向不同GPU提交转码任务
显卡0
| 1
 | ffmpeg -hwaccel cuvid -hwaccel_device 0 -c:v h264_cuvid -i <input> -c:v h264_nvenc -b:v 2048k -vf scale_npp=1280:-1 -y <output>
 | 
显卡1
| 1
 | ffmpeg -hwaccel cuvid -hwaccel_device 1 -c:v h264_cuvid -i <input> -c:v h264_nvenc -b:v 2048k -vf scale_npp=1280:-1 -y <output>
 | 
说明:
-hwaccel_device N:指定某颗GPU执行转码任务,N为数字
视频操作
参数说明:
- -vcodec xvid 使用xvid压缩 
- -s 320x240 指定分辨率 
- -r fps 设置帧频 缺省25 
- -b <比特率> 指定压缩比特 
- -acodec aac 设定声音编码 
- -ac <数值> 设定声道数,1就是单声道,2就是立体声 
- -ar <采样率> 设定声音采样率,PSP只认24000 
- -ab <比特率> 设定声音比特率 
- -vol <百分比> 设定音量 
- -y(覆盖输出文件 
- -t duration 设置纪录时间 hh:mm:ss[.xxx]格式的记录时间也支持 
- -ss position 搜索到指定的时间 [-]hh:mm:ss[.xxx]的格式也支持 
- -title string 设置标题 
- -author string 设置作者 
- -copyright string 设置版权 
- -hq 激活高质量设置 
- -aspect aspect 设置横纵比 4:3 16:9 或 1.3333 1.7777 
- -croptop size 设置顶部切除带大小 像素单位 
- -cropbottom size -cropleft size -cropright size 
- -padtop size 设置顶部补齐的大小 像素单位 
- -padbottom size -padleft size -padright size -padcolor color 设置补齐条颜色(hex,6个16进制的数,红:绿:兰排列,比如 000000代表黑色) 
- -bt tolerance 设置视频码率容忍度kbit/s 
- -maxrate bitrate设置最大视频码率容忍度 
- -minrate bitreate 设置最小视频码率容忍度 
- -bufsize size 设置码率控制缓冲区大小 
- -vcodec codec 强制使用codec编解码方式。 如果用copy表示原始编解码数据必须被拷贝。 
- -sameq 使用同样视频质量作为源(VBR) 
- -pass n 选择处理遍数(1或者2)。两遍编码非常有用。第一遍生成统计信息,第二遍生成精确的请求的码率 
- -passlogfile file 选择两遍的纪录文件名为file 
- -map file:stream 设置输入流映射 
- -debug 打印特定调试信息 
视频格式转换
| 12
 3
 4
 5
 
 | ffmpeg -i out.ogv -vcodec h264 out.mp4ffmpeg -i out.ogv -vcodec mpeg4 out.mp4
 ffmpeg -i out.ogv -vcodec libxvid out.mp4
 ffmpeg -i out.mp4 -vcodec wmv1 out.wmv
 ffmpeg -i out.mp4 -vcodec wmv2 out.wmv
 
 | 
视频剪切
- -ss 指定从什么时间开始
- -t 指定需要截取多长时间
- -i 指定输入文件
| 1
 | ffmpeg -ss 00:00:00 -t 00:00:30 -i test.mp4 -vcodec copy -acodec copy output.mp4
 | 
合并视频
| 12
 
 | //进行视频的合并ffmpeg -f concat -i list.txt -c copy concat.mp4
 
 | 
在list.txt文件中,对要合并的视频片段进行了描述。
| 12
 
 | file 'split.mp4'file 'split1.mp4'
 
 | 
帧间编码转换为帧内编码 文件会大很多
- -i 输入,后面是空格,紧跟着就是输入视频文件;
- INPUT 输入文件;
- -sameq 表示保持同样的视频质量;
- -intra, 帧内编码;
- OUTPUT 输出文件名。
| 1
 | ffmpeg -i ./MyVideo.mpg -sameq -intra ./temp.mpg
 | 
这个命令的结果文件就是./temp.mpg.这个文件的视频和./MyVideo.mpg是一样的,但是你会发现这个文件会比./MyVideo.mpg大很多倍,原因就是转换前一般采用的帧间编码,转换后变成了帧内编码。这里我们说是一般,原因是有些视频文件本身就采用了帧内编码。
经过这样的处理后,我们就可以精确的剪切视频了。
新版本命令
| 1
 | ffmpeg -i output.mp4 -strict -2  -qscale 0 -intra keyoutput.mp4
 | 
m3u8视频合并
| 1
 | ffmpeg -i xxx.m3u8 -vcodec copy -acodec copy xxx.mp4
 | 
去掉视频中的音频
-an: 去掉音频;-vcodec:视频选项,一般后面加copy表示拷贝
| 1
 | ffmpeg -i input.mp4 -vcodec copy -an output.mp4
 | 
音视频合成
-y 覆盖输出文件
| 12
 
 | ffmpeg -y –i input.mp4 –i input.mp3 –vcodec copy –acodec copy output.mp4ffmpeg -i 01v.mp4 -i 01a.m4a -c:v copy -c:a aac -strict experimental 01.mp4
 
 | 
FFmpeg批量提取视频某一帧作为封面
| 1
 | ffmpeg -i input.flv -ss 00:00:02 -frames:v 1 out.png
 | 
将视频提取10帧
| 1
 | ffmpeg -i test.mp4 -r 10 %06d.jpg;
 | 
生产视频的每分钟的缩略图:
| 1
 | ffmpeg -i film.mp4 -vf fps=1/60 img%03d.jpg
 | 
- 上面这个-vf fps=1/60,就是1分钟的意思,比如说视频25分钟,会生成25个jpg图片,分别是img001,img002….,
- 当fps=1的时候:就代表每一秒截取个缩略图
- 而fps=1/600:则代表每10分钟截取一个画面
另外也可以按照关键帧提取画面依次产生画面保存起来,可以按照以下的参数:
| 1
 | ffmpeg -skip_frame nokey -i my-film.mp4 -vsync 0 -f image2 myfilm/my-film-%06d.png
 | 
- -vsync 0参数避免了需要指定帧速率
- my-file-%06d.png保存的文件名字是6个数字
视频截图
-s 设置分辨率; -f 强迫采用格式fmt;
| 1
 | ffmpeg –i test.mp4 –f image2 -t 0.001 -s 320x240 image-%3d.jpg
 | 
视频分解为图片
-r 指定截屏频率
| 1
 | ffmpeg –i test.mp4 –r 1 –f image2 image-%3d.jpg
 | 
将图片合成视频
| 1
 | ffmpeg -f image2 -i image%d.jpg output.mp4
 | 
视频拼接
| 1
 | ffmpeg -f concat -i filelist.txt -c copy output.mp4
 | 
旋转视频
| 1
 | ffmpeg -i input.mp4 -vf rotate=PI/2 output.mp4
 | 
缩放视频
iw 是输入的宽度, iw/2就是一半;-1 为保持宽高比
| 1
 | ffmpeg -i input.mp4 -vf scale=iw/2:-1 output.mp4
 | 
视频变速
| 1
 | ffmpeg -i input.mp4 -filter:v setpts=0.5*PTS output.mp4
 | 
音视频同时变速,但是音视频为互倒关系
| 1
 | ffmpeg -i input.mp4 -filter_complex "[0:v]setpts=0.5*PTS[v];[0:a]atempo=2.0[a]" -map "[v]" -map "[a]" output.mp4
 | 
视频添加水印
main_w-overlay_w-10 视频的宽度-水印的宽度-水印边距;
| 1
 | ffmpeg -i input.mp4 -i logo.jpg -filter_complex [0:v][1:v]overlay=main_w-overlay_w-10:main_h-overlay_h-10[out] -map [out] -map 0:a -codec:a copy output.mp4
 | 
视频压缩
| 1
 | ffmpeg -i a.mp4 -r 10 -b:a 32k 1.mp4
 | 
截取视频局部
| 1
 | ffmpeg -i in.mp4 -filter:v "crop=out_w:out_h:x:y" out.mp4
 | 
截取视频局部
| 12
 
 | // 截取部分视频,从[80,60]的位置开始,截取宽200,高100的视频ffmpeg -i in.mp4 -filter:v "crop=80:60:200:100" -c:a copy out.mp4
 
 | 
截取右下角的四分之一
| 1
 | ffmpeg -i in.mp4 -filter:v "crop=in_w/2:in_h/2:in_w/2:in_h/2" -c:a copy out.mp4
 | 
截去底部40像素高度
| 1
 | ffmpeg -i in.mp4 -filter:v "crop=in_w:in_h-40" -c:a copy out.mp4
 | 
调整视频大小(resize)是改变视频的宽度和高度
使用-s参数实现,语法:ffmpeg  -i  input_file  -s  wxh  output_file (wxh是宽x高,比如320x240)
| 1
 | ffmpeg -i demo.mp4 -s 960x540 demo1.mp4
 | 
视频裁剪
视频裁剪使用crop视频滤镜,它可以把视频从指定的x、y位置裁剪成指定的w、h。坐标系是基于左上点开始的。
| 1
 | ffmpeg  -i  intput.avi  -vf  crop=iw/2:ih/2  output.avi 
 | 
视频裁剪
视频裁剪使用crop视频滤镜,它可以把视频从指定的x、y位置裁剪成指定的w、h。坐标系是基于左上点开始的。
| 12
 
 | ffmpeg -hwaccel cuda -i 输入视频.mp4 -vf "crop=宽度:高度:起始X坐标:起始Y坐标" -c:v h264_nvenc 输出视频.mp4ffmpeg -hwaccel cuda -i intput.avi -vf crop=iw/2:ih/2 output.avi
 
 | 
mp4转h.264
| 1
 | ffmpeg -i input.mp4 -vcodec h264 output.mp4
 | 
腾讯视频qlv转mp4
| 1
 | copy/B 7*.tdl Video001.mp4
 | 
单个文件
| 1
 | ffmpeg -i "input.flv" -c copy "output.mp4"
 | 
批量转换
| 1
 | for %i in (*.flv) do ffmpeg -i "%i" -c copy "%~ni.mp4"
 | 
某些flv文件转换成mp4时会报错,这时可尝试以下代码
| 1
 | ffmpeg -i filename.flv -c:v libx264 -crf 19 -strict experimental filename.mp4
 | 
flv/mp4文件的合并
| 1
 | ffmpeg -f concat -safe 0 -i combine.txt -c copy output.mp4
 | 
combine.txt
| 12
 3
 4
 5
 
 | file '文件1.mp4'file '文件2.mp4'
 file '文件3.mp4'
 file '文件4.mp4'
 file '文件5.mp4'
 
 | 
音频操作
音频变速
| 1
 | ffmpeg -i input.mp3 -filter:a atempo=2.0 output.mp3
 | 
mp3剪切
| 1
 | ffmpeg -y -i input.wav -ss 00:00:00 -t 00:08:52 -acodec copy output_mp3.wav
 | 
提取视频中的音频
-vn: 去掉视频;-acodec: 音频选项, 一般后面加copy表示拷贝
| 1
 | ffmpeg -i input.mp4 -acodec copy -vn output.wma
 | 
音频转换
| 12
 
 | ffmpeg -i qishi.mp3 -acodec aac qishi.aacffmpeg -i qishi.acc -acodec mp3 qishi.mp3
 
 | 
m4a添加封面
| 1
 | ffmpeg -i 1.m4a -i 1.png -map 0 -map 1 -c copy -disposition:v:0 attached_pic output.m4a
 | 
gif操作
尽量不要使用swscale做缩放了,尽量使用ffmpeg里的avfilter的滤镜。
查看图片信息
将视频转为gif
| 1
 | ffmpeg -i input.mp4 out.gif 
 | 
将 GIF 转化为 MP4
| 12
 3
 4
 
 | ffmpeg -f gif -i test.gif test.mp4
 ffmpeg -f gif -i test.gif test.mpeg
 ffmpeg -f gif -i test.gif test.mkv
 
 | 
转化高质量 GIF
默认转化是中等质量模式,若要转化出高质量的 gif,可以修改比特率
| 1
 | ffmpeg -i test.mp4 -b:v 2048k test.gif
 | 
设置截取时间
- -ss -ss代表的是开始时间,时:分:秒.毫秒的格式,比如00:12:14.500。
- -t是要截取的时长,单位秒
| 12
 
 | ffmpeg -i input.mp4 -ss 73.5 -t 12 out.gifffmpeg -i input.mp4 -ss 00:01:13.500 -t 12 out.gif
 
 | 
将视频转为gif
-pix_fmt 指定编码
| 1
 | ffmpeg -i input.mp4 -ss 0:0:30 -t 10 -s 320x240 -pix_fmt rgb24 output.gif
 | 
将视频前30帧转为gif
| 1
 | ffmpeg -i input.mp4 -vframes 30 -f gif output.gif
 | 
gif压缩
降低动图的帧率
用-r参数来降低征率,比如原始的input.mp4是30帧的,可以用-r 15来降低成15帧。
-r参数一定要放到-i参数后面,它在前在后的作用是不一样的
具体效果也是很明显的,生成的文件大小从原来的86MB下降到56MB,具体命令行如下:
| 12
 
 | ffmpeg -i input.mp4 -ss 00:01:13.500 -t 12 -r 15 out1.gifffmpeg -i input.gif -r 8 out1.gif
 
 | 
调整画面分辨率
比如原始视频是1080p的,我们可以将其减低到480p,从而显著降低最终的gif文件大小,
这里可以使用-s参数,后面跟具体的分辨率大小比如480x272 具体命令如下:
| 12
 
 | ffmpeg -i input.mp4 -ss 00:01:13.500 -t 12 -s 480x272 out2.gif ffmpeg -i input.gif -s 320x180 out2.gif
 
 | 
-vf等比例缩放
scale后面可以指定具体的分辨率宽:高,作用同-s,也可以只指定宽或者高,
另一者用-d代替,ffmpeg就会自动缩放,保持原比例
| 1
 | ffmpeg -i input.mp4 -ss 00:01:13.500 -t 12 -vf "scale=480:-1" out3.gif  
 | 
降分辨率的同时降帧率
将上面两种方式结合到一起,命令行如下:
| 1
 | ffmpeg -i input.mp4 -ss 00:01:13.500 -t 12 -vf "scale=480:-1" -r 15 out4.gif 
 | 
裁剪
裁剪区域的宽度为180,高度为180,
从以左上角为原点、x轴向右偏移量为100、y轴向下偏移量为0的位置开始裁剪。
| 1
 | ffmpeg -i input.gif -vf "crop=180:180:100:0" output.gif
 | 
滤镜的排列组合,实现各种各样复杂的功能
FFmpeg滤镜共包含以下3个层级:
filter -> filterchain -> filtergraph 也即 滤镜 -> 滤镜链 -> 滤镜图
多个滤镜可以串联成一条滤镜链,多条滤镜链可以组合成一个滤镜图。
- 首先,使用split滤镜将输入流分割为两个流[main]和[tmp] (你可以理解为copy了一份);
- 将其中一个流[tmp]先通过crop滤镜裁剪出左半部分;
- 将步骤2的输出再经过hflip滤镜进行水平翻转,并输出为[flip];
- 把步骤3的输出[flip]叠加到[main]的右半部分。
| 1
 | ffmpeg -i input.gif -vf "split[main][tmp];[tmp]crop=iw/2:ih:0:0,hflip[flip];[main][flip]overlay=W/2:0" output.gif
 | 
高质量gif优化
原文链接
整理资料
经过上面的分析,视频转gif,
考虑大小使用单一色板,这样对图片压缩好,但是相对使用色板难度较高,如果使用原图生成的色板,可能会失去部分色彩。并且要跑两次程序,一次生成色板,一次抖色。
考虑失真情况,每张图生成一个色板,这个是screentogif使用的方案。效果好,色彩优异。
综合考虑,使用rgb8的色板,进行抖色。这个方案会有噪点,但是体积控制较好,色彩比格式工厂优异
命令行指令
考虑大小版本
| 1
 | ffmpeg -i “H:\样本.mp4” -s 320x180 -vf “[in]scale=320x180,split[split1][split2];[split1]palettegen[pal];[split2][pal]paletteuse” H:\FFOutput\test.gif
 | 
注意-s的尺寸务必与scale一致,否则会造成二次损失,另外如果帧数超过300建议先生成色板再抖色编码,速度很慢
考虑色彩版本
| 1
 | ffmpeg -i “H:\样本.mp4” -s 320x180 -vf “[in]scale=320x180,split[split1][split2];[split1]palettegen=stats_mode=diff[pal];[split2][pal]paletteuse=new=1:diff_mode=rectangle” H:\FFOutput\test.gif
 | 
2021/4/7分析源码后调整因为矩阵扫描会用上一次调色板,调试板是不能变化的,修复bug问题
| 1
 | ffmpeg -i “H:\样本.mp4” -s 320x180 -vf “[in]scale=320x180,split[split1][split2];[split1]palettegen=stats_mode=single[pal];[split2][pal]paletteuse=new=1” H:\FFOutput\test.gif
 | 
注意事项 -s要与scale一致,可以超过300帧速度相对慢
添加文字
| 1
 | ffmpeg -i input.gif -vf "drawtext=fontsize=30:text='吔屎啦你':fontcolor=white:x=25:y=100:fontfile=JingNanYuanMoTi/KNFONTYUANMO-2.otf" output.gif
 | 
多宫格处理
- 首先,通过-i 选项输入4张待处理的静态图素材;
- 其次,通过-filter_complex 选项创建一个复杂滤镜;
- 该复杂滤镜首先创建了一个360x360的空白画布,并指定输出流的标签为[base];
- [0:v]表示取第一个输入流(第1张静态图),然后使用overlay滤镜,将第1张静态图叠加到左上角原点的位置(也即左上角),并指定叠加处理输出流的标签为[tmp1];
- 继续使用overlay滤镜,将第2张静态图叠加到以左上角原点,x轴向右偏移量为180、y轴向下偏移量为0的位置(也即右上角),并指定叠加处理输出流的标签为[tmp2];
- 继续使用overlay滤镜,将第3张静态图叠加到以左上角原点,x轴向右偏移量为0、y轴向下偏移量为180的位置(也即左下角),并指定叠加处理输出流的标签为[tmp3];
- 继续使用overlay滤镜,将第4张静态图叠加到以左上角原点,x轴向右偏移量为180、y轴向下偏移量为180的位置(也即右下角);
- 将全部处理完成的内容输出到一个名为“output.jpg”的文件
| 1
 | ffmpeg -i 1.jpg -i 2.jpg -i 3.jpg -i 4.jpg -filter_complex "nullsrc=size=360x360[base];[base][0:v]overlay=0:0[tmp1];[tmp1][1:v]overlay=180:0[tmp2];[tmp2][2:v]overlay=0:180[tmp3];[tmp3][3:v]overlay=180:180" -frames:v 1 output.jpg
 |