You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用bramp/ffmpeg-cli-wrapper,如何终止线程中的FFmpeg执行任务?

解决FFmpeg推流任务无法终止的问题

你的问题核心是线程中断无法终止外部FFmpeg进程:Thread.interrupt()仅设置线程的中断状态,但executor.createJob(builder).run()是阻塞执行FFmpeg子进程,线程中断不会传递给子进程,导致任务无法停止。

解决方案:直接管理FFmpeg任务实例,而非线程

改用存储FFmpegJob实例,通过其内置方法终止FFmpeg进程:

  1. 修改任务存储结构
    将原来存储线程的ConcurrentHashMap改为存储FFmpegJob:
private final Map<Integer, FFmpegJob> taskJobs = new ConcurrentHashMap<>();
  1. 重构启动任务逻辑
    异步执行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);
}
  1. 修改停止任务逻辑
    调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 23:43:18