I have a... very specific problem. Really tried to find a broader question but couldn't.
I am trying to use mplayer as a subprocess to play music (on windows and also linux), and retain the ability to pass commands to it. I have accomplished this just fine in python 2.7 with subprocess.Popen
and p.stdin.write('pause\n')
.
However this doesn't seem to have survived the trip to Python 3. I have to either use 'pause\n'.encode()
or b'pause\n'
to convert to bytes
, and the mplayer process does not pause. It does seem to work however if i use p.communicate
, but I have ruled that out as a possiblity due to this question which claims it can only be called once per process.
Here's is my code:
p = subprocess.Popen('mplayer -slave -quiet "C:\\users\\me\\music\\Nickel Creek\\Nickel Creek\\07 Sweet Afton.mp3"', stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
time.sleep(1)
mplayer.stdin.write(b'pause\n')
time.sleep(1)
mplayer.stdin.write(b'pause\n')
time.sleep(1)
mplayer.stdin.write(b'quit\n')
seeing as this code worked (without the b
s) in 2.7, i can only assume encoding the string as a bytes
is somehow changing the byte values so that mplayer can't understand it any more? however when i try to see exactly what bytes are sent through the pipeline it looks correct. it could also be windows pipeline acting strange. i've tried this with both cmd.exe and powershell, since i know powershell interprets the pipeline as xml. i used this code to test what comes in through the pipeline:
# test.py
if __name__ == "__main__":
x = ''
with open('test.out','w') as f:
while (len(x) == 0 or x[-1] != 'q'):
x += sys.stdin.read(1)
print(x)
f.write(x)
and
p = subprocess.Popen('python test.py', stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
p.stdin.write(b'hello there\ntest2\nq\n')