Python Django项目中点击HTML按钮关闭网页摄像头视频流的实现方法
初始思路落地方法
你提到的全局变量控制思路只适合单用户本地测试场景,落地步骤如下:
- 后端新增停止摄像头接口
在views.py中新增接口修改全局变量:
from django.http import JsonResponse still_on = True # 原有代码保持不变 def stop_camera(request): global still_on still_on = False return JsonResponse({"status": "success"})
在项目urls.py中添加对应路由:
path('stop-camera/', views.stop_camera, name='stop_camera'),
- 前端修改点击逻辑,先请求停止接口再跳转
修改视频流页面模板代码:
{% extends 'main/base.html' %} {% block content %} <h1>Stimulus Section</h1> <br> <img src="{% url 'video_feed' %}" id="video-feed"> <br> <br> <h2>{{ S6 }}</h2> <br> <br> <br> <button class="btn btn-primary" onclick="goHome()">Home</button> {% endblock %} {% block script %} <script> async function goHome() { // 先请求后端停止摄像头 await fetch("{% url 'stop_camera' %}"); // 再跳转首页 location.href = "{% url 'home' %}"; } </script> {% endblock %}
该思路的缺陷
- 全局变量
still_on是进程级别的,多用户访问时只要一个用户触发停止,所有用户的视频流都会中断 - 如果用户没有点击返回按钮,而是直接关闭页面、点击浏览器返回/前进按钮,不会触发停止逻辑,摄像头会持续运行
更稳定的实现方案(推荐)
不用全局变量,利用Django StreamingHttpResponse的特性,客户端断开连接时自动终止生成器、释放摄像头资源:
- 修改
views.py代码,删除全局still_on变量:
def gen(tryhaar): while True: frame = tryhaar.get_frame() # 帧读取失败直接退出循环 if not frame: break yield (b'--frame\r\n' b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n') # 循环退出后主动释放摄像头 tryhaar.__del__() def video_feed(request): return StreamingHttpResponse(gen(VideoCamera()), content_type='multipart/x-mixed-replace; boundary=frame') def home(request): return render(request, "main/home.html",{})
- 前端增加页面卸载事件,主动断开视频流连接:
在视频流页面的script标签中添加以下代码:
window.addEventListener('beforeunload', function() { // 清空img的src,主动断开和后端视频流的连接 document.getElementById('video-feed').src = ''; });
该方案优势:
- 无全局变量冲突,多用户访问互不干扰
- 覆盖所有用户离开场景:点击按钮跳转、关闭页面、浏览器返回/前进操作都会触发摄像头自动释放
内容的提问来源于stack exchange,提问作者Amin Affandi
相关产品推荐
相关产品推荐

