Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

What is the solution to my problem?

like image 358
P'sao Avatar asked Aug 29 '11 07:08

P'sao


People also ask

Can you play a video in tkinter?

This is a simple library to play video files in tkinter. This library also provides the ability to play, pause, skip and seek to specific timestamps.

Can tkinter play audio?

There are two modules to play sound with the help of tkinter python: pygame : It is a cross-platform module to create games and GUI's. playsound: It is a cross-platform module and its function name is playsound()


3 Answers

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()
like image 190
koehlma Avatar answered Oct 10 '22 20:10

koehlma


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()
like image 39
HendrikFrans Avatar answered Oct 10 '22 18:10

HendrikFrans


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.

like image 2
Shihab Avatar answered Oct 10 '22 19:10

Shihab