jaseg / python-mpv

Python interface to the awesome mpv media player
https://git.jaseg.de/python-mpv.git
Other
532 stars 67 forks source link

Is there an elegant way to recognize a load failed? #194

Closed kanehekili closed 1 year ago

kanehekili commented 2 years ago

I am currently using python-mpv as frontend for a videocut app - and found a file that (if mpv is configured wrongly) can't be opened by mpv. I was expecting an exception, but the only information was a log Event:

callback: {'event_id': 2, 'error': 0, 'reply_userdata': 0, 'event': {'prefix': 'cplayer', 'level': 'error', 'text': 'Failed to recognize file format.'}}

FFMPEG recognized the video (and not defining demuxer_lavf_probesize removes the problem) but I'd like to be on the safe side, in case loading fails. Is there any other way to recognize a failed load?

neinseg commented 2 years ago

Hmmm... good question. I think the issue is that from MPV's point of view, the loadfile command (or our play alias) only tells it to start loading a file. It doesn't actually wait until the file has started playing. The reason for that is that otherwise loadfile on something like a youtube URL that will cause youtube-dl to be invoked in the background might take tens of seconds to finish.

In case a loadfile causes an error later, you actually get an end_file event that contains an error flag. Right now there is no nice way to convert that into an error on your main thread, but this code gets close:

player.loadfile('mpv.py')
#player.loadfile('tests/test.webm')

def check(evt):
    if evt['event']['reason'] == mpv.MpvEventEndFile.ERROR:
        # handle event here
        print('error!')
    return True

player.wait_for_event('end_file', cond=check)

The check callback must not throw an error itself since all that will do is to hang python-mpv's event handling thread. But you could set a variable accessible to whatever runs after wait_for_event. You can achieve a similar thing using a raw MPV.event_callback.

kanehekili commented 2 years ago

Thank you very much for your time and efforts! I've used a more clumsy solution and will check your idea tonight.

kanehekili commented 2 years ago

Implementing your code I've observed, that the event will be triggered whenever I try to enter "loadfile" a second time. Since I've got a QT openGL binding, the player is not closed (because it would destroy the GLWidget). Loading files without the checkEvent works though.