直接上代码:

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进行转码等操作的更多相关文章

  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. POJ 3250:Bad Hair Day 好玩的单调栈

    Bad Hair Day Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 15699   Accepted: 5255 Des ...

  2. HTML的文档结构与语法(一)

    一.走进Web开发 Web运行的原理: 二.HTML 1.1什么是html HTML是用来描述网页的一种语言 HTML指的是超文本标记语言(Hyper Text Markup Language) 超文 ...

  3. P-数学程序猿今天开始写博客了

    ∧          /| /\7          ≤_/      ∧. |      |         /   /      /        〉 |     Z_,<   /      ...

  4. 一、JavaScript之第一个实例,点击按钮修改文本内容

    一.代码如下: 二.运行后效果如下 三.点击按钮,"曾经沧海难为水"变成了日期事件了 <!DOCTYPE html> <html> <meta htt ...

  5. sprngmvc+restFul 请求报错:404

    服务端代码 control类 @RequestMapping(value="getUser",method = RequestMethod.POST) @ResponseBody ...

  6. HTTP TCP UDP ICMP IP ARP 协议详解(10.15 第二十一天)

    ARP协议 ARP(Address Resolution Protocol)协议 地址解析协议 把网络层的IP地址翻译成在数据链路层寻址的48位硬件地址(MAC地址) 在OSI模型中ARP协议属于链路 ...

  7. Android 为控件添加点击涟漪效果

    Android在5.0版为Button默认添加了点击时的涟漪效果,而且在其他的控件上也可以轻松的实现这种炫酷的效果.涟漪效果可以分为两种,一种时有边界的涟漪,另一种时无边界的涟漪.所谓的有边界,即涟漪 ...

  8. 51nod 1435:位数阶乘

    1435 位数阶乘 题目来源: CodeForces 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题  收藏  关注 X是一个n位数的正整数 (x=a0a1...a ...

  9. (2) JVM内存管理:垃圾回收

    回顾上期 1)JVM中引用存在哪里? 答:虚拟机栈,该内存空间线程独有 2)该引用的对象存在哪里? 答:堆,所有通过new方法分配的对象都存在堆中 3)String s1="abc" ...

  10. 201803-2 碰撞的小球 Java

    思路: 直接按照题意模拟,感觉没什么太好的办法.另外注意:int这种基础数据类型不能用equals这个方法 ,必须是Integer类型 import java.util.Scanner; public ...