用Java的Process执行命令行,ffmpeg抽帧到一千多帧图片卡住,不报错。
2023-12-13 11:42:26
项目场景:
最近需要写一个抽帧、推流的工具类,抽帧写好测试的时候也没问题,等到真正用的时候就发现各种问题。
问题描述
用Java执行ffmpeg抽帧命令,测试的时候没有问题,后来发现抽帧图片多了就会卡住。
刚开始觉得可能是网速的问题,测试了一下也没问题阿,抽帧图片多了才发现不知道怎么回事不抽了,最关键的是进程都还没掉。
原因分析:
刚开始觉得可能是这个命令的问题,就直接拿命令在Linux执行发现没这个问题,在Java执行才会有这个问题,然后想着直接用shell脚本试试,也是没有卡住的情况,既然这样,就想着拿Java执行shell脚本再执行命令行,结果还是出现了一样的情况,这是最想不通的一点,这都不是一个进程了,shell脚本后台运行,按理来说就算Java调用shell脚本的进程直接杀掉也还会执行,但是还是会到了一千多张就卡住了。后来就尝试用Javacv 呗,刚开始尝试的还不如直接调用process,只能抽九百多张,这个因为没情况缓冲区,加了
grabber.setVideoOption("fflags", "nobuffer");
以后可以抽到两千多张,还是到不了想要的效果。
解决方案:
想了想会不会process也是这样的情况,当时process只清空了输入流和错误流,没有对输出流进行处理。添加如下代码
ProcessBuilder processBuilder = new ProcessBuilder("cmd",path);
processBuilder.redirectErrorStream(true);
try {
Process process = null;
process = processBuilder.start();
// 读取标准输出和错误
InputStream inputStream = process.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
log.info(line); // 处理标准输出和错误
}
} catch (Exception e) {
throw new RuntimeException(e);
}
这样才给问题解决了,如果需要给前端返回进程号,可以使用下面的代码(jdk1.8),jdk版本高的可以直process.getPid();异步执行process.waitFor(); 提前返回进程号。
pidFiled = process.getClass().getDeclaredField("pid");
pidFiled.setAccessible(true);
String pid = String.valueOf(pidFiled.getInt(process));
根据进程号结束抽帧的代码:
/**
* @param pid 进程号
* @return 0表示正常
*/
public Integer stopByPid(String pid) {
if (!StringUtils.hasText(pid)) {
throw new BadRequestException("Pid cannot be empty");
}
String command = "kill -9 " + pid;
log.info(command);
Integer exitCode = 0;
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command("bash", "-c", command);
try {
Process process = processBuilder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
log.error(line);
}
exitCode = process.waitFor();
log.info("Exited with error code : " + exitCode);
} catch (Exception e) {
e.printStackTrace();
}
return exitCode;
}
文章来源:https://blog.csdn.net/weixin_45299984/article/details/134823130
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!