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

FastAPI中asyncio后台任务阻塞WebSocket连接问题求助

问题原因

你的editing函数里调用了同步的subprocess.run(),这会阻塞整个asyncio事件循环。虽然你用asyncio.create_task()把它包装成了后台任务,但同步操作不会让出CPU,导致所有其他协程(包括WebSocket连接、其他路由请求)都必须等这个耗时的ffmpeg命令完成才能执行。

解决方案

把同步的subprocess.run()替换为asyncio的异步子进程API,让ffmpeg命令在后台执行的同时让出事件循环给其他任务:

修改editing函数:

async def editing(videoId, values, videoWidth, videoHeight, fps, userData):
    recordingFile = os.path.join(temp_dir, f"recording_{videoId}.mp4")
    webFile = os.path.join(temp_dir, f"final_edited_{videoId}.mp4")
    ffmpeg_change_bitrate = ['ffmpeg', '-i', recordingFile, '-b:v', '5M', webFile]

    # 使用异步子进程API替代同步的subprocess.run
    process = await asyncio.create_subprocess_exec(
        *ffmpeg_change_bitrate,
        stdout=asyncio.subprocess.PIPE,
        stderr=asyncio.subprocess.PIPE
    )
    
    # 异步等待子进程完成,不会阻塞事件循环
    stdout, stderr = await process.communicate()
    
    # 按需处理输出或错误
    if process.returncode != 0:
        print(f"FFmpeg执行出错: {stderr.decode()}")
    else:
        print('Completed Editing, it took 4 minutes')
额外说明
  • asyncio.create_subprocess_exec创建异步子进程,await process.communicate()会异步等待进程结束,期间事件循环可以正常处理WebSocket连接、新API请求等其他任务。
  • 如果需要通过WebSocket实时推送ffmpeg的处理进度,可以循环读取stdout/stderr的输出内容,而非一次性调用communicate()。

内容的提问来源于stack exchange,提问作者Zaid

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 12:08:15