Я создаю графический интерфейс для воспроизведения видеофайлов.Проблема в том, что когда я приостанавливаю видео, кнопка «Воспроизведение» не может повторно воспроизвести это видео, и мне приходится снова выбирать видеофайл.
Примечание. Поскольку я хочу показать видео в том же окне tkinter, я не использую команду OpenCV imshow.Вместо этого я использую метод "window.after".
Ниже приведен мой код:
Я пытаюсь использовать переменную «self.pause» для контроля состояния паузы.Когда я нажимаю кнопку Пауза, эта логическая переменная становится Истиной.Однако я не смог найти подходящего места, чтобы сделать его ложным, когда я снова нажму кнопку «Воспроизвести».
from tkinter import *
from tkinter import messagebox
from tkinter import filedialog
import PIL.Image, PIL.ImageTk
import cv2
class videoGUI:
def __init__(self, window, window_title):
self.window = window
self.window.title(window_title)
top_frame = Frame(self.window)
top_frame.pack(side=TOP, pady=5)
bottom_frame = Frame(self.window)
bottom_frame.pack(side=BOTTOM, pady=5)
self.pause = False # Parameter that controls pause button
self.canvas = Canvas(top_frame)
self.canvas.pack()
# Select Button
self.btn_select=Button(bottom_frame, text="Select video file", width=15, command=self.open_file)
self.btn_select.grid(row=0, column=0)
# Play Button
self.btn_play=Button(bottom_frame, text="Play", width=15, command=self.play_video)
self.btn_play.grid(row=0, column=1)
# Pause Button
self.btn_pause=Button(bottom_frame, text="Pause", width=15, command=self.pause_video)
self.btn_pause.grid(row=0, column=2)
self.delay = 15 # ms
self.window.mainloop()
def open_file(self):
self.pause = False
self.filename = filedialog.askopenfilename(title="Select file", filetypes=(("MP4 files", "*.mp4"),
("WMV files", "*.wmv"), ("AVI files", "*.avi")))
print(self.filename)
# Open the video file
self.cap = cv2.VideoCapture(self.filename)
self.width = self.cap.get(cv2.CAP_PROP_FRAME_WIDTH)
self.height = self.cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
self.canvas.config(width = self.width, height = self.height)
def get_frame(self): # get only one frame
try:
if self.cap.isOpened():
ret, frame = self.cap.read()
return (ret, cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
except:
messagebox.showerror(title='Video file not found', message='Please select a video file.')
def play_video(self):
# Get a frame from the video source, and go to the next frame automatically
ret, frame = self.get_frame()
if ret:
self.photo = PIL.ImageTk.PhotoImage(image = PIL.Image.fromarray(frame))
self.canvas.create_image(0, 0, image = self.photo, anchor = NW)
if not self.pause:
self.window.after(self.delay, self.play_video)
def pause_video(self):
self.pause = True
# Release the video source when the object is destroyed
def __del__(self):
if self.cap.isOpened():
self.cap.release()
##### End Class #####
# Create a window and pass it to videoGUI Class
videoGUI(Tk(), "EnJapan")
Если я напишу следующий код в функции play_video:
self.pause = False
Кнопка паузы не будет работать.Потому что метод «window.after» автоматически вызывает функцию «play_video» и делает «self.pause» ложным.Поэтому кнопка Пауза не будет иметь никакого эффекта.