java调用ffmpeg实现转换视频
最近由于项目需要把不同格式的视频转换为ts流,故研究了一下ffmpeg。在网上找了很多资料,主要参考了Java+Windows+ffmpeg实现视频转换功能。
期间也加了几个qq群,咨询了各大高手,其中在代码中关于ffmpeg的命令就是来自其中一个qq群里面的大神。
下载相关文件
ffmpeg地址,我下载是windows64位static版本。
xuggler下载地址
下面的代码我上传到了github,需要的可以下载下来看看。
步骤:
1.研究java如何调用外部程序
2.研究ffmpeg转换视频格式的命令
3.利用xuggle获取ffmpeg解析的ts流的时长、分辨率以及文件大小。
下面直接上代码:
1.ffmpeg转换实现
packagevedio.ffmpeg;
importjava.io.File;
importjava.util.ArrayList;
importjava.util.List;
publicclassFfmpegUtil{
publicstaticBooleanffmpeg(StringffmpegPath,StringinputPath,StringoutputPath)throwsFFmpegException{
if(!checkfile(inputPath)){
thrownewFFmpegException("文件格式不合法");
}
inttype=checkContentType(inputPath);
Listcommand=getFfmpegCommand(type,ffmpegPath,inputPath,outputPath);
if(null!=command&&command.size()>0){
returnprocess(command);
}
returnfalse;
}
privatestaticintcheckContentType(StringinputPath){
Stringtype=inputPath.substring(inputPath.lastIndexOf(".")+1,inputPath.length()).toLowerCase();
//ffmpeg能解析的格式:(asx,asf,mpg,wmv,3gp,mp4,mov,avi,flv等)
if(type.equals("avi")){
return1;
}elseif(type.equals("mpg")){
return1;
}elseif(type.equals("wmv")){
return1;
}elseif(type.equals("3gp")){
return1;
}elseif(type.equals("mov")){
return1;
}elseif(type.equals("mp4")){
return1;
}elseif(type.equals("mkv")){
return1;
}elseif(type.equals("asf")){
return0;
}elseif(type.equals("flv")){
return0;
}elseif(type.equals("rm")){
return0;
}elseif(type.equals("rmvb")){
return1;
}
return9;
}
privatestaticbooleancheckfile(Stringpath){
Filefile=newFile(path);
if(!file.isFile()){
returnfalse;
}
returntrue;
}
privatestaticbooleanprocess(Listcommand)throwsFFmpegException{
try{
if(null==command||command.size()==0)
returnfalse;
ProcessvideoProcess=newProcessBuilder(command).redirectErrorStream(true).start();
newPrintStream(videoProcess.getErrorStream()).start();
newPrintStream(videoProcess.getInputStream()).start();
intexitcode=videoProcess.waitFor();
if(exitcode==1){
returnfalse;
}
returntrue;
}catch(Exceptione){
thrownewFFmpegException("fileuploadfailed",e);
}
}
privatestaticListgetFfmpegCommand(inttype,StringffmpegPath,Stringoldfilepath,StringoutputPath)throwsFFmpegException{
Listcommand=newArrayList();
if(type==1){
command.add(ffmpegPath+"\\ffmpeg");
command.add("-i");
command.add(oldfilepath);
command.add("-c:v");
command.add("libx264");
command.add("-x264opts");
command.add("force-cfr=1");
command.add("-c:a");
command.add("mp2");
command.add("-b:a");
command.add("256k");
command.add("-vsync");
command.add("cfr");
command.add("-f");
command.add("mpegts");
command.add(outputPath);
}elseif(type==0){
command.add(ffmpegPath+"\\ffmpeg");
command.add("-i");
command.add(oldfilepath);
command.add("-c:v");
command.add("libx264");
command.add("-x264opts");
command.add("force-cfr=1");
command.add("-vsync");
command.add("cfr");
command.add("-vf");
command.add("idet,yadif=deint=interlaced");
command.add("-filter_complex");
command.add("aresample=async=1000");
command.add("-c:a");
command.add("libmp3lame");
command.add("-b:a");
command.add("192k");
command.add("-pix_fmt");
command.add("yuv420p");
command.add("-f");
command.add("mpegts");
command.add(outputPath);
}else{
thrownewFFmpegException("不支持当前上传的文件格式");
}
returncommand;
}
}
classPrintStreamextendsThread{
java.io.InputStream__is=null;
publicPrintStream(java.io.InputStreamis){
__is=is;
}
publicvoidrun(){
try{
while(this!=null){
int_ch=__is.read();
if(_ch==-1){
break;
}else{
System.out.print((char)_ch);
}
}
}catch(Exceptione){
e.printStackTrace();
}
}
}
2.调用测试类
packagevedio.ffmpeg;
publicclassConvertVedio{
publicstaticvoidconvertVedio(StringinputPath){
StringffmpegPath=getFfmpegPath();
StringoutputPath=getOutputPath(inputPath);
try{
FfmpegUtil.ffmpeg(ffmpegPath,inputPath,outputPath);
}catch(FFmpegExceptione){
e.printStackTrace();
}
}
privatestaticStringgetFfmpegPath(){
return"ffmpeg";
}
privatestaticStringgetOutputPath(StringinputPath){
returninputPath.substring(0,inputPath.lastIndexOf(".")).toLowerCase()+".ts";
}
}
3.自定义的异常类
packagevedio.ffmpeg;
publicclassFFmpegExceptionextendsException{
privatestaticfinallongserialVersionUID=1L;
publicFFmpegException(){
super();
}
publicFFmpegException(Stringmessage){
super(message);
}
publicFFmpegException(Throwablecause){
super(cause);
}
publicFFmpegException(Stringmessage,Throwablecause){
super(message,cause);
}
}
4.获取ts流的时长、大小以及分辨率(用到了Xuggle,需要下载对应jar包)
importcom.xuggle.xuggler.ICodec;
importcom.xuggle.xuggler.IContainer;
importcom.xuggle.xuggler.IStream;
importcom.xuggle.xuggler.IStreamCoder;
*/
publicstaticvoidgetVedioInfo(Stringfilename){
//firstwecreateaXugglercontainerobject
IContainercontainer=IContainer.make();
//weattempttoopenupthecontainer
intresult=container.open(filename,IContainer.Type.READ,null);
//checkiftheoperationwassuccessful
if(result<0)
return;
//queryhowmanystreamsthecalltoopenfound
intnumStreams=container.getNumStreams();
//queryforthetotalduration
longduration=container.getDuration();
//queryforthefilesize
longfileSize=container.getFileSize();
longsecondDuration=duration/1000000;
System.out.println("时长:"+secondDuration+"秒");
System.out.println("文件大小:"+fileSize+"M");
for(inti=0;i
IStreamstream=container.getStream(i);
IStreamCodercoder=stream.getStreamCoder();
if(coder.getCodecType()==ICodec.Type.CODEC_TYPE_VIDEO){
System.out.println("视频宽度:"+coder.getWidth());
System.out.println("视频高度:"+coder.getHeight());
}
}
}
以上就是在开发过程中做的全部,希望大家多多学习,交流!