diff --git a/api/libretime_api/legacy/migrations/sql/data.sql b/api/libretime_api/legacy/migrations/sql/data.sql
index 6e7e7f2aa..d0a272a5d 100644
--- a/api/libretime_api/legacy/migrations/sql/data.sql
+++ b/api/libretime_api/legacy/migrations/sql/data.sql
@@ -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'));
diff --git a/legacy/application/configs/conf.php b/legacy/application/configs/conf.php
index 45507969b..252a6dcfd 100644
--- a/legacy/application/configs/conf.php
+++ b/legacy/application/configs/conf.php
@@ -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'];
diff --git a/legacy/application/controllers/PreferenceController.php b/legacy/application/controllers/PreferenceController.php
index 11a7d62ac..278340ca0 100644
--- a/legacy/application/controllers/PreferenceController.php
+++ b/legacy/application/controllers/PreferenceController.php
@@ -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 = "
" . _('Stream Setting Updated.') . '
';
}
}
@@ -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();
diff --git a/legacy/application/forms/LiveStreamingPreferences.php b/legacy/application/forms/LiveStreamingPreferences.php
index 69fe75178..a028a35c4 100644
--- a/legacy/application/forms/LiveStreamingPreferences.php
+++ b/legacy/application/forms/LiveStreamingPreferences.php
@@ -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,
],
],
]
diff --git a/legacy/application/forms/StreamSetting.php b/legacy/application/forms/StreamSetting.php
index 44979f0b3..9cc9392eb 100644
--- a/legacy/application/forms/StreamSetting.php
+++ b/legacy/application/forms/StreamSetting.php
@@ -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);
}
}
diff --git a/legacy/application/forms/StreamSettingSubForm.php b/legacy/application/forms/StreamSettingSubForm.php
index 15aeb86a5..079ba0de5 100644
--- a/legacy/application/forms/StreamSettingSubForm.php
+++ b/legacy/application/forms/StreamSettingSubForm.php
@@ -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 = '' . _('Getting information from the server...') . '
';
@@ -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');
- }
- }
- }
}
diff --git a/legacy/application/models/ListenerStat.php b/legacy/application/models/ListenerStat.php
index 090affdcd..96713ffc7 100644
--- a/legacy/application/models/ListenerStat.php
+++ b/legacy/application/models/ListenerStat.php
@@ -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
diff --git a/legacy/application/models/Preference.php b/legacy/application/models/Preference.php
index 1ddc8713e..2fcf9fb43 100644
--- a/legacy/application/models/Preference.php
+++ b/legacy/application/models/Preference.php
@@ -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');
diff --git a/legacy/application/models/StreamSetting.php b/legacy/application/models/StreamSetting.php
index 7587dfa8b..b408b71b8 100644
--- a/legacy/application/models/StreamSetting.php
+++ b/legacy/application/models/StreamSetting.php
@@ -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') ?? '';
}
}
diff --git a/legacy/application/views/scripts/dashboard/stream-player.phtml b/legacy/application/views/scripts/dashboard/stream-player.phtml
index f8e00e963..242339091 100644
--- a/legacy/application/views/scripts/dashboard/stream-player.phtml
+++ b/legacy/application/views/scripts/dashboard/stream-player.phtml
@@ -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 @@
element->getElement('master_username')->render() ?>
element->getElement('master_password')->render() ?>
- element->getElement("master_source_host")->render() ?>
-
-
-
-
+ element->getElement("master_source_host")->render() ?>
element->getElement("master_source_port")->render() ?>
element->getElement("master_source_mount")->render() ?>
@@ -31,15 +25,7 @@
-
- element->getElement("show_source_host")->render() ?>
-
-
-
-
-
+ element->getElement("show_source_host")->render() ?>
element->getElement("show_source_port")->render() ?>
element->getElement("show_source_mount")->render() ?>
diff --git a/legacy/application/views/scripts/form/stream-setting-form.phtml b/legacy/application/views/scripts/form/stream-setting-form.phtml
index e839afcc6..bd53a32b3 100644
--- a/legacy/application/views/scripts/form/stream-setting-form.phtml
+++ b/legacy/application/views/scripts/form/stream-setting-form.phtml
@@ -15,27 +15,13 @@ $s_name = "s" . $this->stream_number;
element->getElement('enable') ?>
-
-
+
+
-
- element->getElement('mobile') ?>
+
+ element->getElement('output') ?>
-
-
-
-
- element->getElement('type') ?>
-
-
-
-
-
-
-
- element->getElement('bitrate') ?>
-
@@ -64,12 +50,6 @@ $s_name = "s" . $this->stream_number;
-
-
-
-
- element->getElement('output') ?>
-
@@ -78,144 +58,100 @@ $s_name = "s" . $this->stream_number;
element->getElement('channels') ?>
-
+
+
+
+
+ element->getElement('type') ?>
+
+
+
+
+
+
+
+ element->getElement('bitrate') ?>
+
+
+
+
+
+
+
+ element->getElement('name') ?>
+ element->getElement('name')->hasErrors()) : ?>
+
+ element->getElement('name')->getMessages() as $error) : ?>
+
+
+
+
+
+
+
+
+
+ element->getElement('description') ?>
+ element->getElement('description')->hasErrors()) : ?>
+
+ element->getElement('description')->getMessages() as $error) : ?>
+
+
+
+
+
+
+
+
+
+ element->getElement('url') ?>
+ element->getElement('url')->hasErrors()) : ?>
+
+ element->getElement('url')->getMessages() as $error) : ?>
+
+
+
+
+
+
+
+
+
+ element->getElement('genre') ?>
+ element->getElement('genre')->hasErrors()) : ?>
+
+ element->getElement('genre')->getMessages() as $error) : ?>
+
+
+
+
+
+
+
+
+
+ element->getElement('mount') ?>
+ element->getElement('mount')->hasErrors()) : ?>
+
+ element->getElement('mount')->getMessages() as $error) : ?>
+
+
+
+
+
+
+
+
+
+ element->getElement('mobile') ?>
+
-
+
-
+
+ element->getElement('public_url')->getValue() ?>
+
diff --git a/legacy/application/views/scripts/preference/stream-setting.phtml b/legacy/application/views/scripts/preference/stream-setting.phtml
index ef732f4c2..3ce7c3fdc 100644
--- a/legacy/application/views/scripts/preference/stream-setting.phtml
+++ b/legacy/application/views/scripts/preference/stream-setting.phtml
@@ -11,39 +11,11 @@