2016-12-07 4 views
0

계속해서 스트림을 읽고 타이틀 정보를 업데이트하고 싶습니다. (이 같은 뭔가가 여기에 게시됩니다 : Receive ice cast meta data with python,하지만 그것은 여러 요청을 만들고, 난 그냥 한 스트림 요청을 만들려고했다. 프로토콜은 여기에 설명되어 있습니다 : http://www.smackfu.com/stuff/programming/shoutcast.html. 그것은 한 번 작동하지 않는 것 같습니다. 지금까지 :ICY 스트림 메타 데이터 제목 모니터링 (Python)

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가 함께 할 수 있다는 것입니다

또한 나던 하나가 요청으로 만든 작품 .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 

답변

0

그 동안 이미 방법을 찾았는지 확실하지 않습니다. 하지만 제가 같은 질문을 한 것처럼 - 여기에 내 (작동하지만 간신히 테스트 된) 버전이 있습니다.

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) 
: 일부 adaptions 및 python3 지원 널리 귀하의 제안에 따라
,