最近由于项目需要把不同格式的视频转换为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 container
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());
}
}
}
以上就是在开发过程中做的全部,希望大家多多学习,交流!
继续阅读与本文标签相同的文章
下一篇 :
C4D R14软件安装教程
-
Springboot+mockito进行单元测试心得整体
2026-05-19栏目: 教程
-
如何用“云”读懂女生的心?TA 做到了
2026-05-19栏目: 教程
-
基于ASP.Net Core开发的一套通用后台框架
2026-05-19栏目: 教程
-
Spring Cloud开发人员如何解决服务冲突和实例乱窜?
2026-05-19栏目: 教程
-
数据上云安全吗
2026-05-19栏目: 教程
