加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

java调用ffmpeg转换视频,并读取转换后视频的分辨率、大小以及时长

(2016-07-09 14:51:40)
标签:

ffmpeg

java

xuggle

最近由于项目需要把不同格式的视频转换为ts流,故研究了一下ffmpeg。在网上找了很多资料,主要参考了
http://www.cnblogs.com/zhwl/p/4670478.html。期间也加了几个qq群,咨询了各大高手,其中在代码中关于ffmpeg的命令就是来自其中一个qq群里面的大神。
下载相关文件
ffmpeg地址:https://ffmpeg.zeranoe.com/builds/,我下载是windows 64位static版本。
下面的代码我上传到了github,需要的可以下载下来看看。
步骤:
1.研究java如何调用外部程序
2.研究ffmpeg转换视频格式的命令
3.利用xuggle获取ffmpeg解析的ts流的时长、分辨率以及文件大小。


下面直接上代码:
1.ffmpeg转换实现
package vedio.ffmpeg;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class FfmpegUtil {

public static Boolean ffmpeg(String ffmpegPath, String inputPath, String outputPath) throws FFmpegException{
 
if (!checkfile(inputPath)) {
throw new FFmpegException("文件格式不合法");
}

int type = checkContentType(inputPath);
List command = getFfmpegCommand(type, ffmpegPath, inputPath, outputPath);
if (null != command && command.size() > 0) {
return process(command);
 
}
return false;
}

private static int checkContentType(String inputPath) {
String type = inputPath.substring(inputPath.lastIndexOf(".") + 1, inputPath.length()).toLowerCase();
// ffmpeg能解析的格式:(asx,asf,mpg,wmv,3gp,mp4,mov,avi,flv等)
if (type.equals("avi")) {
return 1;
} else if (type.equals("mpg")) {
return 1;
} else if (type.equals("wmv")) {
return 1;
} else if (type.equals("3gp")) {
return 1;
} else if (type.equals("mov")) {
return 1;
} else if (type.equals("mp4")) {
return 1;
} else if (type.equals("mkv")){
return 1;
}else if (type.equals("asf")) {
return 0;
} else if (type.equals("flv")) {
return 0;
}else if (type.equals("rm")) {
return 0;
} else if (type.equals("rmvb")) {
return 1;
}
return 9;
}

private static boolean checkfile(String path) {
File file = new File(path);
if (!file.isFile()) {
return false;
}
return true;
}

private static boolean process(List command) throws FFmpegException{

try {

if (null == command || command.size() == 0)
return false;
Process videoProcess = new ProcessBuilder(command).redirectErrorStream(true).start();

new PrintStream(videoProcess.getErrorStream()).start();

new PrintStream(videoProcess.getInputStream()).start();

int exitcode = videoProcess.waitFor();
 
if (exitcode == 1) {
return false;
}
return true;
} catch (Exception e) {
throw new FFmpegException("file upload failed",e);
}

}

private static List getFfmpegCommand(int type, String ffmpegPath, String oldfilepath, String outputPath) throws FFmpegException {
List command = new ArrayList();
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);
} else if(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{
throw new FFmpegException("不支持当前上传的文件格式");
}
return command;
}
}

class PrintStream extends Thread {
java.io.InputStream __is = null;

public PrintStream(java.io.InputStream is) {
__is = is;
}

public void run() {
try {
while (this != null) {
int _ch = __is.read();
if (_ch == -1) {
break;
} else {
System.out.print((char) _ch);
}

}
} catch (Exception e) {
e.printStackTrace();
}
}
}
2.调用测试类
package vedio.ffmpeg;

public class ConvertVedio {
public static void convertVedio(String inputPath){
String ffmpegPath = getFfmpegPath();
String outputPath = getOutputPath(inputPath);
try {
FfmpegUtil.ffmpeg(ffmpegPath, inputPath, outputPath);
} catch (FFmpegException e) {
e.printStackTrace();
}
 
}

private static String getFfmpegPath() {
return "ffmpeg";
}

private static String getOutputPath(String inputPath) {
return inputPath.substring(0, inputPath.lastIndexOf(".")).toLowerCase() + ".ts";
}
}
3.自定义的异常类
package vedio.ffmpeg;

public class FFmpegException extends Exception {

private static final long serialVersionUID = 1L;

public FFmpegException() {
super();
}

public FFmpegException(String message) {
super(message);
}

public FFmpegException(Throwable cause) {
super(cause);
}

public FFmpegException(String message, Throwable cause) {
super(message, cause);
}
}
4.获取ts流的时长、大小以及分辨率(用到了Xuggle,需要下载对应jar包)
import com.xuggle.xuggler.ICodec;
import com.xuggle.xuggler.IContainer;
import com.xuggle.xuggler.IStream;
import com.xuggle.xuggler.IStreamCoder;

*/
    public static void getVedioInfo(String filename){
 
     
            // first we create a Xuggler container object
            IContainer container = IContainer.make();

            // we attempt to open up the container
            int result = container.open(filename, IContainer.Type.READ, null);

            // check if the operation was successful
            if (result<0)
                return ;
            
            // query how many streams the call to open found
            int numStreams = container.getNumStreams();
            // query for the total duration
            long duration = container.getDuration();
            // query for the file size
            long fileSize = container.getFileSize();
            long secondDuration = duration/1000000;
            
            System.out.println("时长:"+secondDuration+"秒");
            System.out.println("文件大小:"+fileSize+"M");
         
      
            for (int i=0; i
                IStream stream = container.getStream(i);
                IStreamCoder coder = stream.getStreamCoder();
                if (coder.getCodecType() == ICodec.Type.CODEC_TYPE_VIDEO) {
                System.out.println("视频宽度:"+coder.getWidth());
                     System.out.println("视频高度:"+coder.getHeight());
                }
            }
    
    }
 

以上就是在开发过程中做的全部,希望大家多多学习,交流!

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有