Что мы получим в конце:
Здесь вы можете скачать архив и посмотреть представленное демо:
Демо | Скачать архив
Внимание! У вас нет прав для просмотра скрытого текста.
Этап 1 – HTML-код
Так выглядит код одного из файлов, использующегося в шаблоне. Давайте посмотрим на шаблон основной (index) страницы. Итак:
templates/main_page.html
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="utf-8" />
<title>Stream Radio Script | Script Tutorials</title>
<link href="css/main.css" rel="stylesheet" type="text/css" />
<link href="css/radio.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script>
google.load("jquery", "1.7.1");
</script>
<script src="js/script.js"></script>
</head>
<body>
<header>
<h2>Stream Radio Script</h2>
<a href="http://www.script-tutorials.com/stream-radio-script/" class="stuts">Back to original tutorial on <span>Script Tutorials</span></a>
</header>
<div class="container">
<form method="get" class="header" action="javascript:void(0)" onsubmit="get_stations_by_keyword(); return false;">
<input type="text" id="search" value="Search" name="s">
<span>
<div id="rplayer">
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="191" height="46" bgcolor="#FFFFFF">
<param name="movie" value="player/ffmp3-config.swf" />
<param name="flashvars" value="url=http://scfire-dtc-aa04.stream.aol.com:80/stream/1013/&lang=en&codec=mp3&volume=100&introurl=media/welcome.mp3&autoplay=true&traking=false&jsevents=false&buffering=5&skin=player/def/skin.xml&title=SKY.FM 80s" />
<param name="wmode" value="opaque" />
<param name="allowscriptaccess" value="always" />
<param name="scale" value="noscale" />
<embed src="player/ffmp3-config.swf" flashvars="url=http://scfire-dtc-aa04.stream.aol.com:80/stream/1013/&lang=en&codec=mp3&volume=100&introurl=media/welcome.mp3&autoplay=true&traking=false&jsevents=false&buffering=5&skin=player/def/skin.xml&title=SKY.FM 80s" width="191" scale="noscale" height="46" wmode="opaque" bgcolor="#FFFFFF" allowscriptaccess="always" type="application/x-shockwave-flash" />
</object>
</div>
</span>
</form>
<div class="clear"></div>
<div class="genres_par">
<ul class="genres">
<li id="1" val="Alternative"><a href="javascript:void(0)">Alternative</a>
<ul>
<li id="11" val="Classic+Alternative"><a href="javascript:void(0)">Classic Alternative</a></li>
<li id="12" val="Industrial"><a href="javascript:void(0)">Industrial</a></li>
<li id="13" val="New+Wave"><a href="javascript:void(0)">New Wave</a></li>
<li id="14" val="Punk"><a href="javascript:void(0)">Punk</a></li>
</ul>
</li>
<li id="2" val="Classical"><a href="javascript:void(0)">Classical</a>
<ul>
<li id="21" val="Modern"><a href="javascript:void(0)">Modern</a></li>
<li id="22" val="Opera"><a href="javascript:void(0)">Opera</a></li>
<li id="23" val="Piano"><a href="javascript:void(0)">Piano</a></li>
<li id="24" val="Romantic"><a href="javascript:void(0)">Romantic</a></li>
<li id="25" val="Symphony"><a href="javascript:void(0)">Symphony</a></li>
</ul>
</li>
<li id="3" val="Electronic"><a href="javascript:void(0)">Electronic</a>
<ul>
<li id="31" val="Breakbeat"><a href="javascript:void(0)">Breakbeat</a></li>
<li id="32" val="Dance"><a href="javascript:void(0)">Dance</a></li>
<li id="33" val="Electro"><a href="javascript:void(0)">Electro</a></li>
<li id="34" val="House"><a href="javascript:void(0)">House</a></li>
<li id="35" val="Techno"><a href="javascript:void(0)">Techno</a></li>
<li id="36" val="Trance"><a href="javascript:void(0)">Trance</a></li>
</ul>
</li>
<li id="4" val="Metal"><a href="javascript:void(0)">Metal</a>
<ul>
<li id="41" val="Classic+Metal"><a href="javascript:void(0)">Classic Metal</a></li>
<li id="42" val="Heavy+Metal"><a href="javascript:void(0)">Heavy Metal</a></li>
<li id="43" val="Metalcore"><a href="javascript:void(0)">Metalcore</a></li>
<li id="44" val="Power+Metal"><a href="javascript:void(0)">Power Metal</a></li>
</ul>
</li>
<li id="5" val="Pop"><a href="javascript:void(0)">Pop</a>
<ul>
<li id="51" val="Dance+Pop"><a href="javascript:void(0)">Dance Pop</a></li>
<li id="52" val="Oldies"><a href="javascript:void(0)">Oldies</a></li>
<li id="53" val="Top+40"><a href="javascript:void(0)">Top 40</a></li>
<li id="54" val="World+Pop"><a href="javascript:void(0)">World Pop</a></li>
</ul>
</li>
</ul>
<div class="clear"></div>
</div>
<div class="stlist">__stations__</div>
<div class="clear"></div>
<div class="cred">Powered by <a href="http://www.script-tutorials.com/">Script Tutorials</a></div>
</div>
</body>
</html>
Во-первых, обратите внимание на то, как скрипт подгружает библиотеку jquery из Google. Это может быть очень полезным, если вы не хотели бы размещать дополнительные файлы у себя на хостинге. Наш элемент шапки состоит из красивой поисковой строки и встроенного jasl-плеера. В примере используется великолепный FFMp3 Live Stream Player. Вы можете поближе познакомиться с ним здесь: http://ffmp3.sourceforge.net/. Он позволяет нам воспроизводить аудио-поток без каких-либо проблем. Далее, в левой панели (под шапкой), у нас UL-LI список категорий (и подкатегорий). В правой панели у нас имеется список последних прослушанных радиостанций (при выборе категорий и при осуществлении поиска список в правой панели будет обновляться и фильтроваться за счет AJAX). Сейчас он содержит __stations__ key (ключ шаблона), который мы заменим актуальным значением PHP. Наш следующий файл шаблона – шаблон самого радио-плеера:
templates/radio.html
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="191" height="46" bgcolor="#FFFFFF">
<param name="movie" value="player/ffmp3-config.swf" />
<param name="flashvars" value="url=__stream__&lang=en&codec=mp3&volume=100&introurl=&autoplay=true&traking=false&jsevents=false&buffering=5&skin=player/def/skin.xml&title=__title__" />
<param name="wmode" value="opaque" />
<param name="allowscriptaccess" value="always" />
<param name="scale" value="noscale" />
<embed src="player/ffmp3-config.swf" flashvars="url=__stream__&lang=en&codec=mp3&volume=100&introurl=&autoplay=true&traking=false&jsevents=false&buffering=5&skin=player/def/skin.xml&title=__title__" width="191" scale="noscale" height="46" wmode="opaque" bgcolor="#FFFFFF" allowscriptaccess="always" type="application/x-shockwave-flash" />
</object>
Конечно же, он содержит собственные ключи шаблона (__title__ and __stream__), которыми мы воспользуемся позже.
Этап 2 – CSS-код
Теперь перейдем к нашим файлам каскадных таблиц стилей:
css/main.css
Первый файл содержит только стили тестовой страницы (данный файл всегда доступен в архиве).
css/radio.css
/* header area */
.header {
height:62px;
}
.header input {
background:#aaa url(../images/search.png) no-repeat 5px center;
border:1px solid #888;
border-radius:10px;
float:right;
margin:14px 10px 0 0;
outline:none;
padding-left:20px;
width:200px;
-webkit-transition: 0.5s;
-moz-transition: 0.5s;
-o-transition: 0.5s;
transition: 0.5s;
}
.header input:focus {
background-color:#eee;
width:300px;
}
.header > span {
display:block;
float:left;
line-height:40px;
padding:7px;
-webkit-transition: 0.5s;
-moz-transition: 0.5s;
-o-transition: 0.5s;
transition: 0.5s;
}
/* stations list */
.stlist {
float:right;
margin-right:1%;
width:71%;
}
.stlist ul {
list-style:none outside none;
margin:0;
padding:0;
}
.stlist ul li {
border-bottom:1px dotted #444;
overflow:hidden;
padding:10px;
}
.stlist ul li > a > img {
border:1px solid #CCC;
float:left;
height:85px;
margin-right:15px;
padding:1px;
width:85px;
}
.stlist ul li > div {
float:right;
margin-left:15px;
margin-top:-5px;
}
.stlist ul li > p.label,.stlist ul li > p.track {
font-size:11px;
font-weight:700;
}
.stlist ul li > p.label {
color:#888;
}
.stlist ul li > p.channel {
font-size:14px;
font-weight:700;
margin-bottom:17px;
}
/* genres list */
.genres_par {
border-right:1px solid #ccc;
float:left;
width:26%;
}
ul.genres,ul.genres ul {
list-style-type:none;
margin:0;
padding:0;
}
ul.genres ul {
display:none;
overflow:hidden;
padding:0 15px;
}
ul.genres ul li {
margin:3px;
}
ul.genres a {
color:#333;
display:block;
font-size:18px;
padding:4px 0;
text-align:center;
text-decoration:none;
}
ul.genres ul a {
font-size:12px;
text-align:left;
}
ul.genres li {
border-bottom:1px solid #CCC;
margin:0;
}
ul.genres li ul li a {
background:none repeat scroll 0 0 #5bb951;
border-radius:2px;
color:#FFF;
font-size:12px;
padding:6px;
}
ul.genres li ul li a:hover {
background-color:#53854E;
}
Этап 3 – JS-код
js/script.js
$(document).ready(function(){
$('#search').blur(function() {
if ('' == $('#search').val()) $('#search').val('Search');
});
$('#search').focus(function() {
if ('Search' == $('#search').val()) $('#search').val('');
});
$('ul.genres li a').click( // category slider
function() {
var checkElement = $(this).next();
if((checkElement.is('ul')) && (!checkElement.is(':visible'))) {
$('.genres li ul').slideUp(150);
$(this).next().slideToggle(150);
}
}
);
$('ul.genres ul li a').click( // get stations by category
function() {
$.ajax({
type: 'GET',
url: 'index.php',
data: 'action=get_genre_stations&id=' + $(this).parent().attr('id') + '&name=' + $(this).parent().attr('val'),
success: function(data){
$('.stlist').fadeOut(400, function () {
$('.stlist').html(data);
$('.stlist').fadeIn(400);
});
}
});
}
);
});
function play(id) { // play function
$('#rplayer').load('index.php?action=play&id=' + id, function() {});
return false;
}
function get_stations_by_keyword() { // get stations by keyword
var keyword = $('#search').val().replace(/ /g,"+");
$.ajax({
type: 'GET',
url: 'index.php',
data: 'action=get_keyword_stations&key=' + keyword,
success: function(data){
$('.stlist').fadeOut(400, function () {
$('.stlist').html(data);
$('.stlist').fadeIn(400);
});
}
});
}
Как видно, здесь нет ничего сложного. Всего лишь несколько контроллеров событий и две новые функции (для воспроизведения радио-станции и осуществления поиска станций по ключевому запросу).
Этап 4 – PHP-код
index.php
<?php
// set error reporting level
if (version_compare(phpversion(), '5.3.0', '>=') == 1)
error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED);
else
error_reporting(E_ALL & ~E_NOTICE);
$aStations = array(
0 => array(
'category' => 31,
'name' => 'EuroDance',
'desc' => 'The newest and best of Eurodance hits',
'url' => 'http://www.di.fm/eurodance',
'br' => 96,
'stream' => 'http://scfire-mtc-aa06.stream.aol.com:80/stream/1024'
),
1 => array (
'category' => 34,
'name' => 'House',
'desc' => 'Silky sexy deep house music direct from New York city!',
'url' => 'http://www.di.fm/house',
'br' => 96,
'stream' => 'http://scfire-ntc-aa04.stream.aol.com:80/stream/1007'
),
2 => array (
'category' => 13,
'name' => 'Trance',
'desc' => 'The hottest, freshest trance music from around the globe!',
'url' => 'http://www.di.fm/trance',
'br' => 96,
'stream' => 'http://scfire-ntc-aa04.stream.aol.com:80/stream/1003'
),
3 => array (
'category' => 51,
'name' => 'Electro House',
'desc' => 'An eclectic mix of electro and dirty house',
'url' => 'http://www.di.fm/electro',
'br' => 96,
'stream' => 'http://scfire-ntc-aa04.stream.aol.com:80/stream/1025'
)
);
function searchByCat($iCat, $aStations) {
$aRes = array();
foreach ($aStations as $i => $aInfo) {
if ($aInfo['category'] == $iCat) {
$aRes[$i] = $aInfo;
}
}
return $aRes;
}
function searchByKeyword($sKey, $aStations) {
$aRes = array();
foreach ($aStations as $i => $aInfo) {
if (false !== strpos($aInfo['name'], $sKey) || false !== strpos($aInfo['desc'], $sKey)) {
$aRes[$i] = $aInfo;
}
}
return $aRes;
}
function parseStationList($aData) {
$sStations = '';
if (is_array($aData) && count($aData) > 0) {
foreach ($aData as $i => $a) {
$sStationId = $i;
$sStationBr = (int)$a['br'];
$sStationName = $a['name'];
$sStationDesc = $a['desc'];
$sStationUrl = $a['url'];
$sThumb = 'media/'.($sStationId+1).'.png';
$sStations .= <<<EOF
<li>
<a href="{$sStationId}" onclick="return play('{$sStationId}'); return false;"><img alt="{$sStationName}" src="{$sThumb}" title="{$sStationName}"></a>
<div class="i">
<p>Bitrate: {$sStationBr}</p>
</div>
<p class="channel"><a href="{$sStationId}" onclick="return play('{$sStationId}'); return false;">{$sStationName}</a></p>
<p class="track">{$sStationDesc}</p>
<p class="label">{$sStationUrl}</p>
</li>
EOF;
}
}
$sStations = ($sStations == '') ? '<li>Nothing found</li>' : $sStations;
return '<ul>' . $sStations . '</ul>';
}
switch ($_GET['action']) {
case 'play':
$i = (int)$_GET['id'];
$aInfo = $aStations[$i];
$aVars = array (
'__stream__' => $aInfo['stream'],
'__title__' => $aInfo['name']
);
echo strtr(file_get_contents('templates/radio.html'), $aVars); exit;
break;
case 'get_genre_stations':
$i = (int)$_GET['id'];
$aSearch = searchByCat($i, $aStations);
$sStations = parseStationList($aSearch);
header('Content-Type: text/html; charset=utf-8');
echo $sStations; exit;
break;
case 'get_keyword_stations':
$sKey = $_GET['key'];
$aSearch = searchByKeyword($sKey, $aStations);
$sStations = parseStationList($aSearch);
header('Content-Type: text/html; charset=utf-8');
echo $sStations; exit;
break;
}
$sLastStations = parseStationList($aStations);
echo strtr(file_get_contents('templates/main_page.html'), array('__stations__' => $sLastStations));
В самом начале был подготовлен список радио-станций (всего 4 станции). Далее идут функции поиска: searchByCat и searchByKeyword. После, у нас идет специальная функция parseStationList, которая трансформирует массив с фильтрованными станциями в HTML. И, наконец, небольшой переключатель для управления внутренними ajax-командами.
Завершение
Вы всегда можете модифицировать или изменить этот скрипт радио, но не забывайте делиться собственными идеями и результатами. Было бы интересно посмотреть, что получится у вас! Удачи!