Flask后端如何接收前端传来的KeyboardInterrupt信号终止录音
结论
不能直接从前端传递KeyboardInterrupt信号到正在运行的录音进程,但是可以通过子进程管理的方式实现前端控制停止录音的需求,你的现有代码还有几处明显问题需要同步修改。
现有代码问题说明
- 路由请求方法不匹配:你给
/record/路由限定了仅接受POST请求,但前端a标签触发的是GET请求,当前点击按钮根本无法触发录音逻辑。 - 脚本调用方式错误:通过
import执行脚本的逻辑仅会在首次导入时运行一次,后续再次触发路由不会重新执行录音逻辑,且导入操作会阻塞当前请求,导致前端长时间收不到响应。 - 没有独立的进程管理:录音逻辑和Flask请求处理逻辑在同一个进程内运行,请求会被一直阻塞,也无法从其他请求控制录音停止。
具体实现方案
后端Flask代码修改
from flask import Flask import multiprocessing import signal import subprocess import os app = Flask(__name__) # 全局变量存储录音子进程对象 rec_process = None # 启动录音路由,调整为支持GET请求匹配前端a标签,也可改为POST配合前端Ajax调用 @app.route('/start_record/', methods=['GET']) def start_record(): global rec_process # 避免重复启动录音 if rec_process is not None and rec_process.is_alive(): return "已有正在运行的录音任务" # 启动独立子进程运行录音脚本 rec_process = multiprocessing.Process( target=subprocess.run, args=(["python", "Voice_Recorder.py"],) ) rec_process.start() return "录音已启动" # 停止录音路由 @app.route('/stop_record/', methods=['GET']) def stop_record(): global rec_process if rec_process is None or not rec_process.is_alive(): return "没有正在运行的录音任务" # 给子进程发送SIGINT信号,等效于触发KeyboardInterrupt os.kill(rec_process.pid, signal.SIGINT) # 等待子进程退出回收资源 rec_process.join() rec_process = None return "录音已停止,文件已保存" if __name__ == '__main__': app.run(debug=True)
前端HTML代码修改
新增停止录音按钮,调整启动按钮的路由地址:
<center> <button><a href="/start_record/">开始录音</a></button> <button><a href="/stop_record/">停止录音</a></button> </center>
注意事项
- 跨平台兼容性:Windows系统下调用
os.kill发送SIGINT信号可能存在异常,可替换为rec_process.terminate(),同时在Voice_Recorder.py中新增对SIGTERM信号的捕获逻辑,和原有KeyboardInterrupt的保存逻辑保持一致即可。 - 生产环境适配:如果后续部署使用多worker的WSGI服务器(如Gunicorn、uWSGI),全局变量无法在多个worker之间共享,建议使用Redis、SQLite或者本地临时文件存储正在运行的录音进程PID。
- 脚本路径问题:运行时请确保
Voice_Recorder.py和Flask启动文件在同一个目录下,否则需要填写脚本的绝对路径。
内容的提问来源于stack exchange,提问作者Don Udawattage
相关产品推荐
相关产品推荐

