diff --git a/lib/helpers/soap.js b/lib/helpers/soap.js
index d83c5ac7..14335ea6 100644
--- a/lib/helpers/soap.js
+++ b/lib/helpers/soap.js
@@ -44,7 +44,7 @@ const TEMPLATES = Object.freeze({
[TYPE.Previous]: '0',
[TYPE.Mute]: '0Master{mute}',
[TYPE.GroupMute]: '0Master{mute}',
- [TYPE.Volume]: '0Master{volume}',
+ [TYPE.Volume]: '0{channel}{volume}',
[TYPE.Seek]: '0{unit}{value}',
[TYPE.RemoveAllTracksFromQueue]: '0',
[TYPE.RemoveTrackFromQueue]: '0Q:0/{track}',
diff --git a/lib/models/Player.js b/lib/models/Player.js
index 76c5d07b..441ca083 100644
--- a/lib/models/Player.js
+++ b/lib/models/Player.js
@@ -146,6 +146,9 @@ function getState(playerInternal, coordinatorInternal, sub) {
const state = {
volume: playerInternal.volume,
+ volumeLeft: playerInternal.volumeLeft,
+ volumeRight: playerInternal.volumeRight,
+ balance: playerInternal.balance,
mute: playerInternal.mute,
equalizer: playerInternal.equalizer,
currentTrack: coordinatorInternal.currentTrack,
@@ -191,10 +194,25 @@ function Player(data, listener, system) {
get: () => state
});
_this.ownVolumeEvents = [];
- _this._setVolume = function _setVolume(level) {
- state.volume = level;
+ _this._setVolume = function _setVolume(level, channel) {
+ switch(channel) {
+ case 'LF':
+ state.volumeLeft = level;
+ break;
+ case 'RF':
+ state.volumeRight = level;
+ break;
+ default:
+ //Master or null (which by legacy is Master)
+ state.volume = level;
+ }
};
+ _this._setBalance = function _setBalance(level) {
+ console.log("_setBalance:" + level);
+ state.balance = level;
+ }
+
let uri = url.parse(data.location);
_this.baseUrl = `${uri.protocol}//${uri.host}`;
@@ -498,28 +516,66 @@ Player.prototype.muteGroup = function muteGroup() {
{ mute: 1 });
};
-Player.prototype.setVolume = function setVolume(level) {
+Player.prototype.setVolume = function setVolume(level, channel) {
if (this.outputFixed) {
return Promise.resolve();
}
-
- // If prefixed with + or -
- if (/^[+\-]/.test(level)) {
- level = this.state.volume + parseInt(level);
+ switch(channel) {
+ case 'LF':
+ // If prefixed with + or -
+ if (/^[+\-]/.test(level)) {
+ level = this.state.volumeLeft + parseInt(level);
+ }
+ break;
+ case 'RF':
+ // If prefixed with + or -
+ if (/^[+\-]/.test(level)) {
+ level = this.state.volumeRight + parseInt(level);
+ }
+ break;
+ default:
+ // If prefixed with + or -
+ if (/^[+\-]/.test(level)) {
+ level = this.state.volume + parseInt(level);
+ }
+ channel = 'Master';
}
if (level < 0) level = 0;
- this._setVolume(level);
+ this._setVolume(level, channel);
// stash this update to ignore the event when it comes back.
- this.ownVolumeEvents.push(level);
+ this.ownVolumeEvents.push(level, channel);
return soap.invoke(
`${this.baseUrl}/MediaRenderer/RenderingControl/Control`,
TYPE.Volume,
- { volume: level });
+ { volume: level, channel: channel });
};
+Player.prototype.setBalance = function setBalance(level) {
+
+ console.log("setBalance: "+level);
+ let volumeLeft = 100;
+ let volumeRight = 100;
+
+ console.log("Balance: "+level);
+
+ const adjustment = (level-50)*2;
+ if (adjustment < 0) {
+ volumeRight = 100+adjustment;
+ } else if(level > 50) {
+ volumeLeft = 100-adjustment;
+ }
+
+ this.setVolume(volumeLeft, 'LF');
+ this.setVolume(volumeRight, 'RF');
+
+ this._setBalance(level);
+
+ return Promise.resolve("success");
+}
+
Player.prototype.timeSeek = function timeSeek(seconds) {
let formattedTime = formatTime(seconds);
return soap.invoke(