@ikonai/sdk 1.0.79 → 1.1.0

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.
Files changed (55) hide show
  1. package/app-messaging.d.ts +1 -1
  2. package/assets/audio-capture-worker-D-0X2Dy8.js +1 -0
  3. package/assets/audio-playback-worker-DivBZPfS.js +1 -0
  4. package/assets/libopus-CnBCihDi.js +1 -0
  5. package/assets/protocol-worker-BH93CVck.js +1 -0
  6. package/assets/src-BKYD07QQ.js +1 -0
  7. package/assets/src-DOUWsCWT.js +1 -0
  8. package/assets/video-capture-worker-BQGOFbZt.js +1 -0
  9. package/assets/video-playback-worker-tC5nUVnw.js +1 -0
  10. package/assets/viseme-worker-Cd-JqTVM.js +1 -0
  11. package/capabilities-BtJblfdG.js +108 -0
  12. package/channel/channel-manager.d.ts +1 -1
  13. package/channel/channel.d.ts +1 -1
  14. package/client/endpoint-selector.d.ts +1 -1
  15. package/client/ikon-client-config.d.ts +13 -11
  16. package/client/ikon-client.d.ts +98 -4
  17. package/connection/authenticator.d.ts +3 -3
  18. package/connection/urls.d.ts +7 -18
  19. package/errors/index.d.ts +22 -13
  20. package/functions/browser-functions.d.ts +1 -1
  21. package/functions/function-registry.d.ts +1 -1
  22. package/functions/types.d.ts +2 -2
  23. package/ikon-media-zqob_QeE.js +3160 -0
  24. package/index.d.ts +8 -8
  25. package/index.js +8119 -12502
  26. package/media/ikon-audio-capture.d.ts +15 -3
  27. package/media/ikon-audio-playback.d.ts +37 -0
  28. package/media/ikon-video-playback.d.ts +24 -0
  29. package/media/media-session-helper.d.ts +8 -0
  30. package/media/video-constants.d.ts +11 -1
  31. package/media/viseme-tracker.d.ts +10 -1
  32. package/package.json +1 -1
  33. package/storage.d.ts +13 -0
  34. package/transport/transport.d.ts +1 -1
  35. package/transport/web-socket-transport.d.ts +1 -1
  36. package/transport/web-transport-transport.d.ts +1 -1
  37. package/utils/inspect-mode.d.ts +4 -0
  38. package/utils/log-sender.d.ts +1 -1
  39. package/utils/platform.d.ts +4 -0
  40. package/utils/query-params.d.ts +8 -4
  41. package/vite.config.d.ts +2 -0
  42. package/webrtc/webrtc-signaling.d.ts +11 -2
  43. package/worker/audio-playback-worker.d.ts +14 -1
  44. package/worker/video-capture-worker.d.ts +2 -2
  45. package/worker/video-playback-worker.d.ts +14 -2
  46. package/worker/viseme-worker.d.ts +10 -2
  47. package/assets/audio-capture-worker-Brmt2Z7a.js +0 -1279
  48. package/assets/audio-playback-worker-DDtsnLoq.js +0 -1473
  49. package/assets/index-Ca9sTcGt.js +0 -119
  50. package/assets/index-D_vz6N3U.js +0 -267
  51. package/assets/libopus-ChbDZJKA.js +0 -139
  52. package/assets/protocol-worker-BoZcMF0x.js +0 -1674
  53. package/assets/video-capture-worker-DxgvFTcw.js +0 -1126
  54. package/assets/video-playback-worker-Ca4XVGqt.js +0 -1005
  55. package/assets/viseme-worker-DVWM4pRh.js +0 -831
@@ -61,7 +61,6 @@ export interface IkonAudioCaptureRequest {
61
61
  constraints?: MediaTrackConstraints;
62
62
  options?: {
63
63
  bitrate?: number;
64
- targetIds?: number[];
65
64
  };
66
65
  /**
67
66
  * Optional correlation identifier embedded in the AudioStreamBegin payload. Used by the
@@ -82,7 +81,6 @@ export interface IkonAudioCaptureRequest {
82
81
  }
83
82
  export interface IkonAudioCaptureOptions {
84
83
  bitrate?: number;
85
- targetIds?: number[];
86
84
  }
87
85
  export interface IkonAudioCaptureHandle {
88
86
  captureId: string;
@@ -120,6 +118,7 @@ export interface IkonAudioCaptureHandle {
120
118
  }
121
119
  export declare class IkonAudioCapture {
122
120
  private readonly client;
121
+ private static readonly RESUME_TIMEOUT_MS;
123
122
  private worker;
124
123
  private sendPort;
125
124
  private workletModuleUrl;
@@ -129,9 +128,9 @@ export declare class IkonAudioCapture {
129
128
  private nextTrackId;
130
129
  private captures;
131
130
  private pendingCaptures;
131
+ private activeWebRtcCaptureInvalidate;
132
132
  private readonly config;
133
133
  private deviceChangeHandler;
134
- private audioContextStateHandler;
135
134
  constructor(client: IkonClient, config?: IkonAudioCaptureConfig);
136
135
  /**
137
136
  * Emit a diagnostic event for telemetry/debugging.
@@ -200,6 +199,12 @@ export declare class IkonAudioCapture {
200
199
  private ensureWorker;
201
200
  private ensureSendPort;
202
201
  private ensureAudioContext;
202
+ /**
203
+ * Resume with a timeout: on iOS an interrupted context's resume() can return a promise
204
+ * that never settles, which would hang the whole mic start silently — the caller's error
205
+ * path never runs and nothing reaches the user or the logs.
206
+ */
207
+ private resumeWithTimeout;
203
208
  /**
204
209
  * Attempt getUserMedia with retry and constraint fallback.
205
210
  * Phase-based approach: try requested constraints first, then fallback if overconstrained.
@@ -219,6 +224,13 @@ export declare class IkonAudioCapture {
219
224
  * De-duplicates concurrent loading attempts for the same context.
220
225
  */
221
226
  private ensureWorklet;
227
+ /**
228
+ * Called by the client when the WebRTC transport is lost mid-session. The active WebRTC
229
+ * capture handle can no longer send or end segments (its signaling object is gone), so mark
230
+ * it stopped and fire its onStopped callback — owners (e.g. CaptureButton) then drop the
231
+ * handle, and the next startMic re-evaluates the transport and takes the protocol channel.
232
+ */
233
+ handleWebRtcTransportLost(): void;
222
234
  startMic(request?: IkonAudioCaptureRequest): Promise<IkonAudioCaptureHandle>;
223
235
  stop(captureId: string): Promise<boolean>;
224
236
  startSegment(captureId: string): boolean;
@@ -1,3 +1,4 @@
1
+ import { GlobalState } from '../../shared/protocol/src/index.ts';
1
2
  import { IkonClient } from '../client/ikon-client';
2
3
  export interface IkonAudioPlaybackConfig {
3
4
  /**
@@ -61,6 +62,8 @@ export declare class IkonAudioPlayback {
61
62
  private recoveryTask;
62
63
  /** Timeout for AudioContext.resume() - normally resolves instantly, but some browsers hang indefinitely */
63
64
  private static readonly RESUME_TIMEOUT_MS;
65
+ private static readonly MAX_WORKER_REBUILD_ATTEMPTS;
66
+ private workerRebuildAttempts;
64
67
  private audioContext;
65
68
  private outputSampleRateHz;
66
69
  private audioWorkletNode;
@@ -73,6 +76,9 @@ export declare class IkonAudioPlayback {
73
76
  private audioWorker;
74
77
  private protocolPort;
75
78
  private readonly mediaSessionHelper;
79
+ private hiddenMuted;
80
+ private lastReportedPlaybackState;
81
+ private readonly lastPlaybackByStream;
76
82
  private readonly fallbackQueues;
77
83
  private readonly activeStreams;
78
84
  private mediaSessionConfig;
@@ -127,6 +133,27 @@ export declare class IkonAudioPlayback {
127
133
  * Set up audio worklet after recreating AudioContext on iOS.
128
134
  */
129
135
  private setupAudioGraphAfterRecreate;
136
+ /**
137
+ * Replay active audio stream state from GlobalState into the decode worker.
138
+ * GlobalState is the server's authoritative stream registry, delivered to every
139
+ * joiner and reconnector — this is how a client that missed a stream's live
140
+ * AUDIO_STREAM_BEGIN (late join, soft reconnect, worker rebuilt mid-stream)
141
+ * recovers its decode state. Idempotent: live same-format streams are untouched.
142
+ */
143
+ syncStreamsFromGlobalState(globalState: GlobalState): void;
144
+ /**
145
+ * Tell the decode worker whether WebRTC currently carries the audio. While it does,
146
+ * the worker skips protocol audio frames (the RTP stack decodes them); once WebRTC
147
+ * falls back to the protocol channel the worker must decode them itself.
148
+ */
149
+ setWebRtcActive(active: boolean): void;
150
+ /**
151
+ * Called when the protocol transport that backs this pipeline's message port is torn
152
+ * down (e.g. the protocol worker is terminated during a reconnect). Drops the decode
153
+ * worker and its dead port; the enabled state and audio graph survive, so the next
154
+ * playback setup rebuilds the worker with a live port.
155
+ */
156
+ handleProtocolTransportLost(): void;
130
157
  /**
131
158
  * Dispose of resources. After calling this, the instance should not be reused.
132
159
  */
@@ -163,10 +190,20 @@ export declare class IkonAudioPlayback {
163
190
  private onAudioWorkerMessage;
164
191
  private postToWorklet;
165
192
  private notifyPlaybackActive;
193
+ private computePlaybackState;
194
+ private sendPlaybackReport;
195
+ /**
196
+ * Push an immediate report for every active stream when audibility flips
197
+ * (context suspended/resumed, tab hidden/visible, unlock succeeded) — the
198
+ * periodic worklet reports would otherwise lag the change by up to 500 ms,
199
+ * and while output is disconnected the worklet does not tick at all.
200
+ */
201
+ private reportPlaybackStateIfChanged;
166
202
  private enqueuePendingWorkletMessage;
167
203
  private stopAudioWorklet;
168
204
  private stopScriptProcessor;
169
205
  private stopAudioGraph;
206
+ private handleWorkerCrash;
170
207
  private stopWorkers;
171
208
  private ensureStateSubscription;
172
209
  }
@@ -1,3 +1,4 @@
1
+ import { GlobalState } from '../../shared/protocol/src/index.ts';
1
2
  import { IkonClient } from '../client/ikon-client';
2
3
  export interface IkonVideoPlaybackConfig {
3
4
  /**
@@ -18,9 +19,11 @@ export interface IkonVideoPlaybackConfig {
18
19
  * decoding and presenting frames efficiently.
19
20
  */
20
21
  export declare class IkonVideoPlayback {
22
+ private static readonly MAX_WORKER_REBUILD_ATTEMPTS;
21
23
  private readonly client;
22
24
  private readonly config;
23
25
  private enabled;
26
+ private workerRebuildAttempts;
24
27
  private stateUnsubscribe;
25
28
  private worker;
26
29
  private protocolPort;
@@ -53,6 +56,27 @@ export declare class IkonVideoPlayback {
53
56
  private requestIdrForStream;
54
57
  private detachProtocolPort;
55
58
  private ensureProtocolPort;
59
+ /**
60
+ * Replay active video stream state from GlobalState into the decode worker.
61
+ * GlobalState is the server's authoritative stream registry, delivered to every
62
+ * joiner and reconnector — this is how a client that missed a stream's live
63
+ * VIDEO_STREAM_BEGIN (late join, soft reconnect, worker rebuilt mid-stream)
64
+ * recovers its decode state. Idempotent: known streams are untouched.
65
+ */
66
+ syncStreamsFromGlobalState(globalState: GlobalState): void;
67
+ /**
68
+ * Tell the decode worker whether WebRTC currently carries the video. While it does,
69
+ * the worker skips protocol video frames (the RTP stack decodes them); once WebRTC
70
+ * falls back to the protocol channel the worker must decode them itself.
71
+ */
72
+ setWebRtcActive(active: boolean): void;
73
+ /**
74
+ * Called when the protocol transport that backs this pipeline's message port is torn
75
+ * down (e.g. the protocol worker is terminated during a reconnect). Drops the decode
76
+ * worker and its dead port; the next playback setup rebuilds them with live ports.
77
+ */
78
+ handleProtocolTransportLost(): void;
79
+ private handleWorkerCrash;
56
80
  private stopWorker;
57
81
  private ensureStateSubscription;
58
82
  }
@@ -10,6 +10,14 @@ export interface MediaSessionCallbacks {
10
10
  export declare class MediaSessionHelper {
11
11
  private _silentAudioElement;
12
12
  get silentAudioElement(): HTMLAudioElement | null;
13
+ /**
14
+ * Create and start the silent audio element without Media Session metadata.
15
+ *
16
+ * On iOS this is load-bearing even in the foreground: pure Web Audio output is
17
+ * silenced by the hardware ringer switch, while a playing media element promotes
18
+ * the audio session to playback category so speech is audible on muted phones.
19
+ */
20
+ ensureSilentPlaybackElement(): void;
13
21
  setup(config: MediaSessionConfig | undefined, callbacks: MediaSessionCallbacks): void;
14
22
  cleanup(): void;
15
23
  }
@@ -13,7 +13,17 @@ export declare const VIDEO_DECODE_CODEC_H264 = "avc1.42E01E";
13
13
  export declare const VIDEO_DECODE_CODEC_VP8 = "vp8";
14
14
  export declare const VIDEO_DECODE_CODEC_VP9 = "vp09.00.10.08";
15
15
  export declare const VIDEO_DECODE_CODEC_AV1 = "av01.0.04M.08";
16
- export declare const VIDEO_CAPTURE_DEFAULT_CODEC_PREFERENCES: readonly ('h264' | 'vp8' | 'vp9' | 'av1')[];
16
+ export type VideoCodecPreference = 'h264' | 'vp8' | 'vp9' | 'av1';
17
+ export declare const VIDEO_CAPTURE_DEFAULT_CODEC_PREFERENCES: readonly VideoCodecPreference[];
18
+ /**
19
+ * The order the capture encoder tries codecs in, given what the caller asked for.
20
+ *
21
+ * The caller's list orders the search; it does not bound it. A browser that cannot encode the
22
+ * app's first choice must still capture — Chromium builds without H.264 are ordinary, and an app
23
+ * naming h264 alone used to leave capture producing nothing at all on them, silently: the encoder
24
+ * resolved nothing, and the only sign was media that never arrived.
25
+ */
26
+ export declare function resolveCodecPreferenceOrder(preferred: VideoCodecPreference[] | undefined): VideoCodecPreference[];
17
27
  export declare const VIDEO_RESOLUTION_FALLBACKS: readonly [{
18
28
  readonly width: 1920;
19
29
  readonly height: 1080;
@@ -1,4 +1,4 @@
1
- import { AudioShapeSet } from '../../../../shared/protocol/src/index.ts';
1
+ import { AudioShapeSet, GlobalState } from '../../shared/protocol/src/index.ts';
2
2
  import { IkonClient } from '../client/ikon-client';
3
3
  /**
4
4
  * Time-synchronized lip-sync / shape-set receiver.
@@ -13,9 +13,11 @@ import { IkonClient } from '../client/ikon-client';
13
13
  * over WebRTC RTP tracks or the SDK's own playback pipeline.
14
14
  */
15
15
  export declare class VisemeTracker {
16
+ private static readonly MAX_WORKER_REBUILD_ATTEMPTS;
16
17
  private readonly client;
17
18
  private worker;
18
19
  private protocolPort;
20
+ private workerRebuildAttempts;
19
21
  private readonly streamShapeSets;
20
22
  private readonly currentShapeSetValues;
21
23
  private readonly visemeBuffers;
@@ -27,6 +29,13 @@ export declare class VisemeTracker {
27
29
  * Idempotent; safe to call once audio is known to be in use.
28
30
  */
29
31
  enable(): void;
32
+ /**
33
+ * Replay active audio stream state from GlobalState into the viseme worker.
34
+ * GlobalState is the server's authoritative stream registry, delivered to every
35
+ * joiner and reconnector — this is how lip-sync recovers mid-utterance after a
36
+ * late join or reconnect. Idempotent: known streams are untouched.
37
+ */
38
+ syncStreamsFromGlobalState(globalState: GlobalState): void;
30
39
  dispose(): void;
31
40
  getShapeSets(streamId: string): AudioShapeSet[] | null;
32
41
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ikonai/sdk",
3
- "version": "1.0.79",
3
+ "version": "1.1.0",
4
4
  "type": "module",
5
5
  "main": "./index.js",
6
6
  "types": "./index.d.ts",
package/storage.d.ts CHANGED
@@ -18,3 +18,16 @@ export declare function clearDeviceId(): void;
18
18
  * Returns null if the token cannot be decoded or doesn't contain an id.
19
19
  */
20
20
  export declare function extractUserIdFromToken(token: string): string | null;
21
+ /**
22
+ * Auth-relevant claims decoded from an Ikon backend JWT.
23
+ */
24
+ export interface AuthTokenClaims {
25
+ userId: string | null;
26
+ authSession: string | null;
27
+ role: string | null;
28
+ }
29
+ /**
30
+ * Extract auth-relevant claims from an Ikon backend JWT (payload fields `id`, `authSession`,
31
+ * `role`). Returns null if the token cannot be decoded.
32
+ */
33
+ export declare function extractAuthClaimsFromToken(token: string): AuthTokenClaims | null;
@@ -1,4 +1,4 @@
1
- import { ProtocolMessage } from '../../../../shared/protocol/src/index.ts';
1
+ import { ProtocolMessage } from '../../shared/protocol/src/index.ts';
2
2
  /**
3
3
  * Transport interface for Ikon server connections.
4
4
  * Designed to support both WebSocket and WebTransport implementations.
@@ -1,4 +1,4 @@
1
- import { ProtocolMessage } from '../../../../shared/protocol/src/index.ts';
1
+ import { ProtocolMessage } from '../../shared/protocol/src/index.ts';
2
2
  import { Transport, TransportConfig } from './transport';
3
3
  /**
4
4
  * WebSocket transport implementation for Ikon server connections.
@@ -1,4 +1,4 @@
1
- import { ProtocolMessage } from '../../../../shared/protocol/src/index.ts';
1
+ import { ProtocolMessage } from '../../shared/protocol/src/index.ts';
2
2
  import { Transport, TransportConfig } from './transport';
3
3
  /**
4
4
  * Check if WebTransport is supported in the current environment.
@@ -1,3 +1,7 @@
1
+ /** Window event dispatched whenever inspect mode flips on, so UI that mounted before the
2
+ * flip (e.g. a boot-snapshot-seeded surface rendering ahead of the client connect that
3
+ * initializes the URL param) can react instead of reading a stale one-shot value. */
4
+ export declare const IKON_INSPECT_MODE_CHANGED_EVENT = "ikon-inspect-mode-changed";
1
5
  export declare function initializeInspectMode(): boolean;
2
6
  export declare function isInspectModeEnabled(): boolean;
3
7
  export declare function enableInspectMode(): void;
@@ -1,3 +1,3 @@
1
- export declare function startLogSender(backendUrl: string, authToken: string, sessionId?: string, channelInstanceId?: string): void;
1
+ export declare function startLogSender(backendUrl: string, authToken: string): void;
2
2
  export declare function sendAnalyticsEvent(eventName: string, parameters: Record<string, string>): void;
3
3
  export declare function stopLogSender(): void;
@@ -3,3 +3,7 @@
3
3
  * Also detects iPadOS which reports as "Macintosh" but has touch support.
4
4
  */
5
5
  export declare const isIOS: () => boolean;
6
+ /**
7
+ * Detect if running on a mobile or tablet device (Android, iOS, and other mobile UAs).
8
+ */
9
+ export declare const isMobileDevice: () => boolean;
@@ -12,8 +12,6 @@
12
12
  * - ikon-debug Enable SDK debug logging (true)
13
13
  * - ikon-lang Override language detection (e.g., "en", "fi")
14
14
  * - ikon-server-url External connect URL for shareable preview links
15
- * - ikon-git-source Enable Git source deployment mode (true)
16
- * - ikon-git-branch Git branch for Git source deployment (e.g., "main")
17
15
  * - ikon-audio Force audio on (true) or off (false)
18
16
  * - ikon-video Force video on (true) or off (false)
19
17
  * - ikon-webrtc Force WebRTC on (true) or off (false)
@@ -22,6 +20,7 @@
22
20
  * - ikon-retry Enable retry loops in auth/channel connect (default true; set false to fail fast)
23
21
  * - ikon-api Route backend API calls through same-origin /ikon/api (default true on deployed apps; false to force direct calls to api.{env}.ikon.live; always off in local dev)
24
22
  * - ikon-snapshot Connect as a build-time snapshot client (true). Sets Context.IsSnapshot so app/Parallax code can branch on snapshot-mode rendering. Dev affordance for tuning the boot-snapshot UI.
23
+ * - ikon-session Join the live app session named by this sessionIdentityHash, bypassing identity resolution. The server publishes the shareable form as GlobalState.SessionUrl. No live session with that hash is an error, never a fresh instance.
25
24
  */
26
25
  export declare const IKON_PARAM_PROXY = "ikon-proxy";
27
26
  export declare const IKON_PARAM_WEBSOCKET = "ikon-websocket";
@@ -29,8 +28,6 @@ export declare const IKON_PARAM_WEBTRANSPORT = "ikon-webtransport";
29
28
  export declare const IKON_PARAM_DEBUG = "ikon-debug";
30
29
  export declare const IKON_PARAM_LANG = "ikon-lang";
31
30
  export declare const IKON_PARAM_SERVER_URL = "ikon-server-url";
32
- export declare const IKON_PARAM_GIT_SOURCE = "ikon-git-source";
33
- export declare const IKON_PARAM_GIT_BRANCH = "ikon-git-branch";
34
31
  export declare const IKON_PARAM_AUDIO = "ikon-audio";
35
32
  export declare const IKON_PARAM_VIDEO = "ikon-video";
36
33
  export declare const IKON_PARAM_WEBRTC = "ikon-webrtc";
@@ -41,6 +38,7 @@ export declare const IKON_PARAM_AUTH = "ikon-auth";
41
38
  export declare const IKON_PARAM_RETRY = "ikon-retry";
42
39
  export declare const IKON_PARAM_API = "ikon-api";
43
40
  export declare const IKON_PARAM_SNAPSHOT = "ikon-snapshot";
41
+ export declare const IKON_PARAM_SESSION = "ikon-session";
44
42
  /**
45
43
  * Set an SDK query parameter in the URL via history.replaceState.
46
44
  */
@@ -83,3 +81,9 @@ export declare function getApiParam(): boolean | null;
83
81
  * the app / Parallax can render in snapshot mode. A dev affordance for tuning the boot-snapshot UI.
84
82
  */
85
83
  export declare function getSnapshotParam(): boolean;
84
+ /**
85
+ * The sessionIdentityHash of a specific live app session to join (`?ikon-session=<hash>`).
86
+ * Bypasses identity resolution: the backend connects to the session that owns this hash, and
87
+ * fails the connect when none is live rather than quietly starting a fresh one.
88
+ */
89
+ export declare function getSessionParam(): string | null;
@@ -0,0 +1,2 @@
1
+ declare const _default: import('vite').UserConfig;
2
+ export default _default;
@@ -1,4 +1,4 @@
1
- import { ProtocolMessage, Opcode, WebRTCTrackMap } from '../../../../shared/protocol/src/index.ts';
1
+ import { ProtocolMessage, Opcode, WebRTCTrackMap } from '../../shared/protocol/src/index.ts';
2
2
  import { WebRTCConnectionState } from './webrtc-connection';
3
3
  export interface WebRTCSignalingConfig {
4
4
  sessionId: number;
@@ -40,6 +40,8 @@ export declare class WebRTCSignaling {
40
40
  disconnect(): void;
41
41
  sendDataChannelMessage(data: ArrayBuffer): void;
42
42
  private audioCaptureStream;
43
+ private audioCaptureConstraints;
44
+ private audioSegmentActive;
43
45
  private videoCaptureStreams;
44
46
  /**
45
47
  * Returns the first active video capture MediaStream, if any.
@@ -54,17 +56,24 @@ export declare class WebRTCSignaling {
54
56
  startAudioCapture(constraints?: MediaTrackConstraints): Promise<void>;
55
57
  startAudioSegment(correlationId?: string): void;
56
58
  endAudioSegment(correlationId?: string): void;
59
+ private acquireAudioTrack;
60
+ private releaseAudioTrack;
57
61
  /**
58
62
  * Communicate the originator's correlation id for a video capture sender to the server-side
59
63
  * WebRtcMediaBridge so the next VideoStreamBegin it emits for this sender carries it.
60
64
  * Called by the video capture path when starting a CaptureButton-initiated stream.
61
65
  */
62
66
  sendVideoCaptureCorrelation(senderIndex: number, correlationId?: string): void;
63
- startVideoCapture(constraints?: MediaTrackConstraints, bitrate?: number, senderIndex?: number, correlationId?: string): Promise<void>;
67
+ startVideoCapture(constraints?: MediaTrackConstraints, bitrate?: number, senderIndex?: number, correlationId?: string): Promise<MediaStream>;
64
68
  startScreenCapture(constraints?: MediaTrackConstraints, bitrate?: number, senderIndex?: number, correlationId?: string): Promise<MediaStream>;
65
69
  stopVideoCapture(senderIndex: number): Promise<void>;
66
70
  private sendVideoStreamBegin;
67
71
  private sendVideoStreamEnd;
72
+ /**
73
+ * Stop only the audio capture side. Video capture (camera, screen share) is left running —
74
+ * ending a push-to-talk session must not tear down an ongoing screen share.
75
+ */
76
+ stopAudioCapture(): void;
68
77
  stopCapture(): Promise<void>;
69
78
  private applyEncodingParams;
70
79
  private sendOffer;
@@ -1,3 +1,4 @@
1
+ import { AudioStreamBegin } from '../../shared/protocol/src/index.ts';
1
2
  export type AudioPlaybackWorkerTransport = 'sab' | 'pcm';
2
3
  export type AudioPlaybackWorkerConfigureMessage = {
3
4
  type: 'configure';
@@ -20,7 +21,19 @@ export type AudioPlaybackWorkerRebindMessage = {
20
21
  export type AudioPlaybackWorkerDisposeMessage = {
21
22
  type: 'dispose';
22
23
  };
23
- export type AudioPlaybackWorkerIn = AudioPlaybackWorkerConfigureMessage | AudioPlaybackWorkerAttachProtocolPortMessage | AudioPlaybackWorkerRebindMessage | AudioPlaybackWorkerDisposeMessage;
24
+ export type AudioPlaybackWorkerSetWebRtcEnabledMessage = {
25
+ type: 'setWebRtcEnabled';
26
+ enabled: boolean;
27
+ };
28
+ export type AudioPlaybackWorkerSyncStreamsMessage = {
29
+ type: 'syncStreams';
30
+ streams: Array<{
31
+ senderId: number;
32
+ trackId: number;
33
+ info: AudioStreamBegin;
34
+ }>;
35
+ };
36
+ export type AudioPlaybackWorkerIn = AudioPlaybackWorkerConfigureMessage | AudioPlaybackWorkerAttachProtocolPortMessage | AudioPlaybackWorkerRebindMessage | AudioPlaybackWorkerDisposeMessage | AudioPlaybackWorkerSetWebRtcEnabledMessage | AudioPlaybackWorkerSyncStreamsMessage;
24
37
  export type AudioPlaybackWorkerOut = {
25
38
  type: 'streamBegin';
26
39
  streamId: string;
@@ -1,4 +1,5 @@
1
- type CodecPreference = 'h264' | 'vp8' | 'vp9' | 'av1';
1
+ import { VideoCodecPreference } from '../media/video-constants';
2
+ type CodecPreference = VideoCodecPreference;
2
3
  type HardwareAcceleration = 'preferHardware' | 'preferSoftware';
3
4
  export type VideoCaptureWorkerOptions = {
4
5
  preferredCodecs?: CodecPreference[];
@@ -8,6 +9,5 @@ export type VideoCaptureWorkerOptions = {
8
9
  bitrate?: number;
9
10
  keyFrameIntervalFrames?: number;
10
11
  hardwareAcceleration?: HardwareAcceleration;
11
- targetIds?: number[];
12
12
  };
13
13
  export {};
@@ -1,4 +1,4 @@
1
- import { VideoCodec } from '../../../../shared/protocol/src/index.ts';
1
+ import { VideoCodec, VideoStreamBegin } from '../../shared/protocol/src/index.ts';
2
2
  export type VideoPlaybackWorkerConfigureMessage = {
3
3
  type: 'configure';
4
4
  webRtcEnabled?: boolean;
@@ -31,7 +31,19 @@ export type VideoPlaybackWorkerSetEnabledMessage = {
31
31
  export type VideoPlaybackWorkerDisposeMessage = {
32
32
  type: 'dispose';
33
33
  };
34
- export type VideoPlaybackWorkerIn = VideoPlaybackWorkerConfigureMessage | VideoPlaybackWorkerAttachProtocolPortMessage | VideoPlaybackWorkerAttachSurfaceMessage | VideoPlaybackWorkerDetachSurfaceMessage | VideoPlaybackWorkerWatchStreamMessage | VideoPlaybackWorkerUnwatchStreamMessage | VideoPlaybackWorkerSetEnabledMessage | VideoPlaybackWorkerDisposeMessage;
34
+ export type VideoPlaybackWorkerSetWebRtcEnabledMessage = {
35
+ type: 'setWebRtcEnabled';
36
+ enabled: boolean;
37
+ };
38
+ export type VideoPlaybackWorkerSyncStreamsMessage = {
39
+ type: 'syncStreams';
40
+ streams: Array<{
41
+ senderId: number;
42
+ trackId: number;
43
+ info: VideoStreamBegin;
44
+ }>;
45
+ };
46
+ export type VideoPlaybackWorkerIn = VideoPlaybackWorkerConfigureMessage | VideoPlaybackWorkerAttachProtocolPortMessage | VideoPlaybackWorkerAttachSurfaceMessage | VideoPlaybackWorkerDetachSurfaceMessage | VideoPlaybackWorkerWatchStreamMessage | VideoPlaybackWorkerUnwatchStreamMessage | VideoPlaybackWorkerSetEnabledMessage | VideoPlaybackWorkerDisposeMessage | VideoPlaybackWorkerSetWebRtcEnabledMessage | VideoPlaybackWorkerSyncStreamsMessage;
35
47
  export type VideoPlaybackWorkerOut = {
36
48
  type: 'streamBegin';
37
49
  streamId: string;
@@ -1,4 +1,4 @@
1
- import { AudioShapeSet, AudioShapeSetValues } from '../../../../shared/protocol/src/index.ts';
1
+ import { AudioShapeSet, AudioShapeSetValues, AudioStreamBegin } from '../../shared/protocol/src/index.ts';
2
2
  export type VisemeWorkerAttachProtocolPortMessage = {
3
3
  type: 'attachProtocolPort';
4
4
  port: MessagePort;
@@ -6,7 +6,15 @@ export type VisemeWorkerAttachProtocolPortMessage = {
6
6
  export type VisemeWorkerDisposeMessage = {
7
7
  type: 'dispose';
8
8
  };
9
- export type VisemeWorkerIn = VisemeWorkerAttachProtocolPortMessage | VisemeWorkerDisposeMessage;
9
+ export type VisemeWorkerSyncStreamsMessage = {
10
+ type: 'syncStreams';
11
+ streams: Array<{
12
+ senderId: number;
13
+ trackId: number;
14
+ info: AudioStreamBegin;
15
+ }>;
16
+ };
17
+ export type VisemeWorkerIn = VisemeWorkerAttachProtocolPortMessage | VisemeWorkerDisposeMessage | VisemeWorkerSyncStreamsMessage;
10
18
  export type VisemeWorkerOut = {
11
19
  type: 'streamBegin';
12
20
  streamId: string;