I'm making a simple video stream to browser app on my Rpi.
I would like to know if there is a way to open a camera only when access the flask page and close the camera if page is not seen anymore. I don't want to let camera open whole time.
I was trying something like this, but it would involve button press (POST request) to flask server every time I want to close the tab what is little bit awkward.
from flask import Flask, render_template, Response, request
import cv2
from time import sleep
app = Flask(__name__)
CAMERA = None
def gen_frames():
global CAMERA
CAMERA = cv2.VideoCapture(0)
sleep(3)
CAMERA.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
CAMERA.set(cv2.CAP_PROP_FRAME_HEIGHT, 960)
while True:
success, frame = CAMERA.read()
if not success:
break
else:
_, buffer = cv2.imencode('.jpg', frame)
frame = buffer.tobytes()
# concat frame one by one and show result
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')
#app.route('/video_feed')
def video_feed():
return Response(gen_frames(), mimetype='multipart/x-mixed-replace; boundary=frame')
#app.route('/', methods = ['POST', 'GET'])
def index():
global CAMERA
if request.method == 'POST':
if request.form['webcam']:
if CAMERA != None and CAMERA.isOpened():
CAMERA.release()
return render_template('index.html')
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=5000)
Related
I am trying to take a RTSP video input and apply analytics and show it as a live stream. I am using Open CV and PyFlask for this purpose.
I can manage to show the output successfully. However, I am having issues when I try to access the host from multiple devices.
If I access from single device, it's working like a charm but when I try to access from multiple devices at the same time, it's breaking.
RTSP = f'''rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mp4'''
# importing
import cv2
from flask import Flask, render_template, Response
app= Flask(__name__)
cap= cv2.VideoCapture(RTSP)
def gen_frames():
while True:
success, frame = cap.read()
ret, buffer = cv2.imencode('.jpg', frame)
frame = buffer.tobytes()
yield(b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')
#app.route('/')
def index():
return render_template('index.html')
#app.route('/video')
def video():
return Response(gen_frames(), mimetype = 'multipart/x-mixed-replace; boundary=frame')
if __name__ == "__main__":
app.run(debug = False, host = '0.0.0.0', port = 8018)
Need some expert advice. Thanks in advance.
Note - index.html code is given below:
<!DOCTYPE html>
<html>
<body>
<h1>Live streaming</h1>
<div>
<img src="{{ url_for('video') }}"/>
</div>
</body>
</html>
I am trying to make a CV project where I have to detect object in video and send it the flask web app. I was able to send the frames to the flask webapp using following code inside generate() function
# show image
ret, buffer = cv2.imencode('.jpg', frame)
frame = buffer.tobytes()
# result
some_more_data = [] # this data will contain more information of object in the frame
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')
then we use another function to send it to flask
#app.route('/video')
def video():
return Response(generate_frames(), mimetype='multipart/x-mixed-replace; boundary=frame')
so, now I also want to send the some_more_data list to the flask..
How can I do that.. or do I have to do something different?
I have a simple FLASK web server, which is waiting for the JSON request.
When JSON is received as {"card": "AC"} it will show me the AC.png card image with OpenCV.
That works. But then it should update & show me the JC.png card when any different JSON is received... that's when it freezes. What am I doing wrong?
# app.py
from flask import Flask, request
import cv2
app = Flask(__name__)
img = cv2.imread('AC.png',1)
img2 = cv2.imread('JC.png',1)
#make window fullscreen
# cv2.namedWindow("window", cv2.WND_PROP_FULLSCREEN)
# cv2.setWindowProperty("window",cv2.WND_PROP_FULLSCREEN,cv2.WINDOW_FULLSCREEN)
#app.route('/webhook', methods=['POST'])
def webhook():
if request.method == 'POST':
#print("Data received from Webhook is: ", request.json)
message = request.json
#print(message["card"])
#When JSON with "AC" received, show AC card
if message["card"] == "AC":
print('first')
cv2.imshow("window", img)
cv2.waitKey(1)
else:
print('second')
cv2.imshow("window", img2) #show JC card
cv2.waitKey(1)
return "Webhook received!"
if __name__ == "__main__":
from waitress import serve
serve(app, host="0.0.0.0", port=8080)
Thanks
In python I am deploying little basic camera streaming Heroku flask app(full code here. Locally, the code works as expected I am able to see my webcam when I run the code on my computer, when I deploy to Heroku I get this error
error: (-215:Assertion failed) !image.empty()
running heroku logs --tail command this is what I get in the logs
mainly this error
cv2.error: OpenCV(4.2.0) /io/opencv/modules/imgcodecs/src/loadsave.cpp:877: error: (-215:Assertion failed) !image.empty() in function 'imencode'
app code:
from flask import Flask, render_template, request, Response
from camera import VideoCamera
import cv2
app = Flask(__name__)
#app.route('/')
def index():
return render_template('index.html')
def gen(camera):
while True:
frame = camera.get_frame()
yield (b'--frame\r\n'b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')
#app.route('/submit', methods=['POST'])
def submit():
if request.method == 'POST':
password = request.form['password']
if password == 'testing':
return render_template('stream_static.html')
else:
return render_template('index.html', message='wrong or empty password')
#app.route('/static', methods=['POST'])
def play():
return render_template('static.html')
#app.route('/stream', methods=['POST'])
def stream():
return Response(gen(VideoCamera()), mimetype='multipart/x-mixed-replace;boundary=frame')
if __name__ == '__main__':
app.debug = True
app.run()
camera.py code:
import cv2
class VideoCamera(object):
def __init__(self):
self.video = cv2.VideoCapture(0)
def __del__(self):
self.video.release()
def get_frame(self):
success, image = self.video.read()
ret, jpeg = cv2.imencode('.jpg', image)
return jpeg.tobytes()
searching error code online people say to check that its not empty, it's not since the program works as it should(camera streams ok on browser) locally right or is it trying to access the "camera" on the heroku server. If I use this code the heroku deployed app displays video properly. Any help would be appreciated, thank you.
I have created a simple live video stream from the raspberry camera. It looks like this
server.py
from flask import Flask
from flask import render_template
from flask import Response
import cv2
app = Flask(__name__)
#app.route('/')
def index():
return render_template('index.html')
#app.route('/video_feed')
def video_feed():
return Response(gen(), mimetype='multipart/x-mixed-replace; boundary=frame')
def gen():
camera = cv2.VideoCapture(0)
while True:
ret, img = camera.read()
if ret:
frame = cv2.imencode('.jpg', img)[1].tobytes()
yield (b'--frame\r\n'b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')
else:
break
app.run(host='192.168.0.241', port=7070, debug=True)
index.html
<html>
<head>
<title>PiCamera stream</title>
</head>
<body>
<h1>Streaming</h1>
<img src="{{ url_for('video_feed') }}">
</body>
</html>
Everything works correct, I enter http://<raspberry_ip>:<port> in the browser and I can see the video.
Right now I need to create mobile app for watching this video, however I am struggling how to do it. Is there a way to capture video stream in iOS app?
Your video is streaming on
http://<raspberry_ip>:<port>/video_feed
http://<raspberry_ip>:<port>
Using Ngrok if you want to push your app to public server!
http://ngrok.com/