一、视频转码
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;
import com.wdy.common.Contants;
public class ConverVideoUtils {
private Date dt;
private long begintime;
private String sourceVideoPath;//源视频路径
private String filerealname; // 文件名 不包括扩展名
private String filename; // 包括扩展名
private String videofolder = Contants.videofolder; // 别的格式视频的目录
private String targetfolder = Contants.targetfolder; // flv视频的目录
private String ffmpegpath = Contants.ffmpegpath; // ffmpeg.exe的目录
private String mencoderpath = Contants.mencoderpath; // mencoder的目录
private String imageRealPath = Contants.imageRealPath; // 截图的存放目录
public ConverVideoUtils() {
}
public ConverVideoUtils(String path) {
sourceVideoPath = path;
}
public String getPATH() {
return sourceVideoPath;
}
public void setPATH(String path) {
sourceVideoPath = path;
}
/**
* 转换视频格式
* @param String targetExtension 目标视频扩展名 .xxx
* @param isDelSourseFile 转换完成后是否删除源文件
* @return
*/
public boolean beginConver(String targetExtension, boolean isDelSourseFile) {
File fi = new File(sourceVideoPath);
filename = fi.getName();
filerealname = filename.substring(0, filename.lastIndexOf(".")).toLowerCase();
System.out.println("----接收到文件(" + sourceVideoPath + ")需要转换-------------------------- ");
if (!checkfile(sourceVideoPath)) {
System.out.println(sourceVideoPath + "文件不存在" + " ");
return false;
}
dt = new Date();
begintime = dt.getTime();
System.out.println("----开始转文件(" + sourceVideoPath + ")-------------------------- ");
if (process(targetExtension,isDelSourseFile)) {
Date dt2 = new Date();
System.out.println("转换成功 ");
long endtime = dt2.getTime();
long timecha = (endtime - begintime);
String totaltime = sumTime(timecha);
System.out.println("转换视频格式共用了:" + totaltime + " ");
if (processImg(sourceVideoPath)) {
System.out.println("截图成功了! ");
} else {
System.out.println("截图失败了! ");
}
if (isDelSourseFile) {
deleteFile(sourceVideoPath);
}
sourceVideoPath = null;
return true;
} else {
sourceVideoPath = null;
return false;
}
}
/**
* 对视频进行截图
* @param sourceVideoPath 需要被截图的视频路径(包含文件名和扩展名)
* @return
*/
public boolean processImg(String sourceVideoPath) {
if (!checkfile(sourceVideoPath)) {
System.out.println(sourceVideoPath + " is not file");
return false;
}
File fi = new File(sourceVideoPath);
filename = fi.getName();
filerealname = filename.substring(0, filename.lastIndexOf(".")).toLowerCase();
List<String> commend = new java.util.ArrayList<String>();
//第一帧: 00:00:01
//time ffmpeg -ss 00:00:01 -i test1.flv -f image2 -y test1.jpg
commend.add(ffmpegpath);
// commend.add("-i");
// commend.add(videoRealPath + filerealname + ".flv");
// commend.add("-y");
// commend.add("-f");
// commend.add("image2");
// commend.add("-ss");
// commend.add("38");
// commend.add("-t");
// commend.add("0.001");
// commend.add("-s");
// commend.add("320x240");
commend.add("-ss");
commend.add("00:00:01");
commend.add("-i");
commend.add(sourceVideoPath);
commend.add("-f");
commend.add("image2");
commend.add("-y");
commend.add(imageRealPath + filerealname + ".jpg");
try {
ProcessBuilder builder = new ProcessBuilder();
builder.command(commend);
builder.start();
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 实际转换视频格式的方法
* @param targetExtension 目标视频扩展名
* @param isDelSourseFile 转换完成后是否删除源文件
* @return
*/
private boolean process(String targetExtension, boolean isDelSourseFile) {
int type = checkContentType();
boolean status = false;
if (type == 0) {
//如果type为0用ffmpeg直接转换
status = processVideoFormat(sourceVideoPath,targetExtension, isDelSourseFile);
} else if (type == 1) {
//如果type为1,将其他文件先转换为avi,然后在用ffmpeg转换为指定格式
String avifilepath = processAVI(type);
if (avifilepath == null){
// avi文件没有得到
return false;
}else {
System.out.println("开始转换:");
status = processVideoFormat(avifilepath,targetExtension, isDelSourseFile);
}
}
return status;
}
/**
* 检查文件类型
* @return
*/
private int checkContentType() {
String type = sourceVideoPath.substring(sourceVideoPath.lastIndexOf(".") + 1, sourceVideoPath.length()).toLowerCase();
// ffmpeg能解析的格式:(asx,asf,mpg,wmv,3gp,mp4,mov,avi,flv等)
if (type.equals("avi")) {
return 0;
} else if (type.equals("mpg")) {
return 0;
} else if (type.equals("wmv")) {
return 0;
} else if (type.equals("3gp")) {
return 0;
} else if (type.equals("mov")) {
return 0;
} else if (type.equals("mp4")) {
return 0;
} else if (type.equals("asf")) {
return 0;
} else if (type.equals("asx")) {
return 0;
} else if (type.equals("flv")) {
return 0;
}
// 对ffmpeg无法解析的文件格式(wmv9,rm,rmvb等),
// 可以先用别的工具(mencoder)转换为avi(ffmpeg能解析的)格式.
else if (type.equals("wmv9")) {
return 1;
} else if (type.equals("rm")) {
return 1;
} else if (type.equals("rmvb")) {
return 1;
}
return 9;
}
/**
* 检查文件是否存在
* @param path
* @return
*/
private boolean checkfile(String path) {
File file = new File(path);
if (!file.isFile()) {
return false;
} else {
return true;
}
}
/**
* 对ffmpeg无法解析的文件格式(wmv9,rm,rmvb等), 可以先用别的工具(mencoder)转换为avi(ffmpeg能解析的)格式.
* @param type
* @return
*/
private String processAVI(int type) {
List<String> commend = new java.util.ArrayList<String>();
commend.add(mencoderpath);
commend.add(sourceVideoPath);
commend.add("-oac");
commend.add("mp3lame");
commend.add("-lameopts");
commend.add("preset=64");
commend.add("-ovc");
commend.add("xvid");
commend.add("-xvidencopts");
commend.add("bitrate=600");
commend.add("-of");
commend.add("avi");
commend.add("-o");
commend.add(videofolder + filerealname + ".avi");
// 命令类型:mencoder 1.rmvb -oac mp3lame -lameopts preset=64 -ovc xvid
// -xvidencopts bitrate=600 -of avi -o rmvb.avi
try {
ProcessBuilder builder = new ProcessBuilder();
builder.command(commend);
Process p = builder.start();
doWaitFor(p);
return videofolder + filerealname + ".avi";
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 转换为指定格式
* ffmpeg能解析的格式:(asx,asf,mpg,wmv,3gp,mp4,mov,avi,flv等)
* @param oldfilepath
* @param targetExtension 目标格式扩展名 .xxx
* @param isDelSourseFile 转换完成后是否删除源文件
* @return
*/
private boolean processVideoFormat(String oldfilepath, String targetExtension, boolean isDelSourceFile) {
if (!checkfile(sourceVideoPath)) {
System.out.println(oldfilepath + " is not file");
return false;
}
//ffmpeg -i FILE_NAME.flv -ar 22050 NEW_FILE_NAME.mp4
List<String> commend = new java.util.ArrayList<>();
commend.add(ffmpegpath);
commend.add("-i");
commend.add(oldfilepath);
commend.add("-ar");
commend.add("22050");
commend.add(targetfolder + filerealname + targetExtension);
try {
ProcessBuilder builder = new ProcessBuilder();
String cmd = commend.toString();
builder.command(commend);
Process p = builder.start();
doWaitFor(p);
p.destroy();
//转换完成后删除源文件
// if (isDelSourceFile) {
// deleteFile(sourceVideoPath);
// }
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* ffmpeg能解析的格式:(asx,asf,mpg,wmv,3gp,mp4,mov,avi,flv等)
* @param oldfilepath
* @return
*/
private boolean processFLV(String oldfilepath) {
if (!checkfile(sourceVideoPath)) {
System.out.println(oldfilepath + " is not file");
return false;
}
List<String> commend = new java.util.ArrayList<>();
commend.add(ffmpegpath);
commend.add("-i");
commend.add(oldfilepath);
commend.add("-ab");
commend.add("64");
commend.add("-acodec");
commend.add("mp3");
commend.add("-ac");
commend.add("2");
commend.add("-ar");
commend.add("22050");
commend.add("-b");
commend.add("230");
commend.add("-r");
commend.add("24");
commend.add("-y");
commend.add(targetfolder + filerealname + ".flv");
try {
ProcessBuilder builder = new ProcessBuilder();
String cmd = commend.toString();
builder.command(commend);
Process p = builder.start();
doWaitFor(p);
p.destroy();
deleteFile(oldfilepath);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public int doWaitFor(Process p) {
InputStream in = null;
InputStream err = null;
int exitValue = -1; // returned to caller when p is finished
try {
System.out.println("comeing");
in = p.getInputStream();
err = p.getErrorStream();
boolean finished = false; // Set to true when p is finished
while (!finished) {
try {
while (in.available() > 0) {
Character c = new Character((char) in.read());
System.out.print(c);
}
while (err.available() > 0) {
Character c = new Character((char) err.read());
System.out.print(c);
}
exitValue = p.exitValue();
finished = true;
} catch (IllegalThreadStateException e) {
Thread.currentThread().sleep(500);
}
}
} catch (Exception e) {
System.err.println("doWaitFor();: unexpected exception - " + e.getMessage());
} finally {
try {
if (in != null) {
in.close();
}
} catch (IOException e) {
System.out.println(e.getMessage());
}
if (err != null) {
try {
err.close();
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
return exitValue;
}
/**
二、测试的案例
package com.royLuo.main.converter.ffmpeg;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
public class Demo01 {
public static void main(String[] args) {
// test();
// test2();
// test3();
// test4();
test5();
// test6();
}
public static void test() {
ProcessBuilder processBuilder = new ProcessBuilder();
//定义命令内容
List<String> command = new ArrayList<String>();
command.add("D:\\luojunrong-gitee\\videoManage\\ffmpeg\\bin\\ffmpeg.exe");
command.add("-i");
//被转码的视频
command.add("D:\\测试视频\\20d008203b85e2ff85ba20f4c54b474f.mp4");
command.add("-y");//覆盖输出文件
command.add("-c:v");
command.add("libx264");
//设定画面的宽高
command.add("-s");
command.add("1280x720");
command.add("-pix_fmt");
command.add("yuv420p");
//音频码率
command.add("-b:a");
command.add("63k");
//视频码率
command.add("-b:v");
command.add("753k");
command.add("-r");
command.add("18");
command.add("D:\\luojunrong-gitee\\videoManage\\test-fmpeg\\1.rmvb");
processBuilder.command(command);
//将标准输入流和错误输入流合并,通过标准输入流读取信息
processBuilder.redirectErrorStream(true);
try {
//启动进程
Process start = processBuilder.start();
//获取输入流
InputStream inputStream = start.getInputStream();
//转成字符输入流
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "gbk");
int len = -1;
char[] c = new char[1024];
StringBuffer outputString = new StringBuffer();
//读取进程输入流中的内容
while ((len = inputStreamReader.read(c)) != -1) {
String s = new String(c, 0, len);
outputString.append(s);
System.out.print(s);
}
inputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 截取一张352x240尺寸大小的,格式为jpg的图片
* ffmpeg -i test.asf -y -f image2 -t 0.001 -s 352x240 a.jpg
**/
public static void test2() {
ProcessBuilder processBuilder = new ProcessBuilder();
//定义命令内容
// ffmpeg -i test.asf -y -f image2 -t 0.001 -s 352x240 a.jpg
List<String> command = new ArrayList<String>();
command.add("D:\\luojunrong-gitee\\videoManage\\ffmpeg\\bin\\ffmpeg.exe");
command.add("-i");
//被转码的视频
command.add("D:\\测试视频\\20d008203b85e2ff85ba20f4c54b474f.mp4");
command.add("-y");//覆盖输出文件
command.add("-f");
command.add("image2");
command.add("-t");
command.add("0.001");
//-s 设置分辨率
// command.add("-s");
// command.add("1280x720");
command.add("D:\\luojunrong-gitee\\videoManage\\test-fmpeg\\20d008203b85e2ff85ba20f4c54b474f.jpg");
processBuilder.command(command);
//将标准输入流和错误输入流合并,通过标准输入流读取信息
processBuilder.redirectErrorStream(true);
try {
//启动进程
Process start = processBuilder.start();
//获取输入流
InputStream inputStream = start.getInputStream();
//转成字符输入流
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "gbk");
int len = -1;
char[] c = new char[1024];
StringBuffer outputString = new StringBuffer();
//读取进程输入流中的内容
while ((len = inputStreamReader.read(c)) != -1) {
String s = new String(c, 0, len);
outputString.append(s);
System.out.print(s);
}
inputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/***
* 1秒24帧
* 把视频的前30帧转换成一个 gif
* ffmpeg -i test.asf -vframes 30 -y -f gif a.gif
* */
public static void test3() {
ProcessBuilder processBuilder = new ProcessBuilder();
//定义命令内容
// ffmpeg -i test.asf -vframes 30 -y -f gif a.gif
List<String> command = new ArrayList<String>();
command.add("D:\\luojunrong-gitee\\videoManage\\ffmpeg\\bin\\ffmpeg.exe");
command.add("-i");
//被转码的视频
command.add("D:\\测试视频\\20d008203b85e2ff85ba20f4c54b474f.mp4");
command.add("-vframes");
command.add("72");
command.add("-y");
command.add("-f");
command.add("gif");
// 1280x720 高清
// 1920×1080 超清
// command.add("-s");
// command.add("1280x720");
command.add("D:\\luojunrong-gitee\\videoManage\\test-fmpeg\\20d008203b85e2ff85ba20f4c54b474f.gif");
processBuilder.command(command);
//将标准输入流和错误输入流合并,通过标准输入流读取信息
processBuilder.redirectErrorStream(true);
try {
//启动进程
Process start = processBuilder.start();
//获取输入流
InputStream inputStream = start.getInputStream();
//转成字符输入流
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "gbk");
int len = -1;
char[] c = new char[1024];
StringBuffer outputString = new StringBuffer();
//读取进程输入流中的内容
while ((len = inputStreamReader.read(c)) != -1) {
String s = new String(c, 0, len);
outputString.append(s);
System.out.print(s);
}
inputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* ffmpeg -i 1.mp4 -codec copy -vbsf h264_mp4toannexb 1.ts
**/
//todo
public static void test4() {
ProcessBuilder processBuilder = new ProcessBuilder();
//定义命令内容
// ffmpeg -i test.asf -vframes 30 -y -f gif a.gif
List<String> command = new ArrayList<String>();
command.add("D:\\luojunrong-gitee\\videoManage\\ffmpeg\\bin\\ffmpeg.exe");
command.add("-i");
//被转码的视频
command.add("D:\\luojunrong-gitee\\videoManage\\test-fmpeg\\20d008203b85e2ff85ba20f4c54b474f.3gp");
command.add("-codec");
command.add("copy");
command.add("-vbsf");
command.add("h264_mp4toannexb");
command.add("-y");
//wmv,3gp,mp4,mov,avi,flv,ts,mkv
command.add("D:\\luojunrong-gitee\\videoManage\\test-fmpeg\\mp4\\20d008203b85e2ff85ba20f4c54b474f.mp4");
processBuilder.command(command);
//将标准输入流和错误输入流合并,通过标准输入流读取信息
processBuilder.redirectErrorStream(true);
try {
//启动进程
Process start = processBuilder.start();
//获取输入流
InputStream inputStream = start.getInputStream();
//转成字符输入流
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "gbk");
int len = -1;
char[] c = new char[1024];
StringBuffer outputString = new StringBuffer();
//读取进程输入流中的内容
while ((len = inputStreamReader.read(c)) != -1) {
String s = new String(c, 0, len);
outputString.append(s);
System.out.print(s);
}
inputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void test5() {
ProcessBuilder processBuilder = new ProcessBuilder();
//定义命令内容
// ffmpeg -i test.asf -vframes 30 -y -f gif a.gif
List<String> command = new ArrayList<String>();
command.add("D:\\luojunrong-gitee\\videoManage\\ffmpeg\\bin\\ffmpeg.exe");
command.add("-i");
//被转码的视频
command.add("D:\\测试视频\\音乐之声-njluyou.rm");
command.add("-vcodec");
command.add("wmv1");
command.add("D:\\luojunrong-gitee\\videoManage\\test-fmpeg\\20d008203b85e2ff85ba20f4c54b474f.mp4");
processBuilder.command(command);
//将标准输入流和错误输入流合并,通过标准输入流读取信息
processBuilder.redirectErrorStream(true);
try {
//启动进程
Process start = processBuilder.start();
//获取输入流
InputStream inputStream = start.getInputStream();
//转成字符输入流
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "gbk");
int len = -1;
char[] c = new char[1024];
StringBuffer outputString = new StringBuffer();
//读取进程输入流中的内容
while ((len = inputStreamReader.read(c)) != -1) {
String s = new String(c, 0, len);
outputString.append(s);
System.out.print(s);
}
inputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* -oac mp3lame -lameopts preset=64 -ovc xvid -xvidencopts
*
* bitrate=600 -of avi -o
*
* **/
// 对ffmpeg无法解析的文件格式(wmv9,rm,rmvb等), 可以先用别的工具(mencoder)转换为avi(ffmpeg能解析的)格式.
public static void test6() {
ProcessBuilder processBuilder = new ProcessBuilder();
//定义命令内容
// ffmpeg -i test.asf -vframes 30 -y -f gif a.gif
List<String> command = new ArrayList<String>();
command.add("D:\\luojunrong-gitee\\videoManage\\MPlayer-mingw32-1.0rc1\\mplayer\\mencoder");
command.add("D:\\测试视频\\音乐之声-njluyou.rm");
command.add("-oac");
command.add("mp3lame");
command.add("-lameopts");
command.add("preset=64");
command.add("-ovc");
command.add("xvid");
command.add("-xvidencopts");
command.add("bitrate=600");
command.add("-of");
command.add("avi");
command.add("-o");
command.add("D:\\luojunrong-gitee\\videoManage\\test-fmpeg\\音乐之声-njluyou.avi");
processBuilder.command(command);
//将标准输入流和错误输入流合并,通过标准输入流读取信息
processBuilder.redirectErrorStream(true);
try {
//启动进程
Process start = processBuilder.start();
//获取输入流
InputStream inputStream = start.getInputStream();
//转成字符输入流
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "gbk");
int len = -1;
char[] c = new char[1024];
StringBuffer outputString = new StringBuffer();
//读取进程输入流中的内容
while ((len = inputStreamReader.read(c)) != -1) {
String s = new String(c, 0, len);
outputString.append(s);
System.out.print(s);
}
inputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
通用选项
-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测试
参考文章:https://blog.youkuaiyun.com/wdy_2099/article/details/71453602