@streaming-cdn/rtc-web 1.3.14 → 1.3.16
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 +70 -1
- package/dist/avatar-rig.d.ts +63 -0
- package/dist/avatar.d.ts +88 -0
- package/dist/call-recorder.d.ts +48 -0
- package/dist/index.d.ts +9 -1
- package/dist/rtc-web.es.js +641 -277
- package/dist/rtc-web.umd.js +1 -1
- package/dist/video-effects.d.ts +46 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# RTC Web SDK 1.3.
|
|
1
|
+
# RTC Web SDK 1.3.16
|
|
2
2
|
|
|
3
3
|
The customer package contains compiled ESM/UMD JavaScript and TypeScript declarations. It intentionally excludes implementation source and source maps. Example source remains available under `examples/`.
|
|
4
4
|
|
|
@@ -169,6 +169,75 @@ the room client (`getNativeClient()`); the publisher keeps sending every
|
|
|
169
169
|
layer. The React Native adapter has the same transport option and the same
|
|
170
170
|
`setRemoteQuality` on the client.
|
|
171
171
|
|
|
172
|
+
## Virtual backgrounds and effects
|
|
173
|
+
|
|
174
|
+
`createVideoEffectsPipeline(cameraTrack)` draws the camera through a canvas
|
|
175
|
+
and hands back a processed track for `setVideoTrack`, so both transports
|
|
176
|
+
publish it unchanged. Backgrounds: `blur`, animated procedural scenes
|
|
177
|
+
(`aurora`, `cybergrid`, `bokeh`, `sunset`), or your own `image`. Overlays:
|
|
178
|
+
`snow`, `confetti`, `vignette`. Person cut-out uses any `Segmenter` you plug
|
|
179
|
+
in (for example a self-hosted MediaPipe selfie model); without one the
|
|
180
|
+
pipeline degrades honestly — `blur` blurs the whole frame, scenes show the
|
|
181
|
+
camera as a floating card.
|
|
182
|
+
|
|
183
|
+
```ts
|
|
184
|
+
const effects = createVideoEffectsPipeline(cameraTrack, { segmenter });
|
|
185
|
+
effects.setBackground("aurora");
|
|
186
|
+
effects.setOverlay("confetti");
|
|
187
|
+
await media.setVideoTrack(effects.track);
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## Virtual avatar
|
|
191
|
+
|
|
192
|
+
`createAvatarPipeline(cameraTrack, { tracker })` analyzes the person on-device
|
|
193
|
+
and publishes an animated avatar instead of the camera — blink, gaze, brows,
|
|
194
|
+
jaw, mouth and head pose all mirror the real face. The output is an ordinary
|
|
195
|
+
canvas track for `setVideoTrack`, so both transports carry it unchanged and
|
|
196
|
+
the camera never leaves the machine.
|
|
197
|
+
|
|
198
|
+
Face perception is pluggable: supply any `FaceTracker` (for example a
|
|
199
|
+
self-hosted MediaPipe Face Landmarker emitting the 52 ARKit-style blendshape
|
|
200
|
+
coefficients). Rendering is pluggable the same way — the built-in stylized
|
|
201
|
+
renderer needs no assets, and a custom `AvatarRenderer` can draw a VRM
|
|
202
|
+
character or anything else from the same `AvatarRig`.
|
|
203
|
+
|
|
204
|
+
Two modes: `replace` (avatar on a backdrop) and `overlay` (avatar anchored to
|
|
205
|
+
the tracked head over the live camera). Client environments differ, so the
|
|
206
|
+
perception constants are an open `tuning` surface, adjustable live:
|
|
207
|
+
|
|
208
|
+
```ts
|
|
209
|
+
const avatar = createAvatarPipeline(cameraTrack, {
|
|
210
|
+
tracker, // your FaceTracker
|
|
211
|
+
mode: "replace",
|
|
212
|
+
tuning: { mouthGain: 1.7, eyeSync: 1, smoothing: 0.4 }
|
|
213
|
+
});
|
|
214
|
+
await media.setVideoTrack(avatar.track);
|
|
215
|
+
avatar.setTuning({ mouthGain: 2 }); // cameras differ; correct per deployment
|
|
216
|
+
avatar.setMode("overlay");
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
`AvatarTuning` covers `mouthGain`, `blinkGain`, `eyeSync` (evens the lids in
|
|
220
|
+
profile, where per-eye data drifts), `smoothing`, `avatarScale`, `avatarLift`
|
|
221
|
+
and `lostHoldMs` (losing the face holds the pose and eases the expression to
|
|
222
|
+
rest instead of snapping to neutral).
|
|
223
|
+
|
|
224
|
+
## Call recording
|
|
225
|
+
|
|
226
|
+
`createCallRecorder(media.getNativeClient(), { credential })` composites every
|
|
227
|
+
participant's video onto a canvas, mixes all audio, records with
|
|
228
|
+
MediaRecorder, and on `stop()` uploads the file with the room signaling token.
|
|
229
|
+
The platform stores it, bills the storage, lists it under
|
|
230
|
+
`GET /v1/rtc/recordings` (Server API), and serves it from
|
|
231
|
+
`GET /v1/rtc/recordings/{id}/download`. Recording happens on this client —
|
|
232
|
+
what is recorded is what this participant saw and heard.
|
|
233
|
+
|
|
234
|
+
```ts
|
|
235
|
+
const recorder = createCallRecorder(media.getNativeClient(), { credential });
|
|
236
|
+
await recorder.start();
|
|
237
|
+
// ... later
|
|
238
|
+
const { recordingId, durationSeconds } = await recorder.stop();
|
|
239
|
+
```
|
|
240
|
+
|
|
172
241
|
## Active speaker
|
|
173
242
|
|
|
174
243
|
The client samples WebRTC audio levels once a second on both transports and
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Face blendshapes → avatar rig.
|
|
3
|
+
*
|
|
4
|
+
* MediaPipe's Face Landmarker emits 52 ARKit-style blendshape coefficients
|
|
5
|
+
* and a facial transformation matrix. This module reduces them to the small
|
|
6
|
+
* rig a stylized avatar needs, as pure functions — the experimental Avatar
|
|
7
|
+
* Lab draws from this rig, and a future VRM renderer can consume the same
|
|
8
|
+
* values. Keeping it pure keeps it testable without a camera.
|
|
9
|
+
*/
|
|
10
|
+
export interface BlendshapeCategory {
|
|
11
|
+
categoryName: string;
|
|
12
|
+
score: number;
|
|
13
|
+
}
|
|
14
|
+
export interface AvatarRig {
|
|
15
|
+
/** 0 open .. 1 closed */
|
|
16
|
+
blinkLeft: number;
|
|
17
|
+
blinkRight: number;
|
|
18
|
+
/** 0 shut .. 1 wide open */
|
|
19
|
+
jawOpen: number;
|
|
20
|
+
/** -1 frown .. 1 smile */
|
|
21
|
+
smile: number;
|
|
22
|
+
/** 0 rest .. 1 raised */
|
|
23
|
+
browUp: number;
|
|
24
|
+
/** -1 left .. 1 right (viewer's perspective) */
|
|
25
|
+
pupilX: number;
|
|
26
|
+
/** -1 up .. 1 down */
|
|
27
|
+
pupilY: number;
|
|
28
|
+
/** radians */
|
|
29
|
+
headYaw: number;
|
|
30
|
+
headPitch: number;
|
|
31
|
+
headRoll: number;
|
|
32
|
+
/** whether a face was tracked at all */
|
|
33
|
+
tracked: boolean;
|
|
34
|
+
}
|
|
35
|
+
export declare function neutralRig(): AvatarRig;
|
|
36
|
+
/**
|
|
37
|
+
* The 4x4 facial transformation matrix is column-major. Yaw/pitch/roll are
|
|
38
|
+
* extracted for a Y-up, viewer-facing convention; angles are what an avatar
|
|
39
|
+
* head joint wants directly.
|
|
40
|
+
*/
|
|
41
|
+
export declare function headPoseFromMatrix(matrix: ArrayLike<number> | null | undefined): {
|
|
42
|
+
yaw: number;
|
|
43
|
+
pitch: number;
|
|
44
|
+
roll: number;
|
|
45
|
+
};
|
|
46
|
+
export declare function rigFromBlendshapes(categories: BlendshapeCategory[] | null | undefined, matrix?: ArrayLike<number> | null, eyeSyncStrength?: number): AvatarRig;
|
|
47
|
+
/**
|
|
48
|
+
* Exponential smoothing between detector ticks so the avatar renders
|
|
49
|
+
* smoothly even when detection runs slower than the paint loop.
|
|
50
|
+
*/
|
|
51
|
+
export declare function smoothRig(previous: AvatarRig, next: AvatarRig, alpha?: number): AvatarRig;
|
|
52
|
+
/** Where to draw the head when compositing over a real frame. */
|
|
53
|
+
export interface AvatarAnchor {
|
|
54
|
+
x: number;
|
|
55
|
+
y: number;
|
|
56
|
+
radius: number;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Draws the built-in stylized avatar. Pure canvas drawing, no assets. With an
|
|
60
|
+
* anchor the head is drawn over whatever is already on the canvas — the
|
|
61
|
+
* keep-real-background mode — otherwise it paints its own backdrop.
|
|
62
|
+
*/
|
|
63
|
+
export declare function drawAvatar(ctx: CanvasRenderingContext2D, rig: AvatarRig, width: number, height: number, anchor?: AvatarAnchor): void;
|
package/dist/avatar.d.ts
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Virtual avatar pipeline.
|
|
3
|
+
*
|
|
4
|
+
* Same shape as the video-effects pipeline: the camera is analyzed on-device,
|
|
5
|
+
* an avatar canvas is captured as a MediaStreamTrack, and that track feeds the
|
|
6
|
+
* existing `setVideoTrack` — every transport (mesh or SFU) publishes the
|
|
7
|
+
* avatar without knowing it exists, and the network sees an ordinary video
|
|
8
|
+
* track.
|
|
9
|
+
*
|
|
10
|
+
* Face perception is an application asset, not an SDK constant: the pipeline
|
|
11
|
+
* takes any `FaceTracker` (the platform meeting room supplies a self-hosted
|
|
12
|
+
* MediaPipe Face Landmarker). Without a tracker the avatar idles untracked
|
|
13
|
+
* rather than pretending. Rendering is pluggable the same way: the built-in
|
|
14
|
+
* stylized renderer needs no assets, and a custom `AvatarRenderer` can draw
|
|
15
|
+
* anything driven by the same rig (the platform's VRM character renderer is
|
|
16
|
+
* exactly that).
|
|
17
|
+
*
|
|
18
|
+
* Client environments differ — cameras, lighting, faces — so every perception
|
|
19
|
+
* constant that needed hand-tuning during development is exposed in
|
|
20
|
+
* `AvatarTuning` and adjustable live via `setTuning`.
|
|
21
|
+
*/
|
|
22
|
+
import { type AvatarAnchor, type AvatarRig, type BlendshapeCategory } from "./avatar-rig";
|
|
23
|
+
export interface FaceTrackerResult {
|
|
24
|
+
/** MediaPipe-style blendshape categories; null/empty means no face. */
|
|
25
|
+
categories: BlendshapeCategory[] | null;
|
|
26
|
+
/** Column-major 4x4 facial transformation matrix, when available. */
|
|
27
|
+
matrix?: ArrayLike<number> | null;
|
|
28
|
+
/** Normalized (0..1) face landmarks, used to anchor overlay mode. */
|
|
29
|
+
landmarks?: Array<{
|
|
30
|
+
x: number;
|
|
31
|
+
y: number;
|
|
32
|
+
}> | null;
|
|
33
|
+
}
|
|
34
|
+
export interface FaceTracker {
|
|
35
|
+
detect(frame: CanvasImageSource, timestampMs: number): FaceTrackerResult | null;
|
|
36
|
+
close?(): void;
|
|
37
|
+
}
|
|
38
|
+
export interface AvatarRenderer {
|
|
39
|
+
/** Draws the rig. `anchor` is set in overlay mode, null in replace mode. */
|
|
40
|
+
render(ctx: CanvasRenderingContext2D, rig: AvatarRig, width: number, height: number, anchor: AvatarAnchor | null): void;
|
|
41
|
+
dispose?(): void;
|
|
42
|
+
}
|
|
43
|
+
/** `replace`: avatar on a backdrop. `overlay`: avatar over the live camera, anchored to the tracked head. */
|
|
44
|
+
export type AvatarMode = "replace" | "overlay";
|
|
45
|
+
export interface AvatarTuning {
|
|
46
|
+
/** jawOpen multiplier — detectors top out well below 1 for a wide-open mouth. */
|
|
47
|
+
mouthGain: number;
|
|
48
|
+
/** Blink coefficient multiplier. */
|
|
49
|
+
blinkGain: number;
|
|
50
|
+
/** 0 off .. 1 full evening of the lids in profile (per-eye data drifts at high yaw). */
|
|
51
|
+
eyeSync: number;
|
|
52
|
+
/** Detector→rig easing per frame; lower is smoother but laggier. */
|
|
53
|
+
smoothing: number;
|
|
54
|
+
/** Avatar size relative to the tracked head (overlay mode). */
|
|
55
|
+
avatarScale: number;
|
|
56
|
+
/** Vertical offset in head radii, positive is down (overlay mode). */
|
|
57
|
+
avatarLift: number;
|
|
58
|
+
/** After this many ms without a face, the expression eases to rest (pose is held). */
|
|
59
|
+
lostHoldMs: number;
|
|
60
|
+
}
|
|
61
|
+
export declare const AVATAR_TUNING_DEFAULTS: AvatarTuning;
|
|
62
|
+
export interface AvatarPipelineOptions {
|
|
63
|
+
width?: number;
|
|
64
|
+
height?: number;
|
|
65
|
+
frameRate?: number;
|
|
66
|
+
tracker?: FaceTracker | null;
|
|
67
|
+
renderer?: AvatarRenderer | null;
|
|
68
|
+
mode?: AvatarMode;
|
|
69
|
+
tuning?: Partial<AvatarTuning>;
|
|
70
|
+
/** Backdrop color for replace mode. */
|
|
71
|
+
backdrop?: string;
|
|
72
|
+
document?: Document;
|
|
73
|
+
}
|
|
74
|
+
export interface AvatarPipeline {
|
|
75
|
+
readonly track: MediaStreamTrack;
|
|
76
|
+
readonly stream: MediaStream;
|
|
77
|
+
/** The current smoothed rig — read-only, useful for meters and debugging. */
|
|
78
|
+
getRig(): AvatarRig;
|
|
79
|
+
setMode(mode: AvatarMode): void;
|
|
80
|
+
setTracker(tracker: FaceTracker | null): void;
|
|
81
|
+
setRenderer(renderer: AvatarRenderer | null): void;
|
|
82
|
+
setTuning(partial: Partial<AvatarTuning>): void;
|
|
83
|
+
getTuning(): AvatarTuning;
|
|
84
|
+
dispose(): void;
|
|
85
|
+
}
|
|
86
|
+
/** The built-in stylized renderer: pure canvas, no assets, no licensing. */
|
|
87
|
+
export declare function stylizedAvatarRenderer(): AvatarRenderer;
|
|
88
|
+
export declare function createAvatarPipeline(source: MediaStreamTrack | MediaStream, options?: AvatarPipelineOptions): AvatarPipeline;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client-side call recording.
|
|
3
|
+
*
|
|
4
|
+
* The mesh has no server with access to the media, so the first recorder that
|
|
5
|
+
* can exist lives where the media already is: this client. It composites every
|
|
6
|
+
* video tile onto a canvas, mixes every audio track, records the result with
|
|
7
|
+
* MediaRecorder, and uploads the finished file with the room signaling token.
|
|
8
|
+
* The platform bills and purges the stored file through the same
|
|
9
|
+
* `rtc_recordings` rows a future server-side recorder will use.
|
|
10
|
+
*/
|
|
11
|
+
export interface RecordableRoomClient {
|
|
12
|
+
getRemoteStreams(): Array<{
|
|
13
|
+
participant: {
|
|
14
|
+
participantId: string;
|
|
15
|
+
displayName: string;
|
|
16
|
+
};
|
|
17
|
+
stream: MediaStream;
|
|
18
|
+
}>;
|
|
19
|
+
getLocalStream(): MediaStream | null;
|
|
20
|
+
}
|
|
21
|
+
export interface CallRecorderOptions {
|
|
22
|
+
credential: {
|
|
23
|
+
signalingToken: string;
|
|
24
|
+
signalingUrl: string;
|
|
25
|
+
};
|
|
26
|
+
/** Canvas output height; width follows 16:9. Default 720. */
|
|
27
|
+
height?: number;
|
|
28
|
+
mimeType?: string;
|
|
29
|
+
/** Test seams. */
|
|
30
|
+
document?: Document;
|
|
31
|
+
mediaRecorderFactory?: (stream: MediaStream, options: {
|
|
32
|
+
mimeType: string;
|
|
33
|
+
}) => MediaRecorder;
|
|
34
|
+
fetchImplementation?: typeof fetch;
|
|
35
|
+
}
|
|
36
|
+
export interface CallRecorderResult {
|
|
37
|
+
recordingId: string;
|
|
38
|
+
sizeBytes: number;
|
|
39
|
+
durationSeconds: number;
|
|
40
|
+
}
|
|
41
|
+
export interface CallRecorder {
|
|
42
|
+
readonly recording: boolean;
|
|
43
|
+
start(): Promise<void>;
|
|
44
|
+
/** Stops, uploads, and marks the recording ready. */
|
|
45
|
+
stop(): Promise<CallRecorderResult>;
|
|
46
|
+
dispose(): void;
|
|
47
|
+
}
|
|
48
|
+
export declare function createCallRecorder(client: RecordableRoomClient, options: CallRecorderOptions): CallRecorder;
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,14 @@ export { createPictureInPictureController } from "./picture-in-picture";
|
|
|
2
2
|
export type { PictureInPictureController, PictureInPictureOptions } from "./picture-in-picture";
|
|
3
3
|
export { pickActiveSpeaker, SPEAKER_NOISE_FLOOR, SPEAKER_TAKEOVER_RATIO } from "./active-speaker";
|
|
4
4
|
export type { SpeakerLevel } from "./active-speaker";
|
|
5
|
+
export { createCallRecorder } from "./call-recorder";
|
|
6
|
+
export type { CallRecorder, CallRecorderOptions, CallRecorderResult } from "./call-recorder";
|
|
7
|
+
export { BACKGROUND_PRESETS, createVideoEffectsPipeline, OVERLAY_EFFECTS, scenePainters } from "./video-effects";
|
|
8
|
+
export type { BackgroundPreset, OverlayEffect, Segmenter, VideoEffectsOptions, VideoEffectsPipeline } from "./video-effects";
|
|
9
|
+
export { AVATAR_TUNING_DEFAULTS, createAvatarPipeline, stylizedAvatarRenderer } from "./avatar";
|
|
10
|
+
export type { AvatarMode, AvatarPipeline, AvatarPipelineOptions, AvatarRenderer, AvatarTuning, FaceTracker, FaceTrackerResult } from "./avatar";
|
|
11
|
+
export { drawAvatar, headPoseFromMatrix, neutralRig, rigFromBlendshapes, smoothRig } from "./avatar-rig";
|
|
12
|
+
export type { AvatarAnchor, AvatarRig, BlendshapeCategory } from "./avatar-rig";
|
|
5
13
|
export type RtcMode = "voice" | "video" | "meeting";
|
|
6
14
|
/**
|
|
7
15
|
* How media travels. `mesh` (the default) opens one connection per pair and
|
|
@@ -338,4 +346,4 @@ export declare class RtcIncomingClient extends EventTarget {
|
|
|
338
346
|
private emit;
|
|
339
347
|
}
|
|
340
348
|
export declare function createRtcIncomingClient(options: RtcIncomingClientOptions): RtcIncomingClient;
|
|
341
|
-
export declare const version = "1.3.
|
|
349
|
+
export declare const version = "1.3.16";
|