Search code examples
pythontkintermoviepy

How can I close a MoviePy Window that opens after clip.preview in e tkinter GUI?


I am developing a GUI application using Tkinter, where the user can click a button to start playing a video. I am using MoviePy to ensure that the video and audio play synchronously, but the issue I am facing is that the video opens in a separate window. This window does not close after the video ends, which prevents the user from interacting with the main GUI.

Here’s a simplified version of my code:

import tkinter as tk
from moviepy.editor import VideoFileClip

root = tk.Tk()
root.title()
root.attributes('-fullscreen', True)

# Function to play the video
def play_video():
    clip = VideoFileClip(video_path)  # Replace with your video path
    clip.preview()

play_button = tk.Button(root, text="Play", command=play_video)
play_button.pack(padx=50, pady=50)

root.mainloop()

Current Issue:

  • When the user clicks the "Play" button, the video plays in a new window. This window stays open after the video ends, preventing further interaction with the main GUI.

Goal:

I want to ensure that after the video is played, users can continue working in the GUI. This might be achieved in one of the following ways:

  • Play the video (including synchronized audio) directly within the Tkinter main window.
  • If the video must open in a separate window, have that window close automatically after the video is finished.
  • If neither of the above is possible, provide a seamless transition back to the main GUI.

Background:

  • I chose MoviePy to ensure audio synchronization, as I experienced issues with other libraries in the past (e.g. tkVideoPlayer, pygame, bvPlayer).
  • My implementation is in Python 3.8.

I appreciate any help or suggestions!


Solution

  • The preview() function does not include parameters to change this behavior.

    However, MoviePy uses PyGame internally, so it is possible to close the window once a video has finished using pygame.quit():

    import tkinter as tk
    import pygame
    from moviepy.editor import VideoFileClip
    
    root = tk.Tk()
    root.title()
    root.attributes('-fullscreen', True)
    
    # Function to play the video
    def play_video():
        clip = VideoFileClip(video_path)  # Replace with your video path
        clip.preview()
        pygame.quit()
    
    play_button = tk.Button(root, text="Play", command=play_video)
    play_button.pack(padx=50, pady=50)
    
    root.mainloop()