首页 > 解决方案 > 使用 Flask 流式传输视频时,Raspberry Pi 冻结

问题描述

我有这个 Flask-Socketio 应用程序,它显示了 Raspberry Pi 系统信息,如温度、RAM 和磁盘空间。这个应用程序还有一个视频流组件VideroStream.py

我添加了使用 Flask 蓝图的VideroStream.py路线。index.py在浏览器 RPI 中访问应用程序时冻结并在错误日志中显示:

>  Truncated or oversized response headers received from daemon process
> 'rpiWebServer': /var/www/rpiWebServer.wsgi

为什么会这样?这条线正确videoStreamBp = Blueprint('video_stream', __name__)吗?我应该使用videopi而不是video_stream吗?

当我创建一个没有蓝图的独立应用程序时,Socketio 流式传输可以完美运行。

更新:

当我按预期删除src="{{url_for(videopi)}}"没有视频的图像页面加载时。

索引.py

from flask import Flask, render_template, Response, request
from flask_socketio import SocketIO, emit
from threading import Lock

#for temp
import os
import datetime
import ast
import psutil

app = Flask(__name__)
#for socket
async_mode = None
socketio = SocketIO(app, async_mode=async_mode)
#thread = None
thread1 = None
thread_lock = Lock()

from findPath import findPathBp
app.register_blueprint(findPathBp)
from videoStream import videoStreamBp
app.register_blueprint(videoStreamBp)

# GET RAM info
def getSysInfo():
    count = 0
    while True:
        #RAM
        memory = psutil.virtual_memory()
        ramAvailable = round(memory.available/1024.0/1024.0,1) # Divide from Bytes -> KB -> MB
        ramTotal = round(memory.total/1024.0/1024.0,1)

        #Temp
        temp = os.popen("vcgencmd measure_temp").readline()
        cpuTemp = temp.replace("temp=","")
        cpuTemp = cpuTemp.replace("'C","°C")

        #DISK
        disk = psutil.disk_usage('/')
        # Divide from Bytes -> KB -> MB -> GB
        diskFree = round(disk.free/1024.0/1024.0/1024.0,1)
        diskTotal = round(disk.total/1024.0/1024.0/1024.0,1)

        socketio.sleep(1)
        count += 1
        socketio.emit('sysStat',{'available': ramAvailable, 'total': ramTotal, 'temp': cpuTemp, 'freeDisk': diskFree, 'totalDisk': diskTotal }, namespace='/getSysInfo')



#index route
@app.route("/", methods=['GET', 'POST'])
def index():
    return render_template('index.html', result= timeString)

#socket IO
# Get system info
@socketio.on('connect', namespace='/getSysInfo')
def test_connect():
    global thread1
    with thread_lock:
        if thread1 is None:
            thread1 = socketio.start_background_task(getSysInfo)

if __name__ == "__main__":
   socketio.run(host='192.168.225.47', port=80, debug=True, threaded=True)

视频流.py

from flask import Blueprint, render_template, Response
videoStreamBp = Blueprint('video_stream', __name__)

# Raspberry Pi camera module (requires picamera package)
from camera_pi import Camera
def gen(camera):
    # Video streaming generator function.
    while True:
        frame = camera.get_frame()
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')

@videoStreamBp.route('/videopi')
def video_stream():
    return Response(gen(Camera()),
                    mimetype='multipart/x-mixed-replace; boundary=frame')

索引.html

        <div class='fifty'>
            <p class='tempConainer'>CPU temperature is: <span id='temp'>Loading..</span></p><br>
            <p class='tempConainer'>RAM available: <span id='ramInfo'>Loading..</span></p>
            <p class='tempConainer'>RAM total: <span id='ramInfo1'>Loading..</span></p><br>
            <p class='tempConainer'>Free disk: <span id='freeDisk'>Loading..</span></p><br>
            <p class='tempConainer'>Total disk: <span id='totalDisk'>Loading..</span></p><br>
        </div>
        <div class='fifty'>
            <img src="{{url_for(videopi)}}">
        </div>

标签: pythonflasksocket.iovideo-streaming

解决方案


最后发现image的src属性不对,改成这样:

<img src='/videopi'>

奇迹般有效。


推荐阅读