@camera.ui/camera-ui-homekit 0.0.28 → 0.0.30
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/bundle.zip +0 -0
- package/package.json +17 -34
- package/CHANGELOG.md +0 -8
- package/CONTRIBUTING.md +0 -1
- package/LICENSE.md +0 -22
- package/README.md +0 -1
- package/dist/camera/accessory.d.ts +0 -28
- package/dist/camera/accessory.js +0 -380
- package/dist/camera/accessory.js.map +0 -1
- package/dist/camera/recordingDelegate.d.ts +0 -27
- package/dist/camera/recordingDelegate.js +0 -264
- package/dist/camera/recordingDelegate.js.map +0 -1
- package/dist/camera/services.d.ts +0 -28
- package/dist/camera/services.js +0 -202
- package/dist/camera/services.js.map +0 -1
- package/dist/camera/sessionWrapper.d.ts +0 -40
- package/dist/camera/sessionWrapper.js +0 -517
- package/dist/camera/sessionWrapper.js.map +0 -1
- package/dist/camera/streamingDelegate.d.ts +0 -14
- package/dist/camera/streamingDelegate.js +0 -100
- package/dist/camera/streamingDelegate.js.map +0 -1
- package/dist/camera/streamingServer.d.ts +0 -26
- package/dist/camera/streamingServer.js +0 -145
- package/dist/camera/streamingServer.js.map +0 -1
- package/dist/constants.d.ts +0 -1
- package/dist/constants.js +0 -7
- package/dist/constants.js.map +0 -1
- package/dist/crypto.d.ts +0 -1
- package/dist/crypto.js +0 -34
- package/dist/crypto.js.map +0 -1
- package/dist/index.d.ts +0 -16
- package/dist/index.js +0 -53
- package/dist/index.js.map +0 -1
- package/dist/types.d.ts +0 -16
- package/dist/types.js +0 -2
- package/dist/types.js.map +0 -1
- package/dist/utils/mac.d.ts +0 -4
- package/dist/utils/mac.js +0 -19
- package/dist/utils/mac.js.map +0 -1
- package/dist/utils/opus-repacketizer.d.ts +0 -7
- package/dist/utils/opus-repacketizer.js +0 -163
- package/dist/utils/opus-repacketizer.js.map +0 -1
- package/dist/utils/processor.d.ts +0 -85
- package/dist/utils/processor.js +0 -475
- package/dist/utils/processor.js.map +0 -1
- package/dist/utils/return-audio-transcoder.d.ts +0 -39
- package/dist/utils/return-audio-transcoder.js +0 -82
- package/dist/utils/return-audio-transcoder.js.map +0 -1
- package/dist/utils/srtp.d.ts +0 -8
- package/dist/utils/srtp.js +0 -22
- package/dist/utils/srtp.js.map +0 -1
- package/dist/utils/utils.d.ts +0 -10
- package/dist/utils/utils.js +0 -38
- package/dist/utils/utils.js.map +0 -1
- package/media/cameraOffline.png +0 -0
- package/media/maxStreams.png +0 -0
- package/media/noSnapshot.png +0 -0
- package/media/privacyMode.png +0 -0
package/dist/utils/processor.js
DELETED
|
@@ -1,475 +0,0 @@
|
|
|
1
|
-
import { RtpHeader, RtpPacket, SrtpSession } from 'werift';
|
|
2
|
-
import { OpusRepacketizer } from './opus-repacketizer.js';
|
|
3
|
-
export function getSessionConfig(srtpOptions) {
|
|
4
|
-
return {
|
|
5
|
-
keys: {
|
|
6
|
-
localMasterKey: srtpOptions.srtpKey,
|
|
7
|
-
localMasterSalt: srtpOptions.srtpSalt,
|
|
8
|
-
remoteMasterKey: srtpOptions.srtpKey,
|
|
9
|
-
remoteMasterSalt: srtpOptions.srtpSalt,
|
|
10
|
-
},
|
|
11
|
-
profile: 1,
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
export class AudioProcessor {
|
|
15
|
-
cameraAccessory;
|
|
16
|
-
audioSsrc;
|
|
17
|
-
audioSrtp;
|
|
18
|
-
audioSplitter;
|
|
19
|
-
targetAddress;
|
|
20
|
-
targetPort;
|
|
21
|
-
payloadType;
|
|
22
|
-
sampleRate;
|
|
23
|
-
packetTime;
|
|
24
|
-
isOpus;
|
|
25
|
-
cameraLogger;
|
|
26
|
-
audioSrtpSession;
|
|
27
|
-
opusRepacketizer;
|
|
28
|
-
audioIntervalScale;
|
|
29
|
-
firstTimestamp;
|
|
30
|
-
audioPacketCount = 0;
|
|
31
|
-
constructor(cameraAccessory, audioSsrc, audioSrtp, audioSplitter, targetAddress, targetPort, payloadType, sampleRate, packetTime, isOpus, cameraLogger) {
|
|
32
|
-
this.cameraAccessory = cameraAccessory;
|
|
33
|
-
this.audioSsrc = audioSsrc;
|
|
34
|
-
this.audioSrtp = audioSrtp;
|
|
35
|
-
this.audioSplitter = audioSplitter;
|
|
36
|
-
this.targetAddress = targetAddress;
|
|
37
|
-
this.targetPort = targetPort;
|
|
38
|
-
this.payloadType = payloadType;
|
|
39
|
-
this.sampleRate = sampleRate;
|
|
40
|
-
this.packetTime = packetTime;
|
|
41
|
-
this.isOpus = isOpus;
|
|
42
|
-
this.cameraLogger = cameraLogger;
|
|
43
|
-
this.audioSrtpSession = new SrtpSession(getSessionConfig(this.audioSrtp));
|
|
44
|
-
this.opusRepacketizer = new OpusRepacketizer(this.packetTime / 20);
|
|
45
|
-
this.audioIntervalScale = ((this.sampleRate / 8) * this.packetTime) / 20;
|
|
46
|
-
}
|
|
47
|
-
processPacket(data) {
|
|
48
|
-
let rtp = RtpPacket.deSerialize(data);
|
|
49
|
-
if (this.isOpus) {
|
|
50
|
-
rtp = this.opusRepacketizer.repacketize(rtp);
|
|
51
|
-
if (!rtp) {
|
|
52
|
-
return null;
|
|
53
|
-
}
|
|
54
|
-
if (!this.firstTimestamp) {
|
|
55
|
-
this.firstTimestamp = rtp.header.timestamp;
|
|
56
|
-
}
|
|
57
|
-
rtp.header.timestamp = (this.firstTimestamp + this.audioPacketCount * 160 * this.audioIntervalScale) % 0xffffffff;
|
|
58
|
-
this.audioPacketCount++;
|
|
59
|
-
this.sendPacket(rtp);
|
|
60
|
-
}
|
|
61
|
-
else {
|
|
62
|
-
this.sendPacket(rtp);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
sendPacket(rtp) {
|
|
66
|
-
try {
|
|
67
|
-
rtp.header.payloadType = this.payloadType;
|
|
68
|
-
rtp.header.ssrc = this.audioSsrc;
|
|
69
|
-
const encryptedPacket = this.audioSrtpSession.encrypt(rtp.payload, rtp.header);
|
|
70
|
-
this.audioSplitter.send(encryptedPacket, {
|
|
71
|
-
port: this.targetPort,
|
|
72
|
-
address: this.targetAddress,
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
catch (error) {
|
|
76
|
-
this.cameraLogger.trace('Error sending audio packet:', error);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
// Constants
|
|
81
|
-
const NAL_UNIT_TYPE_MASK = 0x1f;
|
|
82
|
-
const FU_A_HEADER_SIZE = 2;
|
|
83
|
-
const RTP_HEADER_SIZE = 12;
|
|
84
|
-
// const NAL_UNIT_TYPE_PFRAME = 1;
|
|
85
|
-
const NAL_UNIT_TYPE_IFRAME = 5;
|
|
86
|
-
const NAL_UNIT_TYPE_SEI = 6;
|
|
87
|
-
const NAL_UNIT_TYPE_SPS = 7;
|
|
88
|
-
const NAL_UNIT_TYPE_PPS = 8;
|
|
89
|
-
const NAL_UNIT_TYPE_AUD = 9;
|
|
90
|
-
const NAL_UNIT_TYPE_FILLER = 12;
|
|
91
|
-
const NAL_UNIT_TYPE_STAP_A = 24;
|
|
92
|
-
const NAL_UNIT_TYPE_STAP_B = 25;
|
|
93
|
-
const NAL_UNIT_TYPE_MTAP16 = 26;
|
|
94
|
-
const NAL_UNIT_TYPE_MTAP24 = 27;
|
|
95
|
-
const NAL_UNIT_TYPE_FU_A = 28;
|
|
96
|
-
export class VideoProcessor {
|
|
97
|
-
cameraAccessory;
|
|
98
|
-
streamSession;
|
|
99
|
-
videoSsrc;
|
|
100
|
-
videoSrtp;
|
|
101
|
-
videoSplitter;
|
|
102
|
-
targetAddress;
|
|
103
|
-
targetPort;
|
|
104
|
-
mtu;
|
|
105
|
-
payloadType;
|
|
106
|
-
cameraLogger;
|
|
107
|
-
videoSrtpSession;
|
|
108
|
-
sequenceNumber;
|
|
109
|
-
sps = null;
|
|
110
|
-
pps = null;
|
|
111
|
-
incompleteFrame = null;
|
|
112
|
-
incompleteFrameTimestamp = null;
|
|
113
|
-
lastSequenceNumber = -1;
|
|
114
|
-
sendQueue = [];
|
|
115
|
-
isSending = false;
|
|
116
|
-
isStopped = false;
|
|
117
|
-
constructor(cameraAccessory, streamSession, videoSsrc, videoSrtp, videoSplitter, targetAddress, targetPort, mtu, payloadType, cameraLogger) {
|
|
118
|
-
this.cameraAccessory = cameraAccessory;
|
|
119
|
-
this.streamSession = streamSession;
|
|
120
|
-
this.videoSsrc = videoSsrc;
|
|
121
|
-
this.videoSrtp = videoSrtp;
|
|
122
|
-
this.videoSplitter = videoSplitter;
|
|
123
|
-
this.targetAddress = targetAddress;
|
|
124
|
-
this.targetPort = targetPort;
|
|
125
|
-
this.mtu = mtu;
|
|
126
|
-
this.payloadType = payloadType;
|
|
127
|
-
this.cameraLogger = cameraLogger;
|
|
128
|
-
this.videoSrtpSession = new SrtpSession(getSessionConfig(this.videoSrtp));
|
|
129
|
-
this.sequenceNumber = Math.floor(Math.random() * 65536);
|
|
130
|
-
this.streamSession.onCallEnded.subscribe(() => this.stop());
|
|
131
|
-
}
|
|
132
|
-
processPacket(rtp) {
|
|
133
|
-
if (!rtp || !rtp.payload) {
|
|
134
|
-
this.cameraLogger.trace('Invalid RTP packet or missing payload.');
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
const sequenceNumber = rtp.header.sequenceNumber;
|
|
138
|
-
// Check for sequence number jumps
|
|
139
|
-
if (this.lastSequenceNumber !== -1 && sequenceNumber !== (this.lastSequenceNumber + 1) % 65536) {
|
|
140
|
-
const gap = (sequenceNumber - this.lastSequenceNumber + 65536) % 65536;
|
|
141
|
-
if (gap > 1) {
|
|
142
|
-
this.cameraLogger.trace(`Sequence number gap detected. Missing ${gap - 1} packets.`);
|
|
143
|
-
if (this.incompleteFrame) {
|
|
144
|
-
this.cameraLogger.trace(`Incomplete frame detected during packet loss (${gap - 1}). Discarding ${this.incompleteFrame.length} bytes.`);
|
|
145
|
-
this.incompleteFrame = null;
|
|
146
|
-
this.incompleteFrameTimestamp = null;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
this.lastSequenceNumber = sequenceNumber;
|
|
151
|
-
const naluType = rtp.payload[0] & NAL_UNIT_TYPE_MASK;
|
|
152
|
-
// this.cameraLogger.trace(
|
|
153
|
-
// `Received ordered packet: NAL Unit Type: ${naluType}, Payload length: ${orderedPacket.payload.length}, First 10 bytes: ${orderedPacket.payload.subarray(0, 10).toString('hex')}`,
|
|
154
|
-
// );
|
|
155
|
-
// Process the packet based on its NAL Unit type
|
|
156
|
-
switch (naluType) {
|
|
157
|
-
case NAL_UNIT_TYPE_FU_A:
|
|
158
|
-
this.processFuAPacket(rtp);
|
|
159
|
-
break;
|
|
160
|
-
case NAL_UNIT_TYPE_STAP_A:
|
|
161
|
-
case NAL_UNIT_TYPE_STAP_B:
|
|
162
|
-
this.processSTAP(rtp);
|
|
163
|
-
break;
|
|
164
|
-
case NAL_UNIT_TYPE_MTAP16:
|
|
165
|
-
case NAL_UNIT_TYPE_MTAP24:
|
|
166
|
-
this.processMTAP(rtp);
|
|
167
|
-
break;
|
|
168
|
-
default:
|
|
169
|
-
this.processSimpleNALU(rtp);
|
|
170
|
-
break;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
processFuAPacket(rtp) {
|
|
174
|
-
const payload = rtp.payload;
|
|
175
|
-
if (payload.length < 2) {
|
|
176
|
-
this.cameraLogger.trace('FU-A packet too short. Discarding.');
|
|
177
|
-
return;
|
|
178
|
-
}
|
|
179
|
-
const fuIndicator = payload[0]; // Original NAL header with FU-A type
|
|
180
|
-
const fuHeader = payload[1]; // FU-A header containing S, E, and NAL unit type
|
|
181
|
-
const startBit = (fuHeader & 0x80) !== 0;
|
|
182
|
-
const endBit = (fuHeader & 0x40) !== 0;
|
|
183
|
-
const naluType = fuHeader & NAL_UNIT_TYPE_MASK;
|
|
184
|
-
const originalNalHeader = (fuIndicator & 0xe0) | naluType;
|
|
185
|
-
// If start of a new fragmented NALU
|
|
186
|
-
if (startBit) {
|
|
187
|
-
// If there's an incomplete frame, discard it
|
|
188
|
-
if (this.incompleteFrame) {
|
|
189
|
-
this.cameraLogger.trace('Incomplete frame detected. Discarding previous incomplete frame.');
|
|
190
|
-
this.incompleteFrame = null;
|
|
191
|
-
this.incompleteFrameTimestamp = null;
|
|
192
|
-
}
|
|
193
|
-
// Initialize the incomplete frame buffer with the reconstructed NALU header
|
|
194
|
-
this.incompleteFrame = Buffer.from([originalNalHeader]);
|
|
195
|
-
// Set the timestamp for the incomplete frame
|
|
196
|
-
this.incompleteFrameTimestamp = rtp.header.timestamp;
|
|
197
|
-
}
|
|
198
|
-
// Append the current payload (excluding the FU-A indicator and header) to the incomplete frame
|
|
199
|
-
if (this.incompleteFrame) {
|
|
200
|
-
this.incompleteFrame = Buffer.concat([this.incompleteFrame, payload.subarray(2)]);
|
|
201
|
-
}
|
|
202
|
-
else {
|
|
203
|
-
// this.cameraLogger.trace( 'Received FU-A continuation or end without start. Discarding.');
|
|
204
|
-
return;
|
|
205
|
-
}
|
|
206
|
-
// If this is the end of the fragmented NALU
|
|
207
|
-
if (endBit) {
|
|
208
|
-
// Process the complete frame
|
|
209
|
-
this.processCompleteFrame(this.incompleteFrame, rtp.header.marker, this.incompleteFrameTimestamp);
|
|
210
|
-
// Reset the incomplete frame variables
|
|
211
|
-
this.incompleteFrame = null;
|
|
212
|
-
this.incompleteFrameTimestamp = null;
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
createStapAPacket(nalus) {
|
|
216
|
-
const nalRefIdc = 3 << 5; // nal_ref_idc = 3
|
|
217
|
-
const stapANalUnitType = NAL_UNIT_TYPE_STAP_A;
|
|
218
|
-
const stapAHeader = Buffer.from([nalRefIdc | stapANalUnitType]);
|
|
219
|
-
const naluBuffers = nalus.map((nalu) => {
|
|
220
|
-
const size = Buffer.alloc(2);
|
|
221
|
-
size.writeUInt16BE(nalu.length);
|
|
222
|
-
return Buffer.concat([size, nalu]);
|
|
223
|
-
});
|
|
224
|
-
return Buffer.concat([stapAHeader, ...naluBuffers]);
|
|
225
|
-
}
|
|
226
|
-
processSTAP(rtp) {
|
|
227
|
-
const payload = rtp.payload;
|
|
228
|
-
let offset = 1; // Skip STAP header
|
|
229
|
-
const nalus = [];
|
|
230
|
-
// For STAP-B, skip the DON (Decoding Order Number)
|
|
231
|
-
if ((payload[0] & NAL_UNIT_TYPE_MASK) === NAL_UNIT_TYPE_STAP_B) {
|
|
232
|
-
offset += 2;
|
|
233
|
-
}
|
|
234
|
-
while (offset < payload.length) {
|
|
235
|
-
const naluSize = payload.readUInt16BE(offset);
|
|
236
|
-
offset += 2;
|
|
237
|
-
const nalu = payload.subarray(offset, offset + naluSize);
|
|
238
|
-
offset += naluSize;
|
|
239
|
-
nalus.push(nalu);
|
|
240
|
-
// this.cameraLogger.trace(`Processing embedded NALU of size: ${naluSize}, Total embedded NALUs: ${nalus.length}`);
|
|
241
|
-
}
|
|
242
|
-
// Process all buffered NALUs
|
|
243
|
-
nalus.forEach((nalu, index) => {
|
|
244
|
-
this.processCompleteFrame(nalu, index === nalus.length - 1 && rtp.header.marker, rtp.header.timestamp);
|
|
245
|
-
});
|
|
246
|
-
}
|
|
247
|
-
processMTAP(rtp) {
|
|
248
|
-
const payload = rtp.payload;
|
|
249
|
-
const naluType = payload[0] & NAL_UNIT_TYPE_MASK;
|
|
250
|
-
let offset = 3; // Skip MTAP header and DONB
|
|
251
|
-
while (offset < payload.length) {
|
|
252
|
-
// const dond = payload[offset++]; // DOND (Decoding Order Number Difference)
|
|
253
|
-
const tsOffset = naluType === NAL_UNIT_TYPE_MTAP16 ? payload.readUInt16BE(offset) : payload.readUIntBE(offset, 3);
|
|
254
|
-
offset += naluType === NAL_UNIT_TYPE_MTAP16 ? 2 : 3;
|
|
255
|
-
const naluSize = payload.readUInt16BE(offset);
|
|
256
|
-
offset += 2;
|
|
257
|
-
const nalu = payload.subarray(offset, offset + naluSize);
|
|
258
|
-
offset += naluSize;
|
|
259
|
-
// Calculate the timestamp for this NALU
|
|
260
|
-
const naluTimestamp = (rtp.header.timestamp + tsOffset) & 0xffffffff;
|
|
261
|
-
// this.cameraLogger.trace(`Processing MTAP NALU: size ${naluSize}, timestamp offset ${tsOffset}, DOND ${dond}`);
|
|
262
|
-
this.processCompleteFrame(nalu, offset >= payload.length && rtp.header.marker, naluTimestamp);
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
processSimpleNALU(rtp) {
|
|
266
|
-
const naluType = rtp.payload[0] & NAL_UNIT_TYPE_MASK;
|
|
267
|
-
// this.cameraLogger.trace(`Processing Simple NAL Unit Type: ${naluType}, Marker: ${rtp.header.marker}`);
|
|
268
|
-
switch (naluType) {
|
|
269
|
-
case NAL_UNIT_TYPE_SPS:
|
|
270
|
-
this.sps = Buffer.from(rtp.payload);
|
|
271
|
-
break;
|
|
272
|
-
case NAL_UNIT_TYPE_PPS:
|
|
273
|
-
this.pps = Buffer.from(rtp.payload);
|
|
274
|
-
break;
|
|
275
|
-
case NAL_UNIT_TYPE_SEI:
|
|
276
|
-
case NAL_UNIT_TYPE_AUD:
|
|
277
|
-
case NAL_UNIT_TYPE_FILLER:
|
|
278
|
-
// this.cameraLogger.trace(`Skipping NAL Unit Type: ${naluType}`);
|
|
279
|
-
break;
|
|
280
|
-
default:
|
|
281
|
-
this.processCompleteFrame(rtp.payload, rtp.header.marker, rtp.header.timestamp);
|
|
282
|
-
break;
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
processCompleteFrame(frame, marker, timestamp) {
|
|
286
|
-
const naluType = frame[0] & NAL_UNIT_TYPE_MASK;
|
|
287
|
-
// this.cameraLogger.trace(
|
|
288
|
-
// `Processing complete frame: NAL Unit Type: ${naluType}, Marker: ${marker}, Length: ${frame.length}, First 10 bytes: ${frame.subarray(0, 10).toString('hex')}`,
|
|
289
|
-
// );
|
|
290
|
-
if (this.isIDRFrame(naluType, marker, frame)) {
|
|
291
|
-
if (this.sps && this.pps) {
|
|
292
|
-
const stapAPacket = this.createStapAPacket([this.sps, this.pps]);
|
|
293
|
-
this.queueRTPPacket(stapAPacket, false, timestamp);
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
this.fragmentAndSendNALU(frame, this.mtu - RTP_HEADER_SIZE - FU_A_HEADER_SIZE, marker, timestamp);
|
|
297
|
-
}
|
|
298
|
-
fragmentAndSendNALU(nalu, maxFragmentSize, finalMarker, timestamp) {
|
|
299
|
-
const naluHeader = nalu[0];
|
|
300
|
-
const naluType = naluHeader & NAL_UNIT_TYPE_MASK;
|
|
301
|
-
const naluData = nalu.subarray(1);
|
|
302
|
-
let naluDataIndex = 0;
|
|
303
|
-
while (naluDataIndex < naluData.length) {
|
|
304
|
-
const currentFragmentSize = Math.min(maxFragmentSize - FU_A_HEADER_SIZE, naluData.length - naluDataIndex);
|
|
305
|
-
const isLastFragment = naluDataIndex + currentFragmentSize === naluData.length;
|
|
306
|
-
const fragmentHeader = Buffer.alloc(FU_A_HEADER_SIZE);
|
|
307
|
-
fragmentHeader[0] = (naluHeader & 0xe0) | NAL_UNIT_TYPE_FU_A;
|
|
308
|
-
fragmentHeader[1] = naluType;
|
|
309
|
-
if (naluDataIndex === 0)
|
|
310
|
-
fragmentHeader[1] |= 0x80; // Start bit
|
|
311
|
-
if (isLastFragment)
|
|
312
|
-
fragmentHeader[1] |= 0x40; // End bit
|
|
313
|
-
const fragment = Buffer.concat([fragmentHeader, naluData.subarray(naluDataIndex, naluDataIndex + currentFragmentSize)]);
|
|
314
|
-
// Always set the marker on the last fragment of the NALU
|
|
315
|
-
this.queueRTPPacket(fragment, isLastFragment, timestamp);
|
|
316
|
-
naluDataIndex += currentFragmentSize;
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
queueRTPPacket(payload, marker, timestamp) {
|
|
320
|
-
this.sendQueue.push({ payload, marker, timestamp });
|
|
321
|
-
if (!this.isSending) {
|
|
322
|
-
this.processQueue();
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
async processQueue() {
|
|
326
|
-
if (this.sendQueue.length === 0 || this.isStopped) {
|
|
327
|
-
this.isSending = false;
|
|
328
|
-
return;
|
|
329
|
-
}
|
|
330
|
-
this.isSending = true;
|
|
331
|
-
const { payload, marker, timestamp } = this.sendQueue.shift();
|
|
332
|
-
try {
|
|
333
|
-
const header = new RtpHeader({
|
|
334
|
-
version: 2,
|
|
335
|
-
padding: false,
|
|
336
|
-
extension: false,
|
|
337
|
-
marker: marker,
|
|
338
|
-
payloadType: this.payloadType,
|
|
339
|
-
sequenceNumber: this.sequenceNumber,
|
|
340
|
-
timestamp: timestamp,
|
|
341
|
-
ssrc: this.videoSsrc,
|
|
342
|
-
});
|
|
343
|
-
const rtpPacket = new RtpPacket(header, payload);
|
|
344
|
-
const encryptedPacket = this.videoSrtpSession.encrypt(rtpPacket.payload, rtpPacket.header);
|
|
345
|
-
await this.videoSplitter.send(encryptedPacket, {
|
|
346
|
-
port: this.targetPort,
|
|
347
|
-
address: this.targetAddress,
|
|
348
|
-
});
|
|
349
|
-
}
|
|
350
|
-
catch (error) {
|
|
351
|
-
this.cameraLogger.trace('Error sending video packet:', error);
|
|
352
|
-
}
|
|
353
|
-
this.sequenceNumber = (this.sequenceNumber + 1) & 0xffff;
|
|
354
|
-
setImmediate(() => this.processQueue());
|
|
355
|
-
}
|
|
356
|
-
isIDRFrame(naluType, marker, nalu) {
|
|
357
|
-
if (naluType === NAL_UNIT_TYPE_IFRAME) {
|
|
358
|
-
// this.cameraLogger.trace('Detected explicit IDR frame in single NAL unit packet');
|
|
359
|
-
return true;
|
|
360
|
-
}
|
|
361
|
-
if (naluType === NAL_UNIT_TYPE_FU_A && nalu.length >= 2) {
|
|
362
|
-
const fuHeader = nalu[1];
|
|
363
|
-
const fuNaluType = fuHeader & NAL_UNIT_TYPE_MASK;
|
|
364
|
-
const startBit = (fuHeader & 0x80) !== 0;
|
|
365
|
-
if (fuNaluType === NAL_UNIT_TYPE_IFRAME && startBit) {
|
|
366
|
-
// this.cameraLogger.trace('Detected IDR frame in FU-A packet');
|
|
367
|
-
return true;
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
// Additional check for slice type
|
|
371
|
-
const additionalCheck = true;
|
|
372
|
-
if (additionalCheck && nalu.length > 5) {
|
|
373
|
-
// Ensure we have enough data to check
|
|
374
|
-
let offset = 1; // Start after NAL unit type
|
|
375
|
-
// Skip NAL unit header extension if present
|
|
376
|
-
if ((nalu[0] & 0x60) !== 0) {
|
|
377
|
-
offset += 3;
|
|
378
|
-
}
|
|
379
|
-
try {
|
|
380
|
-
// Ensure we still have enough data after potential header extension
|
|
381
|
-
if (nalu.length > offset + 1) {
|
|
382
|
-
const firstMbInSlice = this.readExponentialGolombCode(nalu, offset);
|
|
383
|
-
offset += firstMbInSlice.numBits;
|
|
384
|
-
// Read slice type
|
|
385
|
-
const sliceType = this.readExponentialGolombCode(nalu, offset).value & NAL_UNIT_TYPE_MASK;
|
|
386
|
-
if (sliceType === 5 || sliceType === 7) {
|
|
387
|
-
// this.cameraLogger.trace( `Detected potential IDR frame based on slice type: ${sliceType}`);
|
|
388
|
-
return true;
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
catch {
|
|
393
|
-
return false;
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
return false;
|
|
397
|
-
}
|
|
398
|
-
readExponentialGolombCode(buffer, start) {
|
|
399
|
-
let leadingZeroBits = 0;
|
|
400
|
-
let offset = start;
|
|
401
|
-
while (offset < buffer.length * 8) {
|
|
402
|
-
if ((buffer[Math.floor(offset / 8)] & (0x80 >> offset % 8)) !== 0) {
|
|
403
|
-
break;
|
|
404
|
-
}
|
|
405
|
-
leadingZeroBits++;
|
|
406
|
-
offset++;
|
|
407
|
-
}
|
|
408
|
-
offset++;
|
|
409
|
-
let value = 1 << leadingZeroBits;
|
|
410
|
-
for (let i = 0; i < leadingZeroBits; i++) {
|
|
411
|
-
if (offset >= buffer.length * 8) {
|
|
412
|
-
throw new Error('Buffer overflow when reading Exp-Golomb code');
|
|
413
|
-
}
|
|
414
|
-
if ((buffer[Math.floor(offset / 8)] & (0x80 >> offset % 8)) !== 0) {
|
|
415
|
-
value += 1 << (leadingZeroBits - i - 1);
|
|
416
|
-
}
|
|
417
|
-
offset++;
|
|
418
|
-
}
|
|
419
|
-
return { value: value - 1, numBits: 2 * leadingZeroBits + 1 };
|
|
420
|
-
}
|
|
421
|
-
stop() {
|
|
422
|
-
this.isStopped = true;
|
|
423
|
-
this.sendQueue = [];
|
|
424
|
-
this.incompleteFrame = null;
|
|
425
|
-
this.incompleteFrameTimestamp = null;
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
export class FFmpegProcessor {
|
|
429
|
-
cameraAccessory;
|
|
430
|
-
streamSession;
|
|
431
|
-
ffmpegSplitter;
|
|
432
|
-
videoSplitter;
|
|
433
|
-
cameraLogger;
|
|
434
|
-
sendQueue = [];
|
|
435
|
-
isProcessing = false;
|
|
436
|
-
isStopped = false;
|
|
437
|
-
constructor(cameraAccessory, streamSession, ffmpegSplitter, videoSplitter, cameraLogger) {
|
|
438
|
-
this.cameraAccessory = cameraAccessory;
|
|
439
|
-
this.streamSession = streamSession;
|
|
440
|
-
this.ffmpegSplitter = ffmpegSplitter;
|
|
441
|
-
this.videoSplitter = videoSplitter;
|
|
442
|
-
this.cameraLogger = cameraLogger;
|
|
443
|
-
this.streamSession.onCallEnded.subscribe(() => this.stop());
|
|
444
|
-
}
|
|
445
|
-
processPacket(packet) {
|
|
446
|
-
this.sendQueue.push(packet);
|
|
447
|
-
if (!this.isProcessing) {
|
|
448
|
-
this.processQueue();
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
async processQueue() {
|
|
452
|
-
if (this.sendQueue.length === 0 || this.isStopped) {
|
|
453
|
-
this.isProcessing = false;
|
|
454
|
-
return;
|
|
455
|
-
}
|
|
456
|
-
this.isProcessing = true;
|
|
457
|
-
const packet = this.sendQueue.shift();
|
|
458
|
-
try {
|
|
459
|
-
await this.ffmpegSplitter.send(packet, {
|
|
460
|
-
port: this.videoSplitter.port,
|
|
461
|
-
address: this.videoSplitter.address,
|
|
462
|
-
});
|
|
463
|
-
this.cameraLogger.debug(`Sent packet of ${packet.length} bytes to video splitter`);
|
|
464
|
-
}
|
|
465
|
-
catch (error) {
|
|
466
|
-
this.cameraLogger.error('Error sending video packet:', error);
|
|
467
|
-
}
|
|
468
|
-
setImmediate(() => this.processQueue());
|
|
469
|
-
}
|
|
470
|
-
stop() {
|
|
471
|
-
this.isStopped = true;
|
|
472
|
-
this.sendQueue = [];
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
//# sourceMappingURL=processor.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"processor.js","sourceRoot":"","sources":["../../src/utils/processor.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { FfmpegProcess } from '@camera.ui/common';
|
|
2
|
-
import type { FfmpegProcessOptions, RtpSplitter } from '@camera.ui/common';
|
|
3
|
-
interface Source {
|
|
4
|
-
srtp_key: Buffer;
|
|
5
|
-
srtp_salt: Buffer;
|
|
6
|
-
}
|
|
7
|
-
interface PrepareStreamRequest {
|
|
8
|
-
targetAddress: string;
|
|
9
|
-
addressVersion: 'ipv4' | 'ipv6';
|
|
10
|
-
audio: Source;
|
|
11
|
-
}
|
|
12
|
-
interface StartStreamRequest {
|
|
13
|
-
audio: {
|
|
14
|
-
codec: 'OPUS' | 'AAC_eld' | string;
|
|
15
|
-
channel: number;
|
|
16
|
-
sample_rate: number;
|
|
17
|
-
pt: number;
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
export declare class ReturnAudioTranscoder {
|
|
21
|
-
private options;
|
|
22
|
-
readonly returnRtpSplitter: RtpSplitter;
|
|
23
|
-
private startStreamRequest;
|
|
24
|
-
readonly ffmpegProcess: FfmpegProcess;
|
|
25
|
-
readonly reservedPortsPromise: Promise<number[]>;
|
|
26
|
-
constructor(options: {
|
|
27
|
-
outputArgs: (string | number)[];
|
|
28
|
-
prepareStreamRequest: PrepareStreamRequest;
|
|
29
|
-
incomingAudioOptions: {
|
|
30
|
-
ssrc: number;
|
|
31
|
-
rtcpPort: number;
|
|
32
|
-
};
|
|
33
|
-
returnAudioSplitter: RtpSplitter;
|
|
34
|
-
startStreamRequest?: StartStreamRequest;
|
|
35
|
-
} & Omit<FfmpegProcessOptions, 'ffmpegArgs'>);
|
|
36
|
-
start(): Promise<void>;
|
|
37
|
-
stop(): void;
|
|
38
|
-
}
|
|
39
|
-
export {};
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { FfmpegProcess, getSsrc, reservePorts } from '@camera.ui/common';
|
|
2
|
-
import { createCryptoLine } from './srtp.js';
|
|
3
|
-
const defaultStartStreamReqeuest = {
|
|
4
|
-
audio: {
|
|
5
|
-
codec: 'AAC_eld',
|
|
6
|
-
channel: 1,
|
|
7
|
-
sample_rate: 16,
|
|
8
|
-
pt: 110,
|
|
9
|
-
},
|
|
10
|
-
};
|
|
11
|
-
export class ReturnAudioTranscoder {
|
|
12
|
-
options;
|
|
13
|
-
returnRtpSplitter;
|
|
14
|
-
startStreamRequest;
|
|
15
|
-
ffmpegProcess;
|
|
16
|
-
reservedPortsPromise = reservePorts({ count: 2 });
|
|
17
|
-
constructor(options) {
|
|
18
|
-
this.options = options;
|
|
19
|
-
this.startStreamRequest = this.options.startStreamRequest || defaultStartStreamReqeuest;
|
|
20
|
-
this.ffmpegProcess = new FfmpegProcess({
|
|
21
|
-
ffmpegArgs: [
|
|
22
|
-
'-hide_banner',
|
|
23
|
-
'-protocol_whitelist',
|
|
24
|
-
'pipe,udp,rtp,file,crypto',
|
|
25
|
-
'-f',
|
|
26
|
-
'sdp',
|
|
27
|
-
'-acodec',
|
|
28
|
-
this.startStreamRequest.audio.codec === 'OPUS' ? 'libopus' : 'libfdk_aac',
|
|
29
|
-
'-i',
|
|
30
|
-
'pipe:',
|
|
31
|
-
'-map',
|
|
32
|
-
'0:0',
|
|
33
|
-
...this.options.outputArgs,
|
|
34
|
-
],
|
|
35
|
-
...this.options,
|
|
36
|
-
});
|
|
37
|
-
// allow return audio splitter to be passed in if you want to create one in the prepare stream phase, and create the transcoder in the stream request phase
|
|
38
|
-
this.returnRtpSplitter = options.returnAudioSplitter;
|
|
39
|
-
}
|
|
40
|
-
async start() {
|
|
41
|
-
const [rtpPort, rtcpPort] = await this.reservedPortsPromise, { targetAddress, addressVersion, audio: { srtp_key: srtpKey, srtp_salt: srtpSalt }, } = this.options.prepareStreamRequest, { ssrc: incomingAudioSsrc, rtcpPort: incomingAudioRtcpPort } = this.options.incomingAudioOptions, { codec, sample_rate, channel, pt: packetType } = this.startStreamRequest.audio;
|
|
42
|
-
this.ffmpegProcess.writeStdin(
|
|
43
|
-
// This SDP was generated using ffmpeg, and describes the type of packets we expect to receive from HomeKit.
|
|
44
|
-
[
|
|
45
|
-
'v=0',
|
|
46
|
-
'o=- 0 0 IN IP4 127.0.0.1',
|
|
47
|
-
's=Talk',
|
|
48
|
-
`c=IN ${addressVersion.replace('v', '').toUpperCase()} ${targetAddress}`,
|
|
49
|
-
't=0 0',
|
|
50
|
-
'a=tool:libavformat 58.38.100',
|
|
51
|
-
`m=audio ${rtpPort} RTP/AVP ${packetType}`,
|
|
52
|
-
'b=AS:24',
|
|
53
|
-
...(codec === 'OPUS'
|
|
54
|
-
? [`a=rtpmap:${packetType} opus/${sample_rate}000/${channel}`, `a=fmtp:${packetType} minptime=10;useinbandfec=1`]
|
|
55
|
-
: [
|
|
56
|
-
`a=rtpmap:${packetType} MPEG4-GENERIC/${sample_rate}000/${channel}`,
|
|
57
|
-
`a=fmtp:${packetType} profile-level-id=1;mode=AAC-hbr;sizelength=13;indexlength=3;indexdeltalength=3; config=F8F0212C00BC00`,
|
|
58
|
-
]),
|
|
59
|
-
createCryptoLine({
|
|
60
|
-
srtpKey,
|
|
61
|
-
srtpSalt,
|
|
62
|
-
}),
|
|
63
|
-
].join('\n'));
|
|
64
|
-
this.returnRtpSplitter.addMessageHandler(({ isRtpMessage, message }) => {
|
|
65
|
-
// This splitter will receive all audio-related packets from HomeKit.
|
|
66
|
-
// This includes RTP + RTCP for return audio, as well as RTCP for incoming audio
|
|
67
|
-
if (!isRtpMessage && getSsrc(message) === incomingAudioSsrc) {
|
|
68
|
-
return {
|
|
69
|
-
port: incomingAudioRtcpPort,
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
return {
|
|
73
|
-
port: isRtpMessage ? rtpPort : rtcpPort,
|
|
74
|
-
};
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
stop() {
|
|
78
|
-
this.ffmpegProcess.stop();
|
|
79
|
-
this.returnRtpSplitter.close();
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
//# sourceMappingURL=return-audio-transcoder.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"return-audio-transcoder.js","sourceRoot":"","sources":["../../src/utils/return-audio-transcoder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAwB7C,MAAM,0BAA0B,GAAuB;IACrD,KAAK,EAAE;QACL,KAAK,EAAE,SAAS;QAChB,OAAO,EAAE,CAAC;QACV,WAAW,EAAE,EAAE;QACf,EAAE,EAAE,GAAG;KACR;CACF,CAAC;AAEF,MAAM,OAAO,qBAAqB;IAOtB;IANM,iBAAiB,CAAC;IAC1B,kBAAkB,CAAqB;IAC/B,aAAa,CAAgB;IAC7B,oBAAoB,GAAG,YAAY,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;IAElE,YACU,OASoC;QATpC,YAAO,GAAP,OAAO,CAS6B;QAE5C,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,OAAO,CAAC,kBAAkB,IAAI,0BAA0B,CAAC;QAExF,IAAI,CAAC,aAAa,GAAG,IAAI,aAAa,CAAC;YACrC,UAAU,EAAE;gBACV,cAAc;gBACd,qBAAqB;gBACrB,0BAA0B;gBAC1B,IAAI;gBACJ,KAAK;gBACL,SAAS;gBACT,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,YAAY;gBACzE,IAAI;gBACJ,OAAO;gBACP,MAAM;gBACN,KAAK;gBACL,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU;aAC3B;YACD,GAAG,IAAI,CAAC,OAAO;SAChB,CAAC,CAAC;QAEH,2JAA2J;QAC3J,IAAI,CAAC,iBAAiB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IACvD,CAAC;IAEM,KAAK,CAAC,KAAK;QAChB,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,GAAG,MAAM,IAAI,CAAC,oBAAoB,EACzD,EACE,aAAa,EACb,cAAc,EACd,KAAK,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,GAClD,GAAG,IAAI,CAAC,OAAO,CAAC,oBAAoB,EACrC,EAAE,IAAI,EAAE,iBAAiB,EAAE,QAAQ,EAAE,qBAAqB,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,oBAAoB,EAChG,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC;QAElF,IAAI,CAAC,aAAa,CAAC,UAAU;QAC3B,4GAA4G;QAC5G;YACE,KAAK;YACL,0BAA0B;YAC1B,QAAQ;YACR,QAAQ,cAAc,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,IAAI,aAAa,EAAE;YACxE,OAAO;YACP,8BAA8B;YAC9B,WAAW,OAAO,YAAY,UAAU,EAAE;YAC1C,SAAS;YACT,GAAG,CAAC,KAAK,KAAK,MAAM;gBAClB,CAAC,CAAC,CAAC,YAAY,UAAU,SAAS,WAAW,OAAO,OAAO,EAAE,EAAE,UAAU,UAAU,6BAA6B,CAAC;gBACjH,CAAC,CAAC;oBACE,YAAY,UAAU,kBAAkB,WAAW,OAAO,OAAO,EAAE;oBACnE,UAAU,UAAU,wGAAwG;iBAC7H,CAAC;YACN,gBAAgB,CAAC;gBACf,OAAO;gBACP,QAAQ;aACT,CAAC;SACH,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;QAEF,IAAI,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,CAAC,EAAE,YAAY,EAAE,OAAO,EAAE,EAAE,EAAE;YACrE,qEAAqE;YACrE,gFAAgF;YAChF,IAAI,CAAC,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC,KAAK,iBAAiB,EAAE,CAAC;gBAC5D,OAAO;oBACL,IAAI,EAAE,qBAAqB;iBAC5B,CAAC;YACJ,CAAC;YAED,OAAO;gBACL,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ;aACxC,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,IAAI;QACT,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;QAC1B,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,CAAC;IACjC,CAAC;CACF"}
|
package/dist/utils/srtp.d.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export interface SrtpOptions {
|
|
2
|
-
srtpKey: Buffer;
|
|
3
|
-
srtpSalt: Buffer;
|
|
4
|
-
}
|
|
5
|
-
export declare function encodeSrtpOptions({ srtpKey, srtpSalt }: SrtpOptions): string;
|
|
6
|
-
export declare function decodeSrtpOptions(encodedOptions: string): SrtpOptions;
|
|
7
|
-
export declare function createCryptoLine(srtpOptions: SrtpOptions): string;
|
|
8
|
-
export declare function generateSrtpOptions(): SrtpOptions;
|
package/dist/utils/srtp.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { randomBytes } from 'node:crypto';
|
|
2
|
-
export function encodeSrtpOptions({ srtpKey, srtpSalt }) {
|
|
3
|
-
return Buffer.concat([srtpKey, srtpSalt]).toString('base64');
|
|
4
|
-
}
|
|
5
|
-
export function decodeSrtpOptions(encodedOptions) {
|
|
6
|
-
const crypto = Buffer.from(encodedOptions, 'base64');
|
|
7
|
-
return {
|
|
8
|
-
srtpKey: crypto.subarray(0, 16),
|
|
9
|
-
srtpSalt: crypto.subarray(16, 30),
|
|
10
|
-
};
|
|
11
|
-
}
|
|
12
|
-
export function createCryptoLine(srtpOptions) {
|
|
13
|
-
const encodedOptions = encodeSrtpOptions(srtpOptions);
|
|
14
|
-
return `a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:${encodedOptions}`;
|
|
15
|
-
}
|
|
16
|
-
export function generateSrtpOptions() {
|
|
17
|
-
return {
|
|
18
|
-
srtpKey: randomBytes(16),
|
|
19
|
-
srtpSalt: randomBytes(14),
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
//# sourceMappingURL=srtp.js.map
|
package/dist/utils/srtp.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"srtp.js","sourceRoot":"","sources":["../../src/utils/srtp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAO1C,MAAM,UAAU,iBAAiB,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAe;IAClE,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,cAAsB;IACtD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;IAErD,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC;QAC/B,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC;KAClC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,WAAwB;IACvD,MAAM,cAAc,GAAG,iBAAiB,CAAC,WAAW,CAAC,CAAC;IAEtD,OAAO,6CAA6C,cAAc,EAAE,CAAC;AACvE,CAAC;AAED,MAAM,UAAU,mBAAmB;IACjC,OAAO;QACL,OAAO,EAAE,WAAW,CAAC,EAAE,CAAC;QACxB,QAAQ,EAAE,WAAW,CAAC,EAAE,CAAC;KAC1B,CAAC;AACJ,CAAC"}
|