@relaymessenger/livekit 0.1.0-staging.15 → 0.1.0-staging.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,457 +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
- * `new Decoder({ channels?: 1 | 2, sample_rate?: 8000 | 12000 | 16000 |
26
- * 24000 | 48000 })` decodes any Opus stream to that count and rate (libopus
27
- * `opus_decoder_create(Fs, channels)`), which is how the sink honours
28
- * `RelayInboundAudioFormat`.
29
- * Participant shapes copied from the headless phone that joined Relay's room
30
- * through Cloudflare's SFU on 2026-09-21 (_runtime/bin/headless-phone-webrtc.mjs
31
- * lines 93-160): `bundlePolicy: "max-bundle", iceServers: []` (Cloudflare
32
- * supplies its ICE candidates in the answer), the local track is id
33
- * "microphone" in stream "relay-call" (Relay-iOS RelayWebRTCAudioTransport),
34
- * the first RTP packet carries the marker bit, empty payloads are skipped and a
35
- * decode failure never tears the sink down.
36
- */
37
- import { Decoder, Encoder } from "@evan/opus";
38
- import { MediaStreamTrack, OpusRtpPayload, RTCPeerConnection, RTCRtpCodecParameters, RTCRtpHeaderExtensionParameters, RtpHeader, RtpPacket, useFIR, useNACK, usePLI, } from "werift";
39
- import { createWeriftVideoFactory } from "./engine-werift-video.js";
40
- /** Opus on the wire is always 48 kHz; Relay sends stereo so callers may pass either channel count. */
41
- export const WERIFT_SAMPLE_RATE = 48_000;
42
- export const WERIFT_CHANNEL_COUNT = 2;
43
- /** One RTP packet carries 20 ms: 960 frames at 48 kHz, timestamp advances by 960. */
44
- export const WERIFT_PACKET_MS = 20;
45
- const PACKET_FRAMES = (WERIFT_SAMPLE_RATE * WERIFT_PACKET_MS) / 1000;
46
- const PACKET_SAMPLES = PACKET_FRAMES * WERIFT_CHANNEL_COUNT;
47
- /** Dynamic payload type; werift's sender replaces it with the negotiated one. */
48
- const LOCAL_PAYLOAD_TYPE = 111;
49
- /** Packets counted for `diagnostics()`; the recent window is the last 5 s. */
50
- export const STATS_WINDOW_MS = 5_000;
51
- /** Monotone packet counter with first/last epoch timestamps and a 5 s window. */
52
- class PacketClock {
53
- count = 0;
54
- firstAt;
55
- lastAt;
56
- #recent = [];
57
- mark(now = Date.now()) {
58
- this.count += 1;
59
- this.firstAt ??= now;
60
- this.lastAt = now;
61
- this.#recent.push(now);
62
- this.#prune(now);
63
- }
64
- recent(now = Date.now()) {
65
- this.#prune(now);
66
- return this.#recent.length;
67
- }
68
- #prune(now) {
69
- const floor = now - STATS_WINDOW_MS;
70
- let drop = 0;
71
- while (drop < this.#recent.length && this.#recent[drop] < floor)
72
- drop += 1;
73
- if (drop)
74
- this.#recent.splice(0, drop);
75
- }
76
- }
77
- /**
78
- * A pacer more than this far behind its clock re-anchors instead of bursting
79
- * the backlog. LiveKit's native `AudioSource` (rust-sdks
80
- * webrtc-sys/src/audio_track.cpp:161-188) runs a 10 ms libwebrtc
81
- * `RepeatingTask`, which schedules against an absolute run time and makes up
82
- * every lost tick with zero delay, unbounded (rtc_base/task_utils/
83
- * repeating_task.cc:86-89, `delay -= lost_time; delay = max(delay, 0)`). The
84
- * bound is ours: 10 packets, so an event-loop hiccup is made up in full and a
85
- * real stall does not dump seconds of audio on the receiver at once.
86
- * Sources saved under _sources/audio-pacing-20260922.
87
- */
88
- export const WERIFT_MAX_CATCH_UP_MS = 200;
89
- /**
90
- * Wall-clock RTP audio pacing: packet `n` of a run is due at `start + n × 20 ms`,
91
- * so the average rate is exactly one packet per 20 ms however late the timer
92
- * fires. `take(now)` returns how many packets are due and counts them as sent.
93
- */
94
- export class RtpAudioPacer {
95
- packetMs;
96
- maxCatchUpMs;
97
- #startedAt;
98
- #sent = 0;
99
- constructor(packetMs = WERIFT_PACKET_MS, maxCatchUpMs = WERIFT_MAX_CATCH_UP_MS) {
100
- this.packetMs = packetMs;
101
- this.maxCatchUpMs = maxCatchUpMs;
102
- }
103
- /** Packets due by `now` and not yet sent; the first call of a run sends one at once. */
104
- take(now) {
105
- if (this.#startedAt === undefined || now - this.nextDueAt() > this.maxCatchUpMs) {
106
- this.#startedAt = now;
107
- this.#sent = 0;
108
- }
109
- const due = Math.floor((now - this.#startedAt) / this.packetMs) + 1 - this.#sent;
110
- if (due <= 0)
111
- return 0;
112
- this.#sent += due;
113
- return due;
114
- }
115
- /** When the next packet is due; `-Infinity` before the first `take` of a run. */
116
- nextDueAt() {
117
- return this.#startedAt === undefined ? -Infinity : this.#startedAt + this.#sent * this.packetMs;
118
- }
119
- /** Forget the run; the next `take` starts a new clock. */
120
- reset() {
121
- this.#startedAt = undefined;
122
- this.#sent = 0;
123
- }
124
- }
125
- /** Convert any PCM16 frame to interleaved 48 kHz stereo by linear interpolation. */
126
- export const toWireFormat = (data) => {
127
- const { samples, sampleRate, channelCount } = data;
128
- const inputFrames = Math.floor(samples.length / channelCount);
129
- if (sampleRate === WERIFT_SAMPLE_RATE && channelCount === WERIFT_CHANNEL_COUNT) {
130
- return samples;
131
- }
132
- const outputFrames = Math.round((inputFrames * WERIFT_SAMPLE_RATE) / sampleRate);
133
- const out = new Int16Array(outputFrames * WERIFT_CHANNEL_COUNT);
134
- const ratio = sampleRate / WERIFT_SAMPLE_RATE;
135
- const leftIndex = 0;
136
- const rightIndex = channelCount > 1 ? 1 : 0;
137
- for (let frame = 0; frame < outputFrames; frame += 1) {
138
- const position = frame * ratio;
139
- const base = Math.min(Math.floor(position), inputFrames - 1);
140
- const next = Math.min(base + 1, inputFrames - 1);
141
- const fraction = position - Math.floor(position);
142
- const left = samples[base * channelCount + leftIndex] * (1 - fraction)
143
- + samples[next * channelCount + leftIndex] * fraction;
144
- const right = samples[base * channelCount + rightIndex] * (1 - fraction)
145
- + samples[next * channelCount + rightIndex] * fraction;
146
- out[frame * 2] = Math.round(left);
147
- out[frame * 2 + 1] = Math.round(right);
148
- }
149
- return out;
150
- };
151
- /**
152
- * PCM16 in, paced 20 ms Opus RTP out. Frames are accumulated into whole
153
- * packets; an `RtpAudioPacer` on the monotonic clock decides how many are
154
- * due, so the wire sees exactly 50 packets/s regardless of how the adapter
155
- * chunks its writes or how late the timer fires. A timer that fired once per
156
- * packet (the old `setInterval`) lost every late tick while the RTP timestamp
157
- * still advanced 960 per packet: @relay's calls on 2026-09-22 sent 48.66-48.98
158
- * packets/s and the phone's jitter buffer ran dry. Adapters may push
159
- * far ahead of real time: `queuedMs()` is what has not left yet and
160
- * `waitForDrain()` resolves once the queued application audio has been
161
- * written (LiveKit's `AudioSource.queuedDuration` / `waitForPlayout` shape).
162
- *
163
- * From `start()` (the transport calls it when the peer first connects) until
164
- * the track stops, the pump never pauses: a tick with no application audio
165
- * queued writes an Opus silence frame instead, as a live microphone track
166
- * does. Cloudflare's SFU refuses to pull a published track that has carried
167
- * no RTP: `tracks/new` for the remote track returned `empty_track_error` "No
168
- * track data from remote peer" after about 8.2 s on staging 2026-09-22, and
169
- * the same pull returned in about 470 ms with silence flowing. Silence and
170
- * application packets share one sequence and timestamp line, so queued audio
171
- * replaces silence on the next tick with no gap and no jump.
172
- */
173
- class WeriftAudioSource {
174
- #encoder = new Encoder({
175
- channels: WERIFT_CHANNEL_COUNT,
176
- sample_rate: WERIFT_SAMPLE_RATE,
177
- application: "voip",
178
- });
179
- /** 20 ms of digital silence, encoded once by the same encoder and reused. */
180
- #silence = Buffer.from(this.#encoder.encode(new Int16Array(PACKET_SAMPLES)));
181
- #track = new MediaStreamTrack({ kind: "audio", id: "microphone", streamId: "relay-call" });
182
- #packets = [];
183
- /** Every RTP packet written, silence included. */
184
- #rtp = new PacketClock();
185
- #opusPackets = 0;
186
- #applicationRtpPackets = 0;
187
- #silencePackets = 0;
188
- #pending = new Int16Array(0);
189
- #sequenceNumber = 1;
190
- #timestamp = 0;
191
- #first = true;
192
- #pump;
193
- #pacer = new RtpAudioPacer();
194
- #started = false;
195
- #stopped = false;
196
- #drainWaiters = new Set();
197
- stats() {
198
- return {
199
- opusPackets: this.#opusPackets,
200
- rtpPackets: this.#applicationRtpPackets,
201
- silencePackets: this.#silencePackets,
202
- firstRtpAt: this.#rtp.firstAt,
203
- lastRtpAt: this.#rtp.lastAt,
204
- recentRtpPackets: this.#rtp.recent(),
205
- queued: this.#packets.length,
206
- pacerAlive: this.#pump !== undefined,
207
- };
208
- }
209
- createTrack() {
210
- const track = this.#track;
211
- const stop = track.stop;
212
- track.stop = () => {
213
- this.#stopped = true;
214
- this.clear();
215
- this.#stopPump();
216
- stop();
217
- };
218
- return track;
219
- }
220
- start() {
221
- if (this.#started || this.#stopped)
222
- return;
223
- this.#started = true;
224
- this.#startPump();
225
- }
226
- queuedMs() {
227
- return this.#packets.length * WERIFT_PACKET_MS
228
- + (this.#pending.length / WERIFT_CHANNEL_COUNT / WERIFT_SAMPLE_RATE) * 1_000;
229
- }
230
- waitForDrain() {
231
- this.#flushPending();
232
- if (this.#drained())
233
- return Promise.resolve();
234
- return new Promise((resolve) => this.#drainWaiters.add(resolve));
235
- }
236
- clear() {
237
- this.#packets.length = 0;
238
- this.#pending = new Int16Array(0);
239
- if (!this.#started)
240
- this.#stopPump();
241
- this.#notifyDrained();
242
- }
243
- onData(data) {
244
- if (this.#stopped)
245
- return;
246
- const wire = toWireFormat(data);
247
- const merged = new Int16Array(this.#pending.length + wire.length);
248
- merged.set(this.#pending);
249
- merged.set(wire, this.#pending.length);
250
- let offset = 0;
251
- while (merged.length - offset >= PACKET_SAMPLES) {
252
- const frame = merged.subarray(offset, offset + PACKET_SAMPLES);
253
- this.#packets.push(Buffer.from(this.#encoder.encode(frame)));
254
- this.#opusPackets += 1;
255
- offset += PACKET_SAMPLES;
256
- }
257
- this.#pending = merged.slice(offset);
258
- this.#startPump();
259
- }
260
- /** Pad a sub-packet remainder with silence so the tail of a segment reaches the wire. */
261
- #flushPending() {
262
- if (this.#stopped || this.#pending.length === 0)
263
- return;
264
- const padded = new Int16Array(PACKET_SAMPLES);
265
- padded.set(this.#pending);
266
- this.#pending = new Int16Array(0);
267
- this.#packets.push(Buffer.from(this.#encoder.encode(padded)));
268
- this.#opusPackets += 1;
269
- this.#startPump();
270
- }
271
- /** Application audio only: the silence the started pump keeps writing never counts. */
272
- #drained() {
273
- return this.#packets.length === 0
274
- && this.#pending.length === 0
275
- && (this.#started || this.#pump === undefined);
276
- }
277
- #notifyDrained() {
278
- if (!this.#drained())
279
- return;
280
- for (const resolve of [...this.#drainWaiters]) {
281
- this.#drainWaiters.delete(resolve);
282
- resolve();
283
- }
284
- }
285
- /**
286
- * The first packet of a run leaves at once; after that each wake sends
287
- * every packet the pacer says is due and sleeps until the next one is due,
288
- * the absolute schedule of libwebrtc's `RepeatingTask`. Before `start()` the
289
- * pump stops once the queue is empty; after it, the pump runs until the
290
- * track stops.
291
- */
292
- #startPump() {
293
- if (this.#pump || this.#stopped)
294
- return;
295
- if (!this.#started && this.#packets.length === 0)
296
- return;
297
- this.#tick();
298
- }
299
- #tick() {
300
- if (this.#stopped)
301
- return;
302
- const due = this.#pacer.take(performance.now());
303
- for (let sent = 0; sent < due; sent += 1) {
304
- if (!this.#sendNext())
305
- break;
306
- }
307
- if (this.#packets.length === 0) {
308
- if (!this.#started) {
309
- this.#stopPump();
310
- this.#notifyDrained();
311
- return;
312
- }
313
- this.#notifyDrained();
314
- }
315
- const delay = Math.max(0, Math.ceil(this.#pacer.nextDueAt() - performance.now()));
316
- this.#pump = setTimeout(() => this.#tick(), delay);
317
- this.#pump.unref?.();
318
- }
319
- #stopPump() {
320
- this.#pacer.reset();
321
- if (!this.#pump)
322
- return;
323
- clearTimeout(this.#pump);
324
- this.#pump = undefined;
325
- }
326
- /** Writes one packet, queued audio first, else silence once started; false when nothing was written. */
327
- #sendNext() {
328
- if (this.#stopped)
329
- return false;
330
- const application = this.#packets.shift();
331
- if (!application && !this.#started)
332
- return false;
333
- const header = new RtpHeader({
334
- payloadType: LOCAL_PAYLOAD_TYPE,
335
- sequenceNumber: this.#sequenceNumber,
336
- timestamp: this.#timestamp,
337
- ssrc: 0,
338
- marker: this.#first,
339
- });
340
- this.#first = false;
341
- this.#sequenceNumber = (this.#sequenceNumber + 1) & 0xffff;
342
- this.#timestamp = (this.#timestamp + PACKET_FRAMES) >>> 0;
343
- this.#track.writeRtp(new RtpPacket(header, application ?? this.#silence));
344
- if (application)
345
- this.#applicationRtpPackets += 1;
346
- else
347
- this.#silencePackets += 1;
348
- this.#rtp.mark();
349
- return true;
350
- }
351
- }
352
- /** Opus RTP in, PCM16 in the requested format (default 48 kHz stereo) out, one `ondata` per packet. */
353
- class WeriftAudioSink {
354
- ondata = null;
355
- #decoder;
356
- #rtp = new PacketClock();
357
- #decodeFailures = 0;
358
- #unsubscribe;
359
- stats() {
360
- return {
361
- rtpPackets: this.#rtp.count,
362
- decodeFailures: this.#decodeFailures,
363
- firstRtpAt: this.#rtp.firstAt,
364
- lastRtpAt: this.#rtp.lastAt,
365
- recentRtpPackets: this.#rtp.recent(),
366
- };
367
- }
368
- constructor(track, format = { sampleRate: WERIFT_SAMPLE_RATE, channelCount: WERIFT_CHANNEL_COUNT }) {
369
- const { sampleRate, channelCount } = format;
370
- this.#decoder = new Decoder({ channels: channelCount, sample_rate: sampleRate });
371
- const { unSubscribe } = track.onReceiveRtp.subscribe((rtp) => {
372
- this.#rtp.mark();
373
- const handler = this.ondata;
374
- if (!handler || !rtp.payload?.length)
375
- return;
376
- const packet = OpusRtpPayload.deSerialize(rtp.payload);
377
- let bytes;
378
- try {
379
- bytes = this.#decoder.decode(packet.payload);
380
- }
381
- catch {
382
- this.#decodeFailures += 1;
383
- return;
384
- }
385
- const samples = new Int16Array(bytes.byteLength >> 1);
386
- new Uint8Array(samples.buffer).set(bytes.subarray(0, samples.byteLength));
387
- handler({
388
- samples,
389
- sampleRate,
390
- bitsPerSample: 16,
391
- channelCount,
392
- numberOfFrames: samples.length / channelCount,
393
- });
394
- });
395
- this.#unsubscribe = unSubscribe;
396
- }
397
- stop() {
398
- this.ondata = null;
399
- this.#unsubscribe();
400
- }
401
- }
402
- /**
403
- * Video codecs. werift matches a remote codec by MIME type alone
404
- * (`findCodecByMimeType` in `TransceiverManager.setRemoteRTP`) and throws
405
- * "negotiate codecs failed." for a media section with no local codec of its
406
- * kind, so every codec a phone may publish is listed. H.264 and VP8 are the
407
- * ones this engine encodes and decodes (engine-werift-video.ts): H.264 as
408
- * constrained baseline `42e01f`, the only H.264 profile Cloudflare's SFU
409
- * accepts, with packetization-mode 1; both ask for NACK, PLI and FIR, without
410
- * which the SFU sends no keyframe request. VP9 and AV1 are receive-only: a
411
- * pull offer carrying them is answered, the track is not decoded.
412
- */
413
- const videoCodecs = () => {
414
- const feedback = () => [useNACK(), usePLI(), useFIR()];
415
- return [
416
- new RTCRtpCodecParameters({
417
- mimeType: "video/H264",
418
- clockRate: 90_000,
419
- rtcpFeedback: feedback(),
420
- parameters: "level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f",
421
- }),
422
- new RTCRtpCodecParameters({ mimeType: "video/VP8", clockRate: 90_000, rtcpFeedback: feedback() }),
423
- new RTCRtpCodecParameters({ mimeType: "video/VP9", clockRate: 90_000, direction: "recvonly" }),
424
- new RTCRtpCodecParameters({ mimeType: "video/AV1", clockRate: 90_000, direction: "recvonly" }),
425
- ];
426
- };
427
- /**
428
- * The 3GPP coordination-of-video-orientation extension: with it negotiated a
429
- * phone sends its camera frames unrotated and says how to turn them, and the
430
- * receiver reports that as `VideoFrameEvent.rotation`, as LiveKit does.
431
- */
432
- const VIDEO_ORIENTATION_URI = "urn:3gpp:video-orientation";
433
- export const createWeriftPeerConnection = (config = { iceServers: [], iceTransportPolicy: "all" }) => new RTCPeerConnection({
434
- bundlePolicy: "max-bundle",
435
- iceServers: config.iceServers,
436
- iceTransportPolicy: config.iceTransportPolicy,
437
- codecs: {
438
- audio: [
439
- new RTCRtpCodecParameters({
440
- mimeType: "audio/opus",
441
- clockRate: WERIFT_SAMPLE_RATE,
442
- channels: WERIFT_CHANNEL_COUNT,
443
- }),
444
- ],
445
- video: videoCodecs(),
446
- },
447
- headerExtensions: {
448
- video: [new RTCRtpHeaderExtensionParameters({ id: 1, uri: VIDEO_ORIENTATION_URI })],
449
- },
450
- });
451
- export const createWeriftWebRTCFactory = () => ({
452
- createPeerConnection: (config) => createWeriftPeerConnection(config),
453
- createAudioSource: () => new WeriftAudioSource(),
454
- createAudioSink: (track, format) => new WeriftAudioSink(track, format),
455
- ...createWeriftVideoFactory(),
456
- });
457
- //# sourceMappingURL=engine-werift.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"engine-werift.js","sourceRoot":"","sources":["../src/engine-werift.ts"],"names":[],"mappings":"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"}