jaseg / python-mpv

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

Handling piped stdin correctly #156

Closed mvonmaltitz closed 3 years ago

mvonmaltitz commented 3 years ago

I would like to use an python-mpv script as drop-in replacement for mplayer.

Highly simplified, my use case is: bash -c 'sleep 5 ; echo -n "99999"' | mplayer <path_to_music_file> MPlayer consumes the chars which are piped in and acts upon them as expected.

My MWE for python-mpv ./mpv-player.py:

#!/usr/bin/env python3                                                          
import mpv, sys                                                                 

infile=sys.argv[1]                                                              
print(f"Starting mpv on {infile}")                                              

player = mpv.MPV(video=False, terminal=True, input_terminal=True,               
input_default_bindings=True)                                                    

@player.on_key_press('q')                                                       
def my_q_binding():                                                             
    print('THERE IS NO ESCAPE')                                                 

@player.on_key_press('0')                                                       
def my_0_binding():                                                             
    print('Pressed 0')                                                          
@player.on_key_press('9')                                                       
def my_9_binding():                                                             
    print('Pressed 9')                                                          

player.play(infile)                                                             
try:                                                                            
    player.wait_for_playback()                                                  
except mpv.ShutdownError:                                                       
    sys.exit(0)                                                                 

However, stdin is not consumed when doing bash -c 'sleep 5 ; echo -n "99999"' | ./mpv-player <path_to_music_file> Instead, mpv still reacts on direct keyboard input.

I already tried the reference link in https://github.com/jaseg/python-mpv/issues/93#issuecomment-558815718 But this does not work for stdin from pipes but only interactive sessions.

Could you give me a hint how to make python-mpv consume stdin (control) input from pipes? Thank you a lot in advance!

jaseg commented 3 years ago

I haven't looked into it in detail, but I'm fairly sure what mpv is doing here is that it just grabs input directly from the attached pty instead of stdin, like e.g. the password prompt from sudo does. What you're trying to do is explicitly discouraged by the doc, so I would not try to work around on the MPV side.

If you can't make whatever your're piping input from use mpv's IPC protocol the easiest way to do things would be to simply sys.stdin.read() on a python thread and control mpv from that. If you actually want to bounce this input into mpv's keybinding subsystem, you can feed what you read from stdin to the keypress command. python-mpv supports that as a method on the MPV object.

mvonmaltitz commented 3 years ago

Thank you a lot! Stressing these points helped me not hunting after a bad solution. I was now able to utilize the IPC protocol and made use of the fact that the IPC interface happily accepts plaintext commands like quit or add volume -10