项目中有个需求需要截取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 它是会自动在输出路径创建出来文件的 ,但是由于我上面这段代码创建过文件了,所以他会问我文件已存在是否覆盖 此时本来应该等待我的输入,但是我主进程也在等他结束,所以造成了死锁!
真是太坑了 其实终极原因还是怪自己不够仔细,竟然犯了这样的低级错误












![[学习笔记] VFX Silhouette](https://img-blog.csdnimg.cn/direct/548fd39447cd41ec98b5e4bdc53e2455.png)






