无法从某些ip和端口获取所需的标头,以使用ShoutCast协议解析歌曲标题


Cannot get required headers from some IPs and ports to parse song title using ShoutCast protocol

我正在尝试使用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.1'r'n";
        $request .= "Icy-MetaData: 1'r'n'r'n";
        //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)|('r'n?))/", $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元数据协议