Как сопоставить битрейт видео opencv с ffmpeg? - PullRequest
0 голосов
/ 24 апреля 2019

Я пытаюсь прочитать три камеры одновременно, одна из которых выполняется через видеокарту. Я хочу иметь возможность передавать данные, а также записывать видео из этих источников. Я использовал FFmpeg для записи данных с карты видеозахвата и устройства записи OpenCV для обычных USB-камер. Но битрейт файлов не соответствует ни размеру. Это становится проблемой, когда я постобработаю файлы. Я позже попытался преобразовать записанные файлы OpenCV с помощью FFmpeg, но продолжительность файлов по-прежнему остается другой, хотя скорость передачи битов изменилась. Я бы очень хотел, чтобы указатели знали, как это сделать из самого сценария. В идеале я бы использовал FFmpeg для всех трех источников с одинаковыми настройками. Но как я могу сделать это, не выплевывая всю информацию на консоли в виде записи файлов, поскольку одновременно должно быть записано три источника? Может кто-нибудь сказать мне, как создать несколько потоков FFmpeg для записи файлов при потоковой передаче видео с использованием OpenCV?

Я приложил свой текущий код с помощью 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...