如何用ffmpeg匹配opencv的视频比特率?

时间:2019-04-24 10:03:58

标签: python multithreading opencv ffmpeg

我正在尝试同时读取三个摄像机,其中一个是通过视频采集卡完成的。我希望能够流式传输数据并从这些来源写出视频。我使用FFmpeg从普通USB摄像机的视频采集卡和OpenCV写入器中写入数据。但是文件的比特率不匹配,大小也不匹配。当我对文件进行后处理时,这成为一个问题。我稍后尝试使用FFmpeg转换OpenCV写入的文件,但文件的持续时间仍然保持不同,尽管比特率已更改。我真的很希望能从脚本本身知道如何进行操作的指针。理想的情况是,我将FFmpeg用于具有相同设置的所有三个源。但是,由于必须同时写出三个源,因此如何在不写出控制台的所有信息的情况下做到这一点呢?有人可以告诉我如何使用OpenCV在流式传输视频时如何使用多个FFmpeg线程写文件吗?

我将我当前的代码与OpenCV writer和FFmpeg附加为一个来源:

from threading import Thread
import cv2
import time
import sys
import subprocess as sp
import os
import datetime
old_stdout=sys.stdout



maindir= "E:/Trial1/"
os.chdir(maindir)
maindir=os.getcwd()

class VideoWriterWidget(object):
    def __init__(self, video_file_name, src=0):
        if (src==3):
            self.frame_name= "Cam_"+str(src)+"(Right)"
        if(src==2):
            self.frame_name= "Cam_"+str(src)+"(Left)" 
        # Create a VideoCapture object
        #self.frame_name =str(src)
        self.video_file = video_file_name+"_"
        self.now=datetime.datetime.now()
        self.ts=datetime.datetime.now()
        self.video_file_nameE="{}.avi".format("Endo_"+self.ts.strftime("%Y%m%d_%H-%M-%S"))
        self.video_file_name = "{}.avi".format(video_file_name+self.ts.strftime("%Y%m%d_%H-%M-%S"))
        self.FFMPEG_BIN = "C:/ffmpeg/bin/ffmpeg.exe"
        self.command=[self.FFMPEG_BIN,'-y','-f','dshow','-rtbufsize','1024M','-video_size','640x480','-i', 'video=Datapath VisionAV Video 01','-pix_fmt', 'bgr24', '-r','60', self.video_file_name]
        self.capture = cv2.VideoCapture(src)

        # Default resolutions of the frame are obtained (system dependent)

        self.frame_width = int(self.capture.get(3))#480
        self.frame_height = int(self.capture.get(4))# 640


        # Set up codec and output video settings
        if(src==2 or src==3):
            self.codec = cv2.VideoWriter_fourcc('M','J','P','G')
            self.output_video = cv2.VideoWriter(self.video_file_name, self.codec, 30, (self.frame_width, self.frame_height))

        # Start the thread to read frames from the video stream
            self.thread = Thread(target=self.update, args=(src,))
            self.thread.daemon = True
            self.thread.start()

        # Start another thread to show/save frames
            self.start_recording()
            print('initialized {}'.format(self.video_file))

        if (src==0):
            self.e_recording_thread = Thread(target=self.endo_recording_thread, args=())
            self.e_recording_thread.daemon = True
            self.e_recording_thread.start() 
            print('initialized endo recording')


    def update(self,src):
        # Read the next frame from the stream in a different thread
        while True:
            if self.capture.isOpened():
                (self.status, self.frame) = self.capture.read()
                if (src==3):
                    self.frame= cv2.flip(self.frame,-1) 


    def show_frame(self):
        # Display frames in main program
        if self.status:
            cv2.namedWindow(self.frame_name, cv2.WINDOW_NORMAL)
            cv2.imshow(self.frame_name, self.frame)


        # Press Q on keyboard to stop recording0000
        key = cv2.waitKey(1)
        if key == ord('q'):#
            self.capture.release()
            self.output_video.release()
            cv2.destroyAllWindows()
            exit(1)

    def save_frame(self):
        # Save obtained frame into video output file
        self.output_video.write(self.frame)

    def start_recording(self):
        # Create another thread to show/save frames
        def start_recording_thread():
            while True:
                try:
                    self.show_frame()
                    self.save_frame()
                except AttributeError:
                    pass
        self.recording_thread = Thread(target=start_recording_thread, args=())
        self.recording_thread.daemon = True
        self.recording_thread.start()

    def endo_recording_thread(self):
         self.Pr1=sp.call(self.command)



if __name__ == '__main__':
    src1 = 'Your link1'
    video_writer_widget1 = VideoWriterWidget('Endo_', 0)
    src2 = 'Your link2'
    video_writer_widget2 = VideoWriterWidget('Camera2_', 2)
    src3 = 'Your link3'
    video_writer_widget3 = VideoWriterWidget('Camera3_', 3)

    # Since each video player is in its own thread, we need to keep the main thread alive.
    # Keep spinning using time.sleep() so the background threads keep running
    # Threads are set to daemon=True so they will automatically die 
    # when the main thread dies
    while True:
      time.sleep(5)

0 个答案:

没有答案