Если вы задумываете разработку собственной программы для интернет-радио, то мы бы хотели поделиться с вами этим опытом.
В этой статье пойдет речь о создании радио-скрипта с прекрасным дизайном (CSS3). Он будет состоять из трёх основных элементов: шапки (с красиво анимированной поисковой строкой и интегрированным радио-плеером), левой панели (со списком категорий и подкатегорий) и правой панели (которая будет содержать список последних или отфильтрованных станций).
Шаг 1. HTML разметка
Вот разметка одного из используемых нами файлов шаблонов.
Шаблон главной (индексной) страницы:
templates/main_page.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
<!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 плеер.
Идём дальше: слева (под шапкой) у нас UL
-LI
-список категорий (с подкатегориями). Правая панель будет содержать список последних станций, а когда мы ищем или выбираем категории – содержимое правой панели будет отфильтровано с помощью Ajax. Пока здесь содержится __stations__
key (ключ шаблона), который мы заменим на действительное значение с помощью PHP.
Далее шаблон радио-плеера:
templates/radio.html
1 2 3 4 5 6 7 8 |
<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__
и __stream__
), которые мы будет использовать позже.
Шаг 2. CSS
Вот наши CSS файлы:
css/radio.css
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
/* область шапки */ .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; } /* список станций */ .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_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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
$(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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
<?php // установка уровня сообщений об ошибках 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 формат. И последнее – небольшой switch-case
для выполнения наших внутренних ajax команд.
Выводы
Вам никогда не помешает улучшить скрипт и попытаться реализовать свои идеи. Будем рады увидеть ваши предложения и замечания по этому поводу. Удачи!
IE 9 и ниже, выдают предупреждение об ошибке, хотя всё нормально работает. Интересно, в чём именно IE находит ошибку. И сам плеер в IE с черным бэкграундом вместо белого или прозрачного.
Здравствуйте! хотел бы спросить, возможно ли в начале вашей этой статьи разместить мои два предложения со ссылкой(ссылку можно закрыть для поисковых систем) на сервис по созданию кода радио для сайта? Примерно в таком стиле: «Если вы хотите быстро создать скрипт радио для своего сайта, то предлагаем Вам посмотреть этот сервис». Если согласны, прошу напишите мне вашу цену мне на stas-serov@mail.ru