I have been looking for a good way to embed vlc in a python tkinter frame.

I found a script on stackexchange that does the basic work, but - to embed the vlc in a frame - the script relies upon an oop technique I have asked about before but never been able to figure out.

In its original state the script didnt have any controls. It just played the video according to the default settings of the video. Consequently, the videos dimensions can open up huge, out of time, and one is unable to stop or pause playback, and even closing a video out is pain in the butt.

Anyway, I advanced the script by writing in some dimensions to play at a reasonable size, and I added in some tkinter buttons and defs where I want it to pause, resume, stop, etc... And I researched the code enough to find the correct bindings... I just dont get how to actually set the bindings and get the buttons commands to call them...

The script is below. The buttons are supposed to show on the bottom but rest a bit high at the top; and the root.destroy is problematic because it only closes tkinter, not the vlc player (so the video will keep playing). The video will also autoplay. But the main problem is getting it to pause and resume. The code is below, and the bindings (which are not in tkinter, but only vlc) are below the code.

The parameter in the Pause / Resume binding is set to 1 to play and 0 to stop, as the original article explains.

Any help much appreciated!

    import tkinter as tk
    import vlc

    class Screen(tk.Frame):

        '''
        Screen widget: Embedded video player from local or youtube
        '''

        def __init__(self, parent, *args, **kwargs):
            tk.Frame.__init__(self, parent, bg='black')
            self.parent = parent
            # Creating VLC player
            self.instance = vlc.Instance()
            self.player = self.instance.media_player_new()

        def GetHandle(self):
            # Getting frame ID
            return self.winfo_id()

        def play(self, _source):
            # Function to start player from given source
            Media = self.instance.media_new(_source)
            Media.get_mrl()
            self.player.set_media(Media)

            self.player.set_hwnd(self.winfo_id())
            self.player.play()         

    ########################################################################        

    def start (): pass

    def pause (): pass

    def resume (): pass

    def stop (): pass

    def close (): pass  

    ########################################################################        

    url = r"C:\Users\whoever\Desktop\whatever.mp4"    # changeable

    root = tk.Tk()
    root.geometry("600x600+100+100")
    player = Screen(root)
    player.place(x=0, y=0, width=600, height=400)
    player.play(url)

    framed2 = tk.Frame(root)  

    k = tk.Button(framed2, text='Play', command=start)
    k.grid(row=0,column=1)

    l = tk.Button(framed2, text='Pause', command=pause)
    l.grid(row=0,column=2)

    m = tk.Button(framed2, text='Stop', command=stop)
    m.grid(row=0,column=3)

    n = tk.Button(framed2, text='Quit', command=root.destroy)
    n.grid(row=0,column=5)

    framed2.pack(padx=5, pady=4)

    root.mainloop()

###############################################################
https://www.geeksforgeeks.org/python-vlc-medialistplayer-pause-resume/?ref=rp

import vlc
import time
media_player = vlc.MediaListPlayer()
player = vlc.Instance()
media_list = player.media_list_new()
media = player.media_new(url)
media_list.add_media(media)
media_player.set_media_list(media_list)
media_player.play()
time.sleep(5)
media_player.set_pause(1) #<---------------------------------- PAUSE / RESUME BINDING
time.sleep(4)

Given the name of the object in line 48, wouldn't we use the following example line to pause?

# pausing the video
player.set_pause(1)

Sadly I can't find a good set of docs on this.

I think I misunderstood your question. Maybe you wanted to learn how to tie buttons to doing something in your code.

I see a close enough button and action in the Hello World at https://docs.python.org/3/library/tkinter.html

Remember I won't write your code for you but look closely at:

self.hi_there = tk.Button(self)
self.hi_there["text"] = "Hello World\n(click me)"
self.hi_there["command"] = self.say_hi`

The command there would be player.set_pause(1). I think you were trying to talk to VLC rather then use the python module vlc.

"Maybe you wanted to learn how to tie buttons to doing something in your code."

Yes, I think that "tie" is the right word. That is probably why they call them "bindings", if I have it right, and that is why I used the word bindings in the narrative of my OP.

I see a close enough button and action in the Hello World at https://docs.python.org/3/library/tkinter.html

That's a very good observation, and I am honestly very glad you pointed out that script.

But that is the problem, too!

Let me explain, please.

Look at the first lines of the class in the example.

class Application(tk.Frame):
    def __init__(self, master=None):
        super().__init__(master)
        self.master = master
        self.pack()

    self.create_widgets()

That is the part that confuses me.

You can see they passed a frame in. That seems to indicate "class Application(tk.Frame):" is a child class inheriting from the "root" parent class. What drives me nuts is - they are inheriting from a frame. Maybe it is no big deal, but usually we just inherit by using root. So, when they inherit by frame, I dont see why.

Remember I won't write your code for you but look closely at:

self.hi_there = tk.Button(self)
self.hi_there["text"] = "Hello World\n(click me)"
self.hi_there["command"] = self.say_hi

The command there would be player.set_pause(1). I think you were trying to talk to VLC rather then use the python module vlc.

I think that is what that bindings are for... that is to say, when you say I think you were trying to talk to VLC rather then use the python module vlc. what you mean by "talking to VLC" is to code the bindings into the child class that operate VLC... this would allow me to pause, resume, play, rewind, etc... that is what I am trying to figure out how to do... and, while I know the bindings, I dont know how to articulate them into the code yet...

You dont have to write the code for me, if you dont want. I cant make anyone do what they dont want to do.

But - as a side note - I am like a 52 y/o hobbyist, not a student, and I am not under any assignments or rules from a school or university. I dont see any problem with debugging each others code, unless it is against site policy. They debug each others code over at stackexchange and other sites, so my question seemed normal. In any case, I dont understand a lot of the logistics or reasonings behind debugging code online, but sometimes it seems done and sometimes not. I think it is mostly because a lot of kids are in school, and the teachers dont want them to plagiarize each others work.

That is not my point anyway. I dont like hacking. I/we often learn by hacking, but hacking is a pain in the butt when one doesnt understand what one is doing. What is better is to understand what one is doing. And I dont. I admittedly "hacked" here, but it is all open source material and I'm trying to learn. That's the problem. In other words, since I hacked the script, I dont understand it. The point of my query is not to repeat the same mistake, but to understand what I am doing. So if you can convince me of a solution as to why tk.frame is passed in as a parameter, then I dont need to hack - I can just figure it out.

I am speaking out of frustration, so please do not take this the wrong way. But if you review my other posts here, specifically "Adjustments to a Python Scipt", you'll see I have honestly been trying to figure this problem out for quite awhile.

https://www.daniweb.com/programming/code/534910/adjustment-to-a-python-script

Somehow I know what is supposed to happen.

Basically, the parent class is passed into the child class, and the child inherits all the properties and methods of the parent. But why a tk.frame? And how to relate (i.e. bind or tie) that to the properties and methods between the instances? Then I can use the bindings correctly to operate the playback of the video.

I appreciate and thank you for your help here. I apologize for being a bit grumpy about it. It's just I keep running into this problem (your script is the 5th example I have found so far), and it's driving me nuts.

Honstely, I think, once I figure it out with VLC - I will have it so fried into my memory I will understand it by rote after just reflecting upon it so much. But I am still not at that point inthe learning curve (for some reason).

As per hacking, it might be just as well to pay someone to fix it, then I'd probably understand it. But I wouldnt know who to trust and hire anyway.

I dont care. I just want to understand it.

Sorry to vent. Thank you again.

This is still incomplete, but it follows the example you sent. I am falling asleep, so I commented out the parts that dont work in order to resume tomorrow.

I still dont understand the mysterious transition that occurs from using tk.frame for the child class, but I wanted to post something to show I appreciated the info you provided in the exampl you sent.

So far in what is below - when I updated the script - I gained functional buttons, but I lost the VLC embedding. I think the problem is better positioned, however. When I wake up, if I can get the embed right, then the other binding commands should follow easy enough.

import tkinter as tk
import vlc
import time

class Application(tk.Frame):

    def __init__(self, master=None, *args, **kwargs):

        super().__init__(master)
        self.master = master
        self.pack()
        self.create_widgets()

    def GetHandle(self):

        return self.winfo_id()


    def create_widgets(self):

        self.instance = vlc.Instance()
        self.player = self.instance.media_player_new()

        self.player.set_hwnd(self.winfo_id())
        self.player.play()              

        Media = self.instance.media_new(url)
        Media.get_mrl()

        self.player.set_media(Media)

        self.player.set_hwnd(self.winfo_id())
        self.player.play()       

        #def play(self, _source):
        #Function to start player from given source
        #Media = self.instance.media_new(_source)
        #Media.get_mrl()
        #self.player.set_media(Media)

        #self.player.set_hwnd(self.winfo_id())
        #self.player.play()              

        self.k = tk.Button(self, text='Play', command=self.start)
        self.k.pack(side="bottom")

        self.l = tk.Button(self, text='Pause', command=self.pause)
        self.l.pack(side="bottom")

        self.m = tk.Button(self, text='Stop', command=self.stop)
        self.m.pack(side="bottom")

        self.n = tk.Button(self, text='Quit', command=self.master.destroy)
        self.n.pack(side="bottom")  

    def stop(self): print ("connection to stop successful")

    def pause(self): print ("connection to pause successful")

    def start(self): print ("connection to start successful")

#####            

url = r"C:\Users\whoever\Desktop\whatever.mp4" # changeable

root = tk.Tk()
root.geometry("600x600+100+100")
app = Application(master=root)
app.place(x=0, y=0, width=600, height=400)
app.play(url)
app.mainloop()

I don't use tkinter. It is sadly out of date. Instead I use wxPython, a python wrapper for the wxwidgets tool set (a cross platform library that renders controls using the native OS). If you are interested I suggest you have a look at this article that I posted some time ago. It embeds VLC Media Player in a wxPython/Python application. The article is posted as a tutorial and includes all code necessary to run a small app. If you decide to go the wxPython route feel free to post questions.

While I am thinking about it, if you are doing Python development you might want to have a look at the free version of Wing Professional IDE. I recently started using it and find it much better than idle or idlex.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.