Closes #4 -- Add basic system-wide support for the ShoutCast 2 broadcast system.
This commit is contained in:
parent
c57d70b2a7
commit
f1276b347c
|
@ -210,24 +210,39 @@ class LiquidSoap extends BackendAbstract
|
|||
$ls_config[] = '# Outbound Broadcast';
|
||||
|
||||
// Configure the outbound broadcast.
|
||||
$fe_settings = (array)$this->station->frontend_config;
|
||||
|
||||
$broadcast_port = $fe_settings['port'];
|
||||
$broadcast_source_pw = $fe_settings['source_pw'];
|
||||
|
||||
switch($this->station->frontend_type)
|
||||
{
|
||||
case 'shoutcast2':
|
||||
// TODO: Implement Shoutcast 2 Broadcasting
|
||||
break;
|
||||
|
||||
case 'remote':
|
||||
$this->log(_('You cannot use an AutoDJ with a remote frontend. Please change the frontend type or update the backend to be "Disabled".'), 'error');
|
||||
return false;
|
||||
break;
|
||||
|
||||
case 'shoutcast2':
|
||||
$format = 'mp3';
|
||||
$bitrate = 128;
|
||||
|
||||
$output_format = '%mp3.cbr(samplerate=44100,stereo=true,bitrate='.(int)$bitrate.')';
|
||||
|
||||
$output_params = [
|
||||
'id="radio_out"',
|
||||
'host = "localhost"',
|
||||
'port = '.($broadcast_port),
|
||||
'password = "'.$broadcast_source_pw.'"',
|
||||
'name = "' . $this->_cleanUpString($this->station->name) . '"',
|
||||
'public = false',
|
||||
$output_format, // Required output format (%mp3 etc)
|
||||
'radio', // Required
|
||||
];
|
||||
$ls_config[] = 'output.shoutcast('.implode(', ', $output_params).')';
|
||||
break;
|
||||
|
||||
case 'icecast':
|
||||
default:
|
||||
$ic_settings = (array)$this->station->frontend_config;
|
||||
|
||||
$icecast_port = $ic_settings['port'];
|
||||
$icecast_source_pw = $ic_settings['source_pw'];
|
||||
|
||||
foreach($this->station->mounts as $mount_row)
|
||||
{
|
||||
if (!$mount_row->enable_autodj)
|
||||
|
@ -241,18 +256,21 @@ class LiquidSoap extends BackendAbstract
|
|||
else
|
||||
$output_format = '%mp3.cbr(samplerate=44100,stereo=true,bitrate='.(int)$bitrate.')';
|
||||
|
||||
$output_params = [
|
||||
$output_format, // Required output format (%mp3 or %ogg)
|
||||
'id="radio_out_'.$mount_row->id.'"',
|
||||
'host = "localhost"',
|
||||
'port = '.$icecast_port,
|
||||
'password = "'.$icecast_source_pw.'"',
|
||||
'name = "'.$this->_cleanUpString($this->station->name).'"',
|
||||
'description = "'.$this->_cleanUpString($this->station->description).'"',
|
||||
'mount = "'.$mount_row->name.'"',
|
||||
'radio', // Required
|
||||
];
|
||||
$ls_config[] = 'output.icecast('.implode(', ', $output_params).')';
|
||||
if (!empty($output_format))
|
||||
{
|
||||
$output_params = [
|
||||
$output_format, // Required output format (%mp3 or %ogg)
|
||||
'id="radio_out_' . $mount_row->id . '"',
|
||||
'host = "localhost"',
|
||||
'port = ' . $broadcast_port,
|
||||
'password = "' . $broadcast_source_pw . '"',
|
||||
'name = "' . $this->_cleanUpString($this->station->name) . '"',
|
||||
'description = "' . $this->_cleanUpString($this->station->description) . '"',
|
||||
'mount = "' . $mount_row->name . '"',
|
||||
'radio', // Required
|
||||
];
|
||||
$ls_config[] = 'output.icecast(' . implode(', ', $output_params) . ')';
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,8 @@ abstract class FrontendAbstract extends \App\Radio\AdapterAbstract
|
|||
return $this->supports_mounts;
|
||||
}
|
||||
|
||||
public function getDefaultMounts() {}
|
||||
|
||||
protected $supports_streamers = true;
|
||||
|
||||
public function supportsStreamers()
|
||||
|
@ -140,4 +142,26 @@ abstract class FrontendAbstract extends \App\Radio\AdapterAbstract
|
|||
if (!empty(trim($message)))
|
||||
parent::log(str_pad('Radio Frontend: ', 20, ' ', STR_PAD_RIGHT).$message, $class);
|
||||
}
|
||||
|
||||
protected function _processCustomConfig($custom_config_raw)
|
||||
{
|
||||
$custom_config = [];
|
||||
|
||||
if (substr($custom_config_raw, 0, 1) == '{')
|
||||
{
|
||||
$custom_config = @json_decode($custom_config_raw, true);
|
||||
}
|
||||
elseif (substr($custom_config_raw, 0, 1) == '<')
|
||||
{
|
||||
$reader = new \App\Xml\Reader;
|
||||
$custom_config = $reader->fromString('<icecast>'.$custom_config_raw.'</icecast>');
|
||||
}
|
||||
|
||||
return $custom_config;
|
||||
}
|
||||
|
||||
protected function _getRadioPort()
|
||||
{
|
||||
return (8000 + (($this->station->id - 1) * 10));
|
||||
}
|
||||
}
|
|
@ -351,25 +351,25 @@ class IceCast extends FrontendAbstract
|
|||
return $defaults;
|
||||
}
|
||||
|
||||
protected function _processCustomConfig($custom_config_raw)
|
||||
public function getDefaultMounts()
|
||||
{
|
||||
$custom_config = [];
|
||||
|
||||
if (substr($custom_config_raw, 0, 1) == '{')
|
||||
{
|
||||
$custom_config = @json_decode($custom_config_raw, true);
|
||||
}
|
||||
elseif (substr($custom_config_raw, 0, 1) == '<')
|
||||
{
|
||||
$reader = new \App\Xml\Reader;
|
||||
$custom_config = $reader->fromString('<icecast>'.$custom_config_raw.'</icecast>');
|
||||
}
|
||||
|
||||
return $custom_config;
|
||||
}
|
||||
|
||||
protected function _getRadioPort()
|
||||
{
|
||||
return (8000 + (($this->station->id - 1) * 10));
|
||||
return [
|
||||
[
|
||||
'name' => '/radio.mp3',
|
||||
'is_default' => 1,
|
||||
'fallback_mount' => '/autodj.mp3',
|
||||
'enable_streamers' => 1,
|
||||
'enable_autodj' => 0,
|
||||
],
|
||||
[
|
||||
'name' => '/autodj.mp3',
|
||||
'is_default' => 0,
|
||||
'fallback_mount' => '/error.mp3',
|
||||
'enable_streamers' => 0,
|
||||
'enable_autodj' => 1,
|
||||
'autodj_format' => 'mp3',
|
||||
'autodj_bitrate' => 128,
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,23 +1,35 @@
|
|||
<?php
|
||||
namespace App\Radio\Frontend;
|
||||
|
||||
use App\Debug;
|
||||
use App\Utilities;
|
||||
use Entity\Station;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
|
||||
class ShoutCast2 extends AdapterAbstract
|
||||
class ShoutCast2 extends FrontendAbstract
|
||||
{
|
||||
/* TODO: This class not fully implemented! */
|
||||
protected $supports_mounts = false;
|
||||
|
||||
/* Process a nowplaying record. */
|
||||
protected function _process(&$np)
|
||||
protected function _getNowPlaying(&$np)
|
||||
{
|
||||
$return_raw = $this->getUrl();
|
||||
$fe_config = (array)$this->station->frontend_config;
|
||||
$radio_port = $fe_config['port'];
|
||||
|
||||
$np_url = 'http://localhost:'.$radio_port.'/stats';
|
||||
$return_raw = $this->getUrl($np_url);
|
||||
|
||||
if (empty($return_raw))
|
||||
return false;
|
||||
|
||||
$current_data = \App\Export::xml_to_array($return_raw);
|
||||
|
||||
Debug::print_r($return_raw);
|
||||
|
||||
$song_data = $current_data['SHOUTCASTSERVER'];
|
||||
|
||||
Debug::print_r($song_data);
|
||||
|
||||
$np['meta']['status'] = 'online';
|
||||
$np['meta']['bitrate'] = $song_data['BITRATE'];
|
||||
$np['meta']['format'] = $song_data['CONTENT'];
|
||||
|
@ -34,4 +46,176 @@ class ShoutCast2 extends AdapterAbstract
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function read()
|
||||
{
|
||||
|
||||
$config = $this->_getConfig();
|
||||
|
||||
$this->station->frontend_config = $this->_loadFromConfig($config);
|
||||
return true;
|
||||
}
|
||||
|
||||
public function write()
|
||||
{
|
||||
$config = $this->_getDefaults();
|
||||
|
||||
$frontend_config = (array)$this->station->frontend_config;
|
||||
|
||||
if (!empty($frontend_config['port']))
|
||||
$config['portbase'] = $frontend_config['port'];
|
||||
|
||||
if (!empty($frontend_config['source_pw']))
|
||||
$config['password'] = $frontend_config['source_pw'];
|
||||
|
||||
if (!empty($frontend_config['admin_pw']))
|
||||
$config['adminpassword'] = $frontend_config['admin_pw'];
|
||||
|
||||
if (!empty($frontend_config['custom_config']))
|
||||
{
|
||||
$custom_conf = $this->_processCustomConfig($frontend_config['custom_config']);
|
||||
if (!empty($custom_conf))
|
||||
$config = array_merge($config, $custom_conf);
|
||||
}
|
||||
|
||||
// Set any unset values back to the DB config.
|
||||
$this->station->frontend_config = $this->_loadFromConfig($config);
|
||||
|
||||
$em = $this->di['em'];
|
||||
$em->persist($this->station);
|
||||
$em->flush();
|
||||
|
||||
$config_path = $this->station->getRadioConfigDir();
|
||||
$sc_path = $config_path.'/sc_serv.conf';
|
||||
|
||||
$sc_file = '';
|
||||
foreach($config as $config_key => $config_value)
|
||||
$sc_file .= $config_key.'='.str_replace("\n", "", $config_value)."\n";
|
||||
|
||||
file_put_contents($sc_path, $sc_file);
|
||||
}
|
||||
|
||||
/*
|
||||
* Process Management
|
||||
*/
|
||||
|
||||
public function isRunning()
|
||||
{
|
||||
return $this->_isPidRunning($this->station->getRadioConfigDir().'/sc_serv.pid');
|
||||
}
|
||||
|
||||
public function stop()
|
||||
{
|
||||
$this->_killPid($this->station->getRadioConfigDir().'/sc_serv.pid');
|
||||
}
|
||||
|
||||
public function start()
|
||||
{
|
||||
$config_path = $this->station->getRadioConfigDir();
|
||||
|
||||
$sc_binary = realpath(APP_INCLUDE_ROOT.'/..').'/servers/sc_serv';
|
||||
$sc_config = $config_path.'/sc_serv.conf';
|
||||
|
||||
if ($this->isRunning())
|
||||
{
|
||||
$this->log(_('Not starting, process is already running.'));
|
||||
return;
|
||||
}
|
||||
|
||||
$cmd = \App\Utilities::run_command($sc_binary.' daemon '.$sc_config.' > '.$config_path.'/sc_pid_raw.txt');
|
||||
|
||||
if (file_exists($config_path.'/sc_pid_raw.txt'))
|
||||
{
|
||||
$pid_raw = file_get_contents($config_path.'/sc_pid_raw.txt');
|
||||
$this->log($pid_raw);
|
||||
|
||||
preg_match('#\[(.*?)\]#', $pid_raw, $match);
|
||||
$pid = (int)$match[1];
|
||||
|
||||
if ($pid != 0)
|
||||
file_put_contents($config_path.'/sc_serv.pid', $pid);
|
||||
|
||||
@unlink($config_path.'/sc_pid_raw.txt');
|
||||
}
|
||||
|
||||
if (!empty($cmd['output']))
|
||||
$this->log($cmd['output']);
|
||||
|
||||
if (!empty($cmd['error']))
|
||||
$this->log($cmd['error'], 'red');
|
||||
}
|
||||
|
||||
public function getStreamUrl()
|
||||
{
|
||||
return $this->getUrlForMount('/stream/1/');
|
||||
}
|
||||
|
||||
public function getStreamUrls()
|
||||
{
|
||||
return [$this->getUrlForMount('/stream/1/')];
|
||||
}
|
||||
|
||||
public function getUrlForMount($mount_name)
|
||||
{
|
||||
return $this->getPublicUrl().$mount_name.'?'.time();
|
||||
}
|
||||
|
||||
public function getAdminUrl()
|
||||
{
|
||||
return $this->getPublicUrl().'/admin.cgi';
|
||||
}
|
||||
|
||||
public function getPublicUrl()
|
||||
{
|
||||
$fe_config = (array)$this->station->frontend_config;
|
||||
$radio_port = $fe_config['port'];
|
||||
|
||||
$base_url = $this->di['em']->getRepository('Entity\Settings')->getSetting('base_url', 'localhost');
|
||||
|
||||
// Vagrant port-forwarding mode.
|
||||
if (APP_APPLICATION_ENV == 'development')
|
||||
return 'http://'.$base_url.':8080/radio/'.$radio_port;
|
||||
else
|
||||
return 'http://'.$base_url.':'.$radio_port;
|
||||
}
|
||||
|
||||
/*
|
||||
* Configuration
|
||||
*/
|
||||
|
||||
protected function _getConfig()
|
||||
{
|
||||
$config_dir = $this->station->getRadioConfigDir();
|
||||
$config = @parse_ini_file($config_dir.'/sc_serv.conf', false, INI_SCANNER_RAW);
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
protected function _loadFromConfig($config)
|
||||
{
|
||||
return [
|
||||
'port' => $config['portbase'],
|
||||
'source_pw' => $config['password'],
|
||||
'admin_pw' => $config['adminpassword'],
|
||||
];
|
||||
}
|
||||
|
||||
protected function _getDefaults()
|
||||
{
|
||||
$config_path = $this->station->getRadioConfigDir();
|
||||
|
||||
$defaults = [
|
||||
'password' => Utilities::generatePassword(),
|
||||
'adminpassword' => Utilities::generatePassword(),
|
||||
'logfile' => $config_path.'/sc_serv.log',
|
||||
'w3clog' => $config_path.'/sc_w3c.log',
|
||||
'publicserver' => 'never',
|
||||
'banfile' => $config_path.'/sc_serv.ban',
|
||||
'ripfile' => $config_path.'/sc_serv.rip',
|
||||
'maxuser' => 500,
|
||||
'portbase' => $this->_getRadioPort(),
|
||||
];
|
||||
|
||||
return $defaults;
|
||||
}
|
||||
}
|
|
@ -205,19 +205,13 @@ class Station extends \App\Doctrine\Entity
|
|||
'default' => 'icecast',
|
||||
'adapters' => [
|
||||
'icecast' => [
|
||||
'name' => 'IceCast v2.4',
|
||||
'name' => 'IceCast 2.4',
|
||||
'class' => '\App\Radio\Frontend\IceCast',
|
||||
],
|
||||
/*
|
||||
'shoutcast1' => array(
|
||||
'name' => 'ShoutCast 1',
|
||||
'class' => '\App\Radio\Frontend\ShoutCast1',
|
||||
),
|
||||
'shoutcast2' => array(
|
||||
'name' => 'ShoutCast 2',
|
||||
'class' => '\App\Radio\Frontend\ShoutCast2',
|
||||
),
|
||||
*/
|
||||
'remote' => [
|
||||
'name' => _('External Radio Server (Statistics Only)'),
|
||||
'class' => '\App\Radio\Frontend\Remote',
|
||||
|
@ -254,6 +248,8 @@ class Station extends \App\Doctrine\Entity
|
|||
*/
|
||||
public static function api(Station $row, ContainerInterface $di)
|
||||
{
|
||||
$fa = $row->getFrontendAdapter($di);
|
||||
|
||||
$api = [
|
||||
'id' => (int)$row->id,
|
||||
'name' => $row->name,
|
||||
|
@ -261,16 +257,12 @@ class Station extends \App\Doctrine\Entity
|
|||
'description' => $row->description,
|
||||
'frontend' => $row->frontend_type,
|
||||
'backend' => $row->backend_type,
|
||||
'listen_url' => '',
|
||||
'listen_url' => $fa->getStreamUrl(),
|
||||
'mounts' => [],
|
||||
];
|
||||
|
||||
if ($row->mounts->count() > 0)
|
||||
{
|
||||
$fa = $row->getFrontendAdapter($di);
|
||||
|
||||
$api['listen_url'] = $fa->getStreamUrl();
|
||||
|
||||
if ($fa->supportsMounts())
|
||||
{
|
||||
foreach($row->mounts as $mount_row)
|
||||
|
@ -418,29 +410,11 @@ class StationRepository extends Repository
|
|||
if ($frontend_adapter->supportsMounts())
|
||||
{
|
||||
// Create default mount points.
|
||||
$mount_points = [
|
||||
[
|
||||
'name' => '/radio.mp3',
|
||||
'is_default' => 1,
|
||||
'fallback_mount' => '/autodj.mp3',
|
||||
'enable_streamers' => 1,
|
||||
'enable_autodj' => 0,
|
||||
],
|
||||
[
|
||||
'name' => '/autodj.mp3',
|
||||
'is_default' => 0,
|
||||
'fallback_mount' => '/error.mp3',
|
||||
'enable_streamers' => 0,
|
||||
'enable_autodj' => 1,
|
||||
'autodj_format' => 'mp3',
|
||||
'autodj_bitrate' => 128,
|
||||
]
|
||||
];
|
||||
$mount_points = $frontend_adapter->getDefaultMounts();
|
||||
|
||||
foreach($mount_points as $mount_point)
|
||||
{
|
||||
$mount_point['station'] = $station;
|
||||
|
||||
$mount_record = new StationMount;
|
||||
$mount_record->fromArray($this->_em, $mount_point);
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ use \Doctrine\Common\Collections\ArrayCollection;
|
|||
* @Table(name="station_media", indexes={
|
||||
* @index(name="search_idx", columns={"title", "artist", "album"})
|
||||
* }, uniqueConstraints={
|
||||
* @UniqueConstraint(name="path_unique_idx", columns={"path"})
|
||||
* @UniqueConstraint(name="path_unique_idx", columns={"path", "station_id"})
|
||||
* })
|
||||
* @Entity(repositoryClass="StationMediaRepository")
|
||||
* @HasLifecycleCallbacks
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace Migration;
|
||||
|
||||
use Doctrine\DBAL\Migrations\AbstractMigration;
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
class Version20161122035237 extends AbstractMigration
|
||||
{
|
||||
/**
|
||||
* @param Schema $schema
|
||||
*/
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
$this->abortIf($this->connection->getDatabasePlatform()->getName() != 'mysql', 'Migration can only be executed safely on \'mysql\'.');
|
||||
|
||||
$this->addSql('DROP INDEX path_unique_idx ON station_media');
|
||||
$this->addSql('CREATE UNIQUE INDEX path_unique_idx ON station_media (path, station_id)');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $schema
|
||||
*/
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->abortIf($this->connection->getDatabasePlatform()->getName() != 'mysql', 'Migration can only be executed safely on \'mysql\'.');
|
||||
|
||||
$this->addSql('DROP INDEX path_unique_idx ON station_media');
|
||||
$this->addSql('CREATE UNIQUE INDEX path_unique_idx ON station_media (path)');
|
||||
}
|
||||
}
|
|
@ -46,6 +46,15 @@ return [
|
|||
'default' => $backend_default,
|
||||
]],
|
||||
|
||||
],
|
||||
],
|
||||
|
||||
'frontend_local' => [
|
||||
'legend' => _('Configure Radio Broadcasting'),
|
||||
'class' => 'frontend_fieldset',
|
||||
|
||||
'elements' => [
|
||||
|
||||
'enable_streamers' => ['radio', [
|
||||
'label' => _('Allow Streamers / DJs'),
|
||||
'description' => _('If this setting is turned on, streamers (or DJs) will be able to connect directly to your stream and broadcast live music that interrupts the AutoDJ stream.'),
|
||||
|
@ -53,29 +62,21 @@ return [
|
|||
'options' => [0 => 'No', 1 => 'Yes'],
|
||||
]],
|
||||
|
||||
],
|
||||
],
|
||||
|
||||
'frontend_icecast' => [
|
||||
'legend' => _('Configure IceCast 2'),
|
||||
'class' => 'frontend_fieldset',
|
||||
'description' => _('These settings are intended for advanced users only. You can safely leave all of these options blank and sensible defaults will be used for them.'),
|
||||
|
||||
'elements' => [
|
||||
|
||||
'port' => ['text', [
|
||||
'label' => _('Broadcasting Port'),
|
||||
'description' => _('No other program can be using this port. An available port is automatically assigned to each new station.'),
|
||||
'description' => _('No other program can be using this port. Leave blank to automatically assign a port.'),
|
||||
'belongsTo' => 'frontend_config',
|
||||
]],
|
||||
|
||||
'source_pw' => ['text', [
|
||||
'label' => _('Source Password'),
|
||||
'description' => _('Leave blank to automatically generate a new password.'),
|
||||
'belongsTo' => 'frontend_config',
|
||||
]],
|
||||
|
||||
'admin_pw' => ['text', [
|
||||
'label' => _('Admin Password'),
|
||||
'description' => _('Leave blank to automatically generate a new password.'),
|
||||
'belongsTo' => 'frontend_config',
|
||||
]],
|
||||
|
||||
|
|
|
@ -1,25 +1,3 @@
|
|||
<?php $this->layout('main', ['title' => _('Edit Station Profile')]); ?>
|
||||
|
||||
<?=$this->fetch('partials/form') ?>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
|
||||
showFieldset('frontend', $('form #field_frontend_type input:checked').val());
|
||||
showFieldset('backend', $('form #field_backend_type input:checked').val());
|
||||
|
||||
$('form #field_frontend_type input').on('change', function() {
|
||||
showFieldset('frontend', $(this).val());
|
||||
});
|
||||
$('form #field_backend_type input').on('change', function() {
|
||||
showFieldset('backend', $(this).val());
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
function showFieldset(fieldset_group, fieldset_id)
|
||||
{
|
||||
$('form fieldset.'+fieldset_group+'_fieldset').hide();
|
||||
$('form fieldset#'+fieldset_group+'_'+fieldset_id).show();
|
||||
}
|
||||
</script>
|
||||
<?=$this->fetch('partials/station_form') ?>
|
|
@ -2,30 +2,8 @@
|
|||
|
||||
<p><?=_('To continue the setup process, enter the basic details of your first station below. Some technical details will automatically be retrieved from the system after you complete this step.') ?></p>
|
||||
|
||||
<?=$this->fetch('partials/form') ?>
|
||||
<?=$this->fetch('partials/station_form') ?>
|
||||
|
||||
<div class="alert alert-info m-b-0 m-t-25">
|
||||
<?=_('Note: If you are not starting with an empty station directory, it may take a while to process any existing MP3 files or playlists that are in this station\'s directory.') ?>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
|
||||
showFieldset('frontend', $('form #field_frontend_type input:checked').val());
|
||||
showFieldset('backend', $('form #field_backend_type input:checked').val());
|
||||
|
||||
$('form #field_frontend_type input').on('change', function() {
|
||||
showFieldset('frontend', $(this).val());
|
||||
});
|
||||
$('form #field_backend_type input').on('change', function() {
|
||||
showFieldset('backend', $(this).val());
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
function showFieldset(fieldset_group, fieldset_id)
|
||||
{
|
||||
$('form fieldset.'+fieldset_group+'_fieldset').hide();
|
||||
$('form fieldset#'+fieldset_group+'_'+fieldset_id).show();
|
||||
}
|
||||
</script>
|
||||
</div>
|
|
@ -0,0 +1,33 @@
|
|||
<?=$this->fetch('partials/form') ?>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
|
||||
showFrontend($('form #field_frontend_type input:checked').val());
|
||||
showBackend($('form #field_backend_type input:checked').val());
|
||||
|
||||
$('form #field_frontend_type input').on('change', function() {
|
||||
showFrontend($(this).val());
|
||||
});
|
||||
$('form #field_backend_type input').on('change', function() {
|
||||
showBackend($(this).val());
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
function showFrontend(selected)
|
||||
{
|
||||
$('form fieldset.frontend_fieldset').hide();
|
||||
|
||||
if (selected == 'remote')
|
||||
$('form fieldset#frontend_remote').show();
|
||||
else
|
||||
$('form fieldset#frontend_local').show();
|
||||
}
|
||||
|
||||
function showBackend(selected)
|
||||
{
|
||||
$('form fieldset.backend_fieldset').hide();
|
||||
$('form fieldset#backend_'+selected).show();
|
||||
}
|
||||
</script>
|
|
@ -24,4 +24,5 @@
|
|||
- "{{ tmp_base }}/cache"
|
||||
- "{{ tmp_base }}/sessions"
|
||||
- "{{ tmp_base }}/proxies"
|
||||
- "{{ app_base }}/stations"
|
||||
- "{{ app_base }}/stations"
|
||||
- "{{ app_base }}/servers"
|
|
@ -9,6 +9,9 @@
|
|||
apt: pkg=icecast2 state=latest
|
||||
when: ansible_distribution == 'Ubuntu' and ansible_distribution_release == 'xenial'
|
||||
|
||||
- name: Link Fallback Error MP3
|
||||
file: src="{{ www_base }}/resources/error.mp3" dest="/usr/share/icecast2/web/error.mp3" state=link
|
||||
|
||||
- name: Remove problematic LiquidSoap plugins
|
||||
become: true
|
||||
apt: pkg="{{ item }}" state=absent
|
||||
|
@ -27,5 +30,15 @@
|
|||
- liquidsoap-plugin-flac
|
||||
- liquidsoap-plugin-icecast
|
||||
|
||||
- name: Link Fallback Error MP3
|
||||
file: src="{{ www_base }}/resources/error.mp3" dest="/usr/share/icecast2/web/error.mp3" state=link
|
||||
- name: Download ShoutCast 2 (x86)
|
||||
command: "wget http://download.nullsoft.com/shoutcast/tools/sc_serv2_linux-latest.tar.gz -O {{ app_base }}/servers/sc_serv.tar.gz"
|
||||
when: ansible_architecture == 'i386'
|
||||
|
||||
- name: Download ShoutCast 2 (x64)
|
||||
command: "wget http://download.nullsoft.com/shoutcast/tools/sc_serv2_linux_x64-latest.tar.gz -O {{ app_base }}/servers/sc_serv.tar.gz"
|
||||
when: ansible_architecture == 'x86_64'
|
||||
|
||||
- name: Extract ShoutCast 2
|
||||
command: "tar xvzf {{ app_base }}/servers/sc_serv.tar.gz"
|
||||
when: ansible_architecture == 'x86_64' or ansible_architecture == 'i386'
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
- debug:
|
||||
msg: "Running Ansible on {{ inventory_hostname }} with OS {{ ansible_distribution }} {{ ansible_distribution_release }} {{ ansible_distribution_version }} ({{ app_env }})"
|
||||
msg: "Running Ansible on {{ inventory_hostname }} with OS {{ ansible_distribution }} {{ ansible_distribution_release }} {{ ansible_distribution_version }} {{ ansible_architecture }} ({{ app_env }})"
|
||||
|
||||
- debug:
|
||||
msg: "Running in Testing Mode."
|
||||
|
@ -17,6 +17,7 @@
|
|||
- apt-transport-https
|
||||
- curl
|
||||
- wget
|
||||
- tar
|
||||
- build-essential
|
||||
- python-software-properties
|
||||
- pwgen
|
||||
|
|
Loading…
Reference in New Issue