Merge branch 'master' of dev.sourcefabric.org:campcaster

This commit is contained in:
Naomi 2011-01-26 18:32:27 -05:00
commit 9e20e935ca
12 changed files with 195 additions and 116 deletions

View File

@ -80,6 +80,7 @@
<controllerFile controllerName="Nowplaying">
<actionMethod actionName="index"/>
<actionMethod actionName="getDataGridData"/>
<actionMethod actionName="livestream"/>
</controllerFile>
</controllersDirectory>
<formsDirectory>
@ -258,6 +259,9 @@
<viewControllerScriptsDirectory forControllerName="User">
<viewScriptFile forActionName="getHosts"/>
</viewControllerScriptsDirectory>
<viewControllerScriptsDirectory forControllerName="Nowplaying">
<viewScriptFile forActionName="livestream"/>
</viewControllerScriptsDirectory>
</viewScriptsDirectory>
<viewHelpersDirectory/>
<viewFiltersDirectory enabled="false"/>

View File

@ -5,24 +5,26 @@ class NowplayingController extends Zend_Controller_Action
public function init()
{
$ajaxContext = $this->_helper->getHelper('AjaxContext');
$ajaxContext->addActionContext('get-data-grid-data', 'json')->initContext();
$ajaxContext = $this->_helper->getHelper('AjaxContext');
$ajaxContext->addActionContext('get-data-grid-data', 'json')->initContext();
}
public function indexAction()
{
$this->view->headScript()->appendFile('/js/datatables/js/jquery.dataTables.min.js','text/javascript');
$this->view->headLink()->appendStylesheet('/css/datatables/css/demo_page.css');
$this->view->headLink()->appendStylesheet('/css/datatables/css/demo_table.css');
//$this->_helper->viewRenderer->setResponseSegment('nowplaying');
$this->view->headScript()->appendFile('/js/datatables/js/jquery.dataTables.min.js','text/javascript');
$this->view->headLink()->appendStylesheet('/css/datatables/css/demo_page.css');
$this->view->headLink()->appendStylesheet('/css/datatables/css/demo_table.css');
}
public function getDataGridDataAction()
{
$this->view->entries = Application_Model_Nowplaying::GetDataGridData();
$this->view->entries = Application_Model_Nowplaying::GetDataGridData();
}
public function livestreamAction()
{
//use bare bones layout (no header bar or menu)
$this->_helper->layout->setLayout('bare');
}
@ -32,3 +34,5 @@ class NowplayingController extends Zend_Controller_Action

View File

@ -0,0 +1,11 @@
<!-- application/layouts/scripts/layout.phtml -->
<?php echo $this->doctype() ?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Livestream</title>
</head>
<body>
<div id="content"><?php echo $this->layout()->content ?></div>
</body>
</html>

View File

@ -481,11 +481,12 @@ class Schedule {
global $CC_CONFIG, $CC_DBC;
$sql = "SELECT pt.name, ft.track_title, ft.artist_name, ft.album_title, st.starts, st.ends, st.clip_length, sdt.start_time, sdt.end_time"
." FROM $CC_CONFIG[scheduleTable] st, $CC_CONFIG[filesTable] ft, $CC_CONFIG[playListTable] pt, $CC_CONFIG[showSchedule] sst, $CC_CONFIG[showDays] sdt"
." WHERE (st.ends < TIMESTAMP '$timeNow')"
." AND (st.playlist_id = pt.id)"
." AND (st.file_id = ft.id)"
." AND (st.group_id = sst.group_id)"
." AND (sdt.show_id = sst.show_id)"
." WHERE st.ends < TIMESTAMP '$timeNow'"
." AND st.ends > (TIMESTAMP '$timeNow' - INTERVAL '1 days')"
." AND st.playlist_id = pt.id"
." AND st.file_id = ft.id"
." AND st.group_id = sst.group_id"
." AND sdt.show_id = sst.show_id"
." ORDER BY st.starts DESC"
." LIMIT $prevCount";
$rows = $CC_DBC->GetAll($sql);
@ -498,12 +499,12 @@ class Schedule {
$sql = "SELECT pt.name, ft.track_title, ft.artist_name, ft.album_title, st.starts, st.ends, st.clip_length, sdt.start_time, sdt.end_time"
." FROM $CC_CONFIG[scheduleTable] st,"
."$CC_CONFIG[filesTable] ft, $CC_CONFIG[playListTable] pt, $CC_CONFIG[showSchedule] sst, $CC_CONFIG[showDays] sdt"
." WHERE (st.starts < TIMESTAMP '$timeNow')"
." AND (st.ends > TIMESTAMP '$timeNow')"
." AND (st.playlist_id = pt.id)"
." AND (st.file_id = ft.id)"
." AND (st.group_id = sst.group_id)"
." AND (sdt.show_id = sst.show_id)";
." WHERE st.starts < TIMESTAMP '$timeNow'"
." AND st.ends > TIMESTAMP '$timeNow'"
." AND st.playlist_id = pt.id"
." AND st.file_id = ft.id"
." AND st.group_id = sst.group_id"
." AND sdt.show_id = sst.show_id";
$rows = $CC_DBC->GetAll($sql);
return $rows;
}
@ -512,11 +513,12 @@ class Schedule {
global $CC_CONFIG, $CC_DBC;
$sql = "SELECT pt.name, ft.track_title, ft.artist_name, ft.album_title, st.starts, st.ends, st.clip_length, sdt.start_time, sdt.end_time"
." FROM $CC_CONFIG[scheduleTable] st, $CC_CONFIG[filesTable] ft, $CC_CONFIG[playListTable] pt, $CC_CONFIG[showSchedule] sst, $CC_CONFIG[showDays] sdt"
." WHERE (st.starts > TIMESTAMP '$timeNow')"
." AND (st.playlist_id = pt.id)"
." AND (st.file_id = ft.id)"
." AND (st.group_id = sst.group_id)"
." AND (sdt.show_id = sst.show_id)"
." WHERE st.starts > TIMESTAMP '$timeNow'"
." AND st.ends < (TIMESTAMP '$timeNow' + INTERVAL '24 hours')"
." AND st.playlist_id = pt.id"
." AND st.file_id = ft.id"
." AND st.group_id = sst.group_id"
." AND sdt.show_id = sst.show_id"
." ORDER BY st.starts"
." LIMIT $nextCount";
$rows = $CC_DBC->GetAll($sql);

View File

@ -0,0 +1,9 @@
<OBJECT ID="MediaPlayer1" CLASSID="CLSID:22d6f312-b0f6-11d0-94ab-0080c74c7e95" CODEBASE="http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab# Version=5,1,52,701" STANDBY="Loading Microsoft Windows® Media Player components..." TYPE="application/x-oleobject" width="280" height="46">
<param name="fileName" value="http://localhost:8000/airtime.mp3">
<param name="animationatStart" value="true">
<param name="transparentatStart" value="true">
<param name="autoStart" value="true">
<param name="showControls" value="true">
<param name="Volume" value="100">
<embed type="application/x-mplayer2" pluginspage="http://www.microsoft.com/Windows/MediaPlayer/" src="http://localhost:8000/airtime.mp3" name="MediaPlayer1" width=280 height=46 autostart=1 showcontrols=1 volume=100>
</OBJECT>

View File

@ -1,5 +1,5 @@
<div id='col0' style='float:left; width: 10%; height: 100%;'>
<div><a href="Schedule" onClick="return popup(this)">Listen</a></div>
<div><a href="Nowplaying/livestream" onClick="return popup(this)">Listen</a></div>
</div>
<div id='col1' style='float:left; width: 25%; height: 100%;'>
@ -30,7 +30,7 @@ function popup(mylink){
href=mylink;
else
href=mylink.href;
window.open(href, "player", 'width=400,height=200,scrollbars=yes');
window.open(href, "player", 'width=300,height=100,scrollbars=yes');
return false;
}
</script>

View File

@ -44,7 +44,7 @@ foreach($lines as $key => $line){
fclose($fp);
echo "******************************* Install Begin ********************************\n";
echo "******************************** Install Begin *********************************\n";
echo " *** Database Installation ***\n";
@ -225,9 +225,13 @@ install_setDirPermissions($CC_CONFIG["storageDir"]);
echo " * Importing sample audio clips \n";
$command = __DIR__."/../utils/airtime-import --copy ../audio_samples/ > /dev/null";
@exec($command, $output, $results);
echo "****************************** Database Install Complete ******************************\n";
$command = "python ".__DIR__."/../pypo/install/pypo-install.py";
$output = array();
@exec($command, $output, $results);
//print_r($output);
foreach ($output as $value){
echo $value."\n";
}
echo "******************************* Install Complete *******************************\n";
?>

View File

@ -21,9 +21,7 @@ if(exec("whoami") != "root"){
}
echo "***************************\n";
echo "* StorageServer Uninstall *\n";
echo "***************************\n";
echo "******************************* Uninstall Begin ********************************\n";
require_once(dirname(__FILE__).'/../application/configs/conf.php');
require_once(dirname(__FILE__).'/installInit.php');
@ -226,11 +224,11 @@ if ($results == 0) {
airtime_uninstall_delete_files($CC_CONFIG['storageDir']);
echo "************************************\n";
echo "* StorageServer Uninstall Complete *\n";
echo "************************************\n";
$command = "python ".__DIR__."/../pypo/install/pypo-uninstall.py";
$output = array();
@exec($command, $output, $results);
//print_r($output);
foreach ($output as $value){
echo $value."\n";
}
echo "****************************** Uninstall Complete ******************************\n";
?>

View File

@ -1,7 +1,6 @@
var estimatedSchedulePosixTime = -1;
var schedulePosixTime;
var currentRemoteTimeOffset;
var localRemoteTimeOffset;
var previousSongs = new Array();
var currentSong = new Array();
@ -9,15 +8,33 @@ var nextSongs = new Array();
var currentElem;
var updateInterval = 5000;
var serverUpdateInterval = 5000;
var uiUpdateInterval = 200;
var songEndFunc;
var showStartPosixTime = 0;
var showEndPosixTime = 0;
var showLengthMs = 1;
/* boolean flag to let us know if we should prepare to execute a function
* that flips the playlist to the next song. This flags purpose is to
* make sure the function is only executed once*/
var nextSongPrepare = true;
/* Another script can register its function here
* when it wishes to know when a song ends. */
function registerSongEndListener(func){
songEndFunc = func;
}
function notifySongEndListener(){
if (typeof songEndFunc == "function")
songEndFunc();
}
/* Takes an input parameter of milliseconds and converts these into
* the format HH:MM:SS */
function convertToHHMMSS(timeInMS){
var time = parseInt(timeInMS);
@ -72,58 +89,64 @@ function getTrackInfo(song){
function secondsTimer(){
var date = new Date();
estimatedSchedulePosixTime = date.getTime() - currentRemoteTimeOffset;
estimatedSchedulePosixTime = date.getTime() - localRemoteTimeOffset;
updateProgressBarValue();
}
/* Called every 0.2 seconds. */
function updateGlobalValues(obj){
showStartPosixTime = obj.showStartPosixTime;
showEndPosixTime = obj.showEndPosixTime;
showLengthMs = showEndPosixTime - showStartPosixTime;
}
function newSongStart(){
nextSongPrepare = true;
currentSong[0] = nextSongs.shift();
updateGlobalValues(currentSong[0]);
updatePlaybar();
notifySongEndListener();
}
/* Called every "uiUpdateInterval" mseconds. */
function updateProgressBarValue(){
if (estimatedSchedulePosixTime != -1){
if (showStartPosixTime != 0){
var showPercentDone = (estimatedSchedulePosixTime - showStartPosixTime)/showLengthMs*100;
if (showPercentDone < 0 || showPercentDone > 100){
showPercentDone = 0;
}
$('#showprogressbar').progressBar(showPercentDone);
}
var songPercentDone = 0;
if (currentSong.length > 0){
var percentDone = (estimatedSchedulePosixTime - currentSong[0].songStartPosixTime)/currentSong[0].songLengthMs*100;
if (percentDone <= 100){
$('#progressbar').progressBar(percentDone);
} else {
if (nextSongs.length > 0){
currentSong[0] = nextSongs.shift();
} else {
currentSong = new Array();
}
$('#progressbar').progressBar(0);
}
percentDone = (estimatedSchedulePosixTime - currentSong[0].showStartPosixTime)/currentSong[0].showLengthMs*100;
//$('#showprogressbar').text(currentSong[0].showLengthMs);
$('#showprogressbar').progressBar(percentDone);
} else {
$('#progressbar').progressBar(0);
//calculate how much time left to next song if there is any
if (nextSongs.length > 0){
if (nextSongs[0].songStartPosixTime - estimatedSchedulePosixTime < updateInterval){
setTimeout(temp, nextSongs[0].songStartPosixTime - estimatedSchedulePosixTime);
}
songPercentDone = (estimatedSchedulePosixTime - currentSong[0].songStartPosixTime)/currentSong[0].songLengthMs*100;
if (songPercentDone < 0 || songPercentDone > 100){
songPercentDone = 0;
currentSong = new Array();
}
}
updatePlaylist();
$('#progressbar').progressBar(songPercentDone);
//calculate how much time left to next song if there is any
if (nextSongs.length > 0 && nextSongPrepare){
if (nextSongs[0].songStartPosixTime - estimatedSchedulePosixTime < serverUpdateInterval){
nextSongPrepare = false;
setTimeout(newSongStart, nextSongs[0].songStartPosixTime - estimatedSchedulePosixTime);
}
}
updatePlaybar();
}
setTimeout(secondsTimer, 200);
setTimeout(secondsTimer, uiUpdateInterval);
}
function temp(){
currentSong[0] = nextSongs[0];
updatePlaylist();
songEndFunc();
}
function updatePlaylist(){
function updatePlaybar(){
/* Column 0 update */
$('#listen');
/* Column 1 update */
$('#playlist').empty();
for (var i=0; i<currentSong.length; i++){
//alert (currentSong[i].playlistname);
//$('#show').text(currentSong[i].show);
@ -132,6 +155,9 @@ function updatePlaylist(){
}
/* Column 2 update */
$('#previous').empty();
$('#current').empty();
$('#next').empty();
for (var i=0; i<previousSongs.length; i++){
$('#previous').text(getTrackInfo(previousSongs[i]));
}
@ -143,51 +169,75 @@ function updatePlaylist(){
}
/* Column 3 update */
$('#start').empty();
$('#end').empty();
$('#songposition').empty();
$('#songlength').empty();
$('#showposition').empty();
$('#showlength').empty();
for (var i=0; i<currentSong.length; i++){
$('#start').text(currentSong[i].starts.substring(currentSong[i].starts.indexOf(" ")+1));
$('#end').text(currentSong[i].ends.substring(currentSong[i].starts.indexOf(" ")+1));
$('#songposition').text(convertToHHMMSS(estimatedSchedulePosixTime - currentSong[i].songStartPosixTime));
/* Get rid of the millisecond accuracy so that the second counters for both
* show and song change at the same time. */
var songStartRoughly = parseInt(currentSong[i].songStartPosixTime/1000)*1000;
$('#songposition').text(convertToHHMMSS(estimatedSchedulePosixTime - songStartRoughly));
$('#songlength').text(currentSong[i].clip_length);
$('#showposition').text(convertToHHMMSS(estimatedSchedulePosixTime - currentSong[i].showStartPosixTime));
$('#showlength').text(convertToHHMMSS(currentSong[i].showEndPosixTime - currentSong[i].showStartPosixTime));
}
if (estimatedSchedulePosixTime < showEndPosixTime){
$('#showposition').text(convertToHHMMSS(estimatedSchedulePosixTime - showStartPosixTime));
$('#showlength').text(convertToHHMMSS(showEndPosixTime - showStartPosixTime));
}
}
function calcAdditionalData(currentItem){
function calcAdditionalData(currentItem, bUpdateGlobalValues){
for (var i=0; i<currentItem.length; i++){
currentItem[i].songStartPosixTime = convertDateToPosixTime(currentItem[i].starts);
currentItem[i].songEndPosixTime = convertDateToPosixTime(currentItem[i].ends);
currentItem[i].songLengthMs = currentItem[i].songEndPosixTime - currentItem[i].songStartPosixTime;
currentItem[i].showStartPosixTime = convertDateToPosixTime(currentItem[i].starts.substring(0, currentItem[i].starts.indexOf(" ")) + " " + currentItem[i].start_time);
currentItem[i].showEndPosixTime = convertDateToPosixTime(currentItem[i].starts.substring(0, currentItem[i].starts.indexOf(" ")) + " " + currentItem[i].end_time);
currentItem[i].showLengthMs = currentItem[i].showEndPosixTime - currentItem[i].showStartPosixTime;
currentItem[i].showStartPosixTime = convertDateToPosixTime(currentItem[i].starts.substring(0, currentItem[i].starts.indexOf(" ")) + " " + currentItem[i].start_time);
currentItem[i].showEndPosixTime = convertDateToPosixTime(currentItem[i].starts.substring(0, currentItem[i].starts.indexOf(" ")) + " " + currentItem[i].end_time);
//check if there is a rollover past midnight
if (currentItem[i].start_time > currentItem[i].end_time){
//start_time is greater than end_time, so we rolled through midnight.
currentItem[i].showEndPosixTime += (1000*3600*24); //add 24 hours
}
currentItem[i].showLengthMs = currentItem[i].showEndPosixTime - currentItem[i].showStartPosixTime;
if (bUpdateGlobalValues){
updateGlobalValues(currentItem[i]);
}
}
}
function parseItems(obj){
schedulePosixTime = convertDateToPosixTime(obj.schedulerTime);
if (estimatedSchedulePosixTime == -1){
var date = new Date();
currentRemoteTimeOffset = date.getTime() - schedulePosixTime;
estimatedSchedulePosixTime = schedulePosixTime;
}
var schedulePosixTime = convertDateToPosixTime(obj.schedulerTime);
previousSongs = obj.previous;
currentSong = obj.current;
nextSongs = obj.next;
calcAdditionalData(previousSongs);
calcAdditionalData(currentSong);
calcAdditionalData(nextSongs);
calcAdditionalData(previousSongs, false);
calcAdditionalData(currentSong, true);
calcAdditionalData(nextSongs, false);
if (estimatedSchedulePosixTime == -1){
var date = new Date();
localRemoteTimeOffset = date.getTime() - schedulePosixTime;
estimatedSchedulePosixTime = schedulePosixTime;
}
}
function getScheduleFromServer(){
$.ajax({ url: "/Schedule/get-current-playlist/format/json", dataType:"json", success:function(data){
parseItems(data.entries);
}});
setTimeout(getScheduleFromServer, updateInterval);
setTimeout(getScheduleFromServer, serverUpdateInterval);
}
function init(elemID) {
@ -196,7 +246,10 @@ function init(elemID) {
$('#progressbar').progressBar(0, {showText : false});
$('#showprogressbar').progressBar(0, {showText : false, barImage:'/js/progressbar/images/progressbg_red.gif'});
//begin producer "thread"
getScheduleFromServer();
//begin consumer "thread"
updateProgressBarValue();
}

View File

@ -150,9 +150,7 @@ try:
print output
if not found:
print "Install has completed, but daemontools is not running, please make sure you have it installed and then reboot."
else:
print "Install complete."
print "Pypo install has completed, but daemontools is not running, please make sure you have it installed and then reboot."
except Exception, e:
print "exception:" + str(e)

View File

@ -42,6 +42,13 @@ def notify(m)
print("./notify.sh --data='#{!pypo_data}' --media-id=#{m['media_id']}")
end
def crossfade(s)
s = fade.in(type="log", s)
s = fade.out(type="log", s)
fader = fun (a,b) -> add(normalize=false,[b,a])
cross(fader,s)
end
server.register(namespace="scheduler","push", scheduler_push)
server.register(namespace="scheduler","flip", fun (s) -> begin scheduler_flip() end)
server.register(namespace="vars", "pypo_data", fun (s) -> begin pypo_data := s "Done" end)
@ -51,6 +58,8 @@ radio = fallback(track_sensitive=false, [switch(track_sensitive=false, [(fun ()
#radio = on_metadata(notify, radio)
radio = crossfade(radio)
#out(radio)
clock(id="clock_icecast",
output.icecast(%mp3,

View File

@ -42,19 +42,6 @@ $pl = new Playlist();
$pl->create($playlistName);
// Add a media clip
$mediaFile = StoredFile::findByOriginalName("ACDC_-_Back_In_Black-sample.ogg");
if (is_null($mediaFile)) {
echo "Adding test audio clip to the database.\n";
$v = array("filepath" => __DIR__."/../../audio_samples/OpSound/ACDC_-_Back_In_Black-sample.ogg");
$mediaFile = StoredFile::Insert($v);
if (PEAR::isError($mediaFile)) {
var_dump($mediaFile);
exit();
}
}
$pl->addAudioClip($mediaFile->getId());
$mediaFile = StoredFile::findByOriginalName("Peter_Rudenko_-_Opening.mp3");
if (is_null($mediaFile)) {
echo "Adding test audio clip to the database.\n";