Web streamer initial commit
This commit is contained in:
		
							
								
								
									
										9
									
								
								templates/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								templates/index.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					<html>
 | 
				
			||||||
 | 
					  <head>
 | 
				
			||||||
 | 
					    <title>rPi KVM by Petrkr</title>
 | 
				
			||||||
 | 
					  </head>
 | 
				
			||||||
 | 
					  <body>
 | 
				
			||||||
 | 
					    <h1>rPi KVM by Petrkr</h1>
 | 
				
			||||||
 | 
					    <img src="{{ url_for('video_feed') }}">
 | 
				
			||||||
 | 
					  </body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
							
								
								
									
										89
									
								
								webstreaming.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								webstreaming.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,89 @@
 | 
				
			|||||||
 | 
					from flask import Response
 | 
				
			||||||
 | 
					from flask import Flask
 | 
				
			||||||
 | 
					from flask import render_template
 | 
				
			||||||
 | 
					import threading
 | 
				
			||||||
 | 
					import argparse
 | 
				
			||||||
 | 
					import datetime
 | 
				
			||||||
 | 
					import imutils
 | 
				
			||||||
 | 
					import time
 | 
				
			||||||
 | 
					import cv2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					outputFrame = None
 | 
				
			||||||
 | 
					lock = threading.Lock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# initialize a flask object
 | 
				
			||||||
 | 
					app = Flask(__name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cap = cv2.VideoCapture(0)
 | 
				
			||||||
 | 
					cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1920)
 | 
				
			||||||
 | 
					cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 1080)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					time.sleep(1.0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@app.route("/")
 | 
				
			||||||
 | 
					def index():
 | 
				
			||||||
 | 
						# return the rendered template
 | 
				
			||||||
 | 
						return render_template("index.html")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def detect_motion(frameCount):
 | 
				
			||||||
 | 
						global vs, outputFrame, lock
 | 
				
			||||||
 | 
						while True:
 | 
				
			||||||
 | 
							flag, frame = cap.read()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if not flag:
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							timestamp = datetime.datetime.now()
 | 
				
			||||||
 | 
							cv2.putText(frame, timestamp.strftime(
 | 
				
			||||||
 | 
								"%A %d %B %Y %I:%M:%S%p"), (10, frame.shape[0] - 10),
 | 
				
			||||||
 | 
								cv2.FONT_HERSHEY_SIMPLEX, 0.35, (0, 0, 255), 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							with lock:
 | 
				
			||||||
 | 
								outputFrame = frame.copy()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def generate():
 | 
				
			||||||
 | 
						global outputFrame, lock
 | 
				
			||||||
 | 
						while True:
 | 
				
			||||||
 | 
							with lock:
 | 
				
			||||||
 | 
								if outputFrame is None:
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								(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=True,
 | 
				
			||||||
 | 
							help="ip address of the device")
 | 
				
			||||||
 | 
						ap.add_argument("-o", "--port", type=int, required=True,
 | 
				
			||||||
 | 
							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())
 | 
				
			||||||
 | 
						# start a thread that will perform motion detection
 | 
				
			||||||
 | 
						t = threading.Thread(target=detect_motion, 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)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Reference in New Issue
	
	Block a user