lib/util
Helpers shared by the streaming cores and the dashboard: a small FIFO queue, the human-readable labels for wire values, the decodability checks that keep a client from asking for a stream it cannot play, the route prefix and localStorage namespace every caller derives the same way, and whether the server answers at all before a page reloads into it.
Classes
Queue
Defined in: lib/util.js:17
A FIFO queue over an array.
Constructors
Constructor
new Queue(...elements): Queue;Defined in: lib/util.js:19
Parameters
| Parameter | Type | Description |
|---|---|---|
...elements | any[] | Initial items, enqueued in order. |
Returns
Properties
items
items: any[];Defined in: lib/util.js:21
Methods
enqueue()
enqueue(...elements): void;Defined in: lib/util.js:27
Parameters
| Parameter | Type | Description |
|---|---|---|
...elements | any[] | Items appended in order. |
Returns
void
dequeue()
dequeue(count?): any;Defined in: lib/util.js:36
Removes the oldest count items.
Parameters
| Parameter | Type | Default value | Description |
|---|---|---|---|
count? | number | 1 | How many items to drop. |
Returns
any
The oldest of the removed items.
size()
size(): number;Defined in: lib/util.js:41
Returns
number
isEmpty()
isEmpty(): boolean;Defined in: lib/util.js:46
Returns
boolean
toArray()
toArray(): any[];Defined in: lib/util.js:51
Returns
any[]
A copy of the items, oldest first.
remove()
remove(element): void;Defined in: lib/util.js:56
Removes the first occurrence of element.
Parameters
| Parameter | Type |
|---|---|
element | any |
Returns
void
find()
find(element): boolean;Defined in: lib/util.js:62
Parameters
| Parameter | Type |
|---|---|
element | any |
Returns
boolean
Whether element is queued.
clear()
clear(): void;Defined in: lib/util.js:67
Drops every item.
Returns
void
Variables
DISPLAY_LABELS
const DISPLAY_LABELS: object;Defined in: lib/util.js:82
Human-readable names for the wire values surfaced in UIs (transport modes, encoders, rate-control modes). The raw values are what the server APIs speak and stay untouched; unknown values fall through unchanged so new wire values render as-is. Locale-invariant technical terms, so they live here once rather than in every dashboard's translation dictionaries.
Type Declaration
websockets
websockets: string = "WebSockets";webrtc
webrtc: string = "WebRTC";h264enc
h264enc: string = "H.264";h265enc
h265enc: string = "H.265";vp8enc
vp8enc: string = "VP8";vp9enc
vp9enc: string = "VP9";av1enc
av1enc: string = "AV1";h264enc-striped
"h264enc-striped": string = "H.264 (Striped)";jpeg
jpeg: string = "JPEG (Striped)";cbr
cbr: string = "CBR (Constant Bitrate)";crf
crf: string = "CRF (Constant Quality)";auto
auto: string = "Auto";h264
h264: string = "H.264";h265
h265: string = "H.265";vp8
vp8: string = "VP8";vp9
vp9: string = "VP9";av1
av1: string = "AV1";mjpeg
mjpeg: string = "MJPEG";DECODER_PROBE_TIMEOUT_MS
const DECODER_PROBE_TIMEOUT_MS: 10000 = 10000;Defined in: lib/util.js:117
How long an engine is given to answer a decoder probe, and a page's first stream decoder configuration before the core's no-output watchdog counts the wait. A decoder that stalls instead of answering must not hold the session up: the answer settles one setting, while a session waits on it to start. Measured answers are immediate, the first in a page costing a media stack its warm-up.
decoderSupportReady
const decoderSupportReady: Promise<{
}>;Defined in: lib/util.js:168
Resolves once every codec has been asked of the decoder. Menus built before it resolves offer every codec an engine with WebCodecs might play, and are rebuilt from the answer.
h264FramingReady
const h264FramingReady: Promise<string>;Defined in: lib/util.js:185
How this engine's VideoDecoder takes H.264: annexb where a key frame in
Annex B form decodes (Chromium, Firefox), avcc where it is refused and an
avcC description with length-prefixed NAL units is needed instead (WebKit).
Asked once, of a 16x16 key frame, in a worker so a slow refusal never holds
the page; annexb without WebCodecs or when nothing answers.
isMobileClient
const isMobileClient: boolean;Defined in: lib/util.js:561
Whether the client is touch-first: its primary pointer is coarse. True on phones and tablets, false on desktops -- including touch-screen laptops, whose primary pointer is still the pointing device. The form factor is fixed for the life of the document, so it is resolved once and available to every first render; a touch-capable device this misses is still caught by the first touchstart.
Functions
displayLabel()
function displayLabel(value): string;Defined in: lib/util.js:107
Parameters
| Parameter | Type | Description |
|---|---|---|
value | string | A wire value. |
Returns
string
Its display label, or the value itself when it has none.
decoderAccepts()
function decoderAccepts(
codec,
width,
height
): Promise<boolean>;Defined in: lib/util.js:128
Whether a VideoDecoder here accepts codec at width x height. False
without WebCodecs, and when the engine throws on the question; null when it
gives no answer within DECODER_PROBE_TIMEOUT_MS, which is not a refusal.
Parameters
| Parameter | Type | Description |
|---|---|---|
codec | string | A WebCodecs codec string. |
width | number | - |
height | number | - |
Returns
Promise<boolean>
h264Framing()
function h264Framing(): string;Defined in: lib/util.js:218
Returns
string
The framing h264FramingReady settled on; annexb until it has.
canDecodeEncoder()
function canDecodeEncoder(encoder): boolean;Defined in: lib/util.js:231
Whether this engine can play an encoder on the WebSocket transport: every
video mode decodes through WebCodecs' VideoDecoder, whose answer per codec
is read once it is in, while jpeg (striped JPEG painted through
createImageBitmap) needs nothing. An engine without WebCodecs therefore
still streams: the core's pre-flight pins jpeg instead of failing, and the
settings offer nothing it cannot play. The WebRTC transport decodes in the
browser's media stack and is not subject to this.
Parameters
| Parameter | Type | Description |
|---|---|---|
encoder | string | An encoder wire value. |
Returns
boolean
canReceiveEncoder()
function canReceiveEncoder(encoder): boolean;Defined in: lib/util.js:250
Whether this engine's own WebRTC stack receives an encoder's codec, from
RTCRtpReceiver.getCapabilities; an engine that cannot answer the question
is given the benefit of the doubt, and the server's negotiation fallback
answers a codec it declines.
Parameters
| Parameter | Type | Description |
|---|---|---|
encoder | string | An encoder wire value. |
Returns
boolean
canPlayEncoder()
function canPlayEncoder(encoder, webrtc): boolean;Defined in: lib/util.js:270
Whether this engine plays an encoder on a transport: canDecodeEncoder on
WebSockets, canReceiveEncoder on WebRTC. A menu lists what it cannot play
disabled and marked, so a missing option reads as the browser's limit and
never as the server's.
Parameters
| Parameter | Type | Description |
|---|---|---|
encoder | string | An encoder wire value. |
webrtc | boolean | Whether the transport is WebRTC. |
Returns
boolean
canDecodeFullColor()
function canDecodeFullColor(codec?): Promise<boolean>;Defined in: lib/util.js:291
Whether this engine's VideoDecoder will take codec at full color (4:4:4).
Engines differ on the 4:4:4 profiles (High 4:4:4 Predictive, HEVC RExt, VP9 profile 1), and one whose decoder lacks them cannot show the stream at all rather than showing it worse, so full color is asked of the decoder before it is asked of the server. Which engines have them changes with their releases, which is why this probes instead of naming them. The profile is the whole question, so it is asked with the constraint bits the encoders emit, at the smallest frame the level allows, since a level is a ceiling and a size beyond it is a pair an implementation may reject on its own. What a real stream is decoded with comes from its key frame's parameter sets instead.
Parameters
| Parameter | Type | Default value | Description |
|---|---|---|---|
codec? | string | "h264" | The codec name, h264 by default. |
Returns
Promise<boolean>
False for a codec without 4:4:4, and where there
is no VideoDecoder at all.
fullColorDecoded()
function fullColorDecoded(codec): boolean;Defined in: lib/util.js:314
What canDecodeFullColor answered for codec, for a decision that cannot
wait on the probe: undefined while it is still out or was never asked.
Parameters
| Parameter | Type | Description |
|---|---|---|
codec | string | The codec name. |
Returns
boolean
tenBitFormat()
function tenBitFormat(codec, fullcolor?): string;Defined in: lib/util.js:328
The name a 10-bit format goes by in TEN_BIT_SAMPLES, in tenBitDecoded, and
in a WebRTC hello: the codec name for 4:2:0, with 444 after it for 4:4:4.
Parameters
| Parameter | Type | Default value | Description |
|---|---|---|---|
codec | string | undefined | The codec name. |
fullcolor? | boolean | false | Whether the format is 4:4:4. |
Returns
string
canDecodeTenBit()
function canDecodeTenBit(codec, fullcolor?): Promise<boolean>;Defined in: lib/util.js:345
Whether this engine's VideoDecoder shows a picture of codec at 10 bits.
The decoder is handed a real 10-bit key frame (TEN_BIT_SAMPLES) and has to
give a frame back, configured as a stream's decoder is, from the key frame's
own codec string: engines accept 10-bit configurations they then fail to
decode (Firefox and VP9 profile 2), and whether a profile decodes turns on
the client's hardware where the engine has no software decoder for the codec
(H.265 everywhere), so nothing short of a decode answers it.
Parameters
| Parameter | Type | Default value | Description |
|---|---|---|---|
codec | string | undefined | The codec name. |
fullcolor? | boolean | false | Whether to ask for the codec's 4:4:4 at 10 bits. |
Returns
Promise<boolean>
False for a format without a sample, where there
is no VideoDecoder, and where no frame comes back within
DECODER_PROBE_TIMEOUT_MS.
tenBitDecoded()
function tenBitDecoded(codec, fullcolor?): boolean;Defined in: lib/util.js:383
What canDecodeTenBit answered, for a decision that cannot wait on the
decode: undefined while it is still out or was never asked.
Parameters
| Parameter | Type | Default value | Description |
|---|---|---|---|
codec | string | undefined | The codec name. |
fullcolor? | boolean | false | Whether the format is 4:4:4. |
Returns
boolean
getRoutePrefix()
function getRoutePrefix(): string;Defined in: lib/util.js:392
Directory this document is served from, without a trailing slash ('' at
the server root). Every request the client builds hangs off it, so a
deployment reverse-proxied under a subfolder reaches its own routes, and an
iframed client reads its own path instead of the frame's.
Returns
string
The path prefix, e.g. /desk.
serverAnswers()
function serverAnswers(url, headers): Promise<Response>;Defined in: lib/util.js:413
The server's answer to a plain GET on one of its endpoints, or null where it gave none: nothing answered within SERVER_ANSWER_MS (a path that swallows packets holds a fetch open for minutes), or the answer says it is not up (502, 503, 504: a gateway in front of a stopped server, or the server itself still starting). A page reloaded into a server stopping or starting lands on an error page with nothing left to retry, so a core reloads only once this returns an answer.
Parameters
| Parameter | Type | Description |
|---|---|---|
url | string | - |
headers | { } | - |
Returns
Promise<Response>
entryPageTag()
function entryPageTag(headers?): Promise<string>;Defined in: lib/util.js:429
The validators (ETag, Last-Modified) the server answers for the page's
own entry document now: two answers differ when a new build is served.
Parameters
| Parameter | Type | Description |
|---|---|---|
headers? | { } | Credentials the page's API calls carry. |
Returns
Promise<string>
Null when the server does not answer.
getStorageAppName()
function getStorageAppName(): string;Defined in: lib/util.js:448
The localStorage namespace every stored key is prefixed with.
Origin and pathname only, not the full URL: a per-session ?token= must
not mint a new namespace on each connect. Cores and dashboards share one
prefix, so this derivation is the single one they all call.
Returns
string
Sanitized namespace, empty outside a browser.
isMacDesktop()
function isMacDesktop(): boolean;Defined in: lib/util.js:463
macOS proper, a narrower question than the Mac family navigator.platform
names: an iPad in its desktop-class default reports MacIntel like a Mac
does, and its touch points are what tell the two apart. navigator.platform
decides and the client hint is only a fallback for an engine that has
dropped the deprecated field, since the question is which pointer
acceleration curve the OS applies, not which brand the browser reports.
Returns
boolean
pageTabId()
function pageTabId(): string;Defined in: lib/util.js:476
This browser tab's id, kept in its sessionStorage: a reload of the page keeps it and another tab has its own, which is how the server tells a page taking its own display back from another page joining it.
Returns
string
Null where the tab has no storage.
ccStartKey()
function ccStartKey(displayId): string;Defined in: lib/util.js:495
The localStorage key of a display's remembered start rate, per origin as every key is.
Parameters
| Parameter | Type |
|---|---|
displayId | any |
Returns
string
rememberCcStart()
function rememberCcStart(displayId, kbps): void;Defined in: lib/util.js:505
Keep the rate congestion control held a display at, as its server reports it, so a restarted server starts the page's next stream there rather than at the configured rate.
Parameters
| Parameter | Type | Description |
|---|---|---|
displayId | string | - |
kbps | number | - |
Returns
void
recalledCcStart()
function recalledCcStart(displayId): number;Defined in: lib/util.js:517
The display's remembered start rate, or null: none kept, a day old, or unreadable.
Parameters
| Parameter | Type | Description |
|---|---|---|
displayId | string | - |
Returns
number
forgetCcStart()
function forgetCcStart(displayId): void;Defined in: lib/util.js:531
Drop the display's remembered start rate, once the user sets a bitrate of their own.
Parameters
| Parameter | Type | Description |
|---|---|---|
displayId | string | - |
Returns
void
isSkiaWebKit()
function isSkiaWebKit(userAgent, platform): boolean;Defined in: lib/util.js:547
WebKit's Linux ports (WPE, WebKitGTK), which draw a canvas through Skia's GPU context, as against Safari, which draws through CoreGraphics. No capability tells the two apart and WebKit on Linux can carry Safari's macOS user agent, so the engine is read from the user agent and the OS from the platform, both of which a worker has too.
Parameters
| Parameter | Type | Description |
|---|---|---|
userAgent | string | navigator.userAgent. |
platform | string | navigator.platform. |
Returns
boolean
isCaptureRefusal()
function isCaptureRefusal(error): boolean;Defined in: lib/util.js:573
Whether a capture the server asked for failed for good: permission withheld, or no getUserMedia at all. A busy camera or an unmet constraint may clear by the next demand.
Parameters
| Parameter | Type | Description |
|---|---|---|
error | any | The rejection from getUserMedia, or the capture's own error. |
Returns
boolean
True where asking again could not succeed.
References
codecOfEncoder
Re-exports codecOfEncoder
codecCarriesFullColor
Re-exports codecCarriesFullColor
codecCarriesTenBit
Re-exports codecCarriesTenBit