I'm trying to make a camera server that shows multiple video process streaming results through Chrome browser using Flask, OpenCV.
Problem
It can handle 6 request at most with a single browser, but I need to process more than 60 camera requests.
Things I've tried.
At first I thought CPU couldn't handle more than 6 inputs but when I request it from another browser(chrome,Firefox,Edge etc), it can handle more simultaneously. So hardware seems not to be a problem. It's somehow limiting the requests per browser. So every single browser could handle only 6 at most.
If I request more than 6 it starts processing the first 6 request and wait till one of them finishes then starts next requests. I think it's because Flask app handles process synchronously.
I've tried with thread=True
options with Flask, and with gunicorn for async process. but there is no difference.
gunicorn video:app -w 81 --threads 81 -k gevent --worker-connections 1000
I have no idea why it's limited to 6 requests only. is it possible to solve this?
Here is a sample code for the project.
video.py
import cv2
from flask import Flask,request, Response
def loadVideo(video):
cap = cv2.VideoCapture(video)
if cap.isOpened(): # try to get the first frame
rval, frame = cap.read()
else:
rval = False
IMG_SIZE = 640
while(1):
rval, image = cap.read()
image = cv2.resize(image, (IMG_SIZE, IMG_SIZE))
if rval==True:
orig = image.copy()
frame = cv2.blur(image, (3,3))
yield (b'--frame\r\n' b'Content-Type: image/jpeg\r\n\r\n'+ cv2.imencode('.jpg', frame)[1].tostring() + b'\r\n')
elif rval==False:
break
end = time.time()
cap.release()
app = Flask(__name__)
@app.route('/')
def hello():
return "Server Established!"
@app.route('/detect',methods = ['GET'])
def detect():
try:
if request.method == 'GET':
src = request.args.get('src')
return Response(loadVideo(src),
mimetype = "multipart/x-mixed-replace; boundary=frame")
except Exception as e:
return e
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=3999, threaded=True)