14.08.14, 23:29
0 комментарий
  Уроки

Скрипт для считывания информации с аудио-потока

Сегодня мы хотели бы рассказать вам о том, как можно получить информацию из аудио-потока. Однако для начала небольшая предыстория. С незапамятных времен музыка была одним из наиболее востребованных видов искусства. Все любят слушать и наслаждаться любимой музыкой. Сегодня мы хотели бы рассказать вам о чем-то напрямую связанным с музыкой. Как известно, сегодня в интернете можно найти множество радиостанций, и буквально каждый из нас может без проблем создать собственную радиостанцию. Другие люди, слушатели, могут прослушивать эти потоки информации.

Зачастую радиостанции представляют собой бесконечный поток информации, передающийся по двум наиболее распространенным протоколам: Shoutcast или Icecast (это интернет-серверы вещания). Некоторое время назад нам нужно было использовать всевозможые flash-плееры для того, чтобы слушать эти станции, однако с приходом HTML5 ситуация значительно изменилась. HTML5 представила нам новый элемент 'audio', который позволяет работать с аудио-потоками.



Мы можем извлекать различную информацию из этих потоков, будь то информация о сервере, заголовки, описание, тип аудио, битрейт, количество слушателей, жанр музыки, имя исполнителя текущей песни, а также просматривать историю воспроизведенных треков.

PHP-код

Для начала, давайте рассмотрим рабочий процесс с Icecast. Сервер Icecast предлагает всю статистику в файле status.xsl. Следовательно, нам нужно скачать его, а затем пропарсить для того, чтобы получить всю информацию. Мы подготовили следующий класс, который собирает данную информацию (при помощи CURL):

class IceCast {
  var $server = '';
  var $stats_file = "/status.xsl";
  var $radio_info = array();

  function __construct() {
    //build array to store our radio stats for later use        
    $this->radio_info['server'] = $this->server;
    $this->radio_info['title'] = 'Offline';
    $this->radio_info['description'] = 'Radio offline';
    $this->radio_info['content_type'] = '';
    $this->radio_info['mount_start'] = '';
    $this->radio_info['bit_rate'] = '';
    $this->radio_info['listeners'] = '';
    $this->radio_info['most_listeners'] = '';
    $this->radio_info['genre'] = '';
    $this->radio_info['url'] = '';
    $this->radio_info['now_playing'] = array();
    $this->radio_info['now_playing']['artist'] = 'Unknown';
    $this->radio_info['now_playing']['track'] = 'Unknown';
  }

  function setUrl($url) {
    $this->server = $url;
    $this->radio_info['server'] = $this->server;
  }

  private function fetch() {
    //create a new curl resource
    $ch = curl_init();

    //set url
    curl_setopt($ch,CURLOPT_URL, $this->server . $this->stats_file);

    //return as a string
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

    //$output = our stauts.xsl file
    $output = curl_exec($ch);

    //close curl resource to free up system resources
    curl_close($ch);

    return $output;
  }

  function getStatus() {
    $output = $this->fetch();

    //loop through $ouput and sort into our different arrays
    $temp_array = array();

    $search_for = "<tds[^>]*class="streamdata">(.*)</td>";
    $search_td = array('<td class="streamdata">', '</td>');


    if (preg_match_all("/$search_for/siU", $output, $matches)) {
      foreach ($matches[0] as $match) {
        $to_push = str_replace($search_td, '', $match);
        $to_push = trim($to_push);
        array_push($temp_array, $to_push);
      }
    }

    if (count($temp_array)) {
      //sort our temp array into our ral array
      $this->radio_info['title'] = $temp_array[0];
      $this->radio_info['description'] = $temp_array[1];
      $this->radio_info['content_type'] = $temp_array[2];
      $this->radio_info['mount_start'] = $temp_array[3];
      $this->radio_info['bit_rate'] = $temp_array[4];
      $this->radio_info['listeners'] = $temp_array[5];
      $this->radio_info['most_listeners'] = $temp_array[6];
      $this->radio_info['genre'] = $temp_array[7];
      $this->radio_info['url'] = $temp_array[8];

      if (isset($temp_array[9])) {
        $x = explode(" - ", $temp_array[9]);
        $this->radio_info['now_playing']['artist'] = $x[0];
        $this->radio_info['now_playing']['track'] = $x[1];
      }
    }
    return $this->radio_info;
  }
}


Сервер Shoutcast предлагает информацию в других файлах: index.html содержит общую информацию о статусе сервера, статусе потока, количестве слушателей, типе аудио, жанре и воспроизводимой песне. Кроме этой информации, сервер также предлагает другой файл, played.html, в котором содержится история песен (этот файл также очень полезен). Мы решили отобразить все доступные значения при помощи foreach:

// get the stream content
$html = file_get_contents(rtrim($url, '/').'/index.html');

// create a new domDocument and load the stream response
$dom = new domDocument;
$dom->loadHTML($html);

// parse the result
$tables = $dom->getElementsByTagName('table');
$rows = $tables->item(3)->getElementsByTagName('tr');
foreach ($rows as $row) {
  $cols = $row->getElementsByTagName('td');

  if (!strstr($cols->item(0)->nodeValue,'@')) {
    $result .= '<div><strong>' . $cols->item(0)->nodeValue . '</strong> ' . $cols->item(1)->nodeValue;

    if ($cols->item(2)->nodeValue)
        $result .= ' *'.$cols->item(2)->nodeValue.'*';

    $result .= '</div>';
  }
}


HTML

HTML-код довольно простой:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <meta property="og:site_name" content="Script Tutorials" />
  <meta property="og:title" content="Script to read information from audio stream | Script Tutorials" />
  <meta property="og:image" content="http://www.script-tutorials.com/demos/398/thumb.png" />
  <meta property="og:type" content="website" />
  <meta name="description" content="Script to read information from audio stream - Script Tutorials">
  <title>Script to read information from audio stream | Script Tutorials</title>
  <link href="css/style.css" rel="stylesheet">
</head>
<body>
  <div class="container">
    <form method="post">
      <h1>Script to read information from audio stream
          <span>Here you can put a stream URL to get it's details</span>
          <span>e.g. http://81.173.3.250:80 (Shoutcast) or http://50-7-66-170.webnow.net.br:80 (Icecast)</span>
      </h1>
      <label><span>Stream URL:</span><input type="url" name="url" placeholder="stream url" /></label>
      <label><span>Stream type:</span>
        <select name="type">
          <option value="s">Shoutcast</option>
          <option value="i">Icecast</option>
        </select>
      </label>
      <label><span>&nbsp;</span><input type="submit" class="button" value="Display info" /></label>
    </form>
    <?= $result ?>
  </div><!--/.container-->
</body>
</html>


Здесь мы просто заставляем форму получать параметры url и type и отобразить результаты.

CSS

Наконец, дабы результат получился более привлекательным, мы подготовили следующие стили:

css/style.css

body {
  font-family: 'Verdana', sans-serif;
}
.container {
  margin: 50px auto 0;
  width: 50%;
}
form {
  margin-right: auto;
  margin-left: auto;
  background: #EEE;
  padding: 20px 30px 20px 30px;
  font-size: 12px;
  color: #888;
  border:1px solid #DADADA;
}
form h1 {
  padding-bottom: 10px;
  display: block;
  border-bottom: 1px solid #DADADA;
}
form h1>span {
  display: block;
  font-size: 11px;
}
form label {
  display: block;
  margin: 0px 0px 5px;
  overflow: hidden;
}
form label>span {
  float: left;
  width: 20%;
  text-align: right;
  padding-right: 1%;
  margin-top: 10px;
}
form input[type="text"], input[type="url"], form input[type="email"], form textarea,form select{
  border: 1px solid #DADADA;
  height: 24px;
  margin-bottom: 16px;
  margin-top: 2px;
  outline: 0 none;
  padding: 3px 3px 3px 5px;
  width: 76%;
  font: normal 12px/12px;
}
form select {
  width: 78%;
  height: 30px;
}
form .button {
  background: #E48F8F;
  border: none;
  padding: 10px 25px 10px 25px;
  color: #FFF;
  cursor: pointer;
}
form .button:hover {
  background: #CF7A7A
}


В завершение

Сегодня мы научились получать всю необходимую информацию из аудио-потоков. И на сегодня все! Хотим поблагодарить вас за ваше внимание. Если вам понравилось то, что мы сегодня сделали, то, пожалуйста, поделитесь этой информацией с вашими друзьями в социальных сетях или расскажите, что вы думаете, в поле комментариев.

Исходники можно получить в архиве.

СКАЧАТЬ

Вес файла
4.03 Kb

Напишите своё мнение