@basmilius/apple-devices 0.9.15 → 0.9.17
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/dist/index.d.mts +24 -1
- package/dist/index.mjs +146 -40
- package/package.json +5 -5
package/dist/index.d.mts
CHANGED
|
@@ -14,6 +14,7 @@ declare class Player {
|
|
|
14
14
|
get nowPlayingInfo(): Proto.NowPlayingInfo | null;
|
|
15
15
|
get playbackQueue(): Proto.PlaybackQueue | null;
|
|
16
16
|
get playbackState(): Proto.PlaybackState_Enum;
|
|
17
|
+
get rawPlaybackState(): Proto.PlaybackState_Enum;
|
|
17
18
|
get playbackStateTimestamp(): number;
|
|
18
19
|
get supportedCommands(): Proto.CommandInfo[];
|
|
19
20
|
get title(): string;
|
|
@@ -33,10 +34,13 @@ declare class Player {
|
|
|
33
34
|
get elapsedTime(): number;
|
|
34
35
|
get currentItem(): Proto.ContentItem | null;
|
|
35
36
|
get currentItemMetadata(): Proto.ContentItemMetadata | null;
|
|
37
|
+
get artworkId(): string | null;
|
|
38
|
+
artworkUrl(width?: number, height?: number): string | null;
|
|
36
39
|
get currentItemArtwork(): Uint8Array | null;
|
|
37
40
|
get currentItemArtworkUrl(): string | null;
|
|
38
41
|
get currentItemLyrics(): Proto.LyricsItem | null;
|
|
39
42
|
constructor(identifier: string, displayName: string);
|
|
43
|
+
findCommand(command: Proto.Command): Proto.CommandInfo | null;
|
|
40
44
|
isCommandSupported(command: Proto.Command): boolean;
|
|
41
45
|
setNowPlayingInfo(nowPlayingInfo: Proto.NowPlayingInfo): void;
|
|
42
46
|
setPlaybackQueue(playbackQueue: Proto.PlaybackQueue): void;
|
|
@@ -72,6 +76,8 @@ declare class Client {
|
|
|
72
76
|
get shuffleMode(): Proto.ShuffleMode_Enum;
|
|
73
77
|
get repeatMode(): Proto.RepeatMode_Enum;
|
|
74
78
|
get elapsedTime(): number;
|
|
79
|
+
get artworkId(): string | null;
|
|
80
|
+
artworkUrl(width?: number, height?: number): string | null;
|
|
75
81
|
get currentItem(): Proto.ContentItem | null;
|
|
76
82
|
get currentItemMetadata(): Proto.ContentItemMetadata | null;
|
|
77
83
|
get currentItemArtwork(): Uint8Array | null;
|
|
@@ -82,7 +88,9 @@ declare class Client {
|
|
|
82
88
|
setActivePlayer(identifier: string): void;
|
|
83
89
|
removePlayer(identifier: string): void;
|
|
84
90
|
setDefaultSupportedCommands(supportedCommands: Proto.CommandInfo[]): void;
|
|
91
|
+
findCommand(command: Proto.Command): Proto.CommandInfo | null;
|
|
85
92
|
isCommandSupported(command: Proto.Command): boolean;
|
|
93
|
+
updateDisplayName(displayName: string): void;
|
|
86
94
|
}
|
|
87
95
|
//#endregion
|
|
88
96
|
//#region src/airplay/const.d.ts
|
|
@@ -91,6 +99,11 @@ declare const STATE_SUBSCRIBE_SYMBOL: unique symbol;
|
|
|
91
99
|
declare const STATE_UNSUBSCRIBE_SYMBOL: unique symbol;
|
|
92
100
|
//#endregion
|
|
93
101
|
//#region src/airplay/remote.d.ts
|
|
102
|
+
declare class SendCommandError extends Error {
|
|
103
|
+
readonly sendError: Proto.SendError_Enum;
|
|
104
|
+
readonly handlerReturnStatus: Proto.HandlerReturnStatus_Enum;
|
|
105
|
+
constructor(sendError: Proto.SendError_Enum, handlerReturnStatus: Proto.HandlerReturnStatus_Enum);
|
|
106
|
+
}
|
|
94
107
|
declare class export_default$1 {
|
|
95
108
|
#private;
|
|
96
109
|
constructor(device: export_default);
|
|
@@ -123,8 +136,18 @@ declare class export_default$1 {
|
|
|
123
136
|
commandSetShuffleMode(mode: Proto.ShuffleMode_Enum): Promise<void>;
|
|
124
137
|
commandSetRepeatMode(mode: Proto.RepeatMode_Enum): Promise<void>;
|
|
125
138
|
commandChangePlaybackRate(rate: number): Promise<void>;
|
|
139
|
+
commandAdvanceShuffleMode(): Promise<void>;
|
|
140
|
+
commandAdvanceRepeatMode(): Promise<void>;
|
|
141
|
+
commandBeginFastForward(): Promise<void>;
|
|
142
|
+
commandEndFastForward(): Promise<void>;
|
|
143
|
+
commandBeginRewind(): Promise<void>;
|
|
144
|
+
commandEndRewind(): Promise<void>;
|
|
126
145
|
commandNextChapter(): Promise<void>;
|
|
127
146
|
commandPreviousChapter(): Promise<void>;
|
|
147
|
+
commandLikeTrack(): Promise<void>;
|
|
148
|
+
commandDislikeTrack(): Promise<void>;
|
|
149
|
+
commandBookmarkTrack(): Promise<void>;
|
|
150
|
+
commandAddNowPlayingItemToLibrary(): Promise<void>;
|
|
128
151
|
tap(x: number, y: number, finger?: number): Promise<void>;
|
|
129
152
|
swipeUp(duration?: number): Promise<void>;
|
|
130
153
|
swipeDown(duration?: number): Promise<void>;
|
|
@@ -363,4 +386,4 @@ declare class export_default$6 extends export_default$8 {}
|
|
|
363
386
|
//#region src/model/homepod-mini.d.ts
|
|
364
387
|
declare class export_default$7 extends export_default$8 {}
|
|
365
388
|
//#endregion
|
|
366
|
-
export { PROTOCOL as AIRPLAY, Client as AirPlayClient, export_default as AirPlayDevice, Player as AirPlayPlayer, export_default$1 as AirPlayRemote, export_default$2 as AirPlayState, export_default$3 as AirPlayVolume, export_default$4 as AppleTV, PROTOCOL$1 as COMPANION_LINK, export_default$5 as CompanionLinkDevice, export_default$6 as HomePod, export_default$7 as HomePodMini };
|
|
389
|
+
export { PROTOCOL as AIRPLAY, Client as AirPlayClient, export_default as AirPlayDevice, Player as AirPlayPlayer, export_default$1 as AirPlayRemote, export_default$2 as AirPlayState, export_default$3 as AirPlayVolume, export_default$4 as AppleTV, PROTOCOL$1 as COMPANION_LINK, export_default$5 as CompanionLinkDevice, export_default$6 as HomePod, export_default$7 as HomePodMini, SendCommandError };
|
package/dist/index.mjs
CHANGED
|
@@ -30,6 +30,10 @@ var Player = class {
|
|
|
30
30
|
return this.#playbackQueue;
|
|
31
31
|
}
|
|
32
32
|
get playbackState() {
|
|
33
|
+
if (this.#playbackState === Proto.PlaybackState_Enum.Playing && this.playbackRate === 0) return Proto.PlaybackState_Enum.Paused;
|
|
34
|
+
return this.#playbackState;
|
|
35
|
+
}
|
|
36
|
+
get rawPlaybackState() {
|
|
33
37
|
return this.#playbackState;
|
|
34
38
|
}
|
|
35
39
|
get playbackStateTimestamp() {
|
|
@@ -83,8 +87,8 @@ var Player = class {
|
|
|
83
87
|
get elapsedTime() {
|
|
84
88
|
const npi = this.#nowPlayingInfo;
|
|
85
89
|
const meta = this.currentItemMetadata;
|
|
86
|
-
const npiValid = npi?.elapsedTime != null && npi.timestamp;
|
|
87
|
-
const metaValid = meta?.elapsedTime != null && meta.elapsedTimeTimestamp;
|
|
90
|
+
const npiValid = npi?.elapsedTime != null && npi.timestamp != null && npi.timestamp !== 0;
|
|
91
|
+
const metaValid = meta?.elapsedTime != null && meta.elapsedTimeTimestamp != null && meta.elapsedTimeTimestamp !== 0;
|
|
88
92
|
if (npiValid && metaValid) {
|
|
89
93
|
if (meta.elapsedTimeTimestamp > npi.timestamp) return extrapolateElapsed(meta.elapsedTime, meta.elapsedTimeTimestamp, meta.playbackRate);
|
|
90
94
|
return extrapolateElapsed(npi.elapsedTime, npi.timestamp, npi.playbackRate);
|
|
@@ -100,6 +104,25 @@ var Player = class {
|
|
|
100
104
|
get currentItemMetadata() {
|
|
101
105
|
return this.currentItem?.metadata ?? null;
|
|
102
106
|
}
|
|
107
|
+
get artworkId() {
|
|
108
|
+
const metadata = this.currentItemMetadata;
|
|
109
|
+
if (!metadata) return null;
|
|
110
|
+
if (!metadata.artworkAvailable && !metadata.artworkURL && !metadata.artworkIdentifier) return null;
|
|
111
|
+
if (metadata.artworkIdentifier) return metadata.artworkIdentifier;
|
|
112
|
+
if (metadata.contentIdentifier) return metadata.contentIdentifier;
|
|
113
|
+
return this.currentItem?.identifier ?? null;
|
|
114
|
+
}
|
|
115
|
+
artworkUrl(width = 600, height = -1) {
|
|
116
|
+
const metadata = this.currentItemMetadata;
|
|
117
|
+
if (metadata?.artworkURL) return metadata.artworkURL;
|
|
118
|
+
const item = this.currentItem;
|
|
119
|
+
if (item?.remoteArtworks.length > 0 && item.remoteArtworks[0].artworkURLString) return item.remoteArtworks[0].artworkURLString;
|
|
120
|
+
if (metadata?.artworkIdentifier) try {
|
|
121
|
+
const url = metadata.artworkIdentifier.replace("{w}", String(width < 1 ? 999999 : width)).replace("{h}", String(height < 1 ? 999999 : height)).replace("{c}", "bb").replace("{f}", "png");
|
|
122
|
+
if (url.startsWith("http://") || url.startsWith("https://")) return url;
|
|
123
|
+
} catch {}
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
103
126
|
get currentItemArtwork() {
|
|
104
127
|
const item = this.currentItem;
|
|
105
128
|
if (!item) return null;
|
|
@@ -108,11 +131,7 @@ var Player = class {
|
|
|
108
131
|
return null;
|
|
109
132
|
}
|
|
110
133
|
get currentItemArtworkUrl() {
|
|
111
|
-
|
|
112
|
-
if (metadata?.artworkURL) return metadata.artworkURL;
|
|
113
|
-
const item = this.currentItem;
|
|
114
|
-
if (item?.remoteArtworks.length > 0 && item.remoteArtworks[0].artworkURLString) return item.remoteArtworks[0].artworkURLString;
|
|
115
|
-
return null;
|
|
134
|
+
return this.artworkUrl();
|
|
116
135
|
}
|
|
117
136
|
get currentItemLyrics() {
|
|
118
137
|
return this.currentItem?.lyrics ?? null;
|
|
@@ -129,8 +148,12 @@ var Player = class {
|
|
|
129
148
|
this.#displayName = displayName;
|
|
130
149
|
this.#playbackState = Proto.PlaybackState_Enum.Unknown;
|
|
131
150
|
}
|
|
151
|
+
findCommand(command) {
|
|
152
|
+
return this.#supportedCommands.find((c) => c.command === command) ?? null;
|
|
153
|
+
}
|
|
132
154
|
isCommandSupported(command) {
|
|
133
|
-
|
|
155
|
+
const info = this.findCommand(command);
|
|
156
|
+
return info != null && info.enabled !== false;
|
|
134
157
|
}
|
|
135
158
|
setNowPlayingInfo(nowPlayingInfo) {
|
|
136
159
|
this.#nowPlayingInfo = nowPlayingInfo;
|
|
@@ -172,8 +195,7 @@ var Client = class {
|
|
|
172
195
|
return this.#players;
|
|
173
196
|
}
|
|
174
197
|
get activePlayer() {
|
|
175
|
-
|
|
176
|
-
return this.#players.get("MediaRemote-DefaultPlayer") ?? null;
|
|
198
|
+
return this.#players.get(this.#activePlayerId ?? "MediaRemote-DefaultPlayer") ?? null;
|
|
177
199
|
}
|
|
178
200
|
get nowPlayingInfo() {
|
|
179
201
|
return this.activePlayer?.nowPlayingInfo ?? null;
|
|
@@ -188,7 +210,13 @@ var Client = class {
|
|
|
188
210
|
return this.activePlayer?.playbackStateTimestamp ?? -1;
|
|
189
211
|
}
|
|
190
212
|
get supportedCommands() {
|
|
191
|
-
|
|
213
|
+
const playerCommands = this.activePlayer?.supportedCommands ?? [];
|
|
214
|
+
if (playerCommands.length === 0) return this.#defaultSupportedCommands;
|
|
215
|
+
if (this.#defaultSupportedCommands.length === 0) return playerCommands;
|
|
216
|
+
const playerCommandSet = new Set(playerCommands.map((c) => c.command));
|
|
217
|
+
const merged = [...playerCommands];
|
|
218
|
+
for (const cmd of this.#defaultSupportedCommands) if (!playerCommandSet.has(cmd.command)) merged.push(cmd);
|
|
219
|
+
return merged;
|
|
192
220
|
}
|
|
193
221
|
get title() {
|
|
194
222
|
return this.activePlayer?.title ?? "";
|
|
@@ -235,6 +263,12 @@ var Client = class {
|
|
|
235
263
|
get elapsedTime() {
|
|
236
264
|
return this.activePlayer?.elapsedTime ?? 0;
|
|
237
265
|
}
|
|
266
|
+
get artworkId() {
|
|
267
|
+
return this.activePlayer?.artworkId ?? null;
|
|
268
|
+
}
|
|
269
|
+
artworkUrl(width = 600, height = -1) {
|
|
270
|
+
return this.activePlayer?.artworkUrl(width, height) ?? null;
|
|
271
|
+
}
|
|
238
272
|
get currentItem() {
|
|
239
273
|
return this.activePlayer?.currentItem ?? null;
|
|
240
274
|
}
|
|
@@ -277,8 +311,17 @@ var Client = class {
|
|
|
277
311
|
setDefaultSupportedCommands(supportedCommands) {
|
|
278
312
|
this.#defaultSupportedCommands = supportedCommands;
|
|
279
313
|
}
|
|
314
|
+
findCommand(command) {
|
|
315
|
+
const playerCmd = this.activePlayer?.findCommand(command) ?? null;
|
|
316
|
+
if (playerCmd) return playerCmd;
|
|
317
|
+
return this.#defaultSupportedCommands.find((c) => c.command === command) ?? null;
|
|
318
|
+
}
|
|
280
319
|
isCommandSupported(command) {
|
|
281
|
-
|
|
320
|
+
const info = this.findCommand(command);
|
|
321
|
+
return info != null && info.enabled !== false;
|
|
322
|
+
}
|
|
323
|
+
updateDisplayName(displayName) {
|
|
324
|
+
this.#displayName = displayName;
|
|
282
325
|
}
|
|
283
326
|
};
|
|
284
327
|
|
|
@@ -291,6 +334,16 @@ const STATE_UNSUBSCRIBE_SYMBOL = Symbol("com.basmilius.airplay:unsubscribe");
|
|
|
291
334
|
|
|
292
335
|
//#endregion
|
|
293
336
|
//#region src/airplay/remote.ts
|
|
337
|
+
var SendCommandError = class extends Error {
|
|
338
|
+
sendError;
|
|
339
|
+
handlerReturnStatus;
|
|
340
|
+
constructor(sendError, handlerReturnStatus) {
|
|
341
|
+
super(`SendCommand failed: sendError=${Proto.SendError_Enum[sendError]}, handlerReturnStatus=${Proto.HandlerReturnStatus_Enum[handlerReturnStatus]}`);
|
|
342
|
+
this.name = "SendCommandError";
|
|
343
|
+
this.sendError = sendError;
|
|
344
|
+
this.handlerReturnStatus = handlerReturnStatus;
|
|
345
|
+
}
|
|
346
|
+
};
|
|
294
347
|
var remote_default = class {
|
|
295
348
|
get #dataStream() {
|
|
296
349
|
return this.#protocol.dataStream;
|
|
@@ -373,22 +426,40 @@ var remote_default = class {
|
|
|
373
426
|
await this.#sendCommand(Proto.Command.PreviousTrack);
|
|
374
427
|
}
|
|
375
428
|
async commandSkipForward(interval = 15) {
|
|
376
|
-
await this.#
|
|
429
|
+
await this.#sendCommandRaw(DataStreamMessage.sendCommandWithSkipInterval(Proto.Command.SkipForward, interval));
|
|
377
430
|
}
|
|
378
431
|
async commandSkipBackward(interval = 15) {
|
|
379
|
-
await this.#
|
|
432
|
+
await this.#sendCommandRaw(DataStreamMessage.sendCommandWithSkipInterval(Proto.Command.SkipBackward, interval));
|
|
380
433
|
}
|
|
381
434
|
async commandSeekToPosition(position) {
|
|
382
|
-
await this.#
|
|
435
|
+
await this.#sendCommandRaw(DataStreamMessage.sendCommandWithPlaybackPosition(Proto.Command.SeekToPlaybackPosition, position));
|
|
383
436
|
}
|
|
384
437
|
async commandSetShuffleMode(mode) {
|
|
385
|
-
await this.#
|
|
438
|
+
await this.#sendCommandRaw(DataStreamMessage.sendCommandWithShuffleMode(Proto.Command.ChangeShuffleMode, mode));
|
|
386
439
|
}
|
|
387
440
|
async commandSetRepeatMode(mode) {
|
|
388
|
-
await this.#
|
|
441
|
+
await this.#sendCommandRaw(DataStreamMessage.sendCommandWithRepeatMode(Proto.Command.ChangeRepeatMode, mode));
|
|
389
442
|
}
|
|
390
443
|
async commandChangePlaybackRate(rate) {
|
|
391
|
-
await this.#
|
|
444
|
+
await this.#sendCommandRaw(DataStreamMessage.sendCommandWithPlaybackRate(Proto.Command.ChangePlaybackRate, rate));
|
|
445
|
+
}
|
|
446
|
+
async commandAdvanceShuffleMode() {
|
|
447
|
+
await this.#sendCommand(Proto.Command.AdvanceShuffleMode);
|
|
448
|
+
}
|
|
449
|
+
async commandAdvanceRepeatMode() {
|
|
450
|
+
await this.#sendCommand(Proto.Command.AdvanceRepeatMode);
|
|
451
|
+
}
|
|
452
|
+
async commandBeginFastForward() {
|
|
453
|
+
await this.#sendCommand(Proto.Command.BeginFastForward);
|
|
454
|
+
}
|
|
455
|
+
async commandEndFastForward() {
|
|
456
|
+
await this.#sendCommand(Proto.Command.EndFastForward);
|
|
457
|
+
}
|
|
458
|
+
async commandBeginRewind() {
|
|
459
|
+
await this.#sendCommand(Proto.Command.BeginRewind);
|
|
460
|
+
}
|
|
461
|
+
async commandEndRewind() {
|
|
462
|
+
await this.#sendCommand(Proto.Command.EndRewind);
|
|
392
463
|
}
|
|
393
464
|
async commandNextChapter() {
|
|
394
465
|
await this.#sendCommand(Proto.Command.NextChapter);
|
|
@@ -396,6 +467,18 @@ var remote_default = class {
|
|
|
396
467
|
async commandPreviousChapter() {
|
|
397
468
|
await this.#sendCommand(Proto.Command.PreviousChapter);
|
|
398
469
|
}
|
|
470
|
+
async commandLikeTrack() {
|
|
471
|
+
await this.#sendCommand(Proto.Command.LikeTrack);
|
|
472
|
+
}
|
|
473
|
+
async commandDislikeTrack() {
|
|
474
|
+
await this.#sendCommand(Proto.Command.DislikeTrack);
|
|
475
|
+
}
|
|
476
|
+
async commandBookmarkTrack() {
|
|
477
|
+
await this.#sendCommand(Proto.Command.BookmarkTrack);
|
|
478
|
+
}
|
|
479
|
+
async commandAddNowPlayingItemToLibrary() {
|
|
480
|
+
await this.#sendCommand(Proto.Command.AddNowPlayingItemToLibrary);
|
|
481
|
+
}
|
|
399
482
|
async tap(x, y, finger = 1) {
|
|
400
483
|
await this.#sendTouch(x, y, 1, finger);
|
|
401
484
|
await waitFor(50);
|
|
@@ -429,7 +512,17 @@ var remote_default = class {
|
|
|
429
512
|
await this.#dataStream.exchange(DataStreamMessage.sendHIDEvent(usePage, usage, false));
|
|
430
513
|
}
|
|
431
514
|
async #sendCommand(command, options) {
|
|
432
|
-
await this.#dataStream.exchange(DataStreamMessage.sendCommand(command, options));
|
|
515
|
+
const response = await this.#dataStream.exchange(DataStreamMessage.sendCommand(command, options));
|
|
516
|
+
return this.#checkCommandResult(response);
|
|
517
|
+
}
|
|
518
|
+
async #sendCommandRaw(message) {
|
|
519
|
+
const response = await this.#dataStream.exchange(message);
|
|
520
|
+
return this.#checkCommandResult(response);
|
|
521
|
+
}
|
|
522
|
+
#checkCommandResult(response) {
|
|
523
|
+
const result = DataStreamMessage.getExtension(response, Proto.sendCommandResultMessage);
|
|
524
|
+
if (result.sendError !== Proto.SendError_Enum.NoError) throw new SendCommandError(result.sendError, result.handlerReturnStatus);
|
|
525
|
+
return result;
|
|
433
526
|
}
|
|
434
527
|
async #sendTouch(x, y, phase, finger) {
|
|
435
528
|
await this.#dataStream.exchange(DataStreamMessage.sendVirtualTouchEvent(x, y, phase, finger));
|
|
@@ -570,15 +663,11 @@ var state_default = class extends EventEmitter {
|
|
|
570
663
|
this.#volumeCapabilities = Proto.VolumeCapabilities_Enum.None;
|
|
571
664
|
}
|
|
572
665
|
onDeviceInfo(message) {
|
|
573
|
-
|
|
574
|
-
else if (message.deviceUID) this.#outputDeviceUID = message.deviceUID;
|
|
575
|
-
else if (message.uniqueIdentifier) this.#outputDeviceUID = message.uniqueIdentifier;
|
|
666
|
+
this.#updateOutputDeviceUID(message);
|
|
576
667
|
this.emit("deviceInfo", message);
|
|
577
668
|
}
|
|
578
669
|
onDeviceInfoUpdate(message) {
|
|
579
|
-
|
|
580
|
-
else if (message.deviceUID) this.#outputDeviceUID = message.deviceUID;
|
|
581
|
-
else if (message.uniqueIdentifier) this.#outputDeviceUID = message.uniqueIdentifier;
|
|
670
|
+
this.#updateOutputDeviceUID(message);
|
|
582
671
|
this.emit("deviceInfoUpdate", message);
|
|
583
672
|
}
|
|
584
673
|
onOriginClientProperties(message) {
|
|
@@ -608,6 +697,7 @@ var state_default = class extends EventEmitter {
|
|
|
608
697
|
}
|
|
609
698
|
onSetNowPlayingClient(message) {
|
|
610
699
|
this.#nowPlayingClientBundleIdentifier = message.client?.bundleIdentifier ?? null;
|
|
700
|
+
if (message.client?.bundleIdentifier && message.client?.displayName) this.#client(message.client.bundleIdentifier, message.client.displayName);
|
|
611
701
|
this.emit("setNowPlayingClient", message);
|
|
612
702
|
this.#emitNowPlayingChangedIfNeeded();
|
|
613
703
|
}
|
|
@@ -678,9 +768,15 @@ var state_default = class extends EventEmitter {
|
|
|
678
768
|
this.#volume = message.volume;
|
|
679
769
|
this.emit("volumeDidChange", message.volume);
|
|
680
770
|
}
|
|
771
|
+
#updateOutputDeviceUID(message) {
|
|
772
|
+
this.#outputDeviceUID = message.clusterID || message.deviceUID || message.uniqueIdentifier || null;
|
|
773
|
+
}
|
|
681
774
|
#client(bundleIdentifier, displayName) {
|
|
682
|
-
if (bundleIdentifier in this.#clients)
|
|
683
|
-
|
|
775
|
+
if (bundleIdentifier in this.#clients) {
|
|
776
|
+
const client = this.#clients[bundleIdentifier];
|
|
777
|
+
if (displayName) client.updateDisplayName(displayName);
|
|
778
|
+
return client;
|
|
779
|
+
} else {
|
|
684
780
|
const client = new Client(bundleIdentifier, displayName);
|
|
685
781
|
this.#clients[bundleIdentifier] = client;
|
|
686
782
|
this.emit("clients", this.#clients);
|
|
@@ -705,7 +801,10 @@ var state_default = class extends EventEmitter {
|
|
|
705
801
|
seriesName: player?.seriesName ?? "",
|
|
706
802
|
seasonNumber: player?.seasonNumber ?? 0,
|
|
707
803
|
episodeNumber: player?.episodeNumber ?? 0,
|
|
708
|
-
contentIdentifier: player?.contentIdentifier ?? ""
|
|
804
|
+
contentIdentifier: player?.contentIdentifier ?? "",
|
|
805
|
+
artworkId: player?.artworkId ?? null,
|
|
806
|
+
hasArtworkUrl: player?.artworkUrl() != null,
|
|
807
|
+
hasArtworkData: player?.currentItemArtwork != null
|
|
709
808
|
};
|
|
710
809
|
}
|
|
711
810
|
#emitNowPlayingChangedIfNeeded() {
|
|
@@ -717,7 +816,7 @@ var state_default = class extends EventEmitter {
|
|
|
717
816
|
this.emit("nowPlayingChanged", client, client?.activePlayer ?? null);
|
|
718
817
|
}
|
|
719
818
|
#snapshotsEqual(a, b) {
|
|
720
|
-
return a.bundleIdentifier === b.bundleIdentifier && a.playerIdentifier === b.playerIdentifier && a.playbackState === b.playbackState && a.title === b.title && a.artist === b.artist && a.album === b.album && a.genre === b.genre && a.duration === b.duration && a.shuffleMode === b.shuffleMode && a.repeatMode === b.repeatMode && a.mediaType === b.mediaType && a.seriesName === b.seriesName && a.seasonNumber === b.seasonNumber && a.episodeNumber === b.episodeNumber && a.contentIdentifier === b.contentIdentifier;
|
|
819
|
+
return a.bundleIdentifier === b.bundleIdentifier && a.playerIdentifier === b.playerIdentifier && a.playbackState === b.playbackState && a.title === b.title && a.artist === b.artist && a.album === b.album && a.genre === b.genre && a.duration === b.duration && a.shuffleMode === b.shuffleMode && a.repeatMode === b.repeatMode && a.mediaType === b.mediaType && a.seriesName === b.seriesName && a.seasonNumber === b.seasonNumber && a.episodeNumber === b.episodeNumber && a.contentIdentifier === b.contentIdentifier && a.artworkId === b.artworkId && a.hasArtworkUrl === b.hasArtworkUrl && a.hasArtworkData === b.hasArtworkData;
|
|
721
820
|
}
|
|
722
821
|
};
|
|
723
822
|
|
|
@@ -851,7 +950,9 @@ var device_default = class extends EventEmitter {
|
|
|
851
950
|
disconnectSafely() {
|
|
852
951
|
try {
|
|
853
952
|
this.disconnect();
|
|
854
|
-
} catch (
|
|
953
|
+
} catch (err) {
|
|
954
|
+
this.#protocol?.context?.logger?.warn("[device]", "Error during safe disconnect", err);
|
|
955
|
+
}
|
|
855
956
|
}
|
|
856
957
|
async addOutputDevices(deviceUIDs) {
|
|
857
958
|
await this.#protocol.dataStream.exchange(DataStreamMessage.modifyOutputContext(deviceUIDs));
|
|
@@ -900,21 +1001,26 @@ var device_default = class extends EventEmitter {
|
|
|
900
1001
|
this.#protocol.controlStream.enableEncryption(keys.accessoryToControllerKey, keys.controllerToAccessoryKey);
|
|
901
1002
|
this.#unsubscribe();
|
|
902
1003
|
if (this.#timingServer) this.#protocol.useTimingServer(this.#timingServer);
|
|
903
|
-
await this.#protocol.setupEventStream(keys.sharedSecret, keys.pairingId);
|
|
904
|
-
await this.#protocol.setupDataStream(keys.sharedSecret, () => this.#subscribe());
|
|
905
|
-
this.#protocol.dataStream.on("error", this.#onError.bind(this));
|
|
906
|
-
this.#protocol.dataStream.on("timeout", this.#onTimeout.bind(this));
|
|
907
|
-
this.#protocol.eventStream.on("error", this.#onError.bind(this));
|
|
908
|
-
this.#protocol.eventStream.on("timeout", this.#onTimeout.bind(this));
|
|
909
|
-
this.#feedbackInterval = setInterval(async () => await this.#feedback(), FEEDBACK_INTERVAL);
|
|
910
1004
|
try {
|
|
1005
|
+
await this.#protocol.setupEventStream(keys.sharedSecret, keys.pairingId);
|
|
1006
|
+
await this.#protocol.setupDataStream(keys.sharedSecret, () => this.#subscribe());
|
|
1007
|
+
this.#protocol.dataStream.on("error", this.#onError.bind(this));
|
|
1008
|
+
this.#protocol.dataStream.on("timeout", this.#onTimeout.bind(this));
|
|
1009
|
+
this.#protocol.eventStream.on("error", this.#onError.bind(this));
|
|
1010
|
+
this.#protocol.eventStream.on("timeout", this.#onTimeout.bind(this));
|
|
1011
|
+
if (this.#feedbackInterval) clearInterval(this.#feedbackInterval);
|
|
1012
|
+
this.#feedbackInterval = setInterval(async () => await this.#feedback(), FEEDBACK_INTERVAL);
|
|
911
1013
|
await this.#protocol.dataStream.exchange(DataStreamMessage.deviceInfo(keys.pairingId));
|
|
912
1014
|
await this.#protocol.dataStream.exchange(DataStreamMessage.setConnectionState());
|
|
913
1015
|
await this.#protocol.dataStream.exchange(DataStreamMessage.clientUpdatesConfig());
|
|
914
1016
|
this.#protocol.context.logger.info("Protocol ready.");
|
|
915
1017
|
} catch (err) {
|
|
916
|
-
|
|
917
|
-
|
|
1018
|
+
if (this.#feedbackInterval) {
|
|
1019
|
+
clearInterval(this.#feedbackInterval);
|
|
1020
|
+
this.#feedbackInterval = void 0;
|
|
1021
|
+
}
|
|
1022
|
+
this.#protocol.context.logger.error("[device]", "Setup failed, cleaning up", err);
|
|
1023
|
+
this.#protocol.disconnect();
|
|
918
1024
|
throw err;
|
|
919
1025
|
}
|
|
920
1026
|
}
|
|
@@ -1354,4 +1460,4 @@ var homepod_default = class extends homepod_base_default {};
|
|
|
1354
1460
|
var homepod_mini_default = class extends homepod_base_default {};
|
|
1355
1461
|
|
|
1356
1462
|
//#endregion
|
|
1357
|
-
export { PROTOCOL as AIRPLAY, Client as AirPlayClient, device_default as AirPlayDevice, Player as AirPlayPlayer, remote_default as AirPlayRemote, state_default as AirPlayState, volume_default as AirPlayVolume, apple_tv_default as AppleTV, PROTOCOL$1 as COMPANION_LINK, device_default$1 as CompanionLinkDevice, homepod_default as HomePod, homepod_mini_default as HomePodMini };
|
|
1463
|
+
export { PROTOCOL as AIRPLAY, Client as AirPlayClient, device_default as AirPlayDevice, Player as AirPlayPlayer, remote_default as AirPlayRemote, state_default as AirPlayState, volume_default as AirPlayVolume, apple_tv_default as AppleTV, PROTOCOL$1 as COMPANION_LINK, device_default$1 as CompanionLinkDevice, homepod_default as HomePod, homepod_mini_default as HomePodMini, SendCommandError };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@basmilius/apple-devices",
|
|
3
3
|
"description": "Exposes various Apple devices to connect with either AirPlay or Companion Link.",
|
|
4
|
-
"version": "0.9.
|
|
4
|
+
"version": "0.9.17",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"author": {
|
|
@@ -49,10 +49,10 @@
|
|
|
49
49
|
}
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@basmilius/apple-airplay": "0.9.
|
|
53
|
-
"@basmilius/apple-common": "0.9.
|
|
54
|
-
"@basmilius/apple-companion-link": "0.9.
|
|
55
|
-
"@basmilius/apple-encoding": "0.9.
|
|
52
|
+
"@basmilius/apple-airplay": "0.9.17",
|
|
53
|
+
"@basmilius/apple-common": "0.9.17",
|
|
54
|
+
"@basmilius/apple-companion-link": "0.9.17",
|
|
55
|
+
"@basmilius/apple-encoding": "0.9.17"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"@types/bun": "^1.3.11",
|