0

I have a python project that reads frames from a ip_camera and writes it in a .avi video, but its size is becomes too large for example a 1 min record has a size about 200 MB. I want to reduce the video bitrate to reduce the size at same time that the video is being written. I tried so many ways but none of them worked out. Here is my code:

import os
from threading import Thread
import cv2


class VideoCamera(object):
    def __init__(self, src=''):
        self.capture = cv2.VideoCapture(src)
        self.status = False
        self.frame = self.capture.read()
        self.frame_width = int(self.capture.get(3))
        self.frame_height = int(self.capture.get(4))
        self.codec = cv2.VideoWriter_fourcc(*'MJPG')
        self.video_name = "video.avi"
        self.output_video = cv2.VideoWriter(
            self.video_name,
            self.codec, 5,
            (self.frame_width, self.frame_height))
        self.stream_thread = Thread(target=self.update, args=())
        self.record_thread = Thread(target=self.record, args=())
        self.stream_thread.daemon = True
        self.stream_thread.start()

    def update(self):
        while True:
            if self.capture.isOpened():
                (self.status, self.frame) = self.capture.read()

    def record(self):
        print('schedule')
        while True:
            print('stop recording')
            self.capture.release()
            self.output_video.release()
            cv2.destroyAllWindows()
            break
            try:
                if self.status:
                    self.output_video.write(self.frame)
            except AttributeError:
                pass


    def start_recording(self):
        self.record_thread.start()


if __name__ == '__main__':
    cam = VideoCamera('rtsp://<username>:<password>@<camera_ip>:<camera_port>')
    cam.start_recording()
Christoph Rackwitz
  • 11,317
  • 4
  • 27
  • 36
  • 1
    That's less than 700k bytes per frame. You need to be realistic. Plus, you can't affect the bit rate with MJPG. MJPG is nothing more than a series of JPEG images. If your camera shows a static image much of the time, then you should switch to MPEG4 or H264, which does interframe compression. – Tim Roberts May 11 '21 at 18:29
  • you may try to use `self.output_video.set(...)` to set some parameters - but only information about parameters I found in documentation for `C/C++` version - [VideoWriterProperties](https://docs.opencv.org/3.4/d4/d15/group__videoio__flags__base.html#ga41c5cfa7859ae542b71b1d33bbd4d2b4) and [Additional flags for video I/O API backends](https://docs.opencv.org/3.4/dc/dfc/group__videoio__flags__others.html). Doc for [set()](https://docs.opencv.org/3.4/dd/d9e/classcv_1_1VideoWriter.html#a7ba668f440d8af5e1a92df58b2475816) – furas May 11 '21 at 18:58
  • @TimRoberts Thank you so much you helped me a lot. I've been looking for this issue for three days and I just changed the fourcc codec to `*'MP4V'` and it solved my problem. Thanks again. – Mohammad Hakimi May 12 '21 at 08:55
  • I've investigated OpenCV's builtin MJPEG encoder, which you get if you ask for `apiPreference=cv.CAP_OPENCV_MJPEG`. there is `VIDEOWRITER_PROP_QUALITY` (range 0 to 100) and it affects bitrate somewhat. -- OpenCV is really not the best choice for writing videos. its facility is just a convenience. recently it's been given some hardware acceleration for decoding (and encoding?) that is not yet documented extensively. it basically exposes all possible ffmpeg options. – Christoph Rackwitz Jul 31 '22 at 00:34
  • @ChristophRackwitz Thanks for your comment. What is your suggestion to write a video like that? I've been using ffmpeg but it uses a lot of RAM to load its libraries and if I wanna use multiple video writing concurrently it would cause lack of memory problems – Mohammad Hakimi Aug 01 '22 at 06:26
  • everything's a tradeoff. OpenCV's built-in MJPEG maybe uses fewer resources, and MJPEG itself has some advantages, but it also uses a lot of storage. if you need ffmpeg, for the selection of codecs you desire, there's no way around it. OpenCV has recently gained the ability to make ffmpeg use hardware acceleration, meaning less work for the CPU, so that's a plus. – Christoph Rackwitz Aug 01 '22 at 08:04

0 Answers0