feat(legacy): read stream config from file

- We don't delete the stream preferences from the database to prevent data loss. This will be handled in a future release.
This commit is contained in:
jo 2022-09-06 12:00:50 +02:00 committed by Kyle Robbertze
parent ba73866e47
commit 5bf62dd9cb
14 changed files with 498 additions and 1237 deletions

View File

@ -7,18 +7,13 @@ INSERT INTO cc_live_log ("state", "start_time") VALUES ('S', now() at time zone
INSERT INTO cc_pref ("keystr", "valstr") VALUES ('import_timestamp', '0');
INSERT INTO cc_pref ("keystr", "valstr") VALUES ('timezone', 'UTC');
INSERT INTO cc_pref ("keystr", "valstr") VALUES ('default_stream_mount_point', 'main');
INSERT INTO cc_pref ("keystr", "valstr") VALUES ('off_air_meta', 'LibreTime - offline');
INSERT INTO cc_pref ("keystr", "valstr") VALUES ('enable_replay_gain', 1);
INSERT INTO cc_pref ("keystr", "valstr") VALUES ('locale', 'en_US');
INSERT INTO cc_pref ("keystr", "valstr") VALUES ('max_bitrate', '320');
INSERT INTO cc_pref ("keystr", "valstr") VALUES ('num_of_streams', '3');
INSERT INTO cc_pref ("keystr", "valstr") VALUES ('plan_level', 'disabled');
INSERT INTO cc_pref ("keystr", "valstr") VALUES ('podcast_album_override', 1);
INSERT INTO cc_pref ("keystr", "valstr") VALUES ('podcast_auto_smartblock', 0);
INSERT INTO cc_pref ("keystr", "valstr") VALUES ('scheduled_play_switch', 'on');
INSERT INTO cc_pref ("keystr", "valstr") VALUES ('stream_bitrate', '24, 32, 48, 64, 96, 128, 160, 192, 224, 256, 320');
INSERT INTO cc_pref ("keystr", "valstr") VALUES ('stream_type', 'ogg, mp3, opus, aac');
INSERT INTO cc_pref ("keystr", "valstr") VALUES ('whats_new_dialog_viewed', 1);
INSERT INTO cc_subjs ("login", "type", "pass") VALUES ('admin', 'A', md5('admin'));

View File

@ -23,6 +23,10 @@ class Schema implements ConfigurationInterface
return rtrim($v, '/') . '/';
};
$trim_leading_slash = function ($v) {
return ltrim($v, '/');
};
$treeBuilder = new TreeBuilder('');
$treeBuilder->getRootNode()
->children()
@ -89,6 +93,111 @@ class Schema implements ConfigurationInterface
/**/->ignoreExtraKeys()
->end()
// Stream schema
->arrayNode('stream')->ignoreExtraKeys()->addDefaultsIfNotSet()->children()
// Stream inputs
->arrayNode('inputs')->addDefaultsIfNotSet()->children()
/**/->arrayNode('main')->addDefaultsIfNotSet()->children()
/* */->booleanNode('enabled')->defaultTrue()->end()
/* */->enumNode('kind')->values(['harbor'])->defaultValue('harbor')->end()
/* */->scalarNode('public_url')->end()
/* */->scalarNode('mount')->defaultValue("main")
/* */->validate()->ifString()->then($trim_leading_slash)->end()
/* */->end()
/* */->integerNode('port')->defaultValue(8001)->end()
/**/->end()->end()
/**/->arrayNode('show')->addDefaultsIfNotSet()->children()
/* */->booleanNode('enabled')->defaultTrue()->end()
/* */->enumNode('kind')->values(['harbor'])->defaultValue('harbor')->end()
/* */->scalarNode('public_url')->end()
/* */->scalarNode('mount')->defaultValue("show")
/* */->validate()->ifString()->then($trim_leading_slash)->end()
/* */->end()
/* */->integerNode('port')->defaultValue(8002)->end()
/**/->end()->end()
->end()->end()
// Stream outputs
->arrayNode('outputs')->ignoreExtraKeys()->addDefaultsIfNotSet()->children()
// Icecast outputs
/**/->arrayNode('icecast')->arrayPrototype()->children()
/* */->booleanNode('enabled')->defaultFalse()->end()
/* */->enumNode('kind')->values(['icecast'])->defaultValue('icecast')->end()
/* */->scalarNode('public_url')->end()
/* */->scalarNode('host')->defaultValue('localhost')->end()
/* */->integerNode('port')->defaultValue(8000)->end()
/* */->scalarNode('mount')->cannotBeEmpty()
/* */->validate()->ifString()->then($trim_leading_slash)->end()
/* */->end()
/* */->scalarNode('source_user')->defaultValue('source')->end()
/* */->scalarNode('source_password')->cannotBeEmpty()->end()
/* */->scalarNode('admin_user')->defaultValue('admin')->end()
/* */->scalarNode('admin_password')->end()
/* */->arrayNode('audio')->addDefaultsIfNotSet()->children()
/* */->scalarNode('channels')->defaultValue('stereo')
/* */->validate()->ifNotInArray(['stereo', 'mono'])
/* */->thenInvalid('invalid stream.outputs.icecast.audio.channels %s')
/* */->end()
/* */->end()
/* */->scalarNode('format')->cannotBeEmpty()
/* */->validate()->ifNotInArray(['aac', 'mp3', 'ogg', 'opus'])
/* */->thenInvalid('invalid stream.outputs.icecast.audio.format %s')
/* */->end()
/* */->end()
/* */->integerNode('bitrate')->isRequired()->end()
/* */->booleanNode('enable_metadata')->defaultFalse()->end()
/* */->end()->end()
/* */->scalarNode('name')->end()
/* */->scalarNode('description')->end()
/* */->scalarNode('website')->end()
/* */->scalarNode('genre')->end()
/**/->end()->end()->end()
// Shoutcast outputs
/**/->arrayNode('shoutcast')->arrayPrototype()->children()
/* */->booleanNode('enabled')->defaultFalse()->end()
/* */->enumNode('kind')->values(['shoutcast'])->defaultValue('shoutcast')->end()
/* */->scalarNode('public_url')->end()
/* */->scalarNode('host')->defaultValue('localhost')->end()
/* */->integerNode('port')->defaultValue(8000)->end()
/* */->scalarNode('source_user')->defaultValue('source')->end()
/* */->scalarNode('source_password')->cannotBeEmpty()->end()
/* */->scalarNode('admin_user')->defaultValue('admin')->end()
/* */->scalarNode('admin_password')->end()
/* */->arrayNode('audio')->addDefaultsIfNotSet()->children()
/* */->scalarNode('channels')->defaultValue('stereo')
/* */->validate()->ifNotInArray(['stereo', 'mono'])
/* */->thenInvalid('invalid stream.outputs.shoutcast.audio.channels %s')
/* */->end()
/* */->end()
/* */->scalarNode('format')->cannotBeEmpty()
/* */->validate()->ifNotInArray(['aac', 'mp3'])
/* */->thenInvalid('invalid stream.outputs.shoutcast.audio.format %s')
/* */->end()
/* */->end()
/* */->integerNode('bitrate')->isRequired()->end()
/* */->end()->end()
/* */->scalarNode('name')->end()
/* */->scalarNode('website')->end()
/* */->scalarNode('genre')->end()
/**/->end()->end()->end()
// System outputs
/**/->arrayNode('system')->arrayPrototype()->children()
/* */->booleanNode('enabled')->defaultFalse()->end()
/* */->scalarNode('kind')->defaultValue('alsa')
/* */->validate()->ifNotInArray(["alsa", "ao", "oss", "portaudio", "pulseaudio"])
/* */->thenInvalid('invalid stream.outputs.system.kind %s')
/* */->end()->end()
/**/->end()->end()->end()
->end()->end()
// END Stream schema
->end()->end()
// END Schema
->end();
@ -138,6 +247,12 @@ class Config
exit;
}
// Merge Icecast and Shoutcast outputs
$values['stream']['outputs']['merged'] = array_merge(
$values['stream']['outputs']['icecast'],
$values['stream']['outputs']['shoutcast']
);
self::$values = $values;
self::fillLegacyValues($values);
self::$dot_values = new Dot($values);
@ -237,6 +352,9 @@ class Config
// Storage
$legacy_values['storagePath'] = $values['storage']['path'];
// Stream
$legacy_values['stream'] = $values['stream'];
// Facebook (DEPRECATED)
if (isset($values['facebook']['facebook_app_id'])) {
$legacy_values['facebook-app-id'] = $values['facebook']['facebook_app_id'];

View File

@ -13,7 +13,6 @@ class PreferenceController extends Zend_Controller_Action
->addActionContext('is-import-in-progress', 'json')
->addActionContext('change-stream-setting', 'json')
->addActionContext('get-liquidsoap-status', 'json')
->addActionContext('set-source-connection-url', 'json')
->addActionContext('get-admin-password-status', 'json')
->initContext();
}
@ -162,28 +161,6 @@ class PreferenceController extends Zend_Controller_Action
$live_stream_subform = new Application_Form_LiveStreamingPreferences();
$form->addSubForm($live_stream_subform, 'live_stream_subform');
// get predefined type and bitrate from pref table
$temp_types = Application_Model_Preference::GetStreamType();
$stream_types = [];
foreach ($temp_types as $type) {
$type = strtolower(trim($type));
if (isset($name_map[$type])) {
$name = $name_map[$type];
} else {
$name = $type;
}
$stream_types[$type] = $name;
}
$temp_bitrate = Application_Model_Preference::GetStreamBitrate();
$max_bitrate = intval(Application_Model_Preference::GetMaxBitrate());
$stream_bitrates = [];
foreach ($temp_bitrate as $type) {
if (intval($type) <= $max_bitrate) {
$stream_bitrates[trim($type)] = strtoupper(trim($type)) . ' kbit/s';
}
}
// get current settings
$setting = Application_Model_StreamSetting::getStreamSetting();
$form->setSetting($setting);
@ -192,10 +169,7 @@ class PreferenceController extends Zend_Controller_Action
$subform = new Application_Form_StreamSettingSubForm();
$subform->setPrefix($i);
$subform->setSetting($setting);
$subform->setStreamTypes($stream_types);
$subform->setStreamBitrates($stream_bitrates);
$subform->startForm();
$subform->toggleState();
$form->addSubForm($subform, 's' . $i . '_subform');
}
@ -208,48 +182,14 @@ class PreferenceController extends Zend_Controller_Action
* $form->isValid() is expecting it in
*/
$postData = explode('&', $params['data']);
$s1_data = [];
$s2_data = [];
$s3_data = [];
$s4_data = [];
$values = [];
foreach ($postData as $k => $v) {
$v = explode('=', urldecode($v));
if (strpos($v[0], 's1_data') !== false) {
/* In this case $v[0] may be 's1_data[enable]' , for example.
* We only want the 'enable' part
*/
preg_match('/\[(.*)\]/', $v[0], $matches);
$s1_data[$matches[1]] = $v[1];
} elseif (strpos($v[0], 's2_data') !== false) {
preg_match('/\[(.*)\]/', $v[0], $matches);
$s2_data[$matches[1]] = $v[1];
} elseif (strpos($v[0], 's3_data') !== false) {
preg_match('/\[(.*)\]/', $v[0], $matches);
$s3_data[$matches[1]] = $v[1];
} elseif (strpos($v[0], 's4_data') !== false) {
preg_match('/\[(.*)\]/', $v[0], $matches);
$s4_data[$matches[1]] = $v[1];
} else {
$values[$v[0]] = $v[1];
}
$values[$v[0]] = $v[1];
}
$values['s1_data'] = $s1_data;
$values['s2_data'] = $s2_data;
$values['s3_data'] = $s3_data;
$values['s4_data'] = $s4_data;
if ($form->isValid($values)) {
Application_Model_StreamSetting::setStreamSetting($values);
/* If the admin password values are empty then we should not
* set the pseudo password ('xxxxxx') on the front-end
*/
$s1_set_admin_pass = !empty($values['s1_data']['admin_pass']);
$s2_set_admin_pass = !empty($values['s2_data']['admin_pass']);
$s3_set_admin_pass = !empty($values['s3_data']['admin_pass']);
$s4_set_admin_pass = !empty($values['s4_data']['admin_pass']);
// this goes into cc_pref table
$this->setStreamPreferences($values);
@ -264,47 +204,9 @@ class PreferenceController extends Zend_Controller_Action
// Application_Model_RabbitMq::PushSchedule();
}
// pulling this from the 2.5.x branch
if (!Application_Model_Preference::GetMasterDjConnectionUrlOverride()) {
$master_connection_url = 'http://' . $_SERVER['SERVER_NAME'] . ':' . $values['master_source_port'] . $values['master_source_mount'];
if (empty($values['master_source_port']) || empty($values['master_source_mount'])) {
Application_Model_Preference::SetMasterDJSourceConnectionURL('N/A');
} else {
Application_Model_Preference::SetMasterDJSourceConnectionURL($master_connection_url);
}
} else {
Application_Model_Preference::SetMasterDJSourceConnectionURL($values['master_source_host']);
}
if (!Application_Model_Preference::GetLiveDjConnectionUrlOverride()) {
$live_connection_url = 'http://' . $_SERVER['SERVER_NAME'] . ':' . $values['show_source_port'] . $values['show_source_mount'];
if (empty($values['show_source_port']) || empty($values['show_source_mount'])) {
Application_Model_Preference::SetLiveDJSourceConnectionURL('N/A');
} else {
Application_Model_Preference::SetLiveDJSourceConnectionURL($live_connection_url);
}
} else {
Application_Model_Preference::SetLiveDJSourceConnectionURL($values['show_source_host']);
}
Application_Model_StreamSetting::setMasterLiveStreamPort($values['master_source_port']);
Application_Model_StreamSetting::setMasterLiveStreamMountPoint($values['master_source_mount']);
Application_Model_StreamSetting::setDjLiveStreamPort($values['show_source_port']);
Application_Model_StreamSetting::setDjLiveStreamMountPoint($values['show_source_mount']);
Application_Model_Preference::setOffAirMeta($values['offAirMeta']);
// store stream update timestamp
Application_Model_Preference::SetStreamUpdateTimestamp();
$data = [];
$info = Application_Model_StreamSetting::getStreamSetting();
$data['setting'] = $info;
for ($i = 1; $i <= $num_of_stream; ++$i) {
Application_Model_Preference::setLiquidsoapError($i, 'waiting');
}
Application_Model_RabbitMq::SendMessageToPypo('update_stream_setting', $data);
$this->view->statusMsg = "<div class='success'>" . _('Stream Setting Updated.') . '</div>';
}
}
@ -312,15 +214,12 @@ class PreferenceController extends Zend_Controller_Action
$this->view->num_stream = $num_of_stream;
$this->view->enable_stream_conf = Application_Model_Preference::GetEnableStreamConf();
$this->view->form = $form;
if ($request->isPost()) {
if ($form->isValid($values)) {
$this->_helper->json->sendJson([
'valid' => 'true',
'html' => $this->view->render('preference/stream-setting.phtml'),
's1_set_admin_pass' => $s1_set_admin_pass,
's2_set_admin_pass' => $s2_set_admin_pass,
's3_set_admin_pass' => $s3_set_admin_pass,
's4_set_admin_pass' => $s4_set_admin_pass,
]);
} else {
$this->_helper->json->sendJson(['valid' => 'false', 'html' => $this->view->render('preference/stream-setting.phtml')]);
@ -335,7 +234,7 @@ class PreferenceController extends Zend_Controller_Action
*/
private function setStreamPreferences($values)
{
Application_Model_Preference::setUsingCustomStreamSettings($values['customStreamSettings']);
Application_Model_Preference::setOffAirMeta($values['offAirMeta']);
Application_Model_Preference::SetStreamLabelFormat($values['streamFormat']);
Application_Model_Preference::SetLiveStreamMasterUsername($values['master_username']);
Application_Model_Preference::SetLiveStreamMasterPassword($values['master_password']);
@ -405,26 +304,6 @@ class PreferenceController extends Zend_Controller_Action
$this->_helper->json->sendJson($out);
}
public function setSourceConnectionUrlAction()
{
SessionHelper::reopenSessionForWriting();
$request = $this->getRequest();
$type = $request->getParam('type', null);
$url = urldecode($request->getParam('url', null));
$override = $request->getParam('override', false);
if ($type == 'masterdj') {
Application_Model_Preference::SetMasterDJSourceConnectionURL($url);
Application_Model_Preference::SetMasterDjConnectionUrlOverride($override);
} elseif ($type == 'livedj') {
Application_Model_Preference::SetLiveDJSourceConnectionURL($url);
Application_Model_Preference::SetLiveDjConnectionUrlOverride($override);
}
$this->_helper->json->sendJson(null);
}
public function getAdminPasswordStatusAction()
{
SessionHelper::reopenSessionForWriting();

View File

@ -4,9 +4,6 @@ class Application_Form_LiveStreamingPreferences extends Zend_Form_SubForm
{
public function init()
{
$CC_CONFIG = Config::getConfig();
$isDemo = isset($CC_CONFIG['demo']) && $CC_CONFIG['demo'] == 1;
$defaultFade = Application_Model_Preference::GetDefaultTransitionFade();
$this->setDecorators([
@ -46,13 +43,9 @@ class Application_Form_LiveStreamingPreferences extends Zend_Form_SubForm
$this->addElement($master_username);
// Master password
if ($isDemo) {
$master_password = new Zend_Form_Element_Text('master_password');
} else {
$master_password = new Zend_Form_Element_Password('master_password');
$master_password->setAttrib('renderPassword', 'true');
}
$master_password->setAttrib('autocomplete', 'off')
$master_password = new Zend_Form_Element_Password('master_password');
$master_password
->setAttrib('autocomplete', 'off')
->setAttrib('renderPassword', 'true')
->setAllowEmpty(true)
->setValue(Application_Model_Preference::GetLiveStreamMasterPassword())
@ -60,74 +53,53 @@ class Application_Form_LiveStreamingPreferences extends Zend_Form_SubForm
->setFilters(['StringTrim']);
$this->addElement($master_password);
$masterSourceParams = parse_url(Application_Model_Preference::GetMasterDJSourceConnectionURL());
// Master source connection url parameters
$masterSourceHost = new Zend_Form_Element_Text('master_source_host');
$masterSourceHost->setLabel(_('Master Source Host:'))
$masterSourceHost
->setLabel(_('Master Source Host:'))
->setAttrib('readonly', true)
->setValue(Application_Model_Preference::GetMasterDJSourceConnectionURL());
$this->addElement($masterSourceHost);
// liquidsoap harbor.input port
$betweenValidator = Application_Form_Helper_ValidationTypes::overrideBetweenValidator(1024, 49151);
$m_port = Application_Model_StreamSetting::getMasterLiveStreamPort();
$masterSourcePort = new Zend_Form_Element_Text('master_source_port');
$masterSourcePort->setLabel(_('Master Source Port:'))
->setValue($m_port)
->setValidators([$betweenValidator])
->addValidator('regex', false, ['pattern' => '/^[0-9]+$/', 'messages' => ['regexNotMatch' => _('Only numbers are allowed.')]]);
$masterSourcePort
->setLabel(_('Master Source Port:'))
->setAttrib('readonly', true)
->setValue(Application_Model_StreamSetting::getMasterLiveStreamPort());
$this->addElement($masterSourcePort);
$m_mount = Application_Model_StreamSetting::getMasterLiveStreamMountPoint();
$masterSourceMount = new Zend_Form_Element_Text('master_source_mount');
$masterSourceMount->setLabel(_('Master Source Mount:'))
->setValue($m_mount)
->setValidators([
['regex', false, ['/^[^ &<>]+$/', 'messages' => _('Invalid character entered')]],
]);
$masterSourceMount
->setLabel(_('Master Source Mount:'))
->setAttrib('readonly', true)
->setValue(Application_Model_StreamSetting::getMasterLiveStreamMountPoint());
$this->addElement($masterSourceMount);
$showSourceParams = parse_url(Application_Model_Preference::GetLiveDJSourceConnectionURL());
// Show source connection url parameters
$showSourceHost = new Zend_Form_Element_Text('show_source_host');
$showSourceHost->setLabel(_('Show Source Host:'))
$showSourceHost
->setLabel(_('Show Source Host:'))
->setAttrib('readonly', true)
->setValue(Application_Model_Preference::GetLiveDJSourceConnectionURL());
$this->addElement($showSourceHost);
// liquidsoap harbor.input port
$l_port = Application_Model_StreamSetting::getDjLiveStreamPort();
$showSourcePort = new Zend_Form_Element_Text('show_source_port');
$showSourcePort->setLabel(_('Show Source Port:'))
->setValue($l_port)
->setValidators([$betweenValidator])
->addValidator('regex', false, ['pattern' => '/^[0-9]+$/', 'messages' => ['regexNotMatch' => _('Only numbers are allowed.')]]);
$showSourcePort
->setLabel(_('Show Source Port:'))
->setAttrib('readonly', true)
->setValue(Application_Model_StreamSetting::getDjLiveStreamPort());
$this->addElement($showSourcePort);
$l_mount = Application_Model_StreamSetting::getDjLiveStreamMountPoint();
$showSourceMount = new Zend_Form_Element_Text('show_source_mount');
$showSourceMount->setLabel(_('Show Source Mount:'))
->setValue($l_mount)
->setValidators([
['regex', false, ['/^[^ &<>]+$/', 'messages' => _('Invalid character entered')]],
]);
$showSourceMount
->setLabel(_('Show Source Mount:'))
->setAttrib('readonly', true)
->setValue(Application_Model_StreamSetting::getDjLiveStreamMountPoint());
$this->addElement($showSourceMount);
}
public function updateVariables()
{
$CC_CONFIG = Config::getConfig();
$isDemo = isset($CC_CONFIG['demo']) && $CC_CONFIG['demo'] == 1;
$masterSourceParams = parse_url(Application_Model_Preference::GetMasterDJSourceConnectionURL());
$showSourceParams = parse_url(Application_Model_Preference::GetLiveDJSourceConnectionURL());
$this->setDecorators(
[
[
@ -140,7 +112,6 @@ class Application_Form_LiveStreamingPreferences extends Zend_Form_SubForm
'show_source_host' => isset($showSourceHost) ? Application_Model_Preference::GetLiveDJSourceConnectionURL() : '',
'show_source_port' => isset($showSourcePort) ? Application_Model_StreamSetting::getDjLiveStreamPort() : '',
'show_source_mount' => isset($showSourceMount) ? Application_Model_StreamSetting::getDjLiveStreamMountPoint() : '',
'isDemo' => $isDemo,
],
],
]

View File

@ -21,88 +21,55 @@ class Application_Form_StreamSetting extends Zend_Form
$setting = $this->setting;
$stream_format = new Zend_Form_Element_Radio('streamFormat');
$stream_format
->setLabel(_('Stream Label:'))
->setMultiOptions([
_('Artist - Title'),
_('Show - Artist - Title'),
_('Station name - Show name'),
])
->setValue(Application_Model_Preference::GetStreamLabelFormat())
->setDecorators(['ViewHelper']);
$this->addElement($stream_format);
$offAirMeta = new Zend_Form_Element_Text('offAirMeta');
$offAirMeta
->setLabel(_('Off Air Metadata'))
->setValue(Application_Model_Preference::getOffAirMeta())
->setDecorators(['ViewHelper']);
$this->addElement($offAirMeta);
$enable_replay_gain = new Zend_Form_Element_Checkbox('enableReplayGain');
$enable_replay_gain
->setLabel(_('Enable Replay Gain'))
->setValue(Application_Model_Preference::GetEnableReplayGain())
->setDecorators(['ViewHelper']);
$this->addElement($enable_replay_gain);
$replay_gain = new Zend_Form_Element_Hidden('replayGainModifier');
$replay_gain
->setLabel(_('Replay Gain Modifier'))
->setValue(Application_Model_Preference::getReplayGainModifier())
->setAttribs(['style' => 'border: 0; color: #f6931f; font-weight: bold;'])
->setDecorators(['ViewHelper']);
$this->addElement($replay_gain);
$output_sound_device = new Zend_Form_Element_Checkbox('output_sound_device');
$output_sound_device->setLabel(_('Hardware Audio Output:'))
$output_sound_device
->setLabel(_('Hardware Audio Output:'))
->setAttrib('readonly', true)
->setRequired(false)
->setValue(($setting['output_sound_device'] == 'true') ? 1 : 0)
->setDecorators(['ViewHelper']);
$this->addElement($output_sound_device);
$output_sound_device_type = new Zend_Form_Element_Select('output_sound_device_type');
$output_sound_device_type->setLabel(_('Output Type'))
->setMultiOptions([
'ALSA' => _('ALSA'),
'AO' => _('AO'),
'OSS' => _('OSS'),
'Portaudio' => _('Portaudio'),
'Pulseaudio' => _('Pulseaudio'),
'Jack' => _('Jack'),
])
$output_sound_device_type
->setLabel(_('Output Type'))
->setAttrib('readonly', true)
->setValue(isset($setting['output_sound_device_type']) ? $setting['output_sound_device_type'] : 0)
->setDecorators(['ViewHelper']);
$this->addElement($output_sound_device_type);
$icecast_vorbis_metadata = new Zend_Form_Element_Checkbox('icecast_vorbis_metadata');
$icecast_vorbis_metadata->setLabel(_('Icecast Vorbis Metadata'))
->setRequired(false)
->setValue(($setting['icecast_vorbis_metadata'] == 'true') ? 1 : 0)
->setDecorators(['ViewHelper']);
if (Application_Model_Preference::GetEnableStreamConf() == 'false') {
$icecast_vorbis_metadata->setAttrib('readonly', true);
}
$this->addElement($icecast_vorbis_metadata);
$stream_format = new Zend_Form_Element_Radio('streamFormat');
$stream_format->setLabel(_('Stream Label:'));
$stream_format->setMultiOptions([
_('Artist - Title'),
_('Show - Artist - Title'),
_('Station name - Show name'),
]);
$stream_format->setValue(Application_Model_Preference::GetStreamLabelFormat());
$stream_format->setDecorators(['ViewHelper']);
$this->addElement($stream_format);
$offAirMeta = new Zend_Form_Element_Text('offAirMeta');
$offAirMeta->setLabel(_('Off Air Metadata'))
->setValue(Application_Model_Preference::getOffAirMeta())
->setDecorators(['ViewHelper']);
$this->addElement($offAirMeta);
$enable_replay_gain = new Zend_Form_Element_Checkbox('enableReplayGain');
$enable_replay_gain->setLabel(_('Enable Replay Gain'))
->setValue(Application_Model_Preference::GetEnableReplayGain())
->setDecorators(['ViewHelper']);
$this->addElement($enable_replay_gain);
$replay_gain = new Zend_Form_Element_Hidden('replayGainModifier');
$replay_gain->setLabel(_('Replay Gain Modifier'))
->setValue(Application_Model_Preference::getReplayGainModifier())
->setAttribs(['style' => 'border: 0; color: #f6931f; font-weight: bold;'])
->setDecorators(['ViewHelper']);
$this->addElement($replay_gain);
$custom = Application_Model_Preference::getUsingCustomStreamSettings();
$customSettings = new Zend_Form_Element_Radio('customStreamSettings');
$customSettings->setLabel(_('Streaming Server:'));
$customSettings->setMultiOptions([_('Default Streaming'), _('Custom / 3rd Party Streaming')]);
$customSettings->setValue(!empty($custom) ? $custom : 0);
$this->addElement($customSettings);
}
public function isValid($data)
{
if (isset($data['output_sound_device'])) {
$d = [];
$d['output_sound_device'] = $data['output_sound_device'];
$d['icecast_vorbis_metadata'] = $data['icecast_vorbis_metadata'];
if (isset($data['output_sound_device_type'])) {
$d['output_sound_device_type'] = $data['output_sound_device_type'];
}
$d['streamFormat'] = $data['streamFormat'];
$this->populate($d);
}
return parent::isValid($data);
}
}

View File

@ -4,8 +4,6 @@ class Application_Form_StreamSettingSubForm extends Zend_Form_SubForm
{
private $prefix;
private $setting;
private $stream_types;
private $stream_bitrates;
public static $customizable;
@ -23,171 +21,127 @@ class Application_Form_StreamSettingSubForm extends Zend_Form_SubForm
$this->setting = $setting;
}
public function setStreamTypes($stream_types)
{
$this->stream_types = $stream_types;
}
public function setStreamBitrates($stream_bitrates)
{
$this->stream_bitrates = $stream_bitrates;
}
public function startForm()
{
$prefix = 's' . $this->prefix;
$stream_number = $this->prefix;
$setting = $this->setting;
$stream_types = $this->stream_types;
$stream_bitrates = $this->stream_bitrates;
$streamDefaults = Application_Model_StreamSetting::getDefaults($prefix);
// If we're not using custom stream settings, use the defaults
$useDefaults = !Application_Model_Preference::getUsingCustomStreamSettings();
$this->setIsArray(true);
$this->setElementsBelongTo($prefix . '_data');
$enable = new Zend_Form_Element_Checkbox('enable');
$enable->setLabel(_('Enabled:'))
$enable
->setLabel(_('Enabled:'))
->setAttrib('disabled', true)
->setValue($setting[$prefix . '_enable'] == 'true' ? 1 : 0)
->setDecorators(['ViewHelper']);
$this->addElement($enable);
static::$customizable[] = $enable->getName();
$mobile = new Zend_Form_Element_Checkbox('mobile');
$mobile->setLabel(_('Mobile:'));
$mobile->setValue($setting[$prefix . '_mobile']);
$mobile->setDecorators(['ViewHelper']);
$mobile
->setLabel(_('Mobile:'))
->setAttrib('disabled', true)
->setValue($setting[$prefix . '_mobile'])
->setDecorators(['ViewHelper']);
$this->addElement($mobile);
static::$customizable[] = $mobile->getName();
$type = new Zend_Form_Element_Select('type');
$type->setLabel(_('Stream Type:'))
->setMultiOptions($stream_types)
$type = new Zend_Form_Element_Text('type');
$type
->setLabel(_('Stream Type:'))
->setAttrib('readonly', true)
->setValue(isset($setting[$prefix . '_type']) ? $setting[$prefix . '_type'] : 0)
->setDecorators(['ViewHelper']);
$this->addElement($type);
static::$customizable[] = $type->getName();
$bitrate = new Zend_Form_Element_Select('bitrate');
$bitrate->setLabel(_('Bit Rate:'))
->setMultiOptions($stream_bitrates)
$bitrate = new Zend_Form_Element_Text('bitrate');
$bitrate
->setLabel(_('Bit Rate:'))
->setAttrib('readonly', true)
->setValue(isset($setting[$prefix . '_bitrate']) ? $setting[$prefix . '_bitrate'] : 0)
->setDecorators(['ViewHelper']);
$this->addElement($bitrate);
static::$customizable[] = $bitrate->getName();
$output = new Zend_Form_Element_Select('output');
$output->setLabel(_('Service Type:'))
->setMultiOptions(['icecast' => 'Icecast', 'shoutcast' => 'SHOUTcast'])
->setValue($useDefaults ? $streamDefaults['output'] : (isset($setting[$prefix . '_output']) ? $setting[$prefix . '_output'] : 'icecast'))
$output = new Zend_Form_Element_Text('output');
$output
->setLabel(_('Service Type:'))
->setAttrib('readonly', true)
->setValue((isset($setting[$prefix . '_output']) ? $setting[$prefix . '_output'] : 'icecast'))
->setDecorators(['ViewHelper']);
$this->addElement($output);
$channels = new Zend_Form_Element_Select('channels');
$channels->setLabel(_('Channels:'))
->setMultiOptions(['mono' => _('1 - Mono'), 'stereo' => _('2 - Stereo')])
$channels = new Zend_Form_Element_Text('channels');
$channels
->setLabel(_('Channels:'))
->setAttrib('readonly', true)
->setValue(isset($setting[$prefix . '_channels']) ? $setting[$prefix . '_channels'] : 'stereo')
->setDecorators(['ViewHelper']);
$this->addElement($channels);
static::$customizable[] = $channels->getName();
$host = new Zend_Form_Element_Text('host');
$host->setLabel(_('Server'))
->setValue($useDefaults ? $streamDefaults['host'] : (isset($setting[$prefix . '_host']) ? $setting[$prefix . '_host'] : ''))
->setValidators([
['regex', false, ['/^[0-9a-zA-Z-_.]+$/', 'messages' => _('Invalid character entered')]],
])
$host
->setLabel(_('Server'))
->setAttrib('readonly', true)
->setValue((isset($setting[$prefix . '_host']) ? $setting[$prefix . '_host'] : ''))
->setDecorators(['ViewHelper']);
$host->setAttrib('alt', 'domain');
$this->addElement($host);
$port = new Zend_Form_Element_Text('port');
$port->setLabel(_('Port'))
->setValue($useDefaults ? $streamDefaults['port'] : (isset($setting[$prefix . '_port']) ? $setting[$prefix . '_port'] : ''))
->setValidators([new Zend_Validate_Between(['min' => 0, 'max' => 99999])])
->addValidator('regex', false, ['pattern' => '/^[0-9]+$/', 'messages' => ['regexNotMatch' => _('Only numbers are allowed.')]])
$port
->setLabel(_('Port'))
->setAttrib('readonly', true)
->setValue((isset($setting[$prefix . '_port']) ? $setting[$prefix . '_port'] : ''))
->setDecorators(['ViewHelper']);
$this->addElement($port);
$pass = new Zend_Form_Element_Text('pass');
$pass->setLabel(_('Password'))
->setValue($useDefaults ? $streamDefaults['pass'] : (isset($setting[$prefix . '_pass']) ? $setting[$prefix . '_pass'] : ''))
->setValidators([
['regex', false, ['/^[^ &<>]+$/', 'messages' => _('Invalid character entered')]],
])
$mount = new Zend_Form_Element_Text('mount');
$mount
->setLabel(_('Mount Point'))
->setAttrib('readonly', true)
->setValue((isset($setting[$prefix . '_mount']) ? $setting[$prefix . '_mount'] : ''))
->setDecorators(['ViewHelper']);
$pass->setAttrib('alt', 'regular_text');
$this->addElement($pass);
$mount->setAttrib('alt', 'regular_text');
$this->addElement($mount);
$name = new Zend_Form_Element_Text('name');
$name
->setLabel(_('Name'))
->setAttrib('readonly', true)
->setValue(isset($setting[$prefix . '_name']) ? $setting[$prefix . '_name'] : '')
->setDecorators(['ViewHelper']);
$this->addElement($name);
$genre = new Zend_Form_Element_Text('genre');
$genre->setLabel(_('Genre'))
$genre
->setAttrib('readonly', true)
->setLabel(_('Genre'))
->setValue(isset($setting[$prefix . '_genre']) ? $setting[$prefix . '_genre'] : '')
->setDecorators(['ViewHelper']);
$this->addElement($genre);
$url = new Zend_Form_Element_Text('url');
$url->setLabel(_('URL'))
$url
->setLabel(_('URL'))
->setAttrib('readonly', true)
->setValue(isset($setting[$prefix . '_url']) ? $setting[$prefix . '_url'] : '')
->setValidators([
['regex', false, ['/^[0-9a-zA-Z\-_.:\/]+$/', 'messages' => _('Invalid character entered')]],
])
->setDecorators(['ViewHelper']);
$url->setAttrib('alt', 'url');
$this->addElement($url);
$name = new Zend_Form_Element_Text('name');
$name->setLabel(_('Name'))
->setValue(isset($setting[$prefix . '_name']) ? $setting[$prefix . '_name'] : '')
->setDecorators(['ViewHelper']);
$this->addElement($name);
$description = new Zend_Form_Element_Text('description');
$description->setLabel(_('Description'))
$description
->setLabel(_('Description'))
->setAttrib('readonly', true)
->setValue(isset($setting[$prefix . '_description']) ? $setting[$prefix . '_description'] : '')
->setDecorators(['ViewHelper']);
$this->addElement($description);
$mount = new Zend_Form_Element_Text('mount');
$mount->setLabel(_('Mount Point'))
->setValue($useDefaults ? $streamDefaults['mount'] : (isset($setting[$prefix . '_mount']) ? $setting[$prefix . '_mount'] : ''))
->setValidators([
['regex', false, ['/^[^ &<>]+$/', 'messages' => _('Invalid character entered')]],
])
->setDecorators(['ViewHelper']);
$mount->setAttrib('alt', 'regular_text');
$this->addElement($mount);
$user = new Zend_Form_Element_Text('user');
$user->setLabel(_('Username'))
->setValue($useDefaults ? $streamDefaults['user'] : (isset($setting[$prefix . '_user']) ? $setting[$prefix . '_user'] : ''))
->setValidators([
['regex', false, ['/^[^ &<>]+$/', 'messages' => _('Invalid character entered')]],
])
->setDecorators(['ViewHelper']);
$user->setAttrib('alt', 'regular_text');
$this->addElement($user);
$adminUser = new Zend_Form_Element_Text('admin_user');
$adminUser->setLabel(_('Admin User'))
->setValue(Application_Model_StreamSetting::getAdminUser($prefix))
->setValidators([
['regex', false, ['/^[^ &<>]+$/', 'messages' => _('Invalid character entered')]],
])
->setDecorators(['ViewHelper']);
$adminUser->setAttrib('alt', 'regular_text');
$this->addElement($adminUser);
$adminPass = new Zend_Form_Element_Password('admin_pass');
$adminPass->setLabel(_('Admin Password'))
->setValue(Application_Model_StreamSetting::getAdminPass($prefix))
->setValidators([
['regex', false, ['/^[^ &<>]+$/', 'messages' => _('Invalid character entered')]],
])
->setDecorators(['ViewHelper']);
$adminPass->setAttrib('alt', 'regular_text');
$this->addElement($adminPass);
$public_url = new Zend_Form_Element_Text('public_url');
$public_url
->setLabel(_('Stream URL'))
->setValue($setting[$prefix . '_public_url'] ?? '');
$this->addElement($public_url);
$liquidsoap_error_msg = '<div class="stream-status status-info"><p>' . _('Getting information from the server...') . '</p></div>';
@ -200,48 +154,4 @@ class Application_Form_StreamSettingSubForm extends Zend_Form_SubForm
]],
]);
}
public function isValid($data)
{
$f_data = $data['s' . $this->prefix . '_data'];
$isValid = parent::isValid($f_data);
// XXX: A couple of ugly workarounds here, but I guess that's what you get when you
// combine an already-complex POST and GET into a single action...
if (Application_Model_Preference::getUsingCustomStreamSettings() && $f_data) {
if ($f_data['enable'] == 1 && isset($f_data['host'])) {
if ($f_data['host'] == '') {
$element = $this->getElement('host');
$element->addError(_('Server cannot be empty.'));
$isValid = false;
}
if ($f_data['port'] == '') {
$element = $this->getElement('port');
$element->addError(_('Port cannot be empty.'));
$isValid = false;
}
if ($f_data['output'] == 'icecast') {
if ($f_data['mount'] == '') {
$element = $this->getElement('mount');
$element->addError(_('Mount cannot be empty with Icecast server.'));
$isValid = false;
}
}
}
}
return $isValid;
}
public function toggleState()
{
$elements = $this->getElements();
foreach ($elements as $element) {
if (Application_Model_Preference::getUsingCustomStreamSettings()) {
$element->setAttrib('disabled', null);
} elseif (!(in_array($element->getName(), static::$customizable)
|| $element->getType() == 'Zend_Form_Element_Hidden')) {
$element->setAttrib('disabled', 'disabled');
}
}
}
}

View File

@ -58,29 +58,6 @@ SQL;
}
return $out;
$enabledStreamIds = Application_Model_StreamSetting::getEnabledStreamIds();
$enabledOut = [];
foreach ($enabledStreamIds as $sId) {
$sql = 'SELECT value FROM cc_stream_setting'
. ' WHERE keyname = :key';
$result = Application_Common_Database::prepareAndExecute($sql, ['key' => $sId . '_mount'], 'single');
$enabledMountPoint = $result['value'];
if (isset($out[$enabledMountPoint])) {
$enabledOut[$enabledMountPoint] = $out[$enabledMountPoint];
} else {
// TODO fix this hack (here for CC-5254)
// all shoutcast streams are automatically put under "shoutcast" mount point.
if (isset($out['shoutcast'])) {
$enabledOut['shoutcast'] = $out['shoutcast'];
}
}
}
return $enabledOut;
}
// this will currently log the average number of listeners to a specific show during a certain range

View File

@ -795,20 +795,6 @@ class Application_Model_Preference
return (int) self::getValue('import_timestamp');
}
public static function GetStreamType()
{
$st = self::getValue('stream_type');
return explode(',', $st);
}
public static function GetStreamBitrate()
{
$sb = self::getValue('stream_bitrate');
return explode(',', $sb);
}
public static function SetPrivacyPolicyCheck($flag)
{
self::setValue('privacy_policy', $flag);
@ -819,36 +805,9 @@ class Application_Model_Preference
return self::getValue('privacy_policy');
}
public static function SetNumOfStreams($num)
{
self::setValue('num_of_streams', intval($num));
// Enable or disable each stream according to whatever was just changed.
for ($streamIdx = 1; $streamIdx <= MAX_NUM_STREAMS; ++$streamIdx) {
$prefix = 's' . $streamIdx . '_';
$enable = 'false';
if ($streamIdx <= intval($num)) {
$enable = 'true';
}
// Enable or disable the stream in the Stream Settings DB table.
Application_Model_StreamSetting::setIndividualStreamSetting([$prefix . 'enable' => $enable]);
}
}
public static function GetNumOfStreams()
{
return self::getValue('num_of_streams');
}
public static function SetMaxBitrate($bitrate)
{
self::setValue('max_bitrate', intval($bitrate));
}
public static function GetMaxBitrate()
{
return self::getValue('max_bitrate');
return count(Config::get('stream.outputs.merged'));
}
public static function SetEnableStreamConf($bool)
@ -1128,58 +1087,32 @@ class Application_Model_Preference
return ($value == null || $value == 'off') ? 'off' : 'on';
}
public static function SetMasterDJSourceConnectionURL($value)
{
self::setValue('master_dj_source_connection_url', $value, false);
}
public static function GetMasterDJSourceConnectionURL()
{
$master_connection_url = self::getValue('master_dj_source_connection_url');
if ($master_connection_url == '') {
$master_connection_url = 'http://' . $_SERVER['SERVER_NAME'] . ':' . Application_Model_StreamSetting::getMasterLiveStreamPort() . Application_Model_StreamSetting::getMasterLiveStreamMountPoint();
if (Config::has('stream.inputs.main.public_url') && Config::get('stream.inputs.main.public_url')) {
return Config::get('stream.inputs.main.public_url');
}
return $master_connection_url;
}
$host = Config::get('general.public_url_raw')->getHost();
$port = Application_Model_StreamSetting::getMasterLiveStreamPort();
$mount = Application_Model_StreamSetting::getMasterLiveStreamMountPoint();
public static function SetLiveDJSourceConnectionURL($value)
{
self::setValue('live_dj_source_connection_url', $value, false);
return "http://{$host}:{$port}/{$mount}";
}
public static function GetLiveDJSourceConnectionURL()
{
$livedj_connection_url = self::getValue('live_dj_source_connection_url');
if ($livedj_connection_url == '') {
$livedj_connection_url = 'http://' . $_SERVER['SERVER_NAME'] . ':' . Application_Model_StreamSetting::getDjLiveStreamPort() . Application_Model_StreamSetting::getDjLiveStreamMountPoint();
if (Config::has('stream.inputs.show.public_url') && Config::get('stream.inputs.show.public_url')) {
return Config::get('stream.inputs.show.public_url');
}
return $livedj_connection_url;
}
$host = Config::get('general.public_url_raw')->getHost();
$port = Application_Model_StreamSetting::getDjLiveStreamPort();
$mount = Application_Model_StreamSetting::getDjLiveStreamMountPoint();
// Source Connection URL override status starts
public static function GetLiveDjConnectionUrlOverride()
{
return self::getValue('live_dj_connection_url_override');
return "http://{$host}:{$port}/{$mount}";
}
public static function SetLiveDjConnectionUrlOverride($value)
{
self::setValue('live_dj_connection_url_override', $value, false);
}
public static function GetMasterDjConnectionUrlOverride()
{
return self::getValue('master_dj_connection_url_override');
}
public static function SetMasterDjConnectionUrlOverride($value)
{
self::setValue('master_dj_connection_url_override', $value, false);
}
// Source Connection URL override status ends
public static function SetAutoTransition($value)
{
self::setValue('auto_transition', $value, false);
@ -1454,28 +1387,6 @@ class Application_Model_Preference
// SAAS-876 - Store the default Icecast password to restore when switching
// back to Airtime Pro streaming settings
public static function getDefaultIcecastPassword()
{
$val = self::getValue('default_icecast_password');
return empty($val) ? DEFAULT_ICECAST_PASS : $val;
}
public static function setDefaultIcecastPassword($value)
{
self::setValue('default_icecast_password', $value);
}
public static function getDefaultStreamMountPoint()
{
return self::getValue('default_stream_mount_point');
}
public static function setDefaultStreamMountPoint($value)
{
self::setValue('default_stream_mount_point', $value);
}
public static function getRadioPageDisplayLoginButton()
{
return self::getValue('radio_page_display_login_button');

View File

@ -2,72 +2,106 @@
define('MAX_NUM_STREAMS', 4);
class Application_Model_StreamConfig
{
private static function toOutputKey($id)
{
return 's' . ($id);
}
private static function toOutputId($key)
{
return intval(trim($key, 's'));
}
public static function getOutput($key, $add_prefix = false)
{
$id = self::toOutputId($key);
$config_id = $id - 1;
$prefix = $add_prefix ? "s{$id}_" : '';
if (!Config::has("stream.outputs.merged.{$config_id}")) {
$result = [
$prefix . 'enable' => 'false',
$prefix . 'public_url' => '',
$prefix . 'output' => 'icecast',
$prefix . 'host' => 'localhost',
$prefix . 'port' => 8000,
$prefix . 'mount' => '',
$prefix . 'user' => 'source',
$prefix . 'pass' => '',
$prefix . 'admin_user' => 'admin',
$prefix . 'admin_pass' => '',
$prefix . 'channels' => 'stereo',
$prefix . 'bitrate' => 128,
$prefix . 'type' => '',
$prefix . 'name' => '',
$prefix . 'description' => '',
$prefix . 'genre' => '',
$prefix . 'url' => '',
$prefix . 'mobile' => 'false',
];
} else {
$output = Config::get("stream.outputs.merged.{$config_id}");
$result = [
$prefix . 'enable' => $output['enabled'] ?? 'false',
$prefix . 'output' => $output['kind'] ?? 'icecast',
$prefix . 'public_url' => $output['public_url'] ?? '',
$prefix . 'host' => $output['host'] ?? 'localhost',
$prefix . 'port' => $output['port'] ?? 8000,
$prefix . 'mount' => $output['mount'] ?? '',
$prefix . 'user' => $output['source_user'] ?? 'source',
$prefix . 'pass' => $output['source_password'] ?? '',
$prefix . 'admin_user' => $output['admin_user'] ?? 'admin',
$prefix . 'admin_pass' => $output['admin_password'] ?? '',
$prefix . 'channels' => $output['audio']['channels'] ?? 'stereo',
$prefix . 'bitrate' => $output['audio']['bitrate'] ?? 128,
$prefix . 'type' => $output['audio']['format'],
$prefix . 'name' => $output['name'] ?? '',
$prefix . 'description' => $output['description'] ?? '',
$prefix . 'genre' => $output['genre'] ?? '',
$prefix . 'url' => $output['website'] ?? '',
$prefix . 'mobile' => 'false',
// $prefix . 'liquidsoap_error' => 'waiting',
];
}
if (!$result[$prefix . 'public_url']) {
$host = $result[$prefix . 'host'];
if ($host == 'localhost') {
$host = Config::get('general.public_url_raw')->getHost();
}
$port = $result[$prefix . 'port'];
$mount = $result[$prefix . 'mount'];
$result[$prefix . 'public_url'] = "http://{$host}:{$port}/{$mount}";
if ($result[$prefix . 'output'] == 'shoutcast') {
// The semi-colon is important to make Shoutcast stream URLs play instead turn into a page.
$result[$prefix . 'public_url'] .= ';';
}
}
return $result;
}
public static function getOutputEnabledKeys()
{
$keys = [];
foreach (Config::get('stream.outputs.merged') as $id => $output) {
if ($output['enabled'] ?? false) {
$keys[] = self::toOutputKey($id + 1);
}
}
return $keys;
}
}
class Application_Model_StreamSetting
{
public static function setValue($key, $value, $type)
{
$con = Propel::getConnection();
// Check if key already exists
$sql = 'SELECT COUNT(*) FROM cc_stream_setting'
. ' WHERE keyname = :key';
$stmt = $con->prepare($sql);
$stmt->bindParam(':key', $key);
if ($stmt->execute()) {
$result = $stmt->fetchColumn(0);
} else {
$msg = implode(',', $stmt->errorInfo());
throw new Exception("Error: {$msg}");
}
if ($result == 1) {
$sql = 'UPDATE cc_stream_setting'
. ' SET value = :value, type = :type'
. ' WHERE keyname = :key';
} else {
$sql = 'INSERT INTO cc_stream_setting (keyname, value, type)'
. ' VALUES (:key, :value, :type)';
}
$stmt = $con->prepare($sql);
$stmt->bindParam(':key', $key);
$stmt->bindParam(':value', $value);
$stmt->bindParam(':type', $type);
if ($stmt->execute()) {
// do nothing
} else {
$msg = implode(',', $stmt->errorInfo());
throw new Exception("Error: {$msg}");
}
}
public static function getValue($key, $default = '')
{
$con = Propel::getConnection();
// Check if key already exists
$sql = 'SELECT value FROM cc_stream_setting'
. ' WHERE keyname = :key';
$stmt = $con->prepare($sql);
$stmt->bindParam(':key', $key);
if ($stmt->execute()) {
$result = $stmt->fetchColumn(0);
} else {
$msg = implode(',', $stmt->errorInfo());
throw new Exception("Error: {$msg}");
}
return $result ? $result : $default;
}
public static function getEnabledStreamData()
{
$streams = [];
@ -75,16 +109,8 @@ class Application_Model_StreamSetting
foreach ($streamIds as $id) {
$streamData = self::getStreamData($id);
$prefix = $id . '_';
$host = $streamData[$prefix . 'host'];
$port = $streamData[$prefix . 'port'];
$mount = $streamData[$prefix . 'mount'];
if ($streamData[$prefix . 'output'] == 'shoutcast') {
$url = "http://{$host}:{$port}/;"; // The semi-colon is important to make Shoutcast stream URLs play instead turn into a page.
} else { // Icecast
$url = "http://{$host}:{$port}/{$mount}";
}
$streams[$id] = [
'url' => $url,
'url' => $streamData[$prefix . 'public_url'],
'codec' => $streamData[$prefix . 'type'],
'bitrate' => $streamData[$prefix . 'bitrate'],
'mobile' => $streamData[$prefix . 'mobile'],
@ -98,102 +124,21 @@ class Application_Model_StreamSetting
* example of the array returned in JSON notation is ["s1", "s2", "s3"] */
public static function getEnabledStreamIds()
{
$con = Propel::getConnection();
$sql = 'SELECT * '
. 'FROM cc_stream_setting '
. "WHERE keyname LIKE '%_enable' "
. "AND value='true'";
$ids = [];
$rows = Application_Common_Database::prepareAndExecute($sql, [], 'all');
foreach ($rows as $row) {
$ids[] = substr($row['keyname'], 0, strpos($row['keyname'], '_'));
}
return $ids;
return Application_Model_StreamConfig::getOutputEnabledKeys();
}
/* Returns all information related to a specific stream. An example
* of a stream id is 's1' or 's2'. */
public static function getStreamData($p_streamId)
{
$rows = CcStreamSettingQuery::create()
->filterByDbKeyName("{$p_streamId}_%")
->find();
// This is way too much code because someone made only stupid decisions about how
// the layout of this table worked. The git history doesn't lie.
$data = [];
foreach ($rows as $row) {
$key = $row->getDbKeyName();
$value = $row->getDbValue();
$type = $row->getDbType();
// Fix stupid defaults so we end up with proper typing in our JSON
if ($row->getDbType() == 'boolean') {
if (empty($value)) {
// In Python, there is no way to tell the difference between ints and booleans,
// which we need to differentiate between for when we're generating the Liquidsoap
// config file. Returning booleans as a string is a workaround that lets us do that.
$value = 'false';
}
$data[$key] = $value;
} elseif ($row->getDbType() == 'integer') {
if (empty($value)) {
$value = 0;
}
$data[$key] = intval($value);
} else {
$data[$key] = $value;
}
}
// Add in defaults in case they don't exist in the database.
$keyPrefix = $p_streamId . '_';
self::ensureKeyExists($keyPrefix . 'admin_pass', $data);
self::ensureKeyExists($keyPrefix . 'admin_user', $data);
self::ensureKeyExists($keyPrefix . 'bitrate', $data, 128);
self::ensureKeyExists($keyPrefix . 'channels', $data, 'stereo');
self::ensureKeyExists($keyPrefix . 'description', $data);
self::ensureKeyExists($keyPrefix . 'enable', $data, 'false');
self::ensureKeyExists($keyPrefix . 'genre', $data);
self::ensureKeyExists($keyPrefix . 'host', $data);
self::ensureKeyExists($keyPrefix . 'liquidsoap_error', $data, 'waiting');
self::ensureKeyExists($keyPrefix . 'mount', $data);
self::ensureKeyExists($keyPrefix . 'name', $data);
self::ensureKeyExists($keyPrefix . 'output', $data);
self::ensureKeyExists($keyPrefix . 'pass', $data);
self::ensureKeyExists($keyPrefix . 'port', $data, 8000);
self::ensureKeyExists($keyPrefix . 'type', $data);
self::ensureKeyExists($keyPrefix . 'url', $data);
self::ensureKeyExists($keyPrefix . 'user', $data);
self::ensureKeyExists($keyPrefix . 'mobile', $data);
return $data;
return Application_Model_StreamConfig::getOutput($p_streamId, true);
}
/* Similar to getStreamData, but removes all sX prefixes to
* make data easier to iterate over */
public static function getStreamDataNormalized($p_streamId)
{
$settings = self::getStreamData($p_streamId);
foreach ($settings as $key => $value) {
unset($settings[$key]);
$newKey = substr($key, strlen($p_streamId) + 1); // $p_streamId is assumed to be the key prefix.
$settings[$newKey] = $value;
}
return $settings;
}
private static function ensureKeyExists($key, &$array, $default = '')
{
if (!array_key_exists($key, $array)) {
$array[$key] = $default;
}
return $array;
return Application_Model_StreamConfig::getOutput($p_streamId, false);
}
public static function getStreamSetting()
@ -215,125 +160,9 @@ class Application_Model_StreamSetting
return $settings;
}
private static function saveStreamSetting($key, $value)
{
$stream_setting = CcStreamSettingQuery::create()->filterByDbKeyName($key)->findOne();
if (is_null($stream_setting)) {
// throw new Exception("Keyname $key does not exist!");
$stream_setting = new CcStreamSetting();
$stream_setting->setDbKeyName($key);
$stream_setting->setDbType('');
}
$stream_setting->setDbValue($value);
$stream_setting->save();
}
/*
* function that take all the information of stream and sets them.
* This is used by stream setting via UI.
*
* @param $data - array that contains all the data. $data is [][] which
* contains multiple stream information
*/
public static function setStreamSetting($data)
{
foreach ($data as $key => $d) {
if ($key == 'output_sound_device' || $key == 'icecast_vorbis_metadata') {
$v = ($d == 1) ? 'true' : 'false';
self::saveStreamSetting($key, $v);
} elseif ($key == 'output_sound_device_type') {
self::saveStreamSetting($key, $d);
} elseif (is_array($d)) {
$temp = explode('_', $key);
$prefix = $temp[0];
// SAAS-876 - If we're using Airtime Pro streaming, set the stream to use the default settings
if (!Application_Model_Preference::getUsingCustomStreamSettings()) {
$d = array_merge($d, static::getDefaults($prefix));
}
foreach ($d as $k => $v) {
$keyname = $prefix . '_' . $k;
if ($k == 'enable') {
$v = $d['enable'] == 1 ? 'true' : 'false';
}
$v = trim($v);
if ($k != 'admin_pass') {
self::saveStreamSetting($keyname, $v);
} elseif ($v != 'xxxxxx') {
// We use 'xxxxxx' as the admin password placeholder so we
// only want to save it when it is a different string
self::saveStreamSetting($keyname, $v);
}
}
}
}
}
/**
* SAAS-876 - Get the default stream settings values for Airtime Pro streaming.
*
* @param int $prefix
*
* @return array array of default stream setting values
*/
public static function getDefaults($prefix)
{
$config = Config::getConfig();
return [
'host' => $config['public_url_raw']->getHost(),
'port' => DEFAULT_ICECAST_PORT,
'output' => 'icecast',
'user' => $config['stationId'],
'pass' => Application_Model_Preference::getDefaultIcecastPassword(),
// Manually setting default mountpoint
'mount' => Application_Model_Preference::getDefaultStreamMountpoint(),
];
}
/*
* Sets individual stream setting.
*
* $data - data array. $data is [].
* TODO: Make this SQL a prepared statement!
*
* Do not remove this function. It is called by airtime-system.php
*/
public static function setIndividualStreamSetting($data)
{
foreach ($data as $keyname => $v) {
$sql = 'UPDATE cc_stream_setting SET value=:v WHERE keyname=:keyname';
$map = [':v' => $v, ':keyname' => $keyname];
$res = Application_Common_Database::prepareAndExecute(
$sql,
$map,
Application_Common_Database::EXECUTE
);
}
}
public static function getStreamEnabled($stream_id)
{
$con = Propel::getConnection();
$keyname = 's' . $stream_id . '_enable';
$sql = 'SELECT value FROM cc_stream_setting'
. ' WHERE keyname = :keyname';
$stmt = $con->prepare($sql);
$stmt->bindParam(':keyname', $keyname);
if ($stmt->execute()) {
$result = $stmt->fetchColumn(0);
} else {
$msg = implode(',', $stmt->errorInfo());
throw new Exception("Error: {$msg}");
}
return $result != 'false';
return in_array('s' . $stream_id, self::getEnabledStreamIds());
}
/*
@ -342,112 +171,66 @@ class Application_Model_StreamSetting
*/
public static function getStreamInfoForDataCollection()
{
$con = Propel::getConnection();
$result = [];
$stream_ids = self::getEnabledStreamIds();
$out = [];
$enabled_stream = self::getEnabledStreamIds();
foreach ($enabled_stream as $stream) {
$keys = ["{$stream}_output", "{$stream}_type", "{$stream}_bitrate", "{$stream}_host"];
$key_csv = implode(',', $keys);
$sql = 'SELECT keyname, value FROM cc_stream_setting'
. ' WHERE keyname IN (:key_csv)';
$stmt = $con->prepare($sql);
$stmt->bindParam(':key_csv', $key_csv);
if ($stmt->execute()) {
$rows = $stmt->fetchAll();
} else {
$msg = implode(',', $stmt->errorInfo());
throw new Exception("Error: {$msg}");
}
$info = [];
foreach ($rows as $r) {
$temp = explode('_', $r['keyname']);
$info[$temp[1]] = $r['value'];
$out[$stream] = $info;
}
foreach ($stream_ids as $stream_id) {
$stream = self::getStreamDataNormalized($stream_id);
$keys = array_flip(['output', 'type', 'bitrate', 'host']);
$result[$stream_id] = array_intersect_key($stream, $keys);
}
return $out;
}
public static function setMasterLiveStreamPort($value)
{
self::setValue('master_live_stream_port', $value, 'integer');
return $result;
}
public static function getMasterLiveStreamPort()
{
return self::getValue('master_live_stream_port', 8001);
}
public static function setMasterLiveStreamMountPoint($value)
{
self::setValue('master_live_stream_mp', $value, 'string');
return Config::get('stream.inputs.main.port') ?? 8001;
}
public static function getMasterLiveStreamMountPoint()
{
return self::getValue('master_live_stream_mp', '/master');
}
public static function setDjLiveStreamPort($value)
{
self::setValue('dj_live_stream_port', $value, 'integer');
return Config::get('stream.inputs.main.mount') ?? 'main';
}
public static function getDjLiveStreamPort()
{
return self::getValue('dj_live_stream_port', 8002);
}
public static function setDjLiveStreamMountPoint($value)
{
self::setValue('dj_live_stream_mp', $value, 'string');
return Config::get('stream.inputs.show.port') ?? 8002;
}
public static function getDjLiveStreamMountPoint()
{
return self::getValue('dj_live_stream_mp', '/show');
return Config::get('stream.inputs.show.mount') ?? 'show';
}
public static function getAdminUser($stream)
{
return self::getValue($stream . '_admin_user');
}
public static function setAdminUser($stream, $v)
{
self::setValue($stream . '_admin_user', $v, 'string');
return self::getStreamDataNormalized($stream)['admin_user'];
}
public static function getAdminPass($stream)
{
return self::getValue($stream . '_admin_pass');
}
public static function setAdminPass($stream, $v)
{
self::setValue($stream . '_admin_pass', $v, 'string');
return self::getStreamDataNormalized($stream)['admin_pass'];
}
public static function getIcecastVorbisMetadata()
{
return self::getValue('icecast_vorbis_metadata', '');
foreach (Config::get('stream.outputs.merged') as $output) {
if ($output['audio']['enable_metadata'] ?? false) {
return true;
}
}
return '';
}
public static function getOutputSoundDevice()
{
return self::getValue('output_sound_device', 'false');
return Config::get('stream.outputs.system.0.enabled') ?? 'false';
}
public static function getOutputSoundDeviceType()
{
return self::getValue('output_sound_device_type', '');
return Config::get('stream.outputs.system.0.kind') ?? '';
}
}

View File

@ -36,7 +36,7 @@
if (count($ids) > 0) {
$id = $ids[0];
$streamData = Application_Model_StreamSetting::getStreamData($id);
$url = "http://" . $streamData["${id}_host"] . ":" . $streamData["${id}_port"] . "/" . $streamData["${id}_mount"];
$url = $streamData["${id}_public_url"];
$type = $streamData["${id}_type"];
$serverType = $streamData["${id}_output"];
if ($type == "ogg")
@ -68,7 +68,7 @@
<?php
foreach ($ids as $id) {
$streamData = Application_Model_StreamSetting::getStreamData($id);
$url = "http://" . $streamData["${id}_host"] . ":" . $streamData["${id}_port"] . "/" . $streamData["${id}_mount"];
$url = $streamData["${id}_public_url"];
$type = $streamData["${id}_type"];
$serverType = $streamData["${id}_output"];
if ($type == "ogg")

View File

@ -15,13 +15,7 @@
<?php echo $this->element->getElement('master_username')->render() ?>
<span class="master_username_help_icon"></span>
<?php echo $this->element->getElement('master_password')->render() ?>
<span id="stream_url"><?php echo $this->element->getElement("master_source_host")->render() ?>
<a href=# id="connection_url_override" style="font-size: 12px;"><?php echo _("Override") ?></a>&nbsp;&nbsp;
<span class="override_help_icon"></span></br>
<div id="master_dj_connection_url_actions" style="display:none">&nbsp;&nbsp;
<a href=# id="ok" style="font-size: 12px;"><?php echo _("OK") ?></a>&nbsp;&nbsp;<a href=# id="reset" style="font-size: 12px;"><?php echo _("RESET"); ?></a>
</div>
</span>
<?php echo $this->element->getElement("master_source_host")->render() ?>
<?php echo $this->element->getElement("master_source_port")->render() ?>
<?php echo $this->element->getElement("master_source_mount")->render() ?>
</fieldset>
@ -31,15 +25,7 @@
<p class="input-settings-inline-p">
<?php echo _("DJs can use these settings in their broadcasting software to broadcast live only during shows assigned to them.") ?>
</p>
<span id="stream_url">
<?php echo $this->element->getElement("show_source_host")->render() ?>
<a href=# id="connection_url_override" style="font-size: 12px;"><?php echo _("Override") ?></a>&nbsp;&nbsp;
<span class="override_help_icon"></span>
</br>
<div id="live_dj_connection_url_actions" style="display:none; float:left">&nbsp;&nbsp;
<a href=# id="ok" style="font-size: 12px;"><?php echo _("OK") ?></a>&nbsp;&nbsp;<a href=# id="reset" style="font-size: 12px;"><?php echo _("RESET"); ?></a>
</div>
</span>
<?php echo $this->element->getElement("show_source_host")->render() ?>
<?php echo $this->element->getElement("show_source_port")->render() ?>
<?php echo $this->element->getElement("show_source_mount")->render() ?>
</fieldset>

View File

@ -15,27 +15,13 @@ $s_name = "s" . $this->stream_number;
<?php echo $this->element->getElement('enable') ?>
</dd>
<dt id="<?php echo $s_name ?>Mobile-label">
<label for="<?php echo $s_name ?>Mobile"><?php echo $this->element->getElement('mobile')->getLabel() ?></label>
<dt id="<?php echo $s_name ?>Output-label">
<label for="<?php echo $s_name ?>Output"><?php echo $this->element->getElement('output')->getLabel() ?></label>
</dt>
<dd id="<?php echo $s_name ?>Mobile-element">
<?php echo $this->element->getElement('mobile') ?>
<dd id="<?php echo $s_name ?>Output-element">
<?php echo $this->element->getElement('output') ?>
</dd>
<dt id="<?php echo $s_name ?>Type-label">
<label for="<?php echo $s_name ?>Type"><?php echo $this->element->getElement('type')->getLabel() ?></label>
</dt>
<dd id="<?php echo $s_name ?>Type-element">
<?php echo $this->element->getElement('type') ?>
<span class='stream_type_help_icon'></span>
</dd>
<dt id="<?php echo $s_name ?>Bitrate-label">
<label for="<?php echo $s_name ?>Bitrate"><?php echo $this->element->getElement('bitrate')->getLabel() ?></label>
</dt>
<dd id="<?php echo $s_name ?>Bitrate-element">
<?php echo $this->element->getElement('bitrate') ?>
</dd>
<dt id="outputServer-label">
<label for="outputServer"><?php echo $this->element->getElement('host')->getLabel() ?><span class="info-text-small">
<?php echo _("(Required)") ?></span> :</label>
@ -64,12 +50,6 @@ $s_name = "s" . $this->stream_number;
</ul>
<?php endif; ?>
</dd>
<dt id="<?php echo $s_name ?>Output-label">
<label for="<?php echo $s_name ?>Output"><?php echo $this->element->getElement('output')->getLabel() ?></label>
</dt>
<dd id="<?php echo $s_name ?>Output-element">
<?php echo $this->element->getElement('output') ?>
</dd>
<dt id="<?php echo $s_name ?>Channels-label">
<label for="<?php echo $s_name ?>Channels"><?php echo $this->element->getElement('channels')->getLabel() ?></label>
@ -78,144 +58,100 @@ $s_name = "s" . $this->stream_number;
<?php echo $this->element->getElement('channels') ?>
</dd>
<fieldset class="padded top-margin display_field toggle closed" id="output_setting">
<legend style="cursor: pointer;">
<span class="ui-icon ui-icon-triangle-2-n-s"></span>
<?php echo _("Additional Options") ?>
</legend>
<dl class="zend_form">
<dt id="outputUser-label">
<label for="outputUser"><?php echo $this->element->getElement('user')->getLabel() ?> :
<span class='stream_username_help_icon'></span>
</label>
</dt>
<dd id="outputUser-element">
<?php echo $this->element->getElement('user') ?>
<?php if ($this->element->getElement('user')->hasErrors()) : ?>
<ul class='errors'>
<?php foreach ($this->element->getElement('user')->getMessages() as $error) : ?>
<li><?php echo $error; ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</dd>
<dt id="outputPassword-label">
<label class="optional" for="outputPassword"><?php echo $this->element->getElement('pass')->getLabel() ?> :</label>
</dt>
<dd id="outputPassword-element" class="clearfix">
<?php echo $this->element->getElement('pass') ?>
<?php if ($this->element->getElement('pass')->hasErrors()) : ?>
<ul class='errors'>
<?php foreach ($this->element->getElement('pass')->getMessages() as $error) : ?>
<li><?php echo $error; ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</dd>
<dt id="adminUser-label">
<label for="outputUser"><?php echo $this->element->getElement('admin_user')->getLabel() ?> :
<span class='admin_username_help_icon'></span>
</label>
</dt>
<dd id="adminUser-element">
<?php echo $this->element->getElement('admin_user') ?>
<?php if ($this->element->getElement('admin_user')->hasErrors()) : ?>
<ul class='errors'>
<?php foreach ($this->element->getElement('admin_user')->getMessages() as $error) : ?>
<li><?php echo $error; ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</dd>
<dt id="adminPassword-label">
<label class="optional" for="outputPassword"><?php echo $this->element->getElement('admin_pass')->getLabel() ?> :</label>
</dt>
<dd id="adminPassword-element" class="clearfix">
<?php echo $this->element->getElement('admin_pass') ?>
<?php if ($this->element->getElement('admin_pass')->hasErrors()) : ?>
<ul class='errors'>
<?php foreach ($this->element->getElement('admin_pass')->getMessages() as $error) : ?>
<li><?php echo $error; ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</dd>
<dt class="block-display info-block">
<?php echo _("The following info will be displayed to listeners in their media player:") ?>
</dt>
<dt id="stationName-label">
<label for="stationName"><?php echo $this->element->getElement('name')->getLabel() ?> :</label>
</dt>
<dd id="stationName-element" class="clearfix">
<?php echo $this->element->getElement('name') ?>
<?php if ($this->element->getElement('name')->hasErrors()) : ?>
<ul class='errors'>
<?php foreach ($this->element->getElement('name')->getMessages() as $error) : ?>
<li><?php echo $error; ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</dd>
<dt id="stationDescription-label">
<label for="stationDescription"><?php echo $this->element->getElement('description')->getLabel() ?> :</label>
</dt>
<dd id="stationDescription-element" class="clearfix">
<?php echo $this->element->getElement('description') ?>
<?php if ($this->element->getElement('description')->hasErrors()) : ?>
<ul class='errors'>
<?php foreach ($this->element->getElement('description')->getMessages() as $error) : ?>
<li><?php echo $error; ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</dd>
<dt id="stationURL-label">
<label for="stationURL"><?php echo $this->element->getElement('url')->getLabel() ?> :</label>
</dt>
<dd id="stationURL-element" class="clearfix">
<?php echo $this->element->getElement('url') ?>
<span class="info-text-small"><?php echo _("(Your radio station website)") ?></span>
<?php if ($this->element->getElement('url')->hasErrors()) : ?>
<ul class='errors'>
<?php foreach ($this->element->getElement('url')->getMessages() as $error) : ?>
<li><?php echo $error; ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</dd>
<dt id="outputGenre-label">
<label for="outputGenre"><?php echo $this->element->getElement('genre')->getLabel() ?> :</label>
</dt>
<dd id="outputGenre-element">
<?php echo $this->element->getElement('genre') ?>
<?php if ($this->element->getElement('genre')->hasErrors()) : ?>
<ul class='errors'>
<?php foreach ($this->element->getElement('genre')->getMessages() as $error) : ?>
<li><?php echo $error; ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</dd>
<dt id="outputMountpoint-label">
<label for="outputMountpoint"><?php echo $this->element->getElement('mount')->getLabel() ?> :</label>
</dt>
<dd id="outputMountpoint-element">
<?php echo $this->element->getElement('mount') ?>
<?php if ($this->element->getElement('mount')->hasErrors()) : ?>
<ul class='errors'>
<?php foreach ($this->element->getElement('mount')->getMessages() as $error) : ?>
<li><?php echo $error; ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</dd>
</dl>
</fieldset>
<dt id="<?php echo $s_name ?>Type-label">
<label for="<?php echo $s_name ?>Type"><?php echo $this->element->getElement('type')->getLabel() ?></label>
</dt>
<dd id="<?php echo $s_name ?>Type-element">
<?php echo $this->element->getElement('type') ?>
<span class='stream_type_help_icon'></span>
</dd>
<dt id="<?php echo $s_name ?>Bitrate-label">
<label for="<?php echo $s_name ?>Bitrate"><?php echo $this->element->getElement('bitrate')->getLabel() ?></label>
</dt>
<dd id="<?php echo $s_name ?>Bitrate-element">
<?php echo $this->element->getElement('bitrate') ?>
</dd>
<dt id="stationName-label">
<label for="stationName"><?php echo $this->element->getElement('name')->getLabel() ?> :</label>
</dt>
<dd id="stationName-element" class="clearfix">
<?php echo $this->element->getElement('name') ?>
<?php if ($this->element->getElement('name')->hasErrors()) : ?>
<ul class='errors'>
<?php foreach ($this->element->getElement('name')->getMessages() as $error) : ?>
<li><?php echo $error; ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</dd>
<dt id="stationDescription-label">
<label for="stationDescription"><?php echo $this->element->getElement('description')->getLabel() ?> :</label>
</dt>
<dd id="stationDescription-element" class="clearfix">
<?php echo $this->element->getElement('description') ?>
<?php if ($this->element->getElement('description')->hasErrors()) : ?>
<ul class='errors'>
<?php foreach ($this->element->getElement('description')->getMessages() as $error) : ?>
<li><?php echo $error; ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</dd>
<dt id="stationURL-label">
<label for="stationURL"><?php echo $this->element->getElement('url')->getLabel() ?> :</label>
</dt>
<dd id="stationURL-element" class="clearfix">
<?php echo $this->element->getElement('url') ?>
<?php if ($this->element->getElement('url')->hasErrors()) : ?>
<ul class='errors'>
<?php foreach ($this->element->getElement('url')->getMessages() as $error) : ?>
<li><?php echo $error; ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</dd>
<dt id="outputGenre-label">
<label for="outputGenre"><?php echo $this->element->getElement('genre')->getLabel() ?> :</label>
</dt>
<dd id="outputGenre-element">
<?php echo $this->element->getElement('genre') ?>
<?php if ($this->element->getElement('genre')->hasErrors()) : ?>
<ul class='errors'>
<?php foreach ($this->element->getElement('genre')->getMessages() as $error) : ?>
<li><?php echo $error; ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</dd>
<dt id="outputMountpoint-label">
<label for="outputMountpoint"><?php echo $this->element->getElement('mount')->getLabel() ?> :</label>
</dt>
<dd id="outputMountpoint-element">
<?php echo $this->element->getElement('mount') ?>
<?php if ($this->element->getElement('mount')->hasErrors()) : ?>
<ul class='errors'>
<?php foreach ($this->element->getElement('mount')->getMessages() as $error) : ?>
<li><?php echo $error; ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</dd>
<dt id="<?php echo $s_name ?>Mobile-label">
<label for="<?php echo $s_name ?>Mobile"><?php echo $this->element->getElement('mobile')->getLabel() ?></label>
</dt>
<dd id="<?php echo $s_name ?>Mobile-element">
<?php echo $this->element->getElement('mobile') ?>
</dd>
<dt id="outputStreamURL-label">
<label for="outputStreamURL"><?php echo _("Stream URL: "); ?></label>
<label for="outputStreamURL"><?php echo $this->element->getElement('public_url')->getLabel() ?> :</label>
</dt>
<dd id="outputStreamURL-element">
<span id="stream_url" class="static_text"></span>
<a href="<?php echo $this->element->getElement('public_url')->getValue() ?>" target="_blank" rel="noopener noreferrer">
<?php echo $this->element->getElement('public_url')->getValue() ?>
</a>
</dd>
</dl>
</fieldset>

View File

@ -11,39 +11,11 @@
<h3><?php echo _("Global") ?></h3>
<fieldset class="padded stream-setting-global">
<dl class="zend_form">
<?php if ($this->form->getElement('output_sound_device') != null) { ?>
<dt id="hardwareOut-label">
<label class="required">
<?php echo $this->form->getElement('output_sound_device')->getLabel() ?> :
</label>
</dt>
<dd id="hardwareOut-element">
<?php echo $this->form->getElement('output_sound_device') ?>
</dd>
<dt id="hardwareOutType-label">
<label class="required">
<?php echo $this->form->getElement('output_sound_device_type')->getLabel() ?> :
</label>
</dt>
<dd id="hardwareOutType-element">
<?php echo $this->form->getElement('output_sound_device_type') ?>
</dd>
<?php } ?>
<dt id="vorbisMetadata-label">
<label class="required">
<?php echo $this->form->getElement('icecast_vorbis_metadata')->getLabel() ?> :
<span class='icecast_metadata_help_icon'></span>
</label>
</dt>
<dd id="vorbisMetadata-element">
<?php echo $this->form->getElement('icecast_vorbis_metadata') ?>
</dd>
<dt id="streamFormat-label">
<label class="optional"><?php echo $this->form->getElement('streamFormat')->getLabel() ?></label>
</dt>
<br>
<dd id="streamFormat-element" class="radio-inline-list">
<dd id="streamFormat-element" class="radio-list">
<?php $i = 0;
$value = $this->form->getElement('streamFormat')->getValue();
?>
@ -52,7 +24,7 @@
<input type="radio" value="<?php echo $i ?>" id="streamFormat-<?php echo $i ?>" name="streamFormat" <?php if ($i == $value) {
echo 'checked="checked"';
} ?>>
<?php echo $radio ?> <br><br>
<?php echo $radio ?><br><br>
</input>
</label>
<?php $i = $i + 1; ?>
@ -65,6 +37,7 @@
</ul>
<?php endif; ?>
</dd>
<dt id="offAirMeta-label">
<label>
<?php echo $this->form->getElement('offAirMeta')->getLabel() ?> :
@ -73,6 +46,7 @@
<dd id="offAirMeta-element">
<?php echo $this->form->getElement('offAirMeta') ?>
</dd>
<dt id="enableReplayGain-label">
<label>
<?php echo $this->form->getElement('enableReplayGain')->getLabel() ?> :
@ -108,8 +82,6 @@
<h3><?php echo _("Output Streams") ?></h3>
<fieldset class="padded">
<?php
// TODO: replace this with something that looks good
echo $this->form->getElement('customStreamSettings')->render();
for ($i = 1; $i <= $this->num_stream; $i++) {
echo $this->form->getSubform("s" . $i . "_subform");
}

View File

@ -10,27 +10,6 @@ function showErrorSections() {
}
});
}
function rebuildStreamURL(ele) {
var div = ele.closest("div");
host = div.find("input[id$=-host]").val();
port = div.find("input[id$=-port]").val();
mount = div.find("input[id$=-mount]").val();
streamurl = "";
if (div.find("select[id$=-output]").val() == "icecast") {
streamurl = "http://" + host;
if ($.trim(port) != "") {
streamurl += ":" + port;
}
if ($.trim(mount) != "") {
streamurl += "/" + mount;
}
} else {
streamurl = "http://" + host + ":" + port + "/";
}
div
.find("#stream_url")
.html('<a href="' + streamurl + '" target="_blank">' + streamurl + "</a>");
}
function restrictOggBitrate(ele, on) {
var div = ele.closest("div");
if (on) {
@ -156,116 +135,7 @@ function checkLiquidsoapStatus() {
});
}
function setLiveSourceConnectionOverrideListener() {
$("[id=connection_url_override]").click(function (event) {
var url_input = $(this)
.parent()
.find("dd[id$='_source_host-element']")
.children();
url_input.removeAttr("readonly");
$(this).parent().find("div[id$='_dj_connection_url_actions']").show();
event.preventDefault();
});
// set action for "OK" and "X"
var live_dj_actions = $("#live_dj_connection_url_actions");
var live_dj_input = live_dj_actions
.parent()
.find("dd[id$='_source_host-element']")
.children();
var master_dj_actions = $("#master_dj_connection_url_actions");
var master_dj_input = master_dj_actions
.parent()
.find("dd[id$='_source_host-element']")
.children();
live_dj_actions.find("#ok").click(function (event) {
event.preventDefault();
var url = live_dj_input.val();
live_dj_input.val(url);
live_dj_input.attr("readonly", "readonly");
live_dj_actions.hide();
$.get(baseUrl + "Preference/set-source-connection-url", {
format: "json",
type: "livedj",
url: encodeURIComponent(url),
override: 1,
});
event.preventDefault();
});
live_dj_actions.find("#reset").click(function (event) {
event.preventDefault();
var port = $("#show_source_port").val();
var mount = $("#show_source_mount").val();
if (mount.charAt(0) != "/") {
mount = "/".concat(mount);
}
var url = "http://" + location.hostname + ":" + port + mount;
live_dj_input.val(url);
live_dj_input.attr("readonly", "readonly");
live_dj_actions.hide();
$.get(baseUrl + "Preference/set-source-connection-url", {
format: "json",
type: "livedj",
url: encodeURIComponent(url),
override: 0,
});
event.preventDefault();
});
master_dj_actions.find("#ok").click(function (event) {
var url = master_dj_input.val();
master_dj_input.val(url);
master_dj_input.attr("readonly", "readonly");
master_dj_actions.hide();
$.get(baseUrl + "Preference/set-source-connection-url", {
format: "json",
type: "masterdj",
url: encodeURIComponent(url),
override: 1,
});
event.preventDefault();
});
master_dj_actions.find("#reset").click(function (event) {
var port = $("#master_source_port").val();
var mount = $("#master_source_mount").val();
if (mount.charAt(0) != "/") {
mount = "/".concat(mount);
}
var url = "http://" + location.hostname + ":" + port + mount;
master_dj_input.val(url);
master_dj_input.attr("readonly", "readonly");
master_dj_actions.hide();
$.get(baseUrl + "Preference/set-source-connection-url", {
format: "json",
type: "masterdj",
url: encodeURIComponent(url),
override: 0,
});
event.preventDefault();
});
}
function setupEventListeners() {
// initial stream url
$("dd[id=outputStreamURL-element]").each(function () {
rebuildStreamURL($(this));
});
$("input[id$=-host], input[id$=-port], input[id$=-mount]").keyup(function () {
rebuildStreamURL($(this));
});
$("input[id$=-port]").keypress(function (e) {
validate($(this), e);
});
$("select[id$=-output]").change(function () {
rebuildStreamURL($(this));
});
if (!$("#output_sound_device").is(":checked")) {
$("select[id=output_sound_device_type]").attr("disabled", "disabled");
} else {
@ -319,8 +189,6 @@ function setupEventListeners() {
return false;
});
setLiveSourceConnectionOverrideListener();
showErrorSections();
checkLiquidsoapStatus();
@ -582,30 +450,18 @@ $(document).ready(function () {
if (e[0] == s[0]) {
return;
}
var confirm_pypo_restart_text = $.i18n._(
"WARNING: This will restart your stream and may cause a short dropout for your listeners!"
);
if (confirm(confirm_pypo_restart_text)) {
var data = $("#stream_form").serialize();
var url = baseUrl + "Preference/stream-setting";
var data = $("#stream_form").serialize();
var url = baseUrl + "Preference/stream-setting";
$.post(url, { format: "json", data: data }, function (json) {
$("#content").empty().append(json.html);
if (json.valid) {
window.location.reload();
}
setupEventListeners();
setSliderForReplayGain();
getAdminPasswordStatus();
});
} else {
if (e.prop("checked")) {
if (e[0] != s[0]) {
e.prop("checked", false);
s.prop("checked", true);
}
$.post(url, { format: "json", data: data }, function (json) {
$("#content").empty().append(json.html);
if (json.valid) {
window.location.reload();
}
}
setupEventListeners();
setSliderForReplayGain();
getAdminPasswordStatus();
});
}
);
});