Way to play video files in Tkinter?
Is there a way to play video files like AVI, MP4, etc.?
I tried using PyMedia, but apparently it only works with Pygame开发者_如何学JAVA.
What is the solution to my problem?
You could use python-gstreamer
for playing videos (this works for me on Linux, but it should also work on Windows). This requires python-gstreamer
and python-gobject
, I would recommend you to use this all-in-one installer.
Here is the code:
import os
import sys
import Tkinter as tkinter
import gobject
import gst
def on_sync_message(bus, message, window_id):
if not message.structure is None:
if message.structure.get_name() == 'prepare-xwindow-id':
image_sink = message.src
image_sink.set_property('force-aspect-ratio', True)
image_sink.set_xwindow_id(window_id)
gobject.threads_init()
window = tkinter.Tk()
window.geometry('500x400')
video = tkinter.Frame(window, bg='#000000')
video.pack(side=tkinter.BOTTOM,anchor=tkinter.S,expand=tkinter.YES,fill=tkinter.BOTH)
window_id = video.winfo_id()
player = gst.element_factory_make('playbin2', 'player')
player.set_property('video-sink', None)
player.set_property('uri', 'file://%s' % (os.path.abspath(sys.argv[1])))
player.set_state(gst.STATE_PLAYING)
bus = player.get_bus()
bus.add_signal_watch()
bus.enable_sync_message_emission()
bus.connect('sync-message::element', on_sync_message, window_id)
window.mainloop()
The following code works for me with GStreamer 1.0 and Python 3 under Ubuntu 16.04. It also enables eight video players stacked in a column in a single window. (The sound channels are simply mixed together.)
The libav/ffmpeg fork created problems under Ubuntu 14.04, which seem to be solved under 16.04. Note that you need the package gstreamer1.0-libav in addition to gstreamer1.0-plugins-*.
The code builds on the 2011 answer by @koehlma, which assumed GStreamer 0.10 and Python 2.
import sys
import os
if sys.version_info[0] < 3:
import Tkinter as tkinter
else:
import tkinter
import gi
gi.require_version('Gst', '1.0')
from gi.repository import Gst, GObject
# Needed for set_window_handle():
gi.require_version('GstVideo', '1.0')
from gi.repository import GstVideo
def set_frame_handle(bus, message, frame_id):
if not message.get_structure() is None:
if message.get_structure().get_name() == 'prepare-window-handle':
display_frame = message.src
display_frame.set_property('force-aspect-ratio', True)
display_frame.set_window_handle(frame_id)
NUMBER_OF_FRAMES = 8 # with more frames than arguments, videos are repeated
relative_height = 1 / float(NUMBER_OF_FRAMES)
# Only argument number checked, not validity.
number_of_file_names_given = len(sys.argv) - 1
if number_of_file_names_given < 1:
print('Give at least one video file name.')
sys.exit()
if number_of_file_names_given < NUMBER_OF_FRAMES:
print('Up to', NUMBER_OF_FRAMES, 'video file names can be given.')
file_names = list()
for index in range(number_of_file_names_given):
file_names.append(sys.argv[index + 1])
window = tkinter.Tk()
window.title("Multiple videos in a column using Tk and GST 1.0")
window.geometry('480x960')
Gst.init(None)
GObject.threads_init()
for number in range(NUMBER_OF_FRAMES):
display_frame = tkinter.Frame(window, bg='')
relative_y = number * relative_height
display_frame.place(relx = 0, rely = relative_y,
anchor = tkinter.NW, relwidth = 1, relheight = relative_height)
frame_id = display_frame.winfo_id()
player = Gst.ElementFactory.make('playbin', None)
fullname = os.path.abspath(file_names[number % len(file_names)])
player.set_property('uri', 'file://%s' % fullname)
player.set_state(Gst.State.PLAYING)
bus = player.get_bus()
bus.enable_sync_message_emission()
bus.connect('sync-message::element', set_frame_handle, frame_id)
window.mainloop()
Make use of tkvideoplayer
version>=2.0.0 library, which can help you to play, pause, seek, get metadata of the video etc.
pip install tkvideoplayer
Sample example:
import tkinter as tk
from tkVideoPlayer import TkinterVideo
root = tk.Tk()
videoplayer = TkinterVideo(master=root, scaled=True)
videoplayer.load(r"samplevideo.mp4")
videoplayer.pack(expand=True, fill="both")
videoplayer.play() # play the video
root.mainloop()
An example to create a complete video player is in the GitHub page
Refer documentation
Tha easy way is by using tkVideo
to install it
pip install tkVideo
this is script that show you how does it work easily!
from tkinter import *
from tkvideo import tkvideo
root = Tk()
my_label = Label(root)
my_label.pack()
player = tkvideo("C:\\path\\to\\video.mp4", my_label, loop = 1, size = (1280,720))
player.play()
root.mainloop()
this is PyPI link to it for more informations.
koehlma's answer is quite outdated. The "Tkinter" should be "tkinter"; "gst" should "Gst"; "playbin2" should be "playbin". "STATE_PLAYING" should be "State.PLAYING". The below setup and codes works on Debian 11 as of Apr 5, 2022.
First of all, the packages you need to install are
apt install python3-gi python3-gst-1.0 python3-tk
And the code should be updated to:
import os
import sys
import tkinter as tkinter
import gi
gi.require_version('Gst', '1.0')
from gi.repository import Gst as gst
from gi.repository import GObject as gobject
def on_sync_message(bus, message, window_id):
return
# message does not have structure field any more.
if not message.structure is None:
if message.structure.get_name() == 'prepare-xwindow-id':
image_sink = message.src
image_sink.set_property('force-aspect-ratio', True)
image_sink.set_xwindow_id(window_id)
gobject.threads_init()
window = tkinter.Tk()
window.geometry('500x400')
video = tkinter.Frame(window, bg='#000000')
video.pack(side=tkinter.BOTTOM,anchor=tkinter.S,expand=tkinter.YES,fill=tkinter.BOTH)
window_id = video.winfo_id()
gst.init(None)
player = gst.ElementFactory.make('playbin', 'player')
player.set_property('video-sink', None)
player.set_property('uri', 'file://%s' % (os.path.abspath(sys.argv[1])))
player.set_state(gst.State.PLAYING)
bus = player.get_bus()
bus.add_signal_watch()
bus.enable_sync_message_emission()
bus.connect('sync-message::element', on_sync_message, window_id)
window.mainloop()
I've recently made a package to do this, borderless video player. It also plays audio in sync.
pip install bvPlayer
The code:
from bvPlayer import bvPlayer
bvPlayer("file.mp4")
The repository
精彩评论