@voltkit-rtc/client 0.3.0 → 0.5.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/CHANGELOG.md +110 -0
- package/README.md +196 -24
- package/dist/cjs/chat.d.ts +2 -0
- package/dist/cjs/chat.d.ts.map +1 -1
- package/dist/cjs/chat.js +23 -4
- package/dist/cjs/chat.js.map +1 -1
- package/dist/cjs/device.d.ts +85 -0
- package/dist/cjs/device.d.ts.map +1 -0
- package/dist/cjs/device.js +134 -0
- package/dist/cjs/device.js.map +1 -0
- package/dist/cjs/index.d.ts +212 -6
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +822 -52
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/music.d.ts +1 -1
- package/dist/cjs/music.d.ts.map +1 -1
- package/dist/cjs/quality.d.ts +43 -16
- package/dist/cjs/quality.d.ts.map +1 -1
- package/dist/cjs/quality.js +81 -31
- package/dist/cjs/quality.js.map +1 -1
- package/dist/cjs/stats.d.ts +151 -0
- package/dist/cjs/stats.d.ts.map +1 -0
- package/dist/cjs/stats.js +243 -0
- package/dist/cjs/stats.js.map +1 -0
- package/dist/esm/chat.d.ts +2 -0
- package/dist/esm/chat.d.ts.map +1 -1
- package/dist/esm/chat.js +23 -4
- package/dist/esm/chat.js.map +1 -1
- package/dist/esm/device.d.ts +85 -0
- package/dist/esm/device.d.ts.map +1 -0
- package/dist/esm/device.js +122 -0
- package/dist/esm/device.js.map +1 -0
- package/dist/esm/index.d.ts +212 -6
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +823 -53
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/music.d.ts +1 -1
- package/dist/esm/music.d.ts.map +1 -1
- package/dist/esm/quality.d.ts +43 -16
- package/dist/esm/quality.d.ts.map +1 -1
- package/dist/esm/quality.js +76 -31
- package/dist/esm/quality.js.map +1 -1
- package/dist/esm/stats.d.ts +151 -0
- package/dist/esm/stats.d.ts.map +1 -0
- package/dist/esm/stats.js +232 -0
- package/dist/esm/stats.js.map +1 -0
- package/package.json +1 -1
- package/src/chat.ts +21 -4
- package/src/device.ts +168 -0
- package/src/index.ts +879 -58
- package/src/music.ts +1 -1
- package/src/quality.ts +96 -32
- package/src/stats.ts +328 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,115 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.5.0
|
|
4
|
+
|
|
5
|
+
- All video tiers included by default: 1080p, 720p and 480p. Per-project restrictions still apply.
|
|
6
|
+
- Authoritative 30 fps ladder: 6/3/1.2 Mbps top layers, 1080p lower layers 0.4/2 Mbps, 720p lower layers 0.2/0.8 Mbps. Phone/tablet defaults remain two layers.
|
|
7
|
+
- `PublishOptions.frameRate` and `setVideoFrameRate(30 | 60)`. At 60 fps only the top layer rises to 9/4.5/1.8 Mbps; smaller layers stay at 30. Low capture fps or sustained device/upload limitation falls back to 30 with `frame-rate-fallback` on `error`.
|
|
8
|
+
- Camera start bitrate is 2000 kbps.
|
|
9
|
+
- The 60 fps monitor allows encoder/bitrate warm-up before counting sustained limitation, so the intentional 30 fps lower layers during startup do not immediately trigger fallback.
|
|
10
|
+
- `publishScreen` / `unpublishScreen`, `ScreenPublishOptions`, `screenShareStarted` / `screenShareEnded`, separate `screen-audio`, native-size detail/motion ladders and reconnect restoration. Screen, camera, mic and music controls remain independent. Browser stop-sharing and interrupted capture clean up both screen producers.
|
|
11
|
+
- `setReceiveQuality(producerId, 'auto' | '1080p' | '720p' | '480p')`, `ReceiveQuality` and producer `videoLayers` metadata. Presets follow actual dimensions; Auto clears both layer ceilings; reconnect restores the choice. Older publishers without metadata report `quality-unavailable` for explicit presets.
|
|
12
|
+
- Same-size `replaceVideoTrack` stays smooth. A change in dimensions republishes camera video so advertised layer dimensions remain accurate.
|
|
13
|
+
- `raiseHand(metadata?)`, `lowerHand(identity?)`, hand-event metadata/reason and roster `handMetadata` support role requests and moderated responses.
|
|
14
|
+
- `participantMuted` normalizes moderation locks to `{ identity, kind, paused }`; `ParticipantInfo.videoBlocked` seeds camera locks on reconnect. Demotion while disconnected releases retained capture, and rejected unmute calls keep the device paused.
|
|
15
|
+
- A screen-share republish that fails halfway cleans up that share while the camera continues.
|
|
16
|
+
- No package publishing is part of this source update.
|
|
17
|
+
|
|
18
|
+
## 0.4.0
|
|
19
|
+
|
|
20
|
+
Sharper video, above all from phones. Nothing to change to upgrade: every 0.3.0
|
|
21
|
+
call works as before, with new defaults.
|
|
22
|
+
|
|
23
|
+
- **Higher bitrates.** Each layer gets about 4 Mbps at 1080p, 2.5 Mbps at
|
|
24
|
+
720p, 1.5 Mbps at 540p, 1 Mbps at 480p, 700 kbps at 360p and 400 kbps at
|
|
25
|
+
240p (were 2.5 Mbps, 1.8 Mbps, 1.2 Mbps, 750, 600 and 250 kbps). At 720p
|
|
26
|
+
that brought VP8's quantiser down from about 64 to 55: finer detail, most
|
|
27
|
+
of all in motion. A new stream's bandwidth estimate starts at 1.5 Mbps (was
|
|
28
|
+
1 Mbps). The service's per-publisher caps rose to match (4 Mbps up to 720p,
|
|
29
|
+
7 Mbps with 1080p), and viewers of 720p now start on the top layer instead
|
|
30
|
+
of taking about 15 s to climb to it.
|
|
31
|
+
- **Phones keep the full picture.** New `PublishOptions.layers` (1, 2 or 3).
|
|
32
|
+
Phones and tablets now send two layers (half and full size) by default,
|
|
33
|
+
computers three as before. A busy phone shrinks its picture and then sends
|
|
34
|
+
fewer layers, dropping the top one: from three, viewers of a 720p phone got
|
|
35
|
+
180×320; from two, the full picture survives.
|
|
36
|
+
- **H.264 on phones.** New `PublishOptions.codec`: `'auto'` (the default)
|
|
37
|
+
sends H.264 on phones and tablets that encode it in hardware and VP8
|
|
38
|
+
everywhere else; `'vp8'` and `'h264'` force one. If H.264 cannot be used,
|
|
39
|
+
VP8 is sent and the publish goes on; a forced `'h264'` that falls back also
|
|
40
|
+
fires `error`. A viewer whose browser cannot decode H.264 (rare: a few
|
|
41
|
+
browser builds leave it out) cannot watch a phone sending it: force `'vp8'`
|
|
42
|
+
if your audience uses such browsers.
|
|
43
|
+
- New `PublishOptions.degradationPreference`: what the encoder gives up first
|
|
44
|
+
on a busy device. Unset leaves the browser's default.
|
|
45
|
+
- **`getVideoStats()`**: what the camera is sending, layer by layer, and why
|
|
46
|
+
it is less than asked (`qualityLimitation`: `cpu` is the device,
|
|
47
|
+
`bandwidth` the upload). **`getReceiveStats(producerId)`**: what this client
|
|
48
|
+
receives of someone's video.
|
|
49
|
+
- **`videoLimited` event**: the camera video is being held back by the device
|
|
50
|
+
(`cpu`), the upload (`bandwidth`) or something else (`other`), or that has
|
|
51
|
+
cleared (`none`). It fires once a reason has held for about 4 s, and is
|
|
52
|
+
checked only while you listen. Tell the publisher, so they know it is their
|
|
53
|
+
device or connection.
|
|
54
|
+
- **`replaceVideoTrack(track)`**: send another video track, such as a canvas
|
|
55
|
+
with effects or the raw camera again. Viewers see no pause when the new
|
|
56
|
+
track takes the same layers. Your own stream is never modified, and a
|
|
57
|
+
track replaced while the camera was paused comes back to you switched on.
|
|
58
|
+
- **`setPreferredLayers(producerId, spatialLayer, temporalLayer?)`**: receive
|
|
59
|
+
a smaller copy of someone's video for a small tile, as the Flutter and
|
|
60
|
+
native SDKs already could. Layer 0 is the smallest copy sent; at 720p the
|
|
61
|
+
640×360 copy needs about 0.76 Mbps instead of 2.6 for the full picture. The
|
|
62
|
+
choice is kept across reconnects and forgotten when the track ends.
|
|
63
|
+
- `setVideoQuality`, `replaceVideoTrack` and publishing now change the camera
|
|
64
|
+
producer one at a time, so quick changes cannot leave two of them, and an
|
|
65
|
+
`unpublish()` in the middle of one leaves none.
|
|
66
|
+
- Upload needed rises with the bitrates: about 3.4 Mbps for 720p from a
|
|
67
|
+
computer (3.2 from a phone), 6 Mbps for 1080p (5.5 from a phone) and
|
|
68
|
+
1.4 Mbps for 480p.
|
|
69
|
+
- New exports: the `LayerCount`, `CodecPreference`, `VideoSendStats`,
|
|
70
|
+
`VideoLayerStats`, `VideoReceiveStats`, `VideoLimitedEvent` and
|
|
71
|
+
`VideoLimitReason` types. `videoEncodings` takes the most layers to send as
|
|
72
|
+
an optional fourth argument.
|
|
73
|
+
- **Fix: reconnecting gives up when it should.** The attempt count restarted
|
|
74
|
+
whenever the socket opened, so a join refused with a code worth retrying
|
|
75
|
+
(`no-capacity`, `no-node`, `internal`) was retried about twice a second,
|
|
76
|
+
forever, and `closed` with `gave-up` never came: in a full cluster every
|
|
77
|
+
client kept at it. The count now restarts only once a join succeeds, the
|
|
78
|
+
gaps keep growing (half a second, doubling to 15 s), and after eight failed
|
|
79
|
+
attempts in a row the client stops with `closed` (`gave-up`). A connection
|
|
80
|
+
that drops again while a reconnect is restoring the session is retried
|
|
81
|
+
too; it was left disconnected, with no `closed`. `ChatClient` counted the
|
|
82
|
+
same way and is fixed the same way.
|
|
83
|
+
- **Fix: a camera that is off stays off, on both ends.** A track handed to
|
|
84
|
+
`publish()` switched off, a camera switched off before a reconnect, or a
|
|
85
|
+
quality change or track swap to other layers could leave the camera paused
|
|
86
|
+
in the client but live on the server, so viewers got black video under a
|
|
87
|
+
camera shown as on (and silence, for a microphone or music switched off
|
|
88
|
+
before a reconnect). The server is now paused too; a camera producer that
|
|
89
|
+
is replaced starts in the camera's state, and while the camera is off no
|
|
90
|
+
frame of the new track is sent; a track swapped in during a reconnect, and
|
|
91
|
+
devices a reconnect has to ask for again, keep a camera that was off, off.
|
|
92
|
+
`camEnabled`, `micEnabled` and `localMediaChanged` report as before.
|
|
93
|
+
- **Fix:** `unpublish()` while `publish()` or `publishMusic()` is still
|
|
94
|
+
making the microphone or music producer no longer leaves it published; the
|
|
95
|
+
camera was already covered. What was being made is closed and that call
|
|
96
|
+
rejects. A reconnect's republish under way when `unpublish()` runs
|
|
97
|
+
publishes nothing either.
|
|
98
|
+
- **Fix: `unpublish()` forgets the devices.** It kept the capture constraints
|
|
99
|
+
given to `publish()`, so after `unpublish()` and then `publishMusic()`, a
|
|
100
|
+
reconnect asked for the camera and microphone again and published them.
|
|
101
|
+
Music published after `unpublish()` now reconnects alone.
|
|
102
|
+
- **Fix:** `publish()` and `unpublish()` act in the order they are called. A
|
|
103
|
+
`publish()` or `publishMusic()` called while an `unpublish()` was still
|
|
104
|
+
waiting on the server had its new stream stopped and its state cleared when
|
|
105
|
+
that `unpublish()` finished. `unpublish()` now makes all its changes at once
|
|
106
|
+
and only then waits for the server.
|
|
107
|
+
- **Fix:** a first `connect()` that fails at the join closes its socket and
|
|
108
|
+
starts no reconnect loop; only a session that has joined is reconnected.
|
|
109
|
+
Before, the server's join deadline closed that socket about 15 s later, and
|
|
110
|
+
the client began reconnecting a session the app had already been told had
|
|
111
|
+
failed. `ChatClient` too.
|
|
112
|
+
|
|
3
113
|
## 0.3.0
|
|
4
114
|
|
|
5
115
|
- **Video quality.** `publish(stream, constraints, { quality })` takes
|
package/README.md
CHANGED
|
@@ -48,7 +48,7 @@ const joined = await client.connect();
|
|
|
48
48
|
|
|
49
49
|
if (joined.role === 'host' || joined.role === 'cohost') {
|
|
50
50
|
const media = await navigator.mediaDevices.getUserMedia({ audio: true, video: { width: 1280, height: 720 } });
|
|
51
|
-
await client.publish(media); // 720p
|
|
51
|
+
await client.publish(media); // 720p: 3 simulcast layers from a computer, 2 from a phone
|
|
52
52
|
}
|
|
53
53
|
```
|
|
54
54
|
|
|
@@ -69,6 +69,40 @@ client.publishing; client.micEnabled; client.camEnabled; client.local; // curr
|
|
|
69
69
|
A `viewer` cannot publish. That is enforced at the media server, not in this
|
|
70
70
|
package — a tampered client gets an error, not a stream.
|
|
71
71
|
|
|
72
|
+
`publish(media, constraints, options)` takes these options. The defaults suit
|
|
73
|
+
phones and computers alike; they are kept for a reconnect's republish.
|
|
74
|
+
|
|
75
|
+
| Option | Default | What it does |
|
|
76
|
+
| --- | --- | --- |
|
|
77
|
+
| `quality` | the highest the project allows | `'1080p'`, `'720p'` or `'480p'`; see [Video quality](#video-quality) |
|
|
78
|
+
| `frameRate` | `30` | `30` or `60`; only the top layer runs at 60 fps; capture at 60 too |
|
|
79
|
+
| `layers` | `2` on phones and tablets, `3` elsewhere | the most simulcast layers to send. When a phone is too busy, the browser shrinks the picture and may then send fewer layers, dropping the top one: asked for two, it keeps the full picture; asked for three, viewers were left with a quarter of it |
|
|
80
|
+
| `codec` | `'auto'` | `'auto'` sends H.264 on phones and tablets that encode it in hardware, VP8 elsewhere. `'vp8'` or `'h264'` forces one; a forced H.264 the browser cannot send is VP8, and fires `error` |
|
|
81
|
+
| `degradationPreference` | the browser's | what the encoder gives up first on a busy device: `'maintain-resolution'` (frame rate goes first), `'maintain-framerate'` or `'balanced'` |
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
await client.publish(media, undefined, { quality: '720p', layers: 2, codec: 'auto', degradationPreference: 'maintain-resolution' });
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Chrome also reads the trade-off from the track itself:
|
|
88
|
+
`track.contentHint = 'detail'` keeps the resolution, `'motion'` the frame rate.
|
|
89
|
+
A viewer whose browser cannot decode the codec cannot watch, so force `'vp8'`
|
|
90
|
+
if your audience uses browsers without H.264 (rare).
|
|
91
|
+
|
|
92
|
+
To send another video track while live, such as a canvas with effects drawn on
|
|
93
|
+
it or the raw camera again:
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
await client.replaceVideoTrack(canvas.captureStream(30).getVideoTracks()[0]);
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
When the new track has the same dimensions and layers as the old one, viewers see no pause; otherwise the camera's producer is replaced
|
|
100
|
+
and they see a brief one. A paused camera stays paused. Your own stream is not
|
|
101
|
+
modified: the client keeps one of its own (`client.local`, announced by
|
|
102
|
+
`localStreamChanged`) with the new track, and a reconnect republishes that. The
|
|
103
|
+
track you replaced is yours again: it is not stopped, and if pausing the camera
|
|
104
|
+
had switched it off, it is switched back on.
|
|
105
|
+
|
|
72
106
|
### Video quality
|
|
73
107
|
|
|
74
108
|
Choose 1080p, 720p or 480p when publishing, or change it while live:
|
|
@@ -78,30 +112,163 @@ const media = await navigator.mediaDevices.getUserMedia({ audio: true, video: {
|
|
|
78
112
|
await client.publish(media, undefined, { quality: '1080p' });
|
|
79
113
|
await client.setVideoQuality('480p'); // resolves to the quality actually used
|
|
80
114
|
|
|
81
|
-
client.videoPolicy; // { maxQuality: '720p' | '1080p', maxBitrate } for this project
|
|
115
|
+
client.videoPolicy; // { maxQuality: '480p' | '720p' | '1080p', maxFrameRate, maxBitrate } for this project
|
|
82
116
|
client.videoQuality; // what is being sent now
|
|
83
117
|
```
|
|
84
118
|
|
|
85
|
-
| Quality | Layers
|
|
86
|
-
|
|
87
|
-
| 1080p | 480×270 · 960×540 · 1920×1080 |
|
|
88
|
-
| 720p | 320×180 · 640×360 · 1280×720 |
|
|
89
|
-
| 480p | 427×240 · 854×480 |
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
119
|
+
| Quality | Layers from a computer at 30 fps | From a phone or tablet | Video upload |
|
|
120
|
+
|---|---|---|---|
|
|
121
|
+
| 1080p | 480×270 @ 0.4 Mbps · 960×540 @ 2 Mbps · 1920×1080 @ **6 Mbps** | the top two | about 8.4 Mbps (phone 8) |
|
|
122
|
+
| 720p | 320×180 @ 0.2 Mbps · 640×360 @ 0.8 Mbps · 1280×720 @ **3 Mbps** | the top two | about 4 Mbps (phone 3.8) |
|
|
123
|
+
| 480p | 427×240 @ 0.4 Mbps · 854×480 @ **1.2 Mbps** | the same two | about 1.6 Mbps |
|
|
124
|
+
|
|
125
|
+
All qualities are included on every plan. The default policy allows 1080p and
|
|
126
|
+
60 fps, with a 25 Mbps incoming safety cap per publisher. A project can have
|
|
127
|
+
an explicit administrative restriction; `videoPolicy` describes it.
|
|
128
|
+
The picture is scaled down to the chosen quality, never up. Portrait phones
|
|
129
|
+
keep their shape, for example 360×640 and 720×1280. Adaptive reception is the
|
|
130
|
+
default: viewers receive the best layer their connection can carry. Viewers
|
|
131
|
+
start with a 4 Mbps estimate, enough for 720p; 1080p ramps up as bandwidth allows.
|
|
132
|
+
|
|
133
|
+
30 fps is the default. For 60 fps, capture at 60 and opt in:
|
|
134
|
+
|
|
135
|
+
```ts
|
|
136
|
+
await client.publish(media, undefined, { quality: '1080p', frameRate: 60 });
|
|
137
|
+
const effectiveFps = await client.setVideoFrameRate(30); // camera only, other tracks continue
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Only the top layer uses 60 fps: 1080p is **9 Mbps**, 720p **4.5 Mbps**, and
|
|
141
|
+
480p **1.8 Mbps**; smaller layers stay at 30. This means roughly 1.5× the top
|
|
142
|
+
layer's data and twice the encoding work. Phones can heat up and use more
|
|
143
|
+
battery, and many front cameras capture only 30. If capture is below 50 fps,
|
|
144
|
+
a project restricts it, or sustained device/upload limitation prevents 60,
|
|
145
|
+
the SDK uses 30 and emits `error` with `code: 'frame-rate-fallback'` as a warning.
|
|
146
|
+
`setVideoFrameRate(60)` retries the preference while preserving a paused camera.
|
|
147
|
+
|
|
148
|
+
The full guide, with data use:
|
|
103
149
|
[voltkit.in/docs/video-quality](https://voltkit.in/docs/video-quality).
|
|
104
150
|
|
|
151
|
+
### When the picture is soft
|
|
152
|
+
|
|
153
|
+
A soft or stuttering picture usually comes from the publisher's device (too
|
|
154
|
+
busy to encode) or their upload (too slow for the top layer), not from the
|
|
155
|
+
service. The client can tell you which.
|
|
156
|
+
|
|
157
|
+
```ts
|
|
158
|
+
const stats = await client.getVideoStats(); // null when no camera is published
|
|
159
|
+
// { codec: 'H264', quality: '720p', width: 720, height: 1280, fps: 30, bitrate: 2400000,
|
|
160
|
+
// qualityLimitation: 'none', availableOutgoingBitrate: 3900000, layers: [ ... ] }
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
The top-level fields describe the biggest layer going out; `layers` lists each
|
|
164
|
+
one (`active`, size, frame rate, bitrate). `qualityLimitation` is the browser's
|
|
165
|
+
reason for sending less than asked: `cpu` is the device, `bandwidth` the
|
|
166
|
+
upload, `none` neither (then look at the camera and the light). Bitrates are
|
|
167
|
+
averaged since your previous call, so call it every second or two; the first
|
|
168
|
+
call reports 0.
|
|
169
|
+
|
|
170
|
+
`videoLimited` tells you when that changes, so you can tell the publisher:
|
|
171
|
+
|
|
172
|
+
```ts
|
|
173
|
+
client.on('videoLimited', ({ reason }) => {
|
|
174
|
+
if (reason === 'cpu') showNotice('Your device is busy, so the stream is softer. Turn off effects or switch to 480p.');
|
|
175
|
+
else if (reason === 'bandwidth') showNotice('Your upload is slow, so viewers get a lighter picture.');
|
|
176
|
+
else hideNotice(); // 'none': cleared; 'other': rare
|
|
177
|
+
});
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
It fires once a new reason has held for about 4 seconds, so brief spikes stay
|
|
181
|
+
quiet, and never fires `none` first. The client checks every 2 seconds, and
|
|
182
|
+
while a camera is published and something listens, or while 60 fps needs fallback monitoring. `unpublish()` fires
|
|
183
|
+
`none` if a limitation was showing.
|
|
184
|
+
|
|
185
|
+
On a viewer, `getReceiveStats(producerId)` (the `producerId` from the `track`
|
|
186
|
+
event) says what arrives: size, frame rate, bitrate, `packetsLost`, `jitter`
|
|
187
|
+
and, where the browser counts them, `freezeCount`. A viewer receiving a
|
|
188
|
+
smaller picture than the publisher's biggest layer is on a lower one, picked
|
|
189
|
+
for their own connection; if every viewer is, look at the publisher's
|
|
190
|
+
`getVideoStats()`.
|
|
191
|
+
|
|
192
|
+
The [troubleshooting guide](https://voltkit.in/docs/troubleshooting) lists the
|
|
193
|
+
usual causes and what to do about each.
|
|
194
|
+
|
|
195
|
+
### Small tiles
|
|
196
|
+
|
|
197
|
+
Each viewer gets the biggest layer their connection carries, which a thumbnail
|
|
198
|
+
or a row of co-host tiles does not need. Ask for a smaller one with the
|
|
199
|
+
`producerId` from the `track` event:
|
|
200
|
+
|
|
201
|
+
```ts
|
|
202
|
+
client.on('track', ({ kind, producerId, track }) => {
|
|
203
|
+
if (kind !== 'video') return;
|
|
204
|
+
showVideo(producerId, track);
|
|
205
|
+
if (isSmallTile(producerId)) client.setPreferredLayers(producerId, 0).catch(console.warn);
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
await client.setPreferredLayers(producerId, 2); // the tile grew: the biggest layer again
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Layer 0 is the smallest copy the publisher sends. At 720p a computer sends
|
|
212
|
+
three (320×180, 640×360 and 1280×720) and a phone two (640×360 and 1280×720);
|
|
213
|
+
a layer above the biggest means the biggest. The 640×360 copy needs about
|
|
214
|
+
0.9 Mbps including audio, the full picture about 3.1. An optional third argument, the
|
|
215
|
+
temporal layer, lowers the frame rate as well; without it the full frame rate
|
|
216
|
+
is kept. It is the most this viewer is sent: a connection that cannot carry it
|
|
217
|
+
still gets less. The choice is kept across reconnects and forgotten when the
|
|
218
|
+
track ends, and `setPreferredLayers` rejects for a video this client is not
|
|
219
|
+
receiving.
|
|
220
|
+
|
|
221
|
+
### Receive quality
|
|
222
|
+
|
|
223
|
+
```ts
|
|
224
|
+
await client.setReceiveQuality(producerId, '480p');
|
|
225
|
+
await client.setReceiveQuality(producerId, 'auto'); // recommended; clears spatial AND temporal ceilings
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
Offer **Auto (recommended) / 1080p / 720p / 480p**. The `ReceiveQuality` helper
|
|
229
|
+
maps the request to the producer's actual `videoLayers` dimensions, including
|
|
230
|
+
portrait phones, two-layer cameras and screen tracks. It chooses the largest
|
|
231
|
+
available copy within the ceiling, or the smallest available if none fits.
|
|
232
|
+
It never creates a missing resolution: a 1080p screen with 540p and 1080p copies
|
|
233
|
+
uses 540p for the 480p choice. Connection adaptation still applies below the
|
|
234
|
+
ceiling. The preference is remembered across reconnects and ends with that
|
|
235
|
+
producer. Without layer metadata, explicit choices reject `quality-unavailable`;
|
|
236
|
+
Auto and the numeric `setPreferredLayers` API still work.
|
|
237
|
+
|
|
238
|
+
### Screen sharing
|
|
239
|
+
|
|
240
|
+
Hosts and cohosts can share a screen beside their camera in SDK 0.5.0:
|
|
241
|
+
|
|
242
|
+
```ts
|
|
243
|
+
client.on('screenShareStarted', ({ stream, mode }) => showScreenPreview(stream, mode));
|
|
244
|
+
client.on('screenShareEnded', ({ reason }) => hideScreenPreview(reason));
|
|
245
|
+
await client.publishScreen({ mode: 'detail', audio: true }); // from a button click
|
|
246
|
+
await client.unpublishScreen(); // camera, mic and music continue
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
`ScreenPublishOptions` accepts `mode: 'detail' | 'motion'` (default `detail`),
|
|
250
|
+
`audio?: boolean` and `stream?: MediaStream`. Without `stream`, the SDK opens
|
|
251
|
+
`getDisplayMedia` and returns its `MediaStream`; capture audio defaults to
|
|
252
|
+
false. An existing stream's audio is used unless `audio: false` is supplied.
|
|
253
|
+
The SDK stops the supplied screen tracks when sharing ends.
|
|
254
|
+
|
|
255
|
+
Detail sends up to native 1920×1080 at 15 fps and 2.5 Mbps plus a half-size
|
|
256
|
+
0.6 Mbps copy. Motion uses 30 fps, 6 Mbps plus 0.6 Mbps. Capture is never
|
|
257
|
+
upscaled. Optional tab/system audio is separate, `source: 'screen-audio'`,
|
|
258
|
+
128 kbps stereo. Viewers play it like `music`; screen video arrives with
|
|
259
|
+
`source: 'screen'`. A browser may grant video without granting audio.
|
|
260
|
+
|
|
261
|
+
The browser's **Stop sharing** automatically unpublishes and emits
|
|
262
|
+
`screenShareEnded({ reason: 'track-ended' })`. Calling `unpublishScreen` emits
|
|
263
|
+
`reason: 'stopped'`. A reconnect republishes a still-live screen without another
|
|
264
|
+
picker. `unpublish()` and `close()` stop all local media. Unsupported capture
|
|
265
|
+
(most mobile browsers) rejects `screen-share-unsupported`; overlapping shares
|
|
266
|
+
reject `screen-share-active`; missing live video rejects `screen-share-no-video`.
|
|
267
|
+
Browser cancellation retains its `NotAllowedError`. Capture requires HTTPS,
|
|
268
|
+
a user gesture and permission; in iframes, also allow `display-capture`.
|
|
269
|
+
|
|
270
|
+
[Setup, modes, native platforms and troubleshooting](https://voltkit.in/docs/screen-sharing).
|
|
271
|
+
|
|
105
272
|
### Music
|
|
106
273
|
|
|
107
274
|
A host can play music to the room from inside the page. It does not go through
|
|
@@ -146,6 +313,8 @@ musicAudio.muted = true; // "mute the music" for this viewer only
|
|
|
146
313
|
```ts
|
|
147
314
|
await client.raiseHand();
|
|
148
315
|
await client.lowerHand();
|
|
316
|
+
await client.raiseHand({ requestRole: 'cohost' }); // metadata also supports 'moderator'
|
|
317
|
+
await client.lowerHand(identity); // host/moderator: decline that raised hand
|
|
149
318
|
await client.muteParticipant(identity); // moderating roles: asks them to mute
|
|
150
319
|
await client.forceMute(identity, 'video'); // moderating roles: camera off, locked until released
|
|
151
320
|
await client.forceMute(identity, 'video', false); // release
|
|
@@ -159,19 +328,22 @@ await client.getRoomState();
|
|
|
159
328
|
|
|
160
329
|
| Event | Fires when |
|
|
161
330
|
| --- | --- |
|
|
162
|
-
| `track` / `trackEnded` | someone's audio or video is ready to render, or went away; `source` is `mic`, `music`, `camera` or `screen` |
|
|
331
|
+
| `track` / `trackEnded` | someone's audio or video is ready to render, or went away; `source` is `mic`, `music`, `camera`, `screen` or `screen-audio` |
|
|
163
332
|
| `trackMuted` | someone paused or resumed a track — muted their mic, switched their music off |
|
|
164
333
|
| `participantJoined` / `participantLeft` | roster changes |
|
|
334
|
+
| `participantMuted` | moderation lock changed: `{ identity, kind, paused }`; reconnect roster `muted` / `videoBlocked` seed the locks |
|
|
165
335
|
| `roleChanged` | someone was promoted or demoted |
|
|
166
|
-
| `handRaised` | a hand went up or down |
|
|
336
|
+
| `handRaised` | a hand went up or down, with optional `metadata` and `reason`; reconnect rosters include `handMetadata` |
|
|
337
|
+
| `screenShareStarted` / `screenShareEnded` | local screen capture began (`stream`, `mode`) or stopped (`reason`) |
|
|
167
338
|
| `forceMuted` | a moderator switched **your** mic or camera off |
|
|
168
339
|
| `streamInterrupted` | media stopped but the connection is fine — the publisher is reconnecting |
|
|
169
340
|
| `localMediaChanged` / `localStreamChanged` | your own mic, camera or stream changed |
|
|
170
341
|
| `connected` / `disconnected` | the socket came up or dropped; reconnection is automatic |
|
|
171
342
|
| `kicked` / `roomClosed` | you were removed, or the host ended the room |
|
|
172
|
-
| `error` |
|
|
343
|
+
| `error` | a failure or recoverable warning such as `frame-rate-fallback`; inspect its code |
|
|
173
344
|
| `usageLimit` | your project ran out of minutes or hit a usage limit; the session ends at `endsAt` unless it is topped up |
|
|
174
|
-
| `
|
|
345
|
+
| `videoLimited` | your camera video is held back by this device (`cpu`) or the upload (`bandwidth`), or that cleared (`none`) |
|
|
346
|
+
| `closed` | terminal — `replaced`, `kicked`, `room-closed` or `gave-up`, or `left` when your own `close()` ends the session |
|
|
175
347
|
|
|
176
348
|
`on()` returns a function that removes the listener.
|
|
177
349
|
|
package/dist/cjs/chat.d.ts
CHANGED
|
@@ -104,6 +104,8 @@ export declare class ChatClient {
|
|
|
104
104
|
private closedByUs;
|
|
105
105
|
private reconnecting;
|
|
106
106
|
private reconnectAttempt;
|
|
107
|
+
/** Set by the first successful join. Only a session that has joined is reconnected. */
|
|
108
|
+
private joinedOnce;
|
|
107
109
|
constructor(wsUrl: string, token: string);
|
|
108
110
|
on<K extends keyof ChatClientEvents>(event: K, fn: ChatClientEvents[K]): () => void;
|
|
109
111
|
private emit;
|
package/dist/cjs/chat.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/chat.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,WAAW,WAAW;IAC1B,4EAA4E;IAC5E,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,oEAAoE;IACpE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,+EAA+E;IAC/E,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iFAAiF;IACjF,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,OAAO,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,KAAK,EAAE,OAAO,CAAC;IACf,mCAAmC;IACnC,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,IAAI,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,8CAA8C;IAC9C,QAAQ,EAAE,WAAW,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,CAAC,CAAC,EAAE,WAAW,KAAK,IAAI,CAAC;IAClC,cAAc,EAAE,CAAC,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACxD,SAAS,EAAE,CAAC,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACzE,MAAM,EAAE,CAAC,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;CAC5D;AAED,MAAM,WAAW,gBAAiB,SAAQ,UAAU;IAClD,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,MAAM,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;IACzC,KAAK,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC;IAC5B,+EAA+E;IAC/E,MAAM,EAAE,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,OAAO,KAAK,IAAI,CAAC;IACvD,4EAA4E;IAC5E,UAAU,EAAE,CAAC,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CACnF;AAED,2EAA2E;AAC3E,qBAAa,YAAa,SAAQ,KAAK;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM;gBAAZ,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAInD;AAyBD;;;GAGG;AACH,qBAAa,UAAU;
|
|
1
|
+
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/chat.ts"],"names":[],"mappings":"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"}
|
package/dist/cjs/chat.js
CHANGED
|
@@ -39,6 +39,8 @@ class ChatClient {
|
|
|
39
39
|
closedByUs = false;
|
|
40
40
|
reconnecting = false;
|
|
41
41
|
reconnectAttempt = 0;
|
|
42
|
+
/** Set by the first successful join. Only a session that has joined is reconnected. */
|
|
43
|
+
joinedOnce = false;
|
|
42
44
|
constructor(wsUrl, token) {
|
|
43
45
|
this.wsUrl = wsUrl;
|
|
44
46
|
this.token = token;
|
|
@@ -67,8 +69,24 @@ class ChatClient {
|
|
|
67
69
|
return this.joinResult;
|
|
68
70
|
}
|
|
69
71
|
async connect() {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
+
let result;
|
|
73
|
+
try {
|
|
74
|
+
await this.openSocket();
|
|
75
|
+
result = (await this.rpc('join', { token: this.token }));
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
// Never joined: the app has the error. Left open, the socket would be
|
|
79
|
+
// closed by the server's join deadline, and that would start
|
|
80
|
+
// reconnecting a session that never began.
|
|
81
|
+
if (!this.joinedOnce)
|
|
82
|
+
this.detachSocket();
|
|
83
|
+
throw err;
|
|
84
|
+
}
|
|
85
|
+
// Joined: the next drop gets every reconnect attempt again. Not when the
|
|
86
|
+
// socket opens, or a join refused with a code worth retrying never uses
|
|
87
|
+
// them up and is retried about twice a second, forever.
|
|
88
|
+
this.reconnectAttempt = 0;
|
|
89
|
+
this.joinedOnce = true;
|
|
72
90
|
this.joinResult = result;
|
|
73
91
|
this.emit('joined', result);
|
|
74
92
|
return result;
|
|
@@ -82,7 +100,6 @@ class ChatClient {
|
|
|
82
100
|
this.ws = ws;
|
|
83
101
|
const onError = () => reject(new Error('websocket failed to open'));
|
|
84
102
|
ws.addEventListener('open', () => {
|
|
85
|
-
this.reconnectAttempt = 0;
|
|
86
103
|
this.emit('connected');
|
|
87
104
|
resolve();
|
|
88
105
|
}, { once: true });
|
|
@@ -105,7 +122,9 @@ class ChatClient {
|
|
|
105
122
|
this.emit('closed', 'ended');
|
|
106
123
|
return;
|
|
107
124
|
}
|
|
108
|
-
|
|
125
|
+
// Before a first join the app is still waiting on connect(), which
|
|
126
|
+
// reports the failure; there is no session to restore.
|
|
127
|
+
if (!this.closedByUs && this.joinedOnce)
|
|
109
128
|
void this.scheduleReconnect();
|
|
110
129
|
});
|
|
111
130
|
});
|
package/dist/cjs/chat.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat.js","sourceRoot":"","sources":["../../src/chat.ts"],"names":[],"mappings":";;;AA+EA,2EAA2E;AAC3E,MAAa,YAAa,SAAQ,KAAK;IAChB;IAArB,YAAqB,IAAY,EAAE,OAAe;QAChD,KAAK,CAAC,GAAG,IAAI,KAAK,OAAO,EAAE,CAAC,CAAC;QADV,SAAI,GAAJ,IAAI,CAAQ;QAE/B,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;IAC7B,CAAC;CACF;AALD,oCAKC;AAUD,MAAM,cAAc,GAAG,MAAM,CAAC;AAC9B,MAAM,sBAAsB,GAAG,CAAC,CAAC;AACjC,mFAAmF;AACnF,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC;IACnC,WAAW;IACX,UAAU;IACV,wEAAwE;IACxE,iBAAiB;IACjB,qBAAqB;IACrB,uBAAuB;IACvB,kBAAkB;CACnB,CAAC,CAAC;AAEH,MAAM,KAAK,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;AAEpE;;;GAGG;AACH,MAAa,UAAU;
|
|
1
|
+
{"version":3,"file":"chat.js","sourceRoot":"","sources":["../../src/chat.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What kind of device is publishing, and which video codec it should send.
|
|
3
|
+
*
|
|
4
|
+
* Phones and tablets get different defaults from computers: each simulcast
|
|
5
|
+
* layer is a separate encode, and a phone encoding VP8 does it in software.
|
|
6
|
+
* Under that load Chrome shrinks the picture, and with three layers asked for
|
|
7
|
+
* it then sends only two and drops the TOP one: viewers got 180×320 from a
|
|
8
|
+
* 720p phone. Two layers in hardware H.264 keep the full picture.
|
|
9
|
+
*
|
|
10
|
+
* Everything here reads the browser through small injectable parameters, so
|
|
11
|
+
* tests can stand in for any device.
|
|
12
|
+
*/
|
|
13
|
+
import type { types as ms } from 'mediasoup-client';
|
|
14
|
+
type RtpCodecCapability = ms.RtpCodecCapability;
|
|
15
|
+
/** What the SDK reads about the browser to choose its defaults. */
|
|
16
|
+
export interface DeviceEnv {
|
|
17
|
+
userAgent: string;
|
|
18
|
+
/** `navigator.userAgentData.mobile`, where the browser has it (Chromium). */
|
|
19
|
+
uaMobile?: boolean;
|
|
20
|
+
maxTouchPoints: number;
|
|
21
|
+
}
|
|
22
|
+
/** The browser this runs in; an empty desktop-like one outside a browser. */
|
|
23
|
+
export declare function currentEnv(): DeviceEnv;
|
|
24
|
+
/**
|
|
25
|
+
* A phone or a tablet. `userAgentData.mobile` is false on Android tablets, so
|
|
26
|
+
* the user agent is checked as well.
|
|
27
|
+
*/
|
|
28
|
+
export declare function isPhoneOrTablet(env?: DeviceEnv): boolean;
|
|
29
|
+
/** An iPhone, iPad or iPod: every one of them encodes H.264 in hardware. */
|
|
30
|
+
export declare function isAppleMobile(env?: DeviceEnv): boolean;
|
|
31
|
+
/** Two layers on phones and tablets, three elsewhere. */
|
|
32
|
+
export declare function defaultLayerCount(env?: DeviceEnv): 2 | 3;
|
|
33
|
+
/** `navigator.mediaCapabilities.encodingInfo`, or a stand-in for tests. */
|
|
34
|
+
export type EncodingInfoProbe = (configuration: MediaEncodingConfiguration) => Promise<MediaCapabilitiesEncodingInfo>;
|
|
35
|
+
/** The browser's own probe, when it has one. */
|
|
36
|
+
export declare function currentProbe(): EncodingInfoProbe | undefined;
|
|
37
|
+
/** The H.264 the media server takes: constrained baseline, packetization mode 1. */
|
|
38
|
+
export declare const H264_CONTENT_TYPE = "video/H264;profile-level-id=42e01f;packetization-mode=1";
|
|
39
|
+
/**
|
|
40
|
+
* Whether this browser encodes H.264 at this size and bitrate in hardware:
|
|
41
|
+
* true or false when it says so, null when it cannot say (no
|
|
42
|
+
* `mediaCapabilities`, no `webrtc` support in it, an error, or no answer in
|
|
43
|
+
* time). Publishing never waits on it for more than a moment.
|
|
44
|
+
*/
|
|
45
|
+
export declare function h264HardwareEncode(video: {
|
|
46
|
+
width: number;
|
|
47
|
+
height: number;
|
|
48
|
+
bitrate: number;
|
|
49
|
+
}, probe?: EncodingInfoProbe | undefined, timeoutMs?: number): Promise<boolean | null>;
|
|
50
|
+
/** What `PublishOptions.codec` may say. */
|
|
51
|
+
export type CodecPreference = 'auto' | 'vp8' | 'h264';
|
|
52
|
+
/** 'vp8' or 'h264' in any case; anything else, including nothing, is 'auto'. */
|
|
53
|
+
export declare function normalizeCodec(codec: unknown): CodecPreference;
|
|
54
|
+
export interface CodecChoiceInput {
|
|
55
|
+
requested: CodecPreference;
|
|
56
|
+
phoneOrTablet: boolean;
|
|
57
|
+
appleMobile: boolean;
|
|
58
|
+
/** This browser can send H.264 to this server (it is in the device's send capabilities). */
|
|
59
|
+
h264Available: boolean;
|
|
60
|
+
/** What the hardware probe said; null when it could not say. Only asked for 'auto' on phones and tablets. */
|
|
61
|
+
h264Hardware: boolean | null;
|
|
62
|
+
}
|
|
63
|
+
export interface CodecChoice {
|
|
64
|
+
codec: 'vp8' | 'h264';
|
|
65
|
+
/** Set when the codec asked for cannot be used: report it, and publish anyway. */
|
|
66
|
+
warning?: string;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* The codec to publish with.
|
|
70
|
+
*
|
|
71
|
+
* 'auto' is H.264 on a phone or tablet that encodes it in hardware, and VP8
|
|
72
|
+
* everywhere else: computers encode VP8 well, and a few desktop browsers
|
|
73
|
+
* cannot decode H.264. When the probe cannot say, an Apple device is taken to
|
|
74
|
+
* have hardware H.264 (they all do) and anything else is not.
|
|
75
|
+
*/
|
|
76
|
+
export declare function chooseCodec(input: CodecChoiceInput): CodecChoice;
|
|
77
|
+
/**
|
|
78
|
+
* The device's own capability entry for a codec, to hand to `produce()`.
|
|
79
|
+
* Only ever pass `produce()` an entry from the device's send capabilities:
|
|
80
|
+
* mediasoup-client adds the transceiver before it checks the codec, so one it
|
|
81
|
+
* cannot match leaves a transceiver behind that breaks every later produce.
|
|
82
|
+
*/
|
|
83
|
+
export declare function findCodec(codecs: readonly RtpCodecCapability[] | undefined, codec: 'vp8' | 'h264'): RtpCodecCapability | undefined;
|
|
84
|
+
export {};
|
|
85
|
+
//# sourceMappingURL=device.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device.d.ts","sourceRoot":"","sources":["../../src/device.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,KAAK,IAAI,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAEpD,KAAK,kBAAkB,GAAG,EAAE,CAAC,kBAAkB,CAAC;AAEhD,mEAAmE;AACnE,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,6EAA6E;AAC7E,wBAAgB,UAAU,IAAI,SAAS,CAStC;AAMD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,GAAE,SAAwB,GAAG,OAAO,CAItE;AAED,4EAA4E;AAC5E,wBAAgB,aAAa,CAAC,GAAG,GAAE,SAAwB,GAAG,OAAO,CAEpE;AAED,yDAAyD;AACzD,wBAAgB,iBAAiB,CAAC,GAAG,GAAE,SAAwB,GAAG,CAAC,GAAG,CAAC,CAEtE;AAED,2EAA2E;AAC3E,MAAM,MAAM,iBAAiB,GAAG,CAAC,aAAa,EAAE,0BAA0B,KAAK,OAAO,CAAC,6BAA6B,CAAC,CAAC;AAEtH,gDAAgD;AAChD,wBAAgB,YAAY,IAAI,iBAAiB,GAAG,SAAS,CAK5D;AAED,oFAAoF;AACpF,eAAO,MAAM,iBAAiB,4DAA4D,CAAC;AAI3F;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,KAAK,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EACzD,KAAK,GAAE,iBAAiB,GAAG,SAA0B,EACrD,SAAS,SAAmB,GAC3B,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAyBzB;AAED,2CAA2C;AAC3C,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;AAEtD,gFAAgF;AAChF,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,CAG9D;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,eAAe,CAAC;IAC3B,aAAa,EAAE,OAAO,CAAC;IACvB,WAAW,EAAE,OAAO,CAAC;IACrB,4FAA4F;IAC5F,aAAa,EAAE,OAAO,CAAC;IACvB,6GAA6G;IAC7G,YAAY,EAAE,OAAO,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,KAAK,GAAG,MAAM,CAAC;IACtB,kFAAkF;IAClF,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,WAAW,CAShE;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,SAAS,kBAAkB,EAAE,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAIlI"}
|