Reputation: 1821
I'm writing a simple frontend in Python to play and record internet radio channels (e.g. from shoutcast) using mplayer (in a subprocess). When a user clicks a station the following code is run:
url = http://77.111.88.131:8010 # only an example
cmd = "mplayer %s" % url
p = subprocess.Popen(cmd.split(), shell=False)
wait = os.waitpid(p.pid, 1)
return int(p.pid)
This works perfectly, the stream starts playing as it should. Although I would like to somehow parse the title of the stream. It seems that I need to fetch the title from the mplayer output. This is the output when I play the stream in a terminal:
$ mplayer http://77.111.88.131:8010 MPlayer 1.0rc4-4.4.5 (C) 2000-2010 MPlayer Team mplayer: could not connect to socket mplayer: No such file or directory Failed to open LIRC support. You will not be able to use your remote control. Playing http://77.111.88.131:8010. Resolving 77.111.88.131 for AF_INET6... Couldn't resolve name for AF_INET6: 77.111.88.131 Connecting to server 77.111.88.131[77.111.88.131]: 8010... Name : Justmusic.Fm Genre : House Website: http://www.justmusic.fm Public : yes Bitrate: 192kbit/s Cache size set to 320 KBytes Cache fill: 0.00% (0 bytes) ICY Info: StreamTitle='(JustMusic.FM) Basement - Zajac, Migren live at Justmusic 2010-10-09';StreamUrl='http://www.justmusic.fm'; Cache fill: 17.50% (57344 bytes) Audio only file format detected.
It then runs until it's stopped. So the question is, how can I retrieve "(JustMusic.FM) Basement - Zajac, Migren live at Justmusic 2010-10-09" and still let the process run? I don't think subprocess() actually stores the output, but I might be mistaken. Any help is deeply appreciated :)
Upvotes: 4
Views: 5637
Reputation: 20644
import re
import shlex
from subprocess import PIPE, Popen
URL = 'http://relay2.slayradio.org:8000/'
def get_exitcode_stdout_stderr(cmd):
"""
Execute the external command and get its exitcode, stdout and stderr.
"""
args = shlex.split(cmd)
proc = Popen(args, stdout=PIPE, stderr=PIPE)
out, err = proc.communicate()
exitcode = proc.returncode
#
return exitcode, out, err
def get_title():
cmd = "mplayer -endpos 1 -ao null {url}".format(url=URL)
out = get_exitcode_stdout_stderr(cmd)[1]
for line in out.split("\n"):
# print(line)
if line.startswith('ICY Info:'):
match = re.search(r"StreamTitle='(.*)';StreamUrl=", line)
title = match.group(1)
return title
def main():
print(get_title())
Edit: I had a different (simpler) solution here that stopped working so I updated my solution. The idea: mplayer stops after 1 sec. (-endpos 1
).
Upvotes: 1
Reputation: 536595
Set the stdout
argument to PIPE
and you'll be able to listen to the output of the command:
p= subprocess.Popen(['mplayer', url], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
for line in p.stdout:
if line.startswith('ICY Info:'):
info = line.split(':', 1)[1].strip()
attrs = dict(re.findall("(\w+)='([^']*)'", info))
print 'Stream title: '+attrs.get('StreamTitle', '(none)')
Upvotes: 5