如何在Flask中调用sounddv.py并将运行结果展示在HTML页面中
解决方案
现有代码问题梳理
- 导入语法错误:app.py中导入
print_sound时不应该加.py后缀 - 提示文本无法传递:sounddv.py中触发条件生成的提示文本是函数内局部变量,没有对外暴露的存储位置
- 路由阻塞问题:
/audio路由中sleep(20000)会导致请求挂起20秒才返回页面,无法实现实时提示推送 - 多进程变量冲突:Flask debug模式默认启动双进程,全局计数变量会出现重复计算、不同步问题
- 前端静态无逻辑:popup.html没有数据获取和渲染逻辑,无法展示提示内容
修正后的完整代码
1. sounddv.py 修改
import sounddevice as sd import numpy as np # 全局变量存储计数和最新提示 cnt = 0 check_cnt = 0 latest_notice = "" # 新增:对外暴露的最新提示文本 def print_sound(indata, outdata, frames, time, status): global cnt, check_cnt, latest_notice volume_norm = np.linalg.norm(indata)*10 a = int(volume_norm) if a <= 28: cnt += 1 if cnt == 300: check_cnt += 1 latest_notice = f"You must be mumbling you have been checked {check_cnt} times" cnt = 0
2. app.py 修改
import sounddevice as sd from flask import Flask, render_template, jsonify from flask_bootstrap import Bootstrap # 修正导入语法,去掉.py后缀 from sounddv import print_sound, latest_notice import threading app = Flask(__name__) Bootstrap(app) # 后台启动音频流,避免阻塞路由 def start_audio_stream(): with sd.Stream(callback=print_sound): # 可修改为while True实现长期运行,当前默认运行20秒 sd.sleep(20 * 1000) # 服务启动时就启动音频检测线程,不需要等请求触发 threading.Thread(target=start_audio_stream, daemon=True).start() @app.route('/audio') def audio_page(): # 直接返回页面,不阻塞 return render_template("popup.html") # 新增接口:供前端拉取最新提示 @app.route('/get-latest-notice') def get_latest_notice(): global latest_notice # 返回后清空提示避免重复展示,不需要可删除下面两行 temp = latest_notice latest_notice = "" return jsonify({"notice": temp}) if __name__ == '__main__': # debug模式下加use_reloader=False避免双进程导致计数异常 app.run(host='127.0.0.1', port=5000, debug=True, use_reloader=False)
3. popup.html 修改
<!DOCTYPE html> <html> <head> <title>Popup!</title> </head> <body> <p id="notice-container"></p> <script> // 每1秒拉取一次最新提示,原生JS实现无需外部依赖 setInterval(async () => { const res = await fetch('/get-latest-notice') const data = await res.json() if (data.notice) { const noticeNode = document.createElement('div') noticeNode.innerText = data.notice document.getElementById('notice-container').appendChild(noticeNode) } }, 1000) </script> </body> </html>
其他页面复用方案
其他HTML页面要使用检测功能,只需要复制popup.html里的JS轮询代码到对应页面,自定义提示渲染位置即可。
注意事项
- 音量阈值28、触发计数300可根据实际测试效果调整
- 生产环境部署时建议使用Gunicorn等WSGI服务器启动,开启单 worker 模式避免全局变量不同步问题
内容的提问来源于stack exchange,提问作者Juliana Jang
相关产品推荐
相关产品推荐

