JAVA调用FFMpeg进行转码等操作
直接上代码:
- public abstract class FFmpegUtils {
- FFmpegUtils ffmpegUtils;
- int timeLengthSec = ;
- String timeLength = "";
- Pattern pattern = Pattern.compile("Duration: (.*?), start: (.*?), bitrate: (\\d*) kb\\/s");
- String frameRegexDuration = "size=([\\s\\S]*) time=(.*?) bitrate=([\\s\\S]*) speed=(.*?)x";
- String videoframeRegexDuration = "frame=([\\s,\\d]*) fps=(.*?) q=(.*?) size=([\\s\\S]*) time=(.*?) bitrate=([\\s\\S]*) speed=(.*?)x";
- Pattern framePattern = Pattern.compile(frameRegexDuration);
- public static void main(String[] args){
- String target = "";
- /* try {
- target = extractAsyn("D:\\ffmpeg4.2\\bin\\ffmpeg.exe",
- "-y -f image2 -ss 1 -t 0.001 -s 640x480",
- "E:\\迅雷下载\\电影\\test.avi",
- "E:\\迅雷下载\\电影\\test.avi.jpg");
- System.out.println(target);
- } catch (Throwable e) {
- System.err.println(e.getMessage());
- }
- */
- try {
- new FFmpegUtils() {
- @Override
- public void dealLine(String line) {
- System.out.println(line);
- if(timeLength == null || timeLength.equals("")) {
- Matcher m = pattern.matcher(line.trim());
- if (m.find()) {
- timeLength = m.group();
- if(timeLength!=null){
- timeLengthSec = FFVideoUtil.getTimelen(timeLength);
- }
- System.out.println(timeLength+"||"+timeLengthSec);
- }
- }
- //获取视频信息
- Matcher matcher = framePattern.matcher(line);
- if(matcher.find()){
- try {
- String execTimeStr = matcher.group();
- int execTimeInt = FFVideoUtil.getTimelen(execTimeStr);
- double devnum = FFBigDecimalUtil.div(execTimeInt,timeLengthSec,);
- double progressDouble = FFBigDecimalUtil.mul(devnum,);
- System.out.println("execTimeInt:"+execTimeInt+"&,devnum:"+devnum+"&,progressDouble:"+progressDouble);
- } catch (IllegalAccessException e) {
- System.err.println("获取输出流异常:"+e.getMessage());
- }
- }
- }
- @Override
- public void dealStream(Process process) {
- if (process == null) {
- return;
- }
- // 处理InputStream的线程
- new Thread() {
- @Override
- public void run() {
- BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
- String line = null;
- try {
- while ((line = in.readLine()) != null) {
- //logger.info("output: " + line);
- dealLine(line);
- }
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- try {
- in.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }.start();
- // 处理ErrorStream的线程
- new Thread() {
- @Override
- public void run() {
- BufferedReader err = new BufferedReader(new InputStreamReader(process.getErrorStream()));
- String line = null;
- try {
- while ((line = err.readLine()) != null) {
- dealLine(line);
- }
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- try {
- err.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }.start();
- }
- }.processVideoSync("D:\\ffmpeg4.2\\bin\\ffmpeg.exe",
- " -f|mp3",
- "E:\\迅雷下载\\电影\\test.avi",
- "E:\\迅雷下载\\电影\\test.avi.mp3");
- System.out.println(target);
- } catch (Throwable e) {
- System.err.println(e.getMessage());
- }
- }
- //异步 适合抽帧等快速的操作
- public static String extractAsyn(
- String ffmpegPath,String cmdParam,
- String sourceFile,String targetFile)
- throws Throwable {
- Runtime runtime = Runtime.getRuntime();
- Process proce = null;
- // 视频截图命令,封面图。 8是代表第8秒的时候截图
- String cmd = "";
- String cut = ffmpegPath +" -i "+ sourceFile +" "+ cmdParam +" "+ targetFile;
- String cutCmd = cmd + cut;
- proce = runtime.exec(cutCmd);
- proce.getOutputStream();
- System.out.println("抽帧命令是:"+cut);
- return targetFile;
- }
- public static boolean checkfile(String path) {
- File file = new File(path);
- if (!file.isFile()) {
- return false;
- }
- return true;
- }
- //异步处理
- public boolean processVideoSync(String ffmpegPath,String cmdParam,
- String sourceFile,String targetFile) {
- // 文件命名
- List<String> commond = new ArrayList<String>();
- commond.add(ffmpegPath);
- commond.add("-i");
- commond.add(sourceFile);
- commond.addAll(Arrays.asList(cmdParam.trim().split("\\|")));
- commond.add(targetFile);
- if(new File(targetFile).exists()) {
- new File(targetFile).delete();
- }
- String cmds = "";
- for (String cmd : commond) {
- cmds = cmds + " " + cmd;
- }
- System.out.println("执行命令参数为:" + cmds);
- try {
- // 调用线程命令进行转码
- Process videoProcess = new ProcessBuilder(commond).redirectErrorStream(true).start();
- //new PrintStream(videoProcess.getInputStream()).start();
- //videoProcess.waitFor();
- /*new InputStreamReader(videoProcess.getErrorStream());
- BufferedReader stdout = new BufferedReader(new InputStreamReader(videoProcess.getInputStream()));
- String line;
- while ((line = stdout.readLine()) != null) {
- dealLine(line);
- }*/
- dealStream(videoProcess);
- videoProcess.waitFor();
- return true;
- } catch (Exception e) {
- e.printStackTrace();
- return false;
- }
- }
- //处理输出流
- public abstract void dealLine(String line);
- public abstract void dealStream(Process process );
- }
FFmpegUtils.java
- @Component
- public class ProgressService extends FFmpegUtils{
- public static Logger logger = LoggerFactory.getLogger(ProgressService.class);
- /**
- * 进度正则查询
- */
- private String frameRegexDuration = "frame=([\\s,\\d]*) fps=(.*?) q=(.*?) size=([\\s\\S]*) time=(.*?) bitrate=([\\s\\S]*) speed=(.*?)x";
- /**
- * 正则模式
- */
- private Pattern framePattern = Pattern.compile(frameRegexDuration);
- /**
- * 秒数
- */
- private Integer timeLengthSec;
- /**
- * 时长
- */
- private String timeLength;
- /**
- * 开始时间
- */
- private String startTime;
- /**
- * 比特率
- */
- private String bitrate;
- /**
- * 时长 正则
- */
- private String regexDuration = "Duration: (.*?), start: (.*?), bitrate: (\\d*) kb\\/s";
- /**
- * 正则模式
- */
- private Pattern pattern = Pattern.compile(regexDuration);
- public String getStartTime() {
- return startTime;
- }
- public void setStartTime(String startTime) {
- this.startTime = startTime;
- }
- public String getBitrate() {
- return bitrate;
- }
- public void setBitrate(String bitrate) {
- this.bitrate = bitrate;
- }
- private TranscodeTask task;
- public TranscodeTask getTask() {
- return task;
- }
- public void setTask(TranscodeTask task) {
- this.task = task;
- }
- @Autowired
- private TaskReposity _taskRep;
- @Override
- public void dealLine(String line) {
- logger.debug("{}输出信息:{}",task.getName(),line);
- //获取视频长度信息
- if(timeLength == null || "".equals(timeLength)) {
- Matcher m = pattern.matcher(line.trim());
- if (m.find()) {
- timeLength = m.group();
- if(timeLength!=null){
- timeLengthSec = FFVideoUtil.getTimelen(timeLength);
- }
- startTime = m.group();
- bitrate = m.group();
- logger.debug("timeLength:{}, startTime:{},bitrate:{}",timeLength,startTime,bitrate);
- }
- }
- //获取视频信息
- Matcher matcher = framePattern.matcher(line);
- if(matcher.find()){
- try {
- String execTimeStr = matcher.group();
- int execTimeInt = FFVideoUtil.getTimelen(execTimeStr);
- double devnum = FFBigDecimalUtil.div(execTimeInt,timeLengthSec,);
- double progressDouble = FFBigDecimalUtil.mul(devnum,);
- logger.debug("execTimeInt:{},devnum:{},progressDouble:{}",execTimeInt,devnum,progressDouble);
- task.setProgress((float)progressDouble);
- _taskRep.saveAndFlush(this.task);
- } catch (IllegalAccessException e) {
- logger.error("获取输出流异常:{}",e.getMessage());
- }
- }
- }
- /**
- * 处理process输出流和错误流,防止进程阻塞
- * 在process.waitFor();前调用
- * @param process
- */
- @Override
- public void dealStream(Process process) {
- if (process == null) {
- return;
- }
- // 处理InputStream的线程
- new Thread() {
- @Override
- public void run() {
- BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
- String line = null;
- try {
- while ((line = in.readLine()) != null) {
- //logger.info("output: " + line);
- dealLine(line);
- }
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- try {
- in.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }.start();
- // 处理ErrorStream的线程
- new Thread() {
- @Override
- public void run() {
- BufferedReader err = new BufferedReader(new InputStreamReader(process.getErrorStream()));
- String line = null;
- try {
- while ((line = err.readLine()) != null) {
- logger.info("err: " + line);
- }
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- try {
- err.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }.start();
- }
- }
- @Component
- public class FileService {
- public static Logger logger = LoggerFactory.getLogger(FileService.class);
- // 下载小文件
- public File downloadFile(String formUrl, String fileName) throws Throwable {
- File desc = null;
- CloseableHttpClient httpclient = HttpClients.createDefault();
- HttpGet httpget = new HttpGet(formUrl);
- httpget.setConfig(RequestConfig.custom() //
- .setConnectionRequestTimeout() //
- .setConnectTimeout() //
- .setSocketTimeout() //
- .build());
- logger.debug("正在从{}下载文件到{}",formUrl,fileName);
- try (CloseableHttpResponse response = httpclient.execute(httpget)) {
- org.apache.http.HttpEntity entity = response.getEntity();
- desc = new File(fileName);
- try (InputStream is = entity.getContent(); //
- OutputStream os = new FileOutputStream(desc)) {
- StreamUtils.copy(is, os);
- logger.debug("成功从{}下载文件到{}",formUrl,fileName);
- }
- }
- return desc;
- }
- public void downloadLittleFileToPath(String url, String target) {
- Instant now = Instant.now();
- RestTemplate template = new RestTemplate();
- ClientHttpRequestFactory clientFactory = new HttpComponentsClientHttpRequestFactory();
- template.setRequestFactory(clientFactory);
- HttpHeaders header = new HttpHeaders();
- List<MediaType> list = new ArrayList<MediaType>();
- // 指定下载文件类型
- list.add(MediaType.APPLICATION_OCTET_STREAM);
- header.setAccept(list);
- HttpEntity<byte[]> request = new HttpEntity<byte[]>(header);
- ResponseEntity<byte[]> rsp = template.exchange(url, HttpMethod.GET, request, byte[].class);
- logger.info("[下载文件] [状态码] code:{}", rsp.getStatusCode());
- try {
- if(Paths.get(target).toFile().exists()) {
- Paths.get(target).toFile().delete();
- }
- Files.write(Paths.get(target), Objects.requireNonNull(rsp.getBody(), "未获取到下载文件"));
- } catch (IOException e) {
- logger.error("[下载文件] 写入失败:", e);
- }
- logger.info("[下载文件] 完成,耗时:{}", ChronoUnit.MILLIS.between(now, Instant.now()));
- }
- public void downloadBigFileToPath(String url, String target) {
- Instant now = Instant.now();
- try {
- RestTemplate template = new RestTemplate();
- ClientHttpRequestFactory clientFactory = new HttpComponentsClientHttpRequestFactory();
- template.setRequestFactory(clientFactory);
- //定义请求头的接收类型
- RequestCallback requestCallback = request -> request.getHeaders()
- .setAccept(Arrays.asList(MediaType.APPLICATION_OCTET_STREAM, MediaType.ALL));
- // getForObject会将所有返回直接放到内存中,使用流来替代这个操作
- ResponseExtractor<Void> responseExtractor = response -> {
- // Here I write the response to a file but do what you like
- if(Files.exists(Paths.get(target), LinkOption.NOFOLLOW_LINKS)) {
- Files.delete(Paths.get(target));
- }
- Files.copy(response.getBody(), Paths.get(target));
- return null;
- };
- template.execute(url, HttpMethod.GET, requestCallback, responseExtractor);
- } catch (Throwable e) {
- logger.error("[下载文件] 写入失败:", e);
- }
- logger.info("[下载文件] 完成,耗时:{}", ChronoUnit.MILLIS.between(now, Instant.now()));
- }
- }
FileService
有个问题需要注意:
转码目标文件必须不存在才行,如果存在 先删除,不然就卡死。
JAVA调用FFMpeg进行转码等操作的更多相关文章
- Java调用FFmpeg进行视频处理及Builder设计模式的应用
1.FFmpeg是什么 FFmpeg(https://www.ffmpeg.org)是一套可以用来记录.转换数字音频.视频,并能将其转化为流的开源计算机程序.它用来干吗呢?视频采集.视频格式转化.视频 ...
- java调用ffmpeg命令行推流遇到的问题
1.Java调用命令行,如果没有额外环境变量,不指定工作路径,Runtime有两个方法 public Process exec(String command) public Process exec( ...
- java调用FFmpeg及mencoder转换视频为FLV并截图
Conver.java package com.ll19.flv; public class Conver { public void run() { try { // 转换并截图 String fi ...
- java运用FFMPEG视频转码技术
基于windows系统安装FFMPEG转码技术 http://wenku.baidu.com/link?url=z4Tv3CUXxxzLpa5QPI-FmfFtrIQeiCYNq6Uhe6QCHkU- ...
- java调用ffmpeg获取视频文件信息的一些参数
一.下载ffmpeg http://www.ffmpeg.org/download.html 主要需要bin目录下的ffmpeg可执行文件 二.java代码实现 package com.aw.util ...
- Java使用FFmpeg处理视频文件指南
Java使用FFmpeg处理视频文件指南 本文主要讲述如何使用Java + FFmpeg实现对视频文件的信息提取.码率压缩.分辨率转换等功能: 之前在网上浏览了一大圈Java使用FFmpeg处理音视频 ...
- Java使用FFmpeg处理视频文件的方法教程
这篇文章主要给大家介绍了关于Java使用FFmpeg处理视频文件的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧 前言 本文主要 ...
- Java调用ffmepg+mencoder视频格式转换(*)
PS: 建议大家在官网下载最新的资源 其他格式转FLV格式,可以用Java调用ffmpeg和memcoder实现 ffmepg: D:\ffmpeg\bin\ffmpeg.exe -i E:\1.mp ...
- java调用c++ dll出现中文乱码
近期的开发用到了使用java调用本机动态连接库的功能,将文件路径通过java调用C++代码对文件进行操作. 在调用中假设路径中包括有中文字符就会出现故障.程序执行就会中止. 以下用一个小样例,来说明记 ...
随机推荐
- bzoj 3696: 化合物
哦,这个困惑了我好久的东西——生成函数(母函数),(然而拿这个东西去向学文化课的同学装逼并不成功...) 生成函数,就是把原来的加法组合变成乘法的指数加法,那么我们要求的值就是相应的指数的系数的值啦, ...
- [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 ...
- jquery实现常用UI布局
tab html <div class="tab"> <ul class="tab-title"> <li class=" ...
- 十二、Sap的压缩类型p的使用方法
一.代码如下 二.我们查看输出结果 三.如果位数超出了会怎样呢?我们试试 四.提示如下
- echarts 柱状图的选中模式实现-被选中变色和再次选中为取消变色
方法: function barCharShow(curr_dim,divId,result_data){ mutilDim(curr_dim);//维度信息 var paint = initEcha ...
- bool之regexp正则注入(原理详解)
感谢原创博主的文章,在此致敬.本文转自:http://www.cnblogs.com/lcamry/articles/5717442.html 我们都已经知道,在MYSQL 5+中 informati ...
- 吴裕雄 Bootstrap 前端框架开发——Bootstrap 字体图标(Glyphicons):glyphicon glyphicon-italic
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...
- redis十-对快照模式分析
复制自:http://www.cnblogs.com/huangxincheng/p/5010795.html 一:快照模式 或许在用Redis之初的时候,就听说过redis有两种持久化模式,第一种是 ...
- (二)requests模块
一 requests模块 概念: python中原生的基于网络请求的模块,模拟浏览器进行请求发送,获取页面数据 安装: pip install requests 二 requests使用的步骤 1 指 ...
- 编程入门-Eclipse的断点调试
编程入门-Eclipse的断点调试 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 1>.双击选中你要调试的代码行数 2>.允许方法透视图 3>.进行代码调试 4& ...