Last active
October 26, 2024 17:32
-
-
Save raiever/df5b6c48217df521094cbe2d12c32c66 to your computer and use it in GitHub Desktop.
[OpenCV] Web Streaming from IP camera with Flask
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Under directory 'templates' */ | |
<html> | |
<head> | |
<title>RTSP web streaming</title> | |
</head> | |
<body> | |
<h1>RTSP web streaming</h1> | |
<h3>XND-6080RV (ip:192.168.2.196)</h3> | |
<h4>python webstreaming.py --ip <host ip> --port <host port></h4> | |
<img src="{{ url_for('video_feed') }}"> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# import the necessary packages | |
from flask import Response, Flask, render_template | |
import threading | |
import argparse | |
import datetime, time | |
import imutils | |
import cv2 | |
# initialize the output frame and a lock used to ensure thread-safe | |
# exchanges of the output frames (useful when multiple browsers/tabs are viewing the stream) | |
outputFrame = None | |
lock = threading.Lock() | |
# initialize a flask object | |
app = Flask(__name__) | |
source = "rtsp://admin:[email protected]/profile2/media.smp" | |
cap = cv2.VideoCapture(source) | |
time.sleep(2.0) | |
@app.route("/") | |
def index(): | |
# return the rendered template | |
return render_template("index.html") | |
def stream(frameCount): | |
global outputFrame, lock | |
if cap.isOpened(): | |
# cv2.namedWindow(('IP camera DEMO'), cv2.WINDOW_AUTOSIZE) | |
while True: | |
ret_val, frame = cap.read() | |
if frame.shape: | |
frame = cv2.resize(frame, (640,360)) | |
with lock: | |
outputFrame = frame.copy() | |
else: | |
continue | |
else: | |
print('camera open failed') | |
def generate(): | |
# grab global references to the output frame and lock variables | |
global outputFrame, lock | |
# loop over frames from the output stream | |
while True: | |
# wait until the lock is acquired | |
with lock: | |
# check if the output frame is available, otherwise skip | |
# the iteration of the loop | |
if outputFrame is None: | |
continue | |
# encode the frame in JPEG format | |
(flag, encodedImage) = cv2.imencode(".jpg", outputFrame) | |
# ensure the frame was successfully encoded | |
if not flag: | |
continue | |
# yield the output frame in the byte format | |
yield(b'--frame\r\n' b'Content-Type: image/jpeg\r\n\r\n' + | |
bytearray(encodedImage) + b'\r\n') | |
@app.route("/video_feed") | |
def video_feed(): | |
# return the response generated along with the specific media | |
# type (mime type) | |
return Response(generate(), | |
mimetype = "multipart/x-mixed-replace; boundary=frame") | |
# check to see if this is the main thread of execution | |
if __name__ == '__main__': | |
# construct the argument parser and parse command line arguments | |
ap = argparse.ArgumentParser() | |
ap.add_argument("-i", "--ip", type=str, required=False, default='192.168.2.226', | |
help="ip address of the device") | |
ap.add_argument("-o", "--port", type=int, required=False, default=8000, | |
help="ephemeral port number of the server (1024 to 65535)") | |
ap.add_argument("-f", "--frame-count", type=int, default=32, | |
help="# of frames used to construct the background model") | |
args = vars(ap.parse_args()) | |
t = threading.Thread(target=stream, args=(args["frame_count"],)) | |
t.daemon = True | |
t.start() | |
# start the flask app | |
app.run(host=args["ip"], port=args["port"], debug=True, | |
threaded=True, use_reloader=False) | |
# release the video stream pointer | |
cap.release() | |
cv2.destroyAllWindows() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
thank you very much