Python:使用mplayer解析流标题

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

我正在用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.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())