In this tutorial, we’ll build a video player application with Tkinter, leveraging the power of the VLC media player through the python-vlc library. Although Tkinter doesn’t provide a built-in widget for video playback, combining it with VLC lets you create a fully functional video player with a simple graphical interface.
This combination is actually super incredible, because using VLC as the video player means you get all the cool features that the highly powerful and mature VLC platform has. This includes things like RTSP stream support, HLS stream support, buffering, syncing mechanisms, etc.
Prerequisites
Before you begin, make sure you have the following installed on your system:
- Python 3
- Tkinter: Typically bundled with Python.
- VLC Media Player: Download and install it from videolan.org.
- python-vlc: Install via pip:
Linux Users, be warned! Do not install VLC using snap if you want this code to work. This is because snap installs VLC in an isolated environment. Whereas Python requires access to the VLC installation for a certain DLL. Installing VLC using snap prevents Python from being able to access that DLL.
Step-by-Step Code Explanation
We’ll explain the code, one snippet at a time. Let’s start with the main Tkinter process creation code.
import tkinter as tk
from tkinter import filedialog
import vlc
import sys
class VideoPlayer:
def __init__(self, root):
pass
if __name__ == "__main__":
root = tk.Tk()
root.geometry("800x600")
player = VideoPlayer(root)
root.mainloop()
Now let’s work on populating our VideoPlayer
class by defining the __init__
method.
class VideoPlayer:
def __init__(self, root):
self.root = root
self.root.title("Tkinter VLC Video Player")
# Create a VLC instance and a media player.
self.instance = vlc.Instance()
self.player = self.instance.media_player_new()
# Create the video panel, which will display the video.
self.video_panel = tk.Frame(root, bg="black")
self.video_panel.pack(fill=tk.BOTH, expand=1)
# Create the control panel with playback buttons.
self.controls = tk.Frame(root)
self.controls.pack(fill=tk.X, padx=10, pady=5)
# Open file button.
self.open_button = tk.Button(self.controls, text="Open", command=self.open_file)
self.open_button.pack(side=tk.LEFT, padx=5)
# Play button.
self.play_button = tk.Button(self.controls, text="Play", command=self.play_video)
self.play_button.pack(side=tk.LEFT, padx=5)
# Pause button.
self.pause_button = tk.Button(self.controls, text="Pause", command=self.pause_video)
self.pause_button.pack(side=tk.LEFT, padx=5)
# Stop button.
self.stop_button = tk.Button(self.controls, text="Stop", command=self.stop_video)
self.stop_button.pack(side=tk.LEFT, padx=5)
The __init__
method sets up the foundation of the video player. First, it receives the Tkinter root window and configures it with a title. Next, it creates a VLC instance and a media player object, which will handle all video playback tasks. The method then constructs a dedicated video panel using a Tkinter Frame
with a black background, providing a canvas where the video output will be embedded.
Additionally, a control panel is created to hold the playback buttons—Open, Play, Pause, and Stop. Each button is configured with a command that links to a corresponding method in the class, ensuring that user interactions trigger the correct functionality.
def open_file(self):
"""
This function opens a file dialog for the user to select a video file.
It then creates a new VLC media object from the selected file and sets it
to the VLC media player instance. Finally, it calls the method to embed
the VLC video output into the Tkinter video panel.
"""
self.filename = filedialog.askopenfilename(
title="Select a Video File",
filetypes=[("Video files", "*.mp4;*.avi;*.mkv;*.mov"), ("All files", "*.*")]
)
if self.filename:
media = self.instance.media_new(self.filename)
self.player.set_media(media)
self.set_video_panel()
The open_file
function is responsible for letting the user select a video file from their system. When the user clicks the “Open” button, this function launches a file dialog (using filedialog.askopenfilename
) that filters for common video formats such as MP4, AVI, MKV, and MOV.
Once the user selects a file, the function creates a new VLC media object from the file path and assigns it to the media player. It then calls the set_video_panel
method to ensure that the video output is rendered inside the Tkinter video panel.
def set_video_panel(self):
"""
This function embeds the VLC player's video output into the Tkinter video panel.
It retrieves the window ID of the video panel and then assigns it to the VLC media player
using platform-specific methods:
- On Linux, it uses set_xwindow.
- On Windows, it uses set_hwnd.
- On macOS, it uses set_nsobject.
This ensures that the video is rendered within the Tkinter frame regardless of the OS.
"""
if sys.platform.startswith("linux"):
self.player.set_xwindow(self.video_panel.winfo_id())
elif sys.platform == "win32":
self.player.set_hwnd(self.video_panel.winfo_id())
elif sys.platform == "darwin":
self.player.set_nsobject(self.video_panel.winfo_id())
Embedding the VLC player’s output into the Tkinter frame is handled by the set_video_panel
method. This function fetches the window ID of the Tkinter video panel and then links it with the VLC media player.
Because different operating systems require different methods for embedding, the method checks the platform using sys.platform
and calls the appropriate function: set_xwindow
for Linux, set_hwnd
for Windows, and set_nsobject
for macOS. This cross-platform approach ensures that the video is properly displayed within the application regardless of the OS.
def play_video(self):
"""
The play_video function starts the video playback by calling the VLC media player’s
play method. Once the media is loaded via the open_file function, clicking the Play
button will trigger this function to begin playback.
"""
self.player.play()
The play_video
function is straightforward—it simply calls the VLC media player’s play
method to start video playback. When the user clicks the “Play” button, this method gets invoked, and the currently loaded video begins playing.
def pause_video(self):
"""
The pause_video function toggles the current playback state. If the video is playing,
it pauses the playback; if it's paused, it resumes playing.
"""
self.player.pause()
For toggling playback, the pause_video
method is used. This function calls the VLC media player’s pause
method, which either pauses the video if it is currently playing or resumes it if it is paused. This toggle behavior is typical for video players, offering a simple way for users to manage playback without needing separate pause and resume controls.
def stop_video(self):
"""
The stop_video function stops the video playback completely and resets the playback state.
"""
self.player.stop()
Finally, the stop_video
method stops the video playback entirely by invoking the VLC media player’s stop
method. This resets the playback state and ensures that the video halts immediately. This function is bound to the “Stop” button, giving users a clear way to exit the video playback mode.
Here’s a look at our completed player:

The Complete Code
The complete code, for your copy-pasting pleasure. We’ve even added some additional functionality in the form of a progress slider and volume control slider. Run the code to see the results!
import tkinter as tk
from tkinter import filedialog
import vlc
import sys
class VideoPlayer:
def __init__(self, root):
self.root = root
self.root.title("Tkinter VLC Video Player")
# Create a VLC instance and media player.
self.instance = vlc.Instance()
self.player = self.instance.media_player_new()
# Create the video panel where the video will be displayed.
self.video_panel = tk.Frame(root, bg="black")
self.video_panel.pack(fill=tk.BOTH, expand=1)
# Create a progress frame that holds the progress slider.
self.progress_frame = tk.Frame(root)
self.progress_frame.pack(fill=tk.X, padx=10, pady=5)
# Create the progress slider.
# This slider's range will be updated dynamically to match the video's duration.
self.progress_slider = tk.Scale(
self.progress_frame, from_=0, to=100,
orient=tk.HORIZONTAL, showvalue=0, length=600
)
self.progress_slider.pack(fill=tk.X)
self.progress_slider.bind("<ButtonPress-1>", self.on_slider_press)
self.progress_slider.bind("<ButtonRelease-1>", self.on_slider_release)
self.slider_dragging = False
# Create the control panel with playback buttons and volume control.
self.controls = tk.Frame(root)
self.controls.pack(fill=tk.X, padx=10, pady=5)
# Open file button.
self.open_button = tk.Button(self.controls, text="Open", command=self.open_file)
self.open_button.pack(side=tk.LEFT, padx=5)
# Play button.
self.play_button = tk.Button(self.controls, text="Play", command=self.play_video)
self.play_button.pack(side=tk.LEFT, padx=5)
# Pause button.
self.pause_button = tk.Button(self.controls, text="Pause", command=self.pause_video)
self.pause_button.pack(side=tk.LEFT, padx=5)
# Stop button.
self.stop_button = tk.Button(self.controls, text="Stop", command=self.stop_video)
self.stop_button.pack(side=tk.LEFT, padx=5)
# Volume control slider.
# This slider controls the player's volume in real time.
self.volume_slider = tk.Scale(
self.controls, from_=0, to=100,
orient=tk.HORIZONTAL, label="Volume",
command=self.set_volume
)
self.volume_slider.set(50) # Set the default volume to 50%
self.volume_slider.pack(side=tk.LEFT, padx=5)
# Begin updating the progress slider periodically.
self.update_progress()
def open_file(self):
"""
This function opens a file dialog for the user to select a video file.
It then creates a new VLC media object from the selected file and sets it
to the VLC media player instance. Finally, it calls the method to embed
the VLC video output into the Tkinter video panel.
"""
self.filename = filedialog.askopenfilename(
title="Select a Video File",
filetypes=[("Video files", "*.mp4;*.avi;*.mkv;*.mov"), ("All files", "*.*")]
)
if self.filename:
media = self.instance.media_new(self.filename)
self.player.set_media(media)
self.set_video_panel()
def set_video_panel(self):
"""
This function embeds the VLC player's video output into the Tkinter video panel.
It retrieves the window ID of the video panel and then assigns it to the VLC media player
using platform-specific methods:
- On Linux, it uses set_xwindow.
- On Windows, it uses set_hwnd.
- On macOS, it uses set_nsobject.
This ensures that the video is rendered within the Tkinter frame regardless of the OS.
"""
if sys.platform.startswith("linux"):
self.player.set_xwindow(self.video_panel.winfo_id())
elif sys.platform == "win32":
self.player.set_hwnd(self.video_panel.winfo_id())
elif sys.platform == "darwin":
self.player.set_nsobject(self.video_panel.winfo_id())
def play_video(self):
"""
Once the media is loaded via the open_file function, clicking the Play button
will trigger this function to begin playback.
"""
self.player.play()
def pause_video(self):
"""
The pause_video function toggles the current playback state. If the video is playing,
it pauses the playback; if it's paused, it resumes playing.
"""
self.player.pause()
def stop_video(self):
"""
The stop_video function stops the video playback completely and resets the playback state.
"""
self.player.stop()
def set_volume(self, value):
"""
Adjusts the player's volume.
This function is triggered whenever the volume slider is moved.
"""
self.player.audio_set_volume(int(value))
def on_slider_press(self, event):
"""
Triggered when the user begins dragging the progress slider.
This sets a flag indicating manual adjustment is in progress,
preventing automatic updates from interfering.
"""
self.slider_dragging = True
def on_slider_release(self, event):
"""
Triggered when the user releases the progress slider.
It resets the dragging flag and seeks the video to the slider's position.
"""
self.slider_dragging = False
self.seek_video()
def seek_video(self):
"""
Seeks the video to a new position based on the slider's value.
The slider's value represents the time in milliseconds.
"""
slider_value = self.progress_slider.get()
self.player.set_time(int(slider_value))
def update_progress(self):
"""
Updates the progress slider to reflect the current playback time.
If the slider is not being manually adjusted by the user,
this function retrieves the current playback time and the video's total length,
updates the slider's range if necessary, and sets the slider to the current time.
This function is called repeatedly every 500 milliseconds.
"""
if not self.slider_dragging:
current_time = self.player.get_time() # Current time in milliseconds.
duration = self.player.get_length() # Total duration in milliseconds.
if duration > 0:
self.progress_slider.config(to=duration)
self.progress_slider.set(current_time)
self.root.after(500, self.update_progress)
if __name__ == "__main__":
root = tk.Tk()
root.geometry("800x600")
player = VideoPlayer(root)
root.mainloop()
By following this tutorial, you’ve learned how to integrate the python-vlc library with Tkinter to build a simple yet powerful video player. You can expand this player by adding extra features like a playlist, fast forward and backwards control, skip button, and much much more.