我正在尝试使用SC协议从直播mp3流中提取歌曲标题。php脚本与一些ip和端口工作得很好,但是与一些ip和端口,我无法从响应中获得所需的标头来确定元块频率,因此我无法在流中找到歌曲标题的位置。下面是我的代码:
<?php
while(true)
{
//close warning messages (re-open for debugging)
error_reporting(E_ERROR | E_PARSE);
//create and connect socket with the parameters entered by the user
$sock = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
echo "Establishing connection to the given adress...n";
$fp = fsockopen($argv[1], $argv[2], $errno, $errstr, 10);
if($fp)
{
echo "Connection established.n";
$result = socket_connect($sock, $argv[1], $argv[2]);
//prepare request
$request = "GET / HTTP/1.1rn";
$request .= "Icy-MetaData: 1rnrn";
//send request
socket_write($sock,$request,strlen($request));
//set sentinel boolean value's initial value
$headers = true;
//put the segment to be parsed into a string variable
$l = socket_read($sock,2048);
$meta = "";
$streamurl = "";
$checkContentType = false;
//Parsing metadata frequency and streamurl from response's headers.
foreach(preg_split("/((r?n)|(rn?))/", $l) as $line)
{
if(!(strpos($line, "metaint:") === false))
{
$meta = $line;
}
if(!(strpos($line, "icy-url:") === false))
{
$streamurl = $line;
}
if(!strpos($line, "audio/mpeg") === false)
{
$checkContentType = true;
}
}
echo $l;
//Checking if the content of the stream is mpeg or not
if($checkContentType)
{
$pos = strpos($meta, ":");
$interval = intval(substr($meta,$pos+1));
$pos = strpos($streamurl, ":");
$streamurl = substr($streamurl, $pos+1);
$flag = false;
//initialize bytecount to 0
$bytecount = 0;
//Extracting song title using SC protocol
while($headers)
{
$l = socket_read($sock,PHP_NORMAL_READ);
$bytecount++;
if($bytecount == $interval )
{
$headers = false;
$flag = true;
}
if($flag)
{
$len = ord($l);
}
}
//Determining length variable
$len = $len * 16;
$string = socket_read($sock,$len);
$pos2 = strpos($string, "'") + 1;
$pos3 = strpos($string, ";",$pos2) -1;
$songtitle = substr($string, $pos2, ($pos3-$pos2));
//Formatting the log entry
$finalstr = "[".date("c")."]"."[".$streamurl."]".$songtitle."n";
echo "logged".$finalstr;
//finalize connection
socket_close($sock);
//Writing the requested info to a log file
file_put_contents("log.txt", $finalstr,FILE_APPEND | LOCK_EX);
//waiting 5 minutes
echo "Logging next entry in five minutes. n";
sleep(300);
}
else
{
echo "Content of the stream is not suitable.n";
exit;
}
}
else
{
echo "Unable to connect to the given ip and port.n Exiting...n";
socket_close($sock);
exit;
}
}
?>
我从未尝试过以编程方式访问广播,但我过去运行过流媒体音频服务器。实际上有两种不同的广播服务器,我猜你的程序正在尝试与其中一种服务器通信,而这些坏掉的服务器是另一种类型。
来自post READING SHOUTCAST METADATA From A STREAM:
原来,SHOUTcast和Icecast(两个最流行的服务器流媒体广播的应用程序应该是兼容的,但是来自每个服务器的响应消息略有不同。
关于shoutcast协议的详细信息:shoutcast元数据协议