У меня есть пара потоков RTSP, которые мне нужно отобразить в браузере. В настоящее время я использую OpenCV cv2.VideoCapture, чтобы сделать это. Это делает свое дело, но когда клиентская сторона перестает получать поток (то есть закрывает окно браузера), похоже, что даже когда захват видео прекращается, экземпляр объекта CameraStream все еще находится в памяти. У меня нет внешних ссылок на это.
Как правильно закрыть их?
Вот мой код:
class Stream(Resource):
def get(self, id):
self.id = id
response = Response(Stream.gen_frame(self),
mimetype='multipart/x-mixed-replace; boundary=frame')
return response
def gen_frame(self):
"""
Video stream generator
"""
self.cap = CameraStream(cameras[self.id]).start()
while self.cap:
frame = self.cap.read()
convert = cv2.imencode('.jpg', frame)[1].tobytes()
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + convert + b'\r\n') # concate frame one by one and show result
time.sleep(0.05)
self.cap.stop()
cv2.destroyAllWindows()
self.cap.stream.release()
print("done")
И класс CameraStream:
class CameraStream(object):
thread = None
frame = None
last_access = 0
def __init__(self, stream, src=0):
self.stream = cv2.VideoCapture(stream)
(self.grabbed, self.frame) = self.stream.read()
self.started = False
self.read_lock = Lock()
def start(self):
if self.started:
print("already started!!")
return None
self.started = True
self.thread = Thread(target=self.update, args=())
self.thread.start()
return self
def update(self):
while self.started:
(grabbed, frame) = self.stream.read()
self.read_lock.acquire()
self.grabbed, self.frame = grabbed, frame
self.read_lock.release()
def read(self):
self.read_lock.acquire()
if not isinstance(self.frame, (numpy.ndarray)):
# debugging stuff
print('achtung', type(self.frame))
return 0
frame = self.frame.copy()
self.read_lock.release()
return frame
def stop(self):
self.started = False
self.thread.join()
def __exit__(self, exc_type, exc_value, traceback):
self.stream.release()
Только идея у меня было, что работало (вроде) использование глобальной переменной для проверки ее значения в каждой итерации l oop. Так что я могу изменить его глобально, чтобы остановить все потоки одновременно
ps Я проверяю объекты, используя этот код:
for x in gc.get_objects():
if isinstance(x, CameraStream):
print(x)