package com.nvvideo.util;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.nvvideo.util.cmd.CmdExecuter;
import com.nvvideo.util.cmd.IStringGetter;
/**
* * Title: FFMpeg工具类
* </p>
* <p>
* Description: 本类封装FFMpeg对视频的操作
* @author zhangwx
*
*/
public class FFMpegUtil implements IStringGetter {
//runtime播放时间,单位秒,second
private int runtime = 0;
//private String ffmpegUri;// ffmpeg的全路径 如e:/ffmpeg/ffmpeg.exe 或 /root/ffmpeg/bin/ffmpeg
private String ffmpegUri;// ffmpeg的全路径 如e:/ffmpeg/ 或 /root/ffmpeg/bin/
//private String originFileUri; // 所操作视频文件的全路径 如e:/upload/temp/test.wmv
//存储命令的list集合类
private List<String> cmd = new ArrayList<String>();
//状态,初始化的是Empty
private FFMpegUtilStatus status = FFMpegUtilStatus.Empty;
//是否支持输如视频
private boolean isSupported;
//枚举的定义
private enum FFMpegUtilStatus {
Empty,
CheckingFile, //检查文件
GettingRuntime,//获取视频的播放时长
ScreenResolution,//获取屏幕的分辨率
GettingFileName//获取文件的名称
};
/**
* 构造函数
*
* @param ffmpegUri
* ffmpeg的全路径 如e:/ffmpeg/ffmpeg.exe 或 /root/ffmpeg/bin/ffmpeg
* @param originFileUri
* 所操作视频文件的全路径 如e:/upload/temp/test.wmv
*/
public FFMpegUtil( String ffmpegUri) {
this.ffmpegUri = ffmpegUri;
//this.originFileUri = originFileUri;
}
/**
* 获取视频时长
* String originFileUri; // 所操作视频文件的全路径 如e:/upload/temp/test.wmv
*/
public int getRuntime(String originFileUri) {
runtime = 0;
status = FFMpegUtilStatus.GettingRuntime;
cmd.clear();
cmd.add(ffmpegUri+"ffmpeg.exe ");
cmd.add("-i");
cmd.add(originFileUri);
CmdExecuter.exec(cmd, this);
return runtime;
}
/**
* 检测文件是否是支持的格式 将检测视频文件本身,而不是扩展名
*
* 判断当前数据的文件,是否是ffmpeg支持的格式,如果是,返回true,如果不是返回false
* String originFileUri; // 所操作视频文件的全路径 如e:/upload/temp/test.wmv
@return
*/
public boolean isSupported(String originFileUri) {
isSupported = false;
status = FFMpegUtilStatus.CheckingFile;
cmd.clear();
cmd.add(ffmpegUri+"ffmpeg.exe ");
cmd.add("-i");
cmd.add(originFileUri);
CmdExecuter.exec(cmd, this);
return isSupported;
}
/**
* 生成视频截图
* String originFileUri; // 所操作视频文件的全路径 如e:/upload/temp/test.wmv
* @param imageSavePath
* 截图文件保存全路径
* @param screenSize
* 截图大小 如640x480
*/
public void makeScreenCut(String originFileUri,String imageSavePath, String screenSize,int ss) {
cmd.clear();
cmd.add(ffmpegUri+"ffmpeg.exe ");
cmd.add("-y");
cmd.add("-i");
cmd.add(originFileUri);
cmd.add("-f");
cmd.add("image2");
cmd.add("-ss");
cmd.add(String.valueOf(ss));
cmd.add("-t");
cmd.add("0.001");
cmd.add("-s");
cmd.add(screenSize);
cmd.add(imageSavePath);
CmdExecuter.exec(cmd, this);
}
/**
* 视频转换
*
* @param fileSavePath
* 文件保存全路径(包括扩展名)如 e:/abc/test.flv
* @param screenSize
* 视频分辨率 如640x480
* @param audioByte
* 音频比特率
* @param audioCollection
* 音频采样率
* @param quality
* 视频质量(0.01-255)越低质量越好
* @param fps
* 每秒帧数(15或29.97)
* String originFileUri; // 所操作视频文件的全路径 如e:/upload/temp/test.wmv
*/
public void videoTransfer(String originFileUri,String fileSavePath, String screenSize,
int audioByte, int audioCollection, double quality, double fps) {
cmd.clear();
cmd.add(ffmpegUri+"ffmpeg.exe ");
cmd.add("-i");
cmd.add(originFileUri);
cmd.add("-y");
cmd.add("-ab");
cmd.add(Integer.toString(audioByte));
cmd.add("-ar");
cmd.add(Integer.toString(audioCollection));
cmd.add("-qscale");
cmd.add(Double.toString(quality));
cmd.add("-r");
cmd.add(Double.toString(fps));
cmd.add("-s");
cmd.add(screenSize);
cmd.add(fileSavePath);
CmdExecuter.exec(cmd, null);
}
/**
* fanhui
*/
@Override
public void dealString(String str) {
switch (status) {
case Empty:
break;
case CheckingFile: {
if (-1 != str.indexOf("Metadata:"))
this.isSupported = true;
break;
}
case GettingRuntime: {
Matcher m = Pattern.compile("Duration:\\s\\d{2}:\\d{2}:\\d{2}.\\d{2}")
.matcher(str);
while (m.find()) {
String msg = m.group();
msg = msg.replace("Duration: ", "");
//msg="00:22:21.27";
runtime = TimeUtil.runtimeToSecond(msg);
}
break;
}
}
}
/**
* String originFileUri; // 所操作视频文件的全路径 如e:/upload/temp/test.wmv
* @param originFileUri
* @return
*/
public String getFileName(String originFileUri) {
String name = originFileUri.substring(originFileUri.lastIndexOf("/") + 1, originFileUri.lastIndexOf(".")).toLowerCase();
return name;
}
/**
*
* 获取输入视频文件的格式
* String originFileUri; // 所操作视频文件的全路径 如e:/upload/temp/test.wmv
* @param originFileUri
* @return
*/
public String getFileType(String originFileUri) {
String type = originFileUri.substring(originFileUri.lastIndexOf(".") + 1, originFileUri.length())
.toLowerCase();
return type;
}
/**
*
* @Title: process
* @Description: 检查格式,完成其他格式的视频转换为mp4格式
* @param
* @return boolean
* @throws
* @author zhangwx
* @version 1.0
* @createtime 2013-7-27 下午11:04:35
*/
public boolean videoTransferToMp4(String originFileUri,String fileSavePath) {
int type = checkContentType(originFileUri);
boolean status = false;
if (type == 0) {
// System.out.println("直接转成mp4格式");
status = processMP4(originFileUri,fileSavePath);// 直接转成MP4格式
} else if (type == 1) {
String avifilepath = processAVI(originFileUri,fileSavePath);
if (avifilepath == null)
return false;// 没有得到avi格式
status = processMP4(avifilepath,fileSavePath);// 将avi转成mp4格式
}
return status;
}
/**
*
* @Title: checkContentType
* @Description: 检查视频文件的类型,如果是avi、mpg、wmv、3gp、mov、asf、asx、flv返回int值0,
* 如果是wmv9,rm,rmvb等返回int值9 mp4
* @param
* @return int
* @throws
* @author zhangwx
* @version 1.0
* @createtime 2013-7-27 下午11:05:37
*/
public int checkContentType(String originFileUri) {
String type = originFileUri.substring(originFileUri.lastIndexOf(".") + 1, originFileUri.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("as