@basmilius/apple-airplay 0.8.2 → 0.9.2

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.mjs CHANGED
@@ -2,7 +2,7 @@ import { t as __exportAll } from "./chunk-DQk6qfdC.mjs";
2
2
  import { randomBytes } from "node:crypto";
3
3
  import { createSocket } from "node:dgram";
4
4
  import { AccessoryPair, AccessoryVerify, Context, ENCRYPTION, EncryptionAwareConnection, HTTP_TIMEOUT, generateActiveRemoteId, generateDacpId, generateSessionId, getMacAddress, randomInt32, randomInt64, uint16ToBE, uuid } from "@basmilius/apple-common";
5
- import { Plist, RTSP } from "@basmilius/apple-encoding";
5
+ import { NTP, Plist, RTSP } from "@basmilius/apple-encoding";
6
6
  import { Chacha20, hkdf } from "@basmilius/apple-encryption";
7
7
 
8
8
  //#region src/audioStream.ts
@@ -12,7 +12,12 @@ const BYTES_PER_CHANNEL = 2;
12
12
  const FRAMES_PER_PACKET = 352;
13
13
  const LATENCY_FRAMES = 11025;
14
14
  const PACKET_BACKLOG_SIZE = 1e3;
15
- const AUDIO_FORMAT = 4194304;
15
+ const SYNC_INTERVAL = 1e3;
16
+ const ntpFromTs = (timestamp, sampleRate) => {
17
+ const seconds = Math.floor(timestamp / sampleRate);
18
+ const fraction = timestamp % sampleRate * 4294967295 / sampleRate;
19
+ return BigInt(seconds) << 32n | BigInt(Math.floor(fraction));
20
+ };
16
21
  var AudioStream = class {
17
22
  #protocol;
18
23
  #context;
@@ -24,6 +29,8 @@ var AudioStream = class {
24
29
  #remoteControlPort = 0;
25
30
  #packetBacklog = /* @__PURE__ */ new Map();
26
31
  #ssrc = 0;
32
+ #syncInterval;
33
+ #streamContext;
27
34
  constructor(protocol) {
28
35
  this.#protocol = protocol;
29
36
  this.#context = protocol.context;
@@ -32,6 +39,7 @@ var AudioStream = class {
32
39
  this.#sharedKey = Buffer.from(randomBytes(32));
33
40
  this.#ssrc = randomInt32() >>> 0;
34
41
  this.#controlSocket = createSocket("udp4");
42
+ this.#controlSocket.on("message", (data, rinfo) => this.#onControlMessage(data, rinfo));
35
43
  await new Promise((resolve, reject) => {
36
44
  this.#controlSocket.once("error", reject);
37
45
  this.#controlSocket.bind(0, () => {
@@ -43,9 +51,10 @@ var AudioStream = class {
43
51
  const shkArrayBuffer = this.#sharedKey.buffer.slice(this.#sharedKey.byteOffset, this.#sharedKey.byteOffset + this.#sharedKey.byteLength);
44
52
  const streamConnectionID = randomInt64();
45
53
  const setupBody = Plist.serialize({ streams: [{
46
- audioFormat: AUDIO_FORMAT,
47
- audioMode: "moviePlayback",
48
- ct: 2,
54
+ audioFormat: 2048,
55
+ audioMode: "default",
56
+ controlPort: this.#controlPort,
57
+ ct: 1,
49
58
  isMedia: true,
50
59
  latencyMax: 88200,
51
60
  latencyMin: 11025,
@@ -54,11 +63,7 @@ var AudioStream = class {
54
63
  sr: SAMPLE_RATE,
55
64
  streamConnectionID,
56
65
  supportsDynamicStreamID: false,
57
- type: 96,
58
- streamConnections: {
59
- streamConnectionTypeRTP: { streamConnectionKeyUseStreamEncryptionKey: true },
60
- streamConnectionTypeRTCP: { streamConnectionKeyPort: this.#controlPort }
61
- }
66
+ type: 96
62
67
  }] });
63
68
  this.#context.logger.debug("[audio]", "Sending audio stream SETUP...");
64
69
  this.#context.logger.debug("[audio]", "shk length:", this.#sharedKey.length);
@@ -70,10 +75,10 @@ var AudioStream = class {
70
75
  const plist = Plist.parse(await response.arrayBuffer());
71
76
  this.#context.logger.debug("[audio]", "Setup stream response:", plist);
72
77
  if (plist.streams && plist.streams.length > 0) {
73
- const connections = plist.streams[0].streamConnections;
74
- this.#dataPort = connections?.streamConnectionTypeRTP?.streamConnectionKeyPort & 65535;
75
- this.#remoteControlPort = connections?.streamConnectionTypeRTCP?.streamConnectionKeyPort & 65535;
76
- this.#context.logger.info("[audio]", `Audio stream setup: rtpPort=${this.#dataPort}, rtcpPort=${this.#remoteControlPort}`);
78
+ const streamInfo = plist.streams[0];
79
+ this.#dataPort = streamInfo.dataPort & 65535;
80
+ this.#remoteControlPort = streamInfo.controlPort & 65535;
81
+ this.#context.logger.info("[audio]", `Audio stream setup: dataPort=${this.#dataPort}, controlPort=${this.#remoteControlPort}`);
77
82
  } else throw new Error("No stream info in SETUP response");
78
83
  this.#context.logger.debug("[audio]", "Sending RECORD...");
79
84
  await this.#protocol.controlStream.record(`/${this.#protocol.controlStream.sessionId}`);
@@ -102,18 +107,26 @@ var AudioStream = class {
102
107
  frameSize,
103
108
  packetSize: FRAMES_PER_PACKET * frameSize,
104
109
  rtpSeq: randomInt32() & 65535,
105
- rtpTime: randomInt32() >>> 0,
110
+ rtpTime: 0,
106
111
  headTs: 0,
107
112
  latency: LATENCY_FRAMES,
108
- paddingSent: 0
113
+ paddingSent: 0,
114
+ totalFrames: 0
109
115
  };
110
- ctx.headTs = ctx.rtpTime;
116
+ this.#streamContext = ctx;
117
+ this.#context.logger.debug("[audio]", "Sending FLUSH...");
118
+ await this.#protocol.controlStream.flush(`/${this.#protocol.controlStream.sessionId}`, {
119
+ "Range": "npt=0-",
120
+ "RTP-Info": `seq=${ctx.rtpSeq};rtptime=${ctx.rtpTime}`
121
+ });
122
+ this.#context.logger.debug("[audio]", "FLUSH complete");
111
123
  let firstPacket = true;
112
124
  let packetCount = 0;
113
125
  const startTime = performance.now();
114
126
  this.#context.logger.info("[audio]", "Starting audio stream...");
115
127
  this.#context.logger.debug("[audio]", `RTP start: seq=${ctx.rtpSeq}, time=${ctx.rtpTime}, ssrc=${this.#ssrc}`);
116
128
  this.#packetBacklog.clear();
129
+ this.#startSync();
117
130
  while (true) {
118
131
  if (await this.#sendPacket(source, firstPacket, ctx) === 0) {
119
132
  this.#context.logger.debug("[audio]", `End of audio stream after ${packetCount} packets (padding complete)`);
@@ -121,12 +134,17 @@ var AudioStream = class {
121
134
  }
122
135
  packetCount++;
123
136
  firstPacket = false;
124
- if (packetCount % 100 === 0) this.#context.logger.debug("[audio]", `Sent ${packetCount} packets`);
125
- const sleepTime = (ctx.headTs - ctx.rtpTime) / SAMPLE_RATE * 1e3 - (performance.now() - startTime);
137
+ if (packetCount % 100 === 0) this.#context.logger.debug("[audio]", `Sent ${packetCount} packets, ${ctx.totalFrames} frames`);
138
+ const sleepTime = ctx.totalFrames / SAMPLE_RATE * 1e3 - (performance.now() - startTime);
126
139
  if (sleepTime > 0) await this.#sleep(sleepTime);
127
140
  }
128
141
  this.#context.logger.info("[audio]", `Audio stream finished, sent ${packetCount} packets`);
142
+ this.#stopSync();
143
+ this.#context.logger.debug("[audio]", "Sending TEARDOWN...");
144
+ await this.#protocol.controlStream.teardown(`/${this.#protocol.controlStream.sessionId}`);
145
+ this.#context.logger.debug("[audio]", "TEARDOWN complete");
129
146
  } catch (err) {
147
+ this.#stopSync();
130
148
  this.#dataSocket?.close();
131
149
  this.#dataSocket = void 0;
132
150
  this.#packetBacklog.clear();
@@ -155,9 +173,11 @@ var AudioStream = class {
155
173
  const packet = Buffer.concat([rtpHeader, payload]);
156
174
  this.#storePacket(ctx.rtpSeq, packet);
157
175
  await this.#send(packet);
176
+ const framesSent = Math.floor(frames.length / ctx.frameSize);
158
177
  ctx.rtpSeq = ctx.rtpSeq + 1 & 65535;
159
- ctx.headTs = ctx.headTs + FRAMES_PER_PACKET >>> 0;
160
- return Math.floor(frames.length / ctx.frameSize);
178
+ ctx.headTs = ctx.headTs + framesSent >>> 0;
179
+ ctx.totalFrames += framesSent;
180
+ return framesSent;
161
181
  }
162
182
  #storePacket(seqno, packet) {
163
183
  this.#packetBacklog.set(seqno, packet);
@@ -189,7 +209,57 @@ var AudioStream = class {
189
209
  #sleep(ms) {
190
210
  return new Promise((resolve) => setTimeout(resolve, ms));
191
211
  }
212
+ #startSync() {
213
+ if (this.#syncInterval) return;
214
+ let firstPacket = true;
215
+ const sendSync = () => {
216
+ if (!this.#controlSocket || !this.#streamContext || !this.#remoteControlPort) return;
217
+ const ctx = this.#streamContext;
218
+ const currentTime = ntpFromTs(ctx.headTs, ctx.sampleRate);
219
+ const [currentSec, currentFrac] = NTP.parts(currentTime);
220
+ const packet = Buffer.allocUnsafe(20);
221
+ packet.writeUInt8(firstPacket ? 144 : 128, 0);
222
+ packet.writeUInt8(212, 1);
223
+ packet.writeUInt16BE(7, 2);
224
+ packet.writeUInt32BE(ctx.headTs - ctx.latency >>> 0, 4);
225
+ packet.writeUInt32BE(currentSec, 8);
226
+ packet.writeUInt32BE(currentFrac, 12);
227
+ packet.writeUInt32BE(ctx.headTs >>> 0, 16);
228
+ firstPacket = false;
229
+ this.#controlSocket.send(packet, this.#remoteControlPort, this.#protocol.discoveryResult.address);
230
+ };
231
+ sendSync();
232
+ this.#syncInterval = setInterval(sendSync, SYNC_INTERVAL);
233
+ }
234
+ #stopSync() {
235
+ if (this.#syncInterval) {
236
+ clearInterval(this.#syncInterval);
237
+ this.#syncInterval = void 0;
238
+ }
239
+ this.#streamContext = void 0;
240
+ }
241
+ #onControlMessage(data, rinfo) {
242
+ if ((data[1] & 127) === 85) this.#retransmitPackets(data, rinfo);
243
+ }
244
+ #retransmitPackets(data, addr) {
245
+ const lostSeqno = data.readUInt16BE(4);
246
+ const lostPackets = data.readUInt16BE(6);
247
+ for (let i = 0; i < lostPackets; i++) {
248
+ const seqno = lostSeqno + i & 65535;
249
+ const packet = this.#packetBacklog.get(seqno);
250
+ if (packet) {
251
+ const originalSeqno = packet.subarray(2, 4);
252
+ const resp = Buffer.concat([
253
+ Buffer.from([128, 214]),
254
+ originalSeqno,
255
+ packet
256
+ ]);
257
+ this.#controlSocket?.send(resp, addr.port, addr.address);
258
+ }
259
+ }
260
+ }
192
261
  close() {
262
+ this.#stopSync();
193
263
  this.#controlSocket?.close();
194
264
  this.#controlSocket = void 0;
195
265
  this.#dataSocket?.close();
@@ -6689,7 +6759,7 @@ const ProtocolMessage_TypeSchema = /* @__PURE__ */ enumDesc(file_ProtocolMessage
6689
6759
  /**
6690
6760
  * Describes the file Common.proto.
6691
6761
  */
6692
- const file_Common = /* @__PURE__ */ fileDesc("CgxDb21tb24ucHJvdG8iPAoKUmVwZWF0TW9kZSIuCgRFbnVtEgsKB1Vua25vd24QABIHCgNPZmYQARIHCgNPbmUQAhIHCgNBbGwQAyJCCgtTaHVmZmxlTW9kZSIzCgRFbnVtEgsKB1Vua25vd24QABIHCgNPZmYQARIKCgZBbGJ1bXMQAhIJCgVTb25ncxADIokBCgtEZXZpY2VDbGFzcyJ6CgRFbnVtEgsKB0ludmFsaWQQABIKCgZpUGhvbmUQARIICgRpUG9kEAISCAoEaVBhZBADEgsKB0FwcGxlVFYQBBIJCgVpRlBHQRAFEgkKBVdhdGNoEAYSDQoJQWNjZXNzb3J5EAcSCgoGQnJpZGdlEAgSBwoDTWFjEAkiYgoKRGV2aWNlVHlwZSJUCgRFbnVtEgsKB1Vua25vd24QABILCgdBaXJQbGF5EAESDQoJQmx1ZXRvb3RoEAISCwoHQ2FyUGxheRADEgsKB0J1aWx0SW4QBBIJCgVXaXJlZBAFIoACCg1EZXZpY2VTdWJUeXBlIu4BCgRFbnVtEgsKB0RlZmF1bHQQABILCgdTcGVha2VyEAESDgoKSGVhZHBob25lcxACEgsKB0hlYWRzZXQQAxIMCghSZWNlaXZlchAEEgsKB0xpbmVPdXQQBRIHCgNVU0IQBhIPCgtEaXNwbGF5UG9ydBAHEggKBEhETUkQCBINCglMb3dFbmVyZ3kQCRIJCgVTUERJRhAKEgYKAlRWEAsSCwoHSG9tZVBvZBAMEgsKB0FwcGxlVFYQDRILCgdWZWhpY2xlEA4SCwoHQ2x1c3RlchAPEg0KCVNldFRvcEJveBAQEgsKB1RWU3RpY2sQESJoCg1QbGF5YmFja1N0YXRlIlcKBEVudW0SCwoHVW5rbm93bhAAEgsKB1BsYXlpbmcQARIKCgZQYXVzZWQQAhILCgdTdG9wcGVkEAMSDwoLSW50ZXJydXB0ZWQQBBILCgdTZWVraW5nEAU");
6762
+ const file_Common = /* @__PURE__ */ fileDesc("CgxDb21tb24ucHJvdG8iPAoKUmVwZWF0TW9kZSIuCgRFbnVtEgsKB1Vua25vd24QABIHCgNPZmYQARIHCgNPbmUQAhIHCgNBbGwQAyJCCgtTaHVmZmxlTW9kZSIzCgRFbnVtEgsKB1Vua25vd24QABIHCgNPZmYQARIKCgZBbGJ1bXMQAhIJCgVTb25ncxADIsUBCgtEZXZpY2VDbGFzcyK1AQoERW51bRILCgdJbnZhbGlkEAASCgoGaVBob25lEAESCAoEaVBvZBACEggKBGlQYWQQAxILCgdBcHBsZVRWEAQSCQoFaUZQR0EQBRIJCgVXYXRjaBAGEg0KCUFjY2Vzc29yeRAHEgoKBkJyaWRnZRAIEgcKA01hYxAJEgsKB0FuZHJvaWQQChIHCgNXZWIQCxIQCgxBcHBsZURpc3BsYXkQDBIRCg1SZWFsaXR5RGV2aWNlEA0iYgoKRGV2aWNlVHlwZSJUCgRFbnVtEgsKB1Vua25vd24QABILCgdBaXJQbGF5EAESDQoJQmx1ZXRvb3RoEAISCwoHQ2FyUGxheRADEgsKB0J1aWx0SW4QBBIJCgVXaXJlZBAFIqkCCg1EZXZpY2VTdWJUeXBlIpcCCgRFbnVtEgsKB0RlZmF1bHQQABILCgdTcGVha2VyEAESDgoKSGVhZHBob25lcxACEgsKB0hlYWRzZXQQAxIMCghSZWNlaXZlchAEEgsKB0xpbmVPdXQQBRIHCgNVU0IQBhIPCgtEaXNwbGF5UG9ydBAHEggKBEhETUkQCBINCglMb3dFbmVyZ3kQCRIJCgVTUERJRhAKEgYKAlRWEAsSCwoHSG9tZVBvZBAMEgsKB0FwcGxlVFYQDRILCgdWZWhpY2xlEA4SCwoHQ2x1c3RlchAPEg0KCVNldFRvcEJveBAQEgsKB1RWU3RpY2sQERIHCgNNYWMQEhIHCgNpT1MQExIJCgVXYXRjaBAUEgoKBlZpc2lvbhAVImgKDVBsYXliYWNrU3RhdGUiVwoERW51bRILCgdVbmtub3duEAASCwoHUGxheWluZxABEgoKBlBhdXNlZBACEgsKB1N0b3BwZWQQAxIPCgtJbnRlcnJ1cHRlZBAEEgsKB1NlZWtpbmcQBSJSCgtDbHVzdGVyVHlwZSJDCgRFbnVtEggKBE5vbmUQABIOCgpTdGVyZW9QYWlyEAESDwoLSG9tZVRoZWF0ZXIQAhIQCgxHZW5lcmljQXVkaW8QAyJoChFWaXJ0dWFsVG91Y2hQaGFzZSJTCgRFbnVtEgsKB1Vua25vd24QABIJCgVCZWdhbhABEgkKBU1vdmVkEAISDgoKU3RhdGlvbmFyeRADEgkKBUVuZGVkEAQSDQoJQ2FuY2VsbGVkEAUiMwoKQ2hhbmdlVHlwZSIlCgRFbnVtEg0KCUltbWVkaWF0ZRAAEg4KCkRlZmVycmFibGUQASKRAQoPRW5kcG9pbnRPcHRpb25zIn4KBEVudW0SCAoETm9uZRAAEhgKFFVwZGF0ZUFjdGl2ZUVuZHBvaW50EAESHgoaRmFsbGJhY2tUb0FkZE91dHB1dERldmljZXMQAhIXChNBbGxvd01pZ3JhdGVUb0dyb3VwEAQSGQoVQWxsb3dNaWdyYXRlRnJvbUdyb3VwEAgiowEKDVBsYXllck9wdGlvbnMikQEKBEVudW0SCAoETm9uZRAAEiMKH1Jlc3RvcmVEZXN0aW5hdGlvblBsYXliYWNrU3RhdGUQARITCg9QbGF5RGVzdGluYXRpb24QAhIPCgtQYXVzZVNvdXJjZRAEEhsKF1Jlc3RvcmVQbGF5YmFja1Bvc2l0aW9uEAgSFwoTUmVzdG9yZVBsYXliYWNrUmF0ZRAQIj4KClJlY2lwZVR5cGUiMAoERW51bRIPCgtOb3RQb3NzaWJsZRAAEgoKBkxlZ2FjeRABEgsKB09uZVNob3QQAiKQAQomUGxheWJhY2tTZXNzaW9uTWlncmF0ZVJlcXVlc3RFdmVudFJvbGUiZgoERW51bRILCgdVbmtub3duEAASEAoMUmVjZXB0aW9uaXN0EAESCgoGU291cmNlEAISDwoLRGVzdGluYXRpb24QAxIJCgVJbkFwcBAEEgwKCEhpamFja2VkEAUSCQoFR3JvdXAQBiJ9ChVHcm91cFNlc3Npb25Sb3V0ZVR5cGUiZAoERW51bRILCgdVbmtub3duEAASCgoGQ2FyS2l0EAESCwoHQ2FyUGxheRACEgsKB1NwZWFrZXIQBRILCgdIb21lUG9kEAgSDwoLSG9tZVBvZE1pbmkQCRILCgdBcHBsZVRWEAsiZAoNUmVwbGFjZUludGVudCJTCgRFbnVtEhIKDk5vbkRlc3RydWN0aXZlEAESDwoLQ2xlYXJVcE5leHQQAhIOCgpLZWVwVXBOZXh0EAMSFgoSTGVhdmVTaGFyZWRTZXNzaW9uEAQiTAoRUGxheWJhY2tRdWV1ZVR5cGUiNwoERW51bRILCgdVbmtub3duEAESCwoHR2VuZXJpYxACEgoKBkN1c3RvbRADEgkKBUVtcHR5EAQ");
6693
6763
  /**
6694
6764
  * Describes the message RepeatMode.
6695
6765
  * Use `create(RepeatModeSchema)` to create a new message.
@@ -6801,6 +6871,22 @@ let DeviceClass_Enum = /* @__PURE__ */ function(DeviceClass_Enum) {
6801
6871
  * @generated from enum value: Mac = 9;
6802
6872
  */
6803
6873
  DeviceClass_Enum[DeviceClass_Enum["Mac"] = 9] = "Mac";
6874
+ /**
6875
+ * @generated from enum value: Android = 10;
6876
+ */
6877
+ DeviceClass_Enum[DeviceClass_Enum["Android"] = 10] = "Android";
6878
+ /**
6879
+ * @generated from enum value: Web = 11;
6880
+ */
6881
+ DeviceClass_Enum[DeviceClass_Enum["Web"] = 11] = "Web";
6882
+ /**
6883
+ * @generated from enum value: AppleDisplay = 12;
6884
+ */
6885
+ DeviceClass_Enum[DeviceClass_Enum["AppleDisplay"] = 12] = "AppleDisplay";
6886
+ /**
6887
+ * @generated from enum value: RealityDevice = 13;
6888
+ */
6889
+ DeviceClass_Enum[DeviceClass_Enum["RealityDevice"] = 13] = "RealityDevice";
6804
6890
  return DeviceClass_Enum;
6805
6891
  }({});
6806
6892
  /**
@@ -6927,6 +7013,22 @@ let DeviceSubType_Enum = /* @__PURE__ */ function(DeviceSubType_Enum) {
6927
7013
  * @generated from enum value: TVStick = 17;
6928
7014
  */
6929
7015
  DeviceSubType_Enum[DeviceSubType_Enum["TVStick"] = 17] = "TVStick";
7016
+ /**
7017
+ * @generated from enum value: Mac = 18;
7018
+ */
7019
+ DeviceSubType_Enum[DeviceSubType_Enum["Mac"] = 18] = "Mac";
7020
+ /**
7021
+ * @generated from enum value: iOS = 19;
7022
+ */
7023
+ DeviceSubType_Enum[DeviceSubType_Enum["iOS"] = 19] = "iOS";
7024
+ /**
7025
+ * @generated from enum value: Watch = 20;
7026
+ */
7027
+ DeviceSubType_Enum[DeviceSubType_Enum["Watch"] = 20] = "Watch";
7028
+ /**
7029
+ * @generated from enum value: Vision = 21;
7030
+ */
7031
+ DeviceSubType_Enum[DeviceSubType_Enum["Vision"] = 21] = "Vision";
6930
7032
  return DeviceSubType_Enum;
6931
7033
  }({});
6932
7034
  /**
@@ -6972,6 +7074,348 @@ let PlaybackState_Enum = /* @__PURE__ */ function(PlaybackState_Enum) {
6972
7074
  * Describes the enum PlaybackState.Enum.
6973
7075
  */
6974
7076
  const PlaybackState_EnumSchema = /* @__PURE__ */ enumDesc(file_Common, 5, 0);
7077
+ /**
7078
+ * Describes the message ClusterType.
7079
+ * Use `create(ClusterTypeSchema)` to create a new message.
7080
+ */
7081
+ const ClusterTypeSchema = /* @__PURE__ */ messageDesc(file_Common, 6);
7082
+ /**
7083
+ * @generated from enum ClusterType.Enum
7084
+ */
7085
+ let ClusterType_Enum = /* @__PURE__ */ function(ClusterType_Enum) {
7086
+ /**
7087
+ * @generated from enum value: None = 0;
7088
+ */
7089
+ ClusterType_Enum[ClusterType_Enum["None"] = 0] = "None";
7090
+ /**
7091
+ * @generated from enum value: StereoPair = 1;
7092
+ */
7093
+ ClusterType_Enum[ClusterType_Enum["StereoPair"] = 1] = "StereoPair";
7094
+ /**
7095
+ * @generated from enum value: HomeTheater = 2;
7096
+ */
7097
+ ClusterType_Enum[ClusterType_Enum["HomeTheater"] = 2] = "HomeTheater";
7098
+ /**
7099
+ * @generated from enum value: GenericAudio = 3;
7100
+ */
7101
+ ClusterType_Enum[ClusterType_Enum["GenericAudio"] = 3] = "GenericAudio";
7102
+ return ClusterType_Enum;
7103
+ }({});
7104
+ /**
7105
+ * Describes the enum ClusterType.Enum.
7106
+ */
7107
+ const ClusterType_EnumSchema = /* @__PURE__ */ enumDesc(file_Common, 6, 0);
7108
+ /**
7109
+ * Describes the message VirtualTouchPhase.
7110
+ * Use `create(VirtualTouchPhaseSchema)` to create a new message.
7111
+ */
7112
+ const VirtualTouchPhaseSchema = /* @__PURE__ */ messageDesc(file_Common, 7);
7113
+ /**
7114
+ * @generated from enum VirtualTouchPhase.Enum
7115
+ */
7116
+ let VirtualTouchPhase_Enum = /* @__PURE__ */ function(VirtualTouchPhase_Enum) {
7117
+ /**
7118
+ * @generated from enum value: Unknown = 0;
7119
+ */
7120
+ VirtualTouchPhase_Enum[VirtualTouchPhase_Enum["Unknown"] = 0] = "Unknown";
7121
+ /**
7122
+ * @generated from enum value: Began = 1;
7123
+ */
7124
+ VirtualTouchPhase_Enum[VirtualTouchPhase_Enum["Began"] = 1] = "Began";
7125
+ /**
7126
+ * @generated from enum value: Moved = 2;
7127
+ */
7128
+ VirtualTouchPhase_Enum[VirtualTouchPhase_Enum["Moved"] = 2] = "Moved";
7129
+ /**
7130
+ * @generated from enum value: Stationary = 3;
7131
+ */
7132
+ VirtualTouchPhase_Enum[VirtualTouchPhase_Enum["Stationary"] = 3] = "Stationary";
7133
+ /**
7134
+ * @generated from enum value: Ended = 4;
7135
+ */
7136
+ VirtualTouchPhase_Enum[VirtualTouchPhase_Enum["Ended"] = 4] = "Ended";
7137
+ /**
7138
+ * @generated from enum value: Cancelled = 5;
7139
+ */
7140
+ VirtualTouchPhase_Enum[VirtualTouchPhase_Enum["Cancelled"] = 5] = "Cancelled";
7141
+ return VirtualTouchPhase_Enum;
7142
+ }({});
7143
+ /**
7144
+ * Describes the enum VirtualTouchPhase.Enum.
7145
+ */
7146
+ const VirtualTouchPhase_EnumSchema = /* @__PURE__ */ enumDesc(file_Common, 7, 0);
7147
+ /**
7148
+ * Describes the message ChangeType.
7149
+ * Use `create(ChangeTypeSchema)` to create a new message.
7150
+ */
7151
+ const ChangeTypeSchema = /* @__PURE__ */ messageDesc(file_Common, 8);
7152
+ /**
7153
+ * @generated from enum ChangeType.Enum
7154
+ */
7155
+ let ChangeType_Enum = /* @__PURE__ */ function(ChangeType_Enum) {
7156
+ /**
7157
+ * @generated from enum value: Immediate = 0;
7158
+ */
7159
+ ChangeType_Enum[ChangeType_Enum["Immediate"] = 0] = "Immediate";
7160
+ /**
7161
+ * @generated from enum value: Deferrable = 1;
7162
+ */
7163
+ ChangeType_Enum[ChangeType_Enum["Deferrable"] = 1] = "Deferrable";
7164
+ return ChangeType_Enum;
7165
+ }({});
7166
+ /**
7167
+ * Describes the enum ChangeType.Enum.
7168
+ */
7169
+ const ChangeType_EnumSchema = /* @__PURE__ */ enumDesc(file_Common, 8, 0);
7170
+ /**
7171
+ * Describes the message EndpointOptions.
7172
+ * Use `create(EndpointOptionsSchema)` to create a new message.
7173
+ */
7174
+ const EndpointOptionsSchema = /* @__PURE__ */ messageDesc(file_Common, 9);
7175
+ /**
7176
+ * @generated from enum EndpointOptions.Enum
7177
+ */
7178
+ let EndpointOptions_Enum = /* @__PURE__ */ function(EndpointOptions_Enum) {
7179
+ /**
7180
+ * @generated from enum value: None = 0;
7181
+ */
7182
+ EndpointOptions_Enum[EndpointOptions_Enum["None"] = 0] = "None";
7183
+ /**
7184
+ * @generated from enum value: UpdateActiveEndpoint = 1;
7185
+ */
7186
+ EndpointOptions_Enum[EndpointOptions_Enum["UpdateActiveEndpoint"] = 1] = "UpdateActiveEndpoint";
7187
+ /**
7188
+ * @generated from enum value: FallbackToAddOutputDevices = 2;
7189
+ */
7190
+ EndpointOptions_Enum[EndpointOptions_Enum["FallbackToAddOutputDevices"] = 2] = "FallbackToAddOutputDevices";
7191
+ /**
7192
+ * @generated from enum value: AllowMigrateToGroup = 4;
7193
+ */
7194
+ EndpointOptions_Enum[EndpointOptions_Enum["AllowMigrateToGroup"] = 4] = "AllowMigrateToGroup";
7195
+ /**
7196
+ * @generated from enum value: AllowMigrateFromGroup = 8;
7197
+ */
7198
+ EndpointOptions_Enum[EndpointOptions_Enum["AllowMigrateFromGroup"] = 8] = "AllowMigrateFromGroup";
7199
+ return EndpointOptions_Enum;
7200
+ }({});
7201
+ /**
7202
+ * Describes the enum EndpointOptions.Enum.
7203
+ */
7204
+ const EndpointOptions_EnumSchema = /* @__PURE__ */ enumDesc(file_Common, 9, 0);
7205
+ /**
7206
+ * Describes the message PlayerOptions.
7207
+ * Use `create(PlayerOptionsSchema)` to create a new message.
7208
+ */
7209
+ const PlayerOptionsSchema = /* @__PURE__ */ messageDesc(file_Common, 10);
7210
+ /**
7211
+ * @generated from enum PlayerOptions.Enum
7212
+ */
7213
+ let PlayerOptions_Enum = /* @__PURE__ */ function(PlayerOptions_Enum) {
7214
+ /**
7215
+ * @generated from enum value: None = 0;
7216
+ */
7217
+ PlayerOptions_Enum[PlayerOptions_Enum["None"] = 0] = "None";
7218
+ /**
7219
+ * @generated from enum value: RestoreDestinationPlaybackState = 1;
7220
+ */
7221
+ PlayerOptions_Enum[PlayerOptions_Enum["RestoreDestinationPlaybackState"] = 1] = "RestoreDestinationPlaybackState";
7222
+ /**
7223
+ * @generated from enum value: PlayDestination = 2;
7224
+ */
7225
+ PlayerOptions_Enum[PlayerOptions_Enum["PlayDestination"] = 2] = "PlayDestination";
7226
+ /**
7227
+ * @generated from enum value: PauseSource = 4;
7228
+ */
7229
+ PlayerOptions_Enum[PlayerOptions_Enum["PauseSource"] = 4] = "PauseSource";
7230
+ /**
7231
+ * @generated from enum value: RestorePlaybackPosition = 8;
7232
+ */
7233
+ PlayerOptions_Enum[PlayerOptions_Enum["RestorePlaybackPosition"] = 8] = "RestorePlaybackPosition";
7234
+ /**
7235
+ * @generated from enum value: RestorePlaybackRate = 16;
7236
+ */
7237
+ PlayerOptions_Enum[PlayerOptions_Enum["RestorePlaybackRate"] = 16] = "RestorePlaybackRate";
7238
+ return PlayerOptions_Enum;
7239
+ }({});
7240
+ /**
7241
+ * Describes the enum PlayerOptions.Enum.
7242
+ */
7243
+ const PlayerOptions_EnumSchema = /* @__PURE__ */ enumDesc(file_Common, 10, 0);
7244
+ /**
7245
+ * Describes the message RecipeType.
7246
+ * Use `create(RecipeTypeSchema)` to create a new message.
7247
+ */
7248
+ const RecipeTypeSchema = /* @__PURE__ */ messageDesc(file_Common, 11);
7249
+ /**
7250
+ * @generated from enum RecipeType.Enum
7251
+ */
7252
+ let RecipeType_Enum = /* @__PURE__ */ function(RecipeType_Enum) {
7253
+ /**
7254
+ * @generated from enum value: NotPossible = 0;
7255
+ */
7256
+ RecipeType_Enum[RecipeType_Enum["NotPossible"] = 0] = "NotPossible";
7257
+ /**
7258
+ * @generated from enum value: Legacy = 1;
7259
+ */
7260
+ RecipeType_Enum[RecipeType_Enum["Legacy"] = 1] = "Legacy";
7261
+ /**
7262
+ * @generated from enum value: OneShot = 2;
7263
+ */
7264
+ RecipeType_Enum[RecipeType_Enum["OneShot"] = 2] = "OneShot";
7265
+ return RecipeType_Enum;
7266
+ }({});
7267
+ /**
7268
+ * Describes the enum RecipeType.Enum.
7269
+ */
7270
+ const RecipeType_EnumSchema = /* @__PURE__ */ enumDesc(file_Common, 11, 0);
7271
+ /**
7272
+ * Describes the message PlaybackSessionMigrateRequestEventRole.
7273
+ * Use `create(PlaybackSessionMigrateRequestEventRoleSchema)` to create a new message.
7274
+ */
7275
+ const PlaybackSessionMigrateRequestEventRoleSchema = /* @__PURE__ */ messageDesc(file_Common, 12);
7276
+ /**
7277
+ * @generated from enum PlaybackSessionMigrateRequestEventRole.Enum
7278
+ */
7279
+ let PlaybackSessionMigrateRequestEventRole_Enum = /* @__PURE__ */ function(PlaybackSessionMigrateRequestEventRole_Enum) {
7280
+ /**
7281
+ * @generated from enum value: Unknown = 0;
7282
+ */
7283
+ PlaybackSessionMigrateRequestEventRole_Enum[PlaybackSessionMigrateRequestEventRole_Enum["Unknown"] = 0] = "Unknown";
7284
+ /**
7285
+ * @generated from enum value: Receptionist = 1;
7286
+ */
7287
+ PlaybackSessionMigrateRequestEventRole_Enum[PlaybackSessionMigrateRequestEventRole_Enum["Receptionist"] = 1] = "Receptionist";
7288
+ /**
7289
+ * @generated from enum value: Source = 2;
7290
+ */
7291
+ PlaybackSessionMigrateRequestEventRole_Enum[PlaybackSessionMigrateRequestEventRole_Enum["Source"] = 2] = "Source";
7292
+ /**
7293
+ * @generated from enum value: Destination = 3;
7294
+ */
7295
+ PlaybackSessionMigrateRequestEventRole_Enum[PlaybackSessionMigrateRequestEventRole_Enum["Destination"] = 3] = "Destination";
7296
+ /**
7297
+ * @generated from enum value: InApp = 4;
7298
+ */
7299
+ PlaybackSessionMigrateRequestEventRole_Enum[PlaybackSessionMigrateRequestEventRole_Enum["InApp"] = 4] = "InApp";
7300
+ /**
7301
+ * @generated from enum value: Hijacked = 5;
7302
+ */
7303
+ PlaybackSessionMigrateRequestEventRole_Enum[PlaybackSessionMigrateRequestEventRole_Enum["Hijacked"] = 5] = "Hijacked";
7304
+ /**
7305
+ * @generated from enum value: Group = 6;
7306
+ */
7307
+ PlaybackSessionMigrateRequestEventRole_Enum[PlaybackSessionMigrateRequestEventRole_Enum["Group"] = 6] = "Group";
7308
+ return PlaybackSessionMigrateRequestEventRole_Enum;
7309
+ }({});
7310
+ /**
7311
+ * Describes the enum PlaybackSessionMigrateRequestEventRole.Enum.
7312
+ */
7313
+ const PlaybackSessionMigrateRequestEventRole_EnumSchema = /* @__PURE__ */ enumDesc(file_Common, 12, 0);
7314
+ /**
7315
+ * Describes the message GroupSessionRouteType.
7316
+ * Use `create(GroupSessionRouteTypeSchema)` to create a new message.
7317
+ */
7318
+ const GroupSessionRouteTypeSchema = /* @__PURE__ */ messageDesc(file_Common, 13);
7319
+ /**
7320
+ * @generated from enum GroupSessionRouteType.Enum
7321
+ */
7322
+ let GroupSessionRouteType_Enum = /* @__PURE__ */ function(GroupSessionRouteType_Enum) {
7323
+ /**
7324
+ * @generated from enum value: Unknown = 0;
7325
+ */
7326
+ GroupSessionRouteType_Enum[GroupSessionRouteType_Enum["Unknown"] = 0] = "Unknown";
7327
+ /**
7328
+ * @generated from enum value: CarKit = 1;
7329
+ */
7330
+ GroupSessionRouteType_Enum[GroupSessionRouteType_Enum["CarKit"] = 1] = "CarKit";
7331
+ /**
7332
+ * @generated from enum value: CarPlay = 2;
7333
+ */
7334
+ GroupSessionRouteType_Enum[GroupSessionRouteType_Enum["CarPlay"] = 2] = "CarPlay";
7335
+ /**
7336
+ * @generated from enum value: Speaker = 5;
7337
+ */
7338
+ GroupSessionRouteType_Enum[GroupSessionRouteType_Enum["Speaker"] = 5] = "Speaker";
7339
+ /**
7340
+ * @generated from enum value: HomePod = 8;
7341
+ */
7342
+ GroupSessionRouteType_Enum[GroupSessionRouteType_Enum["HomePod"] = 8] = "HomePod";
7343
+ /**
7344
+ * @generated from enum value: HomePodMini = 9;
7345
+ */
7346
+ GroupSessionRouteType_Enum[GroupSessionRouteType_Enum["HomePodMini"] = 9] = "HomePodMini";
7347
+ /**
7348
+ * @generated from enum value: AppleTV = 11;
7349
+ */
7350
+ GroupSessionRouteType_Enum[GroupSessionRouteType_Enum["AppleTV"] = 11] = "AppleTV";
7351
+ return GroupSessionRouteType_Enum;
7352
+ }({});
7353
+ /**
7354
+ * Describes the enum GroupSessionRouteType.Enum.
7355
+ */
7356
+ const GroupSessionRouteType_EnumSchema = /* @__PURE__ */ enumDesc(file_Common, 13, 0);
7357
+ /**
7358
+ * Describes the message ReplaceIntent.
7359
+ * Use `create(ReplaceIntentSchema)` to create a new message.
7360
+ */
7361
+ const ReplaceIntentSchema = /* @__PURE__ */ messageDesc(file_Common, 14);
7362
+ /**
7363
+ * @generated from enum ReplaceIntent.Enum
7364
+ */
7365
+ let ReplaceIntent_Enum = /* @__PURE__ */ function(ReplaceIntent_Enum) {
7366
+ /**
7367
+ * @generated from enum value: NonDestructive = 1;
7368
+ */
7369
+ ReplaceIntent_Enum[ReplaceIntent_Enum["NonDestructive"] = 1] = "NonDestructive";
7370
+ /**
7371
+ * @generated from enum value: ClearUpNext = 2;
7372
+ */
7373
+ ReplaceIntent_Enum[ReplaceIntent_Enum["ClearUpNext"] = 2] = "ClearUpNext";
7374
+ /**
7375
+ * @generated from enum value: KeepUpNext = 3;
7376
+ */
7377
+ ReplaceIntent_Enum[ReplaceIntent_Enum["KeepUpNext"] = 3] = "KeepUpNext";
7378
+ /**
7379
+ * @generated from enum value: LeaveSharedSession = 4;
7380
+ */
7381
+ ReplaceIntent_Enum[ReplaceIntent_Enum["LeaveSharedSession"] = 4] = "LeaveSharedSession";
7382
+ return ReplaceIntent_Enum;
7383
+ }({});
7384
+ /**
7385
+ * Describes the enum ReplaceIntent.Enum.
7386
+ */
7387
+ const ReplaceIntent_EnumSchema = /* @__PURE__ */ enumDesc(file_Common, 14, 0);
7388
+ /**
7389
+ * Describes the message PlaybackQueueType.
7390
+ * Use `create(PlaybackQueueTypeSchema)` to create a new message.
7391
+ */
7392
+ const PlaybackQueueTypeSchema = /* @__PURE__ */ messageDesc(file_Common, 15);
7393
+ /**
7394
+ * @generated from enum PlaybackQueueType.Enum
7395
+ */
7396
+ let PlaybackQueueType_Enum = /* @__PURE__ */ function(PlaybackQueueType_Enum) {
7397
+ /**
7398
+ * @generated from enum value: Unknown = 1;
7399
+ */
7400
+ PlaybackQueueType_Enum[PlaybackQueueType_Enum["Unknown"] = 1] = "Unknown";
7401
+ /**
7402
+ * @generated from enum value: Generic = 2;
7403
+ */
7404
+ PlaybackQueueType_Enum[PlaybackQueueType_Enum["Generic"] = 2] = "Generic";
7405
+ /**
7406
+ * @generated from enum value: Custom = 3;
7407
+ */
7408
+ PlaybackQueueType_Enum[PlaybackQueueType_Enum["Custom"] = 3] = "Custom";
7409
+ /**
7410
+ * @generated from enum value: Empty = 4;
7411
+ */
7412
+ PlaybackQueueType_Enum[PlaybackQueueType_Enum["Empty"] = 4] = "Empty";
7413
+ return PlaybackQueueType_Enum;
7414
+ }({});
7415
+ /**
7416
+ * Describes the enum PlaybackQueueType.Enum.
7417
+ */
7418
+ const PlaybackQueueType_EnumSchema = /* @__PURE__ */ enumDesc(file_Common, 15, 0);
6975
7419
 
6976
7420
  //#endregion
6977
7421
  //#region src/proto/DeviceInfoMessage_pb.ts
@@ -9450,7 +9894,7 @@ let ActionType_Enum = /* @__PURE__ */ function(ActionType_Enum) {
9450
9894
  */
9451
9895
  ActionType_Enum[ActionType_Enum["Delete"] = 3] = "Delete";
9452
9896
  /**
9453
- * "Clear" clashes with something, making mypy unhappy
9897
+ * "Clear" clashes with something, making mypy unhappy
9454
9898
  *
9455
9899
  * @generated from enum value: ClearAction = 4;
9456
9900
  */
@@ -9794,7 +10238,13 @@ var proto_exports = /* @__PURE__ */ __exportAll({
9794
10238
  AutocapitalizationTypeSchema: () => AutocapitalizationTypeSchema,
9795
10239
  AutocapitalizationType_Enum: () => AutocapitalizationType_Enum,
9796
10240
  AutocapitalizationType_EnumSchema: () => AutocapitalizationType_EnumSchema,
10241
+ ChangeTypeSchema: () => ChangeTypeSchema,
10242
+ ChangeType_Enum: () => ChangeType_Enum,
10243
+ ChangeType_EnumSchema: () => ChangeType_EnumSchema,
9797
10244
  ClientUpdatesConfigMessageSchema: () => ClientUpdatesConfigMessageSchema,
10245
+ ClusterTypeSchema: () => ClusterTypeSchema,
10246
+ ClusterType_Enum: () => ClusterType_Enum,
10247
+ ClusterType_EnumSchema: () => ClusterType_EnumSchema,
9798
10248
  Command: () => Command,
9799
10249
  CommandInfoSchema: () => CommandInfoSchema,
9800
10250
  CommandOptionsSchema: () => CommandOptionsSchema,
@@ -9822,6 +10272,9 @@ var proto_exports = /* @__PURE__ */ __exportAll({
9822
10272
  DisableReasonSchema: () => DisableReasonSchema,
9823
10273
  DisableReason_Enum: () => DisableReason_Enum,
9824
10274
  DisableReason_EnumSchema: () => DisableReason_EnumSchema,
10275
+ EndpointOptionsSchema: () => EndpointOptionsSchema,
10276
+ EndpointOptions_Enum: () => EndpointOptions_Enum,
10277
+ EndpointOptions_EnumSchema: () => EndpointOptions_EnumSchema,
9825
10278
  ErrorCodeSchema: () => ErrorCodeSchema,
9826
10279
  ErrorCode_Enum: () => ErrorCode_Enum,
9827
10280
  ErrorCode_EnumSchema: () => ErrorCode_EnumSchema,
@@ -9836,6 +10289,9 @@ var proto_exports = /* @__PURE__ */ __exportAll({
9836
10289
  GetVolumeMutedMessageSchema: () => GetVolumeMutedMessageSchema,
9837
10290
  GetVolumeMutedResultMessageSchema: () => GetVolumeMutedResultMessageSchema,
9838
10291
  GetVolumeResultMessageSchema: () => GetVolumeResultMessageSchema,
10292
+ GroupSessionRouteTypeSchema: () => GroupSessionRouteTypeSchema,
10293
+ GroupSessionRouteType_Enum: () => GroupSessionRouteType_Enum,
10294
+ GroupSessionRouteType_EnumSchema: () => GroupSessionRouteType_EnumSchema,
9839
10295
  HandlerReturnStatusSchema: () => HandlerReturnStatusSchema,
9840
10296
  HandlerReturnStatus_Enum: () => HandlerReturnStatus_Enum,
9841
10297
  HandlerReturnStatus_EnumSchema: () => HandlerReturnStatus_EnumSchema,
@@ -9867,10 +10323,19 @@ var proto_exports = /* @__PURE__ */ __exportAll({
9867
10323
  PlaybackQueueContextSchema: () => PlaybackQueueContextSchema,
9868
10324
  PlaybackQueueRequestMessageSchema: () => PlaybackQueueRequestMessageSchema,
9869
10325
  PlaybackQueueSchema: () => PlaybackQueueSchema,
10326
+ PlaybackQueueTypeSchema: () => PlaybackQueueTypeSchema,
10327
+ PlaybackQueueType_Enum: () => PlaybackQueueType_Enum,
10328
+ PlaybackQueueType_EnumSchema: () => PlaybackQueueType_EnumSchema,
10329
+ PlaybackSessionMigrateRequestEventRoleSchema: () => PlaybackSessionMigrateRequestEventRoleSchema,
10330
+ PlaybackSessionMigrateRequestEventRole_Enum: () => PlaybackSessionMigrateRequestEventRole_Enum,
10331
+ PlaybackSessionMigrateRequestEventRole_EnumSchema: () => PlaybackSessionMigrateRequestEventRole_EnumSchema,
9870
10332
  PlaybackStateSchema: () => PlaybackStateSchema,
9871
10333
  PlaybackState_Enum: () => PlaybackState_Enum,
9872
10334
  PlaybackState_EnumSchema: () => PlaybackState_EnumSchema,
9873
10335
  PlayerClientPropertiesMessageSchema: () => PlayerClientPropertiesMessageSchema,
10336
+ PlayerOptionsSchema: () => PlayerOptionsSchema,
10337
+ PlayerOptions_Enum: () => PlayerOptions_Enum,
10338
+ PlayerOptions_EnumSchema: () => PlayerOptions_EnumSchema,
9874
10339
  PlayerPathSchema: () => PlayerPathSchema,
9875
10340
  PlaylistTraitsSchema: () => PlaylistTraitsSchema,
9876
10341
  PlaylistTraits_Enum: () => PlaylistTraits_Enum,
@@ -9885,6 +10350,9 @@ var proto_exports = /* @__PURE__ */ __exportAll({
9885
10350
  QueueEndActionSchema: () => QueueEndActionSchema,
9886
10351
  QueueEndAction_Enum: () => QueueEndAction_Enum,
9887
10352
  QueueEndAction_EnumSchema: () => QueueEndAction_EnumSchema,
10353
+ RecipeTypeSchema: () => RecipeTypeSchema,
10354
+ RecipeType_Enum: () => RecipeType_Enum,
10355
+ RecipeType_EnumSchema: () => RecipeType_EnumSchema,
9888
10356
  RegisterForGameControllerEventsMessageSchema: () => RegisterForGameControllerEventsMessageSchema,
9889
10357
  RegisterForGameControllerEventsMessage_InputModeFlags: () => RegisterForGameControllerEventsMessage_InputModeFlags,
9890
10358
  RegisterForGameControllerEventsMessage_InputModeFlagsSchema: () => RegisterForGameControllerEventsMessage_InputModeFlagsSchema,
@@ -9901,6 +10369,9 @@ var proto_exports = /* @__PURE__ */ __exportAll({
9901
10369
  RepeatModeSchema: () => RepeatModeSchema,
9902
10370
  RepeatMode_Enum: () => RepeatMode_Enum,
9903
10371
  RepeatMode_EnumSchema: () => RepeatMode_EnumSchema,
10372
+ ReplaceIntentSchema: () => ReplaceIntentSchema,
10373
+ ReplaceIntent_Enum: () => ReplaceIntent_Enum,
10374
+ ReplaceIntent_EnumSchema: () => ReplaceIntent_EnumSchema,
9904
10375
  ReturnKeyTypeSchema: () => ReturnKeyTypeSchema,
9905
10376
  ReturnKeyType_Enum: () => ReturnKeyType_Enum,
9906
10377
  ReturnKeyType_EnumSchema: () => ReturnKeyType_EnumSchema,
@@ -9968,6 +10439,9 @@ var proto_exports = /* @__PURE__ */ __exportAll({
9968
10439
  ValueSchema: () => ValueSchema,
9969
10440
  VirtualTouchDeviceDescriptorSchema: () => VirtualTouchDeviceDescriptorSchema,
9970
10441
  VirtualTouchEventSchema: () => VirtualTouchEventSchema,
10442
+ VirtualTouchPhaseSchema: () => VirtualTouchPhaseSchema,
10443
+ VirtualTouchPhase_Enum: () => VirtualTouchPhase_Enum,
10444
+ VirtualTouchPhase_EnumSchema: () => VirtualTouchPhase_EnumSchema,
9971
10445
  VoiceInputDeviceDescriptorSchema: () => VoiceInputDeviceDescriptorSchema,
9972
10446
  VolumeCapabilitiesSchema: () => VolumeCapabilitiesSchema,
9973
10447
  VolumeCapabilities_Enum: () => VolumeCapabilities_Enum,
@@ -10298,6 +10772,9 @@ var ControlStream = class extends BaseStream {
10298
10772
  async post(path, body = null, headers = {}, timeout = HTTP_TIMEOUT) {
10299
10773
  return await this.#request("POST", path, body, headers, timeout);
10300
10774
  }
10775
+ async put(path, body = null, headers = {}, timeout = HTTP_TIMEOUT) {
10776
+ return await this.#request("PUT", path, body, headers, timeout);
10777
+ }
10301
10778
  async record(path, headers = {}, timeout = HTTP_TIMEOUT) {
10302
10779
  return await this.#request("RECORD", path, null, headers, timeout);
10303
10780
  }
@@ -10826,6 +11303,9 @@ var Protocol = class {
10826
11303
  get discoveryResult() {
10827
11304
  return this.#discoveryResult;
10828
11305
  }
11306
+ get audioStream() {
11307
+ return this.#audioStream;
11308
+ }
10829
11309
  get eventStream() {
10830
11310
  return this.#eventStream;
10831
11311
  }
@@ -10844,6 +11324,7 @@ var Protocol = class {
10844
11324
  #pairing;
10845
11325
  #sessionUUID;
10846
11326
  #verify;
11327
+ #audioStream;
10847
11328
  #dataStream;
10848
11329
  #eventStream;
10849
11330
  #timingServer;
@@ -10859,11 +11340,15 @@ var Protocol = class {
10859
11340
  await this.#controlStream.connect();
10860
11341
  }
10861
11342
  destroy() {
11343
+ this.#audioStream?.close();
10862
11344
  this.#controlStream.destroy();
10863
11345
  this.#dataStream?.destroy();
10864
11346
  this.#eventStream?.destroy();
10865
11347
  }
10866
11348
  disconnect() {
11349
+ try {
11350
+ this.#audioStream?.close();
11351
+ } catch {}
10867
11352
  try {
10868
11353
  this.#dataStream?.destroy();
10869
11354
  } catch {}
@@ -10873,6 +11358,7 @@ var Protocol = class {
10873
11358
  try {
10874
11359
  this.#controlStream.destroy();
10875
11360
  } catch {}
11361
+ this.#audioStream = void 0;
10876
11362
  this.#dataStream = void 0;
10877
11363
  this.#eventStream = void 0;
10878
11364
  this.#timingServer = void 0;
@@ -10973,6 +11459,74 @@ var Protocol = class {
10973
11459
  await this.#eventStream.connect();
10974
11460
  await this.#controlStream.record(`/${this.#controlStream.sessionId}`);
10975
11461
  }
11462
+ async playUrl(url, sharedSecret, pairingId, position = 0) {
11463
+ const setupBody = {
11464
+ deviceID: pairingId.toString(),
11465
+ sessionUUID: this.#sessionUUID.toUpperCase(),
11466
+ isMultiSelectAirPlay: true,
11467
+ groupContainsGroupLeader: false,
11468
+ macAddress: getMacAddress().toUpperCase(),
11469
+ model: "iPhone16,2",
11470
+ name: "apple-protocols",
11471
+ osBuildVersion: "18C66",
11472
+ osName: "iPhone OS",
11473
+ osVersion: "14.3",
11474
+ sourceVersion: "320.20",
11475
+ senderSupportsRelay: false,
11476
+ statsCollectionEnabled: false
11477
+ };
11478
+ if (this.#timingServer) {
11479
+ setupBody.timingPort = this.#timingServer.port;
11480
+ setupBody.timingProtocol = "NTP";
11481
+ } else setupBody.timingProtocol = "None";
11482
+ const setupResponse = await this.#controlStream.setup(`/${this.#controlStream.sessionId}`, Buffer.from(Plist.serialize(setupBody)), { "Content-Type": "application/x-apple-binary-plist" });
11483
+ if (setupResponse.status !== 200) throw new Error(`Failed to setup for playback: ${setupResponse.status}`);
11484
+ const eventPort = Plist.parse(await setupResponse.arrayBuffer()).eventPort & 65535;
11485
+ this.#eventStream = new EventStream(this.#context, this.#controlStream.address, eventPort);
11486
+ this.#eventStream.setup(sharedSecret);
11487
+ await this.#eventStream.connect();
11488
+ await this.#controlStream.record(`/${this.#controlStream.sessionId}`);
11489
+ const playBody = Plist.serialize({
11490
+ "Content-Location": url,
11491
+ "Start-Position-Seconds": position,
11492
+ uuid: this.#sessionUUID.toUpperCase(),
11493
+ streamType: 1,
11494
+ mediaType: "file",
11495
+ volume: 1,
11496
+ rate: 1,
11497
+ clientBundleID: "com.basmilius.apple-protocols",
11498
+ clientProcName: "apple-protocols",
11499
+ osBuildVersion: "18C66",
11500
+ model: "iPhone16,2",
11501
+ SenderMACAddress: getMacAddress().toUpperCase()
11502
+ });
11503
+ const response = await this.#controlStream.post("/play", Buffer.from(playBody), { "Content-Type": "application/x-apple-binary-plist" });
11504
+ this.context.logger.info("[protocol]", `play_url response: ${response.status}`);
11505
+ if (response.status !== 200) throw new Error(`Failed to play URL: ${response.status}`);
11506
+ await this.#putProperty("isInterestedInDateRange", { value: true });
11507
+ await this.#putProperty("actionAtItemEnd", { value: 0 });
11508
+ await this.#controlStream.post("/rate?value=1.000000");
11509
+ await this.#putProperty("forwardEndTime", { value: {
11510
+ flags: 0,
11511
+ value: 0,
11512
+ epoch: 0,
11513
+ timescale: 0
11514
+ } });
11515
+ await this.#putProperty("reverseEndTime", { value: {
11516
+ flags: 0,
11517
+ value: 0,
11518
+ epoch: 0,
11519
+ timescale: 0
11520
+ } });
11521
+ }
11522
+ async #putProperty(property, body) {
11523
+ await this.#controlStream.put(`/setProperty?${property}`, Buffer.from(Plist.serialize(body)), { "Content-Type": "application/x-apple-binary-plist" });
11524
+ }
11525
+ async setupAudioStream(source) {
11526
+ this.#audioStream = new AudioStream(this);
11527
+ await this.#audioStream.setup();
11528
+ await this.#audioStream.stream(source, this.#discoveryResult.address);
11529
+ }
10976
11530
  useTimingServer(timingServer) {
10977
11531
  this.#timingServer = timingServer;
10978
11532
  }
@@ -10988,12 +11542,19 @@ var dataStreamMessages_exports = /* @__PURE__ */ __exportAll({
10988
11542
  getState: () => getState,
10989
11543
  getVolume: () => getVolume,
10990
11544
  getVolumeMuted: () => getVolumeMuted,
11545
+ modifyOutputContext: () => modifyOutputContext,
10991
11546
  notification: () => notification,
10992
11547
  playbackQueueRequest: () => playbackQueueRequest,
10993
11548
  protocol: () => protocol,
10994
11549
  sendButtonEvent: () => sendButtonEvent,
10995
11550
  sendCommand: () => sendCommand,
11551
+ sendCommandWithPlaybackPosition: () => sendCommandWithPlaybackPosition,
11552
+ sendCommandWithPlaybackRate: () => sendCommandWithPlaybackRate,
11553
+ sendCommandWithRepeatMode: () => sendCommandWithRepeatMode,
11554
+ sendCommandWithShuffleMode: () => sendCommandWithShuffleMode,
11555
+ sendCommandWithSkipInterval: () => sendCommandWithSkipInterval,
10996
11556
  sendHIDEvent: () => sendHIDEvent,
11557
+ sendVirtualTouchEvent: () => sendVirtualTouchEvent,
10997
11558
  setConnectionState: () => setConnectionState,
10998
11559
  setReadyState: () => setReadyState,
10999
11560
  setVolume: () => setVolume,
@@ -11051,6 +11612,17 @@ function deviceInfo(pairingId) {
11051
11612
  setExtension(protocolMessage, deviceInfoMessage, message);
11052
11613
  return [protocolMessage, deviceInfoMessage];
11053
11614
  }
11615
+ function modifyOutputContext(addingDevices = [], removingDevices = [], settingDevices = []) {
11616
+ const protocolMessage = protocol(ProtocolMessage_Type.MODIFY_OUTPUT_CONTEXT_REQUEST_MESSAGE);
11617
+ const message = create(ModifyOutputContextRequestMessageSchema, {
11618
+ type: ModifyOutputContextRequestType_Enum.SharedAudioPresentation,
11619
+ addingDevices,
11620
+ removingDevices,
11621
+ settingDevices
11622
+ });
11623
+ setExtension(protocolMessage, modifyOutputContextRequestMessage, message);
11624
+ return [protocolMessage, modifyOutputContextRequestMessage];
11625
+ }
11054
11626
  function getState() {
11055
11627
  const protocolMessage = protocol(ProtocolMessage_Type.GET_STATE_MESSAGE);
11056
11628
  const message = create(GetStateMessageSchema, {});
@@ -11105,6 +11677,21 @@ function sendButtonEvent(usagePage, usage, buttonDown) {
11105
11677
  setExtension(protocolMessage, sendButtonEventMessage, message);
11106
11678
  return [protocolMessage, sendButtonEventMessage];
11107
11679
  }
11680
+ function sendCommandWithSkipInterval(command, skipInterval) {
11681
+ return sendCommand(command, create(CommandOptionsSchema, { skipInterval }));
11682
+ }
11683
+ function sendCommandWithPlaybackPosition(command, playbackPosition) {
11684
+ return sendCommand(command, create(CommandOptionsSchema, { playbackPosition }));
11685
+ }
11686
+ function sendCommandWithPlaybackRate(command, playbackRate) {
11687
+ return sendCommand(command, create(CommandOptionsSchema, { playbackRate }));
11688
+ }
11689
+ function sendCommandWithShuffleMode(command, shuffleMode) {
11690
+ return sendCommand(command, create(CommandOptionsSchema, { shuffleMode }));
11691
+ }
11692
+ function sendCommandWithRepeatMode(command, repeatMode) {
11693
+ return sendCommand(command, create(CommandOptionsSchema, { repeatMode }));
11694
+ }
11108
11695
  function sendCommand(command, options) {
11109
11696
  const protocolMessage = protocol(ProtocolMessage_Type.SEND_COMMAND_MESSAGE);
11110
11697
  const message = create(SendCommandMessageSchema, {
@@ -11114,6 +11701,20 @@ function sendCommand(command, options) {
11114
11701
  setExtension(protocolMessage, sendCommandMessage, message);
11115
11702
  return [protocolMessage, sendCommandMessage];
11116
11703
  }
11704
+ function sendVirtualTouchEvent(x, y, phase, finger) {
11705
+ const protocolMessage = protocol(ProtocolMessage_Type.SEND_VIRTUAL_TOUCH_EVENT_MESSAGE);
11706
+ const message = create(SendVirtualTouchEventMessageSchema, {
11707
+ virtualDeviceID: 1n,
11708
+ event: create(VirtualTouchEventSchema, {
11709
+ x: BigInt(x),
11710
+ y: BigInt(y),
11711
+ phase,
11712
+ finger
11713
+ })
11714
+ });
11715
+ setExtension(protocolMessage, sendVirtualTouchEventMessage, message);
11716
+ return [protocolMessage, sendVirtualTouchEventMessage];
11717
+ }
11117
11718
  function sendHIDEvent(usePage, usage, down) {
11118
11719
  const protocolMessage = protocol(ProtocolMessage_Type.SEND_HID_EVENT_MESSAGE);
11119
11720
  const message = create(SendHIDEventMessageSchema, { hidEventData: Buffer.concat([
@@ -11170,5 +11771,5 @@ function getExtension(message, extension) {
11170
11771
  }
11171
11772
 
11172
11773
  //#endregion
11173
- export { BaseStream, ControlStream, DataStream, dataStreamMessages_exports as DataStreamMessage, AudioStream as EXPERIMENTAL_AudioStream, EventStream, Pairing, proto_exports as Proto, Protocol, Verify };
11774
+ export { AudioStream, BaseStream, ControlStream, DataStream, dataStreamMessages_exports as DataStreamMessage, EventStream, Pairing, proto_exports as Proto, Protocol, Verify };
11174
11775
  //# sourceMappingURL=index.mjs.map