【问题标题】:Monitoring ICY Stream Metadata Title (Python)监控 ICY 流元数据标题 (Python)
【发布时间】:2016-12-07 16:44:05
【问题描述】:

我想继续阅读流并更新标题信息。 (类似这样的东西发布在这里:Receive ice cast meta data with python,但是它发出多个请求,我只想发出一个流请求。这里描述了协议:http://www.smackfu.com/stuff/programming/shoutcast.html。它似乎只工作一次然后停止工作。这里是我目前所拥有的:

import urllib2
import struct
import re

request = urllib2.Request('http://icy1.abacast.com:80/wbeb-wbebhd2aac-64')
request.add_header('Icy-MetaData','1')
opener = urllib2.build_opener()
data=opener.open(request)

while True:
    audio = data.read(2048) # 2048 is the metadata interval for this stream
    metadata_size = struct.unpack('B', data.read(1))[0]*16
    metadata = data.read(metadata_size).rstrip(b'\0')
    m = re.search(br"StreamTitle='([^']*)';", metadata)
    title = m.group(1).decode('latin1', errors='replace')
    print title

我认为那个不起作用的原因是url没有作为流打开,这可能与urllib2有关吗?

我也有一个不能用 requests.get 制作的:

def monitor():
     url = 'http://icy1.abacast.com:80/wbeb-wbebhd2aac-64'
     r = requests.get(url, headers={'Icy-MetaData': 1}, stream=True)
     metadata = StringIO.StringIO()
     byte_counter = 0
     meta_counter = 0
     metadata_interval = r.headers['icy-metaint']
     metadata_size = 0
     length = None
     data_bool = True
     for data in r.iter_content(1):
        byte_counter+=1
        print "byte %s" % byte_counter
        if (byte_counter <= 2048):
            pass # audio data
        if (byte_counter > 2048):
            if (meta_counter == 0):
                metadata_size = struct.unpack('B', data)[0]*16
                print "METADATA SIZE: %s" % metadata_size
                meta_counter+=1
            elif (meta_counter <= int(metadata_size+1)):
                metadata.write(data)
                meta_counter+=1
            else: data_bool = False
        if (data_bool is False):
            byte_counter = 0
            meta_counter = 0
            meta_interval = 0
            metadata_size = 0
            meta = metadata.read().rstrip(b'\0')
            m = re.search(br"StreamTitle='([^']*)';", meta)
            if m is not None:
                title = m.group(1).decode('latin1', errors='replace')
                print "Title is: %s" % title
            metadata = StringIO.StringIO()
            data_bool = True

【问题讨论】:

    标签: python stream title


    【解决方案1】:

    不确定您是否已经找到了方法。但是当我遇到同样的问题时 - 这是我的(工作但几乎没有测试过)版本。
    广泛基于您的建议,并进行了一些调整和 python3 支持:

    from __future__ import unicode_literals
    
    import re
    import requests
    import sys
    
    try:
        from StringIO import StringIO as BytesIO
    except ImportError:
        from io import BytesIO
    
    def icy_monitor(stream_url, callback=None):
    
        r = requests.get(stream_url, headers={'Icy-MetaData': '1'}, stream=True)
        if r.encoding is None:
            r.encoding = 'utf-8'
    
        byte_counter = 0
        meta_counter = 0
        metadata_buffer = BytesIO()
    
        metadata_size = int(r.headers['icy-metaint']) + 255
    
        data_is_meta = False
    
    
        for byte in r.iter_content(1):
    
            byte_counter += 1
    
            if (byte_counter <= 2048):
                pass
    
            if (byte_counter > 2048):
                if (meta_counter == 0):
                    meta_counter += 1
    
                elif (meta_counter <= int(metadata_size + 1)):
    
                    metadata_buffer.write(byte)
                    meta_counter += 1
                else:
                    data_is_meta = True
    
            if (byte_counter > 2048 + metadata_size):
                byte_counter = 0
    
            if data_is_meta:
    
                metadata_buffer.seek(0)
    
                meta = metadata_buffer.read().rstrip(b'\0')
    
                m = re.search(br"StreamTitle='([^']*)';", bytes(meta))
                if m:
                    title = m.group(1).decode(r.encoding, errors='replace')
                    print('New title: {}'.format(title))
    
                    if callback:
                        callback(title)
    
                byte_counter = 0
                meta_counter = 0
                metadata_buffer = BytesIO()
    
                data_is_meta = False
    
    
    def print_title(title):
        print('Title: {}'.format(title))
    
    
    
    if __name__ == '__main__':
    
        stream_url = sys.argv[1]
        icy_monitor(stream_url, callback=print_title)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多