Network and CDN
mattebox@0.12.1
This chapter covers the transport: retries, request and response hooks, replacing fetch, and the two CDN stages.
Transport options
Every request the engine makes goes through one transport. Configure it on
mattebox().
const engine = mattebox({
stages: [hlsCmaf()],
transport: {
retry: { maxAttempts: 3, baseDelayMs: 500, factor: 2, maxDelayMs: 8000 },
requestHooks: [(req) => { req.headers.Authorization = `Bearer ${token}`; }],
responseHooks: [(res) => log(res.url, res.status, res.rtt)],
},
});
| Option | Meaning |
|---|---|
retry |
Attempts, backoff, and which HTTP statuses retry |
requestHooks |
Run before each request. May change the URL, headers, and timeout |
responseHooks |
Run after each response with status, round-trip time, size, and outcome |
fetchImpl |
Replaces fetch entirely |
Request hooks see every request: manifests, segments, license requests, steering manifests, thumbnail tracks. One hook adds auth everywhere.
fetchImpl
fetchImpl replaces fetch. Use it in tests to limit bandwidth, delay
responses, or fail a URL.
const engine = mattebox({
stages: [hlsCmaf(), abr()],
transport: {
fetchImpl: async (url, init) => {
if (url.includes('segment-7')) return new Response(null, { status: 404 });
return fetch(url, init);
},
},
});
The cmcd stage
Common Media Client Data tells the CDN what the player is doing: the active
bitrate, the measured throughput, the buffer ahead, and the object type of
each request. The cmcd stage sends it as a query argument or as headers.
import cmcd from 'mattebox/stages/cmcd';
cmcd({ contentId: 'episode-42', mode: 'query', sessionId: crypto.randomUUID() });
| Option | Meaning |
|---|---|
contentId |
A stable content id, sent as cid |
mode |
query appends a CMCD argument. header sends CMCD-* headers |
sessionId |
Overrides the generated session id |
| Key | Value |
|---|---|
sid |
The session id |
cid |
The content id, when given |
ot |
The object type: m manifest, av media, a audio, c captions |
br |
The active rendition’s bitrate, in kbps |
mtp |
The measured throughput, in kbps, to 100 kbps |
bl |
The buffer ahead of the playhead, in ms, to 100 ms |
su |
Starting up or rebuffering: less than one second of buffer |
nor |
The next segment’s path, relative to this request, so the CDN can prefetch it |
nrr |
The next segment’s byte range, when it is a range request |
The stage sends CMCD version 1 (CTA-5004), which defines all of these keys.
Headers need a CORS preflight. Use query unless your CDN prefers headers.
The cmsd stage
Common Media Server Data (CTA-5006) is the reverse of CMCD: the CDN tells
the player about the delivery in response headers. The cmsd stage reads
CMSD-Dynamic on every response. It is in full; add it to another preset
with stages.
import cmsd from 'mattebox/stages/cmsd';
const engine = hls({ stages: [cmsd()] });
| Key | Effect |
|---|---|
etp |
The server’s throughput estimate. ABR uses the lower of it and its own, and it alone before its first measurement |
mb |
The maximum bitrate the server suggests, applied as the cmsd constraint (maxBitrate) |
When several servers append to the header, the stage reads the one nearest the player, the last in the list. A response without the header changes nothing.
For a CDN on another origin, the browser hides the header unless the CDN
sends Access-Control-Expose-Headers: CMSD-Dynamic.
The content-steering stage
Content steering lets a steering server move viewers between CDNs. HLS
declares pathways on variants, DASH on BaseURL elements. The stage handles
both, follows the steering manifest’s priority order, and fails over when
the active pathway returns errors.
import contentSteering from 'mattebox/stages/content-steering';
const engine = mattebox({ stages: [hlsCmaf(), dashCmaf(), contentSteering()] });
engine.on('steering:failover', ({ from, to }) => console.log(`pathway ${from} -> ${to}`));
Nothing to configure. The steering server URL comes from the manifest.
Example
A player that authenticates every request, reports CMCD, and follows steering.
import { mattebox } from 'mattebox';
import hlsCmaf from 'mattebox/protocols/hls-cmaf';
import abr from 'mattebox/stages/abr';
import cmcd from 'mattebox/stages/cmcd';
import contentSteering from 'mattebox/stages/content-steering';
const engine = mattebox({
stages: [hlsCmaf(), abr(), cmcd({ contentId: 'episode-42' }), contentSteering()],
transport: {
retry: { maxAttempts: 4 },
requestHooks: [(req) => { req.headers.Authorization = `Bearer ${token}`; }],
},
});
Next: 12 Diagnostics.