Python:使用mplayer解析流标题
我正在用Python编写一个简单的前端,使用mplayer(在子进程中)播放和录制internet广播频道(例如来自shoutcast)。当用户单击站点时,将运行以下代码:Python:使用mplayer解析流标题,python,parsing,stream,subprocess,mplayer,Python,Parsing,Stream,Subprocess,Mplayer,我正在用Python编写一个简单的前端,使用mplayer(在子进程中)播放和录制internet广播频道(例如来自shoutcast)。当用户单击站点时,将运行以下代码: 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
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)
这工作非常完美,流开始按它应该的方式播放。尽管我想以某种方式解析流的标题。似乎我需要从mplayer输出中获取标题。这是我在终端播放流时的输出:
$ 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.
$mplayerhttp://77.111.88.131:8010
MPlayer 1.0rc4-4.4.5(C)2000-2010 MPlayer团队
mplayer:无法连接到套接字
mplayer:没有这样的文件或目录
无法打开LIRC支持。您将无法使用遥控器。
玩http://77.111.88.131:8010.
为AF INET6解析77.111.88.131。。。
无法解析AF_INET6的名称:77.111.88.131
正在连接到服务器77.111.88.131[77.111.88.131]:8010。。。
姓名:Justmusic.Fm
类型:豪斯
网站:http://www.justmusic.fm
公众:是的
比特率:192kbit/s
缓存大小设置为320 KB
缓存填充:0.00%(0字节)
冰冷的信息:StreamTitle='(JustMusic.FM)地下室-扎哈克,米格伦在JustMusic现场直播2010-10-09';StreamUrl=http://www.justmusic.fm';
缓存填充:17.50%(57344字节)
检测到仅音频文件格式。
然后它运行直到停止。因此,问题是,我如何检索“(JustMusic.FM)地下室-Zajac,Migren在JustMusic 2010-10-09现场直播””并且仍然让流程运行?我不认为subprocess()实际上存储了输出,但我可能弄错了。非常感谢您的帮助:)将
stdout
参数设置为PIPE
,您将能够听到命令的输出:
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)')
编辑:我这里有一个不同的(更简单的)解决方案停止工作,所以我更新了我的解决方案。想法:mplayer在1秒后停止。(
-endpos 1
)。非常感谢!虽然stdout=PIPE,但stderr=stdout会完全死锁TKGUI。如果我“打破”循环,mplayer将在大约30秒后停止。有办法吗?可能在不影响流程的情况下退出循环?请先使用p.communicate()
进行尝试。听起来好像缓冲区被填满了,由于某种原因没有及时读取,导致子进程阻塞。您可能不需要stdout
和stderr
;想必你想要的信息只会出现在其中一个上面,我只是不知道是哪一个!也许是stderr,在这种情况下,试一下stderr=PIPE
?
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())