PHP 脚本来提取艺术家 &来自 Shoutcast/Icecast 流的标题 [英] PHP script to extract artist & title from Shoutcast/Icecast stream

查看:34
本文介绍了PHP 脚本来提取艺术家 &来自 Shoutcast/Icecast 流的标题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我找到了一个可以提取艺术家的脚本来自 Icecast 或 Shoutcast 流的标题名称.我希望脚本在歌曲更改时自动更新,目前它仅在我执行时才起作用.我是 PHP 新手,所以任何帮助将不胜感激.谢谢!

define('CRLF', "
");类流信息{公共 $valid = false;公共 $useragent = 'Winamp 2.81';受保护的 $headers = array();受保护的 $metadata = array();公共函数 __construct($location){$errno = $errstr = '';$t = parse_url($location);$sock = fsockopen($t['host'], $t['port'], $errno, $errstr, 5);$path = isset($t['path'])?$t['path']:'/';如果($袜子){$request = 'GET '.$path.'HTTP/1.0' .CRLF .'主持人: ' .$t['host'] .CRLF .'连接:关闭'.CRLF .'用户代理: ' .$this->useragent .CRLF .'接受: */*' .CRLF .'冰元数据:1'.CRLF.'冰预缓冲:65536'.CRLF.(isset($t['user'])?'Authorization: Basic '.base64_encode($t['user'].':'.$t['pass']).CRLF:'').X-TipOfTheDay:Winamp经典"统治了所有这些..CRLF .CRLF;如果 (fwrite($sock, $request)){$theaders = $line = '';而 (!feof($sock)){$line = fgets($sock, 4096);if('' == trim($line)){休息;}$theaders .= $line;}$theaders = 爆炸(CRLF,$theaders);foreach ($theaders 作为 $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));如果($价值!= ''){如果 (is_numeric($value)){$this->headers[$name] = (int)$value;}别的{$this->headers[$name] = $value;}}}}if (!isset($this->headers['icymetaint'])){$数据 = '';$metainterval = 512;while(!feof($sock)){$data .= fgetc($sock);if (strlen($data) >= $metainterval) 中断;}$this->print_data($data);$matches = array();preg_match_all('/([x00-xff]{2})x0x0([a-z]+)=/i', $data, $matches, PREG_OFFSET_CAPTURE);preg_match_all('/([a-z]+)=([a-z0-9()[]., ]+)/i', $data, $matches, PREG_SPLIT_NO_EMPTY);echo '<pre>';var_dump($matches);echo '</pre>';$title = $artist = '';foreach ($matches[0] as $nr => $values){$offset = $values[1];$length = ord($values[0]{0}) +(ord($values[0]{1}) * 256)+(ord($values[0]{2}) * 256*256)+(ord($values[0]{3}) * 256*256*256);$info = substr($data, $offset + 4, $length);$seperator = strpos($info, '=');$this->metadata[substr($info, 0, $seperator)] = substr($info, $seperator + 1);if (substr($info, 0, $seperator) == 'title') $title = substr($info, $seperator + 1);if (substr($info, 0, $seperator) == 'artist') $artist = substr($info, $seperator + 1);}$this->metadata['streamtitle'] = $artist .' - ' .$title;}别的{$metainterval = $this->headers['icymetaint'];$intervals = 0;$元数据 = '';而(1){$数据 = '';while(!feof($sock)){$data .= fgetc($sock);if (strlen($data) >= $metainterval) 中断;}//$this->print_data($data);$len = join(unpack('c', fgetc($sock))) * 16;如果 ($len > 0){$metadata = str_replace("", '', fread($sock, $len));休息;}别的{$间隔++;如果 ($intervals > 100) 中断;}}$metarr = expand(';', $metadata);foreach ($metarr 作为 $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);}如果($价值!= ''){$this->metadata[$name] = $value;}}}}fclose($sock);$this->valid = true;}else echo '无法写入.';}else echo '无套接字'.$errno.'- '.$errstr.'.';}公共函数打印数据($数据){$data = str_split($data);$c = 0;$string = '';echo "

000000 ";foreach ($data as $char){$string .= addcslashes($char, "

	");$hex = dechex(join(unpack('C', $char)));if ($c % 4 == 0) echo ' ';如果 ($c % (4*4) == 0 && $c != 0){foreach (str_split($string) as $s){//echo " $string
";如果 (ord($s) <32 || ord($s) > 126){echo '\'.ord($s);}别的{回声 $s;}}回声
";$string = '';echo str_pad($c, 6, '0', STR_PAD_LEFT).'';}如果 (strlen($hex) <1) $hex = '00';if (strlen($hex) <2) $hex = '0'.$hex;回声 $hex.'';$c++;}echo " $string
</pre>";}公共函数 __get($name){if (isset($this->metadata[$name])){返回 $this->metadata[$name];}if (isset($this->headers[$name])){返回 $this->headers[$name];}返回空;}}$t = new streaminfo('http://64.236.34.196:80/stream/1014');//获取元数据回声元间隔:$t->icymetaint;回声当前曲目:$t->streamtitle;

解决方案

如果你想运行 PHP 脚本来保持你的元数据是最新的(我假设你正在制作一个网站并在这里使用 html 音频标签) 您可以将 ontimeupdate 事件与 ajax 函数一起使用.如果不是,您可能应该查找类似的音频播放文档.

你可以在这里找到一个很好的例子 http://www.w3schools.com/php/php_ajax_php.asp

您想在脚本的最后使用一个 php 变量一次使用 PHP 回显功能所有相关信息.

然后使用 .onreadystatechange 调用的函数通过使用 .resonseText(这将包含与您的 PHP 脚本的回显相同的内容)来修改您想要在您的网站上显示的特定元素.

I found a script which can extract the artist & title name from an Icecast or Shoutcast stream. I want the script to update automatically when a song changed, at the moment its working only when i execute it. I'm new to PHP so any help will be appreciated. Thanks!

define('CRLF', "
");

class streaminfo{
public $valid = false;
public $useragent = 'Winamp 2.81';

protected $headers = array();
protected $metadata = array();

public function __construct($location){
    $errno = $errstr = '';
    $t = parse_url($location);
    $sock = fsockopen($t['host'], $t['port'], $errno, $errstr, 5);
    $path = isset($t['path'])?$t['path']:'/';
    if ($sock){
        $request = 'GET '.$path.' HTTP/1.0' . CRLF . 
            'Host: ' . $t['host'] . CRLF . 
            'Connection: Close' . CRLF . 
            'User-Agent: ' . $this->useragent . CRLF . 
            'Accept: */*' . CRLF . 
            'icy-metadata: 1'.CRLF.
            'icy-prebuffer: 65536'.CRLF.
            (isset($t['user'])?'Authorization: Basic '.base64_encode($t['user'].':'.$t['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'])){
                $data = ''; $metainterval = 512;
                while(!feof($sock)){
                    $data .= fgetc($sock);
                    if (strlen($data) >= $metainterval) break;
                }
               $this->print_data($data);
                $matches = array();
                preg_match_all('/([x00-xff]{2})x0x0([a-z]+)=/i', $data, $matches, PREG_OFFSET_CAPTURE);
               preg_match_all('/([a-z]+)=([a-z0-9()[]., ]+)/i', $data, $matches, PREG_SPLIT_NO_EMPTY);
               echo '<pre>';var_dump($matches);echo '</pre>';
                $title = $artist = '';
                foreach ($matches[0] as $nr => $values){
                  $offset = $values[1];
                  $length = ord($values[0]{0}) + 
                            (ord($values[0]{1}) * 256)+ 
                            (ord($values[0]{2}) * 256*256)+ 
                            (ord($values[0]{3}) * 256*256*256);
                  $info = substr($data, $offset + 4, $length);
                  $seperator = strpos($info, '=');
                  $this->metadata[substr($info, 0, $seperator)] = substr($info, $seperator + 1);
                    if (substr($info, 0, $seperator) == 'title') $title = substr($info, $seperator + 1);
                    if (substr($info, 0, $seperator) == 'artist') $artist = substr($info, $seperator + 1);
                }
                $this->metadata['streamtitle'] = $artist . ' - ' . $title;
            }else{
                $metainterval = $this->headers['icymetaint'];
                $intervals = 0;
                $metadata = '';
                while(1){
                    $data = '';
                    while(!feof($sock)){
                        $data .= fgetc($sock);
                        if (strlen($data) >= $metainterval) break;
                    }
                    //$this->print_data($data);
                    $len = join(unpack('c', fgetc($sock))) * 16;
                    if ($len > 0){
                        $metadata = str_replace("", '', 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 != ''){
                            $this->metadata[$name] = $value;
                        }
                    }
                }
            }
            fclose($sock);
            $this->valid = true;
        }else echo 'unable to write.';
    }else echo 'no socket '.$errno.' - '.$errstr.'.';
}


public function print_data($data){
    $data = str_split($data);
    $c = 0;
    $string = '';
    echo "<pre>
000000 ";
    foreach ($data as $char){
        $string .= addcslashes($char, "

	");
        $hex = dechex(join(unpack('C', $char)));
        if ($c % 4 == 0) echo ' ';
        if ($c % (4*4) == 0 && $c != 0){
          foreach (str_split($string) as $s){
            //echo " $string
";
            if (ord($s) < 32 || ord($s) > 126){
              echo '\'.ord($s);
            }else{
              echo $s;
            }
          }
          echo "
";
          $string = '';
          echo str_pad($c, 6, '0', STR_PAD_LEFT).'  ';
        }
        if (strlen($hex) < 1) $hex = '00';
        if (strlen($hex) < 2) $hex = '0'.$hex;
          echo $hex.' ';
        $c++;
    }
    echo "  $string
</pre>";
}

public function __get($name){
    if (isset($this->metadata[$name])){
        return $this->metadata[$name];
    }
    if (isset($this->headers[$name])){
        return $this->headers[$name];
    }
    return null;
 }
}

$t = new streaminfo('http://64.236.34.196:80/stream/1014'); // get metadata


echo Meta Interval: $t->icymetaint;
echo Current Track: $t->streamtitle;

解决方案

If you want to run the PHP script to keep your meta data up to date (I'm assuming you're making a website and using html audio tags here) you can use the ontimeupdate event with an ajax function. If you're not you probably should look up your audio playback documentation for something similar.

<audio src="http://ip:port/;" ontimeupdate="loadXMLDoc()">

You can find a great example here http://www.w3schools.com/php/php_ajax_php.asp

You want to use the PHP echo function all the relevant information at once using one php variable at the very end of your script.

<?php ....
$phpVar=$streamtitle;
$phpVar2=$streamsong;
$result="I want my string to look like this: <br> {$phpVar} {$phpVar2}";
echo $result;
?>

and then use the function called by the .onreadystatechange to modify the particular elements you want on your website by using the .resonseText (this will contain the same content as your PHP script's echo).

这篇关于PHP 脚本来提取艺术家 &amp;来自 Shoutcast/Icecast 流的标题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆