今日主题:ffmpeg的常用的一些命令
ffmpeg到底是啥,为什么要讲这个工具呢?它的牛逼之处在于现在的大部分视频剪辑软件底层都用到了这款工具,他可以对视频进行各种操作,剪辑都可以的,我就讲一下一些简单的命令吧。
参考:https://blog.csdn.net/weixin_42081389/article/details/100543007
ffmpeg可视化界面软件:Quick Cut
参考:https://zhuanlan.zhihu.com/p/163652478
ffmpeg一些命令参数:
在这里插入图片描述
通用选项
命令 | 解释 |
---|---|
-L | license |
-h | 帮助 |
-fromats | 显示可用的格式,编解码的,协议的。。。 |
-f fmt | 强迫采用格式fmt |
-I filename | 输入文件 |
-y | 覆盖输出文件 |
-t duration | 设置纪录时间 hh:mm:ss[.xxx]格式的记录时间也支持 |
-ss position | 搜索到指定的时间 [-]hh:mm:ss[.xxx]的格式也支持 |
-title string | 设置标题 |
-author string | 设置作者 |
-copyright string | 设置版权 |
-comment string | 设置评论 |
-target type | 设置目标文件类型(vcd,svcd,dvd) 所有的格式选项(比特率,编解码以及缓冲区大小)自动设置 ,只需要输入如下的就可以了:ffmpeg -i myfile.avi -target vcd /tmp/vcd.mpg |
-hq | 激活高质量设置 |
-itsoffset offset | 设置以秒为基准的时间偏移,该选项影响所有后面的输入文件。该偏移被加到输入文件的时戳,定义一个正偏移意味着相应的流被延迟了 offset秒。[-]hh:mm:ss[.xxx]的格式也支持 |
视频选项
命令 | 解释 |
---|---|
-b bitrate | 设置比特率,缺省200kb/s |
-r fps | 设置帧频 缺省25 |
-s size | 设置帧大小 格式为WXH 缺省160X128.下面的简写也可以直接使用:Sqcif 128X96 qcif 176X144 cif 252X288 4cif 704X576 |
-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代表黑色) |
-vn | 不做视频记录 |
-bt tolerance | 设置视频码率容忍度kbit/s |
-maxrate bitrate | 设置最大视频码率容忍度 |
-minrate bitreate | 设置最小视频码率容忍度 |
-bufsize size | 设置码率控制缓冲区大小 |
-vcodec codec | 强制使用codec编解码方式。如果用copy表示原始编解码数据必须被拷贝。 |
-sameq | 使用同样视频质量作为源(VBR) |
-pass n | 选择处理遍数(1或者2)。两遍编码非常有用。第一遍生成统计信息,第二遍生成精确的请求的码率 |
-passlogfile file | 选择两遍的纪录文件名为file |
高级视频选项
命令 | 解释 |
---|---|
-g gop_size | 设置图像组大小 |
-intra | 仅适用帧内编码 |
-qscale q | 使用固定的视频量化标度(VBR) |
-qmin q | 最小视频量化标度(VBR) |
-qmax q | 最大视频量化标度(VBR) |
-qdiff q | 量化标度间最大偏差 (VBR) |
-qblur blur | 视频量化标度柔化(VBR) |
-qcomp compression | 视频量化标度压缩(VBR) |
-rc_init_cplx complexity | 一遍编码的初始复杂度 |
-b_qfactor factor | 在p和b帧间的qp因子 |
-i_qfactor factor | 在p和i帧间的qp因子 |
-b_qoffset offset | 在p和b帧间的qp偏差 |
-i_qoffset offset | 在p和i帧间的qp偏差 |
-rc_eq equation | 设置码率控制方程 默认tex^qComp |
-rc_override override | 特定间隔下的速率控制重载 |
-me method | 设置运动估计的方法 可用方法有 zero phods log x1 epzs(缺省) full |
-dct_algo algo | 设置dct的算法 可用的有 0 FF_DCT_AUTO 缺省的DCT 1 FF_DCT_FASTINT 2 FF_DCT_INT 3 FF_DCT_MMX 4 FF_DCT_MLIB 5 FF_DCT_ALTIVEC |
-idct_algo algo | 设置idct算法。可用的有 0 FF_IDCT_AUTO 缺省的IDCT 1 FF_IDCT_INT 2 FF_IDCT_SIMPLE 3 FF_IDCT_SIMPLEMMX 4 FF_IDCT_LIBMPEG2MMX 5 FF_IDCT_PS2 6 FF_IDCT_MLIB 7 FF_IDCT_ARM 8 FF_IDCT_ALTIVEC 9 FF_IDCT_SH4 10 FF_IDCT_SIMPLEARM |
-er n | 设置错误残留为n 1 FF_ER_CAREFULL 缺省 2 FF_ER_COMPLIANT 3 FF_ER_AGGRESSIVE 4 FF_ER_VERY_AGGRESSIVE |
-ec bit_mask | 设置错误掩蔽为bit_mask,该值为如下值的位掩码 1 FF_EC_GUESS_MVS (default=enabled) 2 FF_EC_DEBLOCK (default=enabled) |
-bf frames | 使用frames B 帧,支持mpeg1,mpeg2,mpeg4 |
-mbd mode | 宏块决策 0 FF_MB_DECISION_SIMPLE 使用mb_cmp 1 FF_MB_DECISION_BITS 2 FF_MB_DECISION_RD |
-4mv | 使用4个运动矢量 仅用于mpeg4 |
-part | 使用数据划分 仅用于mpeg4 |
-bug param | 绕过没有被自动监测到编码器的问题 |
-strict strictness | 跟标准的严格性 |
-aic | 使能高级帧内编码 h263 |
-umv | 使能无限运动矢量 h263 |
-deinterlace | 不采用交织方法 |
-interlace | 强迫交织法编码 仅对mpeg2和mpeg4有效。当你的输入是交织的并且你想要保持交织以最小图像损失的时候采用该选项。可选的方法是不交织,但是损失更大 |
-psnr | 计算压缩帧的psnr |
-vstats | 输出视频编码统计到vstats_hhmmss.log |
-vhook module | 插入视频处理模块 module 包括了模块名和参数,用空格分开 |
音频选项
命令 | 解释 |
---|---|
-ab bitrate | 设置音频码率 |
-ar freq | 设置音频采样率 |
-ac channels | 设置通道 缺省为1 |
-an | 不使能音频纪录 |
-acodec codec | 使用codec编解码 |
音频/视频捕获选项
命令 | 解释 |
---|---|
-vd device | 设置视频捕获设备。比如/dev/video0 |
-vc channel | 设置视频捕获通道 DV1394专用 |
-tvstd standard | 设置电视标准 NTSC PAL(SECAM) |
-dv1394 | 设置DV1394捕获 |
-av device | 设置音频设备 比如/dev/dsp |
高级选项
命令 | 解释 |
---|---|
-map file:stream | 设置输入流映射 |
-debug | 打印特定调试信息 |
-benchmark | 为基准测试加入时间 |
-hex | 倾倒每一个输入包 |
-bitexact | 仅使用位精确算法 用于编解码测试 |
-ps size | 设置包大小,以bits为单位 |
-re | 以本地帧频读数据,主要用于模拟捕获设备 |
-loop | 循环输入流。只工作于图像流,用于ffserver测试 |
avi转MP4命令:
代码语言:javascript复制ffmpeg -i .Video.avi -c copy -map 0 video.mp4
或
ffmpeg -i .Video.avi -c:v libx264 -crf 19 -preset slow -c:a aac -b:a 192k -ac 2 video.mp4
//剪切视频
ffmpeg -ss 0:1:30 -t 0:0:50 -i 1.avi -vcodec copy -acodec copy 3.mp4
//-r 提取图像的频率,-ss 开始时间,-t 持续时间
MP4转ts
代码语言:javascript复制ffmpeg -i .video.mp4 output.ts
视频压缩
代码语言:javascript复制 1)ffmpeg -i 123_ffmpeg.mp4 (压缩的文件更大更清晰,一般情况下不用)
2)ffmpeg.exe -i 123.MP4 -b:v 700k 1231_ffmpeg.mp4(压缩的更小,相对模糊一些)
去除视频声音
代码语言:javascript复制 ffmpeg -i 1.avi -vcodec copy -an 2.avi
合并音频和视频
代码语言:javascript复制ffmpeg -i a.wav -i a.avi out.avi
若音频比视频长,画面停留在最后一帧,继续播放声音。
给视频添加水印
代码语言:javascript复制ffmpeg -i result2.mp4 -vf "drawtext=fontfile=FZBaoHTJW_Xi.TTF: text='创作者:奮乧妑_仯姩':x=100:y=10:fontsize=24:fontcolor=yellow:shadowy=2" drawtext.mp4
视频剪辑
代码语言:javascript复制//截取从头开始的30s
ffmpeg -ss 00:00:00 -t 00:00:30 -i keyoutput.mp4 -vcodec copy -acodec copy split.mp4
//截取从30s开始的30s
ffmpeg -ss 00:00:30 -t 00:00:30 -i keyoutput.mp4 -vcodec copy -acodec copy split1.mp4
给视频添加字幕srt
参考:https://moejj.com/ffmpeg-add-subtitles-and-watermark/
ffmpeg -i video.avi -vf subtitles=subtitle.srt out.avi
同时给视频添加音乐 字幕
代码语言:javascript复制ffmpeg -i .1111.mp4 -i .2222.mp3 -vf subtitles=all_mp3_srt.srt out2.avi
使用ffmpeg webm 转换 mp4
参考:http://www.voidcn.com/article/p-evqojtvk-bta.html
ffmpeg -fflags genpts -i .111.webm -r 24 1.mp4
解释:
- -r 24 代码生成的视频时24帧,你也可以改成30或者60
- -i .111.webm 111.webm 是我的当前目录下 webm格式的视频
- 1.mp4 会在当前目录下生成 这个mp4视频
合并俩个mp4视频
先创建一个name.txt
代码语言:javascript复制file 'split1.mp4'
file 'split2.mp4'
在这里插入图片描述
命令合并
代码语言:javascript复制ffmpeg -f concat -i name.txt -c copy output.mp4
在这里插入图片描述
视频格式使用
ffmpeg -i 1.mp4 -vcodec mpeg2video -s 1920x1080 -q:v 1 -acodec copy -f mpegts 2.flv
转换格式的视频清晰度还可以
用java代码来进行操作
代码语言:javascript复制/**
* 简易视频处理 -- (cmd(windows): ffmpeg.exe -i test1.mp4 newVideo.avi)
*
* @param ffmpegPath ffmpeg.exe文件路径,可在rest或者admin中进行配置,使用配置文件进行读取
* @param videoInputPath 视频文件路径(输入)
* @param videoOutputPath 转换完成的文件路径(输出)
* @throws IOException
*/
public static void videoConvert(String ffmpegPath, String videoInputPath, String videoOutputPath) throws IOException {
// 构建命令
String videoCommend=ffmpegPath " -i " videoInputPath " -vcodec mpeg2video -s 1920x1080 -q:v 1 -acodec copy -f mpegts " videoOutputPath;
// 执行操作
ProcessBuilder builder = new ProcessBuilder(videoCommend.split(" "));
Process process = builder.start();
InputStream errorStream = process.getErrorStream();
InputStreamReader isr = new InputStreamReader(errorStream);
BufferedReader br = new BufferedReader(isr);
String line = "";
while ((line = br.readLine()) != null) {
}
if (br != null) {
br.close();
}
if (isr != null) {
isr.close();
}
if (errorStream != null) {
errorStream.close();
}
}
提取视频中的音频和视频
提取某个视频的纯视频不包含音频:
代码语言:javascript复制ffmpeg -i E:hevc2.mp4 -vcodec copy -an E:hevc2_bak.mp4
提取某个视频中的音频文件:
代码语言:javascript复制ffmpeg -i E:hevc2.mp4 -acodec libmp3lame -vn E:hevc2_copy.mp3
其他音频格式:https://blog.csdn.net/zhubao124/article/details/104740770
合并音频和视频
前提是这个视频里没有音频
代码语言:javascript复制ffmpeg.exe -i C:Users29265Desktop像鱼.mp3 -i C:Users29265Desktop12_copy.mp4 -t 300 -y C:Users29265Desktop1newVideo.mp4
视频按帧截图
参考:https://zhuanlan.zhihu.com/p/38961122
主要用于用户手动截图或者上传视频生成缩略图。
此处:-ss position 搜索到指定的时间 [-]hh:mm:ss[.xxx]的格式也支持,-vframes 设置转换多少桢(frame)的视频,此命令是获取第一秒第一帧的截图。
注:生成的截图最好使用jpg格式,占用空间较小,如果需要使用其他格式,根据业务需求自行设置即可。
代码语言:javascript复制ffmpeg.exe -ss 00:00:01 -y -i test1.mp4 -vframes 1 new.jpg
用java代码来实现:
代码语言:javascript复制/**
* 音视频合并,视频结束,音频结束 -- (cmd(windows): ffmpeg.exe -i test2.mp3 -i test1.mp4 -t 10 -y newVideo.mp4)
*
* @param ffmpegPath ffmpeg.exe文件路径,可在rest或者admin中进行配置,使用配置文件进行读取
* @param audioInputPath 音频文件路径(输入)
* @param videoInputPath 视频文件路径(输入)
* @param time 文件时长
* @param videoOutputPath 转换完成的文件路径(输出)
* @throws IOException
*/
public static void audioVideoMerge(String ffmpegPath, String audioInputPath, String videoInputPath, double time, String videoOutputPath) throws IOException {
// 构建命令
List<String> command = Lists.newArrayList();
command.add(ffmpegPath);
command.add("-i");
command.add(audioInputPath);
command.add("-i");
command.add(videoInputPath);
command.add("-t");
command.add(String.valueOf(time));
command.add("-y");
command.add(videoOutputPath);
// 执行操作
ProcessBuilder builder = new ProcessBuilder(command);
Process process = builder.start();
InputStream errorStream = process.getErrorStream();
InputStreamReader isr = new InputStreamReader(errorStream);
BufferedReader br = new BufferedReader(isr);
String line = "";
while ((line = br.readLine()) != null) {
}
if (br != null) {
br.close();
}
if (isr != null) {
isr.close();
}
if (errorStream != null) {
errorStream.close();
}
}