修改版Jibri执行kill命令触发Java IO异常,录制视频无法播放
问题排查与解决方案
核心问题定位
报错java.io.IOException: Cannot run program "kill -9 821": error=2, No such file or directory的根本原因是Java/Kotlin的Runtime.exec参数传递错误:你把整个kill -s SIGINT ${pid}命令作为单个字符串放入数组,exec会将这个完整字符串当作可执行文件的路径,而非解析成"命令+参数"的组合,系统自然找不到名为kill -s SIGINT xxx的程序。
直接修复方案
将命令和参数拆分为数组的独立元素,让exec正确识别可执行程序和参数:
val cmdArr = arrayOf("kill", "-s", "SIGINT", process.pidValue.toString()) runtime.exec(cmdArr, null)
- 第一个元素
kill是可执行程序名,后续元素依次是命令的参数-s、SIGINT、进程PID。 - 这样
exec会正确调用系统的kill命令,并传递指定参数,成功给ffmpeg发送SIGINT信号,让ffmpeg正常收尾写入完整视频文件,解决EOF导致的无法播放问题。
额外优化建议
- 优先使用ProcessBuilder:相比
Runtime.exec,ProcessBuilder的API更直观,也更便于处理进程的输入输出流,代码示例:val pb = ProcessBuilder("kill", "-s", "SIGINT", process.pidValue.toString()) pb.start() - 增加异常捕获与日志:在执行命令时捕获异常,记录更详细的调试信息,方便后续排查:
try { val cmdArr = arrayOf("kill", "-s", "SIGINT", process.pidValue.toString()) runtime.exec(cmdArr, null) } catch (e: IOException) { // 替换为你的日志工具 println("Failed to send SIGINT to ffmpeg process ${process.pidValue}: ${e.message}") e.printStackTrace() } - 验证信号有效性:再次在Docker容器内手动执行
kill -s SIGINT <ffmpeg-pid>,确认ffmpeg收到信号后会正常退出,生成的视频文件可正常播放,排除ffmpeg本身的信号处理问题。
内容的提问来源于stack exchange,提问作者Fawaz Sullia
相关产品推荐
相关产品推荐

