Last active
January 10, 2021 21:22
-
-
Save irdanish11/f864ae5985ba826333abcc1bd7ffc5a9 to your computer and use it in GitHub Desktop.
To prevent lagging & stream interruption(breaking) when streaming video from an IP camera, using a buffer with threading can reduce the lagging issue.
This file contains hidden or 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
| #!/usr/bin/env python3 | |
| # -*- coding: utf-8 -*- | |
| """ | |
| Created on Sat Jan 9 13:16:08 2021 | |
| @author: danish | |
| """ | |
| # OpenCV Python script to buffer the video stream | |
| # import libraries of python OpenCV as cv2 | |
| import cv2 | |
| import sys | |
| import threading | |
| import queue | |
| # == Start Initialization == | |
| frame_buffer_size = 5 # The queue size for keeping video frame for processing. Cannot less than 2 | |
| # Capture frames from the ip camera | |
| fn = 'rtsp://user:password@ip_address/Streaming/Channels/101/' | |
| # Set capture device from fn | |
| cap = cv2.VideoCapture(fn) | |
| # The queue for keeping video frame for processing | |
| frame_buffer = queue.Queue(maxsize=frame_buffer_size) | |
| # == End Initialization == | |
| # De-allocate any associated memory usage and exit the program | |
| def deallocateAndExit(): | |
| # De-allocate any associated memory usage | |
| cap.release()# release camera | |
| cv2.destroyAllWindows()# release screen | |
| sys.exit() # exit program | |
| # This is a thread function to keep reading frames and put the frames into frame_buffer for preventing lag of frames reading. | |
| def rtsp_read_buffer(): | |
| # ret will be False when cap.read() timeout or error | |
| ret = True | |
| while (ret): | |
| # If frame_buffer queue is full, get the first queue element out of the queue | |
| if frame_buffer.full(): | |
| frame_buffer.get() | |
| # Read frame-by-frame | |
| # capturing each frame | |
| ret, buffer_frame = cap.read() | |
| # Put the capturing frame to the queue | |
| frame_buffer.put(buffer_frame) | |
| # Exit program | |
| deallocateAndExit() | |
| # Main function to start the program | |
| def main(): | |
| # Start thead functions to continue their task parallelly | |
| threading.Thread(target=rtsp_read_buffer, daemon=True).start() | |
| # Check cv2.VideoCapture(fn) is open | |
| while (cap.isOpened()): | |
| # Check if frame_buffer queue has frames waiting to process or not | |
| # If some processes are waiting, let calculate it | |
| if frame_buffer.empty() != True: | |
| # Get a frame from the frame_buffer queue | |
| frame = frame_buffer.get() | |
| frame_out = frame.copy()# output frame | |
| # Display video | |
| cv2.imshow('Frame out', frame_out)# display each frame | |
| # Terminate program | |
| k = cv2.waitKey(30) & 0xff | |
| if k == 27: #Press 'ESC' to quit | |
| break | |
| # End while loop | |
| # Exit program | |
| deallocateAndExit() | |
| # start process | |
| if __name__ == '__main__': | |
| main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment