我有一個 python 應用程式,當我轉到某個相機頁面時,它有很多幀/頁面,我啟動相機,20 秒后我想關閉視頻錄制并開始在新檔案中錄制。基本上將錄音分成 20 秒的視頻。現在我有一個功能stop_20_seconds()函式,可以在 20 秒后停止錄制并重新開始。但現在我得到了多個檔案,沒有一個接一個地中斷 20 秒。
我的代碼
class FrontCameraPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.label = tk.Label(self, text="FRONT CAMERA", font=MediumFont, bg="white").grid(row=0, column=0, columnspan=2, sticky="nsew")
self.cameraFrame = tk.Frame(self, bg=gray)
self.cameraFrame.grid(row=1, column=0, sticky="nsew")
self.buttonFrame = tk.Frame(self, bg="white")
self.buttonFrame.grid(row=1, column=1, sticky="nsew", padx=(10, 0))
self.endTrip = tk.Button(self.buttonFrame, text="END TRIP", font=small_Font, bg=dark_blue, fg="White")
self.endTrip.grid(row=2, column=0, ipadx=10, pady=(0, 5))
self.endTrip['command'] = self.stop_capture
self.cancelButton = tk.Button(self.buttonFrame, text="Cancel", font=small_Font, bg=dark_blue, fg="white")
self.cancelButton.grid(row=3, column=0, ipadx=10)
self.cancelButton['command'] = lambda: controller.show_frame(changepage)
# setup callbacks for switching in and out events
self.bind('<<SwitchIn>>', self.start_capture)
self.bind('<<SwitchOut>>', self.stop_capture)
self.capture = None
self.lmain = tk.Label(self.cameraFrame)
self.lmain.pack()
def start_capture(self, event=None):
if self.capture is None:
#-----------------------------------
width, height = 200, 200
self.cap = cv2.VideoCapture(0)
self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, width)
self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
width = int(self.cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(self.cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
self.fourcc = cv2.VideoWriter_fourcc(*'XVID')
self.out = cv2.VideoWriter('output.avi', self.fourcc, 25, (width, height))
#-----------------------------------
self.timer =0
self.show_frame()
print('capture started')
def stop_capture(self, event=None):
if self.capture:
self.after_cancel(self.capture)
#-----------------------------------
self.cap.release()
self.out.release()
#------------------------------
self.capture = None
print('capture stopped')
def show_frame(self):
ret, frame = self.cap.read()
if ret:
self.out.write(frame)
frame = cv2.flip(frame, 1)
cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
img = Image.fromarray(cv2image)
self.imgtk = ImageTk.PhotoImage(image=img)
self.lmain.configure(image=self.imgtk)
self.stop20Sec = self.after(5000, self.stop_20_seconds)
self.capture = self.after(10, self.show_frame)
def stop_20_seconds(self):
self.timer = 1
self.out.release()
width = int(self.cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(self.cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
self.out = cv2.VideoWriter(f'{str(self.timer)}.avi', self.fourcc, 25, (width, height))
self.after_cancel(self.capture)
self.after_cancel(self.stop20Sec)
self.stop20Sec = None
self.capture = None
self.show_frame()
uj5u.com熱心網友回復:
其實你不需要stop_20_seconds()。只需在里面進行輸出檔案旋轉show_frame():
def start_capture(self, event=None):
if self.capture is None:
#-----------------------------------
width, height = 200, 200
self.cap = cv2.VideoCapture(0)
self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, width)
self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
# used instance variables for width and height
self.width = int(self.cap.get(cv2.CAP_PROP_FRAME_WIDTH))
self.height = int(self.cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
# initialize file rotation and frame counters
self.timer = 1 # file rotation counter
self.frames = 0 # frame counter
self.fourcc = cv2.VideoWriter_fourcc(*'XVID')
self.out = cv2.VideoWriter(f'{self.timer}.avi', self.fourcc, 25, (self.width, self.height))
#-----------------------------------
self.show_frame()
print('capture started')
...
def show_frame(self):
ret, frame = self.cap.read()
if ret:
self.out.write(frame)
self.frames = 1 # update frame counter
if self.frames >= 500: # reach 20 seconds (20x25 frames)
self.out.release() # close current output file
self.timer = 1 # update file rotation counter
self.out.open(f'{self.timer}.avi', self.fourcc, 25, (self.width, self.height))
self.frames = 0 # reset frame counter
frame = cv2.flip(frame, 1)
cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
img = Image.fromarray(cv2image)
self.imgtk = ImageTk.PhotoImage(image=img)
self.lmain.configure(image=self.imgtk)
self.capture = self.after(10, self.show_frame)
注:由于實際捕捉幀率與輸出幀率不同,每個視頻檔案中的實際時間段可能不是實時20秒。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/382339.html
