Некорректная работа threading вместе с queue

Я пытаюсь записывать видео с камеры в отдельном потоке, не нагружая основной процесс. Для этого я реализовал класс Recorder, но он не всегда работает. Иногда видео получается сломанным, иногда программа просто "встает". Предполагаю, что ошибка где-то в join'ах, но до конца понять не могу

# recorder.py

import queue
import threading
from typing import Tuple

import cv2


class Recorder(threading.Thread):
    def __init__(self, output_path: str,
                 fourcc: str = 'mp4v',
                 fps: float = 30,
                 resolution: Tuple[int, int] = (1920, 1080),
                 record_in_background: bool = True):
        super(Recorder, self).__init__(daemon=record_in_background)

        self.resolution = resolution

        self.writer = cv2.VideoWriter(output_path, cv2.VideoWriter_fourcc(*fourcc),
                                      fps, self.resolution)

        self.frames_queue = queue.Queue()

        self.recording = False

    def __del__(self):
        self.frames_queue.join()

        self.writer.release()

    def write(self, frame):
        self.frames_queue.put(frame)

    def start(self):
        super().start()
        return self

    def run(self):
        self.recording = True
        while self.recording or not self.frames_queue.empty():
            frame = self.frames_queue.get()

            resized_frame = cv2.resize(frame, self.resolution)

            self.writer.write(resized_frame)

            self.frames_queue.task_done()

    def stop(self):
        self.recording = False

        self.join()



# main.py

import cv2

import recoder

cam = cv2.VideoCapture(0)
r = recoder.Recorder("123.mp4", resolution=(640, 480))
r.start()

while True:
    ret, frame = cam.read()

    if not ret:
        break

    r.write(frame)

    cv2.imshow("frame", frame)
    cv2.waitKey(1)

    if cv2.waitKey(25) == ord('q'):
        break

cv2.destroyAllWindows()
cam.release()
r.stop()


Ответы (1 шт):

Автор решения: Gawain

Перенес вызовы функций из деструктора в функцию stop(), а self.join() убрал. Теперь все работает отлично

→ Ссылка