【问题标题】:Python: Parse stream title with mplayerPython:使用 mplayer 解析流标题
【发布时间】:2010-10-14 01:06:48
【问题描述】:

我正在用 Python 编写一个简单的前端,以使用 mplayer(在一个子进程中)播放和录制互联网广播频道(例如来自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 团队 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 字节) ICY 信息:StreamTitle='(JustMusic.FM) 地下室 - Zajac,Migren 住在 Justmusic 2010-10-09';StreamUrl='http://www.justmusic.fm'; 缓存填充:17.50%(57344 字节) 检测到仅音频文件格式。

然后它会一直运行直到它停止。所以问题是,我怎样才能检索“(JustMusic.FM) Basement - Zajac, Migren live at Justmusic 2010-10-09”并且仍然让进程运行?我不认为 subprocess() 实际上存储了输出,但我可能弄错了。任何帮助都深表感谢:)

【问题讨论】:

    标签: python parsing stream subprocess mplayer


    【解决方案1】:

    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)')
    

    【讨论】:

    • 非常感谢!尽管 stdout=PIPE,stderr=STDOUT 完全使 TK GUI 死锁。如果我“打破”循环,那么 mplayer 会在大约 30 秒后停止。有什么办法吗?也许在不影响进程的情况下逃脱循环?
    • 先试试p.communicate()。这听起来像一个缓冲区被填满并且由于某种原因没有及时读取,导致子进程阻塞。你可能不需要stdout stderr;大概你想要的消息只出现在其中一个上,我只是不知道是哪个!也许是标准错误,在这种情况下试试stderr=PIPE
    【解决方案2】:
    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())
    

    编辑:我在这里有一个不同的(更简单的)解决方案停止工作,所以我更新了我的解决方案。这个想法: mplayer 在 1 秒后停止。 (-endpos 1)。

    【讨论】:

      猜你喜欢
      • 2020-01-25
      • 1970-01-01
      • 2022-11-29
      • 1970-01-01
      • 2016-02-14
      • 1970-01-01
      • 1970-01-01
      • 2015-10-17
      • 2012-02-24
      相关资源
      最近更新 更多