@qencode/calls 0.2.0 → 0.3.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.
- package/README.md +19 -2
- package/dist/call.d.ts +11 -3
- package/dist/devices.d.ts +58 -2
- package/dist/index.d.ts +1 -1
- package/dist/qencode-calls.esm.bundle.js +7 -7
- package/dist/qencode-calls.esm.bundle.js.map +3 -3
- package/dist/qencode-calls.esm.js +2 -2
- package/dist/qencode-calls.esm.js.map +3 -3
- package/dist/qencode-calls.umd.js +7 -7
- package/dist/qencode-calls.umd.js.map +3 -3
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Low-latency 1:1 audio and video calls inside your own UI. The SDK takes a short-lived
|
|
4
4
|
participant credential minted by **your backend**, connects, renders media into views you
|
|
5
|
-
place, and reports call quality. It ships no screens and no theme. Version 0.
|
|
5
|
+
place, and reports call quality. It ships no screens and no theme. Version 0.3.0, pre-release,
|
|
6
|
+
on npm as [`@qencode/calls`](https://www.npmjs.com/package/@qencode/calls).
|
|
6
7
|
|
|
7
8
|
## Quickstart
|
|
8
9
|
|
|
@@ -72,7 +73,7 @@ which is about 145 KB gzipped on its own.
|
|
|
72
73
|
| `setJitterBufferTarget(ms)` | Pins the receiver's jitter buffer target regardless of the mode. Returns which property took it: `jitterBufferTarget`, `playoutDelayHint`, or `unsupported` (Firefox). |
|
|
73
74
|
| `setVideoEncoding({ codec, simulcast })` | Switches codec or simulcast mid-call; the video track is republished. |
|
|
74
75
|
| `setVideoSource(source \| null)` | Replaces the published video with a custom track or factory, or returns to the camera. See below. |
|
|
75
|
-
| `devices` | `list()`, `setCamera(id)`, `setMicrophone(id)`, `setSpeaker(id)`, `onChange(handler)`, `canSelectSpeaker`. |
|
|
76
|
+
| `devices` | `list()`, `setCamera(id)`, `setCameraFacing('user' \| 'environment')`, `setMicrophone(id)`, `setSpeaker(id)`, `cameraId`, `cameraFacing`, `microphoneId`, `onChange(handler)`, `canSelectSpeaker`. A choice made before `connect()` or while the camera is off is applied when the camera is next published. |
|
|
76
77
|
| `sendMessage(payload, reliable = true)` | Up to 15 KB, 30 per second, to the peer. Strings and JSON objects arrive as sent, `Uint8Array` as bytes. |
|
|
77
78
|
| `stats` | Latest quality snapshot, refreshed every second. |
|
|
78
79
|
| `peer` | Identity, display name and mute state of the other human, or `null`. |
|
|
@@ -108,6 +109,22 @@ bench wants and what a customer UI rarely does.
|
|
|
108
109
|
| `telemetryExtra` | none | `(direction) => fields` appended to every telemetry row; see telemetry. |
|
|
109
110
|
| `forceRelay` | `false` | Connect through TURN only, to measure the relay path. |
|
|
110
111
|
|
|
112
|
+
### Switching cameras
|
|
113
|
+
|
|
114
|
+
On a phone, flip between the front and the rear camera by direction rather than by id:
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
const facing = call.devices.cameraFacing; // 'user', 'environment', or null when unknown
|
|
118
|
+
await call.devices.setCameraFacing(facing === 'user' ? 'environment' : 'user');
|
|
119
|
+
self.toggleAttribute('mirror', call.devices.cameraFacing !== 'environment'); // mirror only a user-facing camera
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Phone browsers honour the direction directly. Elsewhere the SDK falls back to a camera whose
|
|
123
|
+
label says which way it points (`DeviceInfo.facing`, from labels such as "Back Camera" or
|
|
124
|
+
"camera2 0, facing back") and throws `deviceUnavailable` when there is none; a desktop app
|
|
125
|
+
then offers `devices.list().cameras` and calls `setCamera(id)`. Either way the profile's
|
|
126
|
+
resolution is kept, and a later profile switch stays on the chosen camera.
|
|
127
|
+
|
|
111
128
|
### Custom video source
|
|
112
129
|
|
|
113
130
|
Pass `videoSource` to publish something other than the raw camera: a canvas with an overlay or a
|
package/dist/call.d.ts
CHANGED
|
@@ -65,11 +65,18 @@ export interface CallOptions {
|
|
|
65
65
|
endOnPeerLeft?: boolean;
|
|
66
66
|
/**
|
|
67
67
|
* Let the engine adapt what it sends and receives to how the video is displayed (default true).
|
|
68
|
-
* The receiver asks for the layer matching the rendered size
|
|
69
|
-
*
|
|
70
|
-
*
|
|
68
|
+
* The receiver asks for the layer matching the rendered size in device pixels, and the sender
|
|
69
|
+
* encodes only the layers someone is subscribed to. Set false to always receive and send the
|
|
70
|
+
* full profile regardless of how the video is shown, as a measurement bench does.
|
|
71
71
|
*/
|
|
72
72
|
adaptiveStream?: boolean;
|
|
73
|
+
/**
|
|
74
|
+
* With `adaptiveStream`, pause the remote video on the server while the page is hidden (a
|
|
75
|
+
* background tab, a minimized window) and resume it when the page is shown again. Default
|
|
76
|
+
* false: a call keeps its picture flowing so it is there the moment the user comes back, and
|
|
77
|
+
* the peer's encoder never has to restart. Set true to save bandwidth while hidden.
|
|
78
|
+
*/
|
|
79
|
+
pauseVideoInBackground?: boolean;
|
|
73
80
|
/**
|
|
74
81
|
* Publish this track instead of opening the camera: a canvas, a screen, a processed camera. A
|
|
75
82
|
* factory is called with the profile on every publish and republish. The SDK stops a track a
|
|
@@ -213,6 +220,7 @@ export declare class Call {
|
|
|
213
220
|
sendMessage(payload: MessagePayload, reliable?: boolean): Promise<void>;
|
|
214
221
|
private buildRoom;
|
|
215
222
|
private publishOptions;
|
|
223
|
+
/** Profile resolution plus the camera the devices object currently selects (an id, a facing, or the default). */
|
|
216
224
|
private captureOptions;
|
|
217
225
|
private audioCaptureOptions;
|
|
218
226
|
private publishAudio;
|
package/dist/devices.d.ts
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type Room, type VideoCaptureOptions } from 'livekit-client';
|
|
2
|
+
/** Which way a camera points: `user` faces the person, `environment` faces away (the rear camera on a phone). */
|
|
3
|
+
export type CameraFacing = 'user' | 'environment';
|
|
2
4
|
export interface DeviceInfo {
|
|
3
5
|
id: string;
|
|
4
6
|
label: string;
|
|
7
|
+
/** For cameras: which way it points when the label says so (phones do); null when unknown. */
|
|
8
|
+
facing?: CameraFacing | null;
|
|
5
9
|
}
|
|
6
10
|
export interface DeviceList {
|
|
7
11
|
cameras: DeviceInfo[];
|
|
@@ -10,7 +14,10 @@ export interface DeviceList {
|
|
|
10
14
|
}
|
|
11
15
|
/**
|
|
12
16
|
* Device selection. Labels are empty until the first getUserMedia permission is granted; after
|
|
13
|
-
* `connect()` the list is complete.
|
|
17
|
+
* `connect()` the list is complete. A camera or microphone chosen before `connect()` is used
|
|
18
|
+
* when the track is first published; chosen mid-call it is switched in place; chosen while the
|
|
19
|
+
* camera is off it takes effect when the camera is turned back on. Speaker selection needs
|
|
20
|
+
* `setSinkId`, which Safari lacks.
|
|
14
21
|
*/
|
|
15
22
|
export declare class Devices {
|
|
16
23
|
private readonly emitter;
|
|
@@ -18,11 +25,35 @@ export declare class Devices {
|
|
|
18
25
|
private readonly audioElements;
|
|
19
26
|
private speakerId;
|
|
20
27
|
private customVideo;
|
|
28
|
+
private cameraIdValue;
|
|
29
|
+
private microphoneIdValue;
|
|
30
|
+
/** A facing request not yet turned into a concrete device id. */
|
|
31
|
+
private facingWish;
|
|
32
|
+
/** True when a camera choice is waiting for the camera to be published or unmuted. */
|
|
33
|
+
private pending;
|
|
34
|
+
private captureOptions;
|
|
21
35
|
private readonly onDeviceChange;
|
|
22
36
|
/** @internal */
|
|
23
37
|
_attachRoom(room: Room | null): void;
|
|
24
38
|
/** @internal The call publishes a custom video source, so the engine must not replace it with a camera. */
|
|
25
39
|
_setCustomVideo(on: boolean): void;
|
|
40
|
+
/** @internal Initial ids from CallOptions. */
|
|
41
|
+
_setInitial(cameraId?: string, microphoneId?: string): void;
|
|
42
|
+
/** @internal The call's capture options (profile resolution plus the selection below), used to restart the camera. */
|
|
43
|
+
_setCaptureOptions(fn: () => VideoCaptureOptions): void;
|
|
44
|
+
/**
|
|
45
|
+
* @internal The camera selection part of the capture constraints. A chosen id is exact: a
|
|
46
|
+
* preference lets the browser keep the camera it already has (Chrome does when the other one
|
|
47
|
+
* takes a moment to wake, as a phone used as a webcam does). A facing stays a preference so
|
|
48
|
+
* desktops, which cannot honour it, do not fail.
|
|
49
|
+
*/
|
|
50
|
+
_videoSelection(): Pick<VideoCaptureOptions, 'deviceId' | 'facingMode'>;
|
|
51
|
+
/** @internal The chosen camera could not be opened at publish time; fall back to the default one. */
|
|
52
|
+
_clearCamera(): void;
|
|
53
|
+
/** @internal */
|
|
54
|
+
_microphoneSelection(): string | undefined;
|
|
55
|
+
/** @internal Called by the call when the camera is (re)published or unmuted: applies a deferred choice and records what is in use. */
|
|
56
|
+
_cameraPublished(): Promise<void>;
|
|
26
57
|
/** @internal */
|
|
27
58
|
_registerAudioElement(el: HTMLMediaElement): void;
|
|
28
59
|
/** @internal */
|
|
@@ -31,10 +62,35 @@ export declare class Devices {
|
|
|
31
62
|
_stop(): void;
|
|
32
63
|
list(): Promise<DeviceList>;
|
|
33
64
|
get canSelectSpeaker(): boolean;
|
|
65
|
+
/** The camera in use, or the one chosen for when the camera is next published; null for the system default. */
|
|
66
|
+
get cameraId(): string | null;
|
|
67
|
+
get microphoneId(): string | null;
|
|
68
|
+
/** Which way the camera in use points, when the browser says (phones do); otherwise the last facing asked for, or null. */
|
|
69
|
+
get cameraFacing(): CameraFacing | null;
|
|
70
|
+
/** Use this camera: now when it is published and on, otherwise as soon as it is. */
|
|
34
71
|
setCamera(deviceId: string): Promise<void>;
|
|
72
|
+
/**
|
|
73
|
+
* Use the camera that faces the given way: the front (`user`) or the rear (`environment`)
|
|
74
|
+
* camera on a phone. Browsers on phones honour the request directly; elsewhere a camera whose
|
|
75
|
+
* label says which way it points is used, and `deviceUnavailable` is thrown when there is none.
|
|
76
|
+
*/
|
|
77
|
+
setCameraFacing(mode: CameraFacing): Promise<void>;
|
|
35
78
|
setMicrophone(deviceId: string): Promise<void>;
|
|
36
79
|
setSpeaker(deviceId: string): Promise<void>;
|
|
37
80
|
onChange(handler: (list: DeviceList) => void): () => void;
|
|
81
|
+
/**
|
|
82
|
+
* Records a selection and restarts the published, unmuted camera with it. Returns false when
|
|
83
|
+
* that has to wait. The engine stops the old capture before it opens the new one, so when the
|
|
84
|
+
* new camera cannot be opened the previous selection is put back and reopened, and the call
|
|
85
|
+
* keeps its picture; the failure is still thrown.
|
|
86
|
+
*/
|
|
87
|
+
private select;
|
|
88
|
+
private syncFromTrack;
|
|
89
|
+
private cameraTrack;
|
|
90
|
+
private trackSettings;
|
|
91
|
+
private refuseIfCustomVideo;
|
|
38
92
|
private switch;
|
|
39
93
|
private applySink;
|
|
40
94
|
}
|
|
95
|
+
/** Phones label their cameras by direction ("Back Camera", "camera2 0, facing back"); desktops rarely do. */
|
|
96
|
+
export declare function facingFromLabel(label: string): CameraFacing | null;
|
package/dist/index.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ export type { VideoProfileName, VideoProfile } from './profiles';
|
|
|
10
10
|
export { LATENCY_SETTINGS, DEFAULT_LATENCY_MODE } from './latency';
|
|
11
11
|
export type { LatencyMode, LatencySettings } from './latency';
|
|
12
12
|
export type { CallStats, RecvStats, SendStats, Quality, Direction, Transport, CandidateType, AudioRoute } from './stats';
|
|
13
|
-
export type { DeviceInfo, DeviceList } from './devices';
|
|
13
|
+
export type { DeviceInfo, DeviceList, CameraFacing } from './devices';
|
|
14
14
|
export type { VideoHandle } from './render';
|
|
15
15
|
export { QencodeVideoElement, registerVideoElement } from './render';
|
|
16
16
|
export { SDK_VERSION } from './version';
|