java调用ffmpeg实现转换视频

 更新时间:2018年12月15日 15:07:12   作者:zhengdesheng19930211  
这篇文章主要为大家详细介绍了java调用ffmpeg实现转换视频功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

最近由于项目需要把不同格式的视频转换为ts流,故研究了一下ffmpeg。在网上找了很多资料,主要参考了Java+Windows+ffmpeg实现视频转换功能。

期间也加了几个qq群,咨询了各大高手,其中在代码中关于ffmpeg的命令就是来自其中一个qq群里面的大神。

下载相关文件

ffmpeg地址,我下载是windows 64位static版本。

xuggler下载地址

下面的代码我上传到了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(StringffmpegPath, String inputPath, String outputPath) throwsFFmpegException{
 
if (!checkfile(inputPath)) {
throw newFFmpegException("文件格式不合法");
}
 
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(StringinputPath) {
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(Stringpath) {
File file = new File(path);
if (!file.isFile()) {
return false;
}
return true;
}
 
private static boolean process(Listcommand) throws FFmpegException{
 
try {
 
if (null == command || command.size() ==0)
return false;
Process videoProcess = newProcessBuilder(command).redirectErrorStream(true).start();
 
newPrintStream(videoProcess.getErrorStream()).start();
 
newPrintStream(videoProcess.getInputStream()).start();
 
int exitcode =videoProcess.waitFor();
 
if (exitcode == 1) {
return false;
}
return true;
} catch (Exception e) {
throw new FFmpegException("file uploadfailed",e);
}
 
}
 
private static List getFfmpegCommand(inttype, String ffmpegPath, String oldfilepath, String outputPath)throws FFmpegException {
List command = 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);
} 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 newFFmpegException("不支持当前上传的文件格式");
}
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(StringinputPath){
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(StringinputPath) {
return inputPath.substring(0,inputPath.lastIndexOf(".")).toLowerCase() + ".ts";
}
}

3.自定义的异常类

package vedio.ffmpeg;
 
public class FFmpegException extendsException {
 
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包)

importcom.xuggle.xuggler.ICodec;
importcom.xuggle.xuggler.IContainer;
importcom.xuggle.xuggler.IStream;
importcom.xuggle.xuggler.IStreamCoder;
 
*/
 public static void getVedioInfo(String filename){
 
 
   // first we create a Xuggler containerobject
   IContainer container =IContainer.make();
 
   // we attempt to open up thecontainer
   int result = container.open(filename,IContainer.Type.READ, null);
 
   // check if the operation wassuccessful
   if (result<0)
    return;
   
   // query how many streams the call to openfound
   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
    IStreamstream = 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());
    }
   }
 
 }

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

相关文章

  • apache commons工具集代码详解

    apache commons工具集代码详解

    这篇文章主要介绍了apache commons工具集代码详解,具有一定借鉴价值,需要的朋友可以参考下
    2017-12-12
  • Java计算器核心算法代码实现

    Java计算器核心算法代码实现

    今天小编就为大家分享一篇关于Java计算器核心算法代码实现,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • 浅谈Thread.sleep(0)到底有什么用

    浅谈Thread.sleep(0)到底有什么用

    为什么要用sleep,主要是为了暂停当前线程,把cpu片段让出给其他线程,减缓当前线程的执行,本文主要介绍了Thread.sleep(0)到底有什么用,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-06-06
  • Java 8 中 Map 骚操作之 merge() 的使用方法

    Java 8 中 Map 骚操作之 merge() 的使用方法

    本文简单介绍了一下Map.merge()的方法,除此之外,Java 8 中的HashMap实现方法使用了TreeNode和 红黑树,原理很相似,今天通过本文给大家介绍Java 8 中 Map 骚操作之 merge() 的用法 ,需要的朋友参考下吧
    2021-07-07
  • Maven配置阿里云仓库/国内镜像的详细步骤

    Maven配置阿里云仓库/国内镜像的详细步骤

    在国内使用Maven时,很多时候会遇到下载依赖较慢的问题,主要是因为Maven的默认中央仓库位于国外,网络延迟较高,为了解决这个问题,我们可以配置国内的Maven镜像源,如阿里云提供的镜像,在这篇博客中,我们将详细介绍如何配置Maven使用阿里云仓库,需要的朋友可以参考下
    2025-04-04
  • java图片对比度调整示例代码

    java图片对比度调整示例代码

    这篇文章主要给大家介绍了关于java图片对比度调整的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用java具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-07-07
  • Java中的TreeSet集合详解

    Java中的TreeSet集合详解

    这篇文章主要介绍了Java中的TreeSet集合详解,TreeSet 是一个 有序集合,它扩展了 AbstractSet 类并实现了 NavigableSet 接口,作为自平衡二叉搜索树,二叉树的每个节点包括一个额外的位,用于识别红色或黑色的节点的颜色,需要的朋友可以参考下
    2023-09-09
  • 跨域解决方案Jsonp原理解析

    跨域解决方案Jsonp原理解析

    这篇文章主要介绍了跨域解决方案Jsonp原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02
  • eclipse下搭建hibernate5.0环境的步骤(图文)

    eclipse下搭建hibernate5.0环境的步骤(图文)

    这篇文章主要介绍了eclipse下搭建hibernate5.0环境的步骤(图文),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-05-05
  • Java实现推箱子游戏

    Java实现推箱子游戏

    这篇文章主要为大家详细介绍了Java实现推箱子游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-05-05

最新评论