@relaymessenger/livekit 0.1.0-staging.0 → 0.1.0-staging.10
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/README.md +94 -4
- package/dist/engine-werift.d.ts +4 -2
- package/dist/engine-werift.d.ts.map +1 -1
- package/dist/engine-werift.js +186 -23
- package/dist/engine-werift.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/livekit.d.ts +48 -2
- package/dist/livekit.d.ts.map +1 -1
- package/dist/livekit.js +106 -27
- package/dist/livekit.js.map +1 -1
- package/dist/transport.d.ts +214 -5
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +684 -70
- package/dist/transport.js.map +1 -1
- package/package.json +2 -2
package/dist/livekit.js
CHANGED
|
@@ -1,12 +1,28 @@
|
|
|
1
|
-
import { AudioInput, AudioOutput } from "@livekit/agents";
|
|
1
|
+
import { AudioInput, AudioOutput, Future } from "@livekit/agents";
|
|
2
2
|
import { AudioFrame } from "@livekit/rtc-node";
|
|
3
3
|
import { TransformStream } from "node:stream/web";
|
|
4
4
|
import { RelayCallTransport, } from "./transport.js";
|
|
5
|
+
/**
|
|
6
|
+
* The format LiveKit's own room input hands an AgentSession:
|
|
7
|
+
* `@livekit/agents` dist/voice/room_io/room_io.js:46-48
|
|
8
|
+
* `DEFAULT_ROOM_INPUT_OPTIONS = { audioSampleRate: 24e3, audioNumChannels: 1 }`,
|
|
9
|
+
* passed to the participant `AudioStream` (room_io.js:373-374). Plugins
|
|
10
|
+
* resample assuming the channel count they construct with
|
|
11
|
+
* (`@livekit/agents-plugin-google` 1.9.0 realtime_api.js:1307-1329
|
|
12
|
+
* `new AudioResampler(frame.sampleRate, 16000, 1)`; rtc-node's resampler reads
|
|
13
|
+
* raw bytes and ignores `frame.channels`), so the session must receive mono.
|
|
14
|
+
*/
|
|
15
|
+
export const LIVEKIT_ROOM_INPUT_AUDIO = Object.freeze({
|
|
16
|
+
sampleRate: 24_000,
|
|
17
|
+
channelCount: 1,
|
|
18
|
+
});
|
|
5
19
|
/** LiveKit Agents input backed by the remote Relay participant's WebRTC audio. */
|
|
6
20
|
export class RelayAudioInput extends AudioInput {
|
|
7
21
|
#transport;
|
|
8
22
|
#writer;
|
|
9
23
|
#onAudio;
|
|
24
|
+
/** Serial write chain: each frame waits for the writer, as `pipeTo` does in LiveKit's input. */
|
|
25
|
+
#writes = Promise.resolve();
|
|
10
26
|
#attached = false;
|
|
11
27
|
#closed = false;
|
|
12
28
|
constructor(transport) {
|
|
@@ -19,7 +35,16 @@ export class RelayAudioInput extends AudioInput {
|
|
|
19
35
|
if (this.#closed || !this.#attached)
|
|
20
36
|
return;
|
|
21
37
|
const audio = new AudioFrame(frame.samples, frame.sampleRate, frame.channelCount, frame.samples.length / frame.channelCount);
|
|
22
|
-
|
|
38
|
+
// LiveKit's ParticipantAudioInputStream pipes its AudioStream into the
|
|
39
|
+
// session with `pipeTo(output.writable)` (room_io/_input.js:161-162),
|
|
40
|
+
// which awaits the writer before each chunk. The transport pushes and
|
|
41
|
+
// cannot be paused, so the frames wait here in order instead.
|
|
42
|
+
this.#writes = this.#writes
|
|
43
|
+
.then(async () => {
|
|
44
|
+
await this.#writer.ready;
|
|
45
|
+
await this.#writer.write(audio);
|
|
46
|
+
})
|
|
47
|
+
.catch(() => undefined);
|
|
23
48
|
};
|
|
24
49
|
this.#transport.on("audio", this.#onAudio);
|
|
25
50
|
}
|
|
@@ -31,16 +56,30 @@ export class RelayAudioInput extends AudioInput {
|
|
|
31
56
|
return;
|
|
32
57
|
this.#closed = true;
|
|
33
58
|
this.#transport.off("audio", this.#onAudio);
|
|
59
|
+
await this.#writes;
|
|
34
60
|
await this.#writer.close().catch(() => undefined);
|
|
35
61
|
await super.close();
|
|
36
62
|
}
|
|
37
63
|
}
|
|
38
|
-
/**
|
|
64
|
+
/**
|
|
65
|
+
* LiveKit Agents output that publishes TTS PCM to the Relay participant.
|
|
66
|
+
*
|
|
67
|
+
* Shape copied from `@livekit/agents` `ParticipantAudioOutput`
|
|
68
|
+
* (dist/voice/room_io/_output.js): `captureFrame` hands the frame to the
|
|
69
|
+
* transport and returns without waiting for playout, `flush()` starts a playout
|
|
70
|
+
* task that reports `onPlaybackFinished` only once the transport has drained,
|
|
71
|
+
* and `clearBuffer()` resolves the interruption future so that task reports
|
|
72
|
+
* `interrupted: true` with the position actually played.
|
|
73
|
+
*/
|
|
39
74
|
export class RelayAudioOutput extends AudioOutput {
|
|
40
75
|
#transport;
|
|
41
|
-
|
|
42
|
-
#
|
|
43
|
-
#
|
|
76
|
+
/** Seconds pushed to the transport in the open segment. */
|
|
77
|
+
#pushedDuration = 0;
|
|
78
|
+
#firstFrameEmitted = false;
|
|
79
|
+
#flushTask;
|
|
80
|
+
#flushDone = true;
|
|
81
|
+
/** Resolved by `clearBuffer()` with the milliseconds still queued at that moment. */
|
|
82
|
+
#interruptedFuture = new Future();
|
|
44
83
|
#closed = false;
|
|
45
84
|
constructor(transport, sampleRate = 48_000) {
|
|
46
85
|
super(sampleRate, undefined, { pause: false });
|
|
@@ -49,38 +88,47 @@ export class RelayAudioOutput extends AudioOutput {
|
|
|
49
88
|
async captureFrame(frame) {
|
|
50
89
|
if (this.#closed)
|
|
51
90
|
throw new Error("Relay LiveKit audio output is closed.");
|
|
91
|
+
if (this.#flushTask && !this.#flushDone) {
|
|
92
|
+
this.logger.error("captureFrame called while flush is in progress");
|
|
93
|
+
await this.#flushTask;
|
|
94
|
+
}
|
|
52
95
|
await super.captureFrame(frame);
|
|
53
|
-
if (!this.#
|
|
54
|
-
this.#
|
|
55
|
-
this
|
|
56
|
-
this.onPlaybackStarted(this.#segmentStartedAt);
|
|
96
|
+
if (!this.#firstFrameEmitted) {
|
|
97
|
+
this.#firstFrameEmitted = true;
|
|
98
|
+
this.onPlaybackStarted(Date.now());
|
|
57
99
|
}
|
|
58
|
-
this.#
|
|
100
|
+
this.#pushedDuration += frame.samplesPerChannel / frame.sampleRate;
|
|
101
|
+
// Resolves once the slices are queued; the engine's pump paces the wire.
|
|
59
102
|
await this.#transport.writeAudio({
|
|
60
103
|
samples: frame.data,
|
|
61
104
|
sampleRate: frame.sampleRate,
|
|
62
105
|
channelCount: frame.channels,
|
|
63
106
|
});
|
|
64
107
|
}
|
|
108
|
+
/** Mark the segment complete; `onPlaybackFinished` fires once the transport has drained. */
|
|
65
109
|
flush() {
|
|
66
110
|
super.flush();
|
|
67
|
-
if (!this.#
|
|
111
|
+
if (!this.#pushedDuration)
|
|
112
|
+
return;
|
|
113
|
+
if (this.#flushTask && !this.#flushDone)
|
|
68
114
|
return;
|
|
69
|
-
this
|
|
70
|
-
|
|
71
|
-
|
|
115
|
+
this.#flushDone = false;
|
|
116
|
+
this.#flushTask = this.#waitForPlayoutTask().finally(() => {
|
|
117
|
+
this.#flushDone = true;
|
|
72
118
|
});
|
|
73
|
-
this.#
|
|
119
|
+
void this.#flushTask.catch(() => undefined);
|
|
74
120
|
}
|
|
75
121
|
clearBuffer() {
|
|
122
|
+
const queuedMs = this.#transport.queuedAudioMs();
|
|
76
123
|
this.#transport.clearAudio();
|
|
77
|
-
if (
|
|
124
|
+
if (this.#interruptedFuture.done)
|
|
78
125
|
return;
|
|
79
|
-
this.
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
this.#
|
|
126
|
+
if (this.#pushedDuration === 0 && this.pendingPlayoutSegments === 0)
|
|
127
|
+
return;
|
|
128
|
+
if (!this.#flushTask || this.#flushDone)
|
|
129
|
+
this.flush();
|
|
130
|
+
if (!this.#interruptedFuture.done)
|
|
131
|
+
this.#interruptedFuture.resolve(queuedMs);
|
|
84
132
|
}
|
|
85
133
|
close() {
|
|
86
134
|
if (this.#closed)
|
|
@@ -88,10 +136,19 @@ export class RelayAudioOutput extends AudioOutput {
|
|
|
88
136
|
this.#closed = true;
|
|
89
137
|
this.clearBuffer();
|
|
90
138
|
}
|
|
91
|
-
#
|
|
92
|
-
|
|
93
|
-
this.#
|
|
94
|
-
|
|
139
|
+
async #waitForPlayoutTask() {
|
|
140
|
+
const interruptedFuture = this.#interruptedFuture;
|
|
141
|
+
await Promise.race([this.#transport.waitForPlayout(), interruptedFuture.await]);
|
|
142
|
+
const interrupted = interruptedFuture.done;
|
|
143
|
+
let playbackPosition = this.#pushedDuration;
|
|
144
|
+
if (interrupted) {
|
|
145
|
+
playbackPosition = Math.max(0, playbackPosition - interruptedFuture.result / 1_000);
|
|
146
|
+
}
|
|
147
|
+
this.#pushedDuration = 0;
|
|
148
|
+
this.#firstFrameEmitted = false;
|
|
149
|
+
if (this.#interruptedFuture === interruptedFuture)
|
|
150
|
+
this.#interruptedFuture = new Future();
|
|
151
|
+
this.onPlaybackFinished({ playbackPosition, interrupted });
|
|
95
152
|
}
|
|
96
153
|
}
|
|
97
154
|
/** Build LiveKit Agents audio IO around an already-connected Relay transport. */
|
|
@@ -119,17 +176,27 @@ export class RelayLiveKitCall {
|
|
|
119
176
|
const transportOptions = {
|
|
120
177
|
relay: options.relay,
|
|
121
178
|
callId: options.callId,
|
|
179
|
+
inboundAudio: LIVEKIT_ROOM_INPUT_AUDIO,
|
|
122
180
|
...(options.room ? { room: options.room } : {}),
|
|
181
|
+
...(options.roomClient ? { roomClient: options.roomClient } : {}),
|
|
123
182
|
...(options.webRTC ? { webRTC: options.webRTC } : {}),
|
|
183
|
+
...(options.iceServers ? { iceServers: options.iceServers } : {}),
|
|
184
|
+
...(options.iceTransportPolicy ? { iceTransportPolicy: options.iceTransportPolicy } : {}),
|
|
124
185
|
...(options.iceGatheringTimeoutMs === undefined
|
|
125
186
|
? {}
|
|
126
187
|
: { iceGatheringTimeoutMs: options.iceGatheringTimeoutMs }),
|
|
188
|
+
...(options.sessionConnectTimeoutMs === undefined
|
|
189
|
+
? {}
|
|
190
|
+
: { sessionConnectTimeoutMs: options.sessionConnectTimeoutMs }),
|
|
191
|
+
...(options.mediaConnectTimeoutMs === undefined
|
|
192
|
+
? {}
|
|
193
|
+
: { mediaConnectTimeoutMs: options.mediaConnectTimeoutMs }),
|
|
127
194
|
...(options.connectionTimeoutMs === undefined
|
|
128
195
|
? {}
|
|
129
196
|
: { connectionTimeoutMs: options.connectionTimeoutMs }),
|
|
130
197
|
};
|
|
131
198
|
const transport = new RelayCallTransport(transportOptions);
|
|
132
|
-
await transport.connect();
|
|
199
|
+
await transport.connect(options.signal ? { signal: options.signal } : {});
|
|
133
200
|
return new RelayLiveKitCall(transport, createRelayLiveKitAudio(transport, options));
|
|
134
201
|
}
|
|
135
202
|
attach(session) {
|
|
@@ -150,6 +217,18 @@ export class RelayLiveKitCall {
|
|
|
150
217
|
this.#session.output.audio = null;
|
|
151
218
|
this.#session = undefined;
|
|
152
219
|
}
|
|
220
|
+
/**
|
|
221
|
+
* Resolves once the person's audio has arrived and the room shows them
|
|
222
|
+
* connected (the transport's `peerAudio`). Await it before starting the
|
|
223
|
+
* AgentSession so the greeting is heard.
|
|
224
|
+
*/
|
|
225
|
+
waitForPeerAudio(timeoutMs) {
|
|
226
|
+
return this.transport.waitForPeerAudio(timeoutMs);
|
|
227
|
+
}
|
|
228
|
+
/** ICE candidates and state transitions for this call, with a one-line summary for logs. */
|
|
229
|
+
diagnostics() {
|
|
230
|
+
return this.transport.diagnostics();
|
|
231
|
+
}
|
|
153
232
|
setMuted(muted) {
|
|
154
233
|
this.transport.setMuted(muted);
|
|
155
234
|
}
|
package/dist/livekit.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"livekit.js","sourceRoot":"","sources":["../src/livekit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAqB,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"livekit.js","sourceRoot":"","sources":["../src/livekit.ts"],"names":[],"mappings":"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"}
|
package/dist/transport.d.ts
CHANGED
|
@@ -5,6 +5,46 @@ export interface RelayAudioFrame {
|
|
|
5
5
|
sampleRate: number;
|
|
6
6
|
channelCount: number;
|
|
7
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
|
+
/**
|
|
16
|
+
* Returns the ICE servers for one peer connection. Called before the first
|
|
17
|
+
* peer and again before every restart, so short-lived TURN credentials can be
|
|
18
|
+
* minted per attempt (PartyTracks: a reconnect "will trigger new sessionId,
|
|
19
|
+
* new ice server credentials and a new peerConnection").
|
|
20
|
+
*/
|
|
21
|
+
export type RelayIceServersProvider = (attempt: {
|
|
22
|
+
/** 0 for the first peer, then 1, 2, ... for each restart. */
|
|
23
|
+
restarts: number;
|
|
24
|
+
}) => RelayIceServer[] | Promise<RelayIceServer[]>;
|
|
25
|
+
/** Why the transport replaced its peer connection with a new SFU session. */
|
|
26
|
+
export type RelayCallRestartReason = "timeout" | "failed" | "disconnected" | "error";
|
|
27
|
+
export interface RelayCallRestartEvent {
|
|
28
|
+
reason: RelayCallRestartReason;
|
|
29
|
+
/** `diagnostics().summary` of the session being replaced, taken as it was given up. */
|
|
30
|
+
summary: string;
|
|
31
|
+
/** Restarts since `connect()`, this one included. */
|
|
32
|
+
restarts: number;
|
|
33
|
+
/** Backoff waited before the new peer was built. */
|
|
34
|
+
delayMs: number;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* PCM format the engine decodes the remote participant's Opus into. The values
|
|
38
|
+
* are the ones libopus decodes to (`@evan/opus` lib.d.ts: `channels?: 1 | 2`,
|
|
39
|
+
* `sample_rate?: 8000 | 12000 | 16000 | 24000 | 48000`); the decoder itself
|
|
40
|
+
* resamples and downmixes, so no PCM is converted by hand.
|
|
41
|
+
*/
|
|
42
|
+
export interface RelayInboundAudioFormat {
|
|
43
|
+
sampleRate: 8000 | 12000 | 16000 | 24000 | 48000;
|
|
44
|
+
channelCount: 1 | 2;
|
|
45
|
+
}
|
|
46
|
+
/** Opus's native rate and Relay's wire channel count. */
|
|
47
|
+
export declare const DEFAULT_INBOUND_AUDIO: Readonly<RelayInboundAudioFormat>;
|
|
8
48
|
export type RelayCallEngine = "werift" | "wrtc";
|
|
9
49
|
export interface RelayCallTransportOptions {
|
|
10
50
|
relay: Relay;
|
|
@@ -15,8 +55,110 @@ export interface RelayCallTransportOptions {
|
|
|
15
55
|
* and loads no native binding. `"wrtc"` loads `@roamhq/wrtc` on demand.
|
|
16
56
|
*/
|
|
17
57
|
engine?: RelayCallEngine;
|
|
18
|
-
/**
|
|
58
|
+
/**
|
|
59
|
+
* STUN and TURN servers handed to the engine's `RTCPeerConnection`. Defaults
|
|
60
|
+
* to none: Cloudflare's SFU answers with its own host candidates. Set TURN
|
|
61
|
+
* servers when the agent runs behind a NAT or firewall that blocks UDP. A
|
|
62
|
+
* function is called before every peer connection, restarts included, so
|
|
63
|
+
* it can mint fresh TURN credentials each time.
|
|
64
|
+
*/
|
|
65
|
+
iceServers?: RelayIceServer[] | RelayIceServersProvider;
|
|
66
|
+
/** `"relay"` forces every candidate through TURN. Defaults to `"all"`. */
|
|
67
|
+
iceTransportPolicy?: RelayIceTransportPolicy;
|
|
68
|
+
/**
|
|
69
|
+
* How long one SFU session has, after its answer is applied, to reach
|
|
70
|
+
* `connected` before the transport restarts onto a new session. Defaults to
|
|
71
|
+
* 5 seconds. `connect()` itself has no deadline: it waits through restarts
|
|
72
|
+
* until media connects, the Call ends, `close()` is called, or its signal aborts.
|
|
73
|
+
*/
|
|
74
|
+
sessionConnectTimeoutMs?: number;
|
|
75
|
+
/** @deprecated Use `sessionConnectTimeoutMs`; now the per-session wait, not a `connect()` deadline. */
|
|
76
|
+
mediaConnectTimeoutMs?: number;
|
|
77
|
+
/** @deprecated Use `sessionConnectTimeoutMs`. */
|
|
19
78
|
connectionTimeoutMs?: number;
|
|
79
|
+
/**
|
|
80
|
+
* PCM format of the `audio` events: the Opus decoder decodes the remote
|
|
81
|
+
* track straight to this rate and channel count. Defaults to 48 kHz stereo.
|
|
82
|
+
* The `"wrtc"` engine delivers libwebrtc's own format and accepts only the default.
|
|
83
|
+
*/
|
|
84
|
+
inboundAudio?: RelayInboundAudioFormat;
|
|
85
|
+
/**
|
|
86
|
+
* Called once per call when outbound audio is queued but no RTP packet has
|
|
87
|
+
* been written for 2 s while media is connected. Receives the diagnostics
|
|
88
|
+
* summary. Defaults to a no-op; nothing is restarted.
|
|
89
|
+
*/
|
|
90
|
+
onWarning?: (message: string) => void;
|
|
91
|
+
}
|
|
92
|
+
/** Packet counts for the other participant's track, as seen by this participant. */
|
|
93
|
+
export interface RelayCallInboundDiagnostics {
|
|
94
|
+
/** RTP packets received on the subscribed track. */
|
|
95
|
+
rtpPackets: number;
|
|
96
|
+
/** Opus packets the decoder rejected. */
|
|
97
|
+
decodeFailures: number;
|
|
98
|
+
/** PCM frames handed to the `audio` listeners. */
|
|
99
|
+
frames: number;
|
|
100
|
+
/** ms since `connect()` for the first and last RTP packet; undefined until one arrives. */
|
|
101
|
+
firstPacketAtMs: number | undefined;
|
|
102
|
+
lastPacketAtMs: number | undefined;
|
|
103
|
+
/** RTP packets received in the 5 s before `diagnostics()` was called. */
|
|
104
|
+
recentRtpPackets: number;
|
|
105
|
+
}
|
|
106
|
+
/** Packet counts for this participant's published track. */
|
|
107
|
+
export interface RelayCallOutboundDiagnostics {
|
|
108
|
+
/** PCM slices accepted from the caller and handed to the engine source. */
|
|
109
|
+
frames: number;
|
|
110
|
+
opusPackets: number;
|
|
111
|
+
/** RTP packets carrying the caller's audio. */
|
|
112
|
+
rtpPackets: number;
|
|
113
|
+
/** RTP packets carrying Opus silence, written while nothing was queued. */
|
|
114
|
+
silencePackets: number;
|
|
115
|
+
/** ms since `connect()` for the first and last RTP packet of either kind. */
|
|
116
|
+
firstPacketAtMs: number | undefined;
|
|
117
|
+
lastPacketAtMs: number | undefined;
|
|
118
|
+
/** RTP packets of either kind written in the 5 s before `diagnostics()` was called. */
|
|
119
|
+
recentRtpPackets: number;
|
|
120
|
+
/** Encoded packets waiting for the 20 ms pacer. */
|
|
121
|
+
queued: number;
|
|
122
|
+
/** `undefined` when the engine does not expose its pacer (`wrtc`). */
|
|
123
|
+
pacerAlive: boolean | undefined;
|
|
124
|
+
}
|
|
125
|
+
/** Room signaling frames counted since `connect()`. */
|
|
126
|
+
export interface RelayCallRoomDiagnostics {
|
|
127
|
+
roomStates: number;
|
|
128
|
+
/** Subscription (pull) offers received from the room. */
|
|
129
|
+
offers: number;
|
|
130
|
+
endedReason: string | undefined;
|
|
131
|
+
/** `error` frame messages, in order. */
|
|
132
|
+
errors: string[];
|
|
133
|
+
}
|
|
134
|
+
/** ICE facts recorded for one call, for logs and for the connect timeout error. */
|
|
135
|
+
export interface RelayCallIceDiagnostics {
|
|
136
|
+
/** Local candidates gathered, counted by type. */
|
|
137
|
+
local: {
|
|
138
|
+
host: number;
|
|
139
|
+
srflx: number;
|
|
140
|
+
relay: number;
|
|
141
|
+
other: number;
|
|
142
|
+
};
|
|
143
|
+
/** Remote candidates from the SFU answer: transport and port only, never the address. */
|
|
144
|
+
remote: Array<{
|
|
145
|
+
transport: string;
|
|
146
|
+
port: number;
|
|
147
|
+
}>;
|
|
148
|
+
/** ICE gathering, ICE connection and peer connection state changes since `connect()`. */
|
|
149
|
+
transitions: Array<{
|
|
150
|
+
kind: "gathering" | "ice" | "connection";
|
|
151
|
+
state: string;
|
|
152
|
+
atMs: number;
|
|
153
|
+
}>;
|
|
154
|
+
connected: boolean;
|
|
155
|
+
inbound: RelayCallInboundDiagnostics;
|
|
156
|
+
outbound: RelayCallOutboundDiagnostics;
|
|
157
|
+
room: RelayCallRoomDiagnostics;
|
|
158
|
+
/** Peer connections replaced by a new SFU session since `connect()`. */
|
|
159
|
+
restarts: number;
|
|
160
|
+
/** One-line rendering of the fields above. */
|
|
161
|
+
summary: string;
|
|
20
162
|
}
|
|
21
163
|
export interface RelayCallTransportCloseEvent {
|
|
22
164
|
code: number;
|
|
@@ -26,13 +168,47 @@ export interface RelayCallTransportCloseEvent {
|
|
|
26
168
|
type TransportEventMap = {
|
|
27
169
|
audio: [RelayAudioFrame];
|
|
28
170
|
connected: [];
|
|
171
|
+
/** A new peer connection published on a new SFU session; audio continues on it. */
|
|
172
|
+
restarted: [RelayCallRestartEvent];
|
|
29
173
|
roomState: [CallRoomStateFrame];
|
|
174
|
+
/** The person's camera started (`true`) or stopped (`false`) sending, from `roomState`. */
|
|
175
|
+
remoteVideo: [boolean];
|
|
176
|
+
/**
|
|
177
|
+
* Once per call: the person's audio has reached this peer (first inbound
|
|
178
|
+
* frame on the pulled track) and `roomState` shows the person connected. The
|
|
179
|
+
* room pulls both directions together, so from here the person hears what is
|
|
180
|
+
* written; start speaking after this, as LiveKit Agents start a session once
|
|
181
|
+
* the participant is in the room.
|
|
182
|
+
*/
|
|
183
|
+
peerAudio: [];
|
|
30
184
|
ended: [CallRoomEndedFrame];
|
|
31
185
|
error: [Error];
|
|
32
186
|
close: [RelayCallTransportCloseEvent];
|
|
33
187
|
};
|
|
34
188
|
type TransportEvent = keyof TransportEventMap;
|
|
35
189
|
type TransportListener<K extends TransportEvent> = (...args: TransportEventMap[K]) => void;
|
|
190
|
+
/**
|
|
191
|
+
* Restart rule, copied from PartyTracks and Cloudflare (PROTOCOL.md section 4):
|
|
192
|
+
* not `connected` 5 s after the SFU answer (Cloudflare's echo example waits
|
|
193
|
+
* 5000 ms; SFU operations block up to 5 s awaiting `connected`), `failed`, or
|
|
194
|
+
* `disconnected` for 7 s (PartyTracks.ts `timeoutSeconds = 7`). Backoff 250 ms
|
|
195
|
+
* x1.1 per attempt, capped at 10 s (PartyTracks `retryWithBackoff`
|
|
196
|
+
* `backoffFactor: 1.1`, rxjs-helpers.ts defaults). werift never reports
|
|
197
|
+
* `failed` on a session whose checks go unanswered (ice.js:983-986), so the
|
|
198
|
+
* 5 s timer is the trigger that fires in practice.
|
|
199
|
+
*/
|
|
200
|
+
export declare const RESTART_CONNECT_TIMEOUT_MS = 5000;
|
|
201
|
+
export declare const RESTART_DISCONNECTED_MS = 7000;
|
|
202
|
+
export declare const RESTART_INITIAL_DELAY_MS = 250;
|
|
203
|
+
export declare const RESTART_BACKOFF_FACTOR = 1.1;
|
|
204
|
+
export declare const RESTART_MAX_DELAY_MS = 10000;
|
|
205
|
+
/**
|
|
206
|
+
* Backoff before restart number `attempt` (1-based) counted since the last
|
|
207
|
+
* session that connected. PartyTracks passes `resetOnSuccess: true` to rxjs
|
|
208
|
+
* `retry` (rxjs-helpers.ts:18, :39); this transport reads "success" as a
|
|
209
|
+
* session reaching `connected`.
|
|
210
|
+
*/
|
|
211
|
+
export declare const restartDelayMs: (attempt: number) => number;
|
|
36
212
|
export declare class RelayCallTransportError extends Error {
|
|
37
213
|
readonly code?: string;
|
|
38
214
|
constructor(message: string, code?: string);
|
|
@@ -41,23 +217,56 @@ export declare class RelayCallTransportError extends Error {
|
|
|
41
217
|
* Provider-neutral Node WebRTC bridge for Relay Call rooms.
|
|
42
218
|
*
|
|
43
219
|
* The class owns Relay media negotiation internally. Higher-level adapters only
|
|
44
|
-
* exchange PCM16 frames and call lifecycle events.
|
|
220
|
+
* exchange PCM16 frames and call lifecycle events. When an SFU session never
|
|
221
|
+
* connects or dies, the transport builds a new peer connection on a new
|
|
222
|
+
* session (PROTOCOL.md section 4); the audio source and the `audio` events
|
|
223
|
+
* carry on across the swap, so adapters only hear silence.
|
|
45
224
|
*/
|
|
46
225
|
export declare class RelayCallTransport {
|
|
47
226
|
#private;
|
|
48
227
|
constructor(options: RelayCallTransportOptions);
|
|
49
228
|
on<K extends TransportEvent>(event: K, listener: TransportListener<K>): this;
|
|
50
229
|
off<K extends TransportEvent>(event: K, listener: TransportListener<K>): this;
|
|
51
|
-
|
|
230
|
+
/**
|
|
231
|
+
* Join the room, publish, and resolve on the first `connected`. Dead SFU
|
|
232
|
+
* sessions are replaced as they are found (PROTOCOL.md section 4), with no
|
|
233
|
+
* overall deadline: this rejects only when the Call ends, the room or
|
|
234
|
+
* transport closes, the room reports an error, or `signal` aborts (which
|
|
235
|
+
* also closes the transport).
|
|
236
|
+
*/
|
|
237
|
+
connect(options?: {
|
|
238
|
+
signal?: AbortSignal;
|
|
239
|
+
}): Promise<void>;
|
|
52
240
|
/** Replace only the room signaling socket and replay the identical publication. */
|
|
53
241
|
reconnect(): Promise<void>;
|
|
242
|
+
/**
|
|
243
|
+
* ICE candidates, state transitions, packet counts in both directions,
|
|
244
|
+
* room frame counts and restarts recorded for this call, with a one-line summary.
|
|
245
|
+
*/
|
|
246
|
+
diagnostics(): RelayCallIceDiagnostics;
|
|
54
247
|
/**
|
|
55
248
|
* Feed interleaved PCM16 audio into Relay. Frames are split into 10 ms WebRTC
|
|
56
|
-
* source slices and
|
|
249
|
+
* source slices and handed to the engine at once; the engine's 20 ms pump
|
|
250
|
+
* paces the wire, so adapters may push faster than real time (LiveKit's
|
|
251
|
+
* `AudioSource.captureFrame` shape). Resolves once the slices are queued;
|
|
252
|
+
* `waitForPlayout()` tells when they have left.
|
|
57
253
|
*/
|
|
58
254
|
writeAudio(frame: RelayAudioFrame): Promise<void>;
|
|
59
|
-
/**
|
|
255
|
+
/** Milliseconds of audio accepted by `writeAudio` but not yet written to RTP. */
|
|
256
|
+
queuedAudioMs(): number;
|
|
257
|
+
/**
|
|
258
|
+
* Resolves when every accepted slice has been written to RTP and the engine's
|
|
259
|
+
* pump is idle; immediately when nothing is queued; early on `clearAudio()`
|
|
260
|
+
* or `close()` (the caller reads `queuedAudioMs()` to learn what was dropped).
|
|
261
|
+
*/
|
|
262
|
+
waitForPlayout(): Promise<void>;
|
|
263
|
+
/** Drop outgoing PCM that has not reached RTP and release `waitForPlayout()` callers. */
|
|
60
264
|
clearAudio(): void;
|
|
265
|
+
/**
|
|
266
|
+
* Resolves once `peerAudio` has fired (at once if it already has). Rejects
|
|
267
|
+
* after `timeoutMs`, or when the Call ends or the transport closes first.
|
|
268
|
+
*/
|
|
269
|
+
waitForPeerAudio(timeoutMs: number): Promise<void>;
|
|
61
270
|
setMuted(muted: boolean): void;
|
|
62
271
|
end(): void;
|
|
63
272
|
close(): void;
|
package/dist/transport.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,kBAAkB,EAElB,eAAe,EAGf,kBAAkB,EAElB,KAAK,EACN,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"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"}
|