0

I'm trying to make a video based on an RTSP stream, opencv creates the file correctly, but when opencv saves frames in this file, the video file quickly shows frames in a short time. In my test, I record frames for 10 seconds, after that I stop recording, when I go to check the video file, what is displayed is a video with duration of 2 seconds, but all recorded frames are present in the file.

My thread to save frames

self.rec = False
self.thread = Thread(target=self.grava_frame, args=())
self.thread.daemon = True
self.thread.start()

def grava_frame(self):
        while True:
            if self.rec:
                #self.rec = False
                while not self.thread_end:
                    frame = cv2.cvtColor(self.resized_cropped, cv2.COLOR_RGB2BGR)
                    self.video_writer.write(frame)
                    cv2.waitKey(1)
                self.video_writer.release()

My thread to capture frames:

self.at_frame = Thread(target=self.atualiza_frame, args=())
        self.at_frame.daemon = True
        self.at_frame.start()
def atualiza_frame(self):
        ap = argparse.ArgumentParser()
        ap.add_argument("-v", "--video", required=True,
            help="rtsp://admin:@192.168.1.10:554/live/0/MAIN")
        args = vars(ap.parse_args())
        print("[INFO] starting video file thread...")
        fvs = FileVideoStream(args["video"]).start()
        time.sleep(1.0)
        # start the FPS timer
        fps = FPS().start()
        # loop over frames from the video file stream
        while fvs.more():
            frame = fvs.read()
            self.resized_cropped = cv2.resize(frame, (1024, 600))
            cv2.waitKey(1)
            fps.update()

This is the button that control de record:

def record_button(self):
        if self.is_recording_on:
            # inicia a gravação
            data = self.dataname()
            self.codec = cv2.VideoWriter_fourcc(*'mp4v')
            self.video_writer = cv2.VideoWriter(data+'.MP4', self.codec, 25, (self.frame_width, self.frame_height))
            self.thread_end = False
            self.rec = True

        else:
            # encerra a gravação
            self.rec = False
            self.thread_end = True

I suspect that my thread is writing frames too quickly, but I don't know how to solve this

EDIT: Based on the comments, i put a 'print("frame")' inside the 'while not self.thread_end'. I record a video during 5 seconds, and the output of 'frame' printed is: 30 print in 5 seconds of recording

  • Maybe your source video has a lower framerate than your output video. – Mark Setchell Jul 11 '23 at 20:31
  • If you set fps in VideoWriter to 5 instead of 25, your result video will be 5 times longer when you feed the same number of frames. Probably either your input has less than 25 fps or you are missing frames because your processing is too slow. – Micka Jul 11 '23 at 20:52
  • @MarkSetchell my stream has 25fps, equal to my output video – Jorge Augusto Wilchen Jul 12 '23 at 11:23
  • @Micka i test with 5fps, and the video file contain 24 seconds, for 10 seconds recording, i will test other frame rate's and return with the best fps as possible in few time – Jorge Augusto Wilchen Jul 12 '23 at 11:25
  • @Micka, I'm using openv's videowriter to save frames to a file. opencv allows me to pass a bulean value in the fps field, so a rate of 11.5fps made the file display time perfect, where 10 seconds of recording now generates a video file of 10 seconds in length. Please, add your comment to answers – Jorge Augusto Wilchen Jul 12 '23 at 12:03
  • I tested it again and the generated file had a different duration, this time, 5fps in the videowriter generated a 10 second file, but when recording for 1 minute, the generated file showed 1 minute and 32 seconds – Jorge Augusto Wilchen Jul 12 '23 at 13:00
  • Based on my edit, my problem probably is on my thread, so, how i can solve this? is a delay from opencv to save frames? or is my cpu? – Jorge Augusto Wilchen Jul 12 '23 at 14:06
  • Once you know how fast your device is for decoding, processing and videowriting (encoding and filewriting) such frames you can calculate the maximal achievable fps. Reduce it to make sure you can handle peaks. Then, of your video source is (temporarily) faster, drop franes. When your video source is (temporarily) slower: Duplicate frames. – Micka Jul 12 '23 at 19:57
  • So, how i can do this? Is a mathematical formula? If is, this not apply more delay on video writer? I know ther probally is a newbie question, but i'm recently start in programing, much more newbie in opencv – Jorge Augusto Wilchen Jul 13 '23 at 12:35

0 Answers0