Java使用ffmpeg和mencoder實(shí)現(xiàn)視頻轉(zhuǎn)碼
本文為大家分享了Java使用ffmpeg和mencoder實(shí)現(xiàn)視頻轉(zhuǎn)碼的具體代碼,供大家參考,具體內(nèi)容如下
準(zhǔn)備:
需要下載ffmpeg和mencoder,百度一搜就有了,請(qǐng)自行下載。
不墨跡,上代碼:
1)首先需要定義幾個(gè)量:Contants.java
public class Contants { public static final String ffmpegpath = "D:\\DevTools\\ffmpeg\\bin\\ffmpeg.exe";//ffmpeg的安裝位置 public static final String mencoderpath = "D:\\DevTools\\mencoder\\"; // mencoder的目錄 public static final String videofolder = "D:\\tools\\video\\"; // 需要被轉(zhuǎn)換格式的視頻目錄 public static final String targetfolder = "D:\\tools\\target\\"; // 轉(zhuǎn)換后視頻的目錄 public static final String videoRealPath = "D:\\tools\\target\\"; // 需要被截圖的視頻目錄; public static final String imageRealPath = "D:\\tools\\imgs\\"; // 截圖的存放目錄 }
2)其次,就是Utils類了,具體里面有注釋:ConverVideoUtils.java
import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.Date; import java.util.List; import com.wdy.common.Contants; public class ConverVideoUtils { private Date dt; private long begintime; private String sourceVideoPath;//源視頻路徑 private String filerealname; // 文件名 不包括擴(kuò)展名 private String filename; // 包括擴(kuò)展名 private String videofolder = Contants.videofolder; // 別的格式視頻的目錄 private String targetfolder = Contants.targetfolder; // flv視頻的目錄 private String ffmpegpath = Contants.ffmpegpath; // ffmpeg.exe的目錄 private String mencoderpath = Contants.mencoderpath; // mencoder的目錄 private String imageRealPath = Contants.imageRealPath; // 截圖的存放目錄 public ConverVideoUtils() { } public ConverVideoUtils(String path) { sourceVideoPath = path; } public String getPATH() { return sourceVideoPath; } public void setPATH(String path) { sourceVideoPath = path; } /** * 轉(zhuǎn)換視頻格式 * @param String targetExtension 目標(biāo)視頻擴(kuò)展名 .xxx * @param isDelSourseFile 轉(zhuǎn)換完成后是否刪除源文件 * @return */ public boolean beginConver(String targetExtension, boolean isDelSourseFile) { File fi = new File(sourceVideoPath); filename = fi.getName(); filerealname = filename.substring(0, filename.lastIndexOf(".")).toLowerCase(); System.out.println("----接收到文件(" + sourceVideoPath + ")需要轉(zhuǎn)換-------------------------- "); if (!checkfile(sourceVideoPath)) { System.out.println(sourceVideoPath + "文件不存在" + " "); return false; } dt = new Date(); begintime = dt.getTime(); System.out.println("----開始轉(zhuǎn)文件(" + sourceVideoPath + ")-------------------------- "); if (process(targetExtension,isDelSourseFile)) { Date dt2 = new Date(); System.out.println("轉(zhuǎn)換成功 "); long endtime = dt2.getTime(); long timecha = (endtime - begintime); String totaltime = sumTime(timecha); System.out.println("轉(zhuǎn)換視頻格式共用了:" + totaltime + " "); if (processImg(sourceVideoPath)) { System.out.println("截圖成功了! "); } else { System.out.println("截圖失敗了! "); } if (isDelSourseFile) { deleteFile(sourceVideoPath); } sourceVideoPath = null; return true; } else { sourceVideoPath = null; return false; } } /** * 對(duì)視頻進(jìn)行截圖 * @param sourceVideoPath 需要被截圖的視頻路徑(包含文件名和擴(kuò)展名) * @return */ public boolean processImg(String sourceVideoPath) { if (!checkfile(sourceVideoPath)) { System.out.println(sourceVideoPath + " is not file"); return false; } File fi = new File(sourceVideoPath); filename = fi.getName(); filerealname = filename.substring(0, filename.lastIndexOf(".")).toLowerCase(); List<String> commend = new java.util.ArrayList<String>(); //第一幀: 00:00:01 //time ffmpeg -ss 00:00:01 -i test1.flv -f image2 -y test1.jpg commend.add(ffmpegpath); // commend.add("-i"); // commend.add(videoRealPath + filerealname + ".flv"); // commend.add("-y"); // commend.add("-f"); // commend.add("image2"); // commend.add("-ss"); // commend.add("38"); // commend.add("-t"); // commend.add("0.001"); // commend.add("-s"); // commend.add("320x240"); commend.add("-ss"); commend.add("00:00:01"); commend.add("-i"); commend.add(sourceVideoPath); commend.add("-f"); commend.add("image2"); commend.add("-y"); commend.add(imageRealPath + filerealname + ".jpg"); try { ProcessBuilder builder = new ProcessBuilder(); builder.command(commend); builder.start(); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 實(shí)際轉(zhuǎn)換視頻格式的方法 * @param targetExtension 目標(biāo)視頻擴(kuò)展名 * @param isDelSourseFile 轉(zhuǎn)換完成后是否刪除源文件 * @return */ private boolean process(String targetExtension, boolean isDelSourseFile) { int type = checkContentType(); boolean status = false; if (type == 0) { //如果type為0用ffmpeg直接轉(zhuǎn)換 status = processVideoFormat(sourceVideoPath,targetExtension, isDelSourseFile); } else if (type == 1) { //如果type為1,將其他文件先轉(zhuǎn)換為avi,然后在用ffmpeg轉(zhuǎn)換為指定格式 String avifilepath = processAVI(type); if (avifilepath == null){ // avi文件沒有得到 return false; }else { System.out.println("開始轉(zhuǎn)換:"); status = processVideoFormat(avifilepath,targetExtension, isDelSourseFile); } } return status; } /** * 檢查文件類型 * @return */ private int checkContentType() { String type = sourceVideoPath.substring(sourceVideoPath.lastIndexOf(".") + 1, sourceVideoPath.length()).toLowerCase(); // ffmpeg能解析的格式:(asx,asf,mpg,wmv,3gp,mp4,mov,avi,flv等) if (type.equals("avi")) { return 0; } else if (type.equals("mpg")) { return 0; } else if (type.equals("wmv")) { return 0; } else if (type.equals("3gp")) { return 0; } else if (type.equals("mov")) { return 0; } else if (type.equals("mp4")) { return 0; } else if (type.equals("asf")) { return 0; } else if (type.equals("asx")) { return 0; } else if (type.equals("flv")) { return 0; } // 對(duì)ffmpeg無法解析的文件格式(wmv9,rm,rmvb等), // 可以先用別的工具(mencoder)轉(zhuǎn)換為avi(ffmpeg能解析的)格式. else if (type.equals("wmv9")) { return 1; } else if (type.equals("rm")) { return 1; } else if (type.equals("rmvb")) { return 1; } return 9; } /** * 檢查文件是否存在 * @param path * @return */ private boolean checkfile(String path) { File file = new File(path); if (!file.isFile()) { return false; } else { return true; } } /** * 對(duì)ffmpeg無法解析的文件格式(wmv9,rm,rmvb等), 可以先用別的工具(mencoder)轉(zhuǎn)換為avi(ffmpeg能解析的)格式. * @param type * @return */ private String processAVI(int type) { List<String> commend = new java.util.ArrayList<String>(); commend.add(mencoderpath); commend.add(sourceVideoPath); 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"); commend.add(videofolder + filerealname + ".avi"); // 命令類型:mencoder 1.rmvb -oac mp3lame -lameopts preset=64 -ovc xvid // -xvidencopts bitrate=600 -of avi -o rmvb.avi try { ProcessBuilder builder = new ProcessBuilder(); builder.command(commend); Process p = builder.start(); doWaitFor(p); return videofolder + filerealname + ".avi"; } catch (Exception e) { e.printStackTrace(); return null; } } /** * 轉(zhuǎn)換為指定格式 * ffmpeg能解析的格式:(asx,asf,mpg,wmv,3gp,mp4,mov,avi,flv等) * @param oldfilepath * @param targetExtension 目標(biāo)格式擴(kuò)展名 .xxx * @param isDelSourseFile 轉(zhuǎn)換完成后是否刪除源文件 * @return */ private boolean processVideoFormat(String oldfilepath, String targetExtension, boolean isDelSourceFile) { if (!checkfile(sourceVideoPath)) { System.out.println(oldfilepath + " is not file"); return false; } //ffmpeg -i FILE_NAME.flv -ar 22050 NEW_FILE_NAME.mp4 List<String> commend = new java.util.ArrayList<>(); commend.add(ffmpegpath); commend.add("-i"); commend.add(oldfilepath); commend.add("-ar"); commend.add("22050"); commend.add(targetfolder + filerealname + targetExtension); try { ProcessBuilder builder = new ProcessBuilder(); String cmd = commend.toString(); builder.command(commend); Process p = builder.start(); doWaitFor(p); p.destroy(); //轉(zhuǎn)換完成后刪除源文件 // if (isDelSourceFile) { // deleteFile(sourceVideoPath); // } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * ffmpeg能解析的格式:(asx,asf,mpg,wmv,3gp,mp4,mov,avi,flv等) * @param oldfilepath * @return */ private boolean processFLV(String oldfilepath) { if (!checkfile(sourceVideoPath)) { System.out.println(oldfilepath + " is not file"); return false; } List<String> commend = new java.util.ArrayList<>(); commend.add(ffmpegpath); commend.add("-i"); commend.add(oldfilepath); commend.add("-ab"); commend.add("64"); commend.add("-acodec"); commend.add("mp3"); commend.add("-ac"); commend.add("2"); commend.add("-ar"); commend.add("22050"); commend.add("-b"); commend.add("230"); commend.add("-r"); commend.add("24"); commend.add("-y"); commend.add(targetfolder + filerealname + ".flv"); try { ProcessBuilder builder = new ProcessBuilder(); String cmd = commend.toString(); builder.command(commend); Process p = builder.start(); doWaitFor(p); p.destroy(); deleteFile(oldfilepath); return true; } catch (Exception e) { e.printStackTrace(); return false; } } 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) { Character c = new Character((char) in.read()); System.out.print(c); } while (err.available() > 0) { Character c = new Character((char) err.read()); System.out.print(c); } exitValue = p.exitValue(); finished = true; } catch (IllegalThreadStateException e) { Thread.currentThread().sleep(500); } } } catch (Exception e) { 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 exitValue; }
3)最后,編寫測(cè)試類:ConverVideoTest.java
public class ConverVideoTest { public void run() { try { // 轉(zhuǎn)換并截圖 String filePath = "C:\\Users\\wangdy\\Desktop\\pics\\05.尚硅谷_SVN_啟動(dòng)服務(wù)器.wmv"; ConverVideoUtils cv = new ConverVideoUtils(filePath); String targetExtension = ".mp4"; boolean isDelSourseFile = true; boolean beginConver = cv.beginConver(targetExtension,isDelSourseFile); System.out.println(beginConver); } catch (Exception e) { e.printStackTrace(); } } public static void main(String args[]) { ConverVideoTest c = new ConverVideoTest(); c.run(); } }
這樣就完成了整個(gè)視頻格式的轉(zhuǎn)換,在定義的目標(biāo)視頻文件夾和截圖存放文件夾就可以看到轉(zhuǎn)換后的視頻和視頻第一幀的截圖了。
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Javacv使用ffmpeg實(shí)現(xiàn)音視頻同步播放
- Java利用ffmpeg實(shí)現(xiàn)視頻MP4轉(zhuǎn)m3u8
- Java基于FFmpeg實(shí)現(xiàn)Mp4視頻轉(zhuǎn)GIF
- java使用ffmpeg實(shí)現(xiàn)上傳視頻的轉(zhuǎn)碼提取視頻的截圖等功能(代碼操作)
- java調(diào)用ffmpeg實(shí)現(xiàn)轉(zhuǎn)換視頻
- Java+Windows+ffmpeg實(shí)現(xiàn)視頻轉(zhuǎn)換功能
- 詳解java調(diào)用ffmpeg轉(zhuǎn)換視頻格式為flv
- java調(diào)用ffmpeg實(shí)現(xiàn)視頻轉(zhuǎn)換的方法
- Java工程使用ffmpeg進(jìn)行音視頻格式轉(zhuǎn)換的實(shí)現(xiàn)
相關(guān)文章
SpringBoot2.0整合jackson配置日期格式化和反序列化的實(shí)現(xiàn)
這篇文章主要介紹了SpringBoot2.0整合jackson配置日期格式化和反序列化的實(shí)現(xiàn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-11-11解決springboot mapper注入報(bào)紅問題
這篇文章主要介紹了解決springboot mapper注入報(bào)紅問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11Maven?Pom?文件中的隱式依賴導(dǎo)致Jar沖突問題
這篇文章主要介紹了Maven?Pom?文件中的隱式依賴導(dǎo)致Jar沖突問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12使用try-with-resource的輸入輸出流自動(dòng)關(guān)閉
這篇文章主要介紹了使用try-with-resource的輸入輸出流自動(dòng)關(guān)閉方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07Jeecg-Boot異常處理'jeecg-boot.QRTZ_LOCKS'?doesn'
這篇文章主要介紹了Jeecg-Boot異常處理'jeecg-boot.QRTZ_LOCKS'?doesn't?exist問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12Java8新特性之類型注解_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了Java8新特性之類型注解的相關(guān)資料,需要的朋友可以參考下2017-06-06