Skip to content

Commit

Permalink
Merge pull request volumio#239 from Saiyato/squeezelite
Browse files Browse the repository at this point in the history
Major update squeezelite
  • Loading branch information
Ghembs authored Nov 20, 2018
2 parents b10b491 + 0f32780 commit c0549c2
Show file tree
Hide file tree
Showing 232 changed files with 108 additions and 25,515 deletions.
22 changes: 17 additions & 5 deletions plugins/music_service/squeezelite/UIConfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
},
"sections": [
{
"id": "section_serverconf",
"id": "section_serviceconf",
"element": "section",
"label": "TRANSLATE.SQUEEZELITE.SERVER",
"description": "TRANSLATE.SQUEEZELITE.D_SERVER",
"icon": "fa-server",
"label": "TRANSLATE.SQUEEZELITE.SERVICE",
"description": "TRANSLATE.SQUEEZELITE.D_SERVICE",
"icon": "fa-cogs",
"onSave": {
"type": "controller",
"endpoint": "music_service/squeezelite",
"method": "updateSqueezeliteServerConfig"
"method": "updateSqueezeliteServiceConfig"
},
"saveButton": {
"label": "TRANSLATE.SQUEEZELITE.SAVE",
Expand Down Expand Up @@ -54,6 +54,7 @@
"label": "TRANSLATE.SQUEEZELITE.SAVE",
"data": [
"output_device",
"soundcard_timeout",
"alsa_params",
"extra_params"
]
Expand All @@ -70,6 +71,17 @@
},
"options": []
},
{
"id": "soundcard_timeout",
"element": "select",
"label": "TRANSLATE.SQUEEZELITE.SOUNDCARD_TIMEOUT",
"doc": "TRANSLATE.SQUEEZELITE.D_SOUNDCARD_TIMEOUT",
"value": {
"value": "2",
"label": "2"
},
"options": []
},
{
"id": "alsa_params",
"type":"text",
Expand Down
4 changes: 4 additions & 0 deletions plugins/music_service/squeezelite/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
"type": "string",
"value": "default"
},
"soundcard_timeout": {
"type": "string",
"value": "2"
},
"alsa_params": {
"type": "string",
"value": "80:4::"
Expand Down
8 changes: 5 additions & 3 deletions plugins/music_service/squeezelite/i18n/strings_en.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
{
"SQUEEZELITE":{
"SQUEEZELITECONF":"Squeezelite Configuration",
"SERVER":"Configure server",
"D_CONFIG":"The below settings are for server relation configuration.",
"SERVICE":"Configure service",
"D_SERVICE":"The below settings are for service configuration.",
"PLAYER_ENABLED":"Enable auto-start of service",
"D_PLAYER_ENABLED":"If set to ON the Squeezelite-server will start on boot, else you must manually start the service to use it.",
"D_PLAYER_ENABLED":"If set to ON the Squeezelite-service will start on boot, else you must manually start the service to use it.",
"INSTANCE_NAME":"Instance name",
"D_INSTANCE_NAME":"Controls how the player will appear in the LMS webconsole.",
"AUDIO":"Configure audio output settings",
"D_AUDIO":"Sound output can be controlled with the below settings.",
"OUTPUT_DEVICE":"Output device",
"D_OUTPUT_DEVICE":"Choose the output device you want to use for this Squeezelite instance.",
"SOUNDCARD_TIMEOUT":"Close soundcard after x seconds",
"D_SOUNDCARD_TIMEOUT":"Close output device when idle after timeout seconds, default is to keep it open while player is 'on'",
"ALSAPARAMS":"ALSA Parameters",
"D_ALSAPARAMS":"Fill in the ALSA parameters, don't change them if you have no idea what you are doing (default = 80:4::). <br /><br />Formatting is as follows: <b>b:p:f:m</b> <ul><li>b: is the buffer time in milliseconds (values less than 500) or size in bytes (default 40ms)</li><li>p: is the period count (values less than 50) or size in bytes (default 4 periods)</li><li>f: is the sample format (possible values: 16, 24, 24_3 or 32)</li><li>m: use mmap (0 | 1)</li></ul>",
"EXTRAPARAMS":"Extra Parameters",
Expand Down
123 changes: 62 additions & 61 deletions plugins/music_service/squeezelite/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ ControllerSqueezelite.prototype.getUIConfig = function() {
}
}
//self.logger.info('Cards: ' + JSON.stringify(cards));
var seconds = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"];

self.commandRouter.i18nJson(__dirname+'/i18n/strings_' + lang_code + '.json',
__dirname + '/i18n/strings_en.json',
Expand Down Expand Up @@ -163,8 +164,22 @@ ControllerSqueezelite.prototype.getUIConfig = function() {
uiconf.sections[1].content[0].value.label = oLabel;
}
}
uiconf.sections[1].content[1].value = self.config.get('alsa_params');
uiconf.sections[1].content[2].value = self.config.get('extra_params');

for (var s in seconds)
{
self.configManager.pushUIConfigParam(uiconf, 'sections[1].content[1].options', {
value: s,
label: s
});

if(self.config.get('soundcard_timeout') == s)
{
uiconf.sections[1].content[1].value.value = self.config.get('soundcard_timeout');
uiconf.sections[1].content[1].value.label = self.config.get('soundcard_timeout');
}
}
uiconf.sections[1].content[2].value = self.config.get('alsa_params');
uiconf.sections[1].content[3].value = self.config.get('extra_params');
self.logger.info("2/2 Squeezelite settings sections loaded");

self.logger.info("Populated config screen.");
Expand Down Expand Up @@ -203,15 +218,15 @@ ControllerSqueezelite.prototype.setConf = function(conf) {

// Public Methods ---------------------------------------------------------------------------------------

ControllerSqueezelite.prototype.updateSqueezeliteServerConfig = function (data)
ControllerSqueezelite.prototype.updateSqueezeliteServiceConfig = function (data)
{
var self = this;
var defer = libQ.defer();

self.config.set('enabled', data['enabled']);
self.config.set('name', data['name']);

self.logger.info("Successfully updated Squeezelite server configuration");
self.logger.info("Successfully updated Squeezelite service configuration");

self.constructUnit(__dirname + "/unit/squeezelite.unit-template", __dirname + "/unit/squeezelite.service")
.then(function(stopIfNeeded){
Expand Down Expand Up @@ -239,12 +254,13 @@ ControllerSqueezelite.prototype.updateSqueezeliteAudioConfig = function (data)
var defer = libQ.defer();

self.config.set('output_device', data['output_device'].value);
self.config.set('soundcard_timeout', data['soundcard_timeout'].value);
self.config.set('alsa_params', data['alsa_params']);
self.config.set('extra_params', data['extra_params']);

self.logger.info("Successfully updated Squeezelite audio configuration");

self.constructUnit(__dirname + "/unit/squeezelite.unit-template", __dirname + "/unit/squeezelite.service")
self.constructUnit(__dirname + "/unit/squeezelite.unit-template", __dirname + "/squeezelite.service")
.then(function(stopIfNeeded){
if(self.config.get('enabled') != true)
{
Expand All @@ -264,26 +280,48 @@ ControllerSqueezelite.prototype.updateSqueezeliteAudioConfig = function (data)
return defer.promise;
};

ControllerSqueezelite.prototype.moveAndReloadService = function (unitTemplate, unitFile, serviceName)
ControllerSqueezelite.prototype.restartService = function (serviceName, boot)
{
var self = this;
var defer = libQ.defer();

var command = "/bin/echo volumio | /usr/bin/sudo -S /bin/cp " + unitTemplate + " " + unitFile;

exec(command, {uid:1000,gid:1000}, function (error, stdout, stderr) {
if (error !== null) {
self.commandRouter.pushConsoleMessage('The following error occurred while moving ' + serviceName + ': ' + error);
self.commandRouter.pushToastMessage('error', "Moving service failed", "Stopping " + serviceName + " failed with error: " + error);
defer.reject();
}
else {
self.commandRouter.pushConsoleMessage(serviceName + ' moved');
self.commandRouter.pushToastMessage('success', "Moved", "Moved " + serviceName + ".");
}
});
if(self.config.get('enabled'))
{
var command = "/usr/bin/sudo /bin/systemctl restart " + serviceName;

command = "/bin/echo volumio | /usr/bin/sudo -S systemctl daemon-reload";
self.reloadService(serviceName)
.then(function(restart){
exec(command, {uid:1000,gid:1000}, function (error, stdout, stderr) {
if (error !== null) {
self.commandRouter.pushConsoleMessage('The following error occurred while starting ' + serviceName + ': ' + error);
self.commandRouter.pushToastMessage('error', "Restart failed", "Restarting " + serviceName + " failed with error: " + error);
defer.reject();
}
else {
self.commandRouter.pushConsoleMessage(serviceName + ' started');
if(boot == false)
self.commandRouter.pushToastMessage('success', "Restarted " + serviceName, "Restarted " + serviceName + " for the changes to take effect.");

defer.resolve();
}
});
});
}
else
{
self.logger.info("Not starting " + serviceName + "; it's not enabled.");
defer.resolve();
}

return defer.promise;
};

ControllerSqueezelite.prototype.reloadService = function (serviceName)
{
var self = this;
var defer = libQ.defer();

var command = "/usr/bin/sudo /bin/systemctl daemon-reload";
exec(command, {uid:1000,gid:1000}, function (error, stdout, stderr) {
if (error !== null) {
self.commandRouter.pushConsoleMessage('The following error occurred while reloading ' + serviceName + ': ' + error);
Expand All @@ -296,41 +334,7 @@ ControllerSqueezelite.prototype.moveAndReloadService = function (unitTemplate, u
defer.resolve();
}
});


return defer.promise;
};

ControllerSqueezelite.prototype.restartService = function (serviceName, boot)
{
var self = this;
var defer = libQ.defer();

if(self.config.get('enabled'))
{
var command = "/bin/echo volumio | /usr/bin/sudo -S /bin/systemctl restart " + serviceName;

exec(command, {uid:1000,gid:1000}, function (error, stdout, stderr) {
if (error !== null) {
self.commandRouter.pushConsoleMessage('The following error occurred while starting ' + serviceName + ': ' + error);
self.commandRouter.pushToastMessage('error', "Restart failed", "Restarting " + serviceName + " failed with error: " + error);
defer.reject();
}
else {
self.commandRouter.pushConsoleMessage(serviceName + ' started');
if(boot == false)
self.commandRouter.pushToastMessage('success', "Restarted " + serviceName, "Restarted " + serviceName + " for the changes to take effect.");

defer.resolve();
}
});
}
else
{
self.logger.info("Not starting " + serviceName + "; it's not enabled.");
defer.resolve();
}

return defer.promise;
};

Expand All @@ -339,7 +343,7 @@ ControllerSqueezelite.prototype.stopService = function (serviceName)
var self = this;
var defer = libQ.defer();

var command = "/bin/echo volumio | /usr/bin/sudo -S /bin/systemctl stop " + serviceName;
var command = "/usr/bin/sudo /bin/systemctl stop " + serviceName;

exec(command, {uid:1000,gid:1000}, function (error, stdout, stderr) {
if (error !== null) {
Expand All @@ -365,6 +369,7 @@ ControllerSqueezelite.prototype.constructUnit = function(unitTemplate, unitFile)
var replacementDictionary = [
{ placeholder: "${NAME}", replacement: self.config.get('name') },
{ placeholder: "${OUTPUT_DEVICE}", replacement: self.config.get('output_device') },
{ placeholder: "${SOUNDCARD_TIMEOUT}", replacement: self.config.get('soundcard_timeout') },
{ placeholder: "${ALSA_PARAMS}", replacement: self.config.get('alsa_params') },
{ placeholder: "${EXTRA_PARAMS}", replacement: self.config.get('extra_params') }
];
Expand All @@ -384,18 +389,14 @@ ControllerSqueezelite.prototype.constructUnit = function(unitTemplate, unitFile)
else
replacementDictionary[rep].replacement = "-o default";
}
else if (replacementDictionary[rep].placeholder == "${SOUNDCARD_TIMEOUT}")
replacementDictionary[rep].replacement = "-C " + replacementDictionary[rep].replacement;
else if (replacementDictionary[rep].placeholder == "${ALSA_PARAMS}" && self.config.get('alsa_params') != '')
replacementDictionary[rep].replacement = "-a " + replacementDictionary[rep].replacement;
}
}

//self.logger.info('### Replacement dictionary: ' + JSON.stringify(replacementDictionary));

self.replaceStringsInFile(unitTemplate, unitFile, replacementDictionary)
.then(function(activate)
{
self.moveAndReloadService(unitFile, '/etc/systemd/system/squeezelite.service', 'Squeezelite');
})
.then(function(resolve){
self.restartService('squeezelite', false);
defer.resolve();
Expand Down
12 changes: 7 additions & 5 deletions plugins/music_service/squeezelite/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,29 @@ if [ ! -f $INSTALLING ]; then

touch $INSTALLING

if [ ! -d /data/plugins/music_services/squeezelite ];
if [ ! -d /opt/squeezelite ];
then
# Download latest squeezelite executable
echo "Downloading squeezelite..."
mkdir /home/volumio/logitechmediaserver
wget -O /opt/squeezelite https://github.com/Saiyato/volumio-squeezelite-plugin/raw/master/known_working_versions/squeezelite-armv6hf-noffmpeg
wget -O /opt/squeezelite https://github.com/Saiyato/volumio-squeezelite-plugin/raw/master/known_working_versions/squeezelite-armv6hf-volumio

# Fix executable rights
chown volumio:volumio /opt/squeezelite
chmod 755 /opt/squeezelite

# Download and activate default unit
TMPUNIT="/home/volumio/squeezelite.service"
TMPUNIT="/data/plugins/music_service/squeezelite/squeezelite.service"
wget -O $TMPUNIT https://raw.githubusercontent.com/Saiyato/volumio-squeezelite-plugin/master/unit/squeezelite.unit-template
chown volumio $TMPUNIT

sed 's|${NAME}|-n Volumio|g' -i $TMPUNIT
sed 's|${OUTPUT_DEVICE}|-o default|g' -i $TMPUNIT
sed 's|${SOUNDCARD_TIMEOUT}|2|g' -i $TMPUNIT
sed 's|${ALSA_PARAMS}|-a 80:4::|g' -i $TMPUNIT
sed 's|${EXTRA_PARAMS}||g' -i $TMPUNIT

mv $TMPUNIT /etc/systemd/system/squeezelite.service
#mv $TMPUNIT /etc/systemd/system/squeezelite.service
ln -fs /data/plugins/music_service/squeezelite/squeezelite.service /etc/systemd/system/squeezelite.service
systemctl daemon-reload

else
Expand Down
1 change: 0 additions & 1 deletion plugins/music_service/squeezelite/node_modules/.bin/rimraf

This file was deleted.

This file was deleted.

This file was deleted.

Loading

0 comments on commit c0549c2

Please sign in to comment.