电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

JAVA使用ffmepg處理視頻的方法(壓縮,分片,合并)

瀏覽:43日期:2022-08-12 16:01:56
FFmepg安裝

路徑:然后在使用的類中生命一個全局變量就好

private static String ffmpegPath = 'C:hkffmpegbinffmpeg.exe'; //ffmepg的絕對路徑視頻壓縮

注意:此壓縮視頻涉及轉碼,對cpu的占用比較大(能不壓縮盡量不壓縮)

/** * 壓縮視頻 * @param convertFile 待轉換的文件 * @param targetFile 轉換后的目標文件 */ public static void toCompressFile(String convertFile,String targetFile) throws IOException {List<String> command = new ArrayList<String>();/**將視頻壓縮為 每秒15幀 平均碼率600k 畫面的寬與高 為1280*720*/command.add(ffmpegPath);command.add('-i');command.add(convertFile);command.add('-r');command.add('15');command.add('-b:v');command.add('600k');command.add('-s');command.add('1280x720');command.add(targetFile);ProcessBuilder builder = new ProcessBuilder(command);Process process = null;try { process = builder.start();} catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace();}// 使用這種方式會在瞬間大量消耗CPU和內存等系統資源,所以這里我們需要對流進行處理InputStream errorStream = process.getErrorStream();InputStreamReader inputStreamReader = new InputStreamReader(errorStream);BufferedReader br = new BufferedReader(inputStreamReader);String line = '';while ((line = br.readLine()) != null) {}if (br != null) { br.close();}if (inputStreamReader != null) { inputStreamReader.close();}if (errorStream != null) { errorStream.close();}logger.info('-------------------壓縮完成---轉存文件--'+targetFile+'-------------'); }獲取視頻合并

/** * ffmpeg合并多個視頻文件 * * @param list 需要合并的多視頻url地址以List存放 * @param outputDir 此處是ffmpeg 配置地址,可寫死如“E:/ffmpeg/bin/ffmpeg.exe” * @param outputFile 合并后的視頻存放地址,如:E:/mergevideo.mp4 * @date: 2021/4/17 9:31 * @return: void */ public static String mergeVideo(List<String> list, String outputDir, String outputFile) {try { String format1 = '%s -i %s -c copy -bsf:v h264_mp4toannexb -f mpegts %s'; List<String> commandList = new ArrayList<>(6); List<String> inputList = new ArrayList<>(6); for (int i = 0; i < list.size(); i++) {String input = String.format('input%d.ts', i + 1);String command = String.format(format1, ffmpegPath, list.get(i), outputDir + input);commandList.add(command);inputList.add(input); } String command = getCommand(outputDir,outputFile, inputList); commandList.add(command); Boolean falg = Boolean.FALSE; for (int i = 0; i < commandList.size(); i++) {if (execCommand(commandList.get(i)) > 0) falg = true; } if (falg) {for (int i = 0; i < inputList.size(); i++) { if (i != commandList.size() - 1) {File file = new File(outputDir + inputList.get(i));file.delete(); }}////刪除壓縮的文件//for (String s:list// ) {// new File(s).delete();//}return outputFile; } else {return 'fail'; }} catch (Exception e) { e.printStackTrace(); logger.error('-----合并失敗!!!!!!' + outputFile); return 'fail';} } private static Integer execCommand(String command) {logger.info('execCommand.exec command={}',command);try { Process process = Runtime.getRuntime().exec(command); //獲取進程的標準輸入流 final InputStream is1 = process.getInputStream(); //獲取進城的錯誤流 final InputStream is2 = process.getErrorStream(); //啟動兩個線程,一個線程負責讀標準輸出流,另一個負責讀標準錯誤流 readInputStream(is1); readInputStream(is2); process.waitFor(); process.destroy(); logger.info('-----操作成功' + command + ' ' + sdf.format(new Date())); return 1;} catch (Exception e) { e.printStackTrace(); System.out.println('-----操作失敗' + command); return -1;} } private static void readInputStream(InputStream inputStream) {new Thread(() -> { BufferedReader br1 = new BufferedReader(new InputStreamReader(inputStream)); try {String line1;while ((line1 = br1.readLine()) != null) { if (line1 != null) { }} } catch (IOException e) {e.printStackTrace(); } finally {try { inputStream.close();} catch (IOException e) { e.printStackTrace();} }}).start(); }視頻分片(分割)

/** * 將視頻分割為小段 * * @param fileName 源文件名字(帶路徑) * @param outputPath 輸出文件路徑,會在該路徑下根據系統時間創建目錄,并在此目錄下輸出段視頻 * @param videoTime 總時間,單位 分鐘 * @param periodTime 小段視頻時長 單位 分鐘 * @param merge true合并,false單獨分割 說明:是否將整個視頻結尾部分不足一次分割時間的部分,合并到最后一次分割的視頻中,即false會比true多生成一段視頻 */ public static List<Map<String,Object>> splitVideoFile(String fileName, String outputPath, float videoTime, int periodTime, boolean merge) {final String TAG = '----------------------------';// 在outputPath路徑下根據系統時間創建目錄File file = createFileBySysTime(outputPath);if (file == null) { System.out.println('分割視頻失敗,創建目錄失敗'); return null;}outputPath = file.getPath() + File.separator; // 更新視頻輸出目錄// 計算視頻分割的個數int count;// 分割為幾段float remain = 0; // 不足一次剪輯的剩余時間if (merge) { count = (int) (videoTime / periodTime); remain = videoTime % periodTime; // 不足一次剪輯的剩余時間} else { count = (int) (videoTime / periodTime) + 1;}System.out.println('將視頻分割為' + count + '段,每段約' + periodTime + '分鐘');String indexName; // 第 i 個視頻,打印日志用final String FFMPEG = ffmpegPath;String startTime; // 每段視頻的開始時間String periodVideoName; // 每段視頻的名字,名字規則:視頻i_時間段xx_yyfloat duration; // 每次分割的時長String command;// 執行的命令// 得到視頻后綴 如.mp4String videoSuffix = fileName.substring(fileName.lastIndexOf('.'));//得到點后面的后綴,包括點Runtime runtime = Runtime.getRuntime(); // 執行命令者List<Map<String,Object>> list =new ArrayList<>();// 將視頻分割為count段for (int i = 0; i < count; i++) { Map<String,Object> map =new HashMap<>(); indexName = '第' + (i+1) + '個視頻'; // 決定是否將整個視頻結尾部分不足一次的時間,合并到最后一次分割的視頻中 if (merge) {if (i == count - 1) { duration = periodTime * 60 + remain * 60;// 將整個視頻不足一次剪輯的時間,拼接在最后一次剪裁中 if(periodTime * i /60 >= 1){startTime = '0'+periodTime * i /60+ ':00:00'; }else{startTime = periodTime * i + ':00'; } periodVideoName = 'video' + (i+1) + '_' + periodTime * i + '_end' + videoSuffix;} else { duration = periodTime * 60; if(periodTime * i /60 >= 1){startTime = '0'+periodTime * i /60+ ':00:00'; }else{startTime = periodTime * i + ':00'; } periodVideoName = 'video' +(i+1) + '_' + periodTime * i + '_' + periodTime * (i + 1) + videoSuffix;} } else {duration = periodTime * 60;if(periodTime * i /60 >= 1){ startTime = '0'+periodTime * i /60+ ':00:00';}else{ startTime = periodTime * i + ':00';}periodVideoName = 'video' + (i+1) + '_' + periodTime * i + '_' + periodTime * (i + 1) + videoSuffix; } // 執行分割命令 try {// 創建命令command = FFMPEG + ' -ss ' + startTime +' -accurate_seek '+ ' -i ' + fileName + ' -c copy -t ' + duration + ' ' + outputPath + periodVideoName;System.out.println(TAG);System.out.println(indexName);System.out.println('執行命令:' + command);runtime.exec(command);System.out.println(indexName + '分割成功');map.put('videoPath',(outputPath + periodVideoName).replace('','/'));map.put('count',i);list.add(map); } catch (Exception e) {e.printStackTrace();System.out.println(indexName + '分割失敗!!!!!!'); }}//刪除原來的大視頻new File(fileName).delete();return list; }/** * 在指定目錄下根據系統時間創建文件夾 * 文件名字eg:2019-07-02-23-56-31 * * @param path 路徑:eg: '/Users/amarao/業余/剪輯/output/'; * 結果:創建成功/Users/amarao/業余/剪輯/output/2019-07-03-10-28-05 * <p> * 步驟: * 1. 讀取系統時間 * 2. 格式化系統時間 * 3. 創建文件夾 * <p> * 參考:http://www.bubuko.com/infodetail-1685972.html */ public static File createFileBySysTime(String path) {// 1. 讀取系統時間Calendar calendar = Calendar.getInstance();Date time = calendar.getTime();// 2. 格式化系統時間SimpleDateFormat format = new SimpleDateFormat('yyyy-MM-dd-HH-mm-ss');String fileName = format.format(time); //獲取系統當前時間并將其轉換為string類型,fileName即文件名// 3. 創建文件夾String newPath = path + fileName;File file = new File(newPath);//如果文件目錄不存在則創建目錄if (!file.exists()) { if (!file.mkdir()) {System.out.println('當前路徑不存在,創建失敗');return null; }}System.out.println('創建成功' + newPath);return file; }獲取視頻的時長

/** * 獲取視頻時長 單位/秒 * @param video * @return */ public static long getVideoDuration(File video) {long duration = 0L;FFmpegFrameGrabber ff = new FFmpegFrameGrabber(video);try { ff.start(); duration = ff.getLengthInTime() / (1000 * 1000 * 60); ff.stop();} catch (FrameGrabber.Exception e) { e.printStackTrace();}return duration; }視頻剪切

/** * *剪切視頻 videoInputPath 需要處理的視頻路徑 startTime: 截取的開始時間 格式為 00:00:00(時分秒) endTime: 截取的結束時間 格式為00:03:00(時分秒) devIp: 通道號 業務存在 ,可自行刪除 * */ public static String videoClip(String videoInputPath,String startTime,String endTime,String devIp) throws IOException {SimpleDateFormat sdf1=new SimpleDateFormat('yyyy-MM-dd');SimpleDateFormat dtf=new SimpleDateFormat('yyyyMMddHHmmss');//判斷轉碼文件是否存在if(!new File(videoInputPath).exists()){ System.out.println('需要處理的視頻不存在'); return null;}StringBuffer videoOutPath = new StringBuffer();videoOutPath.append('C:/video/playBack/'+devIp+'/'+sdf1.format(new Date())+'/clip/');File file = new File(videoOutPath.toString());if (!file.exists()){ file.mkdirs();}videoOutPath.append(dtf.format(new Date())+'.mp4');List<String> command = new ArrayList<String>();command.add(ffmpegPath);command.add('-ss');command.add(startTime);command.add('-t');command.add(endTime);command.add('-i');command.add(videoInputPath);command.add('-c');command.add('copy');command.add(videoOutPath.toString());command.add('-y');ProcessBuilder builder = new ProcessBuilder(command);Process process = null;try { process = builder.start();} catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace();}InputStream errorStream = process.getErrorStream();InputStreamReader inputStreamReader = new InputStreamReader(errorStream);BufferedReader br = new BufferedReader(inputStreamReader);String line = '';while ((line = br.readLine()) != null) {}if (br != null) { br.close();}if (inputStreamReader != null) { inputStreamReader.close();}if (errorStream != null) { errorStream.close();}return videoOutPath.toString(); }視頻轉GIF(MP4)

/* * 視頻轉gif *inputVideoPath 需要轉換的視頻 * createGif gif保存的位置 * */ public static String mp4ToGif(String inputVideoPath,String createGif) {String name = UUID.randomUUID().toString().replaceAll('-', '');String paletteFile = createGif +name + '.png';String gifFile = createGif+name + '.gif';boolean isComplete = false;//操作ffmpeg生成gif圖片for (int i = 0; i < 5; i++) { try {//生成調色板Process p = new ProcessBuilder().command(ffmpegPath,'-v', 'warning','-ss', '2','-t', '10','-i', inputVideoPath,'-vf', 'fps=5,scale=400:-1:flags=lanczos,palettegen','-y', paletteFile, '-vn').redirectError(new File('stderr.txt')).start();isComplete = p.waitFor(10, TimeUnit.SECONDS);if (!isComplete) { System.out.println('生成調色板出錯');} else { List<String> command = new ArrayList<String>(); /**將視頻壓縮為 每秒15幀 平均碼率600k 畫面的寬與高 為1280*720*/ command.add(ffmpegPath); command.add('-v'); command.add('warning'); command.add('-ss'); command.add('2'); command.add('-t'); command.add('10'); command.add('-i'); command.add(inputVideoPath); command.add('-i'); command.add(paletteFile); command.add('-lavfi'); command.add('fps=5,scale=400:-1:flags=lanczos [x]; [x][1:v] paletteuse'); command.add('-y'); command.add(gifFile); command.add('-vn'); ProcessBuilder builder = new ProcessBuilder(command); Process process = null; try {process = builder.start();isComplete = process.waitFor(10, TimeUnit.SECONDS);if (isComplete) { new File(paletteFile).delete(); System.out.println('生成gif成功'); break;} else { System.out.println('生成gif出錯');} } catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace(); }//process = new ProcessBuilder()// .command(ffmpegPath,// '-v', 'warning',// '-ss', '2',// '-t', '10',// '-i', 'E:Video_2021-05-14_113013.mp4',// '-i', paletteFile,// '-lavfi', 'fps=5,scale=400:-1:flags=lanczos [x]; [x][1:v] paletteuse',// '-y', gifFile, '-vn')// .redirectError(new File('stderr.txt'))// .start();// isComplete = process.waitFor(10, TimeUnit.SECONDS);// if (isComplete) {//System.out.println('生成gif成功');//break;// } else {//System.out.println('生成gif出錯');// }} } catch (Exception e) {System.out.println('生成gif出錯'); }}return gifFile; }

以上就是JAVA使用ffmepg處理視頻的方法(壓縮,分片,合并)的詳細內容,更多關于java ffmepg處理視頻的資料請關注好吧啦網其它相關文章!

標簽: Java
相關文章:
主站蜘蛛池模板: 手术室净化装修-手术室净化工程公司-华锐手术室净化厂家 | Magnescale探规,Magnescale磁栅尺,Magnescale传感器,Magnescale测厚仪,Mitutoyo光栅尺,笔式位移传感器-苏州连达精密量仪有限公司 | 国际金融网_每日财经新资讯网 | 北京晚会活动策划|北京节目录制后期剪辑|北京演播厅出租租赁-北京龙视星光文化传媒有限公司 | 中国产业发展研究网 - 提供行业研究报告 可行性研究报告 投资咨询 市场调研服务 | 硫化罐-胶管硫化罐-山东鑫泰鑫智能装备有限公司 | 地磅-电子地磅维修-电子吊秤-汽车衡-无人值守系统-公路治超-鹰牌衡器 | 合肥抖音SEO网站优化-网站建设-网络推广营销公司-百度爱采购-安徽企匠科技 | 锻造液压机,粉末冶金,拉伸,坩埚成型液压机定制生产厂家-山东威力重工官方网站 | 免费分销系统 — 分销商城系统_分销小程序开发 -【微商来】 | 齿轮减速马达一体式_蜗轮蜗杆减速机配电机-德国BOSERL齿轮减速电动机生产厂家 | 马尔表面粗糙度仪-MAHR-T500Hommel-Mitutoyo粗糙度仪-笃挚仪器 | 北京乾茂兴业科技发展有限公司| 申江储气罐厂家,储气罐批发价格,储气罐规格-上海申江压力容器有限公司(厂) | 电磁铁_推拉电磁铁_机械手电磁吸盘电磁铁厂家-广州思德隆电子公司 | 水平垂直燃烧试验仪-灼热丝试验仪-漏电起痕试验仪-针焰试验仪-塑料材料燃烧检测设备-IP防水试验机 | 砖机托板价格|免烧砖托板|空心砖托板厂家_山东宏升砖机托板厂 | 尼龙PA610树脂,尼龙PA612树脂,尼龙PA1010树脂,透明尼龙-谷骐科技【官网】 | 除甲醛公司-甲醛检测治理-杭州创绿家环保科技有限公司-室内空气净化十大品牌 | 综合管廊模具_生态,阶梯护坡模具_检查井模具制造-致宏模具厂家 | 碳化硅,氮化硅,冰晶石,绢云母,氟化铝,白刚玉,棕刚玉,石墨,铝粉,铁粉,金属硅粉,金属铝粉,氧化铝粉,硅微粉,蓝晶石,红柱石,莫来石,粉煤灰,三聚磷酸钠,六偏磷酸钠,硫酸镁-皓泉新材料 | 江苏齐宝进出口贸易有限公司| 进口试验机价格-进口生物材料试验机-西安卡夫曼测控技术有限公司 | 重庆LED显示屏_显示屏安装公司_重庆LED显示屏批发-彩光科技公司 重庆钣金加工厂家首页-专业定做监控电视墙_操作台 | 散热器-电子散热器-型材散热器-电源散热片-镇江新区宏图电子散热片厂家 | 杭州高温泵_热水泵_高温油泵|昆山奥兰克泵业制造有限公司 | Dataforth隔离信号调理模块-信号放大模块-加速度振动传感器-北京康泰电子有限公司 | 氧化铝球_高铝球_氧化铝研磨球-淄博誉洁陶瓷新材料有限公司 | 菲希尔X射线测厚仪-菲希尔库伦法测厚仪-无锡骏展仪器有限责任公司 | 学叉车培训|叉车证报名|叉车查询|叉车证怎么考-工程机械培训网 | 农业仪器网 - 中国自动化农业仪器信息交流平台 | 超声波清洗机_细胞破碎仪_实验室超声仪器_恒温水浴-广东洁盟深那仪器 | 披萨石_披萨盘_电器家电隔热绵加工定制_佛山市南海区西樵南方综合保温材料厂 | 品牌策划-品牌设计-济南之式传媒广告有限公司官网-提供品牌整合丨影视创意丨公关活动丨数字营销丨自媒体运营丨数字营销 | ★店家乐|服装销售管理软件|服装店收银系统|内衣店鞋店进销存软件|连锁店管理软件|收银软件手机版|会员管理系统-手机版,云版,App | pbt头梳丝_牙刷丝_尼龙毛刷丝_PP塑料纤维合成毛丝定制厂_广州明旺 | 非甲烷总烃分析仪|环控百科| 螺杆真空泵_耐腐蚀螺杆真空泵_水环真空泵_真空机组_烟台真空泵-烟台斯凯威真空 | 压缩空气冷冻式干燥机_吸附式干燥机_吸干机_沪盛冷干机 | 福州甲醛检测-福建室内空气检测_环境检测_水质检测-福建中凯检测技术有限公司 | 交联度测试仪-湿漏电流测试仪-双85恒温恒湿试验箱-常州市科迈实验仪器有限公司 |