merge from devel
This commit is contained in:
parent
2f0c6b702a
commit
b2699fa914
17 changed files with 143 additions and 84 deletions
2
VERSION
2
VERSION
|
@ -1,2 +1,2 @@
|
||||||
PRODUCT_ID=Airtime
|
PRODUCT_ID=Airtime
|
||||||
PRODUCT_RELEASE=2.2.0
|
PRODUCT_RELEASE=2.2.1
|
||||||
|
|
|
@ -928,7 +928,9 @@ class ApiController extends Zend_Controller_Action
|
||||||
|
|
||||||
$data_arr = json_decode($data);
|
$data_arr = json_decode($data);
|
||||||
|
|
||||||
if (!is_null($media_id) && isset($data_arr->title) && strlen($data_arr->title) < 1024) {
|
if (!is_null($media_id)) {
|
||||||
|
if (isset($data_arr->title) &&
|
||||||
|
strlen($data_arr->title) < 1024) {
|
||||||
|
|
||||||
$previous_metadata = CcWebstreamMetadataQuery::create()
|
$previous_metadata = CcWebstreamMetadataQuery::create()
|
||||||
->orderByDbStartTime('desc')
|
->orderByDbStartTime('desc')
|
||||||
|
@ -950,9 +952,9 @@ class ApiController extends Zend_Controller_Action
|
||||||
$webstream_metadata->setDbLiquidsoapData($data_arr->title);
|
$webstream_metadata->setDbLiquidsoapData($data_arr->title);
|
||||||
$webstream_metadata->save();
|
$webstream_metadata->save();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new Error("Unexpected error. media_id $media_id has a null stream value in cc_schedule!");
|
throw new Exception("Null value of media_id");
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->view->response = $data;
|
$this->view->response = $data;
|
||||||
|
|
|
@ -360,8 +360,10 @@ SQL;
|
||||||
{
|
{
|
||||||
$sql = <<<SQL
|
$sql = <<<SQL
|
||||||
SELECT SUM(cliplength) AS LENGTH
|
SELECT SUM(cliplength) AS LENGTH
|
||||||
FROM cc_blockcontents
|
FROM cc_blockcontents as bc
|
||||||
|
JOIN cc_files as f ON bc.file_id = f.id
|
||||||
WHERE block_id = :block_id
|
WHERE block_id = :block_id
|
||||||
|
AND f.file_exists = true
|
||||||
SQL;
|
SQL;
|
||||||
$result = Application_Common_Database::prepareAndExecute($sql, array(':block_id'=>$this->id), 'all', PDO::FETCH_NUM);
|
$result = Application_Common_Database::prepareAndExecute($sql, array(':block_id'=>$this->id), 'all', PDO::FETCH_NUM);
|
||||||
return $result[0][0];
|
return $result[0][0];
|
||||||
|
|
|
@ -834,25 +834,59 @@ SQL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/* Check if two events are less than or equal to 1 second apart
|
||||||
* Purpose of this function is to iterate through the entire
|
|
||||||
* schedule array that was just built and fix the data up a bit. For
|
|
||||||
* example, if we have two consecutive webstreams, we don't need the
|
|
||||||
* first webstream to shutdown the output, when the second one will
|
|
||||||
* just switch it back on. Preventing this behaviour stops hiccups
|
|
||||||
* in output sound.
|
|
||||||
*/
|
*/
|
||||||
private static function filterData(&$data)
|
public static function areEventsLinked($event1, $event2) {
|
||||||
|
$dt1 = DateTime::createFromFormat("Y-m-d-H-i-s", $event1['start']);
|
||||||
|
$dt2 = DateTime::createFromFormat("Y-m-d-H-i-s", $event2['start']);
|
||||||
|
|
||||||
|
$seconds = $dt2->getTimestamp() - $dt1->getTimestamp();
|
||||||
|
return $seconds <= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Streams are a 4 stage process.
|
||||||
|
* 1) start buffering stream 5 seconds ahead of its start time
|
||||||
|
* 2) at the start time tell liquidsoap to switch to this source
|
||||||
|
* 3) at the end time, tell liquidsoap to stop reading this stream
|
||||||
|
* 4) at the end time, tell liquidsoap to switch away from input.http source.
|
||||||
|
*
|
||||||
|
* When we have two streams back-to-back, some of these steps are unnecessary
|
||||||
|
* for the second stream. Instead of sending commands 1,2,3,4,1,2,3,4 we should
|
||||||
|
* send 1,2,1,2,3,4 - We don't need to tell liquidsoap to stop reading (#3), because #1
|
||||||
|
* of the next stream implies this when we pass in a new url. We also don't need #4.
|
||||||
|
*
|
||||||
|
* There's a special case here is well. When the back-to-back streams are the same, we
|
||||||
|
* can collapse the instructions 1,2,(3,4,1,2),3,4 to 1,2,3,4. We basically cut out the
|
||||||
|
* middle part. This function handles this.
|
||||||
|
*/
|
||||||
|
private static function foldData(&$data)
|
||||||
{
|
{
|
||||||
$previous_key = null;
|
$previous_key = null;
|
||||||
$previous_val = null;
|
$previous_val = null;
|
||||||
|
$previous_previous_key = null;
|
||||||
|
$previous_previous_val = null;
|
||||||
|
$previous_previous_previous_key = null;
|
||||||
|
$previous_previous_previous_val = null;
|
||||||
foreach ($data as $k => $v) {
|
foreach ($data as $k => $v) {
|
||||||
if ($v["type"] == "stream_buffer_start"
|
|
||||||
&& !is_null($previous_val)
|
|
||||||
&& $previous_val["type"] == "stream_output_end") {
|
|
||||||
|
|
||||||
|
if ($v["type"] == "stream_output_start"
|
||||||
|
&& !is_null($previous_previous_val)
|
||||||
|
&& $previous_previous_val["type"] == "stream_output_end"
|
||||||
|
&& self::areEventsLinked($previous_previous_val, $v)) {
|
||||||
|
|
||||||
|
unset($data[$previous_previous_previous_key]);
|
||||||
|
unset($data[$previous_previous_key]);
|
||||||
unset($data[$previous_key]);
|
unset($data[$previous_key]);
|
||||||
|
if ($previous_previous_val['uri'] == $v['uri']) {
|
||||||
|
unset($data[$k]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$previous_previous_previous_key = $previous_previous_key;
|
||||||
|
$previous_previous_previous_val = $previous_previous_val;
|
||||||
|
$previous_previous_key = $previous_key;
|
||||||
|
$previous_previous_val = $previous_val;
|
||||||
$previous_key = $k;
|
$previous_key = $k;
|
||||||
$previous_val = $v;
|
$previous_val = $v;
|
||||||
}
|
}
|
||||||
|
@ -870,7 +904,7 @@ SQL;
|
||||||
self::createInputHarborKickTimes($data, $range_start, $range_end);
|
self::createInputHarborKickTimes($data, $range_start, $range_end);
|
||||||
self::createScheduledEvents($data, $range_start, $range_end);
|
self::createScheduledEvents($data, $range_start, $range_end);
|
||||||
|
|
||||||
self::filterData($data["media"]);
|
self::foldData($data["media"]);
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
|
@ -267,7 +267,11 @@ class Application_Model_ShowBuilder
|
||||||
$row["starts"] = $schedStartDT->format("H:i:s");
|
$row["starts"] = $schedStartDT->format("H:i:s");
|
||||||
$row["ends"] = $schedEndDT->format("H:i:s");
|
$row["ends"] = $schedEndDT->format("H:i:s");
|
||||||
|
|
||||||
$formatter = new LengthFormatter($p_item['file_length']);
|
$cue_out = Application_Common_DateHelper::calculateLengthInSeconds($p_item['cue_out']);
|
||||||
|
$cue_in = Application_Common_DateHelper::calculateLengthInSeconds($p_item['cue_in']);
|
||||||
|
$run_time = $cue_out-$cue_in;
|
||||||
|
|
||||||
|
$formatter = new LengthFormatter(Application_Common_DateHelper::ConvertMSToHHMMSSmm($run_time*1000));
|
||||||
$row['runtime'] = $formatter->format();
|
$row['runtime'] = $formatter->format();
|
||||||
|
|
||||||
$row["title"] = $p_item["file_track_title"];
|
$row["title"] = $p_item["file_track_title"];
|
||||||
|
|
|
@ -34,7 +34,7 @@ class Application_Model_Webstream implements Application_Model_LibraryEditable
|
||||||
|
|
||||||
public function getCreatorId()
|
public function getCreatorId()
|
||||||
{
|
{
|
||||||
return $this->Webstream->getCcSubjs()->getDbId();
|
return $this->webstream->getDbCreatorId();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getLastModified($p_type)
|
public function getLastModified($p_type)
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
# SOME DESCRIPTIVE TITLE.
|
# CANADIAN (en_CA) translation for Airtime.
|
||||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
# Copyright (C) 2012 Sourcefabric
|
||||||
# This file is distributed under the same license as the PACKAGE package.
|
# This file is distributed under the same license as the Airtime package.
|
||||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
# Sourcefabric <contact@sourcefabric.org>, 2012.
|
||||||
#
|
#
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: Airtime 2.3\n"
|
"Project-Id-Version: Airtime 2.3\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: contact@sourcefabric.org\n"
|
||||||
"POT-Creation-Date: 2012-11-28 16:00-0500\n"
|
"POT-Creation-Date: 2012-11-28 16:00-0500\n"
|
||||||
"PO-Revision-Date: 2012-11-29 11:31-0500\n"
|
"PO-Revision-Date: 2012-11-29 11:31-0500\n"
|
||||||
"Last-Translator: Denise Rigato <denise.rigato@sourcefabric.org>\n"
|
"Last-Translator: Denise Rigato <denise.rigato@sourcefabric.org>\n"
|
||||||
"Language-Team: Airtime\n"
|
"Language-Team: Canadian Localization <contact@sourcefabric.org>\n"
|
||||||
"Language: en_CA\n"
|
"Language: en_CA\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
# SOME DESCRIPTIVE TITLE.
|
# KOREAN (ko_KR) translation for Airtime.
|
||||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
# Copyright (C) 2012 Sourcefabric
|
||||||
# This file is distributed under the same license as the PACKAGE package.
|
# This file is distributed under the same license as the Airtime package.
|
||||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
# Sourcefabric <contact@sourcefabric.org>, 2012.
|
||||||
#
|
#
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: Airtime 2.3\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: contact@sourcefabric.org\n"
|
||||||
"POT-Creation-Date: 2012-11-26 14:16-0500\n"
|
"POT-Creation-Date: 2012-11-26 14:16-0500\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: 2012-11-26 14:16-0500\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: James Moon <james.moon@sourcefabric.org>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: Korean Localization <contact@sourcefabric.org>\n"
|
||||||
"Language: ko_KR\n"
|
"Language: ko_KR\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
|
|
@ -154,12 +154,24 @@ function buildplaylist(p_url, p_playIndex) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else if (data[index]['type'] == 1) {
|
} else if (data[index]['type'] == 1) {
|
||||||
media = {title: data[index]['element_title'],
|
var mime = data[index]['mime'];
|
||||||
artist: data[index]['element_artist'],
|
if (mime.search(/mp3/i) > 0 || mime.search(/mpeg/i) > 0) {
|
||||||
mp3:data[index]['uri']
|
key = "mp3";
|
||||||
};
|
} else if (mime.search(/og(g|a)/i) > 0 || mime.search(/vorbis/i) > 0) {
|
||||||
|
key = "oga";
|
||||||
|
} else if (mime.search(/mp4/i) > 0) {
|
||||||
|
key = "m4a";
|
||||||
|
} else if (mime.search(/wav/i) > 0) {
|
||||||
|
key = "wav";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key) {
|
||||||
|
media = {title: data[index]['element_title'],
|
||||||
|
artist: data[index]['element_artist']
|
||||||
|
};
|
||||||
|
media[key] = data[index]['uri']
|
||||||
|
}
|
||||||
}
|
}
|
||||||
console.log(data[index]);
|
|
||||||
if (media && isAudioSupported(data[index]['mime'])) {
|
if (media && isAudioSupported(data[index]['mime'])) {
|
||||||
// javascript doesn't support associative array with numeric key
|
// javascript doesn't support associative array with numeric key
|
||||||
// so we need to remove the gap if we skip any of tracks due to
|
// so we need to remove the gap if we skip any of tracks due to
|
||||||
|
|
|
@ -15,5 +15,6 @@ function isAudioSupported(mime){
|
||||||
//is adding a javascript library to do the work for you, which seems like overkill....
|
//is adding a javascript library to do the work for you, which seems like overkill....
|
||||||
return (!!audio.canPlayType && audio.canPlayType(bMime) != "") ||
|
return (!!audio.canPlayType && audio.canPlayType(bMime) != "") ||
|
||||||
(mime.indexOf("mp3") != -1 && navigator.mimeTypes ["application/x-shockwave-flash"] != undefined) ||
|
(mime.indexOf("mp3") != -1 && navigator.mimeTypes ["application/x-shockwave-flash"] != undefined) ||
|
||||||
(mime.indexOf("mp4") != -1 && navigator.mimeTypes ["application/x-shockwave-flash"] != undefined);
|
(mime.indexOf("mp4") != -1 && navigator.mimeTypes ["application/x-shockwave-flash"] != undefined) ||
|
||||||
|
(mime.indexOf("mpeg") != -1 && navigator.mimeTypes ["application/x-shockwave-flash"] != undefined);
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,6 +81,10 @@ var AIRTIME = (function(AIRTIME) {
|
||||||
return container;
|
return container;
|
||||||
},
|
},
|
||||||
cursor : 'pointer',
|
cursor : 'pointer',
|
||||||
|
cursorAt: {
|
||||||
|
top: 30,
|
||||||
|
left: 100
|
||||||
|
},
|
||||||
connectToSortable : '#show_builder_table'
|
connectToSortable : '#show_builder_table'
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -973,7 +973,6 @@ function addProgressIcon(id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkLibrarySCUploadStatus(){
|
function checkLibrarySCUploadStatus(){
|
||||||
|
|
||||||
var url = baseUrl+'/Library/get-upload-to-soundcloud-status',
|
var url = baseUrl+'/Library/get-upload-to-soundcloud-status',
|
||||||
span,
|
span,
|
||||||
id;
|
id;
|
||||||
|
@ -1026,6 +1025,7 @@ function addQtipToSCIcons(){
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if($(this).hasClass("soundcloud")){
|
else if($(this).hasClass("soundcloud")){
|
||||||
|
var sc_id = $(this).parent().parent().data("aData").soundcloud_id;
|
||||||
$(this).qtip({
|
$(this).qtip({
|
||||||
content: {
|
content: {
|
||||||
text: $.i18n._("Retrieving data from the server..."),
|
text: $.i18n._("Retrieving data from the server..."),
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
define('AIRTIME_VERSION', '2.2.0');
|
define('AIRTIME_VERSION', '2.2.1');
|
||||||
|
|
|
@ -100,4 +100,8 @@ if (strcmp($version, "2.2.0") < 0) {
|
||||||
passthru("php --php-ini $SCRIPTPATH/../airtime-php.ini $SCRIPTPATH/../upgrades/airtime-2.2.0/airtime-upgrade.php");
|
passthru("php --php-ini $SCRIPTPATH/../airtime-php.ini $SCRIPTPATH/../upgrades/airtime-2.2.0/airtime-upgrade.php");
|
||||||
pause();
|
pause();
|
||||||
}
|
}
|
||||||
|
if (strcmp($version, "2.2.1") < 0) {
|
||||||
|
passthru("php --php-ini $SCRIPTPATH/../airtime-php.ini $SCRIPTPATH/../upgrades/airtime-2.2.1/airtime-upgrade.php");
|
||||||
|
pause();
|
||||||
|
}
|
||||||
echo "******************************* Upgrade Complete *******************************".PHP_EOL;
|
echo "******************************* Upgrade Complete *******************************".PHP_EOL;
|
||||||
|
|
|
@ -15,7 +15,7 @@ import json
|
||||||
import base64
|
import base64
|
||||||
from configobj import ConfigObj
|
from configobj import ConfigObj
|
||||||
|
|
||||||
AIRTIME_VERSION = "2.2.0"
|
AIRTIME_VERSION = "2.2.1"
|
||||||
|
|
||||||
|
|
||||||
# TODO : Place these functions in some common module. Right now, media
|
# TODO : Place these functions in some common module. Right now, media
|
||||||
|
|
|
@ -11,11 +11,7 @@ set("server.telnet.port", 1234)
|
||||||
webstream_enabled = ref false
|
webstream_enabled = ref false
|
||||||
|
|
||||||
time = ref string_of(gettimeofday())
|
time = ref string_of(gettimeofday())
|
||||||
queue = audio_to_stereo(id="queue_src", mksafe(request.equeue(id="queue", length=0.5)))
|
|
||||||
queue = cue_cut(queue)
|
|
||||||
queue = amplify(1., override="replay_gain", queue)
|
|
||||||
|
|
||||||
#fallback between queue and input.harbor (for restreaming other web-streams)
|
|
||||||
#live stream setup
|
#live stream setup
|
||||||
set("harbor.bind_addr", "0.0.0.0")
|
set("harbor.bind_addr", "0.0.0.0")
|
||||||
|
|
||||||
|
@ -43,10 +39,9 @@ just_switched = ref false
|
||||||
#web_stream = on_metadata(notify_stream, web_stream)
|
#web_stream = on_metadata(notify_stream, web_stream)
|
||||||
#output.dummy(fallible=true, web_stream)
|
#output.dummy(fallible=true, web_stream)
|
||||||
|
|
||||||
|
queue = audio_to_stereo(id="queue_src", request.equeue(id="queue", length=0.5))
|
||||||
http = input.http_restart(id="http")
|
queue = cue_cut(queue)
|
||||||
http = cross_http(http_input_id="http",http)
|
queue = amplify(1., override="replay_gain", queue)
|
||||||
stream_queue = http_fallback(http_input_id="http",http=http,default=queue)
|
|
||||||
|
|
||||||
# the crossfade function controls fade in/out
|
# the crossfade function controls fade in/out
|
||||||
queue = crossfade_airtime(queue)
|
queue = crossfade_airtime(queue)
|
||||||
|
@ -54,11 +49,9 @@ queue = on_metadata(notify, queue)
|
||||||
queue = map_metadata(update=false, append_title, queue)
|
queue = map_metadata(update=false, append_title, queue)
|
||||||
output.dummy(fallible=true, queue)
|
output.dummy(fallible=true, queue)
|
||||||
|
|
||||||
|
http = input.http_restart(id="http")
|
||||||
#stream_queue = switch(id="stream_queue_switch", track_sensitive=false,
|
http = cross_http(http_input_id="http",http)
|
||||||
# transitions=[transition, transition],
|
stream_queue = http_fallback(http_input_id="http",http=http,default=queue)
|
||||||
# [({!webstream_enabled},web_stream),
|
|
||||||
# ({true}, queue)])
|
|
||||||
|
|
||||||
ignore(output.dummy(stream_queue, fallible=true))
|
ignore(output.dummy(stream_queue, fallible=true))
|
||||||
|
|
||||||
|
@ -88,7 +81,9 @@ server.register(namespace="dynamic_source",
|
||||||
description="Enable webstream output",
|
description="Enable webstream output",
|
||||||
usage='start',
|
usage='start',
|
||||||
"output_start",
|
"output_start",
|
||||||
fun (s) -> begin log("dynamic_source.output_start") webstream_enabled := true "enabled" end)
|
fun (s) -> begin log("dynamic_source.output_start")
|
||||||
|
notify([("schedule_table_id", !current_dyn_id)])
|
||||||
|
webstream_enabled := true "enabled" end)
|
||||||
server.register(namespace="dynamic_source",
|
server.register(namespace="dynamic_source",
|
||||||
description="Enable webstream output",
|
description="Enable webstream output",
|
||||||
usage='stop',
|
usage='stop',
|
||||||
|
@ -229,6 +224,7 @@ end
|
||||||
s = switch(id="default_switch", track_sensitive=false,
|
s = switch(id="default_switch", track_sensitive=false,
|
||||||
transitions=[transition_default, transition],
|
transitions=[transition_default, transition],
|
||||||
[({!scheduled_play_enabled}, stream_queue),({true},default)])
|
[({!scheduled_play_enabled}, stream_queue),({true},default)])
|
||||||
|
|
||||||
s = append_dj_inputs(master_live_stream_port, master_live_stream_mp,
|
s = append_dj_inputs(master_live_stream_port, master_live_stream_mp,
|
||||||
dj_live_stream_port, dj_live_stream_mp, s)
|
dj_live_stream_port, dj_live_stream_mp, s)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue