Python Forum
mpv window freeze before video end
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
mpv window freeze before video end
#1
Hi all,
mostly new to python, certainly new to tkinter and mpv!

wrote a little python/tkinter script to select recorded mkv's (from motion) which then play via mpv. All works OK, but:
whether I select one or multiple video's, one of two things are a problem:
1- if I pause any video before end and try to close the player window, it freezes until I close the app from idle
2- if I select one mor multiple mkv's, then either play to end or go through selection process again (via Browse button), the app closes.
Here is the complete code:
#!/usr/bin/python3

import os
import shutil 
import tkinter as tk 
from tkinter import *
from tkinter import ttk
from tkinter import filedialog
from tkinter import messagebox
import webbrowser

if os.environ.get('DISPLAY','') == "":
    print('no display found.Using :0.0')
    os.environ.__setitem__('DISPLAY',':0.0')

##### MPV.py HAS TO BE copied into the directory which imports mpv  ######
import mpv
player = mpv.MPV(ytdl=True,input_default_bindings=True,input_vo_keyboard=True,osc=True)

root = tk.Tk()
root.title("Motion GUI")
root.minsize(width=1000, height=700)
root.maxsize(width=1400, height = 900)

mainframe = ttk.Frame(root, padding="3 3 12 12")
mainframe.grid(column=0, row=0, sticky=(N,W,E,S))
root.columnconfigure(0, weight=1)
root.rowconfigure(0,weight=1)

WidgetFrame = ttk.Frame(mainframe, borderwidth=2,relief='ridge',height = 60)
WidgetFrame.grid(column=0,row=0, sticky="E,W")

DisplayFrame = ttk.Frame(mainframe, borderwidth=1)
DisplayFrame.grid(column=0, row=1, sticky="E,W", rowspan=10)

StatusFrame = ttk.Frame(mainframe, borderwidth=1)
StatusFrame.grid(column=0,row=11, sticky="E,W")

root.geometry("830x420") 
root.title("View/Copy/Move mkv's") 
root.config(background = "gray")

def CreateWidgets():
    
    WidgetFrame.link_Label = Label(WidgetFrame, text ="Select File(s): ", bg = "#E8D579") 
    WidgetFrame.link_Label.grid(row = 1, column = 0, pady = 5, padx = 5) 
    
    #widget_frame.source_message = Entry(widgetFrame, text= " ")
    #widget_frame.source_message.grid(row = 1, column = 4,columnspan = 2)
     
    WidgetFrame.sourceText = Entry(WidgetFrame, width = 50, textvariable = sourceLocation) 
    WidgetFrame.sourceText.grid(row = 1, column = 1, pady = 5, padx = 5, columnspan = 2) 
     
    WidgetFrame.source_browseButton = Button(WidgetFrame, text ="Browse", command = SourceBrowse, width = 15) 
    WidgetFrame.source_browseButton.grid(row = 1, column = 3, pady = 5, padx = 5) 
     
    WidgetFrame.destinationLabel = Label(WidgetFrame, text ="Select The Destination : ", bg ="#E8D579") 
    WidgetFrame.destinationLabel.grid(row = 2, column = 0, pady = 5, padx = 5) 
     
    WidgetFrame.destinationText = Entry(WidgetFrame, width = 50, textvariable = destinationLocation) 
    WidgetFrame.destinationText.grid(row = 2, column = 1, pady = 5, padx = 5, columnspan = 2) 
     
    WidgetFrame.dest_browseButton = Button(WidgetFrame, text ="Browse", command = DestinationBrowse, width = 15) 
    WidgetFrame.dest_browseButton.grid(row = 2, column = 3, pady = 5, padx = 5) 

    WidgetFrame.viewButton = Button(WidgetFrame, text ="View File(s)", command = ViewFile, width = 15) 
    WidgetFrame.viewButton.grid(row = 3, column = 0, pady = 5, padx = 5) 
        
    WidgetFrame.copyButton = Button(WidgetFrame, text ="Copy File", command = CopyFile, width = 15) 
    WidgetFrame.copyButton.grid(row = 3, column = 1, pady = 5, padx = 5) 
     
    WidgetFrame.moveButton = Button(WidgetFrame, text ="Move File", command = MoveFile, width = 15) 
    WidgetFrame.moveButton.grid(row = 3, column = 2, pady = 5, padx = 5) 

    WidgetFrame.moveButton = Button(WidgetFrame, text ="Delete File(s)", command = DeleteFile, width = 15) 
    WidgetFrame.moveButton.grid(row = 3, column = 3, pady = 5, padx = 5)

    WidgetFrame.MotionButton = Button(WidgetFrame, text="IP Streams",command=MotionHTTP, font="LUCIDA 12")
    WidgetFrame.MotionButton.grid(row=3,column=5,pady=5,padx=5)
    
    WidgetFrame.exitButton = Button(WidgetFrame, text="Quit", command=root.destroy, font="LUCIDA 12 bold")
    WidgetFrame.exitButton.grid(row = 3, column = 6,pady = 5, padx = 5)
    
#destinationdirectory = '/home/rainer/Vids'

def MotionHTTP():
    webbrowser.open("http://<IP>:<port>")

def SourceBrowse(): 
    
    WidgetFrame.files_list = list(filedialog.askopenfilenames(initialdir ="/mnt/data/Motion_Data/Motion_Clips",title="Press shift key plus Left mouse click to select multiple files")) 
WidgetFrame.sourceText.insert() 
    WidgetFrame.sourceText.insert('1', WidgetFrame.files_list) 
     
def DestinationBrowse(): 

    destinationdirectory = filedialog.askdirectory(initialdir ="/mnt/data/Motion_Data/Motion_Clips") 
 
    WidgetFrame.destinationText.insert('1', destinationdirectory) 

def ViewFile_trial():
    files_list = WidgetFrame.files_list
    player.play(files_list)
    player.wait_for_pplayback()
    # messagebox.showinfo("Done")

def ViewFile():
    # plays all selected files one by one, keeps speed selected in 1st clip unless changed..
    files_list = WidgetFrame.files_list

     for f in files_list:
        player.playlist_append(f)

    player.playlist_pos = 0
    player.wait_for_playback
    
    #messagebox.showinfo("Done", "All files have been viewed") ## - ? for some reason, messagbox exits the program ?
        
def CopyFile(): 
    files_list = WidgetFrame.files_list 
     destination_location = destinationLocation.get() 
    for f in files_list: 
        shutil.copy(f, destination_location)
    #messagebox.showinfo("SUCCESSFULL") 
     
def MoveFile(): 
    files_list = WidgetFrame.files_list 
    destination_location = destinationLocation.get() 
    for f in files_list: 
        shutil.move(f, destination_location) 

def DeleteFile(): 
    files_list = WidgetFrame.files_list 
 
    for f in files_list: 
        os.remove(f)
    #messagebox.showinfo("SUCCESSFULL") 
 
# Creating tkinter variable 
sourceLocation = StringVar()
destinationLocation = StringVar() 
CreateWidgets() 
     
root.mainloop() 


#if __name__ == "__main__":
#    app.run('0.0.0.0' , port=7080, debug = True)
Larz60+ write Feb-14-2021, 12:40 AM:
Please post all code, output and errors (it it's entirety) between their respective tags. Refer to BBCode help topic on how to post. Use the "Preview Post" button to make sure the code is presented as you expect before hitting the "Post Reply/Thread" button.

Fixed for you this time. Please use bbcode tags on future posts.
Reply
#2
(Feb-13-2021, 10:54 PM)rfeyer Wrote: [snip...] freezes until I close the app from idle

I think there's known issues with using tk inside idle. Does the same behavior exist when running your program normally, via the command line?
Reply
#3
(Feb-15-2021, 08:52 PM)nilamo Wrote:
(Feb-13-2021, 10:54 PM)rfeyer Wrote: [snip...] freezes until I close the app from idle

I think there's known issues with using tk inside idle. Does the same behavior exist when running your program normally, via the command line?

Ty vm for looking this over. I am kinda lost as I can't find anything online

Yup, the program reacts the same when being called from a bash or terminal.
Reply
#4
Not sure if I overwhelmed with entering the whole code.
It is worth noting, that, with all the Buttons and Defs (i.e.: View, Copy, Delete, Move), the View function is the only one causing problems of sudden program exit on second file selection attempt.

I can not find any examples explaining MPV player playing multiple videos in succession ( i.e.: utilizing the askopenfilenames multiple selection widget.

here is what I am currently using:
def ViewFile():
    # plays all selected files one by one, keeps speed selected in 1st clip unless changed..
    files_list = WidgetFrame.files_list
    print(files_list)
    # loop through files
    for f in files_list:
        player.play(f)
        player.playlist_append(f)
        player.wait_for_playback()
    player.wait_for_playback
    
Would it be better to try and write the askopenfilenames resulting tuble to a playlist file and use that with MPV?
Reply
#5
OK,so I have tried dozens of different avenues to loop through a tuple, no success.
I have been able to write the tuple files to a file called mplaylist.e3u
However, now I can not find any coding or explanation which shows how to play a playlist from within python.
What I have now is:

import mpv
player = mpv.MPV(ytdl=True,input_default_bindings=True,input_vo_keyboard=True,osc=True)

def ViewFile():
     files_list = WidgetFrame.files_list
    # loop through files
    with open( 'mPlaylist.u3e', 'w+' ) as playlist:
        for f in files_list:
            print(f)
            playlist.write( f + '\n' )
        
        player.play("mPlylist.u3e")
    player.wait_for_playback
    playlist.close()
ANY suggestions would be greatly appreciated
Reply
#6
This works for me

import mpv
player = mpv.MPV(ytdl=True,input_default_bindings=True,input_vo_keyboard=True,osc=True)
media = open('playlist.m3u', 'r').read().splitlines()

try:
    for item in media:
        player.play(item)
        player.wait_for_playback()
except mpv.ShutdownError:
    pass
Reply
#7
TY - that works! But only when I use it as a standalone.

When I plug it into the function of the (initially posted) script, one of two things happen:
1- if I halt the strem (rightclick) and try to close the window the stream is playing in, the window freezes and I have to close the program from IDLE (or a quit button I have in it).
2- If I let the video/s run through to end, the window closes. But, if I try to select more files via Browse button (activating askopenfilenames()) then the program closes down abruptly as soon as the new file selections are made.
Essentially, this happens with your code and with mine.
I haven't a clue what to try next!

I made a shorter version of the program (removed the other labes/buttons/functions) to it's easier on the eye to look through:

#!/usr/bin/python3

import os
import shutil 
import tkinter as tk 
from tkinter import *
from tkinter import  filedialog, messagebox
from tkinter import ttk

import mpv
player = mpv.MPV(ytdl=True,input_default_bindings=True,input_vo_keyboard=True,osc=True)
media = open('mPlaylist.u3e', 'r').read().splitlines()
# Creating object of tk class 
root = tk.Tk()
root.title("Motion GUI")
root.minsize(width=1000, height=700)
root.maxsize(width=1400, height = 900)

mainframe = ttk.Frame(root, padding="3 3 12 12")
mainframe.grid(column=0, row=0, sticky=(N,W,E,S))
root.columnconfigure(0, weight=1)
root.rowconfigure(0,weight=1)

WidgetFrame = ttk.Frame(mainframe, borderwidth=2,relief='ridge',height = 60)
WidgetFrame.grid(column=0,row=0, sticky="E,W")

root.geometry("830x420") 
root.title("View/Copy/Move/Delete mkv's") 
root.config(background = "gray")

def CreateWidgets():
    
    WidgetFrame.link_Label = Label(WidgetFrame, text ="Select File(s): ", bg = "#E8D579") 
    WidgetFrame.link_Label.grid(row = 1, column = 0, pady = 5, padx = 5) 
    
    WidgetFrame.sourceText = Entry(WidgetFrame, width = 50, textvariable = sourceLocation) 
    WidgetFrame.sourceText.grid(row = 1, column = 1, pady = 5, padx = 5, columnspan = 2) 
     
    WidgetFrame.source_browseButton = Button(WidgetFrame, text ="Browse", command = SourceBrowse, width = 15) 
    WidgetFrame.source_browseButton.grid(row = 1, column = 3, pady = 5, padx = 5) 
     
    WidgetFrame.viewButton = Button(WidgetFrame, text ="View File(s)", command = ViewFile, width = 15) 
    WidgetFrame.viewButton.grid(row = 3, column = 0, pady = 5, padx = 5) 

def SourceBrowse(): 
     
    # Opening the file-dialog directory prompting the user to select files to copy using 
    # filedialog.askopenfilenames() method. Setting  initialdir argument is optional Since multiple 
    # files may be selected, converting the selection to list using list() 
    
    WidgetFrame.files_list = list(filedialog.askopenfilenames(initialdir ="/home/rainer/Videos",title="Press shift key plus Left mouse click to select multiple files")) 
    files_list = []
    # Displaying the selected files in the WidgetFrame.sourceText  Entry using WidgetFrame.sourceText.insert() 
    WidgetFrame.sourceText.insert('1', WidgetFrame.files_list)
     
def ViewFile():
    try:
        for item in media:
            player.play(item)
            player.wait_for_playback()
    except mpv.ShutdownError:
        pass
  
# Creating tkinter variable 
sourceLocation = StringVar()
destinationLocation = StringVar()  
files_list = StringVar()

# Calling the CreateWidgets() function 
CreateWidgets() 
     
# Defining infinite loop 
root.mainloop() 
Reply
#8
My apology - I thought I had the python /python with [] included before and after text, but it is not showing correctly and the edit button won't let me edit
Reply
#9
Do you have to use tkinter? There are better and easier ways for video.
Reply
#10
no, I don't have to use tkinter.
I simply chose it as it works with python, which I had used some about 12 years ago.
My needs are to view mkv video files (usually 15 to 120 seconds each) which are produced by motion video surveillance program.
I have motion configured to store each cameras files in separate folders. However, it can produce an easy 50 each per day. I would also like it to show live streaming feeds of the cameras, all on one page and separately full screen.
I also need to view the files over LAN, and 2-3 times per year over web.
I could easily ssh, but my wife is not into ssh or even folders.
12 years ago I made a program to automate our chicken coop (doors/lights/water heaters,etc using python and Flask on RPI's. I did start something for the cameras with Flask, but when running into hurdles could not get any help response from forums, so had to give up. Been working on this for a couple of months now.

What suggestions would you have? I am retired and willing to learn something new as long as my 63 yo brain can comprehend it.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Is there a way to call and focus any popup window outside of the main window app? Valjean 6 1,777 Oct-02-2023, 04:11 PM
Last Post: deanhystad
  Tkinter + Multiprocessing startmap makes UI Freeze sunny9495 4 1,398 Nov-13-2022, 12:49 PM
Last Post: sunny9495
  Pyspark Window: perform sum over a window with specific conditions Shena76 0 1,177 Jun-13-2022, 08:59 AM
Last Post: Shena76
  Install Python 3.8 for EduPython and Cx-Freeze mederic39 1 1,795 Jul-24-2020, 01:24 PM
Last Post: Larz60+
  Cx Freeze to exe - HELP WBPYTHON 5 3,873 Apr-09-2020, 01:34 PM
Last Post: WBPYTHON
  A software freeze ! HELP ! redorc15 1 1,792 Oct-10-2019, 10:54 PM
Last Post: Larz60+
  cx-Freeze exe doesn't work ammann 1 4,317 Mar-19-2018, 10:58 AM
Last Post: buran
  Pyusb freeze when using Dev.read(nr,nr,timeout=1000) bojane 3 7,531 Jan-11-2017, 10:17 AM
Last Post: bojane

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020