@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.
Files changed (38) hide show
  1. package/dist/browser-runtime.js +74 -16
  2. package/dist/browser-runtime.js.map +4 -4
  3. package/dist/catalog-fec-params.d.ts +22 -0
  4. package/dist/catalog-fec-params.d.ts.map +1 -1
  5. package/dist/catalog-fec-params.js +19 -0
  6. package/dist/catalog-fec-params.js.map +2 -2
  7. package/dist/delta-fallback-config.d.ts +42 -0
  8. package/dist/delta-fallback-config.d.ts.map +1 -0
  9. package/dist/delta-fallback-config.js +59 -0
  10. package/dist/delta-fallback-config.js.map +7 -0
  11. package/dist/index.d.ts +3 -2
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +8 -0
  14. package/dist/index.js.map +2 -2
  15. package/dist/media-router.d.ts +19 -8
  16. package/dist/media-router.d.ts.map +1 -1
  17. package/dist/media-router.js +25 -15
  18. package/dist/media-router.js.map +2 -2
  19. package/dist/mmtp-container-parser.no-modules.js.map +1 -1
  20. package/dist/multicast-manager.js.map +2 -2
  21. package/node_modules/@blockcast/mmt-fec/dist/index.d.ts +1 -1
  22. package/node_modules/@blockcast/mmt-fec/dist/index.d.ts.map +1 -1
  23. package/node_modules/@blockcast/mmt-fec/dist/index.js +1 -1
  24. package/node_modules/@blockcast/mmt-fec/dist/index.js.map +1 -1
  25. package/node_modules/@blockcast/mmt-fec/dist/repair-group.d.ts +86 -0
  26. package/node_modules/@blockcast/mmt-fec/dist/repair-group.d.ts.map +1 -1
  27. package/node_modules/@blockcast/mmt-fec/dist/repair-group.js +135 -0
  28. package/node_modules/@blockcast/mmt-fec/dist/repair-group.js.map +1 -1
  29. package/node_modules/@blockcast/mmt-fec/package.json +3 -1
  30. package/node_modules/@blockcast/mmt-fec/src/index.ts +4 -0
  31. package/node_modules/@blockcast/mmt-fec/src/repair-group.ts +176 -0
  32. package/node_modules/@blockcast/mmt-fec/test-vectors/repair-epoch.json +119 -0
  33. package/package.json +8 -7
  34. package/src/catalog-fec-params.ts +47 -0
  35. package/src/delta-fallback-config.ts +72 -0
  36. package/src/index.ts +8 -0
  37. package/src/media-router.ts +47 -22
  38. package/test-vectors/catalog-timing.json +336 -0
@@ -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 positiveNumber = (input) => typeof input === "number" && Number.isFinite(input) && input > 0;
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 && !positiveNumber(keyframeIntervalMs) || keyframeIntervalTicks !== void 0 && !positiveInteger2(keyframeIntervalTicks)) {
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
- if (typeof cfg.framerate !== "number" || !Number.isFinite(cfg.framerate) || cfg.framerate <= 0) {
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,