I wrote some years ago an iTunes-replacing program in Python, with mpg123 accessed by a pipe (from the manual: -R, --remote: Activate generic control interface. mpg123 will then read and execute commands from stdin. Basic usage is ``load <filename>'' to play some file
).
I dont have available a machine with the old python & pipes still working so it's hard to give you an example, but it was something like this:
import subprocess,pipes
mpgpipe = "/tmp/mpg123remote.cmd"
mpgout = "/tmp/mpg123.out"
fmpgout=open(mpgout,"w")
mpg123proc = subprocess.Popen(["/usr/bin/mpg123", "-vR", "--fifo", mpgpipe ], stdin=subprocess.PIPE, stdout=fmpgout)
t = pipes.Template()
t.append("echo load \"%s\"" % "test.mp3", '--')
f = t.open(mpgpipe, 'w')
f.close()
Recently I started to get a warning DeprecationWarning: 'pipes' is deprecated and slated for removal in Python 3.13
- and now it happened: the pipes library isnt available anymore.
This is the test code I'm using, trying to access mpg123 by a named pipe:
import os, io, subprocess
mpgpipe = "/tmp/mpg123remote.cmd"
try:
os.mkfifo(mpgpipe)
print("Named pipe created successfully!")
except FileExistsError:
print("Named pipe already exists!")
except OSError as e:
print(f"Named pipe creation failed: {e}")
fmpgout=open("/tmp/mpg123.out","w")
mpg123proc = subprocess.Popen(["/usr/bin/mpg123", "-a", "default", "-vR", "--fifo", mpgpipe ], stdout=fmpgout)
pipfd = os.open(mpgpipe, os.O_RDWR | os.O_NONBLOCK)
songname = "test.mp3"
command=f"load \"{songname}\"\n"
with io.FileIO(pipfd, 'wb') as f: f.write(command.encode())
but it doesnt work: no audio, no error, and this text output :
High Performance MPEG 1.0/2.0/2.5 Audio Player for Layers 1, 2 and 3
version 1.32.9; written and copyright by Michael Hipp and others
free software (LGPL) without any warranty but with best wishes
Decoder: x86-64 (AVX)
Trying output module: alsa, device: default
(of course the audio device is ok and listening to test.mp3 with mpg123 from the terminal works perfectly...)
any idea???
I think I nailed it - here's the solution to drive mpg123 by subprocess, without pipes:
import subprocess
fmpgout=open("/tmp/mpg123.out","w")
songname = "song.mp3"
command=f"load {songname}\n"
mpg123proc = subprocess.Popen(["/usr/bin/mpg123", "-a", "default", "-vR"], stdin=subprocess.PIPE, stdout=fmpgout, text=True) # with text=True I can send text on stdin: not needed to encode()
mpg123proc.stdin.write(command)
mpg123proc.stdin.flush()
while(1): pass
things that at first made me stumble: