@basmilius/apple-airplay 0.10.0 → 0.11.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/dist/index.d.mts +763 -311
- package/dist/index.mjs +966 -366
- package/package.json +5 -5
package/dist/index.mjs
CHANGED
|
@@ -1,30 +1,195 @@
|
|
|
1
1
|
import { t as __exportAll } from "./chunk-DQk6qfdC.mjs";
|
|
2
|
+
import { AUDIO_BYTES_PER_CHANNEL, AUDIO_CHANNELS, AUDIO_FRAMES_PER_PACKET, AUDIO_SAMPLE_RATE, AccessoryPair, AccessoryVerify, ConnectionClosedError, Context, EncryptionAwareConnection, EncryptionError, EncryptionState, HTTP_TIMEOUT, PairingError, PlaybackError, SENDER_FEATURES_AUDIO, SENDER_FEATURES_REMOTE_CONTROL, SetupError, TimeoutError, deriveEncryptionKeys, describeFlags, generateActiveRemoteId, generateDacpId, generateSessionId, getMacAddress, hasFeatureFlag, randomInt32, randomInt64, uint16ToBE, uuid, waitFor } from "@basmilius/apple-common";
|
|
2
3
|
import { randomBytes } from "node:crypto";
|
|
3
4
|
import { createSocket } from "node:dgram";
|
|
4
|
-
import { AccessoryPair, AccessoryVerify, ConnectionClosedError, Context, EncryptionAwareConnection, EncryptionError, EncryptionState, HTTP_TIMEOUT, PairingError, PlaybackError, SetupError, TimeoutError, generateActiveRemoteId, generateDacpId, generateSessionId, getMacAddress, randomInt32, randomInt64, uint16ToBE, uuid, waitFor } from "@basmilius/apple-common";
|
|
5
5
|
import { NTP, Plist } from "@basmilius/apple-encoding";
|
|
6
|
-
import { Chacha20
|
|
6
|
+
import { Chacha20 } from "@basmilius/apple-encryption";
|
|
7
7
|
import { RtspClient, buildResponse, parseRequest } from "@basmilius/apple-rtsp";
|
|
8
8
|
|
|
9
|
+
//#region src/latencyManager.ts
|
|
10
|
+
/**
|
|
11
|
+
* Dynamic latency manager for AirPlay audio streaming.
|
|
12
|
+
*
|
|
13
|
+
* Implements a tier-based latency system inspired by Apple's DynamicLatencyManager.
|
|
14
|
+
* Monitors audio glitches (packet loss, late arrivals) and adjusts the latency
|
|
15
|
+
* tier accordingly: glitches increase latency, stable periods decrease it.
|
|
16
|
+
*/
|
|
17
|
+
/** Available latency tiers in ascending order (as fractions of sample rate). */
|
|
18
|
+
const LATENCY_TIERS = [
|
|
19
|
+
.25,
|
|
20
|
+
.5,
|
|
21
|
+
1,
|
|
22
|
+
2
|
|
23
|
+
];
|
|
24
|
+
/** Number of consecutive successful packets needed to drop one latency tier. */
|
|
25
|
+
const STABILITY_THRESHOLD = 500;
|
|
26
|
+
/** Number of glitches within the glitch window that trigger a tier increase. */
|
|
27
|
+
const GLITCH_THRESHOLD = 3;
|
|
28
|
+
/** Time window in milliseconds for counting glitches. */
|
|
29
|
+
const GLITCH_WINDOW_MS = 5e3;
|
|
30
|
+
/**
|
|
31
|
+
* Manages dynamic latency for an audio stream.
|
|
32
|
+
*
|
|
33
|
+
* Usage:
|
|
34
|
+
* 1. Create with `new LatencyManager(sampleRate)`
|
|
35
|
+
* 2. Call `getLatency()` to get the current latency in samples
|
|
36
|
+
* 3. Call `reportSuccess()` after each successful packet
|
|
37
|
+
* 4. Call `reportGlitch()` when a glitch is detected (packet loss, NACK, late arrival)
|
|
38
|
+
* 5. The manager automatically adjusts the latency tier
|
|
39
|
+
*/
|
|
40
|
+
var LatencyManager = class {
|
|
41
|
+
#sampleRate;
|
|
42
|
+
#tierIndex = 0;
|
|
43
|
+
#consecutiveSuccesses = 0;
|
|
44
|
+
#glitchTimestamps = [];
|
|
45
|
+
/**
|
|
46
|
+
* Creates a new LatencyManager.
|
|
47
|
+
*
|
|
48
|
+
* @param sampleRate - The audio sample rate in Hz (e.g. 44100, 48000).
|
|
49
|
+
* @param initialTierIndex - Starting tier index (defaults to 0, lowest latency).
|
|
50
|
+
*/
|
|
51
|
+
constructor(sampleRate, initialTierIndex = 0) {
|
|
52
|
+
this.#sampleRate = sampleRate;
|
|
53
|
+
this.#tierIndex = Math.min(Math.max(0, initialTierIndex), LATENCY_TIERS.length - 1);
|
|
54
|
+
}
|
|
55
|
+
/** Current latency tier index (0 = lowest latency, 3 = highest). */
|
|
56
|
+
get tierIndex() {
|
|
57
|
+
return this.#tierIndex;
|
|
58
|
+
}
|
|
59
|
+
/** Current latency in samples. */
|
|
60
|
+
get latency() {
|
|
61
|
+
return Math.round(this.#sampleRate * LATENCY_TIERS[this.#tierIndex]);
|
|
62
|
+
}
|
|
63
|
+
/** Current latency in milliseconds. */
|
|
64
|
+
get latencyMs() {
|
|
65
|
+
return Math.round(LATENCY_TIERS[this.#tierIndex] * 1e3);
|
|
66
|
+
}
|
|
67
|
+
/** Whether the manager is at the maximum latency tier. */
|
|
68
|
+
get isMaxTier() {
|
|
69
|
+
return this.#tierIndex >= LATENCY_TIERS.length - 1;
|
|
70
|
+
}
|
|
71
|
+
/** Whether the manager is at the minimum latency tier. */
|
|
72
|
+
get isMinTier() {
|
|
73
|
+
return this.#tierIndex <= 0;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Returns the current latency in samples.
|
|
77
|
+
* Alias for the `latency` getter for use in streaming loops.
|
|
78
|
+
*/
|
|
79
|
+
getLatency() {
|
|
80
|
+
return this.latency;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Reports a successfully sent and acknowledged packet.
|
|
84
|
+
* After enough consecutive successes, drops to a lower latency tier.
|
|
85
|
+
*/
|
|
86
|
+
reportSuccess() {
|
|
87
|
+
this.#consecutiveSuccesses++;
|
|
88
|
+
if (this.#consecutiveSuccesses >= STABILITY_THRESHOLD && !this.isMinTier) {
|
|
89
|
+
this.#tierIndex--;
|
|
90
|
+
this.#consecutiveSuccesses = 0;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Reports a glitch (packet loss, retransmission request, late arrival).
|
|
95
|
+
* If enough glitches occur within the time window, increases the latency tier.
|
|
96
|
+
*/
|
|
97
|
+
reportGlitch() {
|
|
98
|
+
this.#consecutiveSuccesses = 0;
|
|
99
|
+
const now = Date.now();
|
|
100
|
+
this.#glitchTimestamps.push(now);
|
|
101
|
+
const windowStart = now - GLITCH_WINDOW_MS;
|
|
102
|
+
this.#glitchTimestamps = this.#glitchTimestamps.filter((ts) => ts >= windowStart);
|
|
103
|
+
if (this.#glitchTimestamps.length >= GLITCH_THRESHOLD && !this.isMaxTier) {
|
|
104
|
+
this.#tierIndex++;
|
|
105
|
+
this.#glitchTimestamps = [];
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Returns the recommended RFC 2198 redundancy level based on the current latency tier.
|
|
110
|
+
* Higher latency tiers (more glitches) recommend more redundancy.
|
|
111
|
+
*/
|
|
112
|
+
get recommendedRedundancy() {
|
|
113
|
+
if (this.#tierIndex >= 2) return 3;
|
|
114
|
+
if (this.#tierIndex >= 1) return 2;
|
|
115
|
+
return 1;
|
|
116
|
+
}
|
|
117
|
+
/** Resets the manager to the initial (lowest) latency tier. */
|
|
118
|
+
reset() {
|
|
119
|
+
this.#tierIndex = 0;
|
|
120
|
+
this.#consecutiveSuccesses = 0;
|
|
121
|
+
this.#glitchTimestamps = [];
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
//#endregion
|
|
126
|
+
//#region src/streamTiming.ts
|
|
127
|
+
/** Maximum number of extra packets to send when catching up from being behind schedule. */
|
|
128
|
+
const MAX_PACKETS_COMPENSATE = 3;
|
|
129
|
+
/** Number of consecutive slow packets before logging a warning. */
|
|
130
|
+
const SLOW_WARNING_THRESHOLD = 5;
|
|
131
|
+
/**
|
|
132
|
+
* Runs a real-time audio streaming loop with wall-clock timing compensation.
|
|
133
|
+
*
|
|
134
|
+
* Reads and sends packets via the provided {@link sendPacket} callback, pacing
|
|
135
|
+
* them to match real-time playback. When the loop falls behind schedule, it
|
|
136
|
+
* sends up to {@link MAX_PACKETS_COMPENSATE} extra packets per cycle to catch
|
|
137
|
+
* up. Logs progress every 100 packets and warns when consistently behind.
|
|
138
|
+
*
|
|
139
|
+
* @param sendPacket - Callback that sends one packet and returns frames sent (0 = done).
|
|
140
|
+
* @param options - Timing configuration (sample rate, logger, log prefix).
|
|
141
|
+
* @returns Total number of packets sent.
|
|
142
|
+
*/
|
|
143
|
+
async function streamWithTiming(sendPacket, options) {
|
|
144
|
+
const { sampleRate, logger, logPrefix } = options;
|
|
145
|
+
let firstPacket = true;
|
|
146
|
+
let packetCount = 0;
|
|
147
|
+
let slowCount = 0;
|
|
148
|
+
let totalFrames = 0;
|
|
149
|
+
const startTime = performance.now();
|
|
150
|
+
while (true) {
|
|
151
|
+
const framesSent = await sendPacket(firstPacket);
|
|
152
|
+
if (framesSent === 0) {
|
|
153
|
+
logger.debug(logPrefix, `End of stream after ${packetCount} packets`);
|
|
154
|
+
break;
|
|
155
|
+
}
|
|
156
|
+
totalFrames += framesSent;
|
|
157
|
+
packetCount++;
|
|
158
|
+
firstPacket = false;
|
|
159
|
+
if (packetCount % 100 === 0) logger.debug(logPrefix, `Sent ${packetCount} packets, ${totalFrames} frames`);
|
|
160
|
+
const sleepTime = totalFrames / sampleRate * 1e3 - (performance.now() - startTime);
|
|
161
|
+
if (sleepTime > 0) {
|
|
162
|
+
slowCount = 0;
|
|
163
|
+
await waitFor(sleepTime);
|
|
164
|
+
} else {
|
|
165
|
+
const framesBehind = Math.floor(-sleepTime / 1e3 * sampleRate);
|
|
166
|
+
if (framesBehind >= AUDIO_FRAMES_PER_PACKET) {
|
|
167
|
+
const extraPackets = Math.min(Math.floor(framesBehind / AUDIO_FRAMES_PER_PACKET), MAX_PACKETS_COMPENSATE);
|
|
168
|
+
for (let idx = 0; idx < extraPackets; idx++) {
|
|
169
|
+
const extra = await sendPacket(false);
|
|
170
|
+
if (extra === 0) break;
|
|
171
|
+
totalFrames += extra;
|
|
172
|
+
packetCount++;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
slowCount++;
|
|
176
|
+
if (slowCount >= SLOW_WARNING_THRESHOLD) {
|
|
177
|
+
logger.warn(logPrefix, `Stream behind schedule (${slowCount} consecutive, ${Math.abs(sleepTime).toFixed(1)}ms behind)`);
|
|
178
|
+
slowCount = 0;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
return packetCount;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
//#endregion
|
|
9
186
|
//#region src/audioStream.ts
|
|
10
|
-
/** Default sample rate for audio streaming (CD quality). */
|
|
11
|
-
const SAMPLE_RATE = 44100;
|
|
12
|
-
/** Number of audio channels (stereo). */
|
|
13
|
-
const CHANNELS = 2;
|
|
14
|
-
/** Bytes per sample per channel (16-bit PCM). */
|
|
15
|
-
const BYTES_PER_CHANNEL = 2;
|
|
16
|
-
/** Number of audio frames per RTP packet. Matches Apple's ALAC/PCM packet size. */
|
|
17
|
-
const FRAMES_PER_PACKET = 352;
|
|
18
187
|
/** Maximum number of packets to keep in the retransmission backlog. */
|
|
19
188
|
const PACKET_BACKLOG_SIZE = 1e3;
|
|
20
189
|
/** Interval in milliseconds between RTCP sync packets. */
|
|
21
190
|
const SYNC_INTERVAL = 1e3;
|
|
22
|
-
/**
|
|
23
|
-
const
|
|
24
|
-
/** Number of consecutive slow packets before logging a warning. */
|
|
25
|
-
const SLOW_WARNING_THRESHOLD$1 = 5;
|
|
26
|
-
/** Number of previous frames to include as RFC 2198 redundancy (0 = disabled). */
|
|
27
|
-
const REDUNDANCY_COUNT = 0;
|
|
191
|
+
/** Default number of previous frames to include as RFC 2198 redundancy (0 = disabled). */
|
|
192
|
+
const DEFAULT_REDUNDANCY_COUNT = 0;
|
|
28
193
|
/**
|
|
29
194
|
* Audio compression type values for the `ct` field in the SETUP request body.
|
|
30
195
|
*
|
|
@@ -64,14 +229,21 @@ const AudioFormat = {
|
|
|
64
229
|
AAC_LC_44100_2: 131072,
|
|
65
230
|
AAC_ELD_44100_2: 262144,
|
|
66
231
|
AAC_ELD_16000_1: 1048576,
|
|
232
|
+
AAC_ELD_24000_1: 2097152,
|
|
67
233
|
ALAC_44100_16_2: 4194304,
|
|
68
|
-
ALAC_44100_24_2: 8388608
|
|
234
|
+
ALAC_44100_24_2: 8388608,
|
|
235
|
+
AAC_ELD_32000_1: 16777216,
|
|
236
|
+
AAC_ELD_48000_1: 33554432,
|
|
237
|
+
AAC_ELD_48000_2: 67108864,
|
|
238
|
+
ALAC_48000_16_2: 134217728,
|
|
239
|
+
ALAC_48000_24_2: 268435456,
|
|
240
|
+
AAC_LC_48000_2: 536870912
|
|
69
241
|
};
|
|
70
242
|
/**
|
|
71
243
|
* Convert an RTP timestamp to a wall-clock NTP timestamp.
|
|
72
244
|
*
|
|
73
245
|
* Uses a fixed anchor point established when the stream starts: at that moment
|
|
74
|
-
* we record both the RTP timestamp and the wall-clock NTP time. For
|
|
246
|
+
* we record both the RTP timestamp and the wall-clock NTP time. For further
|
|
75
247
|
* packets we compute the elapsed time from the RTP delta and add it to the
|
|
76
248
|
* anchor NTP time. This gives the receiver a real NTP timestamp it can use for
|
|
77
249
|
* multi-room synchronization.
|
|
@@ -97,12 +269,14 @@ const rtpToNtp = (rtpTimestamp, sampleRate, anchorRtp, anchorNtp) => {
|
|
|
97
269
|
* - ChaCha20-Poly1305 audio encryption with per-packet nonces
|
|
98
270
|
* - RTCP sync packets for receiver clock synchronization
|
|
99
271
|
* - Packet retransmission backlog for handling receiver NACK requests
|
|
100
|
-
* - RFC 2198 audio redundancy support (configurable via
|
|
272
|
+
* - RFC 2198 audio redundancy support (configurable via AudioStreamOptions)
|
|
101
273
|
* - Wall-clock-based timing to maintain real-time audio pace
|
|
102
274
|
*/
|
|
103
275
|
var AudioStream = class {
|
|
104
276
|
#protocol;
|
|
105
277
|
#context;
|
|
278
|
+
/** Configurable RFC 2198 redundancy count (0 = disabled). */
|
|
279
|
+
#redundancyCount;
|
|
106
280
|
/** Local RTCP control port. */
|
|
107
281
|
#controlPort = 0;
|
|
108
282
|
/** UDP socket for RTCP control messages (sync, retransmit requests). */
|
|
@@ -114,9 +288,9 @@ var AudioStream = class {
|
|
|
114
288
|
/** Connected UDP socket for sending RTP audio packets. */
|
|
115
289
|
#dataSocket;
|
|
116
290
|
/** Negotiated bytes per channel from format negotiation. */
|
|
117
|
-
#negotiatedBytesPerChannel =
|
|
291
|
+
#negotiatedBytesPerChannel = AUDIO_BYTES_PER_CHANNEL;
|
|
118
292
|
/** Negotiated sample rate from format negotiation. */
|
|
119
|
-
#negotiatedSampleRate =
|
|
293
|
+
#negotiatedSampleRate = AUDIO_SAMPLE_RATE;
|
|
120
294
|
/** RTP timestamp at the anchor point for NTP conversion. */
|
|
121
295
|
#anchorRtp = 0;
|
|
122
296
|
/** NTP timestamp at the anchor point for RTP-to-NTP conversion. */
|
|
@@ -133,12 +307,35 @@ var AudioStream = class {
|
|
|
133
307
|
#syncInterval;
|
|
134
308
|
/** Mutable stream state (RTP counters, timing, etc.). */
|
|
135
309
|
#streamContext;
|
|
310
|
+
/** Dynamic latency manager for adaptive latency control. */
|
|
311
|
+
#latencyManager;
|
|
312
|
+
/** Monotonic encryption counter for ChaCha20 nonce (independent of RTP sequence). */
|
|
313
|
+
#encryptionCounter = 0;
|
|
314
|
+
/** Streaming statistics for feedback and adaptive redundancy. */
|
|
315
|
+
#packetsSent = 0;
|
|
316
|
+
#retransmitRequests = 0;
|
|
317
|
+
#retransmitsFulfilled = 0;
|
|
318
|
+
#retransmitsFailed = 0;
|
|
319
|
+
#totalBytesSent = 0;
|
|
320
|
+
/** Current streaming statistics for feedback and adaptive redundancy. */
|
|
321
|
+
get stats() {
|
|
322
|
+
return {
|
|
323
|
+
packetsSent: this.#packetsSent,
|
|
324
|
+
retransmitRequests: this.#retransmitRequests,
|
|
325
|
+
retransmitsFulfilled: this.#retransmitsFulfilled,
|
|
326
|
+
retransmitsFailed: this.#retransmitsFailed,
|
|
327
|
+
packetLossRate: this.#packetsSent > 0 ? this.#retransmitRequests / this.#packetsSent : 0,
|
|
328
|
+
totalBytesSent: this.#totalBytesSent
|
|
329
|
+
};
|
|
330
|
+
}
|
|
136
331
|
/**
|
|
137
332
|
* @param protocol - The AirPlay protocol instance providing control stream and context.
|
|
333
|
+
* @param options - Optional configuration for redundancy and other settings.
|
|
138
334
|
*/
|
|
139
|
-
constructor(protocol) {
|
|
335
|
+
constructor(protocol, options) {
|
|
140
336
|
this.#protocol = protocol;
|
|
141
337
|
this.#context = protocol.context;
|
|
338
|
+
this.#redundancyCount = options?.redundancyCount ?? DEFAULT_REDUNDANCY_COUNT;
|
|
142
339
|
}
|
|
143
340
|
/**
|
|
144
341
|
* Performs RTSP SETUP to negotiate audio format and get port assignments.
|
|
@@ -169,9 +366,9 @@ var AudioStream = class {
|
|
|
169
366
|
const supportedFormats = this.#protocol.receiverInfo?.supportedAudioFormats;
|
|
170
367
|
let ct = CompressionType.PCM;
|
|
171
368
|
let audioFormat = AudioFormat.PCM_44100_24_2;
|
|
172
|
-
let sampleRate =
|
|
369
|
+
let sampleRate = AUDIO_SAMPLE_RATE;
|
|
173
370
|
if (supportedFormats) this.#context.logger.info("[audio]", `Receiver supported formats: 0x${supportedFormats.toString(16)}`);
|
|
174
|
-
let bytesPerChannel =
|
|
371
|
+
let bytesPerChannel = AUDIO_BYTES_PER_CHANNEL;
|
|
175
372
|
const setupBody = Plist.serialize({ streams: [{
|
|
176
373
|
audioFormat,
|
|
177
374
|
audioMode: "default",
|
|
@@ -181,12 +378,12 @@ var AudioStream = class {
|
|
|
181
378
|
latencyMax: sampleRate * 2,
|
|
182
379
|
latencyMin: Math.round(sampleRate * .25),
|
|
183
380
|
shk: shkArrayBuffer,
|
|
184
|
-
spf:
|
|
381
|
+
spf: AUDIO_FRAMES_PER_PACKET,
|
|
185
382
|
sr: sampleRate,
|
|
186
383
|
streamConnectionID,
|
|
187
384
|
supportsDynamicStreamID: false,
|
|
188
|
-
redundantAudio:
|
|
189
|
-
supportsRTPPacketRedundancy:
|
|
385
|
+
redundantAudio: this.#redundancyCount > 0,
|
|
386
|
+
supportsRTPPacketRedundancy: this.#redundancyCount > 0,
|
|
190
387
|
type: 96
|
|
191
388
|
}] });
|
|
192
389
|
this.#context.logger.debug("[audio]", "Sending audio stream SETUP...");
|
|
@@ -228,15 +425,16 @@ var AudioStream = class {
|
|
|
228
425
|
resolve();
|
|
229
426
|
});
|
|
230
427
|
});
|
|
231
|
-
const frameSize =
|
|
232
|
-
const packetSize =
|
|
233
|
-
|
|
428
|
+
const frameSize = AUDIO_CHANNELS * this.#negotiatedBytesPerChannel;
|
|
429
|
+
const packetSize = AUDIO_FRAMES_PER_PACKET * frameSize;
|
|
430
|
+
this.#latencyManager = new LatencyManager(this.#negotiatedSampleRate);
|
|
431
|
+
const latency = this.#latencyManager.getLatency();
|
|
234
432
|
const initialRtpTime = 0;
|
|
235
433
|
this.#anchorRtp = initialRtpTime;
|
|
236
434
|
this.#anchorNtp = NTP.now();
|
|
237
435
|
const ctx = {
|
|
238
436
|
sampleRate: this.#negotiatedSampleRate,
|
|
239
|
-
channels:
|
|
437
|
+
channels: AUDIO_CHANNELS,
|
|
240
438
|
bytesPerChannel: this.#negotiatedBytesPerChannel,
|
|
241
439
|
frameSize,
|
|
242
440
|
packetSize,
|
|
@@ -313,39 +511,12 @@ var AudioStream = class {
|
|
|
313
511
|
async stream(source, remoteAddress) {
|
|
314
512
|
const ctx = await this.prepare(remoteAddress);
|
|
315
513
|
try {
|
|
316
|
-
let firstPacket = true;
|
|
317
|
-
let packetCount = 0;
|
|
318
|
-
let slowCount = 0;
|
|
319
|
-
const startTime = performance.now();
|
|
320
514
|
this.#context.logger.info("[audio]", "Starting audio stream...");
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
packetCount++;
|
|
327
|
-
firstPacket = false;
|
|
328
|
-
if (packetCount % 100 === 0) this.#context.logger.debug("[audio]", `Sent ${packetCount} packets, ${ctx.totalFrames} frames`);
|
|
329
|
-
const sleepTime = ctx.totalFrames / ctx.sampleRate * 1e3 - (performance.now() - startTime);
|
|
330
|
-
if (sleepTime > 0) {
|
|
331
|
-
slowCount = 0;
|
|
332
|
-
await this.#sleep(sleepTime);
|
|
333
|
-
} else {
|
|
334
|
-
const framesBehind = Math.floor(-sleepTime / 1e3 * ctx.sampleRate);
|
|
335
|
-
if (framesBehind >= 352) {
|
|
336
|
-
const extraPackets = Math.min(Math.floor(framesBehind / 352), MAX_PACKETS_COMPENSATE$1);
|
|
337
|
-
for (let i = 0; i < extraPackets; i++) {
|
|
338
|
-
if (await this.#sendPacket(source, false, ctx) === 0) break;
|
|
339
|
-
packetCount++;
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
slowCount++;
|
|
343
|
-
if (slowCount >= SLOW_WARNING_THRESHOLD$1) {
|
|
344
|
-
this.#context.logger.warn("[audio]", `Stream is behind schedule (${slowCount} consecutive slow packets, ${Math.abs(sleepTime).toFixed(1)}ms behind)`);
|
|
345
|
-
slowCount = 0;
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
}
|
|
515
|
+
const packetCount = await streamWithTiming((firstPacket) => this.#sendPacket(source, firstPacket, ctx), {
|
|
516
|
+
sampleRate: ctx.sampleRate,
|
|
517
|
+
logger: this.#context.logger,
|
|
518
|
+
logPrefix: "[audio]"
|
|
519
|
+
});
|
|
349
520
|
this.#context.logger.info("[audio]", `Audio stream finished, sent ${packetCount} packets`);
|
|
350
521
|
this.#stopSync();
|
|
351
522
|
this.#context.logger.debug("[audio]", "Sending TEARDOWN...");
|
|
@@ -370,7 +541,7 @@ var AudioStream = class {
|
|
|
370
541
|
*/
|
|
371
542
|
async #sendPacket(source, firstPacket, ctx) {
|
|
372
543
|
if (ctx.paddingSent >= ctx.latency) return 0;
|
|
373
|
-
let frames = await source.readFrames(
|
|
544
|
+
let frames = await source.readFrames(AUDIO_FRAMES_PER_PACKET);
|
|
374
545
|
if (!frames || frames.length === 0) {
|
|
375
546
|
frames = Buffer.alloc(ctx.packetSize, 0);
|
|
376
547
|
ctx.paddingSent += Math.floor(frames.length / ctx.frameSize);
|
|
@@ -394,7 +565,7 @@ var AudioStream = class {
|
|
|
394
565
|
* @returns Promise resolving to the number of frames sent.
|
|
395
566
|
*/
|
|
396
567
|
#sendFrameBuffer(frames, firstPacket, ctx) {
|
|
397
|
-
const hasRedundancy =
|
|
568
|
+
const hasRedundancy = this.#redundancyCount > 0 && this.#previousFrames.length > 0;
|
|
398
569
|
const pt = hasRedundancy ? 97 : 96;
|
|
399
570
|
const rtpHeader = Buffer.allocUnsafe(12);
|
|
400
571
|
rtpHeader.writeUInt8(128, 0);
|
|
@@ -404,10 +575,10 @@ var AudioStream = class {
|
|
|
404
575
|
rtpHeader.writeUInt32BE(this.#ssrc, 8);
|
|
405
576
|
let audioPayload;
|
|
406
577
|
if (hasRedundancy) {
|
|
407
|
-
const redundantFrames = this.#previousFrames.slice(-
|
|
578
|
+
const redundantFrames = this.#previousFrames.slice(-this.#redundancyCount);
|
|
408
579
|
const headers = [];
|
|
409
580
|
for (let i = 0; i < redundantFrames.length; i++) {
|
|
410
|
-
const tsOffset = (redundantFrames.length - i) *
|
|
581
|
+
const tsOffset = (redundantFrames.length - i) * AUDIO_FRAMES_PER_PACKET;
|
|
411
582
|
const blockLen = redundantFrames[i].length;
|
|
412
583
|
const header = Buffer.allocUnsafe(4);
|
|
413
584
|
header[0] = 224;
|
|
@@ -424,16 +595,28 @@ var AudioStream = class {
|
|
|
424
595
|
]);
|
|
425
596
|
} else audioPayload = frames;
|
|
426
597
|
this.#previousFrames.push(Buffer.from(frames));
|
|
427
|
-
if (this.#previousFrames.length >
|
|
598
|
+
if (this.#previousFrames.length > this.#redundancyCount) this.#previousFrames.shift();
|
|
428
599
|
const aad = rtpHeader.subarray(4, 12);
|
|
429
|
-
const payload = this.#encryptAudio(audioPayload, aad,
|
|
600
|
+
const payload = this.#encryptAudio(audioPayload, aad, this.#encryptionCounter++);
|
|
430
601
|
const packet = Buffer.concat([rtpHeader, payload]);
|
|
431
602
|
this.#storePacket(ctx.rtpSeq, packet);
|
|
432
603
|
const framesSent = Math.floor(frames.length / ctx.frameSize);
|
|
433
604
|
ctx.rtpSeq = ctx.rtpSeq + 1 & 65535;
|
|
434
605
|
ctx.headTs = ctx.headTs + framesSent >>> 0;
|
|
435
606
|
ctx.totalFrames += framesSent;
|
|
436
|
-
return this.#send(packet).then(() =>
|
|
607
|
+
return this.#send(packet).then(() => {
|
|
608
|
+
this.#packetsSent++;
|
|
609
|
+
this.#totalBytesSent += packet.length;
|
|
610
|
+
this.#latencyManager?.reportSuccess();
|
|
611
|
+
if (this.#redundancyCount > 0 && this.#latencyManager && this.#packetsSent % 50 === 0) {
|
|
612
|
+
const recommended = this.#latencyManager.recommendedRedundancy;
|
|
613
|
+
if (recommended !== this.#redundancyCount) {
|
|
614
|
+
this.#context.logger.debug("[audio]", `Adjusting redundancy: ${this.#redundancyCount} → ${recommended}`);
|
|
615
|
+
this.#redundancyCount = recommended;
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
return framesSent;
|
|
619
|
+
});
|
|
437
620
|
}
|
|
438
621
|
/**
|
|
439
622
|
* Stores a sent packet in the retransmission backlog.
|
|
@@ -569,6 +752,8 @@ var AudioStream = class {
|
|
|
569
752
|
#retransmitPackets(data, addr) {
|
|
570
753
|
const lostSeqno = data.readUInt16BE(4);
|
|
571
754
|
const lostPackets = data.readUInt16BE(6);
|
|
755
|
+
this.#latencyManager?.reportGlitch();
|
|
756
|
+
this.#retransmitRequests += lostPackets;
|
|
572
757
|
for (let i = 0; i < lostPackets; i++) {
|
|
573
758
|
const seqno = lostSeqno + i & 65535;
|
|
574
759
|
const packet = this.#packetBacklog.get(seqno);
|
|
@@ -580,6 +765,7 @@ var AudioStream = class {
|
|
|
580
765
|
packet
|
|
581
766
|
]);
|
|
582
767
|
this.#controlSocket?.send(resp, addr.port, addr.address);
|
|
768
|
+
this.#retransmitsFulfilled++;
|
|
583
769
|
} else {
|
|
584
770
|
const seqBuf = Buffer.alloc(2);
|
|
585
771
|
seqBuf.writeUInt16BE(seqno);
|
|
@@ -589,6 +775,7 @@ var AudioStream = class {
|
|
|
589
775
|
Buffer.alloc(4)
|
|
590
776
|
]);
|
|
591
777
|
this.#controlSocket?.send(resp, addr.port, addr.address);
|
|
778
|
+
this.#retransmitsFailed++;
|
|
592
779
|
}
|
|
593
780
|
}
|
|
594
781
|
}
|
|
@@ -615,10 +802,6 @@ var AudioStream = class {
|
|
|
615
802
|
|
|
616
803
|
//#endregion
|
|
617
804
|
//#region src/audioMultiplexer.ts
|
|
618
|
-
/** Maximum number of extra packets to send when catching up from being behind schedule. */
|
|
619
|
-
const MAX_PACKETS_COMPENSATE = 3;
|
|
620
|
-
/** Number of consecutive slow packets before logging a warning. */
|
|
621
|
-
const SLOW_WARNING_THRESHOLD = 5;
|
|
622
805
|
/**
|
|
623
806
|
* Streams audio from a single source to multiple AirPlay devices simultaneously.
|
|
624
807
|
*
|
|
@@ -629,7 +812,8 @@ const SLOW_WARNING_THRESHOLD = 5;
|
|
|
629
812
|
*
|
|
630
813
|
* Timing is maintained by comparing wall-clock elapsed time against the expected
|
|
631
814
|
* time based on the number of frames sent. When falling behind, extra packets
|
|
632
|
-
* are sent to catch up
|
|
815
|
+
* are sent to catch up. Timing logic is shared with {@link AudioStream} via
|
|
816
|
+
* {@link streamWithTiming}.
|
|
633
817
|
*/
|
|
634
818
|
var AudioMultiplexer = class {
|
|
635
819
|
#context;
|
|
@@ -646,9 +830,10 @@ var AudioMultiplexer = class {
|
|
|
646
830
|
* Creates a new {@link AudioStream} for the device's protocol instance.
|
|
647
831
|
*
|
|
648
832
|
* @param protocol - The AirPlay protocol instance for the target device.
|
|
833
|
+
* @param options - Optional audio stream configuration (e.g. redundancy count).
|
|
649
834
|
*/
|
|
650
|
-
addTarget(protocol) {
|
|
651
|
-
const stream = new AudioStream(protocol);
|
|
835
|
+
addTarget(protocol, options) {
|
|
836
|
+
const stream = new AudioStream(protocol, options);
|
|
652
837
|
this.#targets.push({
|
|
653
838
|
protocol,
|
|
654
839
|
stream
|
|
@@ -666,7 +851,7 @@ var AudioMultiplexer = class {
|
|
|
666
851
|
*
|
|
667
852
|
* Orchestrates the full lifecycle: setup all streams, prepare (connect UDP,
|
|
668
853
|
* FLUSH, start sync), stream audio packets with timing compensation, and
|
|
669
|
-
* finish (padding
|
|
854
|
+
* finish (padding and TEARDOWN). On error, all streams are closed.
|
|
670
855
|
*
|
|
671
856
|
* @param source - Audio source to read PCM frames from.
|
|
672
857
|
* @throws Re-throws any error after cleaning up all streams.
|
|
@@ -683,18 +868,10 @@ var AudioMultiplexer = class {
|
|
|
683
868
|
const sampleRate = contexts[0].sampleRate;
|
|
684
869
|
const packetSize = contexts[0].packetSize;
|
|
685
870
|
try {
|
|
686
|
-
let firstPacket = true;
|
|
687
|
-
let packetCount = 0;
|
|
688
|
-
let slowCount = 0;
|
|
689
|
-
let totalFrames = 0;
|
|
690
|
-
const startTime = performance.now();
|
|
691
871
|
this.#context.logger.info("[multiplexer]", "Starting multi-room audio stream...");
|
|
692
|
-
|
|
693
|
-
let frames = await source.readFrames(
|
|
694
|
-
if (!frames || frames.length === 0)
|
|
695
|
-
this.#context.logger.debug("[multiplexer]", `End of source after ${packetCount} packets`);
|
|
696
|
-
break;
|
|
697
|
-
}
|
|
872
|
+
const sendPacket = async (firstPacket) => {
|
|
873
|
+
let frames = await source.readFrames(AUDIO_FRAMES_PER_PACKET);
|
|
874
|
+
if (!frames || frames.length === 0) return 0;
|
|
698
875
|
if (frames.length < packetSize) {
|
|
699
876
|
const padded = Buffer.alloc(packetSize, 0);
|
|
700
877
|
frames.copy(padded);
|
|
@@ -703,40 +880,13 @@ var AudioMultiplexer = class {
|
|
|
703
880
|
await Promise.all(this.#targets.map(async (target) => {
|
|
704
881
|
await target.stream.sendFrameData(frames, firstPacket);
|
|
705
882
|
}));
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
await this.#sleep(sleepTime);
|
|
714
|
-
} else {
|
|
715
|
-
const framesBehind = Math.floor(-sleepTime / 1e3 * sampleRate);
|
|
716
|
-
if (framesBehind >= 352) {
|
|
717
|
-
const extraPackets = Math.min(Math.floor(framesBehind / 352), MAX_PACKETS_COMPENSATE);
|
|
718
|
-
for (let i = 0; i < extraPackets; i++) {
|
|
719
|
-
let extraFrames = await source.readFrames(352);
|
|
720
|
-
if (!extraFrames || extraFrames.length === 0) break;
|
|
721
|
-
if (extraFrames.length < packetSize) {
|
|
722
|
-
const padded = Buffer.alloc(packetSize, 0);
|
|
723
|
-
extraFrames.copy(padded);
|
|
724
|
-
extraFrames = padded;
|
|
725
|
-
}
|
|
726
|
-
await Promise.all(this.#targets.map(async (target) => {
|
|
727
|
-
await target.stream.sendFrameData(extraFrames, false);
|
|
728
|
-
}));
|
|
729
|
-
totalFrames += 352;
|
|
730
|
-
packetCount++;
|
|
731
|
-
}
|
|
732
|
-
}
|
|
733
|
-
slowCount++;
|
|
734
|
-
if (slowCount >= SLOW_WARNING_THRESHOLD) {
|
|
735
|
-
this.#context.logger.warn("[multiplexer]", `Stream behind schedule (${slowCount} consecutive, ${Math.abs(sleepTime).toFixed(1)}ms behind)`);
|
|
736
|
-
slowCount = 0;
|
|
737
|
-
}
|
|
738
|
-
}
|
|
739
|
-
}
|
|
883
|
+
return AUDIO_FRAMES_PER_PACKET;
|
|
884
|
+
};
|
|
885
|
+
const packetCount = await streamWithTiming(sendPacket, {
|
|
886
|
+
sampleRate,
|
|
887
|
+
logger: this.#context.logger,
|
|
888
|
+
logPrefix: "[multiplexer]"
|
|
889
|
+
});
|
|
740
890
|
this.#context.logger.info("[multiplexer]", `Multi-room stream finished, sent ${packetCount} packets to ${this.#targets.length} device(s)`);
|
|
741
891
|
await Promise.all(this.#targets.map(async (target) => {
|
|
742
892
|
await target.stream.finish();
|
|
@@ -747,14 +897,6 @@ var AudioMultiplexer = class {
|
|
|
747
897
|
throw err;
|
|
748
898
|
}
|
|
749
899
|
}
|
|
750
|
-
/**
|
|
751
|
-
* Sleeps for the given number of milliseconds.
|
|
752
|
-
*
|
|
753
|
-
* @param ms - Duration to sleep in milliseconds.
|
|
754
|
-
*/
|
|
755
|
-
#sleep(ms) {
|
|
756
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
757
|
-
}
|
|
758
900
|
};
|
|
759
901
|
|
|
760
902
|
//#endregion
|
|
@@ -6587,7 +6729,7 @@ function assertExtendee(extension, message) {
|
|
|
6587
6729
|
/**
|
|
6588
6730
|
* Describes the file ProtocolMessage.proto.
|
|
6589
6731
|
*/
|
|
6590
|
-
const file_ProtocolMessage = /* @__PURE__ */ fileDesc("
|
|
6732
|
+
const file_ProtocolMessage = /* @__PURE__ */ fileDesc("ChVQcm90b2NvbE1lc3NhZ2UucHJvdG8i4RQKCUVycm9yQ29kZSLTFAoERW51bRILCgdOb0Vycm9yEAASEAoMVW5rbm93bkVycm9yEAESFAoQSW52YWxpZE9wZXJhdGlvbhACEhkKFU9wZXJhdGlvbk5vdFBlcm1pdHRlZBADEhYKEkNsaWVudERvZXNOb3RFeGlzdBAEEhYKEk9yaWdpbkRvZXNOb3RFeGlzdBAFEhgKFFVuc3VwcG9ydGVkT3BlcmF0aW9uEAYSGgoWRmFpbGVkVG9TZXRQaWNrZWRSb3V0ZRAHEiAKHEZhaWxlZFRvUmVnaXN0ZXJDdXN0b21PcmlnaW4QCBIeChpGYWlsZWRUb1JlbW92ZUN1c3RvbU9yaWdpbhAJEiYKIlRoZUFwcGxpY2F0aW9uQWN0aXZpdHlEb2VzTm90RXhpc3QQChIuCipUaGVBcHBIYXNOb3RTZXR1cEFCcm93c2FibGVDb250ZW50RW5kcG9pbnQQCxJBCj1UaGVSZXF1ZXN0ZWRCcm93c2FibGVDb250ZW50QXBpSXNOb3RTdXBwb3J0ZWRCeVRoZUFwcGxpY2F0aW9uEAwSMgouVGhlTm90ZmljYXRpb25IYXNOb3RCZWVuV2hpdGVsaXN0ZWRCeVRoZVNlcnZlchANEjgKNE9wZXJhdGlvblJlcXVpcmVzQUNsaWVudENhbGxiYWNrVG9IYXZlQmVlblJlZ2lzdGVyZWQQDhI6CjZPcGVyYXRpb25SZXF1aXJlc0FDbGllbnREYXRhU291cmNlVG9IYXZlQmVlblJlZ2lzdGVyZWQQDxI1CjFSZXF1ZXN0ZWREYXRhSXNPdXRPZkRhdGVBbmRTaG91bGRCZVJlcXVlc3RlZEFnYWluEBASMAosVGhlRGV2aWNlc0VuZm9yY2VkVm9sdW1lTGltaXRIYXNCZWVuRXhjZWVkZWQQERIbChdWb2x1bWVWYWx1ZUlzT3V0T2ZSYW5nZRASEiQKIFZvbHVtZUlzQWxyZWFkeUF0VGhlTWF4aW11bVZhbHVlEBMSGAoUVm9sdW1lSXNBbHJlYWR5TXV0ZWQQFBIiCh5Wb2ljZUlucHV0RW5kcG9pbnREb2VzTm90RXhpc3QQFRI0CjBUaGVWb2ljZUlucHV0RGV2aWNlSXNOb3RSZWdpc3RlcmVkT3JEb2VzTm90RXhpc3QQFhIVChFFbmNyeXB0aW9uRmFpbHVyZRAXEhgKFEVuZHBvaW50RG9lc05vdEV4aXN0EBgSLgoqVGhlQ2xpZW50c0FwcGxpY2F0aW9uQ2FuY2VsbGVkVGhlT3BlcmF0aW9uEBkSGAoUVGhlT3BlcmF0aW9uVGltZWRPdXQQGhIqCiZUaGVTcGVjaWZpZWRQbGF5ZXJQYXRoT2JqZWN0V2FzSW52YWxpZBAbEjoKNkFkZGluZ09yUmVtb3ZpbmdEZXZpY2VzRnJvbVRoZUF2T3V0cHV0Q29udGV4dEhhc0ZhaWxlZBAcEiwKKENvdWxkTm90RmluZFRoZVNwZWNpZmllZE5vd1BsYXlpbmdQbGF5ZXIQHRInCiNUaGVTcGVjaWZpZWRDb250ZW50SXRlbURvZXNOb3RFeGlzdBAeEh8KG1RoZVNwZWNpZmllZE9mZnNldElzSW52YWxpZBAfEiYKIlRoZVNwZWNpZmllZE91dHB1dENvbnRleHRJc0ludmFsaWQQIBIyCi5PbmVPck1vcmVTcGVjaWZpZWRPdXRwdXREZXZpY2VzQXJlTm90R3JvdXBhYmxlECESSApEVGhlU3BlY2lmaWVkT3V0cHV0Q29udGV4dERvZXNOb3RTdXBwb3J0QWRkaW5nTW9yZVRoYW5PbmVPdXRwdXREZXZpY2UQIhIsCihDb3VsZE5vdEZpbmRUaGVTcGVjaWZpZWROb3dQbGF5aW5nQ2xpZW50ECMSUApMRW5kcG9pbnRWb2x1bWVDb250cm9sSXNPbmx5UG9zc2libGVJZlRoZUVuZHBvaW50SXNQaWNrZWRPclJlbW90ZUNvbnRyb2xsYWJsZRAkElQKUE91dHB1dERldmljZVZvbHVtZUNvbnRyb2xJc09ubHlQb3NzaWJsZUlmVGhlRW5kcG9pbnRJc1BpY2tlZE9yUmVtb3RlQ29udHJvbGxhYmxlECUSIgoeQ29kZXJNdXN0U3VwcG9ydEtleVZhbHVlQ29kaW5nECYSJAogQ291bGROb3RGaW5kVGhlR2l2ZW5PdXRwdXRkZXZpY2UQJxIhCh1GYWlsZWRUb0Nvbm5lY3RUb1JlbW90ZURldmljZRBkEiAKHEF1dGhlbnRpY2F0aW9uVG9rZW5Jc0ludmFsaWQQZRIzCi9SZWNvcmRpbmdTZXNzaW9uSXNBbHJlYWR5SW5Qcm9ncmVzc09uVGhpc0RldmljZRBmEiQKIFRoZURldmljZUlzTm90Q3VycmVudGx5UmVjb3JkaW5nEGcSHAoYVGhlQ2xpZW50SGFzRGlzY29ubmVjdGVkEGgSHAoYVGhlU2VydmVySGFzRGlzY29ubmVjdGVkEGkSLAooVGhlQ29ubmVjdGlvbkhhc0JlZW5DYW5jZWxsZWRCeVRoZUNsaWVudBBqEjQKMFBhaXJpbmdGdW5jdGlvbmFsaXR5SXNMb2NrZWREdWVUb1NlY3VyaXR5UmVhc29ucxBrEiwKKFRoZUNsaWVudHNPcGVyYXRpbmdTeXN0ZW1WZXJzaW9uSXNUb29PbGQQbBIoCiRUaGVDbGllbnRzQXBwbGljYXRpb25WZXJzaW9uSXNUb29PbGQQbRIYChRUaGVEZXZpY2VJc05vdFBhaXJlZBBuEj8KO1RoZVBpblBhaXJpbmdEaWFsb2dXYXNSZW1vdmVkQnlUaGVVc2VyQmVmb3JlUGFpcmluZ09jY291cmVkEG8SQAo8VGhlUGluUGFpcmluZ0RpYWxvZ1dhc1JlbW92ZWRCeUFUaW1lb3V0QmVmb3JlUGFpcmluZ09jY291cmVkEHASGQoVVGhlQ29ubmVjdGlvblRpbWVkb3V0EHESIgoeUGFpcmluZ1dpdGhUaGlzRGV2aWNlSXNCbG9ja2VkEHISGwoXVGhlRGV2aWNlSXNHb2luZ1RvU2xlZXAQcxIdChlDb25uZWN0aW9uQmxvY2tlZEJ5U2VydmVyEHQSPAo4TXJhdmVuZHBvaW50V2FzRGVhbGxvY2F0ZWRXaGlsZVdhaXRpbmdGb3JEZXZpY2VUb0Nvbm5lY3QQdRJICkNPdXRwdXRDb250ZXh0TW9kaWZpY2F0aW9uQ2F1c2VkQURldmljZVRvTm9Mb25nZXJCZUFQcm94eUdyb3VwUGxheWVyEMgBEkQKP091dHB1dENvbnRleHRNb2RpZmljYXRpb25DYXVzZWRBRGV2aWNlVG9CZWNvbWVBUHJveHlHcm91cFBsYXllchDJARI3CjJPdXRwdXRDb250ZXh0TW9kaWZpY2F0aW9uUmVxdWVzdGVkTm9Ub3BvbG9neUNoYW5nZRDKARIWChFPdGhlclVua25vd25FcnJvchCrAiKEHwoPUHJvdG9jb2xNZXNzYWdlEiMKBHR5cGUYASABKA4yFS5Qcm90b2NvbE1lc3NhZ2UuVHlwZRISCgppZGVudGlmaWVyGAIgASgJEhsKE2F1dGhlbnRpY2F0aW9uVG9rZW4YAyABKAkSIgoJZXJyb3JDb2RlGAQgASgOMg8uRXJyb3JDb2RlLkVudW0SEQoJdGltZXN0YW1wGAUgASgEEhgKEGVycm9yRGVzY3JpcHRpb24YTiABKAkSGAoQdW5pcXVlSWRlbnRpZmllchhVIAEoCSKZHQoEVHlwZRITCg9VTktOT1dOX01FU1NBR0UQABIYChRTRU5EX0NPTU1BTkRfTUVTU0FHRRABEh8KG1NFTkRfQ09NTUFORF9SRVNVTFRfTUVTU0FHRRACEhUKEUdFVF9TVEFURV9NRVNTQUdFEAMSFQoRU0VUX1NUQVRFX01FU1NBR0UQBBIXChNTRVRfQVJUV09SS19NRVNTQUdFEAUSHwobUkVHSVNURVJfSElEX0RFVklDRV9NRVNTQUdFEAYSJgoiUkVHSVNURVJfSElEX0RFVklDRV9SRVNVTFRfTUVTU0FHRRAHEhoKFlNFTkRfSElEX0VWRU5UX01FU1NBR0UQCBIbChdTRU5EX0hJRF9SRVBPUlRfTUVTU0FHRRAJEiQKIFNFTkRfVklSVFVBTF9UT1VDSF9FVkVOVF9NRVNTQUdFEAoSGAoUTk9USUZJQ0FUSU9OX01FU1NBR0UQCxIuCipDT05URU5UX0lURU1TX0NIQU5HRURfTk9USUZJQ0FUSU9OX01FU1NBR0UQDBIXChNERVZJQ0VfSU5GT19NRVNTQUdFEA8SIQodQ0xJRU5UX1VQREFURVNfQ09ORklHX01FU1NBR0UQEBInCiNWT0xVTUVfQ09OVFJPTF9BVkFJTEFCSUxJVFlfTUVTU0FHRRAREhsKF0dBTUVfQ09OVFJPTExFUl9NRVNTQUdFEBISJAogUkVHSVNURVJfR0FNRV9DT05UUk9MTEVSX01FU1NBR0UQExItCilSRUdJU1RFUl9HQU1FX0NPTlRST0xMRVJfUkVTUE9OU0VfTUVTU0FHRRAUEiYKIlVOUkVHSVNURVJfR0FNRV9DT05UUk9MTEVSX01FU1NBR0UQFRIvCitSRUdJU1RFUl9GT1JfR0FNRV9DT05UUk9MTEVSX0VWRU5UU19NRVNTQUdFEBYSFAoQS0VZQk9BUkRfTUVTU0FHRRAXEiAKHEdFVF9LRVlCT0FSRF9TRVNTSU9OX01FU1NBR0UQGBIWChJURVhUX0lOUFVUX01FU1NBR0UQGRIjCh9HRVRfVk9JQ0VfSU5QVVRfREVWSUNFU19NRVNTQUdFEBoSLAooR0VUX1ZPSUNFX0lOUFVUX0RFVklDRVNfUkVTUE9OU0VfTUVTU0FHRRAbEicKI1JFR0lTVEVSX1ZPSUNFX0lOUFVUX0RFVklDRV9NRVNTQUdFEBwSMAosUkVHSVNURVJfVk9JQ0VfSU5QVVRfREVWSUNFX1JFU1BPTlNFX01FU1NBR0UQHRIfChtTRVRfUkVDT1JESU5HX1NUQVRFX01FU1NBR0UQHhIcChhTRU5EX1ZPSUNFX0lOUFVUX01FU1NBR0UQHxIiCh5QTEFZQkFDS19RVUVVRV9SRVFVRVNUX01FU1NBR0UQIBIXChNUUkFOU0FDVElPTl9NRVNTQUdFECESGgoWQ1JZUFRPX1BBSVJJTkdfTUVTU0FHRRAiEiYKIkdBTUVfQ09OVFJPTExFUl9QUk9QRVJUSUVTX01FU1NBR0UQIxIbChdTRVRfUkVBRFlfU1RBVEVfTUVTU0FHRRAkEh4KGkRFVklDRV9JTkZPX1VQREFURV9NRVNTQUdFECUSIAocU0VUX0NPTk5FQ1RJT05fU1RBVEVfTUVTU0FHRRAmEh0KGVNFTkRfQlVUVE9OX0VWRU5UX01FU1NBR0UQJxIbChdTRVRfSElMSVRFX01PREVfTUVTU0FHRRAoEhcKE1dBS0VfREVWSUNFX01FU1NBR0UQKRITCg9HRU5FUklDX01FU1NBR0UQKhIrCidTRU5EX1BBQ0tFRF9WSVJUVUFMX1RPVUNIX0VWRU5UX01FU1NBR0UQKxIVChFTRU5EX0xZUklDU19FVkVOVBAsEiIKHlNFVF9OT1dfUExBWUlOR19DTElFTlRfTUVTU0FHRRAuEiIKHlNFVF9OT1dfUExBWUlOR19QTEFZRVJfTUVTU0FHRRAvEikKJU1PRElGWV9PVVRQVVRfQ09OVEVYVF9SRVFVRVNUX01FU1NBR0UQMBIWChJHRVRfVk9MVU1FX01FU1NBR0UQMRIdChlHRVRfVk9MVU1FX1JFU1VMVF9NRVNTQUdFEDISFgoSU0VUX1ZPTFVNRV9NRVNTQUdFEDMSHQoZVk9MVU1FX0RJRF9DSEFOR0VfTUVTU0FHRRA0EhkKFVJFTU9WRV9DTElFTlRfTUVTU0FHRRA1EhkKFVJFTU9WRV9QTEFZRVJfTUVTU0FHRRA2EhkKFVVQREFURV9DTElFTlRfTUVTU0FHRRA3Eh8KG1VQREFURV9DT05URU5UX0lURU1fTUVTU0FHRRA4EicKI1VQREFURV9DT05URU5UX0lURU1fQVJUV09SS19NRVNTQUdFEDkSGQoVVVBEQVRFX1BMQVlFUl9NRVNTQUdFEDoSKgomUFJPTVBUX0ZPUl9ST1VURV9BVVRIT1JJWkFUSU9OX01FU1NBR0UQOxIzCi9QUk9NUFRfRk9SX1JPVVRFX0FVVEhPUklaQVRJT05fUkVTUE9OU0VfTUVTU0FHRRA8Ei4KKlBSRVNFTlRfUk9VVEVfQVVUSE9SSVpBVElPTl9TVEFUVVNfTUVTU0FHRRA9EisKJ0dFVF9WT0xVTUVfQ09OVFJPTF9DQVBBQklMSVRJRVNfTUVTU0FHRRA+EjIKLkdFVF9WT0xVTUVfQ09OVFJPTF9DQVBBQklMSVRJRVNfUkVTVUxUX01FU1NBR0UQPxIyCi5WT0xVTUVfQ09OVFJPTF9DQVBBQklMSVRJRVNfRElEX0NIQU5HRV9NRVNTQUdFEEASHwobU1lOQ19PVVRQVVRfREVWSUNFU19NRVNTQUdFEEESKAokUkVNT1ZFX1NZTkNFRF9PVVRQVVRfREVWSUNFU19NRVNTQUdFEEISHQoZUkVNT1RFX1RFWFRfSU5QVVRfTUVTU0FHRRBDEikKJUdFVF9SRU1PVEVfVEVYVF9JTlBVVF9TRVNTSU9OX01FU1NBR0UQRBIkCiBSRU1PVkVfRlJPTV9QQVJFTlRfR1JPVVBfTUVTU0FHRRBFEiQKIFBMQVlCQUNLX1NFU1NJT05fUkVRVUVTVF9NRVNTQUdFEEYSJQohUExBWUJBQ0tfU0VTU0lPTl9SRVNQT05TRV9NRVNTQUdFEEcSKgomU0VUX0RFRkFVTFRfU1VQUE9SVEVEX0NPTU1BTkRTX01FU1NBR0UQSBIsCihQTEFZQkFDS19TRVNTSU9OX01JR1JBVEVfUkVRVUVTVF9NRVNTQUdFEEkSLQopUExBWUJBQ0tfU0VTU0lPTl9NSUdSQVRFX1JFU1BPTlNFX01FU1NBR0UQShIqCiZQTEFZQkFDS19TRVNTSU9OX01JR1JBVEVfQkVHSU5fTUVTU0FHRRBLEigKJFBMQVlCQUNLX1NFU1NJT05fTUlHUkFURV9FTkRfTUVTU0FHRRBMEikKJVVQREFURV9BQ1RJVkVfU1lTVEVNX0VORFBPSU5UX01FU1NBR0UQTRIpCiVQTEFZQkFDS19TRVNTSU9OX01JR1JBVEVfUE9TVF9NRVNTQUdFEE4SHgoaU0VUX0RJU0NPVkVSWV9NT0RFX01FU1NBR0UQZRIjCh9VUERBVEVfU1lOQ0VEX0VORFBPSU5UU19NRVNTQUdFEGYSIwofUkVNT1ZFX1NZTkNFRF9FTkRQT0lOVFNfTUVTU0FHRRBnEiQKIFBMQVlFUl9DTElFTlRfUFJPUEVSVElFU19NRVNTQUdFEGgSJAogT1JJR0lOX0NMSUVOVF9QUk9QRVJUSUVTX01FU1NBR0UQaRIWChJBVURJT19GQURFX01FU1NBR0UQahIfChtBVURJT19GQURFX1JFU1BPTlNFX01FU1NBR0UQaxImCiJESVNDT1ZFUllfVVBEQVRFX0VORFBPSU5UU19NRVNTQUdFEGwSKwonRElTQ09WRVJZX1VQREFURV9PVVRQVVRfREVWSUNFU19NRVNTQUdFEG0SHgoaU0VUX0xJU1RFTklOR19NT0RFX01FU1NBR0UQbhIgChxDT05GSUdVUkVfQ09OTkVDVElPTl9NRVNTQUdFEHgSKgomQ1JFQVRFX0hPU1RFRF9FTkRQT0lOVF9SRVFVRVNUX01FU1NBR0UQeRIrCidDUkVBVEVfSE9TVEVEX0VORFBPSU5UX1JFU1BPTlNFX01FU1NBR0UQehIZChVBREpVU1RfVk9MVU1FX01FU1NBR0UQfRIcChhHRVRfVk9MVU1FX01VVEVEX01FU1NBR0UQfhIjCh9HRVRfVk9MVU1FX01VVEVEX1JFU1VMVF9NRVNTQUdFEH8SHQoYU0VUX1ZPTFVNRV9NVVRFRF9NRVNTQUdFEIABEiQKH1ZPTFVNRV9NVVRFRF9ESURfQ0hBTkdFX01FU1NBR0UQgQESLwoqU0VUX0NPTlZFUlNBVElPTl9ERVRFQ1RJT05fRU5BQkxFRF9NRVNTQUdFEIIBEi4KKVBMQVlFUl9DTElFTlRfUEFSVElDSVBBTlRTX1VQREFURV9NRVNTQUdFEIMBEiIKHVJFUVVFU1RfR1JPVVBfU0VTU0lPTl9NRVNTQUdFEIQBEikKJENPTkZJR1VSRV9DT05ORUNUSU9OX1NFUlZJQ0VfTUVTU0FHRRCFARIqCiVDUkVBVEVfQVBQTElDQVRJT05fQ09OTkVDVElPTl9NRVNTQUdFEIYBEiwKJ0FQUExJQ0FUSU9OX0NPTk5FQ1RJT05fUFJPVE9DT0xfTUVTU0FHRRCHARIuCilJTlZBTElEQVRFX0FQUExJQ0FUSU9OX0NPTk5FQ1RJT05fTUVTU0FHRRCIARIqCiVNSUNST1BIT05FX0NPTk5FQ1RJT05fUkVRVUVTVF9NRVNTQUdFEIkBEisKJk1JQ1JPUEhPTkVfQ09OTkVDVElPTl9SRVNQT05TRV9NRVNTQUdFEIoBKgQIBhBOKgQITxBVKggIVhCAgICAAg");
|
|
6591
6733
|
/**
|
|
6592
6734
|
* Describes the message ErrorCode.
|
|
6593
6735
|
* Use `create(ErrorCodeSchema)` to create a new message.
|
|
@@ -7113,13 +7255,17 @@ let ProtocolMessage_Type = /* @__PURE__ */ function(ProtocolMessage_Type) {
|
|
|
7113
7255
|
*/
|
|
7114
7256
|
ProtocolMessage_Type[ProtocolMessage_Type["VOLUME_CONTROL_CAPABILITIES_DID_CHANGE_MESSAGE"] = 64] = "VOLUME_CONTROL_CAPABILITIES_DID_CHANGE_MESSAGE";
|
|
7115
7257
|
/**
|
|
7116
|
-
*
|
|
7258
|
+
* Apple: SyncOutputDevicesMessage
|
|
7259
|
+
*
|
|
7260
|
+
* @generated from enum value: SYNC_OUTPUT_DEVICES_MESSAGE = 65;
|
|
7117
7261
|
*/
|
|
7118
|
-
ProtocolMessage_Type[ProtocolMessage_Type["
|
|
7262
|
+
ProtocolMessage_Type[ProtocolMessage_Type["SYNC_OUTPUT_DEVICES_MESSAGE"] = 65] = "SYNC_OUTPUT_DEVICES_MESSAGE";
|
|
7119
7263
|
/**
|
|
7120
|
-
*
|
|
7264
|
+
* Apple: RemoveSyncedOutputDevicesMessage
|
|
7265
|
+
*
|
|
7266
|
+
* @generated from enum value: REMOVE_SYNCED_OUTPUT_DEVICES_MESSAGE = 66;
|
|
7121
7267
|
*/
|
|
7122
|
-
ProtocolMessage_Type[ProtocolMessage_Type["
|
|
7268
|
+
ProtocolMessage_Type[ProtocolMessage_Type["REMOVE_SYNCED_OUTPUT_DEVICES_MESSAGE"] = 66] = "REMOVE_SYNCED_OUTPUT_DEVICES_MESSAGE";
|
|
7123
7269
|
/**
|
|
7124
7270
|
* @generated from enum value: REMOTE_TEXT_INPUT_MESSAGE = 67;
|
|
7125
7271
|
*/
|
|
@@ -7129,11 +7275,11 @@ let ProtocolMessage_Type = /* @__PURE__ */ function(ProtocolMessage_Type) {
|
|
|
7129
7275
|
*/
|
|
7130
7276
|
ProtocolMessage_Type[ProtocolMessage_Type["GET_REMOTE_TEXT_INPUT_SESSION_MESSAGE"] = 68] = "GET_REMOTE_TEXT_INPUT_SESSION_MESSAGE";
|
|
7131
7277
|
/**
|
|
7132
|
-
*
|
|
7278
|
+
* Apple: RemoveFromParentGroupMessage
|
|
7133
7279
|
*
|
|
7134
|
-
* @generated from enum value:
|
|
7280
|
+
* @generated from enum value: REMOVE_FROM_PARENT_GROUP_MESSAGE = 69;
|
|
7135
7281
|
*/
|
|
7136
|
-
ProtocolMessage_Type[ProtocolMessage_Type["
|
|
7282
|
+
ProtocolMessage_Type[ProtocolMessage_Type["REMOVE_FROM_PARENT_GROUP_MESSAGE"] = 69] = "REMOVE_FROM_PARENT_GROUP_MESSAGE";
|
|
7137
7283
|
/**
|
|
7138
7284
|
* @generated from enum value: PLAYBACK_SESSION_REQUEST_MESSAGE = 70;
|
|
7139
7285
|
*/
|
|
@@ -7167,17 +7313,27 @@ let ProtocolMessage_Type = /* @__PURE__ */ function(ProtocolMessage_Type) {
|
|
|
7167
7313
|
*/
|
|
7168
7314
|
ProtocolMessage_Type[ProtocolMessage_Type["UPDATE_ACTIVE_SYSTEM_ENDPOINT_MESSAGE"] = 77] = "UPDATE_ACTIVE_SYSTEM_ENDPOINT_MESSAGE";
|
|
7169
7315
|
/**
|
|
7316
|
+
* Apple: 0x4E
|
|
7317
|
+
*
|
|
7318
|
+
* @generated from enum value: PLAYBACK_SESSION_MIGRATE_POST_MESSAGE = 78;
|
|
7319
|
+
*/
|
|
7320
|
+
ProtocolMessage_Type[ProtocolMessage_Type["PLAYBACK_SESSION_MIGRATE_POST_MESSAGE"] = 78] = "PLAYBACK_SESSION_MIGRATE_POST_MESSAGE";
|
|
7321
|
+
/**
|
|
7170
7322
|
* @generated from enum value: SET_DISCOVERY_MODE_MESSAGE = 101;
|
|
7171
7323
|
*/
|
|
7172
7324
|
ProtocolMessage_Type[ProtocolMessage_Type["SET_DISCOVERY_MODE_MESSAGE"] = 101] = "SET_DISCOVERY_MODE_MESSAGE";
|
|
7173
7325
|
/**
|
|
7174
|
-
*
|
|
7326
|
+
* Apple: UpdateSyncedEndpointsMessage
|
|
7327
|
+
*
|
|
7328
|
+
* @generated from enum value: UPDATE_SYNCED_ENDPOINTS_MESSAGE = 102;
|
|
7175
7329
|
*/
|
|
7176
|
-
ProtocolMessage_Type[ProtocolMessage_Type["
|
|
7330
|
+
ProtocolMessage_Type[ProtocolMessage_Type["UPDATE_SYNCED_ENDPOINTS_MESSAGE"] = 102] = "UPDATE_SYNCED_ENDPOINTS_MESSAGE";
|
|
7177
7331
|
/**
|
|
7178
|
-
*
|
|
7332
|
+
* Apple: RemoveSyncedEndpointsMessage
|
|
7333
|
+
*
|
|
7334
|
+
* @generated from enum value: REMOVE_SYNCED_ENDPOINTS_MESSAGE = 103;
|
|
7179
7335
|
*/
|
|
7180
|
-
ProtocolMessage_Type[ProtocolMessage_Type["
|
|
7336
|
+
ProtocolMessage_Type[ProtocolMessage_Type["REMOVE_SYNCED_ENDPOINTS_MESSAGE"] = 103] = "REMOVE_SYNCED_ENDPOINTS_MESSAGE";
|
|
7181
7337
|
/**
|
|
7182
7338
|
* @generated from enum value: PLAYER_CLIENT_PROPERTIES_MESSAGE = 104;
|
|
7183
7339
|
*/
|
|
@@ -7195,93 +7351,117 @@ let ProtocolMessage_Type = /* @__PURE__ */ function(ProtocolMessage_Type) {
|
|
|
7195
7351
|
*/
|
|
7196
7352
|
ProtocolMessage_Type[ProtocolMessage_Type["AUDIO_FADE_RESPONSE_MESSAGE"] = 107] = "AUDIO_FADE_RESPONSE_MESSAGE";
|
|
7197
7353
|
/**
|
|
7198
|
-
*
|
|
7199
|
-
|
|
7200
|
-
|
|
7201
|
-
/**
|
|
7202
|
-
* @generated from enum value: SET_CONVERSATION_DETECTION_ENABLED_MESSAGE = 109;
|
|
7203
|
-
*/
|
|
7204
|
-
ProtocolMessage_Type[ProtocolMessage_Type["SET_CONVERSATION_DETECTION_ENABLED_MESSAGE"] = 109] = "SET_CONVERSATION_DETECTION_ENABLED_MESSAGE";
|
|
7205
|
-
/**
|
|
7206
|
-
* @generated from enum value: PLAYER_CLIENT_PARTICIPANTS_UPDATE_MESSAGE = 110;
|
|
7354
|
+
* Apple: DiscoveryUpdateEndpointsMessage — NIEUW
|
|
7355
|
+
*
|
|
7356
|
+
* @generated from enum value: DISCOVERY_UPDATE_ENDPOINTS_MESSAGE = 108;
|
|
7207
7357
|
*/
|
|
7208
|
-
ProtocolMessage_Type[ProtocolMessage_Type["
|
|
7358
|
+
ProtocolMessage_Type[ProtocolMessage_Type["DISCOVERY_UPDATE_ENDPOINTS_MESSAGE"] = 108] = "DISCOVERY_UPDATE_ENDPOINTS_MESSAGE";
|
|
7209
7359
|
/**
|
|
7210
|
-
*
|
|
7360
|
+
* Apple: DiscoveryUpdateOutputDevicesMessage — NIEUW
|
|
7361
|
+
*
|
|
7362
|
+
* @generated from enum value: DISCOVERY_UPDATE_OUTPUT_DEVICES_MESSAGE = 109;
|
|
7211
7363
|
*/
|
|
7212
|
-
ProtocolMessage_Type[ProtocolMessage_Type["
|
|
7364
|
+
ProtocolMessage_Type[ProtocolMessage_Type["DISCOVERY_UPDATE_OUTPUT_DEVICES_MESSAGE"] = 109] = "DISCOVERY_UPDATE_OUTPUT_DEVICES_MESSAGE";
|
|
7213
7365
|
/**
|
|
7214
|
-
*
|
|
7366
|
+
* Apple: SetListeningModeMessage — NIEUW
|
|
7367
|
+
*
|
|
7368
|
+
* @generated from enum value: SET_LISTENING_MODE_MESSAGE = 110;
|
|
7215
7369
|
*/
|
|
7216
|
-
ProtocolMessage_Type[ProtocolMessage_Type["
|
|
7370
|
+
ProtocolMessage_Type[ProtocolMessage_Type["SET_LISTENING_MODE_MESSAGE"] = 110] = "SET_LISTENING_MODE_MESSAGE";
|
|
7217
7371
|
/**
|
|
7218
|
-
* @generated from enum value:
|
|
7372
|
+
* @generated from enum value: CONFIGURE_CONNECTION_MESSAGE = 120;
|
|
7219
7373
|
*/
|
|
7220
|
-
ProtocolMessage_Type[ProtocolMessage_Type["
|
|
7374
|
+
ProtocolMessage_Type[ProtocolMessage_Type["CONFIGURE_CONNECTION_MESSAGE"] = 120] = "CONFIGURE_CONNECTION_MESSAGE";
|
|
7221
7375
|
/**
|
|
7222
|
-
*
|
|
7376
|
+
* Apple: 0x79
|
|
7377
|
+
*
|
|
7378
|
+
* @generated from enum value: CREATE_HOSTED_ENDPOINT_REQUEST_MESSAGE = 121;
|
|
7223
7379
|
*/
|
|
7224
|
-
ProtocolMessage_Type[ProtocolMessage_Type["CREATE_HOSTED_ENDPOINT_REQUEST_MESSAGE"] =
|
|
7380
|
+
ProtocolMessage_Type[ProtocolMessage_Type["CREATE_HOSTED_ENDPOINT_REQUEST_MESSAGE"] = 121] = "CREATE_HOSTED_ENDPOINT_REQUEST_MESSAGE";
|
|
7225
7381
|
/**
|
|
7226
|
-
*
|
|
7382
|
+
* Apple: 0x7A
|
|
7383
|
+
*
|
|
7384
|
+
* @generated from enum value: CREATE_HOSTED_ENDPOINT_RESPONSE_MESSAGE = 122;
|
|
7227
7385
|
*/
|
|
7228
|
-
ProtocolMessage_Type[ProtocolMessage_Type["CREATE_HOSTED_ENDPOINT_RESPONSE_MESSAGE"] =
|
|
7386
|
+
ProtocolMessage_Type[ProtocolMessage_Type["CREATE_HOSTED_ENDPOINT_RESPONSE_MESSAGE"] = 122] = "CREATE_HOSTED_ENDPOINT_RESPONSE_MESSAGE";
|
|
7229
7387
|
/**
|
|
7230
|
-
*
|
|
7388
|
+
* Apple: AdjustVolumeMessage — NIEUW
|
|
7389
|
+
*
|
|
7390
|
+
* @generated from enum value: ADJUST_VOLUME_MESSAGE = 125;
|
|
7231
7391
|
*/
|
|
7232
|
-
ProtocolMessage_Type[ProtocolMessage_Type["
|
|
7392
|
+
ProtocolMessage_Type[ProtocolMessage_Type["ADJUST_VOLUME_MESSAGE"] = 125] = "ADJUST_VOLUME_MESSAGE";
|
|
7233
7393
|
/**
|
|
7234
|
-
* @generated from enum value:
|
|
7394
|
+
* @generated from enum value: GET_VOLUME_MUTED_MESSAGE = 126;
|
|
7235
7395
|
*/
|
|
7236
|
-
ProtocolMessage_Type[ProtocolMessage_Type["
|
|
7396
|
+
ProtocolMessage_Type[ProtocolMessage_Type["GET_VOLUME_MUTED_MESSAGE"] = 126] = "GET_VOLUME_MUTED_MESSAGE";
|
|
7237
7397
|
/**
|
|
7238
|
-
* @generated from enum value:
|
|
7398
|
+
* @generated from enum value: GET_VOLUME_MUTED_RESULT_MESSAGE = 127;
|
|
7239
7399
|
*/
|
|
7240
|
-
ProtocolMessage_Type[ProtocolMessage_Type["
|
|
7400
|
+
ProtocolMessage_Type[ProtocolMessage_Type["GET_VOLUME_MUTED_RESULT_MESSAGE"] = 127] = "GET_VOLUME_MUTED_RESULT_MESSAGE";
|
|
7241
7401
|
/**
|
|
7242
|
-
*
|
|
7402
|
+
* Apple: MuteVolumeMessage
|
|
7403
|
+
*
|
|
7404
|
+
* @generated from enum value: SET_VOLUME_MUTED_MESSAGE = 128;
|
|
7243
7405
|
*/
|
|
7244
|
-
ProtocolMessage_Type[ProtocolMessage_Type["
|
|
7406
|
+
ProtocolMessage_Type[ProtocolMessage_Type["SET_VOLUME_MUTED_MESSAGE"] = 128] = "SET_VOLUME_MUTED_MESSAGE";
|
|
7245
7407
|
/**
|
|
7246
|
-
* @generated from enum value:
|
|
7408
|
+
* @generated from enum value: VOLUME_MUTED_DID_CHANGE_MESSAGE = 129;
|
|
7247
7409
|
*/
|
|
7248
|
-
ProtocolMessage_Type[ProtocolMessage_Type["
|
|
7410
|
+
ProtocolMessage_Type[ProtocolMessage_Type["VOLUME_MUTED_DID_CHANGE_MESSAGE"] = 129] = "VOLUME_MUTED_DID_CHANGE_MESSAGE";
|
|
7249
7411
|
/**
|
|
7250
|
-
*
|
|
7412
|
+
* Apple: 0x82
|
|
7413
|
+
*
|
|
7414
|
+
* @generated from enum value: SET_CONVERSATION_DETECTION_ENABLED_MESSAGE = 130;
|
|
7251
7415
|
*/
|
|
7252
|
-
ProtocolMessage_Type[ProtocolMessage_Type["
|
|
7416
|
+
ProtocolMessage_Type[ProtocolMessage_Type["SET_CONVERSATION_DETECTION_ENABLED_MESSAGE"] = 130] = "SET_CONVERSATION_DETECTION_ENABLED_MESSAGE";
|
|
7253
7417
|
/**
|
|
7254
|
-
*
|
|
7418
|
+
* Apple: 0x83
|
|
7419
|
+
*
|
|
7420
|
+
* @generated from enum value: PLAYER_CLIENT_PARTICIPANTS_UPDATE_MESSAGE = 131;
|
|
7255
7421
|
*/
|
|
7256
|
-
ProtocolMessage_Type[ProtocolMessage_Type["
|
|
7422
|
+
ProtocolMessage_Type[ProtocolMessage_Type["PLAYER_CLIENT_PARTICIPANTS_UPDATE_MESSAGE"] = 131] = "PLAYER_CLIENT_PARTICIPANTS_UPDATE_MESSAGE";
|
|
7257
7423
|
/**
|
|
7258
|
-
*
|
|
7424
|
+
* Apple: 0x84
|
|
7425
|
+
*
|
|
7426
|
+
* @generated from enum value: REQUEST_GROUP_SESSION_MESSAGE = 132;
|
|
7259
7427
|
*/
|
|
7260
|
-
ProtocolMessage_Type[ProtocolMessage_Type["
|
|
7428
|
+
ProtocolMessage_Type[ProtocolMessage_Type["REQUEST_GROUP_SESSION_MESSAGE"] = 132] = "REQUEST_GROUP_SESSION_MESSAGE";
|
|
7261
7429
|
/**
|
|
7262
|
-
*
|
|
7430
|
+
* Apple: ConfigureConnectionServiceMessage — NIEUW
|
|
7431
|
+
*
|
|
7432
|
+
* @generated from enum value: CONFIGURE_CONNECTION_SERVICE_MESSAGE = 133;
|
|
7263
7433
|
*/
|
|
7264
|
-
ProtocolMessage_Type[ProtocolMessage_Type["
|
|
7434
|
+
ProtocolMessage_Type[ProtocolMessage_Type["CONFIGURE_CONNECTION_SERVICE_MESSAGE"] = 133] = "CONFIGURE_CONNECTION_SERVICE_MESSAGE";
|
|
7265
7435
|
/**
|
|
7266
|
-
*
|
|
7436
|
+
* Apple: 0x86
|
|
7437
|
+
*
|
|
7438
|
+
* @generated from enum value: CREATE_APPLICATION_CONNECTION_MESSAGE = 134;
|
|
7267
7439
|
*/
|
|
7268
|
-
ProtocolMessage_Type[ProtocolMessage_Type["
|
|
7440
|
+
ProtocolMessage_Type[ProtocolMessage_Type["CREATE_APPLICATION_CONNECTION_MESSAGE"] = 134] = "CREATE_APPLICATION_CONNECTION_MESSAGE";
|
|
7269
7441
|
/**
|
|
7270
|
-
*
|
|
7442
|
+
* Apple: 0x87 — NIEUW
|
|
7443
|
+
*
|
|
7444
|
+
* @generated from enum value: APPLICATION_CONNECTION_PROTOCOL_MESSAGE = 135;
|
|
7271
7445
|
*/
|
|
7272
|
-
ProtocolMessage_Type[ProtocolMessage_Type["
|
|
7446
|
+
ProtocolMessage_Type[ProtocolMessage_Type["APPLICATION_CONNECTION_PROTOCOL_MESSAGE"] = 135] = "APPLICATION_CONNECTION_PROTOCOL_MESSAGE";
|
|
7273
7447
|
/**
|
|
7274
|
-
*
|
|
7448
|
+
* Apple: 0x88 — NIEUW
|
|
7449
|
+
*
|
|
7450
|
+
* @generated from enum value: INVALIDATE_APPLICATION_CONNECTION_MESSAGE = 136;
|
|
7275
7451
|
*/
|
|
7276
|
-
ProtocolMessage_Type[ProtocolMessage_Type["
|
|
7452
|
+
ProtocolMessage_Type[ProtocolMessage_Type["INVALIDATE_APPLICATION_CONNECTION_MESSAGE"] = 136] = "INVALIDATE_APPLICATION_CONNECTION_MESSAGE";
|
|
7277
7453
|
/**
|
|
7278
|
-
*
|
|
7454
|
+
* Apple: 0x89
|
|
7455
|
+
*
|
|
7456
|
+
* @generated from enum value: MICROPHONE_CONNECTION_REQUEST_MESSAGE = 137;
|
|
7279
7457
|
*/
|
|
7280
|
-
ProtocolMessage_Type[ProtocolMessage_Type["
|
|
7458
|
+
ProtocolMessage_Type[ProtocolMessage_Type["MICROPHONE_CONNECTION_REQUEST_MESSAGE"] = 137] = "MICROPHONE_CONNECTION_REQUEST_MESSAGE";
|
|
7281
7459
|
/**
|
|
7282
|
-
*
|
|
7460
|
+
* Apple: 0x8A
|
|
7461
|
+
*
|
|
7462
|
+
* @generated from enum value: MICROPHONE_CONNECTION_RESPONSE_MESSAGE = 138;
|
|
7283
7463
|
*/
|
|
7284
|
-
ProtocolMessage_Type[ProtocolMessage_Type["
|
|
7464
|
+
ProtocolMessage_Type[ProtocolMessage_Type["MICROPHONE_CONNECTION_RESPONSE_MESSAGE"] = 138] = "MICROPHONE_CONNECTION_RESPONSE_MESSAGE";
|
|
7285
7465
|
return ProtocolMessage_Type;
|
|
7286
7466
|
}({});
|
|
7287
7467
|
/**
|
|
@@ -8019,7 +8199,7 @@ const PlaybackQueueType_EnumSchema = /* @__PURE__ */ enumDesc(file_Common, 15, 0
|
|
|
8019
8199
|
/**
|
|
8020
8200
|
* Describes the file DeviceInfoMessage.proto.
|
|
8021
8201
|
*/
|
|
8022
|
-
const file_DeviceInfoMessage = /* @__PURE__ */ fileDesc("
|
|
8202
|
+
const file_DeviceInfoMessage = /* @__PURE__ */ fileDesc("ChdEZXZpY2VJbmZvTWVzc2FnZS5wcm90byIyChFQcmVmZXJyZWRFbmNvZGluZyIdCgRFbnVtEgsKB0RlZmF1bHQQABIICgRKU09OEAEizQ0KEURldmljZUluZm9NZXNzYWdlEhgKEHVuaXF1ZUlkZW50aWZpZXIYASABKAkSDAoEbmFtZRgCIAIoCRIaChJsb2NhbGl6ZWRNb2RlbE5hbWUYAyABKAkSGgoSc3lzdGVtQnVpbGRWZXJzaW9uGAQgASgJEiMKG2FwcGxpY2F0aW9uQnVuZGxlSWRlbnRpZmllchgFIAEoCRIgChhhcHBsaWNhdGlvbkJ1bmRsZVZlcnNpb24YBiABKAkSFwoPcHJvdG9jb2xWZXJzaW9uGAcgASgFEiAKGGxhc3RTdXBwb3J0ZWRNZXNzYWdlVHlwZRgIIAEoDRIdChVzdXBwb3J0c1N5c3RlbVBhaXJpbmcYCSABKAgSFQoNYWxsb3dzUGFpcmluZxgKIAEoCBIRCgljb25uZWN0ZWQYCyABKAgSHgoWc3lzdGVtTWVkaWFBcHBsaWNhdGlvbhgMIAEoCRITCgtzdXBwb3J0c0FDTBgNIAEoCBIbChNzdXBwb3J0c1NoYXJlZFF1ZXVlGA4gASgIEh4KFnN1cHBvcnRzRXh0ZW5kZWRNb3Rpb24YDyABKAgSGAoQYmx1ZXRvb3RoQWRkcmVzcxgQIAEoDBIaChJzaGFyZWRRdWV1ZVZlcnNpb24YESABKA0SEQoJZGV2aWNlVUlEGBMgASgJEh0KFW1hbmFnZWRDb25maWdEZXZpY2VJRBgUIAEoCRImCgtkZXZpY2VDbGFzcxgVIAEoDjIRLkRldmljZUNsYXNzLkVudW0SGgoSbG9naWNhbERldmljZUNvdW50GBYgASgNEhoKEnRpZ2h0bHlTeW5jZWRHcm91cBgXIAEoCBIaChJpc1Byb3h5R3JvdXBQbGF5ZXIYGCABKAgSFAoMdGlnaHRTeW5jVUlEGBkgASgJEhAKCGdyb3VwVUlEGBogASgJEhEKCWdyb3VwTmFtZRgbIAEoCRIqCg5ncm91cGVkRGV2aWNlcxgcIAMoCzISLkRldmljZUluZm9NZXNzYWdlEhUKDWlzR3JvdXBMZWFkZXIYHSABKAgSFwoPaXNBaXJwbGF5QWN0aXZlGB4gASgIEiAKGHN5c3RlbVBvZGNhc3RBcHBsaWNhdGlvbhgfIAEoCRIdChVzZW5kZXJEZWZhdWx0R3JvdXBVSUQYICABKAkSGAoQYWlycGxheVJlY2VpdmVycxghIAMoCRIRCglsaW5rQWdlbnQYIiABKAkSEQoJY2x1c3RlcklEGCMgASgJEhcKD2NsdXN0ZXJMZWFkZXJJRBgkIAEoCRITCgtjbHVzdGVyVHlwZRglIAEoDRIWCg5pc0NsdXN0ZXJBd2FyZRgmIAEoCBIPCgdtb2RlbElEGCcgASgJEhsKE3N1cHBvcnRzTXVsdGlwbGF5ZXIYKCABKAgSGAoQcm91dGluZ0NvbnRleHRJRBgpIAEoCRIWCg5haXJQbGF5R3JvdXBJRBgqIAEoCRIeChZzeXN0ZW1Cb29rc0FwcGxpY2F0aW9uGCsgASgJEiwKEGNsdXN0ZXJlZERldmljZXMYLCADKAsyEi5EZXZpY2VJbmZvTWVzc2FnZRIyCipwYXJlbnRHcm91cENvbnRhaW5zRGlzY292ZXJhYmxlR3JvdXBMZWFkZXIYLSABKA0SLAokZ3JvdXBDb250YWluc0Rpc2NvdmVyYWJsZUdyb3VwTGVhZGVyGC4gASgNEhwKFGxhc3RLbm93bkNsdXN0ZXJUeXBlGC8gASgNEi8KE2FsbENsdXN0ZXJlZERldmljZXMYMCADKAsyEi5EZXZpY2VJbmZvTWVzc2FnZRIhChlzdXBwb3J0c091dHB1dENvbnRleHRTeW5jGDEgASgIEhQKDGNvbXB1dGVyTmFtZRgyIAEoCRIdChVjb25maWd1cmVkQ2x1c3RlclNpemUYMyABKA0SMgoRcHJlZmVycmVkRW5jb2RpbmcYNCABKA4yFy5QcmVmZXJyZWRFbmNvZGluZy5FbnVtEhkKEWdyb3VwU2Vzc2lvblRva2VuGDUgASgMEiwKEGxlYWRlckRldmljZUluZm8YNiABKAsyEi5EZXZpY2VJbmZvTWVzc2FnZRIXCg9pc0NsdXN0ZXJMZWFkZXIYNyABKAgSHwoXYWN0aXZlU3lzdGVtRW5kcG9pbnRVSUQYOCABKAkSQQo5aXNFbGlnaWJsZUZvckhvc3RpbmdHcm91cFNlc3Npb25FeGNsdWRpbmdBY2tub3dsZWRnZW1lbnRzGDkgASgIEigKIHBhcmVudEdyb3VwU3VwcG9ydHNHcm91cENvaGVzaW9uGDogASgIOlIKEWRldmljZUluZm9NZXNzYWdlEhAuUHJvdG9jb2xNZXNzYWdlGBQgASgLMhIuRGV2aWNlSW5mb01lc3NhZ2VSEWRldmljZUluZm9NZXNzYWdl", [file_ProtocolMessage, file_Common]);
|
|
8023
8203
|
/**
|
|
8024
8204
|
* Describes the message PreferredEncoding.
|
|
8025
8205
|
* Use `create(PreferredEncodingSchema)` to create a new message.
|
|
@@ -8104,7 +8284,7 @@ const Origin_TypeSchema = /* @__PURE__ */ enumDesc(file_Origin, 0, 0);
|
|
|
8104
8284
|
/**
|
|
8105
8285
|
* Describes the file NowPlayingClient.proto.
|
|
8106
8286
|
*/
|
|
8107
|
-
const file_NowPlayingClient = /* @__PURE__ */ fileDesc("
|
|
8287
|
+
const file_NowPlayingClient = /* @__PURE__ */ fileDesc("ChZOb3dQbGF5aW5nQ2xpZW50LnByb3RvIq8CChBOb3dQbGF5aW5nQ2xpZW50EhkKEXByb2Nlc3NJZGVudGlmaWVyGAEgASgFEhgKEGJ1bmRsZUlkZW50aWZpZXIYAiABKAkSKQohcGFyZW50QXBwbGljYXRpb25CdW5kbGVJZGVudGlmaWVyGAMgASgJEh0KFXByb2Nlc3NVc2VySWRlbnRpZmllchgEIAEoBRIcChRub3dQbGF5aW5nVmlzaWJpbGl0eRgFIAEoBRIRCgl0aW50Q29sb3IYBiABKAwSEwoLZGlzcGxheU5hbWUYByABKAkSKgoiZXh0ZW5kZWRCdW5kbGVJZGVudGlmaWVySGllcmFyY2h5cxgIIAMoCRIPCgdpY29uVVJMGAkgASgJEhkKEWlzRW1wdHlEZXByZWNhdGVkGAogASgI");
|
|
8108
8288
|
/**
|
|
8109
8289
|
* Describes the message NowPlayingClient.
|
|
8110
8290
|
* Use `create(NowPlayingClientSchema)` to create a new message.
|
|
@@ -8116,7 +8296,7 @@ const NowPlayingClientSchema = /* @__PURE__ */ messageDesc(file_NowPlayingClient
|
|
|
8116
8296
|
/**
|
|
8117
8297
|
* Describes the file NowPlayingPlayer.proto.
|
|
8118
8298
|
*/
|
|
8119
|
-
const file_NowPlayingPlayer = /* @__PURE__ */ fileDesc("
|
|
8299
|
+
const file_NowPlayingPlayer = /* @__PURE__ */ fileDesc("ChZOb3dQbGF5aW5nUGxheWVyLnByb3RvIpQBChBOb3dQbGF5aW5nUGxheWVyEhIKCmlkZW50aWZpZXIYASABKAkSEwoLZGlzcGxheU5hbWUYAiABKAkSGAoQYXVkaW9TZXNzaW9uVHlwZRgEIAEoBRIUCgxteFNlc3Npb25JRHMYBSABKAMSFgoOYXVkaW9TZXNzaW9uSUQYBiABKA0SDwoHaWNvblVSTBgHIAEoCQ");
|
|
8120
8300
|
/**
|
|
8121
8301
|
* Describes the message NowPlayingPlayer.
|
|
8122
8302
|
* Use `create(NowPlayingPlayerSchema)` to create a new message.
|
|
@@ -8301,7 +8481,7 @@ const ColorSchema = /* @__PURE__ */ messageDesc(file_Color, 0);
|
|
|
8301
8481
|
/**
|
|
8302
8482
|
* Describes the file CommandInfo.proto.
|
|
8303
8483
|
*/
|
|
8304
|
-
const file_CommandInfo = /* @__PURE__ */ fileDesc("
|
|
8484
|
+
const file_CommandInfo = /* @__PURE__ */ fileDesc("ChFDb21tYW5kSW5mby5wcm90byJMCg5RdWV1ZUVuZEFjdGlvbiI6CgRFbnVtEg8KC0NsZWFyQWN0aW9uEAASCAoETm9uZRABEgkKBVJlc2V0EAISDAoIQXV0b1BsYXkQAyJKCg1EaXNhYmxlUmVhc29uIjkKBEVudW0SCwoHVW5rbm93bhAAEg4KCkFkUGxheWJhY2sQARIUChBTa2lwTGltaXRSZWFjaGVkEAIigwEKHFByZWxvYWRlZFBsYXliYWNrU2Vzc2lvbkluZm8SIQoZcGxheWJhY2tTZXNzaW9uSWRlbnRpZmllchgBIAEoCRIfChdwbGF5YmFja1Nlc3Npb25SZXZpc2lvbhgCIAEoCRIfChdwbGF5YmFja1Nlc3Npb25Qcmlvcml0eRgDIAEoBSKHCgoLQ29tbWFuZEluZm8SGQoHY29tbWFuZBgBIAEoDjIILkNvbW1hbmQSDwoHZW5hYmxlZBgCIAEoCBIOCgZhY3RpdmUYAyABKAgSGgoScHJlZmVycmVkSW50ZXJ2YWxzGAQgAygBEhYKDmxvY2FsaXplZFRpdGxlGAUgASgJEhUKDW1pbmltdW1SYXRpbmcYBiABKAISFQoNbWF4aW11bVJhdGluZxgHIAEoAhIWCg5zdXBwb3J0ZWRSYXRlcxgIIAMoAhIbChNsb2NhbGl6ZWRTaG9ydFRpdGxlGAkgASgJEiQKCnJlcGVhdE1vZGUYCiABKA4yEC5SZXBlYXRNb2RlLkVudW0SJgoLc2h1ZmZsZU1vZGUYCyABKA4yES5TaHVmZmxlTW9kZS5FbnVtEhkKEXByZXNlbnRhdGlvblN0eWxlGAwgASgFEhQKDHNraXBJbnRlcnZhbBgNIAEoBRIZChFudW1BdmFpbGFibGVTa2lwcxgOIAEoBRIVCg1za2lwRnJlcXVlbmN5GA8gASgFEhAKCGNhblNjcnViGBAgASgFEiMKG3N1cHBvcnRlZFBsYXliYWNrUXVldWVUeXBlcxgRIAMoBRInCh9zdXBwb3J0ZWRDdXN0b21RdWV1ZUlkZW50aWZpZXJzGBIgAygJEiMKG3N1cHBvcnRlZEluc2VydGlvblBvc2l0aW9ucxgTIAMoBRIXCg91cE5leHRJdGVtQ291bnQYFSABKAUSHQoVcHJlZmVycmVkUGxheWJhY2tSYXRlGBYgASgCEiUKHXN1cHBvcnRlZFBsYXliYWNrU2Vzc2lvblR5cGVzGBcgAygJEiMKG2N1cnJlbnRQbGF5YmFja1Nlc3Npb25UeXBlcxgYIAMoCRIhChlwbGF5YmFja1Nlc3Npb25JZGVudGlmaWVyGBkgASgJEjMKFWN1cnJlbnRRdWV1ZUVuZEFjdGlvbhgaIAEoDjIULlF1ZXVlRW5kQWN0aW9uLkVudW0SNgoYc3VwcG9ydGVkUXVldWVFbmRBY3Rpb25zGBsgAygOMhQuUXVldWVFbmRBY3Rpb24uRW51bRIqCg1kaXNhYmxlUmVhc29uGBwgASgOMhMuRGlzYWJsZVJlYXNvbi5FbnVtEkoKI3N1cHBvcnRlZFBsYXliYWNrU2Vzc2lvbklkZW50aWZpZXJzGB0gAygLMh0uUHJlbG9hZGVkUGxheWJhY2tTZXNzaW9uSW5mbxIfChdwcm9hY3RpdmVDb21tYW5kT3B0aW9ucxgeIAEoDBIbChN2b2NhbHNDb250cm9sQWN0aXZlGB8gASgIEhoKEnZvY2Fsc0NvbnRyb2xMZXZlbBggIAEoDRIdChV2b2NhbHNDb250cm9sTWF4TGV2ZWwYISABKA0SHQoVdm9jYWxzQ29udHJvbE1pbkxldmVsGCIgASgNEh8KF3ZvY2Fsc0NvbnRyb2xDb250aW51b3VzGCMgASgIEhYKDnNsZWVwVGltZXJUaW1lGCQgASgGEhoKEnNsZWVwVGltZXJGaXJlRGF0ZRgmIAEoARIVCg1kaWFsb2dPcHRpb25zGCcgASgMEiEKGXN1cHBvcnRzUmVmZXJlbmNlUG9zaXRpb24YKSABKAgSIwobcGxheWJhY2tTZXNzaW9uUmVxdWlyZW1lbnRzGCogAygJEhcKD3RyYW5zaXRpb25TdHlsZRgrIAEoDSr7CwoHQ29tbWFuZBILCgdVbmtub3duEAASCAoEUGxheRABEgkKBVBhdXNlEAISEwoPVG9nZ2xlUGxheVBhdXNlEAMSCAoEU3RvcBAEEg0KCU5leHRUcmFjaxAFEhEKDVByZXZpb3VzVHJhY2sQBhIWChJBZHZhbmNlU2h1ZmZsZU1vZGUQBxIVChFBZHZhbmNlUmVwZWF0TW9kZRAIEhQKEEJlZ2luRmFzdEZvcndhcmQQCRISCg5FbmRGYXN0Rm9yd2FyZBAKEg8KC0JlZ2luUmV3aW5kEAsSDQoJRW5kUmV3aW5kEAwSEwoPUmV3aW5kMTVTZWNvbmRzEA0SGAoURmFzdEZvcndhcmQxNVNlY29uZHMQDhITCg9SZXdpbmQzMFNlY29uZHMQDxIYChRGYXN0Rm9yd2FyZDMwU2Vjb25kcxAQEg8KC1NraXBGb3J3YXJkEBISEAoMU2tpcEJhY2t3YXJkEBMSFgoSQ2hhbmdlUGxheWJhY2tSYXRlEBQSDQoJUmF0ZVRyYWNrEBUSDQoJTGlrZVRyYWNrEBYSEAoMRGlzbGlrZVRyYWNrEBcSEQoNQm9va21hcmtUcmFjaxAYEhoKFlNlZWtUb1BsYXliYWNrUG9zaXRpb24QLRIUChBDaGFuZ2VSZXBlYXRNb2RlEC4SFQoRQ2hhbmdlU2h1ZmZsZU1vZGUQLxIYChRFbmFibGVMYW5ndWFnZU9wdGlvbhA1EhkKFURpc2FibGVMYW5ndWFnZU9wdGlvbhA2Eg8KC05leHRDaGFwdGVyEBkSEwoPUHJldmlvdXNDaGFwdGVyEBoSDQoJTmV4dEFsYnVtEBsSEQoNUHJldmlvdXNBbGJ1bRAcEhAKDE5leHRQbGF5bGlzdBAdEhQKEFByZXZpb3VzUGxheWxpc3QQHhIMCghCYW5UcmFjaxAfEhYKEkFkZFRyYWNrVG9XaXNoTGlzdBAgEhsKF1JlbW92ZVRyYWNrRnJvbVdpc2hMaXN0ECESEQoNTmV4dEluQ29udGV4dBAiEhUKEVByZXZpb3VzSW5Db250ZXh0ECMSGAoUUmVzZXRQbGF5YmFja1RpbWVvdXQQKRIUChBTZXRQbGF5YmFja1F1ZXVlEDASHgoaQWRkTm93UGxheWluZ0l0ZW1Ub0xpYnJhcnkQMRIWChJDcmVhdGVSYWRpb1N0YXRpb24QMhIUChBBZGRJdGVtVG9MaWJyYXJ5EDMSGwoXSW5zZXJ0SW50b1BsYXliYWNrUXVldWUQNBIYChRSZW9yZGVyUGxheWJhY2tRdWV1ZRA3EhsKF1JlbW92ZUZyb21QbGF5YmFja1F1ZXVlEDgSGwoXUGxheUl0ZW1JblBsYXliYWNrUXVldWUQORIWChJQcmVwYXJlRm9yU2V0UXVldWUQOhIWChJTZXRQbGF5YmFja1Nlc3Npb24QOxIcChhQcmVsb2FkZWRQbGF5YmFja1Nlc3Npb24QPBIhCh1TZXRQcmlvcml0eUZvclBsYXliYWNrU2Vzc2lvbhA9EhoKFkRpc2NhcmRQbGF5YmFja1Nlc3Npb24QPhINCglSZXNodWZmbGUQPxIRCg1TZXRSZXBlYXRNb2RlEEASEgoOU2V0U2h1ZmZsZU1vZGUQQRIRCg1TZXRTbGVlcFRpbWVyEEISDQoJU2V0Vm9sdW1lEEMSEAoMQWRqdXN0Vm9sdW1lEEQSFAoQSW5pdGlhdGVQbGF5YmFjaxBFEhsKF0luaXRpYWxpemVQbGF5YmFja1F1ZXVlEEYSFAoQR2V0UGxheWJhY2tRdWV1ZRBHEhQKEEdldFBsYXliYWNrU3RhdGUQSBIWChJHZXRQbGF5YmFja1Nlc3Npb24QSRIWChJDb29yZGluYXRlUGxheWJhY2sQShIeChpMZWF2ZVNoYXJlZFBsYXliYWNrU2Vzc2lvbhBLEhgKFFByZXBhcmVWb2NhbHNDb250cm9sEEwSEwoPRW5oYW5jZURpYWxvZ3VlEE0SGQoUQ2hhbmdlUXVldWVFbmRBY3Rpb24QhwE", [file_Common]);
|
|
8305
8485
|
/**
|
|
8306
8486
|
* Describes the message QueueEndAction.
|
|
8307
8487
|
* Use `create(QueueEndActionSchema)` to create a new message.
|
|
@@ -8710,7 +8890,7 @@ const SystemPlaybackGenericTracklistQueueSchema = /* @__PURE__ */ messageDesc(fi
|
|
|
8710
8890
|
/**
|
|
8711
8891
|
* Describes the file CommandOptions.proto.
|
|
8712
8892
|
*/
|
|
8713
|
-
const file_CommandOptions = /* @__PURE__ */ fileDesc("
|
|
8893
|
+
const file_CommandOptions = /* @__PURE__ */ fileDesc("ChRDb21tYW5kT3B0aW9ucy5wcm90byLcFAoOQ29tbWFuZE9wdGlvbnMSEAoIc291cmNlSUQYAiABKAkSEQoJbWVkaWFUeXBlGAMgASgJEh0KFWV4dGVybmFsUGxheWVyQ29tbWFuZBgEIAEoCBIUCgxza2lwSW50ZXJ2YWwYBSABKAISFAoMcGxheWJhY2tSYXRlGAYgASgCEg4KBnJhdGluZxgHIAEoAhIQCghuZWdhdGl2ZRgIIAEoCBIYChBwbGF5YmFja1Bvc2l0aW9uGAkgASgBEiQKCnJlcGVhdE1vZGUYCiABKA4yEC5SZXBlYXRNb2RlLkVudW0SJgoLc2h1ZmZsZU1vZGUYCyABKA4yES5TaHVmZmxlTW9kZS5FbnVtEg8KB3RyYWNrSUQYDCABKAQSFgoOcmFkaW9TdGF0aW9uSUQYDSABKAMSGAoQcmFkaW9TdGF0aW9uSGFzaBgOIAEoCRIiChpzeXN0ZW1BcHBQbGF5YmFja1F1ZXVlRGF0YRgPIAEoDBIfChdkZXN0aW5hdGlvbkFwcERpc3BsYXlJRBgQIAEoCRITCgtzZW5kT3B0aW9ucxgRIAEoDRIvCidyZXF1ZXN0RGVmZXJtZW50VG9QbGF5YmFja1F1ZXVlUG9zaXRpb24YEiABKAgSEQoJY29udGV4dElEGBMgASgJEioKInNob3VsZE92ZXJyaWRlTWFudWFsbHlDdXJhdGVkUXVldWUYFCABKAgSEgoKc3RhdGlvblVSTBgVIAEoCRIgChhzaG91bGRCZWdpblJhZGlvUGxheWJhY2sYFiABKAgSJgoecGxheWJhY2tRdWV1ZUluc2VydGlvblBvc2l0aW9uGBcgASgFEhUKDWNvbnRlbnRJdGVtSUQYGCABKAkSGwoTcGxheWJhY2tRdWV1ZU9mZnNldBgZIAEoBRImCh5wbGF5YmFja1F1ZXVlRGVzdGluYXRpb25PZmZzZXQYGiABKAUSFgoObGFuZ3VhZ2VPcHRpb24YGyABKAwSHAoUcGxheWJhY2tRdWV1ZUNvbnRleHQYHCABKAwSIAoYaW5zZXJ0QWZ0ZXJDb250ZW50SXRlbUlEGB0gASgJEh8KF25vd1BsYXlpbmdDb250ZW50SXRlbUlEGB4gASgJEhUKDXJlcGxhY2VJbnRlbnQYHyABKAUSEQoJY29tbWFuZElEGCAgASgJEhAKCHNlbmRlcklEGCEgASgJEh4KFnJlbW90ZUNvbnRyb2xJbnRlcmZhY2UYIiABKAkSEQoJYmVnaW5TZWVrGCggASgEEg8KB2VuZFNlZWsYKSABKAQSFwoPcGxheWJhY2tTZXNzaW9uGCogASgMEhgKEHVzZXJJZGVudGl0eURhdGEYKyABKAwSIQoZaW5zZXJ0QmVmb3JlQ29udGVudEl0ZW1JRBgsIAEoCRIWCg5xdWV1ZUVuZEFjdGlvbhgtIAEoDRIbChNwcmVzZXJ2ZXNSZXBlYXRNb2RlGC4gASgIEhwKFHByZXNlcnZlc1NodWZmbGVNb2RlGC8gASgIEh8KF3ByZXNlcnZlc1F1ZXVlRW5kQWN0aW9uGDAgASgIEh0KFWhvbWVLaXRVc2VySWRlbnRpZmllchgxIAEoCRIfChd2ZXJpZnlTdXBwb3J0ZWRDb21tYW5kcxgyIAEoCBIhChlwbGF5YmFja1Nlc3Npb25JZGVudGlmaWVyGDMgASgJEh8KF3BsYXliYWNrU2Vzc2lvblByaW9yaXR5GDQgASgNEh8KF3BsYXliYWNrU2Vzc2lvbkZpbGVQYXRoGDUgASgJEh8KF3BsYXliYWNrU2Vzc2lvblJldmlzaW9uGDYgASgJEh8KF3BsYXliYWNrU2Vzc2lvbk1ldGFkYXRhGDcgASgMEhsKE3BsYXliYWNrU2Vzc2lvblR5cGUYOCABKAkSFgoOdHJ1ZUNvbXBsZXRpb24YOSABKAgSIgoacGxheWJhY2tBdXRob3JpemF0aW9uVG9rZW4YOiABKAkSFwoPZXZlbnROb3RpY2VUeXBlGDsgASgJEh0KFWV2ZW50Tm90aWNlSWRlbnRpZmllchg8IAEoCRInCh9zaGFyZWRQbGF5YmFja1Nlc3Npb25JZGVudGlmaWVyGD0gASgJEhYKDmNvbW1hbmRUaW1lb3V0GD4gASgEEiAKGGFzc2lzdGFudFRUU0VuZFRpbWVzdGFtcBg/IAEoBBIlCh1hc3Npc3RhbnRDb21tYW5kU2VuZFRpbWVzdGFtcBhAIAEoBBIcChRvcmlnaW5hdGluZ0RldmljZVVJRBhBIAEoCRIdChVkZXN0aW5hdGlvbkRldmljZVVJRHMYQiABKAwSGAoQZGVzaXJlZFNlc3Npb25JRBhDIAEoCRIeChZhbHdheXNJZ25vcmVEdXJpbmdDYWxsGEQgASgIEiMKG2Fsd2F5c0lnbm9yZUR1cmluZ1NoYXJlUGxheRhFIAEoCBIbChNjb21tYW5kU2VxdWVuY2VVVUlEGEYgASgJEiIKGm9yaWdpbmF0ZWRGcm9tUmVtb3RlRGV2aWNlGEcgASgIEhoKEnNpcmlUdXJuSWRlbnRpZmllchhIIAEoCRIjChtzaXJpU2VhcmNoRGF0YVNldElkZW50aWZpZXIYSSABKAkSJQodcHJlcGFyZUZvclNldFF1ZXVlSXNQcm9hY3RpdmUYSiABKAgSKQohcHJlcGFyZUZvclNldFF1ZXVlUHJvYWN0aXZlUmVhc29uGEsgASgJEi0KJXByZXBhcmVGb3JTZXRRdWV1ZVByb2FjdGl2ZVJlYXNvblR5cGUYTCABKA0SHwoXYXBwbGljYXRpb25Vc2VySWRlbnRpdHkYTSABKAwSNAoWc3lzdGVtQXBwUGxheWJhY2tRdWV1ZRhOIAEoCzIULlN5c3RlbVBsYXliYWNrUXVldWUSGwoTdm9jYWxzQ29udHJvbEFjdGl2ZRhPIAEoCBIaChJ2b2NhbHNDb250cm9sTGV2ZWwYUCABKA0SHQoVdm9jYWxzQ29udHJvbE1pbkxldmVsGFEgASgNEh0KFXZvY2Fsc0NvbnRyb2xNYXhMZXZlbBhSIAEoDRIfChd2b2NhbHNDb250cm9sQ29udGludW91cxhTIAEoCBInCh9hc3NvY2lhdGVkUGFydGljaXBhbnRJZGVudGlmaWVyGFQgASgJEhYKDnNsZWVwVGltZXJUaW1lGFUgASgGEhoKEnNsZWVwVGltZXJTdG9wTW9kZRhWIAEoDRIiCg1kaWFsb2dPcHRpb25zGFcgASgLMgsuRGljdGlvbmFyeRIgChhjbGllbnRQcmVmZXJyZWRMYW5ndWFnZXMYWCABKAkSGQoRcmVmZXJlbmNlUG9zaXRpb24YWSABKAYSGwoTZGVsZWdhdGVBY2NvdW50RGF0YRhaIAEoDBIfChdkZWxlZ2F0ZUFjY291bnREYXRhVHlwZRhbIAEoCRIdChVlbmhhbmNlRGlhbG9ndWVBY3RpdmUYXCABKAgSGwoTdXNlckFjdGlvblRpbWVzdGFtcBhfIAEoAQ", [
|
|
8714
8894
|
file_Common,
|
|
8715
8895
|
file_Dictionary,
|
|
8716
8896
|
file_SystemPlaybackQueue
|
|
@@ -8742,7 +8922,7 @@ const configureConnectionMessage = /* @__PURE__ */ extDesc(file_ConfigureConnect
|
|
|
8742
8922
|
/**
|
|
8743
8923
|
* Describes the file ContentItemMetadata.proto.
|
|
8744
8924
|
*/
|
|
8745
|
-
const file_ContentItemMetadata = /* @__PURE__ */ fileDesc("
|
|
8925
|
+
const file_ContentItemMetadata = /* @__PURE__ */ fileDesc("ChlDb250ZW50SXRlbU1ldGFkYXRhLnByb3RvIrkBCg5BdWRpb1JvdXRlVHlwZSKmAQoERW51bRILCgdVbmtub3duEAASEgoORGV2aWNlc1NwZWFrZXIQARILCgdMaW5lT3V0EAISDgoKSGVhZHBob25lcxADEhcKE0JsdWV0b290aEhlYWRwaG9uZXMQBBIUChBCbHVldG9vdGhTcGVha2VyEAUSDAoIVVNCQXVkaW8QBhIMCghDYXJBdWRpbxAHEggKBEhETUkQCBILCgdBaXJQbGF5EAkiWQoKQXVkaW9Sb3V0ZRIdCgR0eXBlGAEgASgLMg8uQXVkaW9Sb3V0ZVR5cGUSDAoEbmFtZRgCIAEoCRIeChZzdXBwb3J0c1NwYXRpYWxpemF0aW9uGAMgASgIInkKCUF1ZGlvVGllciJsCgRFbnVtEhYKEkxvd0JhbmR3aWR0aFN0ZXJlbxABEhUKEUhpZ2hRdWFsaXR5U3RlcmVvEAISDAoITG9zc2xlc3MQAxIaChZIaWdoUmVzb2x1dGlvbkxvc3NsZXNzEAQSCwoHU3BhdGlhbBAFIocBCgpTb25nVHJhaXRzInkKBEVudW0SCAoETm9uZRAAEhcKE0FwcGxlRGlnaXRpYWxNYXN0ZXIQARIMCghMb3NzbGVzcxACEhoKFkhpZ2hSZXNvbHV0aW9uTG9zc2xlc3MQBBILCgdTcGF0aWFsEAgSCQoFQXRtb3MQEBIMCghTdXJyb3VuZBAgIogBCgtBbGJ1bVRyYWl0cyJ5CgRFbnVtEggKBE5vbmUQABIXChNBcHBsZURpZ2l0aWFsTWFzdGVyEAESDAoITG9zc2xlc3MQAhIaChZIaWdoUmVzb2x1dGlvbkxvc3NsZXNzEAQSCwoHU3BhdGlhbBAIEgkKBUF0bW9zEBASDAoIU3Vycm91bmQQICJICg5QbGF5bGlzdFRyYWl0cyI2CgRFbnVtEggKBE5vbmUQABILCgdTcGF0aWFsEAgSCQoFQXRtb3MQEBIMCghTdXJyb3VuZBAgIrwBChlBY3RpdmVGb3JtYXRKdXN0aWZpY2F0aW9uIp4BCgRFbnVtEgsKB1Vua25vd24QABIPCgtVbmF2YWlsYWJsZRABEhIKDlVzZXJQcmVmZXJlbmNlEGQSEAoMVXNlckRvd25sb2FkEGUSFgoRUm91dGVJbmNvbXBhdGlibGUQ9AMSHgoZUm91dGVVbmtub3duQ29tcGF0aWJpbGl0eRD1AxIaChVCYW5kd2lkdGhJbnN1ZmZpY2llbnQQ6AciegoKRm9ybWF0VGllciJsCgRFbnVtEhYKEkxvd0JhbmR3aWR0aFN0ZXJlbxABEhUKEUhpZ2hRdWFsaXR5U3RlcmVvEAISDAoITG9zc2xlc3MQBBIaChZIaWdoUmVzb2x1dGlvbkxvc3NsZXNzEAgSCwoHU3BhdGlhbBAQIoUCCgtBdWRpb0Zvcm1hdBIdCgR0aWVyGAEgASgOMg8uQXVkaW9UaWVyLkVudW0SDwoHYml0cmF0ZRgCIAEoAxISCgpzYW1wbGVSYXRlGAMgASgDEhAKCGJpdERlcHRoGAQgASgDEg0KBWNvZGVjGAUgASgNEhMKC3NwYXRpYWxpemVkGAYgASgIEhQKDG11bHRpQ2hhbm5lbBgHIAEoCBIVCg1jaGFubmVsTGF5b3V0GAggASgNEiUKHWF1ZGlvQ2hhbm5lbExheW91dERlc2NyaXB0aW9uGAkgASgJEg8KB2dyb3VwSUQYCiABKAkSFwoPc3RhYmxlVmFyaWFudElEGAsgASgJIvYYChNDb250ZW50SXRlbU1ldGFkYXRhEg0KBXRpdGxlGAEgASgJEhAKCHN1YnRpdGxlGAIgASgJEhMKC2lzQ29udGFpbmVyGAMgASgIEhIKCmlzUGxheWFibGUYBCABKAgSGAoQcGxheWJhY2tQcm9ncmVzcxgFIAEoAhIRCglhbGJ1bU5hbWUYBiABKAkSFwoPdHJhY2tBcnRpc3ROYW1lGAcgASgJEhcKD2FsYnVtQXJ0aXN0TmFtZRgIIAEoCRIUCgxkaXJlY3Rvck5hbWUYCSABKAkSFAoMc2Vhc29uTnVtYmVyGAogASgFEhUKDWVwaXNvZGVOdW1iZXIYCyABKAUSEwoLcmVsZWFzZURhdGUYDCABKAESEQoJcGxheUNvdW50GA0gASgFEhAKCGR1cmF0aW9uGA4gASgBEh4KFmxvY2FsaXplZENvbnRlbnRSYXRpbmcYDyABKAkSFgoOaXNFeHBsaWNpdEl0ZW0YECABKAgSFAoMcGxheWxpc3RUeXBlGBEgASgFEhgKEHJhZGlvU3RhdGlvblR5cGUYEiABKAUSGAoQYXJ0d29ya0F2YWlsYWJsZRgTIAEoCBIVCg1pbmZvQXZhaWxhYmxlGBUgASgIEiAKGGxhbmd1YWdlT3B0aW9uc0F2YWlsYWJsZRgWIAEoCBIYChBudW1iZXJPZlNlY3Rpb25zGBcgASgFEhcKD2x5cmljc0F2YWlsYWJsZRgYIAEoCBIZChFlZGl0aW5nU3R5bGVGbGFncxgZIAEoBRIaChJpc1N0cmVhbWluZ0NvbnRlbnQYGiABKAgSGgoSaXNDdXJyZW50bHlQbGF5aW5nGBsgASgIEhwKFGNvbGxlY3Rpb25JZGVudGlmaWVyGBwgASgJEhkKEXByb2ZpbGVJZGVudGlmaWVyGB0gASgJEhEKCXN0YXJ0VGltZRgeIAEoARIXCg9hcnR3b3JrTUlNRVR5cGUYHyABKAkSFgoOYXNzZXRVUkxTdHJpbmcYICABKAkSEAoIY29tcG9zZXIYISABKAkSEgoKZGlzY051bWJlchgiIAEoBRITCgtlbGFwc2VkVGltZRgjIAEoARINCgVnZW5yZRgkIAEoCRIUCgxpc0Fsd2F5c0xpdmUYJSABKAgSFAoMcGxheWJhY2tSYXRlGCcgASgCEhQKDGNoYXB0ZXJDb3VudBgoIAEoBRIWCg50b3RhbERpc2NDb3VudBgpIAEoBRIXCg90b3RhbFRyYWNrQ291bnQYKiABKAUSEwoLdHJhY2tOdW1iZXIYKyABKAUSGQoRY29udGVudElkZW50aWZpZXIYLCABKAkSEgoKaXNTaGFyYWJsZRguIAEoCBIPCgdpc0xpa2VkGDAgASgIEhQKDGlzSW5XaXNoTGlzdBgxIAEoCBIeChZyYWRpb1N0YXRpb25JZGVudGlmaWVyGDIgASgDEhgKEHJhZGlvU3RhdGlvbk5hbWUYNCABKAkSGgoScmFkaW9TdGF0aW9uU3RyaW5nGDUgASgJEh0KFWlUdW5lc1N0b3JlSWRlbnRpZmllchg2IAEoAxIpCiFpVHVuZXNTdG9yZVN1YnNjcmlwdGlvbklkZW50aWZpZXIYNyABKAMSIwobaVR1bmVzU3RvcmVBcnRpc3RJZGVudGlmaWVyGDggASgDEiIKGmlUdW5lc1N0b3JlQWxidW1JZGVudGlmaWVyGDkgASgDEhgKEHB1cmNoYXNlSW5mb0RhdGEYOiABKAwSGwoTZGVmYXVsdFBsYXliYWNrUmF0ZRg7IAEoAhIVCg1kb3dubG9hZFN0YXRlGDwgASgFEhgKEGRvd25sb2FkUHJvZ3Jlc3MYPSABKAISFgoOYXBwTWV0cmljc0RhdGEYPiABKAwSEgoKc2VyaWVzTmFtZRg/IAEoCRIxCgltZWRpYVR5cGUYQCABKA4yHi5Db250ZW50SXRlbU1ldGFkYXRhLk1lZGlhVHlwZRI3CgxtZWRpYVN1YlR5cGUYQSABKA4yIS5Db250ZW50SXRlbU1ldGFkYXRhLk1lZGlhU3ViVHlwZRIaChJub3dQbGF5aW5nSW5mb0RhdGEYQyABKAwSFAoMdXNlckluZm9EYXRhGEQgASgMEhMKC2lzU3RlZXJhYmxlGEUgASgIEhIKCmFydHdvcmtVUkwYRiABKAkSEQoJbHlyaWNzVVJMGEcgASgJEiIKGmRldmljZVNwZWNpZmljVXNlckluZm9EYXRhGEggASgMEhoKEmNvbGxlY3Rpb25JbmZvRGF0YRhJIAEoDBIcChRlbGFwc2VkVGltZVRpbWVzdGFtcBhKIAEoARIZChFpbmZlcnJlZFRpbWVzdGFtcBhLIAEoARIZChFzZXJ2aWNlSWRlbnRpZmllchhMIAEoCRIiChphcnR3b3JrRGF0YVdpZHRoRGVwcmVjYXRlZBhNIAEoBRIjChthcnR3b3JrRGF0YUhlaWdodERlcHJlY2F0ZWQYTiABKAUSHwoXY3VycmVudFBsYXliYWNrRGF0ZURhdGEYTyABKAwSGQoRYXJ0d29ya0lkZW50aWZpZXIYUCABKAkSEQoJaXNMb2FkaW5nGFEgASgIEh8KF2FydHdvcmtVUkxUZW1wbGF0ZXNEYXRhGFIgASgMEh4KFmxlZ2FjeVVuaXF1ZUlkZW50aWZpZXIYUyABKAMSEwoLZXBpc29kZVR5cGUYVCABKAUSFgoOYXJ0d29ya0ZpbGVVUkwYVSABKAkSFwoPYnJhbmRJZGVudGlmaWVyGFYgASgJEh8KF2xvY2FsaXplZER1cmF0aW9uU3RyaW5nGFcgASgJEhEKCWFsYnVtWWVhchhYIAEoCRIkCgpzb25nVHJhaXRzGFkgASgOMhAuU29uZ1RyYWl0cy5FbnVtEiYKC2FsYnVtVHJhaXRzGFogASgOMhEuQWxidW1UcmFpdHMuRW51bRIsCg5wbGF5bGlzdFRyYWl0cxhbIAEoDjIULlBsYXlsaXN0VHJhaXRzLkVudW0SJQoPcHJlZmVycmVkRm9ybWF0GFwgASgLMgwuQXVkaW9Gb3JtYXQSIgoMYWN0aXZlRm9ybWF0GF0gASgLMgwuQXVkaW9Gb3JtYXQSQgoZYWN0aXZlRm9ybWF0SnVzdGlmaWNhdGlvbhheIAEoDjIfLkFjdGl2ZUZvcm1hdEp1c3RpZmljYXRpb24uRW51bRIuChRmb3JtYXRUaWVyUHJlZmVyZW5jZRhfIAEoDjIQLkZvcm1hdFRpZXIuRW51bRIfCgphdWRpb1JvdXRlGGAgASgLMgsuQXVkaW9Sb3V0ZRIoChJhbHRlcm5hdGl2ZUZvcm1hdHMYYSADKAsyDC5BdWRpb0Zvcm1hdBIXCg9pc0FkdmVydGlzZW1lbnQYYiABKAgSHQoVaGFzQWx0ZXJuYXRpdmVGb3JtYXRzGGMgASgIEhcKD3BhcnRpY2lwYW50TmFtZRhkIAEoCRIdChVwYXJ0aWNpcGFudElkZW50aWZpZXIYZSABKAkSFQoNY2xhc3NpY2FsV29yaxhmIAEoCRIXCg9yZXBvcnRpbmdBZGFtSUQYZyABKAMSFAoMbHlyaWNzQWRhbUlEGGggASgDEigKIGlUdW5lc1N0b3JlQWxidW1BcnRpc3RJZGVudGlmaWVyGGkgASgDEiUKHWR1cmF0aW9uU3RyaW5nTG9jYWxpemF0aW9uS2V5GGogASgJEh8KF2lzUmVzb2x2YWJsZVBhcnRpY2lwYW50GGsgASgIEioKImludGVybmF0aW9uYWxTdGFuZGFyZFJlY29yZGluZ0NvZGUYbCABKAkSFgoOaXNJblRyYW5zaXRpb24YbSABKAgSHgoWZXhjbHVkZUZyb21TdWdnZXN0aW9ucxhuIAEoCBIlCh10cmFuc2NyaXB0QWxpZ25tZW50c0F2YWlsYWJsZRhvIAEoCBIVCg1zdWJ0aXRsZVNob3J0GHAgASgJEhoKEnRyYW5zaXRpb25JbmZvRGF0YRhxIAEoDBITCgtlbnRpdHlQYXRocxhyIAMoDCI3CglNZWRpYVR5cGUSFAoQVW5rbm93bk1lZGlhVHlwZRAAEgkKBUF1ZGlvEAESCQoFVmlkZW8QAiJbCgxNZWRpYVN1YlR5cGUSFwoTVW5rbm93bk1lZGlhU3ViVHlwZRAAEgkKBU11c2ljEAESCwoHUG9kY2FzdBAEEg0KCUF1ZGlvQm9vaxAFEgsKB0lUdW5lc1UQBg");
|
|
8746
8926
|
/**
|
|
8747
8927
|
* Describes the message AudioRouteType.
|
|
8748
8928
|
* Use `create(AudioRouteTypeSchema)` to create a new message.
|
|
@@ -9224,6 +9404,53 @@ const CryptoPairingMessageSchema = /* @__PURE__ */ messageDesc(file_CryptoPairin
|
|
|
9224
9404
|
*/
|
|
9225
9405
|
const cryptoPairingMessage = /* @__PURE__ */ extDesc(file_CryptoPairingMessage, 0);
|
|
9226
9406
|
|
|
9407
|
+
//#endregion
|
|
9408
|
+
//#region src/proto/DelegationServiceMessage_pb.ts
|
|
9409
|
+
/**
|
|
9410
|
+
* Describes the file DelegationServiceMessage.proto.
|
|
9411
|
+
*/
|
|
9412
|
+
const file_DelegationServiceMessage = /* @__PURE__ */ fileDesc("Ch5EZWxlZ2F0aW9uU2VydmljZU1lc3NhZ2UucHJvdG8ihgIKGERlbGVnYXRpb25TZXJ2aWNlTWVzc2FnZRI3ChZzdGFydERlbGVnYXRpb25SZXF1ZXN0GAEgASgLMhcuU3RhcnREZWxlZ2F0aW9uUmVxdWVzdBI5ChdzdGFydERlbGVnYXRpb25SZXNwb25zZRgCIAEoCzIYLlN0YXJ0RGVsZWdhdGlvblJlc3BvbnNlEjkKF2ZpbmlzaERlbGVnYXRpb25SZXF1ZXN0GAMgASgLMhguRmluaXNoRGVsZWdhdGlvblJlcXVlc3QSOwoYZmluaXNoRGVsZWdhdGlvblJlc3BvbnNlGAQgASgLMhkuRmluaXNoRGVsZWdhdGlvblJlc3BvbnNlIkMKFlN0YXJ0RGVsZWdhdGlvblJlcXVlc3QSEQoJc2VydmljZUlEGAEgASgNEhYKDmRlbGVnYXRpb25VVUlEGAIgASgJIkIKF1N0YXJ0RGVsZWdhdGlvblJlc3BvbnNlEhEKCXNlcnZpY2VJRBgBIAEoDRIUCgxyZXNwb25zZURhdGEYAiABKAwiQQoXRmluaXNoRGVsZWdhdGlvblJlcXVlc3QSEQoJc2VydmljZUlEGAEgASgNEhMKC3JlcXVlc3REYXRhGAIgASgMIj4KGEZpbmlzaERlbGVnYXRpb25SZXNwb25zZRIRCglzZXJ2aWNlSUQYASABKA0SDwoHc3VjY2VzcxgCIAEoCCIrChZQbGF5ZXJJbmZvQ29udGV4dFRva2VuEhEKCXRva2VuRGF0YRgBIAEoCSI/ChdQbGF5ZXJEZWxlZ2F0ZUluZm9Ub2tlbhIRCgl0b2tlbkRhdGEYASABKAkSEQoJc2VydmljZUlEGAIgASgNIkUKHVBsYXllckluZm9Db250ZXh0UmVxdWVzdFRva2VuEhEKCXRva2VuRGF0YRgBIAEoCRIRCglzZXJ2aWNlSUQYAiABKA0", [file_ProtocolMessage]);
|
|
9413
|
+
/**
|
|
9414
|
+
* Describes the message DelegationServiceMessage.
|
|
9415
|
+
* Use `create(DelegationServiceMessageSchema)` to create a new message.
|
|
9416
|
+
*/
|
|
9417
|
+
const DelegationServiceMessageSchema = /* @__PURE__ */ messageDesc(file_DelegationServiceMessage, 0);
|
|
9418
|
+
/**
|
|
9419
|
+
* Describes the message StartDelegationRequest.
|
|
9420
|
+
* Use `create(StartDelegationRequestSchema)` to create a new message.
|
|
9421
|
+
*/
|
|
9422
|
+
const StartDelegationRequestSchema = /* @__PURE__ */ messageDesc(file_DelegationServiceMessage, 1);
|
|
9423
|
+
/**
|
|
9424
|
+
* Describes the message StartDelegationResponse.
|
|
9425
|
+
* Use `create(StartDelegationResponseSchema)` to create a new message.
|
|
9426
|
+
*/
|
|
9427
|
+
const StartDelegationResponseSchema = /* @__PURE__ */ messageDesc(file_DelegationServiceMessage, 2);
|
|
9428
|
+
/**
|
|
9429
|
+
* Describes the message FinishDelegationRequest.
|
|
9430
|
+
* Use `create(FinishDelegationRequestSchema)` to create a new message.
|
|
9431
|
+
*/
|
|
9432
|
+
const FinishDelegationRequestSchema = /* @__PURE__ */ messageDesc(file_DelegationServiceMessage, 3);
|
|
9433
|
+
/**
|
|
9434
|
+
* Describes the message FinishDelegationResponse.
|
|
9435
|
+
* Use `create(FinishDelegationResponseSchema)` to create a new message.
|
|
9436
|
+
*/
|
|
9437
|
+
const FinishDelegationResponseSchema = /* @__PURE__ */ messageDesc(file_DelegationServiceMessage, 4);
|
|
9438
|
+
/**
|
|
9439
|
+
* Describes the message PlayerInfoContextToken.
|
|
9440
|
+
* Use `create(PlayerInfoContextTokenSchema)` to create a new message.
|
|
9441
|
+
*/
|
|
9442
|
+
const PlayerInfoContextTokenSchema = /* @__PURE__ */ messageDesc(file_DelegationServiceMessage, 5);
|
|
9443
|
+
/**
|
|
9444
|
+
* Describes the message PlayerDelegateInfoToken.
|
|
9445
|
+
* Use `create(PlayerDelegateInfoTokenSchema)` to create a new message.
|
|
9446
|
+
*/
|
|
9447
|
+
const PlayerDelegateInfoTokenSchema = /* @__PURE__ */ messageDesc(file_DelegationServiceMessage, 6);
|
|
9448
|
+
/**
|
|
9449
|
+
* Describes the message PlayerInfoContextRequestToken.
|
|
9450
|
+
* Use `create(PlayerInfoContextRequestTokenSchema)` to create a new message.
|
|
9451
|
+
*/
|
|
9452
|
+
const PlayerInfoContextRequestTokenSchema = /* @__PURE__ */ messageDesc(file_DelegationServiceMessage, 7);
|
|
9453
|
+
|
|
9227
9454
|
//#endregion
|
|
9228
9455
|
//#region src/proto/Destination_pb.ts
|
|
9229
9456
|
/**
|
|
@@ -10062,7 +10289,7 @@ const microphoneConnectionResponseMessage = /* @__PURE__ */ extDesc(file_Microph
|
|
|
10062
10289
|
/**
|
|
10063
10290
|
* Describes the file ModifyOutputContextRequestMessage.proto.
|
|
10064
10291
|
*/
|
|
10065
|
-
const file_ModifyOutputContextRequestMessage = /* @__PURE__ */ fileDesc("
|
|
10292
|
+
const file_ModifyOutputContextRequestMessage = /* @__PURE__ */ fileDesc("CidNb2RpZnlPdXRwdXRDb250ZXh0UmVxdWVzdE1lc3NhZ2UucHJvdG8iRQoeTW9kaWZ5T3V0cHV0Q29udGV4dFJlcXVlc3RUeXBlIiMKBEVudW0SGwoXU2hhcmVkQXVkaW9QcmVzZW50YXRpb24QASLOAgohTW9kaWZ5T3V0cHV0Q29udGV4dFJlcXVlc3RNZXNzYWdlEj8KEW91dHB1dENvbnRleHRUeXBlGAEgASgOMiQuTW9kaWZ5T3V0cHV0Q29udGV4dFJlcXVlc3RUeXBlLkVudW0SHgoWYWRkaW5nT3V0cHV0RGV2aWNlVUlEcxgCIAMoCRIgChhyZW1vdmluZ091dHB1dERldmljZVVJRHMYAyADKAkSHwoXc2V0dGluZ091dHB1dERldmljZVVJRHMYBCADKAkSKgoiY2x1c3RlckF3YXJlQWRkaW5nT3V0cHV0RGV2aWNlVUlEcxgFIAMoCRIsCiRjbHVzdGVyQXdhcmVSZW1vdmluZ091dHB1dERldmljZVVJRHMYBiADKAkSKwojY2x1c3RlckF3YXJlU2V0dGluZ091dHB1dERldmljZVVJRHMYByADKAk6ggEKIW1vZGlmeU91dHB1dENvbnRleHRSZXF1ZXN0TWVzc2FnZRIQLlByb3RvY29sTWVzc2FnZRg0IAEoCzIiLk1vZGlmeU91dHB1dENvbnRleHRSZXF1ZXN0TWVzc2FnZVIhbW9kaWZ5T3V0cHV0Q29udGV4dFJlcXVlc3RNZXNzYWdl", [file_ProtocolMessage]);
|
|
10066
10293
|
/**
|
|
10067
10294
|
* Describes the message ModifyOutputContextRequestType.
|
|
10068
10295
|
* Use `create(ModifyOutputContextRequestTypeSchema)` to create a new message.
|
|
@@ -10204,7 +10431,7 @@ const PlaybackQueueContextSchema = /* @__PURE__ */ messageDesc(file_PlaybackQueu
|
|
|
10204
10431
|
/**
|
|
10205
10432
|
* Describes the file PlaybackQueue.proto.
|
|
10206
10433
|
*/
|
|
10207
|
-
const file_PlaybackQueue = /* @__PURE__ */ fileDesc("
|
|
10434
|
+
const file_PlaybackQueue = /* @__PURE__ */ fileDesc("ChNQbGF5YmFja1F1ZXVlLnByb3RvIvsCCg1QbGF5YmFja1F1ZXVlEhAKCGxvY2F0aW9uGAEgASgFEiIKDGNvbnRlbnRJdGVtcxgCIAMoCzIMLkNvbnRlbnRJdGVtEiYKB2NvbnRleHQYAyABKAsyFS5QbGF5YmFja1F1ZXVlQ29udGV4dBIRCglyZXF1ZXN0SUQYBCABKAkSJwoScmVzb2x2ZWRQbGF5ZXJQYXRoGAUgASgLMgsuUGxheWVyUGF0aBInCh9zZW5kaW5nUGxheWJhY2tRdWV1ZVRyYW5zYWN0aW9uGAYgASgIEhcKD3F1ZXVlSWRlbnRpZmllchgHIAEoCRIiCgxwYXJ0aWNpcGFudHMYCCADKAsyDC5Db250ZW50SXRlbRIbChNob21lVXNlcklkZW50aWZpZXJzGAkgAygJEh8KCnByb3BlcnRpZXMYCiABKAsyCy5EaWN0aW9uYXJ5EiwKF2F1eGlsaWFyeU5vd1BsYXlpbmdJbmZvGAsgASgLMgsuRGljdGlvbmFyeQ", [
|
|
10208
10435
|
file_ContentItem,
|
|
10209
10436
|
file_Dictionary,
|
|
10210
10437
|
file_PlaybackQueueContext,
|
|
@@ -12016,6 +12243,7 @@ var proto_exports = /* @__PURE__ */ __exportAll({
|
|
|
12016
12243
|
CreateHostedEndpointResponseSchema: () => CreateHostedEndpointResponseSchema,
|
|
12017
12244
|
CryptoPairingMessageSchema: () => CryptoPairingMessageSchema,
|
|
12018
12245
|
DataArtworkSchema: () => DataArtworkSchema,
|
|
12246
|
+
DelegationServiceMessageSchema: () => DelegationServiceMessageSchema,
|
|
12019
12247
|
DestinationSchema: () => DestinationSchema,
|
|
12020
12248
|
DeviceClassSchema: () => DeviceClassSchema,
|
|
12021
12249
|
DeviceClass_Enum: () => DeviceClass_Enum,
|
|
@@ -12040,6 +12268,8 @@ var proto_exports = /* @__PURE__ */ __exportAll({
|
|
|
12040
12268
|
ErrorCode_Enum: () => ErrorCode_Enum,
|
|
12041
12269
|
ErrorCode_EnumSchema: () => ErrorCode_EnumSchema,
|
|
12042
12270
|
ErrorSchema: () => ErrorSchema,
|
|
12271
|
+
FinishDelegationRequestSchema: () => FinishDelegationRequestSchema,
|
|
12272
|
+
FinishDelegationResponseSchema: () => FinishDelegationResponseSchema,
|
|
12043
12273
|
FormatTierSchema: () => FormatTierSchema,
|
|
12044
12274
|
FormatTier_Enum: () => FormatTier_Enum,
|
|
12045
12275
|
FormatTier_EnumSchema: () => FormatTier_EnumSchema,
|
|
@@ -12141,6 +12371,9 @@ var proto_exports = /* @__PURE__ */ __exportAll({
|
|
|
12141
12371
|
PlaybackState_EnumSchema: () => PlaybackState_EnumSchema,
|
|
12142
12372
|
PlayerClientParticipantsUpdateMessageSchema: () => PlayerClientParticipantsUpdateMessageSchema,
|
|
12143
12373
|
PlayerClientPropertiesMessageSchema: () => PlayerClientPropertiesMessageSchema,
|
|
12374
|
+
PlayerDelegateInfoTokenSchema: () => PlayerDelegateInfoTokenSchema,
|
|
12375
|
+
PlayerInfoContextRequestTokenSchema: () => PlayerInfoContextRequestTokenSchema,
|
|
12376
|
+
PlayerInfoContextTokenSchema: () => PlayerInfoContextTokenSchema,
|
|
12144
12377
|
PlayerOptionsSchema: () => PlayerOptionsSchema,
|
|
12145
12378
|
PlayerOptions_Enum: () => PlayerOptions_Enum,
|
|
12146
12379
|
PlayerOptions_EnumSchema: () => PlayerOptions_EnumSchema,
|
|
@@ -12238,6 +12471,8 @@ var proto_exports = /* @__PURE__ */ __exportAll({
|
|
|
12238
12471
|
SongTraitsSchema: () => SongTraitsSchema,
|
|
12239
12472
|
SongTraits_Enum: () => SongTraits_Enum,
|
|
12240
12473
|
SongTraits_EnumSchema: () => SongTraits_EnumSchema,
|
|
12474
|
+
StartDelegationRequestSchema: () => StartDelegationRequestSchema,
|
|
12475
|
+
StartDelegationResponseSchema: () => StartDelegationResponseSchema,
|
|
12241
12476
|
SupportedCommandsSchema: () => SupportedCommandsSchema,
|
|
12242
12477
|
SystemPlaybackCustomDataSchema: () => SystemPlaybackCustomDataSchema,
|
|
12243
12478
|
SystemPlaybackGenericTracklistQueueSchema: () => SystemPlaybackGenericTracklistQueueSchema,
|
|
@@ -12311,6 +12546,7 @@ var proto_exports = /* @__PURE__ */ __exportAll({
|
|
|
12311
12546
|
file_CreateHostedEndpointRequestMessage: () => file_CreateHostedEndpointRequestMessage,
|
|
12312
12547
|
file_CreateHostedEndpointResponseMessage: () => file_CreateHostedEndpointResponseMessage,
|
|
12313
12548
|
file_CryptoPairingMessage: () => file_CryptoPairingMessage,
|
|
12549
|
+
file_DelegationServiceMessage: () => file_DelegationServiceMessage,
|
|
12314
12550
|
file_Destination: () => file_Destination,
|
|
12315
12551
|
file_DeviceInfoMessage: () => file_DeviceInfoMessage,
|
|
12316
12552
|
file_Diagnostic: () => file_Diagnostic,
|
|
@@ -12945,6 +13181,121 @@ var ControlStream = class extends RtspClient {
|
|
|
12945
13181
|
return await this.exchange("POST", `/volume?volume=${volume.toFixed(6)}`, { allowError: true });
|
|
12946
13182
|
}
|
|
12947
13183
|
/**
|
|
13184
|
+
* Sets the audio routing mode on the receiver.
|
|
13185
|
+
*
|
|
13186
|
+
* @param mode - The audio mode to set (e.g. 'default', 'moviePlayback', 'spoken').
|
|
13187
|
+
* @returns The response.
|
|
13188
|
+
*/
|
|
13189
|
+
async setAudioMode(mode) {
|
|
13190
|
+
const body = Plist.serialize({ audioMode: mode });
|
|
13191
|
+
return await this.exchange("POST", "/audioMode", {
|
|
13192
|
+
body: Buffer.from(body),
|
|
13193
|
+
headers: { "Content-Type": "application/x-apple-binary-plist" },
|
|
13194
|
+
allowError: true
|
|
13195
|
+
});
|
|
13196
|
+
}
|
|
13197
|
+
/**
|
|
13198
|
+
* Stops the current URL playback session.
|
|
13199
|
+
*
|
|
13200
|
+
* @returns The response.
|
|
13201
|
+
*/
|
|
13202
|
+
async stop() {
|
|
13203
|
+
return await this.exchange("POST", "/stop", { allowError: true });
|
|
13204
|
+
}
|
|
13205
|
+
/**
|
|
13206
|
+
* Seeks to a specific position during URL playback.
|
|
13207
|
+
*
|
|
13208
|
+
* @param position - The position in seconds to seek to.
|
|
13209
|
+
* @returns The response.
|
|
13210
|
+
*/
|
|
13211
|
+
async scrub(position) {
|
|
13212
|
+
return await this.exchange("POST", `/scrub?position=${position.toFixed(6)}`, { allowError: true });
|
|
13213
|
+
}
|
|
13214
|
+
/**
|
|
13215
|
+
* Sends an RTSP FLUSHBUFFERED request to flush buffered audio.
|
|
13216
|
+
*
|
|
13217
|
+
* More targeted than FLUSH — specifically for buffered audio sessions.
|
|
13218
|
+
* Supports range-based flushing via flushFromSeq/TS and flushUntilSeq/TS headers.
|
|
13219
|
+
*
|
|
13220
|
+
* @param uri - RTSP resource URI (typically `/{sessionId}`).
|
|
13221
|
+
* @param headers - Additional headers (e.g. flush range parameters).
|
|
13222
|
+
* @returns The RTSP response.
|
|
13223
|
+
*/
|
|
13224
|
+
async flushBuffered(uri, headers = {}) {
|
|
13225
|
+
return await this.exchange("FLUSHBUFFERED", uri, {
|
|
13226
|
+
headers,
|
|
13227
|
+
allowError: true
|
|
13228
|
+
});
|
|
13229
|
+
}
|
|
13230
|
+
/**
|
|
13231
|
+
* Gets a property from the AirPlay receiver.
|
|
13232
|
+
*
|
|
13233
|
+
* Known property keys (from AirPlayReceiver framework):
|
|
13234
|
+
*
|
|
13235
|
+
* **Volume:**
|
|
13236
|
+
* - `Volume` — current volume
|
|
13237
|
+
* - `VolumeDB` — volume in decibels
|
|
13238
|
+
* - `VolumeLinear` — linear volume (0.0-1.0)
|
|
13239
|
+
* - `SoftwareVolume` — software volume level
|
|
13240
|
+
* - `VolumeControlType` / `VolumeControlTypeEx` — volume control capabilities
|
|
13241
|
+
* - `IsMuted` / `MuteForStream` — mute state
|
|
13242
|
+
*
|
|
13243
|
+
* **Playback:**
|
|
13244
|
+
* - `ReceiverDeviceIsPlaying` — whether the device is currently playing
|
|
13245
|
+
* - `IsPlayingBufferedAudio` — whether buffered audio is active
|
|
13246
|
+
* - `DenyInterruptions` — interruption prevention state
|
|
13247
|
+
*
|
|
13248
|
+
* **Audio:**
|
|
13249
|
+
* - `AudioFormat` — current audio format
|
|
13250
|
+
* - `AudioLatencyMs` / `AudioLatencyMax` / `AudioLatencyMin` — latency info
|
|
13251
|
+
* - `RedundantAudio` — redundancy status
|
|
13252
|
+
* - `SpatialAudio` / `SpatialAudioActive` / `SpatialAudioAllowed` — spatial audio state
|
|
13253
|
+
*
|
|
13254
|
+
* **Device:**
|
|
13255
|
+
* - `DeviceID` / `DeviceName` — device identity
|
|
13256
|
+
* - `IdleTimeout` — idle timeout value
|
|
13257
|
+
* - `SecurityMode` — security mode
|
|
13258
|
+
* - `ReceiverMode` — current receiver mode
|
|
13259
|
+
*
|
|
13260
|
+
* **Display:**
|
|
13261
|
+
* - `DisplayHDRMode` — HDR mode
|
|
13262
|
+
* - `DisplaySize` / `DisplaySizeMax` — display dimensions
|
|
13263
|
+
* - `DisplayUUID` — display identifier
|
|
13264
|
+
*
|
|
13265
|
+
* **Cluster/Multi-room:**
|
|
13266
|
+
* - `ClusterUUID` / `ClusterType` / `ClusterSize` — cluster info
|
|
13267
|
+
* - `IsClusterLeader` / `ClusterLeaderUUID` — cluster leadership
|
|
13268
|
+
* - `TightSyncUUID` / `IsTightSyncGroupLeader` — tight sync state
|
|
13269
|
+
* - `GroupContainsDiscoverableLeader` / `GroupContextID` — group info
|
|
13270
|
+
*
|
|
13271
|
+
* **Network:**
|
|
13272
|
+
* - `UsePTPClock` — PTP clock usage
|
|
13273
|
+
* - `NetworkClock` — network clock type
|
|
13274
|
+
*
|
|
13275
|
+
* **DACP-style (via setproperty? URL):**
|
|
13276
|
+
* - `dmcp.device-volume` — DACP device volume
|
|
13277
|
+
* - `dmcp.device-prevent-playback` — DACP prevent playback
|
|
13278
|
+
*
|
|
13279
|
+
* @param property - The property key to query.
|
|
13280
|
+
* @returns The response (body contains the property value, typically as plist).
|
|
13281
|
+
*/
|
|
13282
|
+
async getProperty(property) {
|
|
13283
|
+
return await this.get(`/getProperty?${property}`);
|
|
13284
|
+
}
|
|
13285
|
+
/**
|
|
13286
|
+
* Sets a property on the AirPlay receiver.
|
|
13287
|
+
*
|
|
13288
|
+
* See {@link getProperty} for the full list of known property keys.
|
|
13289
|
+
* For set operations, the property string contains key=value pairs.
|
|
13290
|
+
*
|
|
13291
|
+
* @param property - The property key=value to set (e.g. `Volume=0.5`).
|
|
13292
|
+
* @param body - Optional request body for complex property values (plist).
|
|
13293
|
+
* @returns The response.
|
|
13294
|
+
*/
|
|
13295
|
+
async setProperty(property, body) {
|
|
13296
|
+
return await this.put(`/setProperty?${property}`, body);
|
|
13297
|
+
}
|
|
13298
|
+
/**
|
|
12948
13299
|
* Sends an RTSP TEARDOWN request to end a stream session.
|
|
12949
13300
|
*
|
|
12950
13301
|
* @param path - RTSP resource URI (typically `/{sessionId}`).
|
|
@@ -13053,13 +13404,220 @@ var DataStream = class extends BaseStream {
|
|
|
13053
13404
|
this.#handlers[ProtocolMessage_Type.UPDATE_CONTENT_ITEM_MESSAGE] = [updateContentItemMessage, this.#onUpdateContentItemMessage.bind(this)];
|
|
13054
13405
|
this.#handlers[ProtocolMessage_Type.UPDATE_CONTENT_ITEM_ARTWORK_MESSAGE] = [updateContentItemArtworkMessage, this.#onUpdateContentItemArtworkMessage.bind(this)];
|
|
13055
13406
|
this.#handlers[ProtocolMessage_Type.UPDATE_PLAYER_MESSAGE] = [updatePlayerMessage, this.#onUpdatePlayerMessage.bind(this)];
|
|
13056
|
-
this.#handlers[ProtocolMessage_Type.
|
|
13407
|
+
this.#handlers[ProtocolMessage_Type.SYNC_OUTPUT_DEVICES_MESSAGE] = [updateOutputDeviceMessage, this.#onUpdateOutputDeviceMessage.bind(this)];
|
|
13057
13408
|
this.#handlers[ProtocolMessage_Type.VOLUME_CONTROL_AVAILABILITY_MESSAGE] = [volumeControlAvailabilityMessage, this.#onVolumeControlAvailabilityMessage.bind(this)];
|
|
13058
13409
|
this.#handlers[ProtocolMessage_Type.VOLUME_CONTROL_CAPABILITIES_DID_CHANGE_MESSAGE] = [volumeControlCapabilitiesDidChangeMessage, this.#onVolumeControlCapabilitiesDidChangeMessage.bind(this)];
|
|
13059
13410
|
this.#handlers[ProtocolMessage_Type.VOLUME_DID_CHANGE_MESSAGE] = [volumeDidChangeMessage, this.#onVolumeDidChangeMessage.bind(this)];
|
|
13060
13411
|
this.#handlers[ProtocolMessage_Type.VOLUME_MUTED_DID_CHANGE_MESSAGE] = [volumeMutedDidChangeMessage, this.#onVolumeMutedDidChangeMessage.bind(this)];
|
|
13061
13412
|
this.#handlers[ProtocolMessage_Type.SEND_LYRICS_EVENT] = [sendLyricsEventMessage, this.#onSendLyricsEventMessage.bind(this)];
|
|
13062
13413
|
this.#handlers[ProtocolMessage_Type.CONFIGURE_CONNECTION_MESSAGE] = [configureConnectionMessage, this.#onConfigureConnectionMessage.bind(this)];
|
|
13414
|
+
this.#handlers[ProtocolMessage_Type.PLAYER_CLIENT_PARTICIPANTS_UPDATE_MESSAGE] = [playerClientParticipantsUpdateMessage, this.#onPlayerClientParticipantsUpdateMessage.bind(this)];
|
|
13415
|
+
const auto = [
|
|
13416
|
+
[
|
|
13417
|
+
ProtocolMessage_Type.AUDIO_FADE_MESSAGE,
|
|
13418
|
+
audioFadeMessage,
|
|
13419
|
+
"audioFade"
|
|
13420
|
+
],
|
|
13421
|
+
[
|
|
13422
|
+
ProtocolMessage_Type.AUDIO_FADE_RESPONSE_MESSAGE,
|
|
13423
|
+
audioFadeResponseMessage,
|
|
13424
|
+
"audioFadeResponse"
|
|
13425
|
+
],
|
|
13426
|
+
[
|
|
13427
|
+
ProtocolMessage_Type.ADJUST_VOLUME_MESSAGE,
|
|
13428
|
+
adjustVolumeMessage,
|
|
13429
|
+
"adjustVolume"
|
|
13430
|
+
],
|
|
13431
|
+
[
|
|
13432
|
+
ProtocolMessage_Type.GET_VOLUME_RESULT_MESSAGE,
|
|
13433
|
+
getVolumeResultMessage,
|
|
13434
|
+
"getVolumeResult"
|
|
13435
|
+
],
|
|
13436
|
+
[
|
|
13437
|
+
ProtocolMessage_Type.GET_VOLUME_MUTED_RESULT_MESSAGE,
|
|
13438
|
+
getVolumeMutedResultMessage,
|
|
13439
|
+
"getVolumeMutedResult"
|
|
13440
|
+
],
|
|
13441
|
+
[
|
|
13442
|
+
ProtocolMessage_Type.NOTIFICATION_MESSAGE,
|
|
13443
|
+
notificationMessage,
|
|
13444
|
+
"notification"
|
|
13445
|
+
],
|
|
13446
|
+
[
|
|
13447
|
+
ProtocolMessage_Type.SET_CONNECTION_STATE_MESSAGE,
|
|
13448
|
+
setConnectionStateMessage,
|
|
13449
|
+
"setConnectionState"
|
|
13450
|
+
],
|
|
13451
|
+
[
|
|
13452
|
+
ProtocolMessage_Type.SET_DISCOVERY_MODE_MESSAGE,
|
|
13453
|
+
setDiscoveryModeMessage,
|
|
13454
|
+
"setDiscoveryMode"
|
|
13455
|
+
],
|
|
13456
|
+
[
|
|
13457
|
+
ProtocolMessage_Type.SET_LISTENING_MODE_MESSAGE,
|
|
13458
|
+
setListeningModeMessage,
|
|
13459
|
+
"setListeningMode"
|
|
13460
|
+
],
|
|
13461
|
+
[
|
|
13462
|
+
ProtocolMessage_Type.TRANSACTION_MESSAGE,
|
|
13463
|
+
transactionMessage,
|
|
13464
|
+
"transaction"
|
|
13465
|
+
],
|
|
13466
|
+
[
|
|
13467
|
+
ProtocolMessage_Type.UPDATE_ACTIVE_SYSTEM_ENDPOINT_MESSAGE,
|
|
13468
|
+
updateActiveSystemEndpointMessage,
|
|
13469
|
+
"updateActiveSystemEndpoint"
|
|
13470
|
+
],
|
|
13471
|
+
[
|
|
13472
|
+
ProtocolMessage_Type.UPDATE_SYNCED_ENDPOINTS_MESSAGE,
|
|
13473
|
+
updateEndPointsMessage,
|
|
13474
|
+
"updateEndpoints"
|
|
13475
|
+
],
|
|
13476
|
+
[
|
|
13477
|
+
ProtocolMessage_Type.REMOVE_SYNCED_ENDPOINTS_MESSAGE,
|
|
13478
|
+
removeEndpointsMessage,
|
|
13479
|
+
"removeEndpoints"
|
|
13480
|
+
],
|
|
13481
|
+
[
|
|
13482
|
+
ProtocolMessage_Type.REMOVE_SYNCED_OUTPUT_DEVICES_MESSAGE,
|
|
13483
|
+
removeOutputDevicesMessage,
|
|
13484
|
+
"removeOutputDevices"
|
|
13485
|
+
],
|
|
13486
|
+
[
|
|
13487
|
+
ProtocolMessage_Type.WAKE_DEVICE_MESSAGE,
|
|
13488
|
+
wakeDeviceMessage,
|
|
13489
|
+
"wakeDevice"
|
|
13490
|
+
],
|
|
13491
|
+
[
|
|
13492
|
+
ProtocolMessage_Type.GENERIC_MESSAGE,
|
|
13493
|
+
genericMessage,
|
|
13494
|
+
"genericMessage"
|
|
13495
|
+
],
|
|
13496
|
+
[
|
|
13497
|
+
ProtocolMessage_Type.PLAYBACK_SESSION_REQUEST_MESSAGE,
|
|
13498
|
+
playbackSessionRequestMessage,
|
|
13499
|
+
"playbackSessionRequest"
|
|
13500
|
+
],
|
|
13501
|
+
[
|
|
13502
|
+
ProtocolMessage_Type.PLAYBACK_SESSION_RESPONSE_MESSAGE,
|
|
13503
|
+
playbackSessionResponseMessage,
|
|
13504
|
+
"playbackSessionResponse"
|
|
13505
|
+
],
|
|
13506
|
+
[
|
|
13507
|
+
ProtocolMessage_Type.PLAYBACK_SESSION_MIGRATE_REQUEST_MESSAGE,
|
|
13508
|
+
playbackSessionMigrateRequestMessage,
|
|
13509
|
+
"playbackSessionMigrateRequest"
|
|
13510
|
+
],
|
|
13511
|
+
[
|
|
13512
|
+
ProtocolMessage_Type.PLAYBACK_SESSION_MIGRATE_RESPONSE_MESSAGE,
|
|
13513
|
+
playbackSessionMigrateResponseMessage,
|
|
13514
|
+
"playbackSessionMigrateResponse"
|
|
13515
|
+
],
|
|
13516
|
+
[
|
|
13517
|
+
ProtocolMessage_Type.PLAYBACK_SESSION_MIGRATE_BEGIN_MESSAGE,
|
|
13518
|
+
playbackSessionMigrateBeginMessage,
|
|
13519
|
+
"playbackSessionMigrateBegin"
|
|
13520
|
+
],
|
|
13521
|
+
[
|
|
13522
|
+
ProtocolMessage_Type.PLAYBACK_SESSION_MIGRATE_END_MESSAGE,
|
|
13523
|
+
playbackSessionMigrateEndMessage,
|
|
13524
|
+
"playbackSessionMigrateEnd"
|
|
13525
|
+
],
|
|
13526
|
+
[
|
|
13527
|
+
ProtocolMessage_Type.PLAYBACK_SESSION_MIGRATE_POST_MESSAGE,
|
|
13528
|
+
playbackSessionMigratePostMessage,
|
|
13529
|
+
"playbackSessionMigratePost"
|
|
13530
|
+
],
|
|
13531
|
+
[
|
|
13532
|
+
ProtocolMessage_Type.CREATE_HOSTED_ENDPOINT_REQUEST_MESSAGE,
|
|
13533
|
+
createHostedEndpointRequest,
|
|
13534
|
+
"createHostedEndpointRequest"
|
|
13535
|
+
],
|
|
13536
|
+
[
|
|
13537
|
+
ProtocolMessage_Type.CREATE_HOSTED_ENDPOINT_RESPONSE_MESSAGE,
|
|
13538
|
+
createHostedEndpointResponse,
|
|
13539
|
+
"createHostedEndpointResponse"
|
|
13540
|
+
],
|
|
13541
|
+
[
|
|
13542
|
+
ProtocolMessage_Type.PROMPT_FOR_ROUTE_AUTHORIZATION_MESSAGE,
|
|
13543
|
+
promptForRouteAuthorizationMessage,
|
|
13544
|
+
"promptForRouteAuthorization"
|
|
13545
|
+
],
|
|
13546
|
+
[
|
|
13547
|
+
ProtocolMessage_Type.PROMPT_FOR_ROUTE_AUTHORIZATION_RESPONSE_MESSAGE,
|
|
13548
|
+
promptForRouteAuthorizationResponseMessage,
|
|
13549
|
+
"promptForRouteAuthorizationResponse"
|
|
13550
|
+
],
|
|
13551
|
+
[
|
|
13552
|
+
ProtocolMessage_Type.PRESENT_ROUTE_AUTHORIZATION_STATUS_MESSAGE,
|
|
13553
|
+
presentRouteAuthorizationStatusMessage,
|
|
13554
|
+
"presentRouteAuthorizationStatus"
|
|
13555
|
+
],
|
|
13556
|
+
[
|
|
13557
|
+
ProtocolMessage_Type.REQUEST_GROUP_SESSION_MESSAGE,
|
|
13558
|
+
requestGroupSessionMessage,
|
|
13559
|
+
"requestGroupSession"
|
|
13560
|
+
],
|
|
13561
|
+
[
|
|
13562
|
+
ProtocolMessage_Type.MICROPHONE_CONNECTION_REQUEST_MESSAGE,
|
|
13563
|
+
microphoneConnectionRequestMessage,
|
|
13564
|
+
"microphoneConnectionRequest"
|
|
13565
|
+
],
|
|
13566
|
+
[
|
|
13567
|
+
ProtocolMessage_Type.MICROPHONE_CONNECTION_RESPONSE_MESSAGE,
|
|
13568
|
+
microphoneConnectionResponseMessage,
|
|
13569
|
+
"microphoneConnectionResponse"
|
|
13570
|
+
],
|
|
13571
|
+
[
|
|
13572
|
+
ProtocolMessage_Type.CREATE_APPLICATION_CONNECTION_MESSAGE,
|
|
13573
|
+
createApplicationConnectionMessage,
|
|
13574
|
+
"createApplicationConnection"
|
|
13575
|
+
],
|
|
13576
|
+
[
|
|
13577
|
+
ProtocolMessage_Type.SET_HILITE_MODE_MESSAGE,
|
|
13578
|
+
setHiliteModeMessage,
|
|
13579
|
+
"setHiliteMode"
|
|
13580
|
+
],
|
|
13581
|
+
[
|
|
13582
|
+
ProtocolMessage_Type.TEXT_INPUT_MESSAGE,
|
|
13583
|
+
textInputMessage,
|
|
13584
|
+
"textInput"
|
|
13585
|
+
],
|
|
13586
|
+
[
|
|
13587
|
+
ProtocolMessage_Type.REMOTE_TEXT_INPUT_MESSAGE,
|
|
13588
|
+
remoteTextInputMessage,
|
|
13589
|
+
"remoteTextInput"
|
|
13590
|
+
],
|
|
13591
|
+
[
|
|
13592
|
+
ProtocolMessage_Type.CRYPTO_PAIRING_MESSAGE,
|
|
13593
|
+
cryptoPairingMessage,
|
|
13594
|
+
"cryptoPairing"
|
|
13595
|
+
],
|
|
13596
|
+
[
|
|
13597
|
+
ProtocolMessage_Type.GAME_CONTROLLER_MESSAGE,
|
|
13598
|
+
gameControllerMessage,
|
|
13599
|
+
"gameController"
|
|
13600
|
+
],
|
|
13601
|
+
[
|
|
13602
|
+
ProtocolMessage_Type.GAME_CONTROLLER_PROPERTIES_MESSAGE,
|
|
13603
|
+
gameControllerPropertiesMessage,
|
|
13604
|
+
"gameControllerProperties"
|
|
13605
|
+
],
|
|
13606
|
+
[
|
|
13607
|
+
ProtocolMessage_Type.REGISTER_GAME_CONTROLLER_MESSAGE,
|
|
13608
|
+
registerGameControllerMessage,
|
|
13609
|
+
"registerGameController"
|
|
13610
|
+
],
|
|
13611
|
+
[
|
|
13612
|
+
ProtocolMessage_Type.REGISTER_GAME_CONTROLLER_RESPONSE_MESSAGE,
|
|
13613
|
+
registerGameControllerResponseMessage,
|
|
13614
|
+
"registerGameControllerResponse"
|
|
13615
|
+
]
|
|
13616
|
+
];
|
|
13617
|
+
for (const [type, extension, eventName] of auto) if (!(type in this.#handlers)) this.#handlers[type] = [extension, (msg) => {
|
|
13618
|
+
this.context.logger.info("[data]", `${eventName}`, msg);
|
|
13619
|
+
this.emit(eventName, msg);
|
|
13620
|
+
}];
|
|
13063
13621
|
}
|
|
13064
13622
|
/**
|
|
13065
13623
|
* Disconnects the data stream, rejecting all outstanding exchanges and clearing buffers.
|
|
@@ -13148,20 +13706,7 @@ var DataStream = class extends BaseStream {
|
|
|
13148
13706
|
* @param seed - Random 64-bit seed sent in the SETUP request.
|
|
13149
13707
|
*/
|
|
13150
13708
|
setup(sharedSecret, seed) {
|
|
13151
|
-
const readKey =
|
|
13152
|
-
hash: "sha512",
|
|
13153
|
-
key: sharedSecret,
|
|
13154
|
-
length: 32,
|
|
13155
|
-
salt: Buffer.from(`DataStream-Salt${seed}`),
|
|
13156
|
-
info: Buffer.from("DataStream-Input-Encryption-Key")
|
|
13157
|
-
});
|
|
13158
|
-
const writeKey = hkdf({
|
|
13159
|
-
hash: "sha512",
|
|
13160
|
-
key: sharedSecret,
|
|
13161
|
-
length: 32,
|
|
13162
|
-
salt: Buffer.from(`DataStream-Salt${seed}`),
|
|
13163
|
-
info: Buffer.from("DataStream-Output-Encryption-Key")
|
|
13164
|
-
});
|
|
13709
|
+
const { readKey, writeKey } = deriveEncryptionKeys(sharedSecret, `DataStream-Salt${seed}`, "DataStream-Input-Encryption-Key", "DataStream-Output-Encryption-Key");
|
|
13165
13710
|
this.enableEncryption(readKey, writeKey);
|
|
13166
13711
|
}
|
|
13167
13712
|
/**
|
|
@@ -13444,6 +13989,15 @@ var DataStream = class extends BaseStream {
|
|
|
13444
13989
|
this.emit("updateOutputDevice", message);
|
|
13445
13990
|
}
|
|
13446
13991
|
/**
|
|
13992
|
+
* Handles playback queue participant updates (e.g. SharePlay users).
|
|
13993
|
+
*
|
|
13994
|
+
* @param message - The decoded PlayerClientParticipantsUpdateMessage.
|
|
13995
|
+
*/
|
|
13996
|
+
#onPlayerClientParticipantsUpdateMessage(message) {
|
|
13997
|
+
this.context.logger.info("[data]", "Player client participants update", message);
|
|
13998
|
+
this.emit("playerClientParticipantsUpdate", message);
|
|
13999
|
+
}
|
|
14000
|
+
/**
|
|
13447
14001
|
* Handles volume control availability changes.
|
|
13448
14002
|
*
|
|
13449
14003
|
* @param message - The decoded VolumeControlAvailabilityMessage.
|
|
@@ -13512,7 +14066,7 @@ var DataStream = class extends BaseStream {
|
|
|
13512
14066
|
* The stream is encrypted with ChaCha20-Poly1305 after setup. Note that the
|
|
13513
14067
|
* HKDF info strings are swapped compared to what you might expect: the key
|
|
13514
14068
|
* derived from 'Events-Write-Encryption-Key' becomes our read key, because
|
|
13515
|
-
* these names are from the Apple TV's perspective
|
|
14069
|
+
* these names are from the Apple TV's perspective.
|
|
13516
14070
|
*/
|
|
13517
14071
|
var EventStream = class extends BaseStream {
|
|
13518
14072
|
/** Accumulated plaintext buffer for partial RTSP request reassembly. */
|
|
@@ -13569,20 +14123,7 @@ var EventStream = class extends BaseStream {
|
|
|
13569
14123
|
* @param sharedSecret - Shared secret from pair-verify.
|
|
13570
14124
|
*/
|
|
13571
14125
|
setup(sharedSecret) {
|
|
13572
|
-
const readKey =
|
|
13573
|
-
hash: "sha512",
|
|
13574
|
-
key: sharedSecret,
|
|
13575
|
-
length: 32,
|
|
13576
|
-
salt: Buffer.from("Events-Salt"),
|
|
13577
|
-
info: Buffer.from("Events-Read-Encryption-Key")
|
|
13578
|
-
});
|
|
13579
|
-
const writeKey = hkdf({
|
|
13580
|
-
hash: "sha512",
|
|
13581
|
-
key: sharedSecret,
|
|
13582
|
-
length: 32,
|
|
13583
|
-
salt: Buffer.from("Events-Salt"),
|
|
13584
|
-
info: Buffer.from("Events-Write-Encryption-Key")
|
|
13585
|
-
});
|
|
14126
|
+
const { readKey, writeKey } = deriveEncryptionKeys(sharedSecret, "Events-Salt", "Events-Read-Encryption-Key", "Events-Write-Encryption-Key");
|
|
13586
14127
|
this.enableEncryption(writeKey, readKey);
|
|
13587
14128
|
}
|
|
13588
14129
|
/**
|
|
@@ -13606,14 +14147,20 @@ var EventStream = class extends BaseStream {
|
|
|
13606
14147
|
async #handle(method, path, headers, body) {
|
|
13607
14148
|
const key = `${method} ${path}`;
|
|
13608
14149
|
switch (key) {
|
|
13609
|
-
case "POST /command":
|
|
14150
|
+
case "POST /command": {
|
|
13610
14151
|
const data = Plist.parse(body.buffer.slice(body.byteOffset, body.byteOffset + body.byteLength));
|
|
13611
|
-
|
|
14152
|
+
const commandType = data.type;
|
|
14153
|
+
this.context.logger.info("[event]", "Received command:", commandType ?? "unknown", data);
|
|
14154
|
+
this.emit("command", data);
|
|
14155
|
+
if (commandType === "cycleUsePickedRoute" || commandType === "duckAudio") this.emit("duckAudio", data);
|
|
14156
|
+
else if (commandType === "unduckAudio") this.emit("unduckAudio", data);
|
|
14157
|
+
else if (commandType === "died") this.emit("sessionDied");
|
|
13612
14158
|
this.respond(200, "OK", {
|
|
13613
14159
|
"Audio-Latency": 0,
|
|
13614
14160
|
"CSeq": headers["CSeq"] ?? 0
|
|
13615
14161
|
});
|
|
13616
14162
|
break;
|
|
14163
|
+
}
|
|
13617
14164
|
default:
|
|
13618
14165
|
this.context.logger.warn("[event]", "No handler for url", key);
|
|
13619
14166
|
this.respond(200, "OK", { "CSeq": headers["CSeq"] ?? 0 });
|
|
@@ -13809,21 +14356,10 @@ var Verify = class {
|
|
|
13809
14356
|
*/
|
|
13810
14357
|
async start(credentials) {
|
|
13811
14358
|
const keys = await this.#internal.start(credentials);
|
|
14359
|
+
const { readKey: accessoryToControllerKey, writeKey: controllerToAccessoryKey } = deriveEncryptionKeys(keys.sharedSecret, "Control-Salt", "Control-Read-Encryption-Key", "Control-Write-Encryption-Key");
|
|
13812
14360
|
return {
|
|
13813
|
-
accessoryToControllerKey
|
|
13814
|
-
|
|
13815
|
-
key: keys.sharedSecret,
|
|
13816
|
-
length: 32,
|
|
13817
|
-
salt: Buffer.from("Control-Salt"),
|
|
13818
|
-
info: Buffer.from("Control-Read-Encryption-Key")
|
|
13819
|
-
}),
|
|
13820
|
-
controllerToAccessoryKey: hkdf({
|
|
13821
|
-
hash: "sha512",
|
|
13822
|
-
key: keys.sharedSecret,
|
|
13823
|
-
length: 32,
|
|
13824
|
-
salt: Buffer.from("Control-Salt"),
|
|
13825
|
-
info: Buffer.from("Control-Write-Encryption-Key")
|
|
13826
|
-
}),
|
|
14361
|
+
accessoryToControllerKey,
|
|
14362
|
+
controllerToAccessoryKey,
|
|
13827
14363
|
pairingId: keys.pairingId,
|
|
13828
14364
|
sharedSecret: keys.sharedSecret
|
|
13829
14365
|
};
|
|
@@ -13844,106 +14380,9 @@ var Verify = class {
|
|
|
13844
14380
|
}
|
|
13845
14381
|
};
|
|
13846
14382
|
|
|
13847
|
-
//#endregion
|
|
13848
|
-
//#region src/features.ts
|
|
13849
|
-
/**
|
|
13850
|
-
* AirPlay feature flags as a 64-bit bitmask.
|
|
13851
|
-
*
|
|
13852
|
-
* Each flag represents a capability advertised by AirPlay senders or receivers
|
|
13853
|
-
* in the `features`/`featuresEx` fields of SETUP and /info responses. The lower
|
|
13854
|
-
* 32 bits map to `features`, the upper 32 bits to `featuresEx`.
|
|
13855
|
-
*
|
|
13856
|
-
* Sources: pyatv, Apple framework disassembly (AirPlayReceiver sysInfo_createFeaturesInternal),
|
|
13857
|
-
* https://emanuelecozzi.net/docs/airplay2/features/
|
|
13858
|
-
*/
|
|
13859
|
-
const AirPlayFeature = {
|
|
13860
|
-
SupportsAirPlayVideoV1: 1n << 0n,
|
|
13861
|
-
SupportsAirPlayPhoto: 1n << 1n,
|
|
13862
|
-
SupportsAirPlaySlideShow: 1n << 5n,
|
|
13863
|
-
SupportsAirPlayScreen: 1n << 7n,
|
|
13864
|
-
SupportsAirPlayAudio: 1n << 9n,
|
|
13865
|
-
AudioRedundant: 1n << 11n,
|
|
13866
|
-
Authentication4: 1n << 14n,
|
|
13867
|
-
MetadataFeatures0: 1n << 15n,
|
|
13868
|
-
MetadataFeatures1: 1n << 16n,
|
|
13869
|
-
MetadataFeatures2: 1n << 17n,
|
|
13870
|
-
AudioFormats0: 1n << 18n,
|
|
13871
|
-
AudioFormats1: 1n << 19n,
|
|
13872
|
-
AudioFormats2: 1n << 20n,
|
|
13873
|
-
AudioFormats3: 1n << 21n,
|
|
13874
|
-
Authentication1: 1n << 23n,
|
|
13875
|
-
Authentication8: 1n << 26n,
|
|
13876
|
-
SupportsLegacyPairing: 1n << 27n,
|
|
13877
|
-
HasUnifiedAdvertiserInfo: 1n << 30n,
|
|
13878
|
-
SupportsVolume: 1n << 32n,
|
|
13879
|
-
SupportsAirPlayVideoPlayQueue: 1n << 33n,
|
|
13880
|
-
SupportsAirPlayFromCloud: 1n << 34n,
|
|
13881
|
-
SupportsTLSPSK: 1n << 35n,
|
|
13882
|
-
SupportsUnifiedMediaControl: 1n << 38n,
|
|
13883
|
-
SupportsBufferedAudio: 1n << 40n,
|
|
13884
|
-
SupportsPTP: 1n << 41n,
|
|
13885
|
-
SupportsScreenMultiCodec: 1n << 42n,
|
|
13886
|
-
SupportsSystemPairing: 1n << 43n,
|
|
13887
|
-
IsAPValeriaScreenSender: 1n << 44n,
|
|
13888
|
-
SupportsHKPairingAndAccessControl: 1n << 46n,
|
|
13889
|
-
SupportsCoreUtilsPairingAndEncryption: 1n << 48n,
|
|
13890
|
-
SupportsAirPlayVideoV2: 1n << 49n,
|
|
13891
|
-
MetadataFeatures3: 1n << 50n,
|
|
13892
|
-
SupportsUnifiedPairSetupAndMFi: 1n << 51n,
|
|
13893
|
-
SupportsSetPeersExtendedMessage: 1n << 52n,
|
|
13894
|
-
SupportsAPSync: 1n << 54n,
|
|
13895
|
-
SupportsWoL: 1n << 55n,
|
|
13896
|
-
SupportsWoL2: 1n << 56n,
|
|
13897
|
-
SupportsHangdogRemoteControl: 1n << 58n,
|
|
13898
|
-
SupportsAudioStreamConnectionSetup: 1n << 59n,
|
|
13899
|
-
SupportsAudioMetadataControl: 1n << 60n,
|
|
13900
|
-
SupportsRFC2198Redundancy: 1n << 61n
|
|
13901
|
-
};
|
|
13902
|
-
/**
|
|
13903
|
-
* Feature bitmask advertised when connecting for remote control sessions.
|
|
13904
|
-
*
|
|
13905
|
-
* Includes media control, system pairing, encryption, volume, and
|
|
13906
|
-
* hangdog remote control capabilities.
|
|
13907
|
-
*/
|
|
13908
|
-
const SENDER_FEATURES_REMOTE_CONTROL = AirPlayFeature.SupportsAirPlayAudio | AirPlayFeature.AudioRedundant | AirPlayFeature.MetadataFeatures0 | AirPlayFeature.MetadataFeatures1 | AirPlayFeature.MetadataFeatures2 | AirPlayFeature.MetadataFeatures3 | AirPlayFeature.Authentication4 | AirPlayFeature.Authentication1 | AirPlayFeature.HasUnifiedAdvertiserInfo | AirPlayFeature.SupportsUnifiedMediaControl | AirPlayFeature.SupportsSystemPairing | AirPlayFeature.SupportsCoreUtilsPairingAndEncryption | AirPlayFeature.SupportsHKPairingAndAccessControl | AirPlayFeature.SupportsHangdogRemoteControl | AirPlayFeature.SupportsAPSync | AirPlayFeature.SupportsSetPeersExtendedMessage | AirPlayFeature.SupportsVolume;
|
|
13909
|
-
/**
|
|
13910
|
-
* Feature bitmask advertised when connecting for audio streaming sessions.
|
|
13911
|
-
*
|
|
13912
|
-
* Extends the remote control features with buffered audio, audio stream
|
|
13913
|
-
* connection setup, metadata control, format negotiation, and PTP
|
|
13914
|
-
* synchronization support.
|
|
13915
|
-
*/
|
|
13916
|
-
const SENDER_FEATURES_AUDIO = SENDER_FEATURES_REMOTE_CONTROL | AirPlayFeature.SupportsBufferedAudio | AirPlayFeature.SupportsAudioStreamConnectionSetup | AirPlayFeature.SupportsAudioMetadataControl | AirPlayFeature.AudioFormats0 | AirPlayFeature.AudioFormats1 | AirPlayFeature.AudioFormats2 | AirPlayFeature.AudioFormats3 | AirPlayFeature.SupportsPTP;
|
|
13917
|
-
/**
|
|
13918
|
-
* Checks whether a feature bitmask contains a specific feature flag.
|
|
13919
|
-
*
|
|
13920
|
-
* @param features - The combined feature bitmask to test.
|
|
13921
|
-
* @param feature - The individual feature flag to check for.
|
|
13922
|
-
* @returns `true` if the feature is present.
|
|
13923
|
-
*/
|
|
13924
|
-
const hasFeature = (features, feature) => (features & feature) === feature;
|
|
13925
|
-
/**
|
|
13926
|
-
* Decodes a feature bitmask into a list of human-readable flag names.
|
|
13927
|
-
*
|
|
13928
|
-
* @param features - The combined feature bitmask to decode.
|
|
13929
|
-
* @returns Array of feature names that are set in the bitmask.
|
|
13930
|
-
*/
|
|
13931
|
-
const decodeFeatures = (features) => {
|
|
13932
|
-
const result = [];
|
|
13933
|
-
for (const [name, bit] of Object.entries(AirPlayFeature)) if ((features & bit) === bit) result.push(name);
|
|
13934
|
-
return result;
|
|
13935
|
-
};
|
|
13936
|
-
|
|
13937
14383
|
//#endregion
|
|
13938
14384
|
//#region src/protocol.ts
|
|
13939
14385
|
/**
|
|
13940
|
-
* Compares two semver-like version strings component by component.
|
|
13941
|
-
*
|
|
13942
|
-
* @param a - First version string (e.g. "935.7.1").
|
|
13943
|
-
* @param b - Second version string (e.g. "935.7").
|
|
13944
|
-
* @returns Negative if a < b, positive if a > b, 0 if equal.
|
|
13945
|
-
*/
|
|
13946
|
-
/**
|
|
13947
14386
|
* Parses a feature value from /info which can be a number, hex string, or decimal string.
|
|
13948
14387
|
*/
|
|
13949
14388
|
function parseFeatureValue(value) {
|
|
@@ -14008,6 +14447,14 @@ var Protocol = class {
|
|
|
14008
14447
|
get discoveryResult() {
|
|
14009
14448
|
return this.#discoveryResult;
|
|
14010
14449
|
}
|
|
14450
|
+
/**
|
|
14451
|
+
* The receiver's dedicated keep-alive port, or undefined if not provided.
|
|
14452
|
+
* Returned by the receiver in the SETUP response. Can be used for a
|
|
14453
|
+
* separate low-power keep-alive TCP connection.
|
|
14454
|
+
*/
|
|
14455
|
+
get keepAlivePort() {
|
|
14456
|
+
return this.#keepAlivePort;
|
|
14457
|
+
}
|
|
14011
14458
|
/** The active audio stream, or undefined if not streaming audio. */
|
|
14012
14459
|
get audioStream() {
|
|
14013
14460
|
return this.#audioStream;
|
|
@@ -14038,6 +14485,7 @@ var Protocol = class {
|
|
|
14038
14485
|
#dataStream;
|
|
14039
14486
|
#effectiveSourceVersion;
|
|
14040
14487
|
#eventStream;
|
|
14488
|
+
#keepAlivePort;
|
|
14041
14489
|
#playUrlFeedbackInterval;
|
|
14042
14490
|
#receiverFeatures = 0n;
|
|
14043
14491
|
#receiverInfo;
|
|
@@ -14049,7 +14497,7 @@ var Protocol = class {
|
|
|
14049
14497
|
constructor(discoveryResult, identity) {
|
|
14050
14498
|
this.#context = new Context(discoveryResult.id, identity);
|
|
14051
14499
|
this.#discoveryResult = discoveryResult;
|
|
14052
|
-
this.#sessionUUID = uuid();
|
|
14500
|
+
this.#sessionUUID = uuid().toUpperCase();
|
|
14053
14501
|
this.#controlStream = new ControlStream(this.#context, discoveryResult.address, discoveryResult.service.port);
|
|
14054
14502
|
this.#pairing = new Pairing(this);
|
|
14055
14503
|
this.#verify = new Verify(this);
|
|
@@ -14069,7 +14517,7 @@ var Protocol = class {
|
|
|
14069
14517
|
* @returns `true` if the receiver advertises support for this feature.
|
|
14070
14518
|
*/
|
|
14071
14519
|
hasReceiverFeature(feature) {
|
|
14072
|
-
return
|
|
14520
|
+
return hasFeatureFlag(this.#receiverFeatures, feature);
|
|
14073
14521
|
}
|
|
14074
14522
|
/**
|
|
14075
14523
|
* Opens the TCP connection to the AirPlay RTSP server.
|
|
@@ -14101,7 +14549,7 @@ var Protocol = class {
|
|
|
14101
14549
|
this.#receiverFeatures = features;
|
|
14102
14550
|
}
|
|
14103
14551
|
this.context.logger.info("[protocol]", `Receiver: ${info.name ?? "unknown"}, model=${info.model ?? "?"}, sourceVersion=${receiverSourceVersion ?? "?"}`);
|
|
14104
|
-
this.context.logger.info("[protocol]", `Receiver features: ${
|
|
14552
|
+
this.context.logger.info("[protocol]", `Receiver features: ${describeFlags(this.#receiverFeatures).join(", ")}`);
|
|
14105
14553
|
if (info.initialVolume != null) this.context.logger.info("[protocol]", `Receiver initial volume: ${info.initialVolume}`);
|
|
14106
14554
|
if (receiverSourceVersion) {
|
|
14107
14555
|
if (compareVersions(String(this.#context.identity.sourceVersion), receiverSourceVersion) > 0) {
|
|
@@ -14162,9 +14610,14 @@ var Protocol = class {
|
|
|
14162
14610
|
*
|
|
14163
14611
|
* The feedback loop keeps the AirPlay session alive. Uses a 1.9s timeout
|
|
14164
14612
|
* (slightly less than the 2s interval) to avoid overlapping requests.
|
|
14613
|
+
*
|
|
14614
|
+
* Optionally includes session stats in the body (Apple's `keepAliveSendStatsAsBody`
|
|
14615
|
+
* pattern), which gives the receiver better information about connection quality.
|
|
14616
|
+
*
|
|
14617
|
+
* @param stats - Optional stats to include in the feedback body (plist-serializable).
|
|
14165
14618
|
*/
|
|
14166
|
-
async feedback() {
|
|
14167
|
-
await this.#controlStream.post("/feedback",
|
|
14619
|
+
async feedback(stats) {
|
|
14620
|
+
await this.#controlStream.post("/feedback", stats, void 0, 1900);
|
|
14168
14621
|
}
|
|
14169
14622
|
/**
|
|
14170
14623
|
* Sets the playback volume on the receiver.
|
|
@@ -14175,6 +14628,25 @@ var Protocol = class {
|
|
|
14175
14628
|
await this.#controlStream.setVolume(volume);
|
|
14176
14629
|
}
|
|
14177
14630
|
/**
|
|
14631
|
+
* Gets a property value from the AirPlay receiver.
|
|
14632
|
+
*
|
|
14633
|
+
* @param property - The property key to query (e.g. 'dmcp.device-volume').
|
|
14634
|
+
* @returns The RTSP response (body contains the value, typically plist-encoded).
|
|
14635
|
+
*/
|
|
14636
|
+
async getProperty(property) {
|
|
14637
|
+
return await this.#controlStream.getProperty(property);
|
|
14638
|
+
}
|
|
14639
|
+
/**
|
|
14640
|
+
* Sets a property value on the AirPlay receiver.
|
|
14641
|
+
*
|
|
14642
|
+
* @param property - The property key=value string (e.g. 'dmcp.device-volume=0.5').
|
|
14643
|
+
* @param body - Optional body for complex property values.
|
|
14644
|
+
* @returns The RTSP response.
|
|
14645
|
+
*/
|
|
14646
|
+
async setProperty(property, body) {
|
|
14647
|
+
return await this.#controlStream.setProperty(property, body);
|
|
14648
|
+
}
|
|
14649
|
+
/**
|
|
14178
14650
|
* Sets up and connects the MRP data stream for protobuf-based remote control.
|
|
14179
14651
|
*
|
|
14180
14652
|
* Sends an RTSP SETUP request for a type 130 (MRP) stream with a dedicated
|
|
@@ -14211,11 +14683,10 @@ var Protocol = class {
|
|
|
14211
14683
|
* Sends an RTSP SETUP request and parses the plist response.
|
|
14212
14684
|
*
|
|
14213
14685
|
* @param body - Plist body for the SETUP request.
|
|
14214
|
-
* @param sharedSecret - Optional shared secret (unused, reserved for future use).
|
|
14215
14686
|
* @returns Parsed plist response from the receiver.
|
|
14216
14687
|
* @throws SetupError if the SETUP request returns a non-200 status.
|
|
14217
14688
|
*/
|
|
14218
|
-
async #performSetup(body
|
|
14689
|
+
async #performSetup(body) {
|
|
14219
14690
|
const response = await this.#controlStream.setup(`/${this.#controlStream.sessionId}`, body);
|
|
14220
14691
|
if (response.status !== 200) {
|
|
14221
14692
|
this.context.logger.error("[protocol]", "Failed SETUP request.", response.status, response.statusText, await response.text());
|
|
@@ -14223,7 +14694,10 @@ var Protocol = class {
|
|
|
14223
14694
|
}
|
|
14224
14695
|
const plist = Plist.parse(await response.arrayBuffer());
|
|
14225
14696
|
if (plist.enabledFeatures != null) this.context.logger.info("[protocol]", `Receiver enabled features: 0x${BigInt(plist.enabledFeatures).toString(16)}`);
|
|
14226
|
-
if (plist.keepAlivePort != null)
|
|
14697
|
+
if (plist.keepAlivePort != null) {
|
|
14698
|
+
this.#keepAlivePort = plist.keepAlivePort;
|
|
14699
|
+
this.context.logger.info("[protocol]", `Receiver keep-alive port: ${plist.keepAlivePort}`);
|
|
14700
|
+
}
|
|
14227
14701
|
return plist;
|
|
14228
14702
|
}
|
|
14229
14703
|
/**
|
|
@@ -14269,7 +14743,7 @@ var Protocol = class {
|
|
|
14269
14743
|
body.timingPort = this.#timingServer.port;
|
|
14270
14744
|
body.timingProtocol = "NTP";
|
|
14271
14745
|
}
|
|
14272
|
-
const eventPort = (await this.#performSetup(body
|
|
14746
|
+
const eventPort = (await this.#performSetup(body)).eventPort & 65535;
|
|
14273
14747
|
this.context.logger.net("[protocol]", `Connecting to event stream on port ${eventPort}...`);
|
|
14274
14748
|
this.#eventStream?.destroy();
|
|
14275
14749
|
this.#eventStream = new EventStream(this.#context, this.#controlStream.address, eventPort);
|
|
@@ -14304,7 +14778,7 @@ var Protocol = class {
|
|
|
14304
14778
|
body.timingPort = this.#timingServer.port;
|
|
14305
14779
|
body.timingProtocol = "NTP";
|
|
14306
14780
|
}
|
|
14307
|
-
const eventPort = (await this.#performSetup(body
|
|
14781
|
+
const eventPort = (await this.#performSetup(body)).eventPort & 65535;
|
|
14308
14782
|
this.context.logger.net("[protocol]", `Connecting to event stream on port ${eventPort}...`);
|
|
14309
14783
|
this.#eventStream?.destroy();
|
|
14310
14784
|
this.#eventStream = new EventStream(this.#context, this.#controlStream.address, eventPort);
|
|
@@ -14333,10 +14807,13 @@ var Protocol = class {
|
|
|
14333
14807
|
async playUrl(url, sharedSecret, pairingId, position = 0) {
|
|
14334
14808
|
const setupBody = {
|
|
14335
14809
|
...this.#setupBody(pairingId, SENDER_FEATURES_AUDIO),
|
|
14336
|
-
isMultiSelectAirPlay: true,
|
|
14337
14810
|
groupContainsGroupLeader: false,
|
|
14811
|
+
groupUUID: uuid(),
|
|
14812
|
+
isMultiSelectAirPlay: true,
|
|
14338
14813
|
senderSupportsRelay: false,
|
|
14339
|
-
statsCollectionEnabled: false
|
|
14814
|
+
statsCollectionEnabled: false,
|
|
14815
|
+
supportsGroupCohesion: true,
|
|
14816
|
+
updateSessionRequest: false
|
|
14340
14817
|
};
|
|
14341
14818
|
if (this.#timingServer) {
|
|
14342
14819
|
setupBody.timingPort = this.#timingServer.port;
|
|
@@ -14531,6 +15008,8 @@ var Protocol = class {
|
|
|
14531
15008
|
//#endregion
|
|
14532
15009
|
//#region src/dataStreamMessages.ts
|
|
14533
15010
|
var dataStreamMessages_exports = /* @__PURE__ */ __exportAll({
|
|
15011
|
+
adjustVolume: () => adjustVolume,
|
|
15012
|
+
audioFade: () => audioFade,
|
|
14534
15013
|
clientUpdatesConfig: () => clientUpdatesConfig,
|
|
14535
15014
|
configureConnection: () => configureConnection,
|
|
14536
15015
|
deviceInfo: () => deviceInfo,
|
|
@@ -14542,7 +15021,10 @@ var dataStreamMessages_exports = /* @__PURE__ */ __exportAll({
|
|
|
14542
15021
|
modifyOutputContext: () => modifyOutputContext,
|
|
14543
15022
|
notification: () => notification,
|
|
14544
15023
|
playbackQueueRequest: () => playbackQueueRequest,
|
|
15024
|
+
playbackSessionMigrateBegin: () => playbackSessionMigrateBegin,
|
|
15025
|
+
playbackSessionMigrateEnd: () => playbackSessionMigrateEnd,
|
|
14545
15026
|
protocol: () => protocol,
|
|
15027
|
+
requestGroupSession: () => requestGroupSession,
|
|
14546
15028
|
sendButtonEvent: () => sendButtonEvent,
|
|
14547
15029
|
sendCommand: () => sendCommand,
|
|
14548
15030
|
sendCommandWithPlaybackPosition: () => sendCommandWithPlaybackPosition,
|
|
@@ -14550,10 +15032,13 @@ var dataStreamMessages_exports = /* @__PURE__ */ __exportAll({
|
|
|
14550
15032
|
sendCommandWithRepeatMode: () => sendCommandWithRepeatMode,
|
|
14551
15033
|
sendCommandWithShuffleMode: () => sendCommandWithShuffleMode,
|
|
14552
15034
|
sendCommandWithSkipInterval: () => sendCommandWithSkipInterval,
|
|
15035
|
+
sendCommandWithSleepTimer: () => sendCommandWithSleepTimer,
|
|
14553
15036
|
sendHIDEvent: () => sendHIDEvent,
|
|
14554
15037
|
sendVirtualTouchEvent: () => sendVirtualTouchEvent,
|
|
14555
15038
|
setConnectionState: () => setConnectionState,
|
|
14556
15039
|
setConversationDetectionEnabled: () => setConversationDetectionEnabled,
|
|
15040
|
+
setDiscoveryMode: () => setDiscoveryMode,
|
|
15041
|
+
setListeningMode: () => setListeningMode,
|
|
14557
15042
|
setReadyState: () => setReadyState,
|
|
14558
15043
|
setVolume: () => setVolume,
|
|
14559
15044
|
setVolumeMuted: () => setVolumeMuted,
|
|
@@ -14593,7 +15078,7 @@ function protocol(type, errorCode = ErrorCode_Enum.NoError) {
|
|
|
14593
15078
|
* @param systemEndpointUpdates - Subscribe to system endpoint changes.
|
|
14594
15079
|
* @returns Tuple of [ProtocolMessage, extension descriptor] for sending via DataStream.
|
|
14595
15080
|
*/
|
|
14596
|
-
function clientUpdatesConfig(artworkUpdates = true, nowPlayingUpdates = true, volumeUpdates = true, keyboardUpdates = false, outputDeviceUpdates =
|
|
15081
|
+
function clientUpdatesConfig(artworkUpdates = true, nowPlayingUpdates = true, volumeUpdates = true, keyboardUpdates = false, outputDeviceUpdates = false, systemEndpointUpdates = true, subscribedPlayerPaths = []) {
|
|
14597
15082
|
const protocolMessage = protocol(ProtocolMessage_Type.CLIENT_UPDATES_CONFIG_MESSAGE);
|
|
14598
15083
|
const message = create(ClientUpdatesConfigMessageSchema, {
|
|
14599
15084
|
artworkUpdates,
|
|
@@ -14601,7 +15086,8 @@ function clientUpdatesConfig(artworkUpdates = true, nowPlayingUpdates = true, vo
|
|
|
14601
15086
|
volumeUpdates,
|
|
14602
15087
|
keyboardUpdates,
|
|
14603
15088
|
outputDeviceUpdates,
|
|
14604
|
-
systemEndpointUpdates
|
|
15089
|
+
systemEndpointUpdates,
|
|
15090
|
+
subscribedPlayerPaths
|
|
14605
15091
|
});
|
|
14606
15092
|
setExtension(protocolMessage, clientUpdatesConfigMessage, message);
|
|
14607
15093
|
return [protocolMessage, clientUpdatesConfigMessage];
|
|
@@ -14638,19 +15124,22 @@ function deviceInfo(pairingId, identity) {
|
|
|
14638
15124
|
applicationBundleIdentifier: identity.applicationBundleIdentifier,
|
|
14639
15125
|
applicationBundleVersion: identity.applicationBundleVersion,
|
|
14640
15126
|
protocolVersion: 1,
|
|
14641
|
-
lastSupportedMessageType:
|
|
15127
|
+
lastSupportedMessageType: 139,
|
|
14642
15128
|
supportsSystemPairing: true,
|
|
14643
15129
|
allowsPairing: true,
|
|
14644
15130
|
systemMediaApplication: "com.apple.TVMusic",
|
|
14645
15131
|
supportsACL: true,
|
|
14646
15132
|
supportsSharedQueue: true,
|
|
14647
15133
|
supportsExtendedMotion: true,
|
|
14648
|
-
sharedQueueVersion:
|
|
15134
|
+
sharedQueueVersion: 3,
|
|
14649
15135
|
deviceClass: DeviceClass_Enum.iPhone,
|
|
14650
15136
|
logicalDeviceCount: 1,
|
|
14651
15137
|
modelID: identity.model,
|
|
14652
15138
|
clusterType: 0,
|
|
14653
15139
|
isClusterAware: true,
|
|
15140
|
+
isGroupLeader: false,
|
|
15141
|
+
isProxyGroupPlayer: false,
|
|
15142
|
+
groupContainsDiscoverableGroupLeader: 0,
|
|
14654
15143
|
supportsOutputContextSync: true,
|
|
14655
15144
|
computerName: identity.name
|
|
14656
15145
|
});
|
|
@@ -14670,13 +15159,13 @@ function deviceInfo(pairingId, identity) {
|
|
|
14670
15159
|
function modifyOutputContext(addingDevices = [], removingDevices = [], settingDevices = []) {
|
|
14671
15160
|
const protocolMessage = protocol(ProtocolMessage_Type.MODIFY_OUTPUT_CONTEXT_REQUEST_MESSAGE);
|
|
14672
15161
|
const message = create(ModifyOutputContextRequestMessageSchema, {
|
|
14673
|
-
|
|
14674
|
-
addingDevices,
|
|
14675
|
-
removingDevices,
|
|
14676
|
-
settingDevices,
|
|
14677
|
-
|
|
14678
|
-
|
|
14679
|
-
|
|
15162
|
+
outputContextType: ModifyOutputContextRequestType_Enum.SharedAudioPresentation,
|
|
15163
|
+
addingOutputDeviceUIDs: addingDevices,
|
|
15164
|
+
removingOutputDeviceUIDs: removingDevices,
|
|
15165
|
+
settingOutputDeviceUIDs: settingDevices,
|
|
15166
|
+
clusterAwareAddingOutputDeviceUIDs: addingDevices,
|
|
15167
|
+
clusterAwareRemovingOutputDeviceUIDs: removingDevices,
|
|
15168
|
+
clusterAwareSettingOutputDeviceUIDs: settingDevices
|
|
14680
15169
|
});
|
|
14681
15170
|
setExtension(protocolMessage, modifyOutputContextRequestMessage, message);
|
|
14682
15171
|
return [protocolMessage, modifyOutputContextRequestMessage];
|
|
@@ -14881,6 +15370,19 @@ function sendCommand(command, options) {
|
|
|
14881
15370
|
return [protocolMessage, sendCommandMessage];
|
|
14882
15371
|
}
|
|
14883
15372
|
/**
|
|
15373
|
+
* Builds a SEND_COMMAND message with sleep timer options.
|
|
15374
|
+
*
|
|
15375
|
+
* @param seconds - Timer duration in seconds. Use 0 to cancel.
|
|
15376
|
+
* @param stopMode - Stop mode: 0 = stop, 1 = pause, 2 = end of track, 3 = end of queue.
|
|
15377
|
+
* @returns Tuple of [ProtocolMessage, extension descriptor] for sending via DataStream.
|
|
15378
|
+
*/
|
|
15379
|
+
function sendCommandWithSleepTimer(seconds, stopMode = 0) {
|
|
15380
|
+
return sendCommand(Command.Pause, create(CommandOptionsSchema, {
|
|
15381
|
+
sleepTimerTime: BigInt(seconds),
|
|
15382
|
+
sleepTimerStopMode: stopMode
|
|
15383
|
+
}));
|
|
15384
|
+
}
|
|
15385
|
+
/**
|
|
14884
15386
|
* Builds a SEND_VIRTUAL_TOUCH_EVENT message for touchpad simulation.
|
|
14885
15387
|
*
|
|
14886
15388
|
* Simulates touch input on a virtual trackpad, used for gesture-based
|
|
@@ -15007,6 +15509,104 @@ function setConversationDetectionEnabled(enabled, outputDeviceUID) {
|
|
|
15007
15509
|
return [protocolMessage, setConversationDetectionEnabledMessage];
|
|
15008
15510
|
}
|
|
15009
15511
|
/**
|
|
15512
|
+
* Builds an ADJUST_VOLUME message for relative volume changes.
|
|
15513
|
+
*
|
|
15514
|
+
* Uses the dedicated AdjustVolumeMessage (extension field 97) for incremental
|
|
15515
|
+
* volume adjustments without needing to know the current volume level.
|
|
15516
|
+
*
|
|
15517
|
+
* @param adjustment - The volume adjustment type (e.g. IncrementSmall, DecrementSmall).
|
|
15518
|
+
* @param outputDeviceUID - UID of the target output device.
|
|
15519
|
+
* @returns Tuple of [ProtocolMessage, extension descriptor] for sending via DataStream.
|
|
15520
|
+
*/
|
|
15521
|
+
function adjustVolume(adjustment, outputDeviceUID) {
|
|
15522
|
+
const protocolMessage = protocol(ProtocolMessage_Type.ADJUST_VOLUME_MESSAGE);
|
|
15523
|
+
const message = create(AdjustVolumeMessageSchema, {
|
|
15524
|
+
adjustment,
|
|
15525
|
+
outputDeviceUID
|
|
15526
|
+
});
|
|
15527
|
+
setExtension(protocolMessage, adjustVolumeMessage, message);
|
|
15528
|
+
return [protocolMessage, adjustVolumeMessage];
|
|
15529
|
+
}
|
|
15530
|
+
/**
|
|
15531
|
+
* Builds an AUDIO_FADE message to trigger a cross-fade between audio sources.
|
|
15532
|
+
*
|
|
15533
|
+
* @param fadeType - The type of audio fade to perform.
|
|
15534
|
+
* @param playerPath - Optional player path to target a specific player.
|
|
15535
|
+
* @returns Tuple of [ProtocolMessage, extension descriptor] for sending via DataStream.
|
|
15536
|
+
*/
|
|
15537
|
+
function audioFade(fadeType, playerPath) {
|
|
15538
|
+
const protocolMessage = protocol(ProtocolMessage_Type.AUDIO_FADE_MESSAGE);
|
|
15539
|
+
const message = create(AudioFadeMessageSchema, {
|
|
15540
|
+
fadeType,
|
|
15541
|
+
playerPath
|
|
15542
|
+
});
|
|
15543
|
+
setExtension(protocolMessage, audioFadeMessage, message);
|
|
15544
|
+
return [protocolMessage, audioFadeMessage];
|
|
15545
|
+
}
|
|
15546
|
+
/**
|
|
15547
|
+
* Builds a SET_LISTENING_MODE message to change the audio listening mode on a HomePod.
|
|
15548
|
+
*
|
|
15549
|
+
* @param listeningMode - The listening mode string (e.g. 'Default', 'Vivid', 'LateNight').
|
|
15550
|
+
* @param outputDeviceUID - The output device UID to target.
|
|
15551
|
+
* @returns Tuple of [ProtocolMessage, extension descriptor] for sending via DataStream.
|
|
15552
|
+
*/
|
|
15553
|
+
function setListeningMode(listeningMode, outputDeviceUID) {
|
|
15554
|
+
const protocolMessage = protocol(ProtocolMessage_Type.SET_LISTENING_MODE_MESSAGE);
|
|
15555
|
+
const message = create(SetListeningModeMessageSchema, {
|
|
15556
|
+
listeningMode,
|
|
15557
|
+
outputDeviceUID
|
|
15558
|
+
});
|
|
15559
|
+
setExtension(protocolMessage, setListeningModeMessage, message);
|
|
15560
|
+
return [protocolMessage, setListeningModeMessage];
|
|
15561
|
+
}
|
|
15562
|
+
/**
|
|
15563
|
+
* Builds a SET_DISCOVERY_MODE message to enable or disable device discovery.
|
|
15564
|
+
*
|
|
15565
|
+
* @param mode - The discovery mode to set.
|
|
15566
|
+
* @returns Tuple of [ProtocolMessage, extension descriptor] for sending via DataStream.
|
|
15567
|
+
*/
|
|
15568
|
+
function setDiscoveryMode(mode) {
|
|
15569
|
+
const protocolMessage = protocol(ProtocolMessage_Type.SET_DISCOVERY_MODE_MESSAGE);
|
|
15570
|
+
const message = create(SetDiscoveryModeMessageSchema, { mode });
|
|
15571
|
+
setExtension(protocolMessage, setDiscoveryModeMessage, message);
|
|
15572
|
+
return [protocolMessage, setDiscoveryModeMessage];
|
|
15573
|
+
}
|
|
15574
|
+
/**
|
|
15575
|
+
* Builds a REQUEST_GROUP_SESSION message to initiate a SharePlay/group listening session.
|
|
15576
|
+
*
|
|
15577
|
+
* @returns Tuple of [ProtocolMessage, extension descriptor] for sending via DataStream.
|
|
15578
|
+
*/
|
|
15579
|
+
function requestGroupSession() {
|
|
15580
|
+
const protocolMessage = protocol(ProtocolMessage_Type.REQUEST_GROUP_SESSION_MESSAGE);
|
|
15581
|
+
const message = create(RequestGroupSessionMessageSchema, {});
|
|
15582
|
+
setExtension(protocolMessage, requestGroupSessionMessage, message);
|
|
15583
|
+
return [protocolMessage, requestGroupSessionMessage];
|
|
15584
|
+
}
|
|
15585
|
+
/**
|
|
15586
|
+
* Builds a PLAYBACK_SESSION_MIGRATE_BEGIN message to start migrating playback to another device.
|
|
15587
|
+
*
|
|
15588
|
+
* @param playerPath - The player path of the session to migrate.
|
|
15589
|
+
* @returns Tuple of [ProtocolMessage, extension descriptor] for sending via DataStream.
|
|
15590
|
+
*/
|
|
15591
|
+
function playbackSessionMigrateBegin(playerPath) {
|
|
15592
|
+
const protocolMessage = protocol(ProtocolMessage_Type.PLAYBACK_SESSION_MIGRATE_BEGIN_MESSAGE);
|
|
15593
|
+
const message = create(PlaybackSessionMigrateBeginMessageSchema, { playerPath });
|
|
15594
|
+
setExtension(protocolMessage, playbackSessionMigrateBeginMessage, message);
|
|
15595
|
+
return [protocolMessage, playbackSessionMigrateBeginMessage];
|
|
15596
|
+
}
|
|
15597
|
+
/**
|
|
15598
|
+
* Builds a PLAYBACK_SESSION_MIGRATE_END message to complete a playback migration.
|
|
15599
|
+
*
|
|
15600
|
+
* @param playerPath - The player path of the migrated session.
|
|
15601
|
+
* @returns Tuple of [ProtocolMessage, extension descriptor] for sending via DataStream.
|
|
15602
|
+
*/
|
|
15603
|
+
function playbackSessionMigrateEnd(playerPath) {
|
|
15604
|
+
const protocolMessage = protocol(ProtocolMessage_Type.PLAYBACK_SESSION_MIGRATE_END_MESSAGE);
|
|
15605
|
+
const message = create(PlaybackSessionMigrateEndMessageSchema, { playerPath });
|
|
15606
|
+
setExtension(protocolMessage, playbackSessionMigrateEndMessage, message);
|
|
15607
|
+
return [protocolMessage, playbackSessionMigrateEndMessage];
|
|
15608
|
+
}
|
|
15609
|
+
/**
|
|
15010
15610
|
* Builds a WAKE_DEVICE message to wake a sleeping Apple TV or HomePod.
|
|
15011
15611
|
*
|
|
15012
15612
|
* @returns Tuple of [ProtocolMessage, extension descriptor] for sending via DataStream.
|
|
@@ -15032,4 +15632,4 @@ function getExtension(message, extension) {
|
|
|
15032
15632
|
}
|
|
15033
15633
|
|
|
15034
15634
|
//#endregion
|
|
15035
|
-
export {
|
|
15635
|
+
export { AudioMultiplexer, AudioStream, ControlStream, DataStream, dataStreamMessages_exports as DataStreamMessage, EventStream, LatencyManager, Pairing, proto_exports as Proto, Protocol, Verify };
|