记一次极其坑爹的 process.waitFor() 卡死问题

项目中有个需求需要截取wav的音频文件 ,网上找了找方法 用java调用ffmpeg 来截取

public static InputStream trimAudio(MultipartFile inputFile,  Double startTime, Double endTime,Double volume) throws IOException {
        File file = new File(FileUtil.getTmpDirPath() + File.separator + System.currentTimeMillis() + ".wav");
        inputFile.transferTo(file);
        String outputFilePath =FileUtil.getTmpDirPath() + File.separator + System.currentTimeMillis() + 1 + ".wav";
        if(!FileUtil.exist(outputFilePath)) {
            new File(outputFilePath).createNewFile();
        }
        // 确保ffmpeg.exe在系统的PATH变量中或者提供完整路径
        String ffmpeg = "ffmpeg";

        // 构建FFmpeg命令
        String command = String.format("%s -i %s -ss %s -t %s -af volume=%s %s",
                ffmpeg, file.getAbsolutePath(),startTime, endTime - startTime, volume, outputFilePath);

        // 执行FFmpeg命令
        try {

            log.info("执行的cmd命令:{}", command);
            Process process = Runtime.getRuntime().exec(command);
            process.waitFor();
            return FileUtil.getInputStream(outputFilePath);
        } catch ( Exception e) {
            e.printStackTrace();
        } finally {
            FileUtil.del(file);
            FileUtil.del(outputFilePath);
        }
        return inputFile.getInputStream();
    }

代码比较简单 就是生成俩文件  使用ffmpeg对第一个文件进行截取处理 ,但是问题来了

每次执行到process.waitFor()就会卡死 

在网上搜答案都说是要处理子线程的输出 

那好 加上试试呗

ThreadUtil.execute(()->{
            log.info("处理FFMPEG音频截取进程错误信息");
            //防止ffmpeg进程塞满缓存造成死锁
            InputStream error = exec.getErrorStream();
            StringBuffer result = new StringBuffer();
            String line = null;
            try {
                BufferedReader br = new BufferedReader(new InputStreamReader(error,"GBK"));

                while((line = br.readLine()) != null){
                    result.append(line+"\n");
                }
                log.info("FFMPEG音频截取进程错误信息:"+result.toString());

            }catch (IOException e2){
                e2.printStackTrace();
            }finally {
                try {
                    error.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        });

        ThreadUtil.execute(()->{
            log.info("处理FFMPEG音频截取进程输出信息");
            InputStream is = exec.getInputStream();

            StringBuffer result = new StringBuffer();
            String line = null;
            try {
                BufferedReader br2 = new BufferedReader(new InputStreamReader(is,"GBK"));

                while((line = br2.readLine()) != null){
                    result.append(line+"\n");
                }
                log.info("FFMPEG音频截取进程输出内容为:"+result.toString());
            }catch (IOException e2){
                e2.printStackTrace();
            }finally {
                try {
                    is.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        });

但是问题依然没有得到解决 断点跟进 发现每次一读取InputStream就卡住了 日志也就到这里

在网上搜了大半天 基本全是这样处理的  

cmd命令拷贝出来 也没问题啊

然后就陷入了循环,网上搜-> 试试 -> 不行 -> 网上搜

最后折腾了一整天 ,偶然间一次重启程序,发现程序一关闭的时候打印了点日志 但是立马重启了没看清,然后我等他卡住的时候关闭程序 发现报错信息上面有这样一条日志

我简直要吐血了

因为刚开始的时候 调试程序 一直提示我文件找不到 我就加了这样的代码 如果文件没有就创建(上面第一段代码的4 - 7行)

String outputFilePath =FileUtil.getTmpDirPath() + File.separator + System.currentTimeMillis() + 1 + ".wav";
        if(!FileUtil.exist(outputFilePath)) {
            new File(outputFilePath).createNewFile();
        }

本来调用ffmpeg 它是会自动在输出路径创建出来文件的 ,但是由于我上面这段代码创建过文件了,所以他会问我文件已存在是否覆盖 此时本来应该等待我的输入,但是我主进程也在等他结束,所以造成了死锁!

真是太坑了 其实终极原因还是怪自己不够仔细,竟然犯了这样的低级错误

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值