我正在尝试同时读取三个摄像机,其中一个是通过视频采集卡完成的。我希望能够流式传输数据并从这些来源写出视频。我使用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)