@relaymessenger/livekit 0.1.0-staging.3 → 0.1.0-staging.31

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.
@@ -1,309 +0,0 @@
1
- /**
2
- * Relay's default call participant engine: werift (pure-TypeScript WebRTC:
3
- * ICE, DTLS, SRTP, RTP) plus `@evan/opus` (prebuilt libopus, WASM fallback).
4
- *
5
- * API sources read for this file, in node_modules/werift/lib/webrtc/src:
6
- * - peerConnection.d.ts: `new RTCPeerConnection({ codecs: { audio: [...] } })`,
7
- * `addTransceiver(track, { direction })`, the W3C-style `ontrack`,
8
- * `onconnectionstatechange`, `localDescription`, `close()`, and the
9
- * `"icegatheringstatechange"` / `"connectionstatechange"` events emitted
10
- * through `EventTarget.addEventListener` (peerConnection.js:317, :330).
11
- * `RTCConfiguration.iceServers: RTCIceServer[]` ({ urls, username?,
12
- * credential? }) and `iceTransportPolicy: "all" | "relay"` (peerConnection.d.ts
13
- * :264-273); utils.js:110-179 parses `stun|stuns|turn|turns:` URLs with
14
- * `?transport=`, and `secureTransportManager.js:121` maps `"relay"` to
15
- * `forceTurn`. The W3C setters `onicecandidate`, `onicegatheringstatechange`
16
- * and `oniceconnectionstatechange` (peerConnection.d.ts:67-82, fired at
17
- * peerConnection.js:314-341) feed the transport's ICE diagnostics.
18
- * - media/track.d.ts: `MediaStreamTrack({ kind })`, `writeRtp(RtpPacket)`,
19
- * `onReceiveRtp: Event<[RtpPacket, Extensions?]>` with `subscribe()`.
20
- * - media/rtpSender.js:544-549: the sender rewrites ssrc and payloadType and
21
- * offsets sequenceNumber/timestamp, so the local track starts both at 0.
22
- * - ../../rtp/src/codec/opus.d.ts: `OpusRtpPayload.deSerialize(buffer)`.
23
- * - node_modules/@evan/opus/lib.d.ts: `Encoder.encode(pcm16)` returns one Opus
24
- * packet; `Decoder.decode(packet)` returns interleaved PCM16 bytes.
25
- * Participant shapes copied from the headless phone that joined Relay's room
26
- * through Cloudflare's SFU on 2026-09-21 (_runtime/bin/headless-phone-webrtc.mjs
27
- * lines 93-160): `bundlePolicy: "max-bundle", iceServers: []` (Cloudflare
28
- * supplies its ICE candidates in the answer), the local track is id
29
- * "microphone" in stream "relay-call" (Relay-iOS RelayWebRTCAudioTransport),
30
- * the first RTP packet carries the marker bit, empty payloads are skipped and a
31
- * decode failure never tears the sink down.
32
- */
33
- import { Decoder, Encoder } from "@evan/opus";
34
- import { MediaStreamTrack, OpusRtpPayload, RTCPeerConnection, RTCRtpCodecParameters, RtpHeader, RtpPacket, } from "werift";
35
- /** Opus on the wire is always 48 kHz; Relay sends stereo so callers may pass either channel count. */
36
- export const WERIFT_SAMPLE_RATE = 48_000;
37
- export const WERIFT_CHANNEL_COUNT = 2;
38
- /** One RTP packet carries 20 ms: 960 frames at 48 kHz, timestamp advances by 960. */
39
- export const WERIFT_PACKET_MS = 20;
40
- const PACKET_FRAMES = (WERIFT_SAMPLE_RATE * WERIFT_PACKET_MS) / 1000;
41
- const PACKET_SAMPLES = PACKET_FRAMES * WERIFT_CHANNEL_COUNT;
42
- /** Dynamic payload type; werift's sender replaces it with the negotiated one. */
43
- const LOCAL_PAYLOAD_TYPE = 111;
44
- /** Packets counted for `diagnostics()`; the recent window is the last 5 s. */
45
- export const STATS_WINDOW_MS = 5_000;
46
- /** Monotone packet counter with first/last epoch timestamps and a 5 s window. */
47
- class PacketClock {
48
- count = 0;
49
- firstAt;
50
- lastAt;
51
- #recent = [];
52
- mark(now = Date.now()) {
53
- this.count += 1;
54
- this.firstAt ??= now;
55
- this.lastAt = now;
56
- this.#recent.push(now);
57
- this.#prune(now);
58
- }
59
- recent(now = Date.now()) {
60
- this.#prune(now);
61
- return this.#recent.length;
62
- }
63
- #prune(now) {
64
- const floor = now - STATS_WINDOW_MS;
65
- let drop = 0;
66
- while (drop < this.#recent.length && this.#recent[drop] < floor)
67
- drop += 1;
68
- if (drop)
69
- this.#recent.splice(0, drop);
70
- }
71
- }
72
- /** Convert any PCM16 frame to interleaved 48 kHz stereo by linear interpolation. */
73
- export const toWireFormat = (data) => {
74
- const { samples, sampleRate, channelCount } = data;
75
- const inputFrames = Math.floor(samples.length / channelCount);
76
- if (sampleRate === WERIFT_SAMPLE_RATE && channelCount === WERIFT_CHANNEL_COUNT) {
77
- return samples;
78
- }
79
- const outputFrames = Math.round((inputFrames * WERIFT_SAMPLE_RATE) / sampleRate);
80
- const out = new Int16Array(outputFrames * WERIFT_CHANNEL_COUNT);
81
- const ratio = sampleRate / WERIFT_SAMPLE_RATE;
82
- const leftIndex = 0;
83
- const rightIndex = channelCount > 1 ? 1 : 0;
84
- for (let frame = 0; frame < outputFrames; frame += 1) {
85
- const position = frame * ratio;
86
- const base = Math.min(Math.floor(position), inputFrames - 1);
87
- const next = Math.min(base + 1, inputFrames - 1);
88
- const fraction = position - Math.floor(position);
89
- const left = samples[base * channelCount + leftIndex] * (1 - fraction)
90
- + samples[next * channelCount + leftIndex] * fraction;
91
- const right = samples[base * channelCount + rightIndex] * (1 - fraction)
92
- + samples[next * channelCount + rightIndex] * fraction;
93
- out[frame * 2] = Math.round(left);
94
- out[frame * 2 + 1] = Math.round(right);
95
- }
96
- return out;
97
- };
98
- /**
99
- * PCM16 in, paced 20 ms Opus RTP out. Frames are accumulated into whole
100
- * packets; a timer drains one packet every 20 ms so the wire sees a steady
101
- * cadence regardless of how the adapter chunks its writes. Adapters may push
102
- * far ahead of real time: `queuedMs()` is what has not left yet and
103
- * `waitForDrain()` resolves once the queue is empty and the pump has stopped
104
- * (LiveKit's `AudioSource.queuedDuration` / `waitForPlayout` shape).
105
- */
106
- class WeriftAudioSource {
107
- #encoder = new Encoder({
108
- channels: WERIFT_CHANNEL_COUNT,
109
- sample_rate: WERIFT_SAMPLE_RATE,
110
- application: "voip",
111
- });
112
- #track = new MediaStreamTrack({ kind: "audio", id: "microphone", streamId: "relay-call" });
113
- #packets = [];
114
- #rtp = new PacketClock();
115
- #opusPackets = 0;
116
- #pending = new Int16Array(0);
117
- #sequenceNumber = 1;
118
- #timestamp = 0;
119
- #first = true;
120
- #pump;
121
- #stopped = false;
122
- #drainWaiters = new Set();
123
- stats() {
124
- return {
125
- opusPackets: this.#opusPackets,
126
- rtpPackets: this.#rtp.count,
127
- firstRtpAt: this.#rtp.firstAt,
128
- lastRtpAt: this.#rtp.lastAt,
129
- recentRtpPackets: this.#rtp.recent(),
130
- queued: this.#packets.length,
131
- pacerAlive: this.#pump !== undefined,
132
- };
133
- }
134
- createTrack() {
135
- const track = this.#track;
136
- const stop = track.stop;
137
- track.stop = () => {
138
- this.#stopped = true;
139
- this.clear();
140
- stop();
141
- };
142
- return track;
143
- }
144
- queuedMs() {
145
- return this.#packets.length * WERIFT_PACKET_MS
146
- + (this.#pending.length / WERIFT_CHANNEL_COUNT / WERIFT_SAMPLE_RATE) * 1_000;
147
- }
148
- waitForDrain() {
149
- this.#flushPending();
150
- if (this.#drained())
151
- return Promise.resolve();
152
- return new Promise((resolve) => this.#drainWaiters.add(resolve));
153
- }
154
- clear() {
155
- this.#packets.length = 0;
156
- this.#pending = new Int16Array(0);
157
- this.#stopPump();
158
- this.#notifyDrained();
159
- }
160
- onData(data) {
161
- if (this.#stopped)
162
- return;
163
- const wire = toWireFormat(data);
164
- const merged = new Int16Array(this.#pending.length + wire.length);
165
- merged.set(this.#pending);
166
- merged.set(wire, this.#pending.length);
167
- let offset = 0;
168
- while (merged.length - offset >= PACKET_SAMPLES) {
169
- const frame = merged.subarray(offset, offset + PACKET_SAMPLES);
170
- this.#packets.push(Buffer.from(this.#encoder.encode(frame)));
171
- this.#opusPackets += 1;
172
- offset += PACKET_SAMPLES;
173
- }
174
- this.#pending = merged.slice(offset);
175
- this.#startPump();
176
- }
177
- /** Pad a sub-packet remainder with silence so the tail of a segment reaches the wire. */
178
- #flushPending() {
179
- if (this.#stopped || this.#pending.length === 0)
180
- return;
181
- const padded = new Int16Array(PACKET_SAMPLES);
182
- padded.set(this.#pending);
183
- this.#pending = new Int16Array(0);
184
- this.#packets.push(Buffer.from(this.#encoder.encode(padded)));
185
- this.#opusPackets += 1;
186
- this.#startPump();
187
- }
188
- #drained() {
189
- return this.#packets.length === 0 && this.#pending.length === 0 && this.#pump === undefined;
190
- }
191
- #notifyDrained() {
192
- if (!this.#drained())
193
- return;
194
- for (const resolve of [...this.#drainWaiters]) {
195
- this.#drainWaiters.delete(resolve);
196
- resolve();
197
- }
198
- }
199
- /**
200
- * The first packet of a run leaves at once; every later one waits for the
201
- * 20 ms tick, so a burst pushed faster than real time reaches the wire at
202
- * packet cadence. The interval stops one tick after the queue empties, which
203
- * is when the last packet has played.
204
- */
205
- #startPump() {
206
- if (this.#pump || this.#packets.length === 0)
207
- return;
208
- this.#sendNext();
209
- this.#pump = setInterval(() => {
210
- this.#sendNext();
211
- if (this.#packets.length === 0) {
212
- this.#stopPump();
213
- this.#notifyDrained();
214
- }
215
- }, WERIFT_PACKET_MS);
216
- this.#pump.unref?.();
217
- }
218
- #stopPump() {
219
- if (!this.#pump)
220
- return;
221
- clearInterval(this.#pump);
222
- this.#pump = undefined;
223
- }
224
- #sendNext() {
225
- const payload = this.#packets.shift();
226
- if (!payload || this.#stopped)
227
- return;
228
- const header = new RtpHeader({
229
- payloadType: LOCAL_PAYLOAD_TYPE,
230
- sequenceNumber: this.#sequenceNumber,
231
- timestamp: this.#timestamp,
232
- ssrc: 0,
233
- marker: this.#first,
234
- });
235
- this.#first = false;
236
- this.#sequenceNumber = (this.#sequenceNumber + 1) & 0xffff;
237
- this.#timestamp = (this.#timestamp + PACKET_FRAMES) >>> 0;
238
- this.#track.writeRtp(new RtpPacket(header, payload));
239
- this.#rtp.mark();
240
- }
241
- }
242
- /** Opus RTP in, PCM16 (48 kHz stereo) out, one `ondata` per packet. */
243
- class WeriftAudioSink {
244
- ondata = null;
245
- #decoder = new Decoder({ channels: WERIFT_CHANNEL_COUNT, sample_rate: WERIFT_SAMPLE_RATE });
246
- #rtp = new PacketClock();
247
- #decodeFailures = 0;
248
- #unsubscribe;
249
- stats() {
250
- return {
251
- rtpPackets: this.#rtp.count,
252
- decodeFailures: this.#decodeFailures,
253
- firstRtpAt: this.#rtp.firstAt,
254
- lastRtpAt: this.#rtp.lastAt,
255
- recentRtpPackets: this.#rtp.recent(),
256
- };
257
- }
258
- constructor(track) {
259
- const { unSubscribe } = track.onReceiveRtp.subscribe((rtp) => {
260
- this.#rtp.mark();
261
- const handler = this.ondata;
262
- if (!handler || !rtp.payload?.length)
263
- return;
264
- const packet = OpusRtpPayload.deSerialize(rtp.payload);
265
- let bytes;
266
- try {
267
- bytes = this.#decoder.decode(packet.payload);
268
- }
269
- catch {
270
- this.#decodeFailures += 1;
271
- return;
272
- }
273
- const samples = new Int16Array(bytes.byteLength >> 1);
274
- new Uint8Array(samples.buffer).set(bytes.subarray(0, samples.byteLength));
275
- handler({
276
- samples,
277
- sampleRate: WERIFT_SAMPLE_RATE,
278
- bitsPerSample: 16,
279
- channelCount: WERIFT_CHANNEL_COUNT,
280
- numberOfFrames: samples.length / WERIFT_CHANNEL_COUNT,
281
- });
282
- });
283
- this.#unsubscribe = unSubscribe;
284
- }
285
- stop() {
286
- this.ondata = null;
287
- this.#unsubscribe();
288
- }
289
- }
290
- export const createWeriftPeerConnection = (config = { iceServers: [], iceTransportPolicy: "all" }) => new RTCPeerConnection({
291
- bundlePolicy: "max-bundle",
292
- iceServers: config.iceServers,
293
- iceTransportPolicy: config.iceTransportPolicy,
294
- codecs: {
295
- audio: [
296
- new RTCRtpCodecParameters({
297
- mimeType: "audio/opus",
298
- clockRate: WERIFT_SAMPLE_RATE,
299
- channels: WERIFT_CHANNEL_COUNT,
300
- }),
301
- ],
302
- },
303
- });
304
- export const createWeriftWebRTCFactory = () => ({
305
- createPeerConnection: (config) => createWeriftPeerConnection(config),
306
- createAudioSource: () => new WeriftAudioSource(),
307
- createAudioSink: (track) => new WeriftAudioSink(track),
308
- });
309
- //# sourceMappingURL=engine-werift.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"engine-werift.js","sourceRoot":"","sources":["../src/engine-werift.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,qBAAqB,EACrB,SAAS,EACT,SAAS,GACV,MAAM,QAAQ,CAAC;AAYhB,sGAAsG;AACtG,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC;AACzC,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC;AACtC,qFAAqF;AACrF,MAAM,CAAC,MAAM,gBAAgB,GAAG,EAAE,CAAC;AACnC,MAAM,aAAa,GAAG,CAAC,kBAAkB,GAAG,gBAAgB,CAAC,GAAG,IAAI,CAAC;AACrE,MAAM,cAAc,GAAG,aAAa,GAAG,oBAAoB,CAAC;AAC5D,iFAAiF;AACjF,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAI/B,8EAA8E;AAC9E,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,CAAC;AAErC,iFAAiF;AACjF,MAAM,WAAW;IACf,KAAK,GAAG,CAAC,CAAC;IACV,OAAO,CAAqB;IAC5B,MAAM,CAAqB;IAClB,OAAO,GAAa,EAAE,CAAC;IAEhC,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;QACnB,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC;QAChB,IAAI,CAAC,OAAO,KAAK,GAAG,CAAC;QACrB,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC;QAClB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACvB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC;IAED,MAAM,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;QACrB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjB,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;IAC7B,CAAC;IAED,MAAM,CAAC,GAAW;QAChB,MAAM,KAAK,GAAG,GAAG,GAAG,eAAe,CAAC;QACpC,IAAI,IAAI,GAAG,CAAC,CAAC;QACb,OAAO,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAE,GAAG,KAAK;YAAE,IAAI,IAAI,CAAC,CAAC;QAC5E,IAAI,IAAI;YAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IACzC,CAAC;CACF;AAED,oFAAoF;AACpF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,IAI5B,EAAc,EAAE;IACf,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC;IACnD,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,YAAY,CAAC,CAAC;IAC9D,IAAI,UAAU,KAAK,kBAAkB,IAAI,YAAY,KAAK,oBAAoB,EAAE,CAAC;QAC/E,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW,GAAG,kBAAkB,CAAC,GAAG,UAAU,CAAC,CAAC;IACjF,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,YAAY,GAAG,oBAAoB,CAAC,CAAC;IAChE,MAAM,KAAK,GAAG,UAAU,GAAG,kBAAkB,CAAC;IAC9C,MAAM,SAAS,GAAG,CAAC,CAAC;IACpB,MAAM,UAAU,GAAG,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5C,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,YAAY,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACrD,MAAM,QAAQ,GAAG,KAAK,GAAG,KAAK,CAAC;QAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,WAAW,GAAG,CAAC,CAAC,CAAC;QAC7D,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,EAAE,WAAW,GAAG,CAAC,CAAC,CAAC;QACjD,MAAM,QAAQ,GAAG,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACjD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,GAAG,YAAY,GAAG,SAAS,CAAE,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC;cACnE,OAAO,CAAC,IAAI,GAAG,YAAY,GAAG,SAAS,CAAE,GAAG,QAAQ,CAAC;QACzD,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,GAAG,YAAY,GAAG,UAAU,CAAE,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC;cACrE,OAAO,CAAC,IAAI,GAAG,YAAY,GAAG,UAAU,CAAE,GAAG,QAAQ,CAAC;QAC1D,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAClC,GAAG,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACzC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,iBAAiB;IACZ,QAAQ,GAAG,IAAI,OAAO,CAAC;QAC9B,QAAQ,EAAE,oBAAoB;QAC9B,WAAW,EAAE,kBAAkB;QAC/B,WAAW,EAAE,MAAM;KACpB,CAAC,CAAC;IACM,MAAM,GAAG,IAAI,gBAAgB,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC,CAAC;IAC3F,QAAQ,GAAa,EAAE,CAAC;IACxB,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC;IAClC,YAAY,GAAG,CAAC,CAAC;IACjB,QAAQ,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;IAC7B,eAAe,GAAG,CAAC,CAAC;IACpB,UAAU,GAAG,CAAC,CAAC;IACf,MAAM,GAAG,IAAI,CAAC;IACd,KAAK,CAA6B;IAClC,QAAQ,GAAG,KAAK,CAAC;IACR,aAAa,GAAG,IAAI,GAAG,EAAc,CAAC;IAE/C,KAAK;QACH,OAAO;YACL,WAAW,EAAE,IAAI,CAAC,YAAY;YAC9B,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK;YAC3B,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO;YAC7B,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM;YAC3B,gBAAgB,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YACpC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM;YAC5B,UAAU,EAAE,IAAI,CAAC,KAAK,KAAK,SAAS;SACrC,CAAC;IACJ,CAAC;IAED,WAAW;QACT,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC;QAC1B,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;QACxB,KAAK,CAAC,IAAI,GAAG,GAAG,EAAE;YAChB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;YACrB,IAAI,CAAC,KAAK,EAAE,CAAC;YACb,IAAI,EAAE,CAAC;QACT,CAAC,CAAC;QACF,OAAO,KAAK,CAAC;IACf,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,gBAAgB;cAC1C,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,oBAAoB,GAAG,kBAAkB,CAAC,GAAG,KAAK,CAAC;IACjF,CAAC;IAED,YAAY;QACV,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,IAAI,IAAI,CAAC,QAAQ,EAAE;YAAE,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;QAC9C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;IACnE,CAAC;IAED,KAAK;QACH,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;QACzB,IAAI,CAAC,QAAQ,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;QAClC,IAAI,CAAC,SAAS,EAAE,CAAC;QACjB,IAAI,CAAC,cAAc,EAAE,CAAC;IACxB,CAAC;IAED,MAAM,CAAC,IAA2B;QAChC,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO;QAC1B,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;QAClE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC1B,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,OAAO,MAAM,CAAC,MAAM,GAAG,MAAM,IAAI,cAAc,EAAE,CAAC;YAChD,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CAAC,CAAC;YAC/D,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAC7D,IAAI,CAAC,YAAY,IAAI,CAAC,CAAC;YACvB,MAAM,IAAI,cAAc,CAAC;QAC3B,CAAC;QACD,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACrC,IAAI,CAAC,UAAU,EAAE,CAAC;IACpB,CAAC;IAED,yFAAyF;IACzF,aAAa;QACX,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QACxD,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,cAAc,CAAC,CAAC;QAC9C,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC1B,IAAI,CAAC,QAAQ,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;QAClC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC9D,IAAI,CAAC,YAAY,IAAI,CAAC,CAAC;QACvB,IAAI,CAAC,UAAU,EAAE,CAAC;IACpB,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC;IAC9F,CAAC;IAED,cAAc;QACZ,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;YAAE,OAAO;QAC7B,KAAK,MAAM,OAAO,IAAI,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC;YAC9C,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACnC,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,UAAU;QACR,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QACrD,IAAI,CAAC,SAAS,EAAE,CAAC;QACjB,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE;YAC5B,IAAI,CAAC,SAAS,EAAE,CAAC;YACjB,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC/B,IAAI,CAAC,SAAS,EAAE,CAAC;gBACjB,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,CAAC;QACH,CAAC,EAAE,gBAAgB,CAAC,CAAC;QACrB,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;IACvB,CAAC;IAED,SAAS;QACP,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,OAAO;QACxB,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1B,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;IACzB,CAAC;IAED,SAAS;QACP,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QACtC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO;QACtC,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;YAC3B,WAAW,EAAE,kBAAkB;YAC/B,cAAc,EAAE,IAAI,CAAC,eAAe;YACpC,SAAS,EAAE,IAAI,CAAC,UAAU;YAC1B,IAAI,EAAE,CAAC;YACP,MAAM,EAAE,IAAI,CAAC,MAAM;SACpB,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC,eAAe,GAAG,CAAC,IAAI,CAAC,eAAe,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC;QAC3D,IAAI,CAAC,UAAU,GAAG,CAAC,IAAI,CAAC,UAAU,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;QAC1D,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;QACrD,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IACnB,CAAC;CACF;AAED,uEAAuE;AACvE,MAAM,eAAe;IACnB,MAAM,GAAiC,IAAI,CAAC;IACnC,QAAQ,GAAG,IAAI,OAAO,CAAC,EAAE,QAAQ,EAAE,oBAAoB,EAAE,WAAW,EAAE,kBAAkB,EAAE,CAAC,CAAC;IAC5F,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC;IAClC,eAAe,GAAG,CAAC,CAAC;IACX,YAAY,CAAa;IAElC,KAAK;QACH,OAAO;YACL,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK;YAC3B,cAAc,EAAE,IAAI,CAAC,eAAe;YACpC,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO;YAC7B,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM;YAC3B,gBAAgB,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;SACrC,CAAC;IACJ,CAAC;IAED,YAAY,KAAuB;QACjC,MAAM,EAAE,WAAW,EAAE,GAAG,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE;YAC3D,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACjB,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC;YAC5B,IAAI,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM;gBAAE,OAAO;YAC7C,MAAM,MAAM,GAAG,cAAc,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACvD,IAAI,KAAiB,CAAC;YACtB,IAAI,CAAC;gBACH,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAC/C,CAAC;YAAC,MAAM,CAAC;gBACP,IAAI,CAAC,eAAe,IAAI,CAAC,CAAC;gBAC1B,OAAO;YACT,CAAC;YACD,MAAM,OAAO,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,UAAU,IAAI,CAAC,CAAC,CAAC;YACtD,IAAI,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;YAC1E,OAAO,CAAC;gBACN,OAAO;gBACP,UAAU,EAAE,kBAAkB;gBAC9B,aAAa,EAAE,EAAE;gBACjB,YAAY,EAAE,oBAAoB;gBAClC,cAAc,EAAE,OAAO,CAAC,MAAM,GAAG,oBAAoB;aACtD,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,YAAY,GAAG,WAAW,CAAC;IAClC,CAAC;IAED,IAAI;QACF,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,IAAI,CAAC,YAAY,EAAE,CAAC;IACtB,CAAC;CACF;AAED,MAAM,CAAC,MAAM,0BAA0B,GAAG,CACxC,SAAoC,EAAE,UAAU,EAAE,EAAE,EAAE,kBAAkB,EAAE,KAAK,EAAE,EAC9D,EAAE,CACrB,IAAI,iBAAiB,CAAC;IACpB,YAAY,EAAE,YAAY;IAC1B,UAAU,EAAE,MAAM,CAAC,UAAU;IAC7B,kBAAkB,EAAE,MAAM,CAAC,kBAAkB;IAC7C,MAAM,EAAE;QACN,KAAK,EAAE;YACL,IAAI,qBAAqB,CAAC;gBACxB,QAAQ,EAAE,YAAY;gBACtB,SAAS,EAAE,kBAAkB;gBAC7B,QAAQ,EAAE,oBAAoB;aAC/B,CAAC;SACH;KACF;CACF,CAAC,CAAC;AAEL,MAAM,CAAC,MAAM,yBAAyB,GAAG,GAAuB,EAAE,CAAC,CAAC;IAClE,oBAAoB,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,0BAA0B,CAAC,MAAM,CAAuC;IAC1G,iBAAiB,EAAE,GAAG,EAAE,CAAC,IAAI,iBAAiB,EAAE;IAChD,eAAe,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,eAAe,CAAC,KAAoC,CAAC;CACtF,CAAC,CAAC"}
@@ -1,170 +0,0 @@
1
- import type { CallRoomEndedFrame, CallRoomOptions, CallRoomStateFrame, Relay } from "@relaymessenger/sdk";
2
- export interface RelayAudioFrame {
3
- /** Interleaved signed PCM16 samples. */
4
- samples: Int16Array;
5
- sampleRate: number;
6
- channelCount: number;
7
- }
8
- /** Standard `RTCIceServer` shape: STUN or TURN URLs with optional credentials. */
9
- export interface RelayIceServer {
10
- urls: string | string[];
11
- username?: string;
12
- credential?: string;
13
- }
14
- export type RelayIceTransportPolicy = "all" | "relay";
15
- export type RelayCallEngine = "werift" | "wrtc";
16
- export interface RelayCallTransportOptions {
17
- relay: Relay;
18
- callId: string;
19
- room?: CallRoomOptions;
20
- /**
21
- * WebRTC engine. `"werift"` (default) is pure TypeScript plus prebuilt Opus
22
- * and loads no native binding. `"wrtc"` loads `@roamhq/wrtc` on demand.
23
- */
24
- engine?: RelayCallEngine;
25
- /**
26
- * STUN and TURN servers handed to the engine's `RTCPeerConnection`. Defaults
27
- * to none: Cloudflare's SFU answers with its own host candidates. Set TURN
28
- * servers when the agent runs behind a NAT or firewall that blocks UDP.
29
- */
30
- iceServers?: RelayIceServer[];
31
- /** `"relay"` forces every candidate through TURN. Defaults to `"all"`. */
32
- iceTransportPolicy?: RelayIceTransportPolicy;
33
- /** Maximum wait for the WebRTC peer to become connected. Defaults to 15 seconds. */
34
- mediaConnectTimeoutMs?: number;
35
- /** @deprecated Use `mediaConnectTimeoutMs`. */
36
- connectionTimeoutMs?: number;
37
- /**
38
- * Called once per call when outbound audio is queued but no RTP packet has
39
- * been written for 2 s while media is connected. Receives the diagnostics
40
- * summary. Defaults to a no-op; nothing is restarted.
41
- */
42
- onWarning?: (message: string) => void;
43
- }
44
- /** Packet counts for the other participant's track, as seen by this participant. */
45
- export interface RelayCallInboundDiagnostics {
46
- /** RTP packets received on the subscribed track. */
47
- rtpPackets: number;
48
- /** Opus packets the decoder rejected. */
49
- decodeFailures: number;
50
- /** PCM frames handed to the `audio` listeners. */
51
- frames: number;
52
- /** ms since `connect()` for the first and last RTP packet; undefined until one arrives. */
53
- firstPacketAtMs: number | undefined;
54
- lastPacketAtMs: number | undefined;
55
- /** RTP packets received in the 5 s before `diagnostics()` was called. */
56
- recentRtpPackets: number;
57
- }
58
- /** Packet counts for this participant's published track. */
59
- export interface RelayCallOutboundDiagnostics {
60
- /** PCM slices accepted from the caller and handed to the engine source. */
61
- frames: number;
62
- opusPackets: number;
63
- rtpPackets: number;
64
- firstPacketAtMs: number | undefined;
65
- lastPacketAtMs: number | undefined;
66
- /** RTP packets written in the 5 s before `diagnostics()` was called. */
67
- recentRtpPackets: number;
68
- /** Encoded packets waiting for the 20 ms pacer. */
69
- queued: number;
70
- /** `undefined` when the engine does not expose its pacer (`wrtc`). */
71
- pacerAlive: boolean | undefined;
72
- }
73
- /** Room signaling frames counted since `connect()`. */
74
- export interface RelayCallRoomDiagnostics {
75
- roomStates: number;
76
- /** Subscription (pull) offers received from the room. */
77
- offers: number;
78
- endedReason: string | undefined;
79
- /** `error` frame messages, in order. */
80
- errors: string[];
81
- }
82
- /** ICE facts recorded for one call, for logs and for the connect timeout error. */
83
- export interface RelayCallIceDiagnostics {
84
- /** Local candidates gathered, counted by type. */
85
- local: {
86
- host: number;
87
- srflx: number;
88
- relay: number;
89
- other: number;
90
- };
91
- /** Remote candidates from the SFU answer: transport and port only, never the address. */
92
- remote: Array<{
93
- transport: string;
94
- port: number;
95
- }>;
96
- /** ICE gathering, ICE connection and peer connection state changes since `connect()`. */
97
- transitions: Array<{
98
- kind: "gathering" | "ice" | "connection";
99
- state: string;
100
- atMs: number;
101
- }>;
102
- connected: boolean;
103
- inbound: RelayCallInboundDiagnostics;
104
- outbound: RelayCallOutboundDiagnostics;
105
- room: RelayCallRoomDiagnostics;
106
- /** One-line rendering of the fields above. */
107
- summary: string;
108
- }
109
- export interface RelayCallTransportCloseEvent {
110
- code: number;
111
- reason: string;
112
- wasClean: boolean;
113
- }
114
- type TransportEventMap = {
115
- audio: [RelayAudioFrame];
116
- connected: [];
117
- roomState: [CallRoomStateFrame];
118
- ended: [CallRoomEndedFrame];
119
- error: [Error];
120
- close: [RelayCallTransportCloseEvent];
121
- };
122
- type TransportEvent = keyof TransportEventMap;
123
- type TransportListener<K extends TransportEvent> = (...args: TransportEventMap[K]) => void;
124
- export declare class RelayCallTransportError extends Error {
125
- readonly code?: string;
126
- constructor(message: string, code?: string);
127
- }
128
- /**
129
- * Provider-neutral Node WebRTC bridge for Relay Call rooms.
130
- *
131
- * The class owns Relay media negotiation internally. Higher-level adapters only
132
- * exchange PCM16 frames and call lifecycle events.
133
- */
134
- export declare class RelayCallTransport {
135
- #private;
136
- constructor(options: RelayCallTransportOptions);
137
- on<K extends TransportEvent>(event: K, listener: TransportListener<K>): this;
138
- off<K extends TransportEvent>(event: K, listener: TransportListener<K>): this;
139
- connect(): Promise<void>;
140
- /** Replace only the room signaling socket and replay the identical publication. */
141
- reconnect(): Promise<void>;
142
- /**
143
- * ICE candidates, state transitions, packet counts in both directions and
144
- * room frame counts recorded for this call, with a one-line summary.
145
- */
146
- diagnostics(): RelayCallIceDiagnostics;
147
- /**
148
- * Feed interleaved PCM16 audio into Relay. Frames are split into 10 ms WebRTC
149
- * source slices and handed to the engine at once; the engine's 20 ms pump
150
- * paces the wire, so adapters may push faster than real time (LiveKit's
151
- * `AudioSource.captureFrame` shape). Resolves once the slices are queued;
152
- * `waitForPlayout()` tells when they have left.
153
- */
154
- writeAudio(frame: RelayAudioFrame): Promise<void>;
155
- /** Milliseconds of audio accepted by `writeAudio` but not yet written to RTP. */
156
- queuedAudioMs(): number;
157
- /**
158
- * Resolves when every accepted slice has been written to RTP and the engine's
159
- * pump is idle; immediately when nothing is queued; early on `clearAudio()`
160
- * or `close()` (the caller reads `queuedAudioMs()` to learn what was dropped).
161
- */
162
- waitForPlayout(): Promise<void>;
163
- /** Drop outgoing PCM that has not reached RTP and release `waitForPlayout()` callers. */
164
- clearAudio(): void;
165
- setMuted(muted: boolean): void;
166
- end(): void;
167
- close(): void;
168
- }
169
- export {};
170
- //# sourceMappingURL=transport.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"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"}