@blockcast/mmt-container 0.3.0-main.4c73d3ecc2db → 0.3.0-main.61f6a400e7ac
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/dist/browser-runtime.js +74 -16
- package/dist/browser-runtime.js.map +4 -4
- package/dist/catalog-fec-params.d.ts +22 -0
- package/dist/catalog-fec-params.d.ts.map +1 -1
- package/dist/catalog-fec-params.js +19 -0
- package/dist/catalog-fec-params.js.map +2 -2
- package/dist/delta-fallback-config.d.ts +42 -0
- package/dist/delta-fallback-config.d.ts.map +1 -0
- package/dist/delta-fallback-config.js +59 -0
- package/dist/delta-fallback-config.js.map +7 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -0
- package/dist/index.js.map +2 -2
- package/dist/media-router.d.ts +19 -8
- package/dist/media-router.d.ts.map +1 -1
- package/dist/media-router.js +25 -15
- package/dist/media-router.js.map +2 -2
- package/dist/mmtp-container-parser.no-modules.js.map +1 -1
- package/dist/multicast-manager.js.map +2 -2
- package/node_modules/@blockcast/mmt-fec/dist/index.d.ts +1 -1
- package/node_modules/@blockcast/mmt-fec/dist/index.d.ts.map +1 -1
- package/node_modules/@blockcast/mmt-fec/dist/index.js +1 -1
- package/node_modules/@blockcast/mmt-fec/dist/index.js.map +1 -1
- package/node_modules/@blockcast/mmt-fec/dist/repair-group.d.ts +86 -0
- package/node_modules/@blockcast/mmt-fec/dist/repair-group.d.ts.map +1 -1
- package/node_modules/@blockcast/mmt-fec/dist/repair-group.js +135 -0
- package/node_modules/@blockcast/mmt-fec/dist/repair-group.js.map +1 -1
- package/node_modules/@blockcast/mmt-fec/package.json +3 -1
- package/node_modules/@blockcast/mmt-fec/src/index.ts +4 -0
- package/node_modules/@blockcast/mmt-fec/src/repair-group.ts +176 -0
- package/node_modules/@blockcast/mmt-fec/test-vectors/repair-epoch.json +119 -0
- package/package.json +8 -7
- package/src/catalog-fec-params.ts +47 -0
- package/src/delta-fallback-config.ts +72 -0
- package/src/index.ts +8 -0
- package/src/media-router.ts +47 -22
- package/test-vectors/catalog-timing.json +336 -0
package/dist/browser-runtime.js
CHANGED
|
@@ -6700,7 +6700,7 @@ function validateCmsfMmtpCatalog(value) {
|
|
|
6700
6700
|
const tracks = catalog["tracks"];
|
|
6701
6701
|
const trackRecords = [];
|
|
6702
6702
|
const positiveInteger2 = (input) => Number.isSafeInteger(input) && input > 0;
|
|
6703
|
-
const
|
|
6703
|
+
const positiveNumber2 = (input) => typeof input === "number" && Number.isFinite(input) && input > 0;
|
|
6704
6704
|
for (let index = 0; index < tracks.length; index++) {
|
|
6705
6705
|
const raw = tracks[index];
|
|
6706
6706
|
const path = `$.tracks[${index}]`;
|
|
@@ -6745,7 +6745,7 @@ function validateCmsfMmtpCatalog(value) {
|
|
|
6745
6745
|
if (groupDurationTicks !== void 0 && !positiveInteger2(groupDurationTicks)) {
|
|
6746
6746
|
catalogError("track_group_duration_ticks", `${path}.groupDurationTicks`, "must be a positive integer");
|
|
6747
6747
|
}
|
|
6748
|
-
if (keyframeIntervalMs !== void 0 && !
|
|
6748
|
+
if (keyframeIntervalMs !== void 0 && !positiveNumber2(keyframeIntervalMs) || keyframeIntervalTicks !== void 0 && !positiveInteger2(keyframeIntervalTicks)) {
|
|
6749
6749
|
catalogError("track_keyframe_interval", path, "keyframe interval fields must be positive numbers");
|
|
6750
6750
|
}
|
|
6751
6751
|
if (packaging === "fec-repair") {
|
|
@@ -22299,6 +22299,23 @@ function resolveCatalogTrackGroupDurationMs(catalog, track) {
|
|
|
22299
22299
|
const renditions = track.type === "audio" ? catalog?.audio?.renditions : catalog?.video?.renditions;
|
|
22300
22300
|
return catalogGroupDurationMs(renditions?.[track.name]);
|
|
22301
22301
|
}
|
|
22302
|
+
function positiveNumber(value) {
|
|
22303
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : void 0;
|
|
22304
|
+
}
|
|
22305
|
+
function catalogKeyframeCadenceMs(rendition) {
|
|
22306
|
+
if (!rendition) return void 0;
|
|
22307
|
+
const timescale = positiveNumber(rendition.timescale);
|
|
22308
|
+
const ticksToMs = (ticks) => {
|
|
22309
|
+
const value = positiveNumber(ticks);
|
|
22310
|
+
return value !== void 0 && timescale !== void 0 ? value * 1e3 / timescale : void 0;
|
|
22311
|
+
};
|
|
22312
|
+
return ticksToMs(rendition.keyframeIntervalTicks) ?? positiveNumber(rendition.keyframeIntervalMs) ?? ticksToMs(rendition.keyframeDurationTicks) ?? positiveNumber(rendition.keyframeDurationMs) ?? ticksToMs(rendition.gopDurationTicks) ?? positiveNumber(rendition.gopDurationMs);
|
|
22313
|
+
}
|
|
22314
|
+
function catalogFecMediaUnitsPerSecond(type, rendition, endpointSampleRate) {
|
|
22315
|
+
if (type === "video") return positiveNumber(rendition?.framerate);
|
|
22316
|
+
const sampleRate = positiveNumber(endpointSampleRate ?? rendition?.sampleRate ?? rendition?.timescale);
|
|
22317
|
+
return sampleRate === void 0 ? void 0 : sampleRate / 1024;
|
|
22318
|
+
}
|
|
22302
22319
|
var NO_FEC = {
|
|
22303
22320
|
fecK: 0,
|
|
22304
22321
|
fecRepairCount: 0,
|
|
@@ -24380,6 +24397,28 @@ var TrackSourceConflictError = class extends Error {
|
|
|
24380
24397
|
};
|
|
24381
24398
|
var DEFAULT_CROSSFADE_FRAMES = 10;
|
|
24382
24399
|
var DEFAULT_MAX_OVERLAY_BUFFER = 128;
|
|
24400
|
+
function assertDeltaFallbackConfig(cfg, prefix) {
|
|
24401
|
+
if (!isPositiveFinite2(cfg.framerate)) throw new Error(`${prefix}: framerate required and must be > 0`);
|
|
24402
|
+
if (!isPositiveFinite2(cfg.sourceSymbols))
|
|
24403
|
+
throw new Error(`${prefix}: sourceSymbols (K_delta) required and must be > 0`);
|
|
24404
|
+
if (!isPositiveFinite2(cfg.repairSymbols))
|
|
24405
|
+
throw new Error(`${prefix}: repairSymbols (P_delta) required and must be > 0`);
|
|
24406
|
+
if (cfg.deltaFailWindowBlocks !== void 0 && !(Number.isInteger(cfg.deltaFailWindowBlocks) && cfg.deltaFailWindowBlocks > 0)) {
|
|
24407
|
+
throw new Error(`${prefix}: deltaFailWindowBlocks must be a positive integer when present`);
|
|
24408
|
+
}
|
|
24409
|
+
if (cfg.deltaProbeIntervalMs !== void 0 && !isPositiveFinite2(cfg.deltaProbeIntervalMs))
|
|
24410
|
+
throw new Error(`${prefix}: deltaProbeIntervalMs must be > 0 when present`);
|
|
24411
|
+
if (cfg.interleaveDepthMs !== void 0 && !isPositiveFinite2(cfg.interleaveDepthMs))
|
|
24412
|
+
throw new Error(`${prefix}: interleaveDepthMs must be > 0 when present`);
|
|
24413
|
+
if (cfg.deltaProbeIntervalMs === void 0 && cfg.interleaveDepthMs === void 0) {
|
|
24414
|
+
throw new Error(
|
|
24415
|
+
`${prefix}: either deltaProbeIntervalMs or interleaveDepthMs required for probe interval derivation`
|
|
24416
|
+
);
|
|
24417
|
+
}
|
|
24418
|
+
}
|
|
24419
|
+
function isPositiveFinite2(value) {
|
|
24420
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0;
|
|
24421
|
+
}
|
|
24383
24422
|
var MediaRouter = class {
|
|
24384
24423
|
#active = "moq";
|
|
24385
24424
|
#multicastVideoKeyed = false;
|
|
@@ -24541,20 +24580,7 @@ var MediaRouter = class {
|
|
|
24541
24580
|
* Calling again resets deltaActive=true and clears the window buffer (stream restart).
|
|
24542
24581
|
*/
|
|
24543
24582
|
configureDelta(cfg) {
|
|
24544
|
-
|
|
24545
|
-
throw new Error("[MediaRouter] configureDelta: framerate required and must be > 0");
|
|
24546
|
-
}
|
|
24547
|
-
if (typeof cfg.sourceSymbols !== "number" || cfg.sourceSymbols <= 0) {
|
|
24548
|
-
throw new Error("[MediaRouter] configureDelta: sourceSymbols (K_delta) required and must be > 0");
|
|
24549
|
-
}
|
|
24550
|
-
if (typeof cfg.repairSymbols !== "number" || cfg.repairSymbols <= 0) {
|
|
24551
|
-
throw new Error("[MediaRouter] configureDelta: repairSymbols (P_delta) required and must be > 0");
|
|
24552
|
-
}
|
|
24553
|
-
if (cfg.deltaProbeIntervalMs === void 0 && cfg.interleaveDepthMs === void 0) {
|
|
24554
|
-
throw new Error(
|
|
24555
|
-
"[MediaRouter] configureDelta: either deltaProbeIntervalMs or interleaveDepthMs required for probe interval derivation"
|
|
24556
|
-
);
|
|
24557
|
-
}
|
|
24583
|
+
assertDeltaFallbackConfig(cfg, "[MediaRouter] configureDelta");
|
|
24558
24584
|
this.#deltaWindowSize = cfg.deltaFailWindowBlocks ?? Math.ceil(cfg.framerate);
|
|
24559
24585
|
this.#deltaFailThresholdRatio = cfg.repairSymbols / cfg.sourceSymbols;
|
|
24560
24586
|
this.#deltaRecoverThresholdRatio = this.#deltaFailThresholdRatio / 2;
|
|
@@ -24931,6 +24957,35 @@ var MediaRouter = class {
|
|
|
24931
24957
|
}
|
|
24932
24958
|
};
|
|
24933
24959
|
|
|
24960
|
+
// src/delta-fallback-config.ts
|
|
24961
|
+
function resolveDeltaFallback(base, delta) {
|
|
24962
|
+
const repair = base.fec?.repairTrack;
|
|
24963
|
+
if (!repair) throw new Error(`[delta-fallback] base track "${base.name}" missing fec.repairTrack`);
|
|
24964
|
+
const deltaFec = delta.fec;
|
|
24965
|
+
if (!deltaFec?.repairTrack) throw new Error(`[delta-fallback] delta track "${delta.name}" missing fec.repairTrack`);
|
|
24966
|
+
if (deltaFec.repairTrack !== repair)
|
|
24967
|
+
throw new Error(
|
|
24968
|
+
`[delta-fallback] inconsistent repair tracks: ${base.name} references "${repair}" but ${delta.name} references "${deltaFec.repairTrack}"`
|
|
24969
|
+
);
|
|
24970
|
+
if (!(typeof base.framerate === "number" && Number.isFinite(base.framerate) && base.framerate > 0))
|
|
24971
|
+
throw new Error(`[delta-fallback] base track "${base.name}" missing positive framerate`);
|
|
24972
|
+
if (!(isPositive(deltaFec.sourceSymbols) && isPositive(deltaFec.repairSymbols)))
|
|
24973
|
+
throw new Error(`[delta-fallback] delta track "${delta.name}" missing positive fec.sourceSymbols/repairSymbols`);
|
|
24974
|
+
const config = {
|
|
24975
|
+
framerate: base.framerate,
|
|
24976
|
+
sourceSymbols: deltaFec.sourceSymbols,
|
|
24977
|
+
repairSymbols: deltaFec.repairSymbols,
|
|
24978
|
+
deltaFailWindowBlocks: base.fec?.deltaFailWindowBlocks ?? deltaFec.deltaFailWindowBlocks,
|
|
24979
|
+
deltaProbeIntervalMs: base.fec?.deltaProbeIntervalMs ?? deltaFec.deltaProbeIntervalMs,
|
|
24980
|
+
interleaveDepthMs: base.fec?.interleaveDepthMs ?? deltaFec.interleaveDepthMs
|
|
24981
|
+
};
|
|
24982
|
+
assertDeltaFallbackConfig(config, `[delta-fallback] group ${base.name}/${delta.name}`);
|
|
24983
|
+
return { repairTrackName: repair, config };
|
|
24984
|
+
}
|
|
24985
|
+
function isPositive(value) {
|
|
24986
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0;
|
|
24987
|
+
}
|
|
24988
|
+
|
|
24934
24989
|
// src/align.ts
|
|
24935
24990
|
function secondsFromTicks(ticks, timescale) {
|
|
24936
24991
|
if (!Number.isFinite(ticks)) {
|
|
@@ -26356,8 +26411,10 @@ export {
|
|
|
26356
26411
|
catalogAmtNetworkSource,
|
|
26357
26412
|
catalogDeclaresFec,
|
|
26358
26413
|
catalogFecInterleaveMs,
|
|
26414
|
+
catalogFecMediaUnitsPerSecond,
|
|
26359
26415
|
catalogFecUnavailable,
|
|
26360
26416
|
catalogGroupDurationMs,
|
|
26417
|
+
catalogKeyframeCadenceMs,
|
|
26361
26418
|
catalogRepairTarget,
|
|
26362
26419
|
classifyH264Keyframe,
|
|
26363
26420
|
classifyHevcKeyframe,
|
|
@@ -26455,6 +26512,7 @@ export {
|
|
|
26455
26512
|
repairReachability,
|
|
26456
26513
|
resolveCatalogTrackFec,
|
|
26457
26514
|
resolveCatalogTrackGroupDurationMs,
|
|
26515
|
+
resolveDeltaFallback,
|
|
26458
26516
|
resolveFecState,
|
|
26459
26517
|
resolveGlobalMmtWasmBindings,
|
|
26460
26518
|
resolveGroupDurationMs,
|