#!/usr/bin/python
# coding: utf-8
import sys, telnetlib, os, time, socket
HOST = "localhost"
password = "admin"
port = "4212"
def check_port():
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
res = sock.connect_ex((HOST, int(port)))
sock.close()
return res == 0
def checkstat():
if not check_port():
os.popen('vlc --no-audio --intf telnet --telnet-password admin --quiet 2>/dev/null &')
while not check_port():
time.sleep(.1)
def docmd(cmd):
tn = telnetlib.Telnet(HOST, port)
tn.read_until(b"Password: ")
tn.write(password.encode('utf-8') + b"\n")
tn.read_until(b"> ")
tn.write(cmd.encode('utf-8') + b"\n")
ans=tn.read_until(">".encode("utf-8"))[0:-3]
return(ans)
tn.close()
def nowplaying(playing):
npstart=playing.find('now_playing')
mystr=playing[npstart:]
npend=mystr.find('\n')
return mystr[:npend]
def metadata(playing):
fstr='+----'
mstart=playing.find(fstr)
mend=playing.find(fstr,mstart+len(fstr))
return playing[mstart:mend+len(fstr)]
checkstat()
docmd('add '+sys.argv[1])
playing=""
count=0
while not 'now_playing:' in playing:
time.sleep(.5)
playing=docmd('info')
count+=1
if count>9:
break
if playing == "":
print("--Timeout--")
else:
print(metadata(playing))
docmd('shutdown')
例如,从Crypt Theater Station提取元数据:
./radiometatdata.py http://107.181.227.250:8026
回应:
+----[ Meta data ]
|
| title: *CRYPT THEATER*
| filename: 107.181.227.250:8026
| genre: Old Time Radio
| now_playing: CBS Radio Mystery Theatre - A Ghostly Game of Death
|
+----
5条答案
按热度按时间rsl1atfo1#
这是一个SHOUTcast流,是的,这是可能的。它与ID 3标签无关。我写了一个脚本前一段时间这样做,但不能找到它了。就在上周,我帮助了另一个家伙,他有一个相当完整的脚本来做同样的事情,但我不能把源代码贴到它上面,因为它不是我的。不过,我会让你与他联系,如果你给我发电子邮件在email protected(http://mailto:brad@musatcha.com)。
无论如何,以下是如何自己做的:
你需要做的第一件事是直接连接到服务器。不要使用HTTP。好吧,你可能会使用cURL,但它可能会比它的价值更麻烦。您可以使用
fsockopen()
(doc)连接到它。确保使用正确的端口。另外请注意,许多Web主机会阻止很多端口,但您通常可以使用端口80。幸运的是,所有AOL托管的SHOUTcast流都使用端口80。现在,像你的客户那样提出你的要求。
GET /whatever HTTP/1.0
但是,在发送
<CrLf><CrLf>
之前,包括下一个头!Icy-MetaData:1
这告诉服务器您需要元数据。现在,发送您的一对
<CrLf>
。好的,服务器会响应一堆头,然后开始向你发送数据。在这些标题中将是
icy-metaint:8192
或类似的。8192是Meta区间。这很重要,也是你唯一需要的价值。它通常是8192,但并不总是,所以请确保实际读取此值!基本上这意味着,你将得到8192字节的MP3数据,然后是一大块Meta,然后是8192字节的MP3数据,然后是一大块元数据。
读取8192个字节的数据(确保您没有在此计数中包括头),丢弃它们,然后读取下一个字节。该字节是Meta数据的第一个字节,并指示元数据的长度。取此字节的值(实际字节为
ord()
(doc)),然后乘以16。结果是要为元数据读取的字节数。将这些字节数读入一个字符串变量,以便您使用。接下来,修剪这个变量的值。为什么呢?因为字符串在末尾填充了
0x0
(使其均匀地适合16字节的倍数),trim()
(doc)为我们处理了这一点。你会得到这样的东西:
StreamTitle='Awesome Trance Mix - DI.fm';StreamUrl=''
我会让你选择你的方法来解析它。就我个人而言,我可能只是在
;
上限制为2,但要小心包含;
的标题。我不知道转义字符方法是什么。一个小实验可以帮助你。不要忘记断开与服务器的连接,当你完成它!
有很多SHOUTcast元数据参考。这是一个很好的例子:https://web.archive.org/web/20191121035806/http://www.smackfu.com/stuff/programming/shoutcast.html
v64noz0r2#
看看这个:https://gist.github.com/fracasula/5781710
这是一个PHP函数的小要点,它允许您从流URL中提取MP3元数据(StreamTitle)。
通常,流媒体服务器会在响应中放置一个
icy-metaint
头,告诉我们流中元数据的发送频率。该函数检查响应头,如果存在,则用它替换interval参数。否则,该函数将根据您的时间间隔调用流URL,如果没有任何元数据,则它将从偏移量参数开始通过递归再次尝试。
希望这对你有帮助!
lrpiutwd3#
非常感谢您提供的代码fra_casula。这里是一个稍微简化的版本,运行在PHP <= 5.3上(原始版本的目标是5.4)。它还重用相同的连接资源。
我因为自己的需要而删除了异常,如果没有找到任何东西,则返回false。
63lcw9qa4#
这是使用HttpClient获取元数据的C#代码:
kyxcudwk5#
更新:这是一个更新,有一个更合适的解决方案的问题。原文也在下面提供,以供参考。
这篇文章中的脚本,经过一些错误更正,工作并使用PHP提取流标题:PHP script to extract artist & title from Shoutcast/Icecast stream。
我不得不做一些修改,因为最后的echo语句抛出了一个错误。我在函数后添加了两个print_r()语句,并在调用中添加了$argv[1],这样您就可以从命令行向它传递URL。
使用更新的代码,它打印header和streamtitle信息的数组。如果你只想要now_playing的音轨,那么注解掉两个print_r()语句,并在结尾取消注解echo语句。
PHP解决方案一直在搜索,但从未为我返回响应。
这不是PHP的要求,但可能会帮助其他人寻找一种方法来提取'now_playing'信息从直播流。
如果你只想要'now_playing'信息,你可以编辑脚本来返回它。
python脚本使用VLC提取元数据(包括“now_playing”曲目)。你需要VLC和Python库:sys、telnetlib、os、time和socket。
例如,从Crypt Theater Station提取元数据:
回应: