2014-06-19 19 views
0

我試圖從使用SC協議的實時mp3流中提取歌曲標題。 php腳本可以和一些IP和端口一起工作,但是有些IP和端口我無法從響應中獲得所需的標題來確定元塊頻率,因此我無法在流中找到歌曲標題的位置。這裏是我的代碼:無法從一些IP和端口獲得所需的標題來解析使用ShoutCast協議的歌曲標題

<?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; 
    } 
} 

>

+0

你能提供一個不一個工程的例子,一個?另外,你爲什麼要檢查內容類型?並非所有的流都是'audio/mpeg'。最後,您正在以區分大小寫的方式搜索標題...標題名稱不區分大小寫。 – Brad

回答

2

我從來沒有嘗試以編程方式訪問Shoutcast的,但我已經運行在過去的音頻流服務器?實際上有兩種不同口味的shoutcast服務器,我猜你的程序正在試圖與其中一個進行對話,而這些破碎的服務器是另一種類型。

從後READING SHOUTCAST METADATA FROM A STREAM

原來,Shoutcast一樣和的Icecast(兩種最流行的服務器 應用的流媒體廣播的)應該是兼容的,但 從每個服務器響應消息略不同。

關於Shoutcast的協議的全部細節:Shoutcast Metadata Protocol

+0

謝謝你的迴應。我認爲我的解析代碼工作正常,因爲我可以解析來自某些IP的歌曲標題。我解析了手動輸入的第一個鏈接中提到的頭文件。問題是,我得到這樣的事情時,我發送給一些服務器的請求: 'ICY 200 OK 冰冷-notice1:
此流需要Winamp
冰冷-notice2:Shoutcast一樣分佈式網絡音頻服務器/ Linux的v1.9.8
' 因此,我無法獲得meta-int標題以找到元塊間隔... – dogadikbayir

+0

Winamp是一個媒體播放器,這些流必須期待一些Winamp特定的響應。下載winamp&wireshark,然後連接並查看通信的外觀。 –

相關問題