Flask 从web服务器上的Raspberry Pi向多个用户传输视频
我有一个Raspberry Pi,使用Wifi,它正在运行人员计数模型,并将使用ZeroMQ套接字将处理后的图像发送到我的服务器。在这个服务器上,我使用Flask构建了一个web服务器。我得到了一个错误,第一个访问网站的人在流媒体播放过程中没有显示,但是第一个访问之后的下一个访问将失败:Flask 从web服务器上的Raspberry Pi向多个用户传输视频,flask,raspberry-pi,streaming,zeromq,pyzmq,Flask,Raspberry Pi,Streaming,Zeromq,Pyzmq,我有一个Raspberry Pi,使用Wifi,它正在运行人员计数模型,并将使用ZeroMQ套接字将处理后的图像发送到我的服务器。在这个服务器上,我使用Flask构建了一个web服务器。我得到了一个错误,第一个访问网站的人在流媒体播放过程中没有显示,但是第一个访问之后的下一个访问将失败: zmq.error.ZMQError:正在使用的地址 我应该怎么做才能让更多的人访问我的服务器并观看视频流 服务器代码: from flask import Flask, render_temp
zmq.error.ZMQError:正在使用的地址
我应该怎么做才能让更多的人访问我的服务器并观看视频流
服务器代码:
from flask import Flask, render_template, Response, request, jsonify
from flask_restful import Api
import numpy as np
from api.configs import configs
from flask_cors import CORS
import zmq
import cv2
import base64
app = Flask(__name__, static_url_path='/static')
api_restful = Api(app)
cors = CORS(app)
def gen():
context = zmq.Context()
footage_socket = context.socket(zmq.SUB)
footage_socket.bind('tcp://*:{}'.format(configs.SOCKET_PORT))
footage_socket.setsockopt_string(zmq.SUBSCRIBE, np.unicode(''))
while True:
frame = footage_socket.recv()
npimg = np.fromstring(frame, dtype=np.uint8)
source = cv2.imdecode(npimg, 1)
s = cv2.imencode('.jpg', source)[1].tobytes()
yield ( b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + s + b'\r\n' )
@app.route('/video_feed')
def video_feed():
return Response( gen(),
mimetype = 'multipart/x-mixed-replace; boundary=frame'
)
if __name__ == '__main__':
app.run( debug = True,
threaded = True,
port = configs.PORT,
host = configs.HOST
)
Raspberry Pi客户端代码:
import socket
import logging as log
import numpy as np
from api.configs import configs
import zmq
import numpy as np
import cv2
context = zmq.Context()
footage_socket = context.socket(zmq.PUB)
footage_socket.connect( 'tcp://{}:{}'.format( configs.SERVER_HOST,
configs.SOCKET_PORT )
)
time.sleep(1)
cap = cv2.VideoCapture(0)
while True:
while cap.isOpened():
ret, frame = cap.read()
frame = cv2.resize(frame, (640, 480))
encoded, buffer_ = cv2.imencode('.jpg', frame)
footage_socket.send(buffer_)
我省略了一些代码,以便于查看欢迎来到Zen of Zero的艺术。
如果您从未使用过ZeroMQ,
您可能会喜欢在深入了解更多细节之前先看看
我无法谈论
Flask()
web服务视频重新包装/交付中隐藏的细节,但ZeroMQ部分似乎是问题所在,因此:
a)似乎每个web观察家都会产生另一个
@app.route('/video\u feed')
-desk()-instance(检查模式-如果只是基于线程或基于进程-这很重要,无论是中央上下文()
实例可能得到共享,也可能无法得到有效重用)
b)驻留在那里的代码钩住了
Response()
-feeder,它试图为每个后续的Flask()
-服务的用户.bind()
,这显然是因为资源(地址:端口
)在第一次访问时被POSACK
”专用,第一位访客(任何下一位访客都必须崩溃,并按照上述记录崩溃)
专业的解决方案(或者只是一个快速但肮脏的解决方案): 对于小规模的用例,它应该足以反转
.bind()
/.connect()
-s,即发布将.bind()
(因为它不会复制自身,并且可以通过.connect()
-s提供任何少量的进一步子项)
然而,这个快速修复有点脏。这决不能在生产级系统中进行。工作量范围很快就会超过合理水平。适当的体系结构应该以不同的方式工作
- 实例化一个中央
zmq.Context(configs.nIOthreads)
-实例(可以共享以在调用的方法中重用),因此出于性能原因,还可以对nIOthreads
进行中央缩放
- 实例化一个中央
子实例,该实例与Rpi通信并收集视频帧,以避免图像/服务的任何重复
- 将双方配置为使用
.setsockopt(zmq.CONFLATE)
主要避免重新播放视频“无价值的历史记录”
- 实例化所有的
@app
-Flask()
-工具,以重用中央上下文()
-实例,并使用另一个发布/发布
原型的SUB
-侧,在此处内部连接到中央视频,使用proc://
中映射的高效内存,再次使用.setsockopt(zmq.CONFLATE)
将所有资源配置为具有更高的健壮性-至少使用显式的.setsockopt(zmq.LINGER,0)
检测和处理所有错误状态,因为ZeroMQ API充分记录了所有错误状态,可以帮助您专业、安全地诊断和管理任何故障状态
欢迎来到Zero的禅宗艺术。
如果您从未使用过ZeroMQ,
您可能会喜欢在深入了解更多细节之前先看看
我无法谈论Flask()
web服务视频重新包装/交付中隐藏的细节,但ZeroMQ部分似乎是问题所在,因此:
a)
似乎每个web观察家都会产生另一个@app.route('/video\u feed')
-desk()
-instance(检查模式-如果只是基于线程或基于进程-这很重要,无论是中央上下文()
实例可能得到共享,也可能无法得到有效重用)
b)驻留在那里的代码钩住了
Response()
-feeder,它试图为每个后续的Flask()
-服务的用户.bind()
,这显然是因为资源(地址:端口
)在第一次访问时被POSACK
”专用,第一位访客(任何下一位访客都必须崩溃,并按照上述记录崩溃)
专业的解决方案(或者只是一个快速但肮脏的解决方案): 对于小规模的用例,它应该足以反转
.bind()
/.connect()
-s,即发布将.bind()
(因为它不会复制自身,并且可以通过.connect()
-s提供任何少量的进一步子项)
然而,这个快速修复有点脏。这决不能在生产级系统中进行。工作量范围很快就会超过合理水平。适当的体系结构应该以不同的方式工作
- 实例化一个中央
zmq.Context(configs.nIOthreads)
-实例(可以共享以在调用的方法中重用),因此出于性能原因,还可以对nIOthreads
进行中央缩放
- 实例化一个与Rpi通信并收集视频-f的中央
子-实例