Video player by Python tkinter, When I pause video, I cannot re-play

后端 未结 4 1012
时光说笑
时光说笑 2021-01-19 05:06

I am creating GUI to play video files. The problem is that when I pause video, Play button cannot re-play that video, and I have to select video file again.

Note: S

相关标签:
4条回答
  • 2021-01-19 05:21

    Simply add in the play_video(self) method:

    if self.pause == True:
        self.pause = False
        return
     
    
    0 讨论(0)
  • 2021-01-19 05:27
    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)
    
            # Resume Button
            self.btn_resume=Button(bottom_frame, text="resume", width=15, command=self.resume_video)
            self.btn_resume.grid(row=0, column=3)
    
            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
    
    #Addition
        def resume_video(self):
            self.pause=False
            self.play_video()
    
    
        # 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")
    
    0 讨论(0)
  • 2021-01-19 05:44

    I would create another method for the play button callback. Something like this:

    def play_start(self):
        self.pause = False
        self.play_video()
    

    However, I would make sure you disable the play button if it's already playing. Otherwise, you could have multiple "instances" of play_video going if the play button is pressed multiple times.


    An alternative is to combine your play and pause button, so it toggles the value of self.pause. Then you could have just one button with one callback function.

    0 讨论(0)
  • 2021-01-19 05:46

    Question: Pause button will have no effect.

    Reference:

    • Tkinter.Widget.after-method - after(delay_ms, callback=None, *args)

      Registers an callback that is called after a given time.

    • Tkinter.Widget.after_cancel-method - after_cancel(id)

      Cancels an callback.


    To cancel the allready queued events for self.play_video change the following:

    def play_video(self):
        ...
    
        if self.pause:
            self.window.after_cancel(self.after_id)
        else:
            self.after_id = self.window.after(self.delay, self.play_video)
    
    0 讨论(0)
提交回复
热议问题