@lox-audio-server/sonos 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +57 -0
- package/dist/esm/index.js +27 -0
- package/dist/esm/package.json +1 -0
- package/dist/esm/sonos/api/namespace.js +38 -0
- package/dist/esm/sonos/api/namespaces/audioClip.js +25 -0
- package/dist/esm/sonos/api/namespaces/groupVolume.js +25 -0
- package/dist/esm/sonos/api/namespaces/groups.js +31 -0
- package/dist/esm/sonos/api/namespaces/homeTheater.js +13 -0
- package/dist/esm/sonos/api/namespaces/playback.js +56 -0
- package/dist/esm/sonos/api/namespaces/playbackMetadata.js +16 -0
- package/dist/esm/sonos/api/namespaces/playbackSession.js +67 -0
- package/dist/esm/sonos/api/namespaces/playerVolume.js +41 -0
- package/dist/esm/sonos/api/websocket.js +310 -0
- package/dist/esm/sonos/client.js +193 -0
- package/dist/esm/sonos/constants.js +18 -0
- package/dist/esm/sonos/errors.js +49 -0
- package/dist/esm/sonos/group.js +231 -0
- package/dist/esm/sonos/models.js +63 -0
- package/dist/esm/sonos/player.js +112 -0
- package/dist/esm/sonos/types.js +46 -0
- package/dist/esm/sonos/utils.js +18 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +27 -0
- package/dist/sonos/api/namespace.d.ts +16 -0
- package/dist/sonos/api/namespace.js +38 -0
- package/dist/sonos/api/namespaces/audioClip.d.ts +16 -0
- package/dist/sonos/api/namespaces/audioClip.js +25 -0
- package/dist/sonos/api/namespaces/groupVolume.d.ts +10 -0
- package/dist/sonos/api/namespaces/groupVolume.js +25 -0
- package/dist/sonos/api/namespaces/groups.d.ts +10 -0
- package/dist/sonos/api/namespaces/groups.js +31 -0
- package/dist/sonos/api/namespaces/homeTheater.d.ts +5 -0
- package/dist/sonos/api/namespaces/homeTheater.js +13 -0
- package/dist/sonos/api/namespaces/playback.d.ts +17 -0
- package/dist/sonos/api/namespaces/playback.js +56 -0
- package/dist/sonos/api/namespaces/playbackMetadata.d.ts +7 -0
- package/dist/sonos/api/namespaces/playbackMetadata.js +16 -0
- package/dist/sonos/api/namespaces/playbackSession.d.ts +30 -0
- package/dist/sonos/api/namespaces/playbackSession.js +67 -0
- package/dist/sonos/api/namespaces/playerVolume.d.ts +12 -0
- package/dist/sonos/api/namespaces/playerVolume.js +41 -0
- package/dist/sonos/api/websocket.d.ts +51 -0
- package/dist/sonos/api/websocket.js +310 -0
- package/dist/sonos/client.d.ts +44 -0
- package/dist/sonos/client.js +193 -0
- package/dist/sonos/constants.d.ts +14 -0
- package/dist/sonos/constants.js +18 -0
- package/dist/sonos/errors.d.ts +25 -0
- package/dist/sonos/errors.js +49 -0
- package/dist/sonos/group.d.ts +58 -0
- package/dist/sonos/group.js +231 -0
- package/dist/sonos/models.d.ts +20 -0
- package/dist/sonos/models.js +63 -0
- package/dist/sonos/player.d.ts +33 -0
- package/dist/sonos/player.js +112 -0
- package/dist/sonos/types.d.ts +279 -0
- package/dist/sonos/types.js +46 -0
- package/dist/sonos/utils.d.ts +6 -0
- package/dist/sonos/utils.js +18 -0
- package/package.json +49 -0
package/README.md
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# lox-sonos-controller
|
|
2
|
+
|
|
3
|
+
TypeScript Sonos controller that talks directly to the local WebSocket API on a Sonos player.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @lox-audio-server/sonos
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Node.js 18+ is required.
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { SonosClient, EventType } from '@lox-audio-server/sonos';
|
|
17
|
+
|
|
18
|
+
async function main() {
|
|
19
|
+
const client = new SonosClient('192.168.1.50'); // IP of any Sonos player
|
|
20
|
+
await client.connect();
|
|
21
|
+
|
|
22
|
+
// Listen for group/player updates
|
|
23
|
+
client.subscribe((evt) => console.log(evt.eventType, evt.objectId));
|
|
24
|
+
|
|
25
|
+
// Start websocket + initial sync (blocks until socket closes)
|
|
26
|
+
await client.start();
|
|
27
|
+
|
|
28
|
+
// Access player + groups
|
|
29
|
+
const player = client.player;
|
|
30
|
+
const [group] = client.groups;
|
|
31
|
+
await group.play();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
void main();
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Opties
|
|
38
|
+
|
|
39
|
+
`SonosClient` accepteert optionele betrouwbaarheidsettings:
|
|
40
|
+
|
|
41
|
+
- `heartbeatIntervalMs` (default 30000)
|
|
42
|
+
- `retryDelayMs` (default 2000) + `retryJitterMs` (default 500)
|
|
43
|
+
- `maxReconnects` (default onbeperkt)
|
|
44
|
+
|
|
45
|
+
## Features
|
|
46
|
+
|
|
47
|
+
- Local Sonos WebSocket client (token-based TLS)
|
|
48
|
+
- Group + player state sync with event callbacks
|
|
49
|
+
- Playback controls: play/pause/seek/skip, play modes, line-in, cloud queue/stream
|
|
50
|
+
- Group management: create/modify membership
|
|
51
|
+
- Volume controls for player + group, duck/unduck
|
|
52
|
+
- Audio clips + home theater helper
|
|
53
|
+
|
|
54
|
+
## Notes
|
|
55
|
+
|
|
56
|
+
- The local API uses a self-signed TLS certificate; the client disables certificate validation for this connection, matching the official behavior.
|
|
57
|
+
- Only one player connection is handled per client instance (per Sonos requirements). Create multiple clients for multiple players.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.SonosPlayer = exports.SonosGroup = exports.SonosClient = void 0;
|
|
18
|
+
var client_1 = require("./sonos/client");
|
|
19
|
+
Object.defineProperty(exports, "SonosClient", { enumerable: true, get: function () { return client_1.SonosClient; } });
|
|
20
|
+
var group_1 = require("./sonos/group");
|
|
21
|
+
Object.defineProperty(exports, "SonosGroup", { enumerable: true, get: function () { return group_1.SonosGroup; } });
|
|
22
|
+
var player_1 = require("./sonos/player");
|
|
23
|
+
Object.defineProperty(exports, "SonosPlayer", { enumerable: true, get: function () { return player_1.SonosPlayer; } });
|
|
24
|
+
__exportStar(require("./sonos/models"), exports);
|
|
25
|
+
__exportStar(require("./sonos/types"), exports);
|
|
26
|
+
__exportStar(require("./sonos/constants"), exports);
|
|
27
|
+
__exportStar(require("./sonos/errors"), exports);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"module"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SonosNamespace = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Base helper for namespace handlers.
|
|
6
|
+
*/
|
|
7
|
+
class SonosNamespace {
|
|
8
|
+
api;
|
|
9
|
+
namespace;
|
|
10
|
+
eventKey;
|
|
11
|
+
listeners = new Map();
|
|
12
|
+
eventType;
|
|
13
|
+
constructor(api, namespace, eventType, eventKey) {
|
|
14
|
+
this.api = api;
|
|
15
|
+
this.namespace = namespace;
|
|
16
|
+
this.eventKey = eventKey;
|
|
17
|
+
this.eventType = eventType;
|
|
18
|
+
}
|
|
19
|
+
async handleSubscribe(id, callback) {
|
|
20
|
+
if (this.listeners.has(id)) {
|
|
21
|
+
this.api.logger.error(`Duplicate subscription detected for ${id}`);
|
|
22
|
+
}
|
|
23
|
+
await this.api.sendCommand(this.namespace, 'subscribe', undefined, { [this.eventKey]: id });
|
|
24
|
+
this.listeners.set(id, callback);
|
|
25
|
+
return () => {
|
|
26
|
+
this.listeners.delete(id);
|
|
27
|
+
this.api.sendCommandNoWait(this.namespace, 'unsubscribe', undefined, { [this.eventKey]: id });
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
handleEvent(event, eventData) {
|
|
31
|
+
const id = event[this.eventKey];
|
|
32
|
+
if (typeof id === 'string') {
|
|
33
|
+
const handler = this.listeners.get(id);
|
|
34
|
+
handler?.(eventData);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
exports.SonosNamespace = SonosNamespace;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AudioClipNamespace = void 0;
|
|
4
|
+
const namespace_1 = require("../namespace");
|
|
5
|
+
class AudioClipNamespace extends namespace_1.SonosNamespace {
|
|
6
|
+
constructor(api) {
|
|
7
|
+
super(api, 'audioClip', 'audioClip', 'playerId');
|
|
8
|
+
}
|
|
9
|
+
async loadAudioClip(playerId, options) {
|
|
10
|
+
return this.api.sendCommand(this.namespace, 'loadAudioClip', {
|
|
11
|
+
name: options.name,
|
|
12
|
+
appId: options.appId,
|
|
13
|
+
priority: options.priority,
|
|
14
|
+
clipType: options.clipType,
|
|
15
|
+
streamUrl: options.streamUrl,
|
|
16
|
+
httpAuthorization: options.httpAuthorization,
|
|
17
|
+
volume: options.volume,
|
|
18
|
+
clipLEDBehavior: options.clipLEDBehavior,
|
|
19
|
+
}, { playerId });
|
|
20
|
+
}
|
|
21
|
+
async subscribe(playerId, callback) {
|
|
22
|
+
return this.handleSubscribe(playerId, callback);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
exports.AudioClipNamespace = AudioClipNamespace;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GroupVolumeNamespace = void 0;
|
|
4
|
+
const namespace_1 = require("../namespace");
|
|
5
|
+
class GroupVolumeNamespace extends namespace_1.SonosNamespace {
|
|
6
|
+
constructor(api) {
|
|
7
|
+
super(api, 'groupVolume', 'groupVolume', 'groupId');
|
|
8
|
+
}
|
|
9
|
+
async setVolume(groupId, volume) {
|
|
10
|
+
await this.api.sendCommand(this.namespace, 'setVolume', { volume }, { groupId });
|
|
11
|
+
}
|
|
12
|
+
async getVolume(groupId) {
|
|
13
|
+
return this.api.sendCommand(this.namespace, 'getVolume', undefined, { groupId });
|
|
14
|
+
}
|
|
15
|
+
async setMute(groupId, muted) {
|
|
16
|
+
await this.api.sendCommand(this.namespace, 'setMute', { muted }, { groupId });
|
|
17
|
+
}
|
|
18
|
+
async setRelativeVolume(groupId, volumeDelta) {
|
|
19
|
+
await this.api.sendCommand(this.namespace, 'setRelativeVolume', { volumeDelta }, { groupId });
|
|
20
|
+
}
|
|
21
|
+
async subscribe(groupId, callback) {
|
|
22
|
+
return this.handleSubscribe(groupId, callback);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
exports.GroupVolumeNamespace = GroupVolumeNamespace;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GroupsNamespace = void 0;
|
|
4
|
+
const namespace_1 = require("../namespace");
|
|
5
|
+
class GroupsNamespace extends namespace_1.SonosNamespace {
|
|
6
|
+
constructor(api) {
|
|
7
|
+
super(api, 'groups', 'groups', 'householdId');
|
|
8
|
+
}
|
|
9
|
+
async modifyGroupMembers(groupId, playerIdsToAdd, playerIdsToRemove) {
|
|
10
|
+
return this.api.sendCommand(this.namespace, 'modifyGroupMembers', { playerIdsToAdd, playerIdsToRemove }, { groupId });
|
|
11
|
+
}
|
|
12
|
+
async setGroupMembers(groupId, playerIds, areaIds) {
|
|
13
|
+
const options = { playerIds };
|
|
14
|
+
if (areaIds)
|
|
15
|
+
options.areaIds = areaIds;
|
|
16
|
+
return this.api.sendCommand(this.namespace, 'setGroupMembers', options, { groupId });
|
|
17
|
+
}
|
|
18
|
+
async getGroups(householdId, includeDeviceInfo = false) {
|
|
19
|
+
return this.api.sendCommand(this.namespace, 'getGroups', { includeDeviceInfo }, { householdId });
|
|
20
|
+
}
|
|
21
|
+
async createGroup(householdId, playerIds, musicContextGroupId) {
|
|
22
|
+
const options = { playerIds };
|
|
23
|
+
if (musicContextGroupId)
|
|
24
|
+
options.musicContextGroupId = musicContextGroupId;
|
|
25
|
+
return this.api.sendCommand(this.namespace, 'createGroup', options, { householdId });
|
|
26
|
+
}
|
|
27
|
+
async subscribe(householdId, callback) {
|
|
28
|
+
return this.handleSubscribe(householdId, callback);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
exports.GroupsNamespace = GroupsNamespace;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HomeTheaterNamespace = void 0;
|
|
4
|
+
const namespace_1 = require("../namespace");
|
|
5
|
+
class HomeTheaterNamespace extends namespace_1.SonosNamespace {
|
|
6
|
+
constructor(api) {
|
|
7
|
+
super(api, 'homeTheater', 'homeTheaterStatus', 'playerId');
|
|
8
|
+
}
|
|
9
|
+
async loadHomeTheaterPlayback(playerId) {
|
|
10
|
+
await this.api.sendCommand(this.namespace, 'loadHomeTheaterPlayback', undefined, { playerId });
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
exports.HomeTheaterNamespace = HomeTheaterNamespace;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PlaybackNamespace = void 0;
|
|
4
|
+
const namespace_1 = require("../namespace");
|
|
5
|
+
class PlaybackNamespace extends namespace_1.SonosNamespace {
|
|
6
|
+
constructor(api) {
|
|
7
|
+
super(api, 'playback', 'playbackStatus', 'groupId');
|
|
8
|
+
}
|
|
9
|
+
async getPlaybackStatus(groupId) {
|
|
10
|
+
return this.api.sendCommand(this.namespace, 'getPlaybackStatus', undefined, { groupId });
|
|
11
|
+
}
|
|
12
|
+
async loadLineIn(groupId, deviceId, playOnCompletion = false) {
|
|
13
|
+
const options = {};
|
|
14
|
+
if (deviceId)
|
|
15
|
+
options.deviceId = deviceId;
|
|
16
|
+
options.playOnCompletion = playOnCompletion;
|
|
17
|
+
await this.api.sendCommand(this.namespace, 'loadLineIn', options, { groupId });
|
|
18
|
+
}
|
|
19
|
+
async loadContent(groupId, content) {
|
|
20
|
+
await this.api.sendCommand(this.namespace, 'loadContent', content, { groupId });
|
|
21
|
+
}
|
|
22
|
+
async pause(groupId) {
|
|
23
|
+
await this.api.sendCommand(this.namespace, 'pause', undefined, { groupId });
|
|
24
|
+
}
|
|
25
|
+
async play(groupId) {
|
|
26
|
+
await this.api.sendCommand(this.namespace, 'play', undefined, { groupId });
|
|
27
|
+
}
|
|
28
|
+
async togglePlayPause(groupId) {
|
|
29
|
+
await this.api.sendCommand(this.namespace, 'togglePlayPause', undefined, { groupId });
|
|
30
|
+
}
|
|
31
|
+
async setPlayModes(groupId, playModes) {
|
|
32
|
+
await this.api.sendCommand(this.namespace, 'setPlayModes', { playModes }, { groupId });
|
|
33
|
+
}
|
|
34
|
+
async seek(groupId, positionMillis, itemId) {
|
|
35
|
+
const options = { positionMillis };
|
|
36
|
+
if (itemId)
|
|
37
|
+
options.itemId = itemId;
|
|
38
|
+
await this.api.sendCommand(this.namespace, 'seek', options, { groupId });
|
|
39
|
+
}
|
|
40
|
+
async seekRelative(groupId, deltaMillis, itemId) {
|
|
41
|
+
const options = { deltaMillis };
|
|
42
|
+
if (itemId)
|
|
43
|
+
options.itemId = itemId;
|
|
44
|
+
await this.api.sendCommand(this.namespace, 'seekRelative', options, { groupId });
|
|
45
|
+
}
|
|
46
|
+
async skipToNextTrack(groupId) {
|
|
47
|
+
await this.api.sendCommand(this.namespace, 'skipToNextTrack', undefined, { groupId });
|
|
48
|
+
}
|
|
49
|
+
async skipToPreviousTrack(groupId) {
|
|
50
|
+
await this.api.sendCommand(this.namespace, 'skipToPreviousTrack', undefined, { groupId });
|
|
51
|
+
}
|
|
52
|
+
async subscribe(groupId, callback) {
|
|
53
|
+
return this.handleSubscribe(groupId, callback);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
exports.PlaybackNamespace = PlaybackNamespace;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PlaybackMetadataNamespace = void 0;
|
|
4
|
+
const namespace_1 = require("../namespace");
|
|
5
|
+
class PlaybackMetadataNamespace extends namespace_1.SonosNamespace {
|
|
6
|
+
constructor(api) {
|
|
7
|
+
super(api, 'playbackMetadata', 'metadataStatus', 'groupId');
|
|
8
|
+
}
|
|
9
|
+
async getMetadataStatus(groupId) {
|
|
10
|
+
return this.api.sendCommand(this.namespace, 'getMetadataStatus', undefined, { groupId });
|
|
11
|
+
}
|
|
12
|
+
async subscribe(groupId, callback) {
|
|
13
|
+
return this.handleSubscribe(groupId, callback);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
exports.PlaybackMetadataNamespace = PlaybackMetadataNamespace;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PlaybackSessionNamespace = void 0;
|
|
4
|
+
const namespace_1 = require("../namespace");
|
|
5
|
+
class PlaybackSessionNamespace extends namespace_1.SonosNamespace {
|
|
6
|
+
constructor(api) {
|
|
7
|
+
super(api, 'playbackSession', 'playbackSession', 'sessionId');
|
|
8
|
+
}
|
|
9
|
+
async createSession(groupId, appId, appContext, accountId, customData) {
|
|
10
|
+
const options = { appId, appContext };
|
|
11
|
+
if (accountId)
|
|
12
|
+
options.accountId = accountId;
|
|
13
|
+
if (customData)
|
|
14
|
+
options.customData = customData;
|
|
15
|
+
return this.api.sendCommand(this.namespace, 'createSession', options, { groupId });
|
|
16
|
+
}
|
|
17
|
+
async loadCloudQueue(sessionId, queueBaseUrl, options) {
|
|
18
|
+
await this.api.sendCommand(this.namespace, 'loadCloudQueue', {
|
|
19
|
+
queueBaseUrl,
|
|
20
|
+
httpAuthorization: options.httpAuthorization,
|
|
21
|
+
useHttpAuthorizationForMedia: options.useHttpAuthorizationForMedia,
|
|
22
|
+
itemId: options.itemId,
|
|
23
|
+
queueVersion: options.queueVersion,
|
|
24
|
+
positionMillis: options.positionMillis,
|
|
25
|
+
playOnCompletion: options.playOnCompletion,
|
|
26
|
+
trackMetadata: options.trackMetadata,
|
|
27
|
+
}, { sessionId });
|
|
28
|
+
}
|
|
29
|
+
async loadStreamUrl(sessionId, streamUrl, options = {}) {
|
|
30
|
+
await this.api.sendCommand(this.namespace, 'loadStreamUrl', {
|
|
31
|
+
streamUrl,
|
|
32
|
+
playOnCompletion: options.playOnCompletion,
|
|
33
|
+
stationMetadata: options.stationMetadata,
|
|
34
|
+
itemId: options.itemId,
|
|
35
|
+
}, { sessionId });
|
|
36
|
+
}
|
|
37
|
+
async refreshCloudQueue(sessionId) {
|
|
38
|
+
await this.api.sendCommand(this.namespace, 'refreshCloudQueue', undefined, { sessionId });
|
|
39
|
+
}
|
|
40
|
+
async seek(sessionId, positionMillis, itemId) {
|
|
41
|
+
const options = { positionMillis };
|
|
42
|
+
if (itemId)
|
|
43
|
+
options.itemId = itemId;
|
|
44
|
+
await this.api.sendCommand(this.namespace, 'seek', options, { sessionId });
|
|
45
|
+
}
|
|
46
|
+
async seekRelative(sessionId, deltaMillis, itemId) {
|
|
47
|
+
const options = { deltaMillis };
|
|
48
|
+
if (itemId)
|
|
49
|
+
options.itemId = itemId;
|
|
50
|
+
await this.api.sendCommand(this.namespace, 'seekRelative', options, { sessionId });
|
|
51
|
+
}
|
|
52
|
+
async skipToItem(sessionId, itemId, options = {}) {
|
|
53
|
+
await this.api.sendCommand(this.namespace, 'skipToItem', {
|
|
54
|
+
itemId,
|
|
55
|
+
queueVersion: options.queueVersion,
|
|
56
|
+
positionMillis: options.positionMillis,
|
|
57
|
+
playOnCompletion: options.playOnCompletion,
|
|
58
|
+
}, { sessionId });
|
|
59
|
+
}
|
|
60
|
+
async suspend(sessionId, queueVersion) {
|
|
61
|
+
await this.api.sendCommand(this.namespace, 'suspend', queueVersion ? { queueVersion } : undefined, { sessionId });
|
|
62
|
+
}
|
|
63
|
+
async subscribe(sessionId, callback) {
|
|
64
|
+
return this.handleSubscribe(sessionId, callback);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
exports.PlaybackSessionNamespace = PlaybackSessionNamespace;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PlayerVolumeNamespace = void 0;
|
|
4
|
+
const namespace_1 = require("../namespace");
|
|
5
|
+
class PlayerVolumeNamespace extends namespace_1.SonosNamespace {
|
|
6
|
+
constructor(api) {
|
|
7
|
+
super(api, 'playerVolume', 'playerVolume', 'playerId');
|
|
8
|
+
}
|
|
9
|
+
async setVolume(playerId, volume, muted) {
|
|
10
|
+
const options = {};
|
|
11
|
+
if (typeof volume === 'number')
|
|
12
|
+
options.volume = volume;
|
|
13
|
+
if (typeof muted === 'boolean')
|
|
14
|
+
options.muted = muted;
|
|
15
|
+
await this.api.sendCommand(this.namespace, 'setVolume', options, { playerId });
|
|
16
|
+
}
|
|
17
|
+
async getVolume(playerId) {
|
|
18
|
+
return this.api.sendCommand(this.namespace, 'getVolume', undefined, { playerId });
|
|
19
|
+
}
|
|
20
|
+
async duck(playerId, durationMillis) {
|
|
21
|
+
await this.api.sendCommand(this.namespace, 'duck', durationMillis ? { durationMillis } : undefined, { playerId });
|
|
22
|
+
}
|
|
23
|
+
async unduck(playerId) {
|
|
24
|
+
await this.api.sendCommand(this.namespace, 'unduck', undefined, { playerId });
|
|
25
|
+
}
|
|
26
|
+
async setMute(playerId, muted) {
|
|
27
|
+
await this.api.sendCommand(this.namespace, 'setMute', { muted }, { playerId });
|
|
28
|
+
}
|
|
29
|
+
async setRelativeVolume(playerId, volumeDelta, muted) {
|
|
30
|
+
const options = {};
|
|
31
|
+
if (typeof volumeDelta === 'number')
|
|
32
|
+
options.volumeDelta = volumeDelta;
|
|
33
|
+
if (typeof muted === 'boolean')
|
|
34
|
+
options.muted = muted;
|
|
35
|
+
await this.api.sendCommand(this.namespace, 'setRelativeVolume', options, { playerId });
|
|
36
|
+
}
|
|
37
|
+
async subscribe(playerId, callback) {
|
|
38
|
+
return this.handleSubscribe(playerId, callback);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
exports.PlayerVolumeNamespace = PlayerVolumeNamespace;
|