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

news2024/11/27 22:30:12

项目中有个需求需要截取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 它是会自动在输出路径创建出来文件的 ,但是由于我上面这段代码创建过文件了,所以他会问我文件已存在是否覆盖 此时本来应该等待我的输入,但是我主进程也在等他结束,所以造成了死锁!

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1805032.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

程序猿大战Python——运算符

常见的运算符 目标:了解Python中常见的运算符有哪些? 运算符是用于执行程序代码的操作运算。常见的运算符有: (1)算术运算符:、-、*、/、//、% 、**; (2)赋值运算符&am…

“论边缘计算及应用”必过范文,突击2024软考高项论文

论文真题 边缘计算是在靠近物或数据源头的网络边缘侧,融合网络、计算、存储、应用核心能力的分布式开放平台(架构),就近提供边缘智能服务。边缘计算与云计算各有所长,云计算擅长全局性、非实时、长周期的大数据处理与分析,能够在…

拯救者Legion Y9000X IRX9 2024(83FD)原装出厂Windows11系统镜像下载

lenovo联想2024款拯救者Y9000X IRX9 笔记本电脑【83FD】OEM预装Win11系统安装包,恢复开箱状态,自带恢复重置还原功能 链接:https://pan.baidu.com/s/1i_sVcnXF4qgsuj02rebe-Q?pwdyefp 提取码:yefp 联想原装WIN11系统自带所有…

Leetcode 力扣 112. 路径总和 (抖音号:708231408)

给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。 叶子节点 是指没有子节点…

Git:从配置到合并冲突

目录 1.前言 2.Git的下载与初始化配置 3.Git中新建仓库 4.Git的工作区域和文件状态 5.Git中查看操作和提交记录 6.Git中添加和提交文件 7.Git中回退提交版本 8.Git中查看版本间的差异 9.Git中删除文件 10.Git中忽略指定文件 11.Git中配置SSH密钥 12.Git中关联克隆仓库 13.Git中…

参考——温湿度传感器DHT11驱动_STM32

设备:stm32f407ZGT6 环境:FreeRTOS HAL 一、简介 到网上找DHT11的驱动,但是都无法使用。原因是RTOS环境中,由于多线程,使用循环计数阻塞式的delay_us延时函数就没那么准,且不同设备中delay_us的计数…

ChatGPT Prompt技术全攻略-精通篇:Prompt工程技术的高级应用

系列篇章💥 No.文章1ChatGPT Prompt技术全攻略-入门篇:AI提示工程基础2ChatGPT Prompt技术全攻略-进阶篇:深入Prompt工程技术3ChatGPT Prompt技术全攻略-高级篇:掌握高级Prompt工程技术4ChatGPT Prompt技术全攻略-应用篇&#xf…

USB (2)

USB transaction 以2.0的枚举过程为例。 首先是TOKEN TRANSACTION,其次是DATA TRANSACTION,再次是Handshake Transaction。 上面的SETUP TRANSACTION是TOKEN TRANSACTION的一种。另外三种是OUT, IN, SOF。 在每个TRANSACTION中又包含了3个STAGE&#x…

层次聚类分析星

clc,clear a [73,40,7;60,15,5;61,19,2;34,18,6;67,126,10;91,40,4;101,40,13;81,40,6;88,40,8;122,40,17;102,50,17;87,50,12;110,50,14;164,50,17;40,30,1;76,40,17;118,50,9;160,50,15];[m,n] size(a);d zeros(m); d mandist(a); % mandist 求矩阵列向量组之间的两两…

pxe批量部署linux介绍

1、PXE批量部署的作用及必要性: 1)智能实现操作系统的批量安装(无人值守安装)2)减少管理员工作,提高工作效率3)可以定制操作系统的安装流程a.标准流程定制(ks.cfg)b.自定义流程定制(ks.cfg(%pos…

linux系统——telnet,ssh命令

telent命令用于登录远程主机,监测远程主机端口是否打开,明文传输,安全性较低,后被弃用,改为ssh

『大模型笔记』Transformer的几种高效自注意力(降低计算复杂度的方法)!

Transformer的几种高效自注意力(降低计算复杂度的方法)! 文章目录 一. 快速回顾一下注意力机制二. 有哪些技术可以用来提高注意力的效率1. Sparse attention(1) 算法原理:Strided Attention & Fixed Attention(2) 复杂度分析: O ( N N p ) \mathscr{O}(N\sqrt[p]{N}) O(…

[学习笔记] VFX Silhouette

Part 1 : The interface of Silhouettte (Silhouette的界面介绍) Part 2: The shape divisions and manual roto(形状分区和手动roto工作): roto过程一般使用 b 曲线roto工作需要逐帧工作按Alt可以修改锚点(拖动)和改变锚点平滑…

基于Gabor小波特征提取和PSO-SVM的胃溃疡分类(MATLAB R2018a)

Gabor滤波器是在测不准原则下能够在时域和频域中唯一能取得最佳的联合分辨率函数(测不准原则:是指在时域与频域中都要获得任何的测量精度那是不可能同时实现的,要使时域分辨率有所提高,必须牺牲频域的分辨率,反之亦然&…

Hugging Face系列2:详细剖析Hugging Face网站资源——实战六类开源库

Hugging Face系列2:详细剖析Hugging Face网站资源——实战六类开源库 前言本篇摘要2. Hugging Face开源库2.1 transformers2.1.1 简介2.1.2 实战1. 文本分类2. 图像识别3. 在Pytorch和TensorFlow中使用pipeline 2.2 diffusers2.2.1 简介2.2.2 实战1. 管线2. 模型和调…

【AI大模型】Prompt Engineering

目录 什么是提示工程(Prompt Engineering) Prompt 调优 Prompt 的典型构成 「定义角色」为什么有效? 防止 Prompt 攻击 攻击方式 1:著名的「奶奶漏洞」 攻击方式 2:Prompt 注入 防范措施 1:Prompt 注…

如何从清空的回收站恢复照片

担心如何从清空的回收站中恢复已删除的照片?您删除的文件和文件夹暂时存储在 Windows 回收站中。它使 Windows 用户能够快速恢复意外或故意丢失的项目。但是,为了释放计算机驱动器上的某些空间,有时可能需要清理回收站。 然而,有…

车用柴油氧化安定性检测 GB 19147-2009全项检测

柴油分为轻柴油(沸点范围约180-370℃)和重柴油(沸点范围约350-410℃)两大类。柴油使用性能中最重要的是着火性和流动性,其技术指标分别为十六烷值和凝点,我国柴油现行规格中要求含硫量控制在0.5%-1.5%。 检…

增值税发票OCR识别功能介绍

OCR增值税发票识别功能介绍如下: 一、技术原理 OCR增值税发票识别系统基于光学字符识别(OCR)技术和人工智能的支持,将传统纸质发票的信息自动转换为计算机可以读取的数字信息。具体技术流程包括: 图像预处理&#x…

SAP ABAP 往数据库表里加数据

目录 方法一:SE16N SE11 方法二:创建维护VIEW:SE11 SM30 Error补充说明: 方法一:SE16N SE11 首先SE16N 进来。 进来之后在テーブル的位置输入表名,然后点击执行(F8) 如果第一次…