Flask+OpenCV项目中跨模块传递user_data变量失败求解决方案
问题分析
你混淆了Flask请求上下文g的作用域,同时模块间全局变量的隔离也导致了数据同步失败:
g是每个HTTP请求独立的上下文对象,在/save_file请求中设置的g.user_data,在/video_feed的新请求里会被重置,无法跨请求共享;- app.py和camera.py是两个独立模块,各自的全局变量互相隔离,修改其中一个不会同步到另一个。
解决方案
方案1:使用Flask应用全局配置(推荐)
Flask的app.config是跨请求共享的全局存储,且天然支持线程安全,适合存储这类需要全局访问的配置项。
修改app.py
from flask import Flask, render_template, request, Response, jsonify from camera import generate_frames # 明确导入函数,避免模块变量冲突 import threading app = Flask(__name__) # 初始化全局配置项 app.config['USER_DATA'] = None video_thread = None # ... 其他导入和函数 ... @app.route('/save_file', methods=['GET', 'POST']) def test(): if request.method == 'POST': name = request.form['name'] # 更新全局配置 app.config['USER_DATA'] = name print(f"Recording path updated to: {app.config['USER_DATA']}") return f"System will now record and store the data as per the destination you selected, {name}." return render_template('index.html', system_info=get_system_info(), user_data=app.config['USER_DATA']) @app.route('/video_feed') def video_feed(): return Response(generate_frames(), mimetype='multipart/x-mixed-replace; boundary=frame')
修改camera.py
from flask import current_app import cv2 # 补充OpenCV导入 # ... 其他函数 ... def generate_frames(): cap = cv2.VideoCapture(0) while True: success, frame = cap.read() if not success: break # 从全局配置获取最新的录制路径 user_data = current_app.config.get('USER_DATA') print(f"User data in generate_frames: {user_data}") # 这里添加你的视频录制逻辑,使用user_data作为存储路径 # ... # 生成视频帧的逻辑 ret, buffer = cv2.imencode('.jpg', frame) frame = buffer.tobytes() yield (b'--frame\r\n' b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n') cap.release()
方案2:直接传递参数给生成器
如果不想依赖app.config,也可以在调用generate_frames时直接传递最新的user_data值,缺点是生成器运行期间无法自动同步后续的变量更新。
修改app.py的video_feed路由
@app.route('/video_feed') def video_feed(): # 传递当前最新的USER_DATA给生成器 return Response(generate_frames(app.config['USER_DATA']), mimetype='multipart/x-mixed-replace; boundary=frame')
修改camera.py的generate_frames
import cv2 def generate_frames(user_data): cap = cv2.VideoCapture(0) while True: success, frame = cap.read() if not success: break print(f"User data in generate_frames: {user_data}") # 注意:如果user_data在生成器运行后被更新,这里不会自动获取新值 # ... 视频录制和帧生成逻辑 ... ret, buffer = cv2.imencode('.jpg', frame) frame = buffer.tobytes() yield (b'--frame\r\n' b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n') cap.release()
内容的提问来源于stack exchange,提问作者Astro
相关产品推荐
相关产品推荐

