通过java代码,调用底层工具,实现视频格式转换
原理是这样的:
ffmpeg可以转换大多数视频文件,如:avi|wmv|mkv|asx|swf|asf|vob|mpg|mp4|mov|flv等
但有些视频格式,ffmpeg无法转,比如:rm,rmvb等
所以遇到ffmpeg不能转的视频格式时,需要调用另一个工具mencoder,利用mencoder将那些文件转成ffmpeg能够转换的格式。基本通过这2个工具可以转换大多数视频文件
必备组件有
pthreadGC2.dll需要放到system32目录下
全部文件下载地址
下载下来的压缩包除了有上述组件外,还有5个文件夹
具体解释
这里有一片CSDN的文章 ,写得很好,推荐给大件看看。具体就是看一些ffmpeg和mencoder的参数详解,这样让你之后的修改,也有的放失
http://blog.csdn.net/hemingwang0902/article/details/4382342
import java.io.File; import java.io.IOException; import java.io.InputStream; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; class ConvertVideo { private List<String> pathRight = new ArrayList<String>();// 经处理后,得到的有效地址 private List<String> path1 = new ArrayList<String>();// ffmpeg能处理的文件的地址集 private List<String> path2 = new ArrayList<String>();// ffmpeg不能处理的文件的地址集 public static int fileNum = 0;// 所有经过验证合法,并需要转换的视频数量 public static void main(String[] args) { Date start = new Date(); ConvertVideo conver = new ConvertVideo(); String fileFolder = "e:\\input"; List<String> listFile = conver.getFilesInPath(fileFolder); List<String> listVideo = conver.filter(listFile); int fileNumMax = listVideo.size(); // 所有视频数量 conver.checkfile(listVideo); conver.process(); if (fileNum == fileNumMax) { Date end = new Date(); System.out.println("耗时:" + (end.getTime() - start.getTime()) / 1000 + "秒"); } } /** * 过滤avi|wmv|rmvb|rm|asx|asf|mpg|3gp|mp4|mov|flv)$格式的视频 */ private List<String> filter(List<String> list) { List<String> fileList = new ArrayList<String>(); for (String str : list) { if (str.matches(".+\\.(avi|wmv|rmvb|rm|asx|mkv|asf|mpg|swf|3gp|mp4|mov|vob|flv)$")) { fileList.add(str); } } return fileList; } /** * * 获取e:\\input下所有文件路径 */ public List<String> getFilesInPath(String path) { List<String> fileList = new ArrayList<String>(); if (path == null || "".equals(path)) return fileList; File file = new File(path); if (!file.exists()) { return fileList; } File[] childFiles = file.listFiles(); try { for (int i = 0; i < childFiles.length; i++) { String filePath = childFiles[i].getAbsolutePath(); if (childFiles[i].isDirectory()) { fileList.addAll(getFilesInPath(filePath)); } else { fileList.add(filePath); } } } catch (Exception e) { return fileList; } return fileList; } /** * * 避免文件重名,在文件尾部加唯一标识,主要是以获取当前时间,以字符串格式hhmmssSSSSSS */ public String transform(Date date) { SimpleDateFormat sdFormat = new SimpleDateFormat("hhmmssSSSSSS"); String myTime = sdFormat.format(date); return myTime; } /** * 核心处理函数 */ public void process() { checkContentType(pathRight); pathRight.clear(); if (path1.size() > 0) { // 地址集中的文件全部是ffmpeg所能解析的文件 processFLV(path1); // 直接将文件转为flv文件 } if (path2.size() > 0) { processAVI(path2); // 得到ffmpeg不能解析的文件所转换成avi文件的地址集 } } /** * 将传过来的地址集分类,ffmpeg能解析的分到path1中,ffmpeg不能解析的分到path2中 */ public void checkContentType(List<String> list) { for (String str : list) { if (str.matches(".+\\.(avi|wmv|mkv|asx|swf|asf|vob|mpg|mp4|mov|flv)$")) { path1.add(str); } else { path2.add(str); } } } /** * . 处理用户传递过来的地址集 有效的放到pathRight中 无效的放到pathWrong中 */ public void checkfile(List<String> path) { for (int i = 0; i < path.size(); i++) { File file = new File((String) path.get(i)); if (file.isFile()) { pathRight.add(path.get(i)); } } } /** * 对ffmpeg无法解析的文件格式(wmv9,rm,rmvb等), 可以先用别的工具(mencoder)转换为avi(ffmpeg能解析的)格式. */ public void processAVI(List<String> list) { List<String> finish = new ArrayList<String>(); for (String str : list) { List<String> commend = new java.util.ArrayList<String>(); commend.add("\"e:\\mencoder\""); commend.add("\"" + str + "\""); commend.add("-oac"); commend.add("mp3lame"); commend.add("-lameopts"); commend.add("preset=64"); commend.add("-ovc"); commend.add("xvid"); commend.add("-xvidencopts"); commend.add("bitrate=600"); commend.add("-of"); commend.add("avi"); commend.add("-o"); String file = str.substring(str.lastIndexOf("\\") + 1, str.lastIndexOf(".")); file = (file + transform(new Date())).trim(); commend.add("\"e:\\System\\" + file + ".avi\""); // 最后输出出来的avi,尽量不要出现二义性,否则会覆盖掉原有的视频 try { ProcessBuilder builder = new ProcessBuilder(); builder.command(commend); Process p = builder.start(); int exitValue = doWaitFor(p); if (exitValue != -1) { processFLV1("e:\\System\\" + file + ".avi"); } } catch (Exception e) { // e.printStackTrace(); System.out.println("********avi转换出错********"); } finish.add(str); } path2.removeAll(finish); } /** * ffmpeg能解析的格式:(asx,asf,mpg,wmv,3gp,mp4,mov,avi,flv等) */ public boolean processFLV1(String str) { List<String> commend = new java.util.ArrayList<String>(); commend.add("\"e:\\ffmpeg\""); commend.add("-i"); commend.add("\"" + str + "\""); commend.add("-ab"); commend.add("64"); commend.add("-ac"); commend.add("2"); commend.add("-ar"); commend.add("22050"); commend.add("-b"); commend.add("230"); commend.add("-r"); commend.add("29.97"); commend.add("-y"); String file = str.substring(str.lastIndexOf("\\") + 1, str.lastIndexOf(".")); String fileName = "e:\\output\\" + file + ".flv"; commend.add("\"" + fileName + "\""); try { ProcessBuilder builder = new ProcessBuilder(); builder.command(commend); Process p = builder.start(); int exitValue = doWaitFor(p); if (exitValue != -1) { fileNum++; } processImg(fileName); } catch (Exception e) { System.out.println("*********转换为FLV格式出错*********"); // e.printStackTrace(); return false; } deleteFile(str); return true; } public void processFLV(List<String> list) { List<String> finish = new ArrayList<String>(); for (String str : list) { List<String> commend = new java.util.ArrayList<String>(); commend.add("\"e:\\ffmpeg\""); commend.add("-i"); commend.add("\"" + str + "\""); commend.add("-ab"); commend.add("64"); commend.add("-ac"); commend.add("2"); commend.add("-ar"); commend.add("22050"); commend.add("-b"); commend.add("230"); commend.add("-r"); commend.add("29.97"); commend.add("-y"); String file = str.substring(str.lastIndexOf("\\") + 1, str.lastIndexOf(".")); String fileName = "e:\\output\\" + file + transform(new Date()) + ".flv"; commend.add("\"" + fileName + "\""); try { ProcessBuilder builder = new ProcessBuilder(); builder.command(commend); Process p = builder.start(); int exitValue = doWaitFor(p); if (exitValue != -1) { fileNum++; processImg(fileName); } } catch (Exception e) { // System.out.println("*********转换为FLV格式出错*********"); e.printStackTrace(); } finish.add(str); } path1.removeAll(finish); } /** * 生成图片 参数String newfilename, String newimg */ public boolean processImg(String str) { List<String> commend = new java.util.ArrayList<String>(); commend.add("\"e:\\ffmpeg\""); commend.add("-i"); commend.add("\"" + str + "\""); commend.add("-y"); commend.add("-f"); commend.add("image2"); commend.add("-ss"); commend.add("5"); commend.add("-t"); commend.add("0.001"); commend.add("-s"); commend.add("320x240"); commend.add("\"e:\\img\\" + str.substring(10, str.lastIndexOf(".")) + ".jpg\""); try { ProcessBuilder builder = new ProcessBuilder(); builder.command(commend); builder.start(); } catch (Exception e) { e.printStackTrace(); return false; } return true; } public void deleteFile(String str) { File file = new File(str); file.delete(); } /** * ffmpeg不能转换的格式要先转换成avi的格式,才转化为flv格式,doWaitFor方法保证,原视频完全转化为avi后, * 才转化成flv,避免avi,flv同时转换出错 */ public int doWaitFor(Process p) { InputStream in = null; InputStream err = null; int exitValue = -1; // returned to caller when p is finished try { System.out.println("comeing"); in = p.getInputStream(); err = p.getErrorStream(); boolean finished = false; // Set to true when p is finished while (!finished) { try { while (in.available() > 0) { // Print the output of our system call Character c = new Character((char) in.read()); System.out.print(c); } while (err.available() > 0) { // Print the output of our system call Character c = new Character((char) err.read()); System.out.print(c); } // Ask the process for its exitValue. If the process // is not finished, an IllegalThreadStateException // is thrown. If it is finished, we fall through and // the variable finished is set to true. exitValue = p.exitValue(); finished = true; } catch (IllegalThreadStateException e) { // Process is not finished yet; // Sleep a little to save on CPU cycles Thread.currentThread().sleep(500); } } } catch (Exception e) { // unexpected exception! print it out for debugging... System.err.println("doWaitFor();: unexpected exception - " + e.getMessage()); } finally { try { if (in != null) { in.close(); } } catch (IOException e) { System.out.println(e.getMessage()); } if (err != null) { try { err.close(); } catch (IOException e) { System.out.println(e.getMessage()); } } } // return completion status to caller return exitValue; } }