@furious.luke/argus-js 0.4.0 → 0.5.1
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 +127 -23
- package/dist/index.cjs +1459 -171
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +349 -23
- package/dist/index.d.ts +349 -23
- package/dist/index.js +1458 -171
- package/dist/index.js.map +1 -1
- package/package.json +4 -2
package/dist/index.d.cts
CHANGED
|
@@ -1,3 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The logical purpose of a track within a stream. A stream may carry more than
|
|
3
|
+
* one track — camera and screen-share video, plus a single `audio` microphone
|
|
4
|
+
* track. Reads and change notifications address a specific video track by type;
|
|
5
|
+
* the `audio` track feeds server-side transcription rather than the frame path.
|
|
6
|
+
*/
|
|
7
|
+
type TrackType = "camera" | "screen" | "audio";
|
|
8
|
+
/**
|
|
9
|
+
* The video track types. The video publish surface (start, publish, unpublish,
|
|
10
|
+
* replaceStream) is typed to this rather than {@link TrackType}, so `audio`
|
|
11
|
+
* cannot be passed to a video call — the microphone has its own dedicated API
|
|
12
|
+
* ({@link Publisher.startAudioOnly}, {@link Publisher.publishMicrophone}). A
|
|
13
|
+
* session may also begin without media via {@link Publisher.startTextOnly}.
|
|
14
|
+
*/
|
|
15
|
+
type VideoTrackType = "camera" | "screen";
|
|
16
|
+
/**
|
|
17
|
+
* Declares the logical type and identity of a single published track.
|
|
18
|
+
*
|
|
19
|
+
* `mid` is the negotiated media-section id — the ROUTING key the server matches a
|
|
20
|
+
* track to its type by. It is used rather than the browser `MediaStreamTrack.id`
|
|
21
|
+
* because it is the only track identifier both peers agree on: Firefox mints an
|
|
22
|
+
* SDP msid track id unrelated to the `MediaStreamTrack.id`, so routing keyed on
|
|
23
|
+
* the latter cannot be matched server-side.
|
|
24
|
+
*
|
|
25
|
+
* `id` is the browser `MediaStreamTrack.id` — the GENERATION identity. The mid is
|
|
26
|
+
* stable across renegotiation and is reused when a track of the same type is
|
|
27
|
+
* republished on the same m-line, so it cannot distinguish a delayed end of a
|
|
28
|
+
* removed track from a failure of its replacement; the id changes with each new
|
|
29
|
+
* capture and can. The server echoes it in `media_track_ended`, and the publisher
|
|
30
|
+
* correlates that against the id it intentionally removed.
|
|
31
|
+
*/
|
|
32
|
+
interface TrackLabel {
|
|
33
|
+
mid: string;
|
|
34
|
+
id: string;
|
|
35
|
+
type: TrackType;
|
|
36
|
+
}
|
|
1
37
|
/**
|
|
2
38
|
* Message types exchanged over the WebSocket signaling channel.
|
|
3
39
|
*/
|
|
@@ -5,10 +41,14 @@ type SignalMessage = {
|
|
|
5
41
|
type: "offer";
|
|
6
42
|
sdp: string;
|
|
7
43
|
sdp_type: "offer";
|
|
44
|
+
tracks?: TrackLabel[];
|
|
45
|
+
negotiation_id?: string;
|
|
46
|
+
speech_enabled?: boolean;
|
|
8
47
|
} | {
|
|
9
48
|
type: "answer";
|
|
10
49
|
sdp: string;
|
|
11
50
|
sdp_type: "answer";
|
|
51
|
+
negotiation_id?: string;
|
|
12
52
|
} | {
|
|
13
53
|
type: "ice_candidate";
|
|
14
54
|
candidate: string;
|
|
@@ -18,27 +58,38 @@ type SignalMessage = {
|
|
|
18
58
|
} | {
|
|
19
59
|
type: "connection_state";
|
|
20
60
|
state: string;
|
|
61
|
+
} | {
|
|
62
|
+
type: "ice_path";
|
|
63
|
+
local_candidate_type: string;
|
|
64
|
+
local_protocol?: string;
|
|
65
|
+
remote_candidate_type?: string;
|
|
66
|
+
remote_protocol?: string;
|
|
67
|
+
relay_protocol?: string;
|
|
68
|
+
turn_url?: string;
|
|
21
69
|
} | {
|
|
22
70
|
type: "media_stall";
|
|
23
|
-
track:
|
|
71
|
+
track: TrackType;
|
|
24
72
|
frame_age_ms: number;
|
|
25
73
|
} | {
|
|
26
74
|
type: "media_resumed";
|
|
27
|
-
track:
|
|
75
|
+
track: TrackType;
|
|
28
76
|
duration_ms: number;
|
|
29
77
|
} | {
|
|
30
78
|
type: "media_track_ended";
|
|
31
|
-
track:
|
|
79
|
+
track: TrackType;
|
|
80
|
+
track_id?: string;
|
|
32
81
|
reason?: string;
|
|
33
82
|
} | {
|
|
34
83
|
type: "recovery_event";
|
|
35
84
|
event: "recovery_started" | "recovery_retry" | "recovery_failed";
|
|
36
|
-
track:
|
|
85
|
+
track: TrackType;
|
|
37
86
|
action?: "sender_restart" | "ice_restart";
|
|
38
87
|
reason?: "capture_ended" | "automatic_recovery_failed";
|
|
39
88
|
} | {
|
|
40
89
|
type: "error";
|
|
41
90
|
error: string;
|
|
91
|
+
negotiation_id?: string;
|
|
92
|
+
fatal?: boolean;
|
|
42
93
|
} | {
|
|
43
94
|
type: "resumed";
|
|
44
95
|
} | {
|
|
@@ -66,14 +117,31 @@ interface PublisherCallbacks {
|
|
|
66
117
|
onRecoveryStateChange?: (event: PublisherRecoveryEvent) => void;
|
|
67
118
|
/** Called when recovery requires the host application to obtain a new screen share. */
|
|
68
119
|
onRecoveryRequired?: (event: PublisherRecoveryEvent) => void;
|
|
120
|
+
/** Called when paced assistant text arrives alongside synthesized speech. */
|
|
121
|
+
onAssistantText?: (event: AssistantTextEvent) => void;
|
|
122
|
+
/** Called when the server accepts or rejects typed user input. */
|
|
123
|
+
onUserTextResult?: (event: UserTextResultEvent) => void;
|
|
124
|
+
/** Called once the explicitly requested outbound speech track arrives. */
|
|
125
|
+
onSpeechTrack?: (track: MediaStreamTrack, streams: readonly MediaStream[]) => void;
|
|
126
|
+
}
|
|
127
|
+
interface AssistantTextEvent {
|
|
128
|
+
utteranceId: string;
|
|
129
|
+
text: string;
|
|
130
|
+
}
|
|
131
|
+
interface UserTextResultEvent {
|
|
132
|
+
messageId: string;
|
|
133
|
+
accepted: boolean;
|
|
134
|
+
reason?: string;
|
|
69
135
|
}
|
|
70
136
|
type PublisherRecoveryState = "recovering" | "recovered" | "failed";
|
|
71
137
|
type PublisherRecoveryAction = "sender_restart" | "ice_restart";
|
|
72
138
|
type PublisherRecoveryFailureReason = "capture_ended" | "automatic_recovery_failed";
|
|
139
|
+
/** Restricts gateway-advertised TURN URLs used for ICE candidate gathering. */
|
|
140
|
+
type TurnTransportPolicy = "all" | "udp" | "tls";
|
|
73
141
|
/** A transition in the publisher's fixed automatic media-recovery ladder. */
|
|
74
142
|
interface PublisherRecoveryEvent {
|
|
75
143
|
state: PublisherRecoveryState;
|
|
76
|
-
track:
|
|
144
|
+
track: TrackType;
|
|
77
145
|
action?: PublisherRecoveryAction;
|
|
78
146
|
reason?: PublisherRecoveryFailureReason;
|
|
79
147
|
}
|
|
@@ -81,7 +149,7 @@ interface PublisherRecoveryEvent {
|
|
|
81
149
|
* TURN and read-token info delivered in the gateway `ready` message.
|
|
82
150
|
*/
|
|
83
151
|
interface GatewayReadyInfo {
|
|
84
|
-
/**
|
|
152
|
+
/** Bounded TURN URLs with UDP and TCP transports for each selected relay server. */
|
|
85
153
|
turn_urls?: string[];
|
|
86
154
|
turn_username?: string;
|
|
87
155
|
turn_credential?: string;
|
|
@@ -98,6 +166,29 @@ interface PublisherOptions {
|
|
|
98
166
|
token: string;
|
|
99
167
|
/** Optional extra ICE servers (e.g. STUN). TURN is supplied by the winning gateway. */
|
|
100
168
|
iceServers?: RTCIceServer[];
|
|
169
|
+
/**
|
|
170
|
+
* ICE transport policy passed to the underlying `RTCPeerConnection`. Defaults
|
|
171
|
+
* to `"all"`, letting ICE pick the best path (usually direct). Set to
|
|
172
|
+
* `"relay"` to force media through the TURN relay only — no host or
|
|
173
|
+
* server-reflexive candidates — which is how you verify the TURN path end to
|
|
174
|
+
* end rather than have ICE silently bypass it.
|
|
175
|
+
*/
|
|
176
|
+
iceTransportPolicy?: RTCIceTransportPolicy;
|
|
177
|
+
/**
|
|
178
|
+
* Restricts TURN URLs supplied by the winning gateway. Defaults to `"all"`.
|
|
179
|
+
* `"tls"` admits only secure `turns:` URLs and `"udp"` admits only TURN/UDP.
|
|
180
|
+
* Combine an explicit policy with `iceTransportPolicy: "relay"` when proving
|
|
181
|
+
* a particular relay path end to end rather than merely making it available.
|
|
182
|
+
*/
|
|
183
|
+
turnTransportPolicy?: TurnTransportPolicy;
|
|
184
|
+
/**
|
|
185
|
+
* Overall deadline for the initial accepted/proceed/ready gateway race.
|
|
186
|
+
* Unaccepted sockets are replaced after three seconds within this deadline.
|
|
187
|
+
* Defaults to 20 seconds.
|
|
188
|
+
*/
|
|
189
|
+
gatewayHandshakeTimeoutMs?: number;
|
|
190
|
+
/** Deadline after the initial offer for WebRTC to reach connected. Defaults to 30 seconds. */
|
|
191
|
+
peerConnectionTimeoutMs?: number;
|
|
101
192
|
/** How long to retry a dropped signaling connection to the selected gateway. Defaults to 20 seconds. */
|
|
102
193
|
signalingReconnectTimeoutMs?: number;
|
|
103
194
|
/** Callbacks for lifecycle events. */
|
|
@@ -105,11 +196,12 @@ interface PublisherOptions {
|
|
|
105
196
|
}
|
|
106
197
|
|
|
107
198
|
/**
|
|
108
|
-
* Publisher
|
|
109
|
-
*
|
|
199
|
+
* Publisher establishes a browser WebRTC session with an Argus media server.
|
|
200
|
+
* The session may start with camera, microphone, or only its reliable text data
|
|
201
|
+
* channel. Given the `gateway_urls` and `token` from a join-token response, it
|
|
110
202
|
* races the candidate gateways to the fastest one, completes the two-phase
|
|
111
|
-
* signaling handshake, and manages
|
|
112
|
-
*
|
|
203
|
+
* signaling handshake, and manages offer/answer exchange, ICE candidate
|
|
204
|
+
* trickling, and track (re)negotiation.
|
|
113
205
|
*
|
|
114
206
|
* After {@link Publisher.start} resolves, {@link Publisher.frameReadToken} holds
|
|
115
207
|
* the token your application server needs to fetch frames for this stream.
|
|
@@ -132,18 +224,44 @@ declare class Publisher {
|
|
|
132
224
|
private pc;
|
|
133
225
|
private hasAnswer;
|
|
134
226
|
private pendingRemoteCandidates;
|
|
135
|
-
private
|
|
227
|
+
private pendingLocalCandidates;
|
|
228
|
+
private localCandidateOfferSent;
|
|
229
|
+
private retainedLocalCandidates;
|
|
230
|
+
private retainedLocalCandidateKeys;
|
|
231
|
+
private localCandidateGeneration;
|
|
232
|
+
private remoteCandidateKeys;
|
|
233
|
+
private remoteCandidateOrder;
|
|
234
|
+
private remoteCandidateGeneration;
|
|
136
235
|
private readToken;
|
|
137
236
|
private gatewayURL;
|
|
237
|
+
private lastReportedICEPath;
|
|
238
|
+
private watchedICETransports;
|
|
138
239
|
private stopped;
|
|
240
|
+
private lifecycleGeneration;
|
|
241
|
+
private runAbort;
|
|
242
|
+
private peerConnectionTimer;
|
|
139
243
|
private reconnecting;
|
|
140
244
|
private reconnectGeneration;
|
|
141
245
|
private resumeSocket;
|
|
142
|
-
private
|
|
143
|
-
private
|
|
144
|
-
private
|
|
145
|
-
private
|
|
246
|
+
private signalingWaiters;
|
|
247
|
+
private pendingOffer;
|
|
248
|
+
private recoverySequence;
|
|
249
|
+
private recoveryStates;
|
|
250
|
+
private iceRestartSequence;
|
|
251
|
+
private iceRestartAttempt;
|
|
146
252
|
private trackEndHandlers;
|
|
253
|
+
private published;
|
|
254
|
+
private publishedStreams;
|
|
255
|
+
private typeSenders;
|
|
256
|
+
private intentionalTrackEnds;
|
|
257
|
+
private negotiationChain;
|
|
258
|
+
private pendingAnswer;
|
|
259
|
+
private negotiationSeq;
|
|
260
|
+
private textChannel;
|
|
261
|
+
private speechEnabled;
|
|
262
|
+
private speechPending;
|
|
263
|
+
private speechTransceiver;
|
|
264
|
+
private microphoneTransceiver;
|
|
147
265
|
constructor(opts: PublisherOptions);
|
|
148
266
|
/** The read token used for frame fetches and signaling resume in the selected region. */
|
|
149
267
|
get frameReadToken(): string | null;
|
|
@@ -153,41 +271,218 @@ declare class Publisher {
|
|
|
153
271
|
* region for frame reads and change-notification subscriptions.
|
|
154
272
|
*/
|
|
155
273
|
get selectedGatewayURL(): string | null;
|
|
274
|
+
/** Requests the persistent outbound `speech` track. This is explicit user
|
|
275
|
+
* opt-in and renegotiates only once; the track remains silent between turns. */
|
|
276
|
+
enableSpeech(): Promise<void>;
|
|
277
|
+
/** Sends typed input over the reliable ordered Argus text channel. */
|
|
278
|
+
sendUserText(messageId: string, text: string): void;
|
|
156
279
|
/**
|
|
157
280
|
* Starts the publisher: races all gateways to find the fastest, completes
|
|
158
281
|
* the two-phase handshake, creates the peer connection, and sends the SDP
|
|
159
282
|
* offer. Resolves when the offer has been sent (not when ICE completes —
|
|
160
283
|
* use onConnected for that).
|
|
284
|
+
*
|
|
285
|
+
* The stream's single video track is published under `type` (default `"camera"`),
|
|
286
|
+
* declared to the server so reads and change notifications can address them by
|
|
287
|
+
* type. Add or remove further tracks live with {@link Publisher.publish} and
|
|
288
|
+
* {@link Publisher.unpublish}.
|
|
289
|
+
*/
|
|
290
|
+
start(stream: MediaStream, type?: VideoTrackType): Promise<void>;
|
|
291
|
+
/**
|
|
292
|
+
* Starts the publisher with a microphone track and no video — a fully valid
|
|
293
|
+
* audio-only stream, the natural starting point for a voice agent. Exactly one
|
|
294
|
+
* audio track must be present in `stream`. Video can be added later with
|
|
295
|
+
* {@link Publisher.publish}; a stream carries at most one microphone track.
|
|
296
|
+
*
|
|
297
|
+
* Like {@link Publisher.start} it races the gateways, completes the handshake,
|
|
298
|
+
* and sends the offer; it resolves once the offer is sent. The microphone is not
|
|
299
|
+
* subject to the video recovery ladder — a mic that stops simply ends
|
|
300
|
+
* transcription for the stream.
|
|
301
|
+
*/
|
|
302
|
+
startAudioOnly(stream: MediaStream): Promise<void>;
|
|
303
|
+
/**
|
|
304
|
+
* Starts a WebRTC session with only the ordered `argus.text` data channel.
|
|
305
|
+
* This is the natural entry point for a typed, text-only agent: it requests no
|
|
306
|
+
* camera or microphone permission and publishes no media. Camera, screen, or
|
|
307
|
+
* microphone tracks can be added later with {@link Publisher.publish} or
|
|
308
|
+
* {@link Publisher.publishMicrophone}; {@link Publisher.enableSpeech} can add
|
|
309
|
+
* the optional inbound speech track independently.
|
|
310
|
+
*/
|
|
311
|
+
startTextOnly(): Promise<void>;
|
|
312
|
+
/**
|
|
313
|
+
* Shared startup for video, audio-only, and text-only entry points: race the
|
|
314
|
+
* gateways, build the peer connection and text channel, optionally add an
|
|
315
|
+
* initial media track, and send the first offer.
|
|
316
|
+
*/
|
|
317
|
+
private startSession;
|
|
318
|
+
/**
|
|
319
|
+
* Adds the single video track from `stream` to the live session under `type`,
|
|
320
|
+
* renegotiating so the media server begins ingesting them. Use this to add a
|
|
321
|
+
* track after {@link Publisher.start} — for example to begin a screen share on
|
|
322
|
+
* top of a live camera.
|
|
323
|
+
*
|
|
324
|
+
* Exactly one video track must be present in `stream`. If a track of `type` is already
|
|
325
|
+
* live it is removed and replaced (a "screen" published while another "screen"
|
|
326
|
+
* is live supersedes it).
|
|
327
|
+
*/
|
|
328
|
+
publish(stream: MediaStream, type: VideoTrackType): Promise<void>;
|
|
329
|
+
/**
|
|
330
|
+
* Removes the live track(s) of the given type, stops their local capture, and
|
|
331
|
+
* renegotiates so the media server ends ingestion for that track. A no-op if
|
|
332
|
+
* no track of that type is published.
|
|
333
|
+
*/
|
|
334
|
+
unpublish(type: VideoTrackType): Promise<void>;
|
|
335
|
+
/**
|
|
336
|
+
* Adds the microphone (audio) track from `stream` to the live session and
|
|
337
|
+
* renegotiates, so the media server begins transcribing it. Exactly one audio
|
|
338
|
+
* track must be present in `stream`. Publishing a microphone while one is
|
|
339
|
+
* already live replaces it.
|
|
340
|
+
*
|
|
341
|
+
* The audio track feeds server-side speech-to-text; its transcripts are
|
|
342
|
+
* delivered to the customer server over the change-notification subscription,
|
|
343
|
+
* not to the browser. Audio is not subject to the video recovery ladder — a
|
|
344
|
+
* mic that stops is simply removed.
|
|
345
|
+
*/
|
|
346
|
+
publishMicrophone(stream: MediaStream): Promise<void>;
|
|
347
|
+
/**
|
|
348
|
+
* Removes the live microphone track, stops its local capture, and
|
|
349
|
+
* renegotiates so the media server ends transcription. A no-op if no
|
|
350
|
+
* microphone is published.
|
|
351
|
+
*/
|
|
352
|
+
unpublishMicrophone(): Promise<void>;
|
|
353
|
+
/**
|
|
354
|
+
* Replaces the published track of a single type with a new stream and
|
|
355
|
+
* renegotiates in place — e.g. to swap to a freshly reacquired screen share
|
|
356
|
+
* after {@link PublisherCallbacks.onRecoveryRequired}. Defaults to the
|
|
357
|
+
* `"camera"` type. This is a convenience over {@link Publisher.publish}, which
|
|
358
|
+
* it delegates to (publishing one track per type replaces any existing track
|
|
359
|
+
* of that type).
|
|
161
360
|
*/
|
|
162
|
-
|
|
163
|
-
/** Replaces the currently published stream with a new one. */
|
|
164
|
-
replaceStream(stream: MediaStream): Promise<void>;
|
|
361
|
+
replaceStream(stream: MediaStream, type?: VideoTrackType): Promise<void>;
|
|
165
362
|
/** Stops publishing and tears down the peer connection. */
|
|
166
363
|
stop(): void;
|
|
364
|
+
private rejectPendingAnswer;
|
|
167
365
|
/** Returns the current RTCPeerConnection, or null if not started. */
|
|
168
366
|
get peerConnection(): RTCPeerConnection | null;
|
|
169
367
|
/** Returns true if the peer connection is in the "connected" state. */
|
|
170
368
|
get isConnected(): boolean;
|
|
171
369
|
private raceGateways;
|
|
172
370
|
private installSignaling;
|
|
371
|
+
private awaitSignaling;
|
|
372
|
+
private resolveSignalingWaiters;
|
|
373
|
+
private rejectSignalingWaiters;
|
|
374
|
+
private sendWhenSignalingAvailable;
|
|
375
|
+
private sendOffer;
|
|
173
376
|
private resumeSignaling;
|
|
174
377
|
private openResumeSocket;
|
|
175
378
|
private wait;
|
|
379
|
+
private isActiveRun;
|
|
380
|
+
private assertActiveRun;
|
|
381
|
+
private armPeerConnectionTimeout;
|
|
382
|
+
private clearPeerConnectionTimeout;
|
|
176
383
|
private terminateWithError;
|
|
177
384
|
private handleSignal;
|
|
178
385
|
private beginMediaRecovery;
|
|
179
386
|
private restartSenders;
|
|
180
|
-
|
|
387
|
+
/**
|
|
388
|
+
* Adds a recovery renegotiation to the same queue as user operations. The
|
|
389
|
+
* recovery ladder awaits its completion before starting the stage observation
|
|
390
|
+
* window. If recovery has completed by the time this reaches the head of the
|
|
391
|
+
* queue, it is skipped.
|
|
392
|
+
*/
|
|
393
|
+
/** Returns the peer-wide ICE attempt shared by all active track recoveries. */
|
|
394
|
+
private sharedIceRestart;
|
|
395
|
+
/**
|
|
396
|
+
* Serializes a renegotiation onto the shared chain: it waits for any prior
|
|
397
|
+
* negotiation to finish (its answer applied), sends a fresh offer, and resolves
|
|
398
|
+
* only once this offer's answer has been applied. This prevents overlapping
|
|
399
|
+
* offers and answers being applied to the wrong offer.
|
|
400
|
+
*/
|
|
401
|
+
private enqueueNegotiation;
|
|
402
|
+
private negotiateOnce;
|
|
403
|
+
/**
|
|
404
|
+
* Registers interest in the answer for the offer identified by `id` and returns
|
|
405
|
+
* a promise for its SDP. A second pending answer is an invariant violation: all
|
|
406
|
+
* offer creation, including recovery, must pass through negotiationChain.
|
|
407
|
+
*/
|
|
408
|
+
private nextNegotiationId;
|
|
409
|
+
private handleTextMessage;
|
|
410
|
+
private awaitAnswer;
|
|
411
|
+
private negotiationAnswerTimeoutMs;
|
|
412
|
+
private handleLocalICECandidate;
|
|
413
|
+
private candidateKey;
|
|
414
|
+
private retainLocalCandidate;
|
|
415
|
+
private retainRemoteCandidate;
|
|
416
|
+
private clearRetainedICECandidates;
|
|
417
|
+
private beginLocalCandidateBatch;
|
|
418
|
+
private releaseLocalCandidateBatch;
|
|
419
|
+
private applyAnswered;
|
|
420
|
+
private watchSelectedICEPairChanges;
|
|
421
|
+
private reportSelectedICEPath;
|
|
181
422
|
private completeMediaRecovery;
|
|
182
423
|
private failMediaRecovery;
|
|
424
|
+
private recoveryState;
|
|
183
425
|
private cancelMediaRecovery;
|
|
426
|
+
private cancelAllMediaRecovery;
|
|
184
427
|
private isCurrentRecovery;
|
|
428
|
+
private hasActiveMediaRecovery;
|
|
429
|
+
private clearSharedIceRestartIfIdle;
|
|
185
430
|
private emitRecoveryTransition;
|
|
186
431
|
private sendRecoveryDiagnostic;
|
|
187
|
-
private
|
|
432
|
+
private requireSingleVideoTrack;
|
|
433
|
+
private requireLiveVideoTrack;
|
|
434
|
+
private requireLiveTrack;
|
|
435
|
+
private requireSingleAudioTrack;
|
|
436
|
+
/**
|
|
437
|
+
* Stages the microphone track onto the peer connection. Unlike video, audio
|
|
438
|
+
* has no recovery ladder and no SSIM/frame semantics, so this simply adds (or
|
|
439
|
+
* replaces) the single audio sender and declares the updated labels.
|
|
440
|
+
*/
|
|
441
|
+
private stagePublishAudio;
|
|
442
|
+
/**
|
|
443
|
+
* Gives the microphone its own sendonly transceiver. addTrack() may reuse an
|
|
444
|
+
* existing compatible recvonly transceiver, which would collapse the
|
|
445
|
+
* microphone and assistant speech roles when speech was enabled first.
|
|
446
|
+
* addTransceiver() always creates a distinct m-line and its direction keeps
|
|
447
|
+
* the server's outbound speech sender on the dedicated speech transceiver.
|
|
448
|
+
*/
|
|
449
|
+
private addMicrophoneTrack;
|
|
450
|
+
/** Registers one physical video track under its logical type and source stream. */
|
|
451
|
+
private registerTrack;
|
|
452
|
+
/** The live video tracks currently published under the given type. */
|
|
453
|
+
private tracksOfType;
|
|
454
|
+
/** Builds the id → type label array declared to the server on every offer. */
|
|
455
|
+
private buildTrackLabels;
|
|
456
|
+
private labelsReplacingType;
|
|
457
|
+
/**
|
|
458
|
+
* The negotiated mid of the transceiver currently sending `track`, or null if
|
|
459
|
+
* none is found or it has not been negotiated yet. The mid is the identifier
|
|
460
|
+
* both peers agree on; it is assigned once setLocalDescription runs, which the
|
|
461
|
+
* publisher always does before sending an offer's labels.
|
|
462
|
+
*/
|
|
463
|
+
private midForTrack;
|
|
464
|
+
private stagePublish;
|
|
465
|
+
private stageUnpublish;
|
|
466
|
+
/** Stops every published local track and clears the published map. */
|
|
467
|
+
private stopPublishedTracks;
|
|
468
|
+
private expectIntentionalTrackEnd;
|
|
469
|
+
private forgetIntentionalTrackEnds;
|
|
470
|
+
private consumeIntentionalTrackEnd;
|
|
471
|
+
private clearIntentionalTrackEnds;
|
|
472
|
+
/**
|
|
473
|
+
* Watches a track's "ended" event so an involuntary capture stop (the user
|
|
474
|
+
* revokes a screen share, a device unplugs) reports as a recovery failure for
|
|
475
|
+
* that track's actual type. Intentional removals unwatch first.
|
|
476
|
+
*/
|
|
477
|
+
private watchTrack;
|
|
478
|
+
/**
|
|
479
|
+
* Watches a microphone only for lifecycle removal. An ended microphone is not
|
|
480
|
+
* recovered like video; it is negotiated away so the media server can flush
|
|
481
|
+
* the utterance and release transcription resources.
|
|
482
|
+
*/
|
|
483
|
+
private watchMicrophone;
|
|
484
|
+
private unwatchTrack;
|
|
188
485
|
private unwatchStreamTracks;
|
|
189
|
-
/** Waits for ICE gathering to reach the "complete" state. */
|
|
190
|
-
private gatherComplete;
|
|
191
486
|
}
|
|
192
487
|
|
|
193
488
|
/**
|
|
@@ -306,5 +601,36 @@ declare function captureCamera(opts?: CaptureCameraOptions): Promise<MediaStream
|
|
|
306
601
|
* ```
|
|
307
602
|
*/
|
|
308
603
|
declare function captureScreen(opts?: CaptureScreenOptions): Promise<MediaStream>;
|
|
604
|
+
/**
|
|
605
|
+
* Options for {@link captureMicrophone}.
|
|
606
|
+
*/
|
|
607
|
+
interface CaptureMicrophoneOptions {
|
|
608
|
+
/**
|
|
609
|
+
* Audio constraints, or `true`. Defaults to enabling the browser's echo
|
|
610
|
+
* cancellation, noise suppression, and auto gain control — the settings that
|
|
611
|
+
* give a speech-to-text engine the cleanest signal.
|
|
612
|
+
*/
|
|
613
|
+
audio?: MediaTrackConstraints | boolean;
|
|
614
|
+
/**
|
|
615
|
+
* The `MediaDevices` instance to capture from. Defaults to the global
|
|
616
|
+
* `navigator.mediaDevices`.
|
|
617
|
+
*/
|
|
618
|
+
mediaDevices?: MediaDevices;
|
|
619
|
+
}
|
|
620
|
+
/**
|
|
621
|
+
* Captures the user's microphone via `navigator.mediaDevices.getUserMedia`,
|
|
622
|
+
* applying defaults tuned for speech-to-text. Pair with
|
|
623
|
+
* {@link Publisher.publishMicrophone} to add transcription to a stream.
|
|
624
|
+
*
|
|
625
|
+
* Defaults:
|
|
626
|
+
* - `audio`: `{ echoCancellation: true, noiseSuppression: true, autoGainControl: true }`.
|
|
627
|
+
*
|
|
628
|
+
* @example
|
|
629
|
+
* ```ts
|
|
630
|
+
* const mic = await captureMicrophone();
|
|
631
|
+
* await publisher.publishMicrophone(mic);
|
|
632
|
+
* ```
|
|
633
|
+
*/
|
|
634
|
+
declare function captureMicrophone(opts?: CaptureMicrophoneOptions): Promise<MediaStream>;
|
|
309
635
|
|
|
310
|
-
export { type CaptureCameraOptions, type CaptureScreenOptions, type GatewayReadyInfo, Publisher, type PublisherCallbacks, type PublisherOptions, type PublisherRecoveryAction, type PublisherRecoveryEvent, type PublisherRecoveryFailureReason, type PublisherRecoveryState, type SignalMessage, captureCamera, captureScreen };
|
|
636
|
+
export { type AssistantTextEvent, type CaptureCameraOptions, type CaptureMicrophoneOptions, type CaptureScreenOptions, type GatewayReadyInfo, Publisher, type PublisherCallbacks, type PublisherOptions, type PublisherRecoveryAction, type PublisherRecoveryEvent, type PublisherRecoveryFailureReason, type PublisherRecoveryState, type SignalMessage, type TrackLabel, type TrackType, type TurnTransportPolicy, type UserTextResultEvent, type VideoTrackType, captureCamera, captureMicrophone, captureScreen };
|