直接上代码:

  1. public abstract class FFmpegUtils {
  2.  
  3. FFmpegUtils ffmpegUtils;
  4.  
  5. int timeLengthSec = ;
  6.  
  7. String timeLength = "";
  8.  
  9. Pattern pattern = Pattern.compile("Duration: (.*?), start: (.*?), bitrate: (\\d*) kb\\/s");
  10. String frameRegexDuration = "size=([\\s\\S]*) time=(.*?) bitrate=([\\s\\S]*) speed=(.*?)x";
  11. String videoframeRegexDuration = "frame=([\\s,\\d]*) fps=(.*?) q=(.*?) size=([\\s\\S]*) time=(.*?) bitrate=([\\s\\S]*) speed=(.*?)x";
  12. Pattern framePattern = Pattern.compile(frameRegexDuration);
  13.  
  14. public static void main(String[] args){
  15. String target = "";
  16. /* try {
  17. target = extractAsyn("D:\\ffmpeg4.2\\bin\\ffmpeg.exe",
  18. "-y -f image2 -ss 1 -t 0.001 -s 640x480",
  19. "E:\\迅雷下载\\电影\\test.avi",
  20. "E:\\迅雷下载\\电影\\test.avi.jpg");
  21. System.out.println(target);
  22. } catch (Throwable e) {
  23. System.err.println(e.getMessage());
  24. }
  25. */
  26. try {
  27.  
  28. new FFmpegUtils() {
  29. @Override
  30. public void dealLine(String line) {
  31. System.out.println(line);
  32. if(timeLength == null || timeLength.equals("")) {
  33. Matcher m = pattern.matcher(line.trim());
  34. if (m.find()) {
  35. timeLength = m.group();
  36. if(timeLength!=null){
  37. timeLengthSec = FFVideoUtil.getTimelen(timeLength);
  38. }
  39. System.out.println(timeLength+"||"+timeLengthSec);
  40. }
  41. }
  42.  
  43. //获取视频信息
  44. Matcher matcher = framePattern.matcher(line);
  45. if(matcher.find()){
  46. try {
  47. String execTimeStr = matcher.group();
  48. int execTimeInt = FFVideoUtil.getTimelen(execTimeStr);
  49. double devnum = FFBigDecimalUtil.div(execTimeInt,timeLengthSec,);
  50. double progressDouble = FFBigDecimalUtil.mul(devnum,);
  51. System.out.println("execTimeInt:"+execTimeInt+"&,devnum:"+devnum+"&,progressDouble:"+progressDouble);
  52. } catch (IllegalAccessException e) {
  53. System.err.println("获取输出流异常:"+e.getMessage());
  54. }
  55. }
  56. }
  57.  
  58. @Override
  59. public void dealStream(Process process) {
  60. if (process == null) {
  61. return;
  62. }
  63. // 处理InputStream的线程
  64. new Thread() {
  65. @Override
  66. public void run() {
  67. BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
  68. String line = null;
  69. try {
  70. while ((line = in.readLine()) != null) {
  71. //logger.info("output: " + line);
  72. dealLine(line);
  73. }
  74. } catch (IOException e) {
  75. e.printStackTrace();
  76. } finally {
  77. try {
  78. in.close();
  79. } catch (IOException e) {
  80. e.printStackTrace();
  81. }
  82. }
  83. }
  84. }.start();
  85. // 处理ErrorStream的线程
  86. new Thread() {
  87. @Override
  88. public void run() {
  89. BufferedReader err = new BufferedReader(new InputStreamReader(process.getErrorStream()));
  90. String line = null;
  91. try {
  92. while ((line = err.readLine()) != null) {
  93. dealLine(line);
  94. }
  95. } catch (IOException e) {
  96. e.printStackTrace();
  97. } finally {
  98. try {
  99. err.close();
  100. } catch (IOException e) {
  101. e.printStackTrace();
  102. }
  103. }
  104. }
  105. }.start();
  106. }
  107. }.processVideoSync("D:\\ffmpeg4.2\\bin\\ffmpeg.exe",
  108. " -f|mp3",
  109. "E:\\迅雷下载\\电影\\test.avi",
  110. "E:\\迅雷下载\\电影\\test.avi.mp3");
  111. System.out.println(target);
  112. } catch (Throwable e) {
  113. System.err.println(e.getMessage());
  114. }
  115.  
  116. }
  117.  
  118. //异步 适合抽帧等快速的操作
  119. public static String extractAsyn(
  120. String ffmpegPath,String cmdParam,
  121. String sourceFile,String targetFile)
  122. throws Throwable {
  123.  
  124. Runtime runtime = Runtime.getRuntime();
  125. Process proce = null;
  126. // 视频截图命令,封面图。 8是代表第8秒的时候截图
  127. String cmd = "";
  128. String cut = ffmpegPath +" -i "+ sourceFile +" "+ cmdParam +" "+ targetFile;
  129. String cutCmd = cmd + cut;
  130. proce = runtime.exec(cutCmd);
  131. proce.getOutputStream();
  132. System.out.println("抽帧命令是:"+cut);
  133. return targetFile;
  134. }
  135.  
  136. public static boolean checkfile(String path) {
  137. File file = new File(path);
  138. if (!file.isFile()) {
  139. return false;
  140. }
  141. return true;
  142. }
  143.  
  144. //异步处理
  145. public boolean processVideoSync(String ffmpegPath,String cmdParam,
  146. String sourceFile,String targetFile) {
  147.  
  148. // 文件命名
  149. List<String> commond = new ArrayList<String>();
  150. commond.add(ffmpegPath);
  151. commond.add("-i");
  152. commond.add(sourceFile);
  153. commond.addAll(Arrays.asList(cmdParam.trim().split("\\|")));
  154. commond.add(targetFile);
  155.  
  156. if(new File(targetFile).exists()) {
  157. new File(targetFile).delete();
  158. }
  159.  
  160. String cmds = "";
  161. for (String cmd : commond) {
  162. cmds = cmds + " " + cmd;
  163. }
  164. System.out.println("执行命令参数为:" + cmds);
  165. try {
  166. // 调用线程命令进行转码
  167. Process videoProcess = new ProcessBuilder(commond).redirectErrorStream(true).start();
  168. //new PrintStream(videoProcess.getInputStream()).start();
  169. //videoProcess.waitFor();
  170. /*new InputStreamReader(videoProcess.getErrorStream());
  171. BufferedReader stdout = new BufferedReader(new InputStreamReader(videoProcess.getInputStream()));
  172. String line;
  173. while ((line = stdout.readLine()) != null) {
  174. dealLine(line);
  175. }*/
  176. dealStream(videoProcess);
  177. videoProcess.waitFor();
  178.  
  179. return true;
  180. } catch (Exception e) {
  181. e.printStackTrace();
  182. return false;
  183. }
  184. }
  185.  
  186. //处理输出流
  187. public abstract void dealLine(String line);
  188. public abstract void dealStream(Process process );
  189. }

FFmpegUtils.java

  1. @Component
  2. public class ProgressService extends FFmpegUtils{
  3.  
  4. public static Logger logger = LoggerFactory.getLogger(ProgressService.class);
  5.  
  6. /**
  7. * 进度正则查询
  8. */
  9. private String frameRegexDuration = "frame=([\\s,\\d]*) fps=(.*?) q=(.*?) size=([\\s\\S]*) time=(.*?) bitrate=([\\s\\S]*) speed=(.*?)x";
  10.  
  11. /**
  12. * 正则模式
  13. */
  14. private Pattern framePattern = Pattern.compile(frameRegexDuration);
  15.  
  16. /**
  17. * 秒数
  18. */
  19. private Integer timeLengthSec;
  20.  
  21. /**
  22. * 时长
  23. */
  24. private String timeLength;
  25.  
  26. /**
  27. * 开始时间
  28. */
  29. private String startTime;
  30.  
  31. /**
  32. * 比特率
  33. */
  34. private String bitrate;
  35.  
  36. /**
  37. * 时长 正则
  38. */
  39. private String regexDuration = "Duration: (.*?), start: (.*?), bitrate: (\\d*) kb\\/s";
  40.  
  41. /**
  42. * 正则模式
  43. */
  44. private Pattern pattern = Pattern.compile(regexDuration);
  45.  
  46. public String getStartTime() {
  47. return startTime;
  48. }
  49.  
  50. public void setStartTime(String startTime) {
  51. this.startTime = startTime;
  52. }
  53.  
  54. public String getBitrate() {
  55. return bitrate;
  56. }
  57.  
  58. public void setBitrate(String bitrate) {
  59. this.bitrate = bitrate;
  60. }
  61.  
  62. private TranscodeTask task;
  63.  
  64. public TranscodeTask getTask() {
  65. return task;
  66. }
  67.  
  68. public void setTask(TranscodeTask task) {
  69. this.task = task;
  70. }
  71.  
  72. @Autowired
  73. private TaskReposity _taskRep;
  74.  
  75. @Override
  76. public void dealLine(String line) {
  77. logger.debug("{}输出信息:{}",task.getName(),line);
  78. //获取视频长度信息
  79. if(timeLength == null || "".equals(timeLength)) {
  80. Matcher m = pattern.matcher(line.trim());
  81. if (m.find()) {
  82. timeLength = m.group();
  83. if(timeLength!=null){
  84. timeLengthSec = FFVideoUtil.getTimelen(timeLength);
  85. }
  86. startTime = m.group();
  87. bitrate = m.group();
  88. logger.debug("timeLength:{}, startTime:{},bitrate:{}",timeLength,startTime,bitrate);
  89. }
  90. }
  91.  
  92. //获取视频信息
  93. Matcher matcher = framePattern.matcher(line);
  94. if(matcher.find()){
  95. try {
  96. String execTimeStr = matcher.group();
  97. int execTimeInt = FFVideoUtil.getTimelen(execTimeStr);
  98. double devnum = FFBigDecimalUtil.div(execTimeInt,timeLengthSec,);
  99. double progressDouble = FFBigDecimalUtil.mul(devnum,);
  100. logger.debug("execTimeInt:{},devnum:{},progressDouble:{}",execTimeInt,devnum,progressDouble);
  101. task.setProgress((float)progressDouble);
  102. _taskRep.saveAndFlush(this.task);
  103. } catch (IllegalAccessException e) {
  104. logger.error("获取输出流异常:{}",e.getMessage());
  105. }
  106. }
  107. }
  108.  
  109. /**
  110. * 处理process输出流和错误流,防止进程阻塞
  111. * 在process.waitFor();前调用
  112. * @param process
  113. */
  114. @Override
  115. public void dealStream(Process process) {
  116. if (process == null) {
  117. return;
  118. }
  119. // 处理InputStream的线程
  120. new Thread() {
  121. @Override
  122. public void run() {
  123. BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
  124. String line = null;
  125. try {
  126. while ((line = in.readLine()) != null) {
  127. //logger.info("output: " + line);
  128. dealLine(line);
  129. }
  130. } catch (IOException e) {
  131. e.printStackTrace();
  132. } finally {
  133. try {
  134. in.close();
  135. } catch (IOException e) {
  136. e.printStackTrace();
  137. }
  138. }
  139. }
  140. }.start();
  141. // 处理ErrorStream的线程
  142. new Thread() {
  143. @Override
  144. public void run() {
  145. BufferedReader err = new BufferedReader(new InputStreamReader(process.getErrorStream()));
  146. String line = null;
  147. try {
  148. while ((line = err.readLine()) != null) {
  149. logger.info("err: " + line);
  150. }
  151. } catch (IOException e) {
  152. e.printStackTrace();
  153. } finally {
  154. try {
  155. err.close();
  156. } catch (IOException e) {
  157. e.printStackTrace();
  158. }
  159. }
  160. }
  161. }.start();
  162. }
  163.  
  164. }
  1. @Component
  2. public class FileService {
  3.  
  4. public static Logger logger = LoggerFactory.getLogger(FileService.class);
  5.  
  6. // 下载小文件
  7. public File downloadFile(String formUrl, String fileName) throws Throwable {
  8. File desc = null;
  9. CloseableHttpClient httpclient = HttpClients.createDefault();
  10. HttpGet httpget = new HttpGet(formUrl);
  11. httpget.setConfig(RequestConfig.custom() //
  12. .setConnectionRequestTimeout() //
  13. .setConnectTimeout() //
  14. .setSocketTimeout() //
  15. .build());
  16. logger.debug("正在从{}下载文件到{}",formUrl,fileName);
  17. try (CloseableHttpResponse response = httpclient.execute(httpget)) {
  18. org.apache.http.HttpEntity entity = response.getEntity();
  19. desc = new File(fileName);
  20. try (InputStream is = entity.getContent(); //
  21. OutputStream os = new FileOutputStream(desc)) {
  22. StreamUtils.copy(is, os);
  23. logger.debug("成功从{}下载文件到{}",formUrl,fileName);
  24. }
  25. }
  26. return desc;
  27. }
  28.  
  29. public void downloadLittleFileToPath(String url, String target) {
  30. Instant now = Instant.now();
  31. RestTemplate template = new RestTemplate();
  32. ClientHttpRequestFactory clientFactory = new HttpComponentsClientHttpRequestFactory();
  33. template.setRequestFactory(clientFactory);
  34. HttpHeaders header = new HttpHeaders();
  35. List<MediaType> list = new ArrayList<MediaType>();
  36. // 指定下载文件类型
  37. list.add(MediaType.APPLICATION_OCTET_STREAM);
  38. header.setAccept(list);
  39. HttpEntity<byte[]> request = new HttpEntity<byte[]>(header);
  40. ResponseEntity<byte[]> rsp = template.exchange(url, HttpMethod.GET, request, byte[].class);
  41. logger.info("[下载文件] [状态码] code:{}", rsp.getStatusCode());
  42. try {
  43. if(Paths.get(target).toFile().exists()) {
  44. Paths.get(target).toFile().delete();
  45. }
  46. Files.write(Paths.get(target), Objects.requireNonNull(rsp.getBody(), "未获取到下载文件"));
  47. } catch (IOException e) {
  48. logger.error("[下载文件] 写入失败:", e);
  49. }
  50. logger.info("[下载文件] 完成,耗时:{}", ChronoUnit.MILLIS.between(now, Instant.now()));
  51. }
  52.  
  53. public void downloadBigFileToPath(String url, String target) {
  54. Instant now = Instant.now();
  55. try {
  56. RestTemplate template = new RestTemplate();
  57. ClientHttpRequestFactory clientFactory = new HttpComponentsClientHttpRequestFactory();
  58. template.setRequestFactory(clientFactory);
  59. //定义请求头的接收类型
  60. RequestCallback requestCallback = request -> request.getHeaders()
  61. .setAccept(Arrays.asList(MediaType.APPLICATION_OCTET_STREAM, MediaType.ALL));
  62. // getForObject会将所有返回直接放到内存中,使用流来替代这个操作
  63. ResponseExtractor<Void> responseExtractor = response -> {
  64. // Here I write the response to a file but do what you like
  65. if(Files.exists(Paths.get(target), LinkOption.NOFOLLOW_LINKS)) {
  66. Files.delete(Paths.get(target));
  67. }
  68. Files.copy(response.getBody(), Paths.get(target));
  69. return null;
  70. };
  71. template.execute(url, HttpMethod.GET, requestCallback, responseExtractor);
  72. } catch (Throwable e) {
  73. logger.error("[下载文件] 写入失败:", e);
  74. }
  75. logger.info("[下载文件] 完成,耗时:{}", ChronoUnit.MILLIS.between(now, Instant.now()));
  76. }
  77.  
  78. }

FileService

有个问题需要注意:

转码目标文件必须不存在才行,如果存在 先删除,不然就卡死。

JAVA调用FFMpeg进行转码等操作的更多相关文章

  1. Java调用FFmpeg进行视频处理及Builder设计模式的应用

    1.FFmpeg是什么 FFmpeg(https://www.ffmpeg.org)是一套可以用来记录.转换数字音频.视频,并能将其转化为流的开源计算机程序.它用来干吗呢?视频采集.视频格式转化.视频 ...

  2. java调用ffmpeg命令行推流遇到的问题

    1.Java调用命令行,如果没有额外环境变量,不指定工作路径,Runtime有两个方法 public Process exec(String command) public Process exec( ...

  3. java调用FFmpeg及mencoder转换视频为FLV并截图

    Conver.java package com.ll19.flv; public class Conver { public void run() { try { // 转换并截图 String fi ...

  4. java运用FFMPEG视频转码技术

    基于windows系统安装FFMPEG转码技术 http://wenku.baidu.com/link?url=z4Tv3CUXxxzLpa5QPI-FmfFtrIQeiCYNq6Uhe6QCHkU- ...

  5. java调用ffmpeg获取视频文件信息的一些参数

    一.下载ffmpeg http://www.ffmpeg.org/download.html 主要需要bin目录下的ffmpeg可执行文件 二.java代码实现 package com.aw.util ...

  6. Java使用FFmpeg处理视频文件指南

    Java使用FFmpeg处理视频文件指南 本文主要讲述如何使用Java + FFmpeg实现对视频文件的信息提取.码率压缩.分辨率转换等功能: 之前在网上浏览了一大圈Java使用FFmpeg处理音视频 ...

  7. Java使用FFmpeg处理视频文件的方法教程

    这篇文章主要给大家介绍了关于Java使用FFmpeg处理视频文件的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧 前言 本文主要 ...

  8. Java调用ffmepg+mencoder视频格式转换(*)

    PS: 建议大家在官网下载最新的资源 其他格式转FLV格式,可以用Java调用ffmpeg和memcoder实现 ffmepg: D:\ffmpeg\bin\ffmpeg.exe -i E:\1.mp ...

  9. java调用c++ dll出现中文乱码

    近期的开发用到了使用java调用本机动态连接库的功能,将文件路径通过java调用C++代码对文件进行操作. 在调用中假设路径中包括有中文字符就会出现故障.程序执行就会中止. 以下用一个小样例,来说明记 ...

随机推荐

  1. bzoj 3696: 化合物

    哦,这个困惑了我好久的东西——生成函数(母函数),(然而拿这个东西去向学文化课的同学装逼并不成功...) 生成函数,就是把原来的加法组合变成乘法的指数加法,那么我们要求的值就是相应的指数的系数的值啦, ...

  2. [LeetCode] 931. Minimum Falling Path Sum 下降路径最小和

    Given a square array of integers A, we want the minimum sum of a falling path through A. A falling p ...

  3. jquery实现常用UI布局

    tab html <div class="tab"> <ul class="tab-title"> <li class=" ...

  4. 十二、Sap的压缩类型p的使用方法

    一.代码如下 二.我们查看输出结果 三.如果位数超出了会怎样呢?我们试试 四.提示如下

  5. echarts 柱状图的选中模式实现-被选中变色和再次选中为取消变色

    方法: function barCharShow(curr_dim,divId,result_data){ mutilDim(curr_dim);//维度信息 var paint = initEcha ...

  6. bool之regexp正则注入(原理详解)

    感谢原创博主的文章,在此致敬.本文转自:http://www.cnblogs.com/lcamry/articles/5717442.html 我们都已经知道,在MYSQL 5+中 informati ...

  7. 吴裕雄 Bootstrap 前端框架开发——Bootstrap 字体图标(Glyphicons):glyphicon glyphicon-italic

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...

  8. redis十-对快照模式分析

    复制自:http://www.cnblogs.com/huangxincheng/p/5010795.html 一:快照模式 或许在用Redis之初的时候,就听说过redis有两种持久化模式,第一种是 ...

  9. (二)requests模块

    一 requests模块 概念: python中原生的基于网络请求的模块,模拟浏览器进行请求发送,获取页面数据 安装: pip install requests 二 requests使用的步骤 1 指 ...

  10. 编程入门-Eclipse的断点调试

    编程入门-Eclipse的断点调试 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 1>.双击选中你要调试的代码行数 2>.允许方法透视图 3>.进行代码调试 4& ...