ale*_*dro 1 streaming audio-streaming internet-radio
有一些标准方法可以向流媒体广播服务询问当前播放的歌曲吗?我目前以不同的方式为每个站点执行此操作,例如(SomaFM):
$wg=join("\n",`wget -q -O - https://somafm.com/secretagent/songhistory.html`);
$wg=~/\(Now\).*>([^<]*)<\/a><\/td><td>([^<]*)/s;
print "Secret Agent\n$1\n$2\n"
Run Code Online (Sandbox Code Playgroud)
或(Radio Svizzera Classica):
$wg=join("\n",`wget -q -O - http://www.radioswissclassic.ch/en`);
$wg=~/On Air.*?titletag">([^<]*).*?artist">([^<]*)/s;
print "Radio Svizzera Classic\n$1\n$2\n"
Run Code Online (Sandbox Code Playgroud)
...但我想知道是否有更标准的方法可以做到这一点,而不是依赖于下载迟早会改变的html页面
对于具有ICY元数据(构成大量互联网广播电台)的SHOUTcast/Icecast风格电台,最好的办法是从流本身获取这些数据.
首先,您需要一个指向实际流的URL.如果您访问http://somafm.com/secretagent/上的SomaFM的秘密特工页面,您将看到其他玩家收听的链接.例如,让我们使用128k AAC链接,该链接指向http://somafm.com/secretagent130.pls.这不是实际的流...它是一个播放列表文件,包含指向实际流的链接.在您喜欢的文本或代码编辑器中打开它,看看我的意思:
[playlist]
numberofentries=2
File1=http://ice1.somafm.com/secretagent-128-aac
Title1=SomaFM: Secret Agent (#1 ): The soundtrack for your stylish, mysterious, dangerous life. For Spies and PIs too!
Length1=-1
File2=http://ice2.somafm.com/secretagent-128-aac
Title2=SomaFM: Secret Agent (#2 ): The soundtrack for your stylish, mysterious, dangerous life. For Spies and PIs too!
Length2=-1
Version=2
Run Code Online (Sandbox Code Playgroud)
因特网无线电台通常包括多个服务器以进行故障转移.如果监听器与一个监听器断开连接,则播放器通常会滚动到下一个项目.当一个服务器达到其监听器限制时,这也很有用......玩家将(希望)最终击中另一个活跃的服务器.
无论如何,启动Wireshark或其他一些数据包嗅探器的副本.点击音频播放器中的一个网址,然后检查流量.我们要看的第一件事是请求和响应.
GET /secretagent-128-aac HTTP/1.1
Host: ice1.somafm.com
User-Agent: VLC/2.2.4 LibVLC/2.2.4
Range: bytes=0-
Connection: close
Icy-MetaData: 1
HTTP/1.0 200 OK
Content-Type: audio/aacp
Date: Sat, 20 May 2017 20:43:56 GMT
icy-br:128
icy-genre:Various
icy-name:Secret Agent from SomaFM [SomaFM]
icy-notice1:<BR>This stream requires <a href="http://www.winamp.com/">Winamp</a><BR>
icy-notice2:SHOUTcast Distributed Network Audio Server/Linux v1.9.5<BR>
icy-pub:0
icy-url:http://SomaFM.com
Server: Icecast 2.4.0-kh3
Cache-Control: no-cache, no-store
Pragma: no-cache
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Origin, Accept, X-Requested-With, Content-Type
Access-Control-Allow-Methods: GET, OPTIONS, HEAD
Connection: Close
Expires: Mon, 26 Jul 1997 05:00:00 GMT
icy-metaint:45000
Run Code Online (Sandbox Code Playgroud)
这些互联网无线电服务器是HTTP(在Icecast和其他情况下)或非常接近它(传统SHOUTcast),并接受正常GET请求.在这种情况下,我的播放器(VLC)发出GET请求/secretagent-128-aac,这是实际流的路径.
我的播放器还包含一个键请求标头:
Icy-MetaData: 1
Run Code Online (Sandbox Code Playgroud)
此Icy-MetaData标头要求服务器将元数据与音频流数据进行多路复用.也就是说,"正在播放"的音轨信息将被定期发送到流中.
在服务器响应头中,还有另一个密钥头:
icy-metaint:45000
Run Code Online (Sandbox Code Playgroud)
这告诉我们两件事......首先是服务器同意发送元数据.第二个是元数据间隔是45,000字节.每45,000个字节,服务器将注入一大块元数据.让我们回到我们的数据包嗅探器,看看它是什么样的:
元数据块的第一个字节0x06告诉我们元数据块的长度.获取该字节的值,将其乘以16,您将获得元数据块的长度(以字节为单位).也就是说,0x06对于第一个元数据块字节告诉我们,在返回常规流数据之前,接下来的96个字节将是元数据.请注意,这意味着整个元数据为97个字节...长度指示符为1个字节,其余为96个字节(在本例中为).
现在,让我们进入实际的文本元数据格式:
StreamTitle='Buscemi - First Flight To London';StreamUrl='http://SomaFM.com/secretagent/';
Run Code Online (Sandbox Code Playgroud)
它看起来非常简单. key='value',分号;分隔.虽然有一些大的捕获.例如......没有真正标准的方法可以转义单引号.如果元数据值需要包含单引号,有时它是\',有时它是'''.有时它根本没有逃脱!
此外,并非所有服务器都使用相同的字符编码.您可以安全地假设UTF-8,但确实期望某些服务器可能不同,或者只是简单地在自己的元数据编码中断开.
无论如何,既然你知道所有这些是如何工作的,你就可以实现.如果你愿意,我有一些你可以许可的代码.一个是Node.js API服务器,当给定流URL时,将为您返回元数据,执行所有缓冲和解析服务器端.另一个是基于MSE的客户端播放器......请注意,这仅适用于支持CORS的服务器,据我所知,目前只有我自己的服务器(AudioPump CDN)才能这样做.如果您对以下任何代码感兴趣,请随时发送电子邮件至brad@audiopump.co.如果您对Stack Overflow上的答案有疑问,请在此处发表评论.