使用bramp/ffmpeg-cli-wrapper,如何终止线程中的FFmpeg执行任务?
解决FFmpeg推流任务无法终止的问题
你的问题核心是线程中断无法终止外部FFmpeg进程:Thread.interrupt()仅设置线程的中断状态,但executor.createJob(builder).run()是阻塞执行FFmpeg子进程,线程中断不会传递给子进程,导致任务无法停止。
解决方案:直接管理FFmpeg任务实例,而非线程
改用存储FFmpegJob实例,通过其内置方法终止FFmpeg进程:
- 修改任务存储结构
将原来存储线程的ConcurrentHashMap改为存储FFmpegJob:
private final Map<Integer, FFmpegJob> taskJobs = new ConcurrentHashMap<>();
- 重构启动任务逻辑
异步执行FFmpeg任务,并保存FFmpegJob实例:
private void startTask(Device task) { FFmpegBuilder builder = new FFmpegBuilder() .setInput(source) .overrideOutputFiles(true) .addOutput(destination) .setFormat("flv") .addExtraArgs("-c", "copy") .done(); FFmpegExecutor executor = new FFmpegExecutor(ffmpeg, ffprobe); FFmpegJob job = executor.createJob(builder); // 异步启动任务,避免阻塞主线程 new Thread(() -> { job.run(); // 任务自然结束后自动清理 taskJobs.remove(task.getId()); }).start(); taskJobs.put(task.getId(), job); }
- 修改停止任务逻辑
调用FFmpegJob的stop()方法直接终止FFmpeg进程:
public void stopTask(Integer taskId) { FFmpegJob job = taskJobs.get(taskId); if (job != null) { // 发送终止信号给FFmpeg进程 job.stop(); taskJobs.remove(taskId); DeviceDto task = deviceService.findById(taskId); if (task != null) { task.setIsOnline(0); Device device = new Device(); BeanUtils.copyProperties(task, device); deviceService.update(device); } } }
原理说明
FFmpegJob.stop()方法会直接向FFmpeg子进程发送终止信号(比如SIGTERM),能真正终止推流任务;而原方案的线程中断只是标记线程状态,无法影响外部运行的FFmpeg进程。
内容的提问来源于stack exchange,提问作者Hao Tan
相关产品推荐
相关产品推荐

