当前位置: 首页 > backend >正文

树莓派网页监控

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
极简 Flask:网页内直接嵌入 MJPEG 视频流(不需要 VNC 窗口)
- 通过 libcamera-vid 输出 MJPEG 到 stdout,再由 Flask 包成 multipart/x-mixed-replace
- 两路接口:/cam/0/mjpeg 与 /cam/1/mjpeg
- 主页内嵌 <img src=...> 连续刷新即可看到实时画面依赖:sudo apt-get updatesudo apt-get install -y python3-flask libcamera-apps运行:sudo python3 app.py --host 0.0.0.0 --port 8000浏览器打开 http://<Pi-IP>:8000/注意:
- 每个浏览器连接会各自启动一个 libcamera-vid 子进程,断开连接即结束。
- 如果提示相机被占用,请先关闭其它正在使用相机的进程(包含你开的 libcamera-hello 窗口)。
"""import os
import sys
import subprocess
from flask import Flask, Response, render_template_stringapp = Flask(__name__)INDEX_HTML = """
<!doctype html>
<html lang="zh">
<head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>Pi 双摄网页预览(MJPEG)</title><style>body{font-family:system-ui,Segoe UI,Roboto,Arial,sans-serif;margin:16px}.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(320px,1fr));gap:16px}.card{border:1px solid #e5e7eb;border-radius:12px;padding:12px;box-shadow:0 1px 2px rgba(0,0,0,.04)}img{width:100%;height:auto;border-radius:8px;background:#000}small{color:#6b7280}</style>
</head>
<body><h1>Pi 双摄网页预览(MJPEG)</h1><div class="grid"><div class="card"><h3>Camera 0</h3><img src="/cam/0/mjpeg" alt="Camera 0"/><small>源:libcamera-vid --camera 0 --codec mjpeg -t 0 -o -</small></div><div class="card"><h3>Camera 1</h3><img src="/cam/1/mjpeg" alt="Camera 1"/><small>源:libcamera-vid --camera 1 --codec mjpeg -t 0 -o -</small></div></div>
</body>
</html>
"""def _mjpeg_stream(camera_index: int, width: int = 1280, height: int = 720):"""启动 libcamera-vid 输出 MJPEG 到 stdout,并逐帧切片为 multipart 片段。"""cmd = ["libcamera-vid","--camera", str(camera_index),"--codec", "mjpeg","--width", str(width),"--height", str(height),"-t", "0",            # 无限时长"-o", "-",            # 输出到 stdout"--nopreview",         # 不启用本地预览窗口]# 启动子进程proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=0)boundary = b"--FRAME"buffer = bytearray()SOI = b"\xff\xd8"  # JPEG Start Of ImageEOI = b"\xff\xd9"  # JPEG End Of Imagetry:# 持续读取 stdout,按 SOI/EOI 切出完整 JPEG 帧while True:chunk = proc.stdout.read(4096)if not chunk:breakbuffer.extend(chunk)# 可能会一次到多帧;循环切片while True:soi = buffer.find(SOI)if soi < 0:# 丢弃 SOI 之前的无效数据if len(buffer) > 1024:del buffer[:-2]breakeoi = buffer.find(EOI, soi + 2)if eoi < 0:# 帧未结束,继续读break# 取出完整 JPEG 帧(包含 EOI 0xFFD9)frame = bytes(buffer[soi:eoi + 2])del buffer[:eoi + 2]# 发送 multipart 片段headers = (boundary + b"\r\n" +b"Content-Type: image/jpeg\r\n" +b"Content-Length: " + str(len(frame)).encode() + b"\r\n\r\n")yield headers + frame + b"\r\n"finally:# 断开或异常时,确保子进程退出try:proc.terminate()except Exception:pass@app.route("/")
def index():return render_template_string(INDEX_HTML)@app.route("/cam/<int:cam>/mjpeg")
def stream(cam: int):# 这里可按需改分辨率,如 1640x1232 以适配 IMX219 方便return Response(_mjpeg_stream(cam, width=1280, height=720),mimetype='multipart/x-mixed-replace; boundary=FRAME')if __name__ == '__main__':host = os.environ.get('HOST', '0.0.0.0')port = int(os.environ.get('PORT', '8000'))print(f"Serving on http://{host}:{port}")app.run(host=host, port=port, threaded=True, debug=False)

在这里插入图片描述

http://www.xdnf.cn/news/19669.html

相关文章:

  • 从 Arm Compiler 5 迁移到 Arm Compiler 6
  • 2025 随身 WIFI 行业报告:从拼参数到重体验,华为 / 格行 / 中兴技术差异化路径解析
  • 梳理一下 @types/xxx
  • java面试中经常会问到的多线程问题有哪些(基础版)
  • think
  • ubuntu系统设置中文失败问题
  • grpc-swift-2 学习笔记
  • 均匀分布直线阵的常规波束形成方位谱和波束图
  • (Arxiv-2025)ConceptMaster:基于扩散 Transformer 模型的多概念视频定制,无需测试时微调
  • 【2025终极对决】Python三大后端框架Django vs FastAPI vs Robyn,你的选择将决定项目生死?
  • [光学原理与应用-366]:ZEMAX - 用成像原理说明人眼为什么能看清物体?
  • 两款超实用办公插件推荐:Excel聚光灯与Word公文排版
  • MySQL 多表查询方法
  • Spring Boot 全局字段处理最佳实践
  • mysql初学者练习题(从基础到进阶,相关数据sql脚本在最后)
  • 59.螺旋矩阵II
  • 框架-SpringMVC-1
  • WPF中的静态资源和动态资源
  • 支付系统设计模式应用:从单例到观察者模式实践
  • 网络编程 05:UDP 连接,UDP 与 TCP 的区别,实现 UDP 消息发送和接收,通过 URL 下载资源
  • EPLAN 分散式端子:提升原理图设计效率的实用功能
  • 使用 C 模仿 C++ 模板的拙劣方法
  • Replit在线编程工具:支持多语言环境免配置与实时协作,助力编程学习调试与社区项目复用
  • 企业微信员工聊天记录能看吗?合规管理三要素一次性说清
  • cuDNN深度解析:实战演练
  • Electron 菜单与托盘:构建用户友好的界面元素
  • 9月2日
  • 深入分析 json2(新)与标准的 jsonrpc的区别
  • zephyr设备树的硬件描述转换为c语言
  • Hash 算法 SHA-1、SHA-256、SHA-384、SHA-512 对比