Beispiel #1
0
    def record_to(self, dest):
        try:
            self.dest_path = dest
            os.makedirs(os.path.dirname(dest), exist_ok=True)
            self.dest_video = cv2.VideoWriter(
                self.dest_path, _FourCC, self.src_fps,
                (self.src_width, self.src_height))

        except BaseException as exc:
            log.warn(
                f'VideoSource [{self.video_source_id}] - start record to {dest} failed: {exc}'
            )
Beispiel #2
0
 def _write_frame(self, frame: np.ndarray):
     # noinspection PyBroadException
     try:
         if self.dest_video is not None:
             if frame is None:
                 self._decode_frame()
                 frame = self.cur_frame
             with self.dest_lock:
                 self.dest_video.write(frame.astype('uint8'))
     except BaseException as exc:
         log.warn(
             f'VideoSource [{self.video_source_id}] - write frame failed: {exc}'
         )
Beispiel #3
0
    def stop_record(self):
        # noinspection PyBroadException
        try:
            if self.dest_video is None:
                return
            video_writer = self.dest_video
            self.dest_video = None
            self.dest_path = None
            if video_writer is not None:
                with self.dest_lock:
                    video_writer.release()

        except BaseException as exc:
            log.warn(
                f'VideoSource [{self.video_source_id}] - stop record failed: {exc}'
            )
Beispiel #4
0
    def __init__(
        self,
        stream_url,
        video_config=None,
        video_source_id=None,
        event_listener=None,
    ):
        import copy
        log.warn(
            f'VideoSource init: stream_url={stream_url} video_config={video_config}'
        )
        try:
            stream_url = int(stream_url)
        except ValueError:
            pass
        self.stream_url: str = stream_url
        self.video: Optional[cv2.VideoCapture] = None
        self.src_width = -1
        self.src_height = -1
        self.src_fps = -1
        self.read_lock = Lock()

        self.dest_path = None
        self.dest_video = None
        self.dest_lock = Lock()

        self.cur_frame = None
        self.cur_frame_num = -1
        self.decoded = False

        self.vidconfig: dict = copy.deepcopy(self.DfConfig)
        self.update_conf(video_config)

        self.video_source_id = video_source_id
        self.callback: Callable = event_listener

        self.stt = VideoSourceStt.Init
        self.corrupt = False

        self.scale_width = self.vidconfig['scale_width']
        self.scale_height = self.vidconfig['scale_height']
        self.auto_retry = self.vidconfig['auto_retry']
        self.auto_pass = self.vidconfig['auto_pass']

        self.stream_subscriber_ids = set()
        self.cur_frame_stream_data = None
        self.cur_frame_stream_id = -1
Beispiel #5
0
    def start(self, first_access_check=True):
        if (self.stt is VideoSourceStt.TryingToCapture
                or self.stt is VideoSourceStt.Running
                or self.stt is VideoSourceStt.Retrying):
            return

        if first_access_check and not self.check():
            raise IOError('Access video failed')

        log.warn(f'VideoSource [{self.video_source_id}] - connecting...')
        self.stt = VideoSourceStt.TryingToCapture

        self.video = self._get_video()
        self._get_video_info()
        if self.video is None:
            self._notify_listener(VideoSourceStt.Stopped)
            raise IOError('Access video failed')
        self.corrupt = False
        self.stt = VideoSourceStt.Running
        if self.auto_pass:
            thread = Thread(target=self._stream_loop)
            thread.daemon = True
            thread.start()
Beispiel #6
0
    def _stream_loop(self):
        self.cur_frame_num = -1
        while not self.corrupt and self.auto_pass:
            grabbed = self.video.grab()
            if not grabbed:
                if self.auto_retry:
                    self.video = self._get_video()
                    self._get_video_info()
                    continue
                else:
                    self.stop()
                    break
            self.decoded = False

            _WriteVideoExecutor.submit(self._write_frame, None)

            if sys.getsizeof(self.cur_frame_num) > _FrameNumStorage:
                self.cur_frame_num = 0
            else:
                self.cur_frame_num += 1

        log.warn(f'VideoSource [{self.video_source_id}] - stopped')
        self.stt = VideoSourceStt.Stopped
Beispiel #7
0
    def _get_video(self):
        with self.read_lock:
            video = None
            while not self.corrupt:
                # noinspection PyBroadException
                try:
                    video = cv2.VideoCapture(self.stream_url)
                    if video.isOpened():
                        log.warn(
                            f'VideoSource [{self.video_source_id}] - connect successfully, streaming'
                        )
                        self._notify_listener(VideoSourceStt.Running)
                        self.stt = VideoSourceStt.Running
                        break

                except BaseException:
                    pass

                if not self.auto_retry:
                    log.warn(
                        f'VideoSource [{self.video_source_id}] - connect failed, stopped'
                    )
                    self._notify_listener(VideoSourceStt.Stopped)
                    self.stt = VideoSourceStt.Stopped
                    break

                if self.stt is not VideoSourceStt.Retrying:
                    self.stt = VideoSourceStt.Retrying

                log.warn(
                    f'VideoSource [{self.video_source_id}] - connect failed')
                self._notify_listener(VideoSourceStt.Stopped)
                time.sleep(3)
                log.warn(
                    f'VideoSource [{self.video_source_id}] - retry connect')

            return video