@voltkit-rtc/client 0.2.0 → 0.4.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 (48) hide show
  1. package/CHANGELOG.md +112 -0
  2. package/README.md +147 -3
  3. package/dist/cjs/chat.d.ts +2 -0
  4. package/dist/cjs/chat.d.ts.map +1 -1
  5. package/dist/cjs/chat.js +23 -4
  6. package/dist/cjs/chat.js.map +1 -1
  7. package/dist/cjs/device.d.ts +85 -0
  8. package/dist/cjs/device.d.ts.map +1 -0
  9. package/dist/cjs/device.js +134 -0
  10. package/dist/cjs/device.js.map +1 -0
  11. package/dist/cjs/index.d.ts +184 -1
  12. package/dist/cjs/index.d.ts.map +1 -1
  13. package/dist/cjs/index.js +546 -32
  14. package/dist/cjs/index.js.map +1 -1
  15. package/dist/cjs/quality.d.ts +74 -0
  16. package/dist/cjs/quality.d.ts.map +1 -0
  17. package/dist/cjs/quality.js +115 -0
  18. package/dist/cjs/quality.js.map +1 -0
  19. package/dist/cjs/stats.d.ts +151 -0
  20. package/dist/cjs/stats.d.ts.map +1 -0
  21. package/dist/cjs/stats.js +243 -0
  22. package/dist/cjs/stats.js.map +1 -0
  23. package/dist/esm/chat.d.ts +2 -0
  24. package/dist/esm/chat.d.ts.map +1 -1
  25. package/dist/esm/chat.js +23 -4
  26. package/dist/esm/chat.js.map +1 -1
  27. package/dist/esm/device.d.ts +85 -0
  28. package/dist/esm/device.d.ts.map +1 -0
  29. package/dist/esm/device.js +122 -0
  30. package/dist/esm/device.js.map +1 -0
  31. package/dist/esm/index.d.ts +184 -1
  32. package/dist/esm/index.d.ts.map +1 -1
  33. package/dist/esm/index.js +541 -31
  34. package/dist/esm/index.js.map +1 -1
  35. package/dist/esm/quality.d.ts +74 -0
  36. package/dist/esm/quality.d.ts.map +1 -0
  37. package/dist/esm/quality.js +107 -0
  38. package/dist/esm/quality.js.map +1 -0
  39. package/dist/esm/stats.d.ts +151 -0
  40. package/dist/esm/stats.d.ts.map +1 -0
  41. package/dist/esm/stats.js +232 -0
  42. package/dist/esm/stats.js.map +1 -0
  43. package/package.json +3 -2
  44. package/src/chat.ts +21 -4
  45. package/src/device.ts +168 -0
  46. package/src/index.ts +627 -29
  47. package/src/quality.ts +126 -0
  48. package/src/stats.ts +328 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,117 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.4.0
4
+
5
+ Sharper video, above all from phones. Nothing to change to upgrade: every 0.3.0
6
+ call works as before, with new defaults.
7
+
8
+ - **Higher bitrates.** Each layer gets about 4 Mbps at 1080p, 2.5 Mbps at
9
+ 720p, 1.5 Mbps at 540p, 1 Mbps at 480p, 700 kbps at 360p and 400 kbps at
10
+ 240p (were 2.5 Mbps, 1.8 Mbps, 1.2 Mbps, 750, 600 and 250 kbps). At 720p
11
+ that brought VP8's quantiser down from about 64 to 55: finer detail, most
12
+ of all in motion. A new stream's bandwidth estimate starts at 1.5 Mbps (was
13
+ 1 Mbps). The service's per-publisher caps rose to match (4 Mbps up to 720p,
14
+ 7 Mbps with 1080p), and viewers of 720p now start on the top layer instead
15
+ of taking about 15 s to climb to it.
16
+ - **Phones keep the full picture.** New `PublishOptions.layers` (1, 2 or 3).
17
+ Phones and tablets now send two layers (half and full size) by default,
18
+ computers three as before. A busy phone shrinks its picture and then sends
19
+ fewer layers, dropping the top one: from three, viewers of a 720p phone got
20
+ 180×320; from two, the full picture survives.
21
+ - **H.264 on phones.** New `PublishOptions.codec`: `'auto'` (the default)
22
+ sends H.264 on phones and tablets that encode it in hardware and VP8
23
+ everywhere else; `'vp8'` and `'h264'` force one. If H.264 cannot be used,
24
+ VP8 is sent and the publish goes on; a forced `'h264'` that falls back also
25
+ fires `error`. A viewer whose browser cannot decode H.264 (rare: a few
26
+ browser builds leave it out) cannot watch a phone sending it: force `'vp8'`
27
+ if your audience uses such browsers.
28
+ - New `PublishOptions.degradationPreference`: what the encoder gives up first
29
+ on a busy device. Unset leaves the browser's default.
30
+ - **`getVideoStats()`**: what the camera is sending, layer by layer, and why
31
+ it is less than asked (`qualityLimitation`: `cpu` is the device,
32
+ `bandwidth` the upload). **`getReceiveStats(producerId)`**: what this client
33
+ receives of someone's video.
34
+ - **`videoLimited` event**: the camera video is being held back by the device
35
+ (`cpu`), the upload (`bandwidth`) or something else (`other`), or that has
36
+ cleared (`none`). It fires once a reason has held for about 4 s, and is
37
+ checked only while you listen. Tell the publisher, so they know it is their
38
+ device or connection.
39
+ - **`replaceVideoTrack(track)`**: send another video track, such as a canvas
40
+ with effects or the raw camera again. Viewers see no pause when the new
41
+ track takes the same layers. Your own stream is never modified, and a
42
+ track replaced while the camera was paused comes back to you switched on.
43
+ - **`setPreferredLayers(producerId, spatialLayer, temporalLayer?)`**: receive
44
+ a smaller copy of someone's video for a small tile, as the Flutter and
45
+ native SDKs already could. Layer 0 is the smallest copy sent; at 720p the
46
+ 640×360 copy needs about 0.76 Mbps instead of 2.6 for the full picture. The
47
+ choice is kept across reconnects and forgotten when the track ends.
48
+ - `setVideoQuality`, `replaceVideoTrack` and publishing now change the camera
49
+ producer one at a time, so quick changes cannot leave two of them, and an
50
+ `unpublish()` in the middle of one leaves none.
51
+ - Upload needed rises with the bitrates: about 3.4 Mbps for 720p from a
52
+ computer (3.2 from a phone), 6 Mbps for 1080p (5.5 from a phone) and
53
+ 1.4 Mbps for 480p.
54
+ - New exports: the `LayerCount`, `CodecPreference`, `VideoSendStats`,
55
+ `VideoLayerStats`, `VideoReceiveStats`, `VideoLimitedEvent` and
56
+ `VideoLimitReason` types. `videoEncodings` takes the most layers to send as
57
+ an optional fourth argument.
58
+ - **Fix: reconnecting gives up when it should.** The attempt count restarted
59
+ whenever the socket opened, so a join refused with a code worth retrying
60
+ (`no-capacity`, `no-node`, `internal`) was retried about twice a second,
61
+ forever, and `closed` with `gave-up` never came: in a full cluster every
62
+ client kept at it. The count now restarts only once a join succeeds, the
63
+ gaps keep growing (half a second, doubling to 15 s), and after eight failed
64
+ attempts in a row the client stops with `closed` (`gave-up`). A connection
65
+ that drops again while a reconnect is restoring the session is retried
66
+ too; it was left disconnected, with no `closed`. `ChatClient` counted the
67
+ same way and is fixed the same way.
68
+ - **Fix: a camera that is off stays off, on both ends.** A track handed to
69
+ `publish()` switched off, a camera switched off before a reconnect, or a
70
+ quality change or track swap to other layers could leave the camera paused
71
+ in the client but live on the server, so viewers got black video under a
72
+ camera shown as on (and silence, for a microphone or music switched off
73
+ before a reconnect). The server is now paused too; a camera producer that
74
+ is replaced starts in the camera's state, and while the camera is off no
75
+ frame of the new track is sent; a track swapped in during a reconnect, and
76
+ devices a reconnect has to ask for again, keep a camera that was off, off.
77
+ `camEnabled`, `micEnabled` and `localMediaChanged` report as before.
78
+ - **Fix:** `unpublish()` while `publish()` or `publishMusic()` is still
79
+ making the microphone or music producer no longer leaves it published; the
80
+ camera was already covered. What was being made is closed and that call
81
+ rejects. A reconnect's republish under way when `unpublish()` runs
82
+ publishes nothing either.
83
+ - **Fix: `unpublish()` forgets the devices.** It kept the capture constraints
84
+ given to `publish()`, so after `unpublish()` and then `publishMusic()`, a
85
+ reconnect asked for the camera and microphone again and published them.
86
+ Music published after `unpublish()` now reconnects alone.
87
+ - **Fix:** `publish()` and `unpublish()` act in the order they are called. A
88
+ `publish()` or `publishMusic()` called while an `unpublish()` was still
89
+ waiting on the server had its new stream stopped and its state cleared when
90
+ that `unpublish()` finished. `unpublish()` now makes all its changes at once
91
+ and only then waits for the server.
92
+ - **Fix:** a first `connect()` that fails at the join closes its socket and
93
+ starts no reconnect loop; only a session that has joined is reconnected.
94
+ Before, the server's join deadline closed that socket about 15 s later, and
95
+ the client began reconnecting a session the app had already been told had
96
+ failed. `ChatClient` too.
97
+
98
+ ## 0.3.0
99
+
100
+ - **Video quality.** `publish(stream, constraints, { quality })` takes
101
+ `'1080p'`, `'720p'` or `'480p'`, and `setVideoQuality(quality)` changes it
102
+ while live. `videoPolicy` reports what the project may publish (from the
103
+ join result's new `video` field) and `videoQuality` what is being sent.
104
+ 1080p needs the project to allow it (it does during the free trial); asking
105
+ for more sends the highest allowed.
106
+ - **Simulcast layers follow the real picture size.** Smaller pictures (480p,
107
+ portrait phones, 4:3 webcams) used to be sent with three layers that the
108
+ browser could not all send, and it dropped the top ones, so viewers got half
109
+ or a quarter of the resolution. Now each picture gets the layers it can
110
+ really send. 720p at 1280×720 is unchanged (200 kbps, 600 kbps, 1.8 Mbps).
111
+ - New exports: `videoEncodings`, `layerBitrate`, `allowedQuality`,
112
+ `VIDEO_QUALITIES` and the `VideoQuality`, `VideoPolicy`, `VideoEncoding` and
113
+ `PublishOptions` types.
114
+
3
115
  ## 0.2.0
4
116
 
5
117
  First release on npm, as `@voltkit-rtc/client`. Earlier builds were shared as
package/README.md CHANGED
@@ -47,8 +47,8 @@ client.on('closed', (reason) => leaveScreen(reason)); // terminal; nothing f
47
47
  const joined = await client.connect();
48
48
 
49
49
  if (joined.role === 'host' || joined.role === 'cohost') {
50
- const media = await navigator.mediaDevices.getUserMedia({ audio: true, video: true });
51
- await client.publish(media); // simulcast: 180p / 360p / 720p
50
+ const media = await navigator.mediaDevices.getUserMedia({ audio: true, video: { width: 1280, height: 720 } });
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,149 @@ 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
+ | `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 |
79
+ | `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` |
80
+ | `degradationPreference` | the browser's | what the encoder gives up first on a busy device: `'maintain-resolution'` (frame rate goes first), `'maintain-framerate'` or `'balanced'` |
81
+
82
+ ```ts
83
+ await client.publish(media, undefined, { quality: '720p', layers: 2, codec: 'auto', degradationPreference: 'maintain-resolution' });
84
+ ```
85
+
86
+ Chrome also reads the trade-off from the track itself:
87
+ `track.contentHint = 'detail'` keeps the resolution, `'motion'` the frame rate.
88
+ A viewer whose browser cannot decode the codec cannot watch, so force `'vp8'`
89
+ if your audience uses browsers without H.264 (rare).
90
+
91
+ To send another video track while live, such as a canvas with effects drawn on
92
+ it or the raw camera again:
93
+
94
+ ```ts
95
+ await client.replaceVideoTrack(canvas.captureStream(30).getVideoTracks()[0]);
96
+ ```
97
+
98
+ When the new track takes the same layers as the old one (the same size is the
99
+ safe choice), 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
+
106
+ ### Video quality
107
+
108
+ Choose 1080p, 720p or 480p when publishing, or change it while live:
109
+
110
+ ```ts
111
+ const media = await navigator.mediaDevices.getUserMedia({ audio: true, video: { width: 1920, height: 1080 } });
112
+ await client.publish(media, undefined, { quality: '1080p' });
113
+ await client.setVideoQuality('480p'); // resolves to the quality actually used
114
+
115
+ client.videoPolicy; // { maxQuality: '720p' | '1080p', maxBitrate } for this project
116
+ client.videoQuality; // what is being sent now
117
+ ```
118
+
119
+ | Quality | Layers from a computer | From a phone or tablet | Upload needed |
120
+ |---|---|---|---|
121
+ | 1080p | 480×270 @ 400 kbps · 960×540 @ 1.5 Mbps · 1920×1080 @ **4 Mbps** | the top two | about 6 Mbps (phone 5.5); 8 Mbps or more to be safe |
122
+ | 720p | 320×180 @ 200 kbps · 640×360 @ 700 kbps · 1280×720 @ **2.5 Mbps** | the top two | about 3.4 Mbps (phone 3.2); 4 Mbps or more to be safe |
123
+ | 480p | 427×240 @ 400 kbps · 854×480 @ **1 Mbps** | the same two | about 1.4 Mbps; 2 Mbps or more to be safe |
124
+
125
+ - 720p and 480p are available to every project. 1080p is available to projects
126
+ that have it enabled (request it from your project's Settings in the VoltKit
127
+ dashboard), and to your first project during the free trial. Asking for more
128
+ than the project allows sends the highest it does allow.
129
+ - The default is the highest the project allows. The picture is scaled down to
130
+ the quality, never up: capture at least that size for the full picture.
131
+ - The layers follow the picture's real size (a portrait phone, a 4:3 webcam),
132
+ so the browser sends every layer requested. A portrait 720p phone sends
133
+ 360×640 and 720×1280.
134
+ - At 720p and 480p each viewer starts on the top layer and gets a lower one
135
+ only while their connection cannot carry it. 1080p's top layer can need more
136
+ than a viewer's starting estimate (3 Mbps), so a 1080p viewer may start one
137
+ layer down and move up as their connection allows.
138
+ - The server caps each publisher's incoming bitrate for the project's tier
139
+ (4 Mbps up to 720p, 7 Mbps with 1080p, audio included), whatever client is
140
+ used.
141
+
142
+ The full guide, with data use:
143
+ [voltkit.in/docs/video-quality](https://voltkit.in/docs/video-quality).
144
+
145
+ ### When the picture is soft
146
+
147
+ A soft or stuttering picture usually comes from the publisher's device (too
148
+ busy to encode) or their upload (too slow for the top layer), not from the
149
+ service. The client can tell you which.
150
+
151
+ ```ts
152
+ const stats = await client.getVideoStats(); // null when no camera is published
153
+ // { codec: 'H264', quality: '720p', width: 720, height: 1280, fps: 30, bitrate: 2400000,
154
+ // qualityLimitation: 'none', availableOutgoingBitrate: 3900000, layers: [ ... ] }
155
+ ```
156
+
157
+ The top-level fields describe the biggest layer going out; `layers` lists each
158
+ one (`active`, size, frame rate, bitrate). `qualityLimitation` is the browser's
159
+ reason for sending less than asked: `cpu` is the device, `bandwidth` the
160
+ upload, `none` neither (then look at the camera and the light). Bitrates are
161
+ averaged since your previous call, so call it every second or two; the first
162
+ call reports 0.
163
+
164
+ `videoLimited` tells you when that changes, so you can tell the publisher:
165
+
166
+ ```ts
167
+ client.on('videoLimited', ({ reason }) => {
168
+ if (reason === 'cpu') showNotice('Your device is busy, so the stream is softer. Turn off effects or switch to 480p.');
169
+ else if (reason === 'bandwidth') showNotice('Your upload is slow, so viewers get a lighter picture.');
170
+ else hideNotice(); // 'none': cleared; 'other': rare
171
+ });
172
+ ```
173
+
174
+ It fires once a new reason has held for about 4 seconds, so brief spikes stay
175
+ quiet, and never fires `none` first. The client checks every 2 seconds, and
176
+ only while a camera is published and something listens. `unpublish()` fires
177
+ `none` if a limitation was showing.
178
+
179
+ On a viewer, `getReceiveStats(producerId)` (the `producerId` from the `track`
180
+ event) says what arrives: size, frame rate, bitrate, `packetsLost`, `jitter`
181
+ and, where the browser counts them, `freezeCount`. A viewer receiving a
182
+ smaller picture than the publisher's biggest layer is on a lower one, picked
183
+ for their own connection; if every viewer is, look at the publisher's
184
+ `getVideoStats()`.
185
+
186
+ The [troubleshooting guide](https://voltkit.in/docs/troubleshooting) lists the
187
+ usual causes and what to do about each.
188
+
189
+ ### Small tiles
190
+
191
+ Each viewer gets the biggest layer their connection carries, which a thumbnail
192
+ or a row of co-host tiles does not need. Ask for a smaller one with the
193
+ `producerId` from the `track` event:
194
+
195
+ ```ts
196
+ client.on('track', ({ kind, producerId, track }) => {
197
+ if (kind !== 'video') return;
198
+ showVideo(producerId, track);
199
+ if (isSmallTile(producerId)) client.setPreferredLayers(producerId, 0).catch(console.warn);
200
+ });
201
+
202
+ await client.setPreferredLayers(producerId, 2); // the tile grew: the biggest layer again
203
+ ```
204
+
205
+ Layer 0 is the smallest copy the publisher sends. At 720p a computer sends
206
+ three (320×180, 640×360 and 1280×720) and a phone two (640×360 and 1280×720);
207
+ a layer above the biggest means the biggest. The 640×360 copy needs about
208
+ 0.76 Mbps, the full picture about 2.6. An optional third argument, the
209
+ temporal layer, lowers the frame rate as well; without it the full frame rate
210
+ is kept. It is the most this viewer is sent: a connection that cannot carry it
211
+ still gets less. The choice is kept across reconnects and forgotten when the
212
+ track ends, and `setPreferredLayers` rejects for a video this client is not
213
+ receiving.
214
+
72
215
  ### Music
73
216
 
74
217
  A host can play music to the room from inside the page. It does not go through
@@ -138,7 +281,8 @@ await client.getRoomState();
138
281
  | `kicked` / `roomClosed` | you were removed, or the host ended the room |
139
282
  | `error` | something failed that the SDK could not recover from by itself |
140
283
  | `usageLimit` | your project ran out of minutes or hit a usage limit; the session ends at `endsAt` unless it is topped up |
141
- | `closed` | terminal — `replaced`, `kicked`, `room-closed` or `gave-up`; your own `close()` does not fire it |
284
+ | `videoLimited` | your camera video is held back by this device (`cpu`) or the upload (`bandwidth`), or that cleared (`none`) |
285
+ | `closed` | terminal — `replaced`, `kicked`, `room-closed` or `gave-up`, or `left` when your own `close()` ends the session |
142
286
 
143
287
  `on()` returns a function that removes the listener.
144
288
 
@@ -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;
@@ -1 +1 @@
1
- {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/chat.ts"],"names":[],"mappings":"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"}
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
- await this.openSocket();
71
- const result = (await this.rpc('join', { token: this.token }));
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
- if (!this.closedByUs)
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
  });
@@ -1 +1 @@
1
- {"version":3,"file":"chat.js","sourceRoot":"","sources":["../../src/chat.ts"],"names":[],"mappings":"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"}
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"}
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.H264_CONTENT_TYPE = void 0;
4
+ exports.currentEnv = currentEnv;
5
+ exports.isPhoneOrTablet = isPhoneOrTablet;
6
+ exports.isAppleMobile = isAppleMobile;
7
+ exports.defaultLayerCount = defaultLayerCount;
8
+ exports.currentProbe = currentProbe;
9
+ exports.h264HardwareEncode = h264HardwareEncode;
10
+ exports.normalizeCodec = normalizeCodec;
11
+ exports.chooseCodec = chooseCodec;
12
+ exports.findCodec = findCodec;
13
+ /** The browser this runs in; an empty desktop-like one outside a browser. */
14
+ function currentEnv() {
15
+ if (typeof navigator === 'undefined')
16
+ return { userAgent: '', maxTouchPoints: 0 };
17
+ const nav = navigator;
18
+ const mobile = nav.userAgentData?.mobile;
19
+ return {
20
+ userAgent: typeof nav.userAgent === 'string' ? nav.userAgent : '',
21
+ ...(typeof mobile === 'boolean' ? { uaMobile: mobile } : {}),
22
+ maxTouchPoints: typeof nav.maxTouchPoints === 'number' ? nav.maxTouchPoints : 0,
23
+ };
24
+ }
25
+ // iPadOS asks for desktop sites, so an iPad says "Macintosh". No Mac has a
26
+ // touch screen, so one that reports touch points is an iPad.
27
+ const isIPadOS = (env) => /Macintosh/.test(env.userAgent) && env.maxTouchPoints > 1;
28
+ /**
29
+ * A phone or a tablet. `userAgentData.mobile` is false on Android tablets, so
30
+ * the user agent is checked as well.
31
+ */
32
+ function isPhoneOrTablet(env = currentEnv()) {
33
+ if (env.uaMobile === true)
34
+ return true;
35
+ if (/Android|iPhone|iPad|iPod|Mobile/.test(env.userAgent))
36
+ return true;
37
+ return isIPadOS(env);
38
+ }
39
+ /** An iPhone, iPad or iPod: every one of them encodes H.264 in hardware. */
40
+ function isAppleMobile(env = currentEnv()) {
41
+ return /iPhone|iPad|iPod/.test(env.userAgent) || isIPadOS(env);
42
+ }
43
+ /** Two layers on phones and tablets, three elsewhere. */
44
+ function defaultLayerCount(env = currentEnv()) {
45
+ return isPhoneOrTablet(env) ? 2 : 3;
46
+ }
47
+ /** The browser's own probe, when it has one. */
48
+ function currentProbe() {
49
+ if (typeof navigator === 'undefined')
50
+ return undefined;
51
+ const capabilities = navigator.mediaCapabilities;
52
+ if (!capabilities || typeof capabilities.encodingInfo !== 'function')
53
+ return undefined;
54
+ return (configuration) => capabilities.encodingInfo(configuration);
55
+ }
56
+ /** The H.264 the media server takes: constrained baseline, packetization mode 1. */
57
+ exports.H264_CONTENT_TYPE = 'video/H264;profile-level-id=42e01f;packetization-mode=1';
58
+ const PROBE_TIMEOUT_MS = 1500;
59
+ /**
60
+ * Whether this browser encodes H.264 at this size and bitrate in hardware:
61
+ * true or false when it says so, null when it cannot say (no
62
+ * `mediaCapabilities`, no `webrtc` support in it, an error, or no answer in
63
+ * time). Publishing never waits on it for more than a moment.
64
+ */
65
+ async function h264HardwareEncode(video, probe = currentProbe(), timeoutMs = PROBE_TIMEOUT_MS) {
66
+ if (!probe)
67
+ return null;
68
+ let timer;
69
+ try {
70
+ const answer = probe({
71
+ type: 'webrtc',
72
+ video: {
73
+ contentType: exports.H264_CONTENT_TYPE,
74
+ width: Math.round(video.width),
75
+ height: Math.round(video.height),
76
+ bitrate: video.bitrate,
77
+ framerate: 30,
78
+ },
79
+ });
80
+ const late = new Promise((resolve) => {
81
+ timer = setTimeout(() => resolve(null), timeoutMs);
82
+ });
83
+ const info = await Promise.race([answer, late]);
84
+ if (!info)
85
+ return null;
86
+ return Boolean(info.supported && info.powerEfficient);
87
+ }
88
+ catch {
89
+ return null;
90
+ }
91
+ finally {
92
+ if (timer !== undefined)
93
+ clearTimeout(timer);
94
+ }
95
+ }
96
+ /** 'vp8' or 'h264' in any case; anything else, including nothing, is 'auto'. */
97
+ function normalizeCodec(codec) {
98
+ const name = typeof codec === 'string' ? codec.toLowerCase() : '';
99
+ return name === 'vp8' || name === 'h264' ? name : 'auto';
100
+ }
101
+ /**
102
+ * The codec to publish with.
103
+ *
104
+ * 'auto' is H.264 on a phone or tablet that encodes it in hardware, and VP8
105
+ * everywhere else: computers encode VP8 well, and a few desktop browsers
106
+ * cannot decode H.264. When the probe cannot say, an Apple device is taken to
107
+ * have hardware H.264 (they all do) and anything else is not.
108
+ */
109
+ function chooseCodec(input) {
110
+ if (input.requested === 'h264') {
111
+ return input.h264Available
112
+ ? { codec: 'h264' }
113
+ : { codec: 'vp8', warning: 'H.264 was asked for, but this browser cannot send it to this server: publishing VP8 instead' };
114
+ }
115
+ if (input.requested === 'vp8')
116
+ return { codec: 'vp8' };
117
+ if (!input.phoneOrTablet || !input.h264Available)
118
+ return { codec: 'vp8' };
119
+ return { codec: (input.h264Hardware ?? input.appleMobile) ? 'h264' : 'vp8' };
120
+ }
121
+ /**
122
+ * The device's own capability entry for a codec, to hand to `produce()`.
123
+ * Only ever pass `produce()` an entry from the device's send capabilities:
124
+ * mediasoup-client adds the transceiver before it checks the codec, so one it
125
+ * cannot match leaves a transceiver behind that breaks every later produce.
126
+ */
127
+ function findCodec(codecs, codec) {
128
+ if (!codecs)
129
+ return undefined;
130
+ if (codec === 'vp8')
131
+ return codecs.find((c) => c.mimeType.toLowerCase() === 'video/vp8');
132
+ return codecs.find((c) => c.mimeType.toLowerCase() === 'video/h264' && Number(c.parameters?.['packetization-mode'] ?? 0) === 1);
133
+ }
134
+ //# sourceMappingURL=device.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device.js","sourceRoot":"","sources":["../../src/device.ts"],"names":[],"mappings":"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"}