2016-10-21 3 views
0

스트림에서 icecast 메타 데이터를 추출하려고합니다. 일부 스트림에서는 작동하지만 다른 스트림에서는 작동하지 않는 코드가 있습니다. 일부 스트림은 icymetaint 값을 반환하지 않으며 코드가 손실되는 부분입니다.일부 icecast 스트림에서 메타 데이터를 추출 할 수 없습니다.

내가이 스트림에서 icymetaint 헤더 얻을 수 없습니다 http://radio.hbr1.com:19800/tronic.ogg

을하지만 VLC 미디어 플레이어에 넣을 때 메타가 잘 보여줍니다. 그래서 내가 정확히 여기에 누락 되었습니까? 메타 데이터를 전송하는 다른 방법으로는 icecast 스트림이 있습니까? 만하는 Shoutcast에 널 소프트에 의해 도입 된 뇌사 고대의 메타 데이터 슬립 스트림을 구문 분석하려고하기 때문이다

public function GetDataFromStream($parsedUrl) 
{ 
    $returnData = array(); 
    $addr = $parsedUrl['host']; 

    $addr = gethostbyname($addr); 

    $sock = fsockopen($addr, $parsedUrl['port'], $errno, $errstr, 5); 
    $path = isset($parsedUrl['path'])?$parsedUrl['path']:'/'; 

    if ($sock) 
    { 
     $request = 'GET '. $path .' HTTP/1.0' . CRLF . 
      'Host: ' . $parsedUrl['host'] . CRLF . 
      'Connection: Close' . CRLF . 
      'User-Agent: ' . $this->useragent . CRLF . 
      'Accept: */*' . CRLF . 
      'icy-metadata: 1'.CRLF. 
      'icy-prebuffer: 65536'.CRLF. 
      (isset($parsedUrl['user']) ? 'Authorization: Basic ' . 
      base64_encode($parsedUrl['user'] . ':' . $parsedUrl['pass']) . CRLF : ''). 
      'X-TipOfTheDay: Winamp "Classic" rulez all of them.' . CRLF . CRLF; 

     if (fwrite($sock, $request)) 
     { 
      $theaders = $line = ''; 

      while (!feof($sock)) 
      { 
       $line = fgets($sock, 4096); 

       if('' == trim($line)) 
        break; 
       $theaders .= $line; 
      } 

      $theaders = explode(CRLF, $theaders); 

      foreach ($theaders as $header) 
      { 
       $t = explode(':', $header); 


       if (isset($t[0]) && trim($t[0]) != '') 
       { 
        $name = preg_replace('/[^a-z][^a-z0-9]*/i','', strtolower(trim($t[0]))); 
        array_shift($t); 
        $value = trim(implode(':', $t)); 

        if ($value != '') 
        { 
         if (is_numeric($value)) 
          $this->headers[$name] = (int)$value; 
         else 
          $this->headers[$name] = $value; 
        } 
       } 
      } 

      if (isset($this->headers['icymetaint'])) 
      { 
       $metainterval = $this->headers['icymetaint']; 
       $intervals = 0; 
       $metadata = ''; 

       while(1) 
       { 
        $data = ''; 

        while(!feof($sock)) 
        { 
         $data .= fgetc($sock); 

         if (strlen($data) >= $metainterval) 
          break; 
        } 

        $len = join(unpack('c', fgetc($sock))) * 16; 

        if ($len > 0) 
        { 
         $metadata = str_replace("\0", '', fread($sock, $len)); 
         break; 
        } 
        else 
        { 
         $intervals++; 
         if ($intervals > 100) break; 
        } 
       } 

       $metarr = explode(';', $metadata); 

       foreach ($metarr as $meta) 
       { 
        $t = explode('=', $meta); 

        if (isset($t[0]) && trim($t[0]) != '') 
        { 
         $name = preg_replace('/[^a-z][^a-z0-9]*/i','', strtolower(trim($t[0]))); 

         array_shift($t); 

         $value = trim(implode('=', $t)); 

         if (substr($value, 0, 1) == '"' || substr($value, 0, 1) == "'") 
          $value = substr($value, 1); 

         if (substr($value, -1) == '"' || substr($value, -1) == "'") 
          $value = substr($value, 0, -1); 

         if ($value != '') 
         { 
          $tmp = &$this->metadata; 
          $tmp[$name] = $value; 
         } 
        } 
       } 
       $this->valid = true; 
      } 
      else 
      { 
       $this->valid = false; 
      } 

      fclose($sock); 
     } 
     else 
      echo 'unable to write.'; 
    } 
    else 
     //echo 'no socket '.$errno.' - '.$errstr.'.'; 
     ; 

} 

답변

2

당신은 XML을 얻을 .xspf 마운트 지점 확장을 사용할 수 있으며 구문 분석 :

$ lynx -mime_header http://radio.hbr1.com:19800/tronic.ogg.xspf 
HTTP/1.0 200 OK 
Content-Type: application/xspf+xml 
Content-Length: 615 

<?xml version="1.0" encoding="UTF-8"?> 
<playlist xmlns="http://xspf.org/ns/0/" version="1"> 
    <title/> 
    <creator/> 
    <trackList> 
    <track> 
     <location>http://radio.hbr1.com:19800/tronic.ogg</location> 
     <creator>Res Q</creator> 
     <title>Fakesleep (2012)</title> 
     <annotation>Stream Title: HBR1 - Tronic Lounge 
Stream Description: Music on Futurenet 
Content Type:application/ogg 
Bitrate: Quality 0,00 
Current Listeners: 28 
Peak Listeners: 45 
Stream Genre: Tech House, Progressive House, Electro, Minimal</annotation> 
     <info>http://www.hbr1.com</info> 
    </track> 
    </trackList> 
</playlist> 

로를 :

여기
<?php 
$stream_url = "http://radio.hbr1.com:19800/tronic.ogg"; 
$xspf_url = $stream_url . ".xspf"; 
$xml = file_get_contents($xspf_url); 
if($xml){ 
    $data = simplexml_load_string($xml); 
    // Track artist 
    print $data->trackList->track->creator; 
    // Track title 
    print $data->trackList->track->title; 
} 
?> 

.xspf 데이터 (필자는 URL의 내용을 읽을 수 lynx를 사용)과 같은 모습입니다 당신은 /playlist/trackList/track/title XML 노드가 당신의 노래 제목임을 알 수 있습니다. /playlist/trackList/track/creator은 대개 예술가입니다.

+0

.xspf를 확인했으며 청취자 수, 청취자 피크 수, 품질을 나열합니다. 그것은 나를 위해 가장 중요한 것을 나열하지 않습니다, 그것은 노래 제목입니다. 내가 놓친 게 있니? –

+0

'.xspf' 만 있으면됩니다. 내 답변을 업데이트했습니다. –

+0

json 버전 2.4 이상을 지원하는 스트림이 .xspf 파일에서 제목을 반환하지 않는 스트림임을 알게되었습니다. 다른 사람들도 그렇습니다. 고맙습니다. 정답으로 표시됩니다. –

0

: 스트림 버전은 아이스 캐스트 2.3.3

이 메타 데이터와 헤더를 검색하는 클래스의 내부 코드입니다 .

적절한 스트림은 원시 데이터를 내보내는 대신 컨테이너 (예 : Ogg 또는 WebM)를 사용합니다.

최신 Icecast 서버는 JSON API (버전 2.4.1 이상)를 제공합니다. 이것은 메타 데이터에 대해서만 전체 스트림을 가져 오는 것보다 더 유용합니다.

어쨌든 스트림을 디코딩하는 경우, 스트림, libogg, libopus, libvorbis를 구문 분석하기위한 적절한 라이브러리를 살펴 봐야합니다.

+0

답변 해 주셔서 감사합니다. 문제는 내가 스트림 내가 그들 모두를 구문 분석 할 수 있어야 그렇게 될 것입니다 버전을 통제 할 수 없다는 것입니다. Ogg와 WebM, libogg, libopus, php 키워드로 libvorbis를 시도했지만 php로 sterams를 파싱하는 데 유용한 것은 찾지 못했습니다. –

관련 문제