java调用ffmpeg实现转换视频

作者:zhengdesheng19930211 时间:2022-08-25 15:21:04 

最近由于项目需要把不同格式的视频转换为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());
   }
  }

}

来源:https://blog.csdn.net/zhengdesheng19930211/article/details/64443620

标签:java,ffmpeg,转换视频
0
投稿

猜你喜欢

  • android 类似微信的摇一摇功能实现思路及代码

    2022-09-16 03:45:36
  • flutter实现appbar下选项卡切换

    2023-06-21 13:35:24
  • Intellij搭建springmvc常见问题解决方案

    2023-07-23 12:53:29
  • Android 文件操作方法

    2023-06-02 12:51:17
  • java Long类型转为json后数据损失精度的处理方式

    2022-08-11 12:37:43
  • c#多线程中Lock()关键字的用法小结

    2022-07-08 04:33:27
  • C#重写DataGridView

    2021-06-09 11:56:26
  • Android 详解沉浸式状态栏的实现流程

    2023-12-18 23:03:31
  • springboot+jersey+tomcat实现跨域方式上传文件到服务器的方式

    2023-08-16 10:26:45
  • Java实现简单的日历界面

    2021-10-08 03:13:01
  • 全网最详细Hutool工具详解

    2023-05-04 06:21:53
  • 聊聊@RequestBody和Json之间的关系

    2023-11-27 03:31:45
  • IDEA 如何控制编辑左侧的功能图标ICON(操作步骤)

    2022-11-04 21:10:05
  • 读取xml文件中的配置参数实例

    2023-10-16 16:20:41
  • Java通俗易懂系列设计模式之建造者模式

    2022-11-01 23:27:24
  • Java实现排球比赛计分系统

    2021-07-11 09:11:14
  • Java集合Map的clear与new Map区别详解

    2022-03-21 15:41:39
  • Android仿微信列表滑动删除之可滑动控件(一)

    2021-12-24 21:15:46
  • SpringBoot bean查询加载顺序流程详解

    2023-09-02 02:43:16
  • android自定义ImageView仿图片上传示例

    2023-08-11 20:34:08
  • asp之家 软件编程 m.aspxhome.com