PVL API phase 1!

This commit is contained in:
Buster Neece 2014-03-12 03:02:28 -05:00
parent 4ff2003a05
commit ef1e1f117d
23 changed files with 551 additions and 197 deletions

View File

@ -10,7 +10,7 @@ $skin = \PVL\Customization::get('theme');
<li class="divider">&nbsp;</li>
<li><a href="<?=$this->route(array('controller' => 'account', 'action' => 'theme', 'skin' => 'toggle')) ?>"><i class="icon-adjust"></i> <? if ($skin == 'light'): ?>Dark Theme<? else: ?>Light Theme<? endif; ?></a></li>
<li class="divider">&nbsp;</li>
<li><a href="<?=$this->route(array('module' => 'default', 'controller' => 'index', 'action' => 'tunein', 'origin' => 'home')) ?>" id="btn-tune-in"><i class="icon-youtube-play"></i> Player</a></li>
<li><a href="<?=$this->route(array('module' => 'mobile')) ?>" id="btn-tune-in"><i class="icon-youtube-play"></i> Player</a></li>
<li class="divider">&nbsp;</li>
<li><a href="<?=$this->route(array('module' => 'default', 'controller' => 'index', 'action' => 'app')) ?>"><i class="icon-cloud-download"></i> Plugins &amp; Apps</a></li>
<li class="divider">&nbsp;</li>

View File

@ -60,10 +60,12 @@ echo $this->headLink()."\n";
echo $this->headScript()."\n";
?>
<script>
document.domain = 'ponyvillelive.com';
var DF_ContentPath = '<?php echo \DF\Url::content(); ?>';
var DF_IsApp = false;
</script>
</head>
<body class="<?=$this->body_class ?>">
<body>
<!-- Google Universal Analytics -->
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
@ -76,50 +78,52 @@ ga('send', 'pageview');
</script>
<!-- End Google Universal Analytics -->
<!-- Header -->
<div data-role="header" data-position="fixed" data-tap-toggle="false" data-theme="a">
<a id="btn_back" href="#" data-rel="back" class="ui-btn-left ui-alt-icon ui-nodisc-icon ui-btn ui-icon-carat-l ui-btn-icon-notext ui-corner-all" data-role="button" role="button">Back</a>
<h1><?=$title ?></h1>
</div>
<!-- Main Body -->
<div id="page" data-role="page" data-title="<?=$title ?>" class="jqm-demos">
<div role="main" class="ui-content jqm-content jqm-fullwidth">
<?php echo $this->layout()->content; ?>
</div>
</div>
<!-- Footer Nav -->
<div data-role="footer" data-position="fixed" data-tap-toggle="false" data-theme="a">
<div id="player_controls" data-role="controlgroup">
<a class="ui-corner-all ui-btn ui-btn-left" id="player_pause">Stop</a>
<input type="range" class="volume_slider" name="player_volume" id="player_volume" min="0" max="100" value="50" data-role="none" data-highlight="true">
<div id="webapp">
<!-- Header -->
<div data-role="header" data-position="fixed" data-tap-toggle="false" data-theme="a">
<a id="btn_back" href="#" data-rel="back" class="ui-btn-left ui-alt-icon ui-nodisc-icon ui-btn ui-icon-carat-l ui-btn-icon-notext ui-corner-all" data-role="button" role="button">Back</a>
<h1><?=$title ?></h1>
</div>
<div data-role="navbar">
<ul>
<li><a href="<?=$this->route(array('module' => 'mobile', 'action' => 'view', 'type' => 'radio')) ?>">
<span class="icon"><i class="fa fa-music"></i></span>
<span class="tab-label">Radio</span>
</a></li>
<li><a href="<?=$this->route(array('module' => 'mobile', 'action' => 'view', 'type' => 'video')) ?>">
<span class="icon"><i class="fa fa-video-camera"></i></span>
<span class="tab-label">Video</span>
</a></li>
<li><a href="<?=$this->route(array('module' => 'mobile', 'action' => 'view', 'type' => 'show')) ?>">
<span class="icon"><i class="fa fa-rss"></i></span>
<span class="tab-label">Shows</span>
</a></li>
<li><a href="<?=$this->route(array('module' => 'mobile', 'controller' => 'requests')) ?>">
<span class="icon"><i class="fa fa-comments"></i></span>
<span class="tab-label">Requests</span>
</a></li>
</ul>
<!-- Main Body -->
<div id="page" data-role="page" data-title="<?=$title ?>" class="jqm-demos">
<div role="main" class="ui-content jqm-content jqm-fullwidth">
<?php echo $this->layout()->content; ?>
</div>
</div>
</div>
<!-- Radio Player -->
<div id="pvl-jplayer" style="width: 0; height: 0;"></div>
<!-- Footer Nav -->
<div data-role="footer" data-position="fixed" data-tap-toggle="false" data-theme="a">
<div id="player_controls" data-role="controlgroup">
<a class="ui-corner-all ui-btn ui-btn-left" id="player_pause">Stop</a>
<input type="range" class="volume_slider" name="player_volume" id="player_volume" min="0" max="100" value="50" data-role="none" data-highlight="true">
</div>
<div data-role="navbar">
<ul>
<li><a href="<?=$this->route(array('module' => 'mobile', 'action' => 'view', 'type' => 'radio')) ?>">
<span class="icon"><i class="fa fa-music"></i></span>
<span class="tab-label">Radio</span>
</a></li>
<li><a href="<?=$this->route(array('module' => 'mobile', 'action' => 'view', 'type' => 'video')) ?>">
<span class="icon"><i class="fa fa-video-camera"></i></span>
<span class="tab-label">Video</span>
</a></li>
<li><a href="<?=$this->route(array('module' => 'mobile', 'action' => 'view', 'type' => 'show')) ?>">
<span class="icon"><i class="fa fa-rss"></i></span>
<span class="tab-label">Shows</span>
</a></li>
<li><a href="<?=$this->route(array('module' => 'mobile', 'controller' => 'requests')) ?>">
<span class="icon"><i class="fa fa-comments"></i></span>
<span class="tab-label">Requests</span>
</a></li>
</ul>
</div>
</div>
<!-- Radio Player -->
<div id="pvl-jplayer" style="width: 0; height: 0;"></div>
</div>
</body>
</html>

View File

@ -14,12 +14,50 @@ class Api extends \DF\Controller\Action
// Disable rendering.
$this->doNotRender();
// Allow AJAX retrieval.
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
// Log request.
}
/**
* Authentication
*/
public function requireKey()
{
$this->returnError('API keys are not yet implemented.');
return;
}
/**
* Result Printout
*/
public function returnSuccess($data)
{
$this->returnJson(array(
'status' => 'success',
'result' => $data,
));
}
public function returnError($message)
{
$this->returnJson(array(
'status' => 'error',
'error' => $message,
));
}
public function returnJson($obj)
{
echo json_encode($obj, JSON_UNESCAPED_SLASHES);
}
}

View File

@ -8,6 +8,8 @@ class Mobile extends \DF\Controller\Action
parent::init();
\Zend_Layout::getMvcInstance()->setLayout('mobile');
header("Access-Control-Allow-Origin: *");
}
public function preDispatch()

View File

@ -5,6 +5,7 @@ use \Entity\Statistic;
use \Entity\Schedule;
use \Entity\Station;
use \Entity\Song;
use \Entity\Settings;
class NowPlaying
{
@ -54,7 +55,7 @@ class NowPlaying
$pvl_file_path = self::getFilePath('nowplaying');
$nowplaying = self::loadNowPlaying();
$nowplaying_feed = json_encode($nowplaying);
$nowplaying_feed = json_encode($nowplaying, JSON_UNESCAPED_SLASHES);
@file_put_contents($pvl_file_path, $nowplaying_feed);
// Write shorter delimited file.
@ -200,7 +201,10 @@ class NowPlaying
list($artist, $track) = explode(' - ', $return['SERVERTITLE'], 2);
$np['listeners'] = (int)$return['UNIQUELISTENERS'];
$np['listeners_unique'] = (int)$song_data['UNIQUELISTENERS'];
$np['listeners_total'] = (int)$song_data['CURRENTLISTENERS'];
$np['listeners'] = self::getListenerCount($np['listeners_unique'], $np['listeners_total']);
$np['artist'] = $artist;
$np['title'] = $track;
$np['text'] = $return['SERVERTITLE'];
@ -274,7 +278,11 @@ class NowPlaying
$np['title'] = $title;
$np['artist'] = $artist;
$np['text'] = $song_data['SONGTITLE'];
$np['listeners'] = (int)$song_data['UNIQUELISTENERS'];
$np['listeners_unique'] = (int)$song_data['UNIQUELISTENERS'];
$np['listeners_total'] = (int)$song_data['CURRENTLISTENERS'];
$np['listeners'] = self::getListenerCount($np['listeners_unique'], $np['listeners_total']);
$np['is_live'] = 'false'; // ($song_data['NEXTTITLE'] != '') ? 'false' : 'true';
}
else
@ -294,7 +302,10 @@ class NowPlaying
list($artist, $title) = explode(" - ", $parts[6], 2);
$np['listeners'] = (int)$parts[0];
$np['listeners_unique'] = (int)$parts[4];
$np['listeners_total'] = (int)$parts[0];
$np['listeners'] = self::getListenerCount($np['listeners_unique'], $np['listeners_total']);
$np['title'] = $title;
$np['artist'] = $artist;
$np['text'] = $parts[6];
@ -488,13 +499,13 @@ class NowPlaying
// Pull from current NP data if song details haven't changed.
if (strcmp($np['text'], $current_np_data['text']) == 0)
{
$np['image'] = $current_np_data['image'];
// $np['image'] = $current_np_data['image'];
$np['song_id'] = $current_np_data['song_id'];
$np['song_history'] = $current_np_data['song_history'];
}
else if (empty($np['text']))
{
$np['image'] = $np['logo'];
// $np['image'] = $np['logo'];
$np['song_id'] = NULL;
$np['song_history'] = $station->getRecentHistory();
}
@ -505,8 +516,8 @@ class NowPlaying
self::notifyStation($station, 'offline');
// Fetch new NP image in the event of a changed song.
$np['image'] = $np['logo'];
$station->nowplaying_image = $np['image'];
// $np['image'] = $np['logo'];
// $station->nowplaying_image = $np['image'];
// Register a new item in song history.
$np['song_history'] = $station->getRecentHistory();
@ -601,4 +612,17 @@ class NowPlaying
return true;
}
public static function getListenerCount($unique_listeners = 0, $current_listeners = 0)
{
$unique_listeners = (int)$unique_listeners;
$current_listeners = (int)$current_listeners;
if ($unique_listeners == 0 || $current_listeners == 0)
return max($unique_listeners, $current_listeners);
else
return min($unique_listeners, $current_listeners);
// return round(($unique_listeners + $unique_listeners + $current_listeners) / 3);
}
}

View File

@ -289,6 +289,19 @@ class Station extends \DF\Doctrine\Entity
return $lookup;
}
public static function findByShortCode($short_code)
{
$short_names = self::getShortNameLookup();
if (isset($short_names[$short_code]))
{
$id = $short_names[$short_code]['id'];
return self::find($id);
}
return NULL;
}
public static function getCategories()
{
return array(

View File

@ -3,6 +3,14 @@ class Api_IndexController extends \PVL\Controller\Action\Api
{
public function indexAction()
{
$this->returnSuccess('The PVL! API is online and functioning. For more information, visit http://docs.ponyvillelive.apiary.io/');
}
public function statusAction()
{
$this->returnSuccess(array(
'online' => 'true',
'timestamp' => time(),
));
}
}

View File

@ -0,0 +1,48 @@
<?php
use \Entity\Station;
class Api_NowplayingController extends \PVL\Controller\Action\Api
{
public function indexAction()
{
if ($this->_hasParam('id'))
{
$id = (int)$this->_getParam('id');
$station = Station::find($id);
if (!($station instanceof Station))
return $this->returnError('Station not found!');
else
return $this->returnSuccess($station->nowplaying_data);
}
elseif ($this->_hasParam('station'))
{
$short_names = Station::getShortNameLookup(true);
$short = $this->_getParam('station');
if (isset($short_names[$short]))
{
$data = $short_names[$short];
return $this->returnSuccess($data['nowplaying_data']);
}
else
{
return $this->returnError('Station not found!');
}
}
else
{
$return_raw = $this->em->createQuery('SELECT s.name, s.nowplaying_data FROM Entity\Station s WHERE s.is_active = 1 ORDER BY s.weight ASC')
->getArrayResult();
$np = array();
foreach($return_raw as $row)
{
$short_name = Station::getStationShortName($row['name']);
$np[$short_name] = $row['nowplaying_data'];
}
return $this->returnSuccess($np);
}
}
}

View File

@ -0,0 +1,95 @@
<?php
use \Entity\Station;
use \Entity\Schedule;
class Api_ScheduleController extends \PVL\Controller\Action\Api
{
public function indexAction()
{
if ($this->_hasParam('month'))
{
$show = $this->_getParam('month');
$calendar = new \DF\Calendar($show);
$timestamps = $calendar->getTimestamps();
$start_timestamp = $timestamps['start'];
$end_timestamp = $timestamps['end'];
}
elseif ($this->_hasParam('start'))
{
$start_timestamp = (int)$this->_getParam('start');
$end_timestamp = (int)$this->_getParam('end');
}
else
{
$start_timestamp = time();
$end_timestamp = time()+(86400 * 30);
}
$station_shortcode = $this->_getParam('station', 'all');
$short_names = Station::getShortNameLookup();
if ($station_shortcode != "all")
{
$station = $short_names[$station_shortcode];
$events_raw = $this->em->createQuery('SELECT s FROM Entity\Schedule s WHERE (s.station_id = :sid) AND (s.start_time <= :end AND s.end_time >= :start) ORDER BY s.start_time ASC')
->setParameter('sid', $station['id'])
->setParameter('start', $start_timestamp)
->setParameter('end', $end_timestamp)
->getArrayResult();
}
else
{
$events_raw = $this->em->createQuery('SELECT s, st FROM Entity\Schedule s LEFT JOIN s.station st WHERE (s.start_time <= :end AND s.end_time >= :start) ORDER BY s.start_time ASC')
->setParameter('start', $start_timestamp)
->setParameter('end', $end_timestamp)
->getArrayResult();
}
$events = array();
foreach((array)$events_raw as $event)
{
if ($station_shortcode == 'all')
{
$shortcode = Station::getStationShortName($event['station']['name']);
$event['station'] = $shortcode;
}
else
{
unset($event['station']);
}
unset($event['is_notified']);
$events[] = $event;
}
$this->returnSuccess($events);
}
public function conventionsAction()
{
$start_timestamp = strtotime('-1 month');
$end_timestamp = strtotime('+1 year');
$events_raw = $this->em->createQuery('SELECT s FROM Entity\Schedule s WHERE s.type = :type AND s.start_time <= :end AND s.end_time >= :start ORDER BY s.start_time ASC')
->setParameter('type', 'convention')
->setParameter('start', $start_timestamp)
->setParameter('end', $end_timestamp)
->getArrayResult();
$events = array();
foreach((array)$events_raw as $event)
{
$special_info = \PVL\ScheduleManager::formatName($event['title']);
$event = array_merge($event, $special_info);
unset($event['station_id'], $event['icon'], $event['is_notified']);
$events[] = $event;
}
$this->returnSuccess($events);
}
}

View File

@ -0,0 +1,18 @@
<?php
use \Entity\Song;
class Api_SongController extends \PVL\Controller\Action\Api
{
public function indexAction()
{
$id = $this->_getParam('id');
$record = Song::find($id);
if (!($record instanceof Song))
return $this->returnError('Song not found.');
$return = $record->toArray();
return $this->returnSuccess($return);
}
}

View File

@ -0,0 +1,69 @@
<?php
use \Entity\Station;
class Api_StationController extends \PVL\Controller\Action\Api
{
public function indexAction()
{
if ($this->_hasParam('station'))
{
$record = Station::findByShortCode($this->_getParam('station'));
}
elseif ($this->_hasParam('id'))
{
$id = (int)$this->_getParam('id');
$record = Station::find($id);
}
if (!($record instanceof Station) || $record->deleted_at)
return $this->returnError('Station not found.');
return $this->returnSuccess($this->_processStation($record));
}
public function listAction()
{
$category = $this->_getParam('category', 'all');
if ($category == 'all')
{
$stations_raw = Station::fetchArray();
}
else
{
$cats = Station::getStationsInCategories();
if (!isset($cats[$category]))
return $this->returnError('Category not found.');
$stations_raw = $cats[$category]['stations'];
}
$stations = array();
foreach($stations_raw as $row)
$stations[] = $this->_processStation($row);
return $this->returnSuccess($stations);
}
protected function _processStation($row)
{
if ($row instanceof Station)
$row = $row->toArray();
return array(
'id' => (int)$row['id'],
'name' => $row['name'],
'shortcode' => Station::getStationShortName($row['name']),
'genre' => $row['genre'],
'category' => $row['category'],
'type' => $row['type'],
'image_url' => \DF\Url::content($row['image_url']),
'web_url' => $row['web_url'],
'stream_url' => $row['stream_url'],
'twitter_url' => $row['twitter_url'],
'irc' => $row['irc'],
);
}
}

View File

@ -26,6 +26,7 @@ class EventsController extends \DF\Controller\Action
$event['end_timestamp'] = $event['end_time'];
$special_info = \PVL\ScheduleManager::formatName($event['title']);
$event['title'] = $special_info['title'];
$event['city'] = $special_info['city'];
$event['title_full'] = $special_info['title_full'];

View File

@ -263,27 +263,6 @@ for($i = 0; $i <= $num_cols-1; $i++)
<script type="text/javascript">
$(function() {
/*
<? if (!$this->special_event): ?>
$('a').not('.station').not('#btn-tune-in').on('click', function(e) {
var url = $(this).attr("href");
if(url.slice(0, 1) != "#")
{
var current_station = $('#tunein_player').data('current_station');
if (current_station)
playInPopUp('current');
}
});
<? endif; ?>
*/
/* Web player link */
$('#btn-tune-in').click(function(e) {
e.preventDefault();
playInPopUp('current');
return false;
});
$('.btn-play-station').click(function(e) {
e.preventDefault();

View File

@ -7,7 +7,7 @@ $this->headTitle('Ponyville Live!');
</div>
<div id="home_buttons">
<a class="ui-btn ui-corner-all" href="<?=$this->route(array('module' => 'mobile', 'action' => 'view', 'type' => 'radio')) ?>">
<a class="ui-btn ui-corner-all" data-ajax="true" href="<?=$this->route(array('module' => 'mobile', 'action' => 'view', 'type' => 'radio')) ?>">
<i class="fa fa-music"></i> Radio Stations
</a>
<a class="ui-btn ui-corner-all" href="<?=$this->route(array('module' => 'mobile', 'action' => 'view', 'type' => 'video')) ?>">

View File

@ -1,6 +1,6 @@
$(function() {
$('#btn-tunein').click(function(e) {
$('#btn-tune-in').click(function(e) {
var href = $(this).attr('href');
window.open(href, "pvlplayer", "width=400,height=600,menubar=0,toolbar=0,location=0,status=1");

View File

@ -2,10 +2,13 @@
* Mobile Custom JS
*/
var pvl_player;
var is_playing = false;
var is_first_load = true;
var volume = 100;
var nowplaying_data;
var nowplaying_last_run = 0;
var nowplaying_timeout;
var nowplaying_interval;
@ -15,18 +18,21 @@ $(document).on("pageinit", function() {
{
$('#btn_back').hide();
$("#pvl-jplayer").jPlayer({
swfPath: DF_ContentPath+'/jplayer/jplayer.swf',
solution: (canPlayMp3()) ? 'html, flash' : 'flash',
supplied: 'mp3',
preload: 'none',
volume: (volume / 100),
muted: false,
backgroundColor: '#000000',
cssSelectorAncestor: '#pvl-jplayer-controls',
errorAlerts: false,
warningAlerts: false
});
if (!DF_IsApp)
{
$("#pvl-jplayer").jPlayer({
swfPath: DF_ContentPath+'/jplayer/jplayer.swf',
solution: (canPlayMp3()) ? 'html, flash' : 'flash',
supplied: 'mp3',
preload: 'none',
volume: (volume / 100),
muted: false,
backgroundColor: '#000000',
cssSelectorAncestor: '#pvl-jplayer-controls',
errorAlerts: false,
warningAlerts: false
});
}
$('#player_controls').hide();
@ -34,11 +40,10 @@ $(document).on("pageinit", function() {
$('#player_volume').slider({
stop: function(event, ui) {
volume = parseInt(event.target.value);
if (is_playing)
$('#pvl-jplayer').jPlayer('volume', (volume / 100));
playerSetVolume(volume);
}
});
$('#player_controls #player_pause').on("click", function(event, ui) {
stopAllPlayers();
});
@ -79,8 +84,8 @@ $(window).on("pagecontainershow", function(event) {
$(this).addClass("ui-btn-active");
});
// Detect autoplay station.
checkNowPlaying(true);
// Force a reload (or re-print) of now playing data.
checkNowPlaying();
});
// Ensure now-playing is being checked, in spite of any interruptions.
@ -98,111 +103,119 @@ function checkNowPlaying(force_update)
// Only run now-playing once every 10 seconds max.
var current_timestamp = getUnixTimestamp();
if (current_timestamp - nowplaying_last_run < 10 && !force_update)
{
processNowPlaying();
}
else
{
jQuery.ajax({
cache: false,
url: DF_ContentPath+'/api/nowplaying.json',
dataType: 'json'
}).done(function(data) {
nowplaying_data = data;
processNowPlaying();
});
}
}
function processNowPlaying()
{
if (typeof nowplaying_data === 'undefined')
return;
nowplaying_last_run = getUnixTimestamp();
for (var station_id in nowplaying_data)
{
var station_info = nowplaying_data[station_id];
var station = $('[data-role="page"].ui-page-active #station_'+station_id);
var station_exists = (station.length != 0);
jQuery.ajax({
cache: false,
url: DF_ContentPath+'/api/nowplaying.json',
dataType: 'json'
}).done(function(data) {
var listener_total = 0;
var listeners_by_type = new Array();
for (var station_id in data)
if (station_exists)
{
var station_info = data[station_id];
var station = $('[data-role="page"].ui-page-active #station_'+station_id);
var station_exists = (station.length != 0);
if (station_exists)
// Format title.
if (!station_info.title)
{
// Format title.
if (!station_info.title)
{
station.find('.nowplaying-artist').text(station_info.text);
station.find('.nowplaying-title').text('');
}
else
{
station.find('.nowplaying-artist').text(station_info.title);
station.find('.nowplaying-title').text(station_info.artist);
}
// Post listener count.
if (station_info.listeners)
station.find('.nowplaying-listeners').show().html('<i class="fa fa-user"></i>&nbsp;'+station_info.listeners);
else
station.find('.nowplaying-listeners').hide();
// Set station "live" status or "offline" status.
if (station_info.text == 'Stream Offline')
{
station.find('.nowplaying-live').hide();
station.removeClass('live').addClass('offline');
if (station.data('inactive') == 'hide')
station.hide();
}
else
{
station.find('.nowplaying-live').hide();
station.removeClass('live offline');
if (!station.is(':visible'))
station.show();
}
// Set event data.
if (station_info.event)
{
var event_info = station_info.event;
station.find('.nowplaying-onair').show().find('.nowplaying-onair-inner').html('<i class="fa fa-star"></i>&nbsp;On Air: '+event_info.title);
}
else if (station_info.event_upcoming)
{
var event_info = station_info.event_upcoming;
station.find('.nowplaying-onair').show().find('.nowplaying-onair-inner').html('<i class="fa fa-star"></i>&nbsp;In '+event_info.minutes_until+' mins: '+event_info.title);
}
else
{
station.find('.nowplaying-onair').hide();
}
// Set station history.
if (station_info.song_history)
{
var history_block = '';
for (var j in station_info.song_history)
{
var song_num = parseInt(j)+1;
var history_row = station_info.song_history[j];
history_block += '<div>#'+song_num+": "+history_row.text+'</div>';
}
station.find('.station-history').html(history_block);
}
if (station_info.song_id)
{
// Detect a change in song.
var current_song_id = station.data('song_id');
if (station_info.song_id != current_song_id)
{
station.find('.btn-like').removeClass('btn-disabled').addClass('btn-success');
}
station.data('song_id', station_info.song_id);
}
station.find('.nowplaying-artist').text(station_info.text);
station.find('.nowplaying-title').text('');
}
else
{
station.find('.nowplaying-artist').text(station_info.title);
station.find('.nowplaying-title').text(station_info.artist);
}
}
nowplaying_timeout = setTimeout('checkNowPlaying()', 20000);
});
// Post listener count.
if (station_info.listeners)
station.find('.nowplaying-listeners').show().html('<i class="fa fa-user"></i>&nbsp;'+station_info.listeners);
else
station.find('.nowplaying-listeners').hide();
// Set station "live" status or "offline" status.
if (station_info.text == 'Stream Offline')
{
station.find('.nowplaying-live').hide();
station.removeClass('live').addClass('offline');
if (station.data('inactive') == 'hide')
station.hide();
}
else
{
station.find('.nowplaying-live').hide();
station.removeClass('live offline');
if (!station.is(':visible'))
station.show();
}
// Set event data.
if (station_info.event)
{
var event_info = station_info.event;
station.find('.nowplaying-onair').show().find('.nowplaying-onair-inner').html('<i class="fa fa-star"></i>&nbsp;On Air: '+event_info.title);
}
else if (station_info.event_upcoming)
{
var event_info = station_info.event_upcoming;
station.find('.nowplaying-onair').show().find('.nowplaying-onair-inner').html('<i class="fa fa-star"></i>&nbsp;In '+event_info.minutes_until+' mins: '+event_info.title);
}
else
{
station.find('.nowplaying-onair').hide();
}
// Set station history.
if (station_info.song_history)
{
var history_block = '';
for (var j in station_info.song_history)
{
var song_num = parseInt(j)+1;
var history_row = station_info.song_history[j];
history_block += '<div>#'+song_num+": "+history_row.text+'</div>';
}
station.find('.station-history').html(history_block);
}
if (station_info.song_id)
{
// Detect a change in song.
var current_song_id = station.data('song_id');
if (station_info.song_id != current_song_id)
{
station.find('.btn-like').removeClass('btn-disabled').addClass('btn-success');
}
station.data('song_id', station_info.song_id);
}
}
}
nowplaying_timeout = setTimeout('checkNowPlaying()', 20000);
}
function playStation(id)
@ -222,7 +235,10 @@ function playStation(id)
if (stream_type == "stream")
{
window.location.href = stream_url;
if (DF_IsApp)
window.open(stream_url);
else
window.location.href = stream_url;
return false;
}
else
@ -240,21 +256,42 @@ function playStation(id)
function startPlayer(stream_url)
{
var stream = {
title: "Ponyville Live!",
mp3: stream_url
};
if (DF_IsApp)
{
pvl_player = new Media(stream_url, function() {
playerSetVolume(volume);
console.log("playAudio(): Audio Success");
},
function(err) {
console.log("playAudio(): Audio Error: "+err);
});
pvl_player.play();
}
else
{
var stream = {
title: "Ponyville Live!",
mp3: stream_url
};
$("#pvl-jplayer").jPlayer("setMedia", stream).jPlayer("play");
}
is_playing = true;
$('.btn_tunein').hide();
$("#pvl-jplayer").jPlayer("setMedia", stream).jPlayer("play");
$('#player_controls').show();
$("[data-role='header'], [data-role='footer']").toolbar("updatePagePadding");
}
function stopAllPlayers()
{
if ($("#pvl-jplayer").length > 0)
if (DF_IsApp && typeof pvl_player !== 'undefined')
{
pvl_player.stop();
pvl_player.release();
}
else if ($("#pvl-jplayer").length > 0)
{
try
{
@ -275,6 +312,18 @@ function stopAllPlayers()
$('#player_controls').hide();
}
function playerSetVolume(volume)
{
if (DF_IsApp)
{
pvl_player.setVolume(volume / 100);
}
else if (is_playing)
{
$('#pvl-jplayer').jPlayer('volume', (volume / 100));
}
}
function canPlayMp3()
{
if (isIE())

View File

@ -0,0 +1,6 @@
/**
* Mobile Bootstraper CSS
*/
@import url('jquery.mobile-1.4.0.min.css');
@import url('custom.css');

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 491 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB