Use track metadata from Airtime in playout engine
* Resolves CC-5893: Metadata not updated on Airtime Pro * Report track metadata in the schedule API, and make pypo pass that along to Liquidsoap via annotations. * Move HTTP response sanitization for file metadata out of the REST module and into CcFiles * Slightly improved the terrible exception handling in pypo
This commit is contained in:
parent
63113b4e75
commit
790af06929
|
@ -738,13 +738,16 @@ SQL;
|
|||
$replay_gain = is_null($item["replay_gain"]) ? "0": $item["replay_gain"];
|
||||
$replay_gain += Application_Model_Preference::getReplayGainModifier();
|
||||
|
||||
if ( !Application_Model_Preference::GetEnableReplayGain() ) {
|
||||
if (!Application_Model_Preference::GetEnableReplayGain() ) {
|
||||
$replay_gain = 0;
|
||||
}
|
||||
|
||||
$fileMetadata = CcFiles::sanitizeResponse(CcFilesQuery::create()->findPk($media_id));
|
||||
|
||||
$schedule_item = array(
|
||||
'id' => $media_id,
|
||||
'type' => 'file',
|
||||
'metadata' => $fileMetadata,
|
||||
'row_id' => $item["id"],
|
||||
'uri' => $uri,
|
||||
'fade_in' => Application_Model_Schedule::WallTimeToMillisecs($item["fade_in"]),
|
||||
|
|
|
@ -13,6 +13,14 @@
|
|||
*/
|
||||
class CcFiles extends BaseCcFiles {
|
||||
|
||||
//fields we should never expose through our RESTful API
|
||||
private static $privateFields = array(
|
||||
'file_exists',
|
||||
'silan_check',
|
||||
'is_scheduled',
|
||||
'is_playlist'
|
||||
);
|
||||
|
||||
public function getCueLength()
|
||||
{
|
||||
$cuein = $this->getDbCuein();
|
||||
|
@ -46,4 +54,20 @@ class CcFiles extends BaseCcFiles {
|
|||
$this->save();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Strips out the private fields we do not want to send back in API responses
|
||||
* @param $file a CcFiles object
|
||||
*/
|
||||
//TODO: rename this function?
|
||||
public static function sanitizeResponse($file)
|
||||
{
|
||||
$response = $file->toArray(BasePeer::TYPE_FIELDNAME);
|
||||
|
||||
foreach (self::$privateFields as $key) {
|
||||
unset($response[$key]);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
} // CcFiles
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
class Rest_MediaController extends Zend_Rest_Controller
|
||||
{
|
||||
//fields that are not modifiable via our RESTful API
|
||||
private $blackList = array(
|
||||
private static $blackList = array(
|
||||
'id',
|
||||
'directory',
|
||||
'filepath',
|
||||
|
@ -18,14 +18,6 @@ class Rest_MediaController extends Zend_Rest_Controller
|
|||
'is_playlist'
|
||||
);
|
||||
|
||||
//fields we should never expose through our RESTful API
|
||||
private $privateFields = array(
|
||||
'file_exists',
|
||||
'silan_check',
|
||||
'is_scheduled',
|
||||
'is_playlist'
|
||||
);
|
||||
|
||||
public function init()
|
||||
{
|
||||
$this->view->layout()->disableLayout();
|
||||
|
@ -41,7 +33,7 @@ class Rest_MediaController extends Zend_Rest_Controller
|
|||
$files_array = array();
|
||||
foreach (CcFilesQuery::create()->find() as $file)
|
||||
{
|
||||
array_push($files_array, $this->sanitizeResponse($file));
|
||||
array_push($files_array, CcFiles::sanitizeResponse($file));
|
||||
}
|
||||
|
||||
$this->getResponse()
|
||||
|
@ -134,7 +126,7 @@ class Rest_MediaController extends Zend_Rest_Controller
|
|||
|
||||
$this->getResponse()
|
||||
->setHttpResponseCode(200)
|
||||
->appendBody(json_encode($this->sanitizeResponse($file)));
|
||||
->appendBody(json_encode(CcFiles::sanitizeResponse($file)));
|
||||
} else {
|
||||
$this->fileNotFoundResponse();
|
||||
}
|
||||
|
@ -201,7 +193,7 @@ class Rest_MediaController extends Zend_Rest_Controller
|
|||
|
||||
$this->getResponse()
|
||||
->setHttpResponseCode(201)
|
||||
->appendBody(json_encode($this->sanitizeResponse($file)));
|
||||
->appendBody(json_encode(CcFiles::sanitizeResponse($file)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -265,7 +257,7 @@ class Rest_MediaController extends Zend_Rest_Controller
|
|||
|
||||
$this->getResponse()
|
||||
->setHttpResponseCode(200)
|
||||
->appendBody(json_encode($this->sanitizeResponse($file)));
|
||||
->appendBody(json_encode(CcFiles::sanitizeResponse($file)));
|
||||
} else {
|
||||
$file->setDbImportStatus(2)->save();
|
||||
$this->fileNotFoundResponse();
|
||||
|
@ -490,30 +482,15 @@ class Rest_MediaController extends Zend_Rest_Controller
|
|||
* from outside of Airtime
|
||||
* @param array $data
|
||||
*/
|
||||
private function removeBlacklistedFieldsFromRequestData($data)
|
||||
private static function removeBlacklistedFieldsFromRequestData($data)
|
||||
{
|
||||
foreach ($this->blackList as $key) {
|
||||
foreach (self::$blackList as $key) {
|
||||
unset($data[$key]);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Strips out the private fields we do not want to send back in API responses
|
||||
*/
|
||||
//TODO: rename this function?
|
||||
public function sanitizeResponse($file)
|
||||
{
|
||||
$response = $file->toArray(BasePeer::TYPE_FIELDNAME);
|
||||
|
||||
foreach ($this->privateFields as $key) {
|
||||
unset($response[$key]);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
private function removeEmptySubFolders($path)
|
||||
{
|
||||
|
|
|
@ -44,5 +44,8 @@ while not successful:
|
|||
logging.error("traceback: %s", traceback.format_exc())
|
||||
sys.exit(1)
|
||||
else:
|
||||
logging.error(str(e))
|
||||
logging.error("traceback: %s", traceback.format_exc())
|
||||
logging.info("Retrying in 3 seconds...")
|
||||
time.sleep(3)
|
||||
attempts += 1
|
||||
|
|
|
@ -3,17 +3,31 @@ from timeout import ls_timeout
|
|||
|
||||
def create_liquidsoap_annotation(media):
|
||||
# We need liq_start_next value in the annotate. That is the value that controls overlap duration of crossfade.
|
||||
return ('annotate:media_id="%s",liq_start_next="0",liq_fade_in="%s",' + \
|
||||
|
||||
filename = media['dst']
|
||||
annotation = ('annotate:media_id="%s",liq_start_next="0",liq_fade_in="%s",' + \
|
||||
'liq_fade_out="%s",liq_cue_in="%s",liq_cue_out="%s",' + \
|
||||
'schedule_table_id="%s",replay_gain="%s dB":%s') % \
|
||||
(media['id'],
|
||||
float(media['fade_in']) / 1000,
|
||||
float(media['fade_out']) / 1000,
|
||||
float(media['cue_in']),
|
||||
float(media['cue_out']),
|
||||
media['row_id'],
|
||||
media['replay_gain'],
|
||||
media['dst'])
|
||||
'schedule_table_id="%s",replay_gain="%s dB"') % \
|
||||
(media['id'],
|
||||
float(media['fade_in']) / 1000,
|
||||
float(media['fade_out']) / 1000,
|
||||
float(media['cue_in']),
|
||||
float(media['cue_out']),
|
||||
media['row_id'],
|
||||
media['replay_gain'])
|
||||
|
||||
# Override the the artist/title that Liquidsoap extracts from a file's metadata
|
||||
# with the metadata we get from Airtime. (You can modify metadata in Airtime's library,
|
||||
# which doesn't get saved back to the file.)
|
||||
if 'metadata' in media:
|
||||
if 'artist_name' in media['metadata']:
|
||||
annotation += ',artist="%s"' % (media['metadata']['artist_name'])
|
||||
if 'track_title' in media['metadata']:
|
||||
annotation += ',title="%s"' % (media['metadata']['track_title'])
|
||||
|
||||
annotation += ":" + filename
|
||||
|
||||
return annotation
|
||||
|
||||
class TelnetLiquidsoap:
|
||||
|
||||
|
|
Loading…
Reference in New Issue