@blockcast/mmt-container 0.1.0-main.149f78a4adae
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/README.md +432 -0
- package/dist/.build-stamp +0 -0
- package/dist/__tests__/test-utils.d.ts +71 -0
- package/dist/__tests__/test-utils.d.ts.map +1 -0
- package/dist/align.d.ts +148 -0
- package/dist/align.d.ts.map +1 -0
- package/dist/align.js +88 -0
- package/dist/align.js.map +7 -0
- package/dist/audio-init-parser.d.ts +66 -0
- package/dist/audio-init-parser.d.ts.map +1 -0
- package/dist/audio-init-parser.js +118 -0
- package/dist/audio-init-parser.js.map +7 -0
- package/dist/audio-ring-buffer.d.ts +50 -0
- package/dist/audio-ring-buffer.d.ts.map +1 -0
- package/dist/audio-ring-buffer.js +93 -0
- package/dist/audio-ring-buffer.js.map +7 -0
- package/dist/authored-timing.d.ts +32 -0
- package/dist/authored-timing.d.ts.map +1 -0
- package/dist/authored-timing.js +32 -0
- package/dist/authored-timing.js.map +7 -0
- package/dist/browser-runtime.js +17109 -0
- package/dist/browser-runtime.js.map +7 -0
- package/dist/carp-catalog.d.ts +318 -0
- package/dist/carp-catalog.d.ts.map +1 -0
- package/dist/carp-catalog.js +549 -0
- package/dist/carp-catalog.js.map +7 -0
- package/dist/catalog-fec-params.d.ts +82 -0
- package/dist/catalog-fec-params.d.ts.map +1 -0
- package/dist/catalog-fec-params.js +66 -0
- package/dist/catalog-fec-params.js.map +7 -0
- package/dist/catalog-network-source.d.ts +19 -0
- package/dist/catalog-network-source.d.ts.map +1 -0
- package/dist/catalog-network-source.js +22 -0
- package/dist/catalog-network-source.js.map +7 -0
- package/dist/catalog-validator.d.ts +18 -0
- package/dist/catalog-validator.d.ts.map +1 -0
- package/dist/catalog-validator.js +7747 -0
- package/dist/catalog-validator.js.map +7 -0
- package/dist/cmaf-block-assembler.d.ts +168 -0
- package/dist/cmaf-block-assembler.d.ts.map +1 -0
- package/dist/cmaf-block-assembler.js +1755 -0
- package/dist/cmaf-block-assembler.js.map +7 -0
- package/dist/cmaf-group-batcher.d.ts +38 -0
- package/dist/cmaf-group-batcher.d.ts.map +1 -0
- package/dist/cmaf-group-batcher.js +195 -0
- package/dist/cmaf-group-batcher.js.map +7 -0
- package/dist/cmcd-producer.d.ts +104 -0
- package/dist/cmcd-producer.d.ts.map +1 -0
- package/dist/cmcd-producer.js +207 -0
- package/dist/cmcd-producer.js.map +7 -0
- package/dist/codec-utils.d.ts +235 -0
- package/dist/codec-utils.d.ts.map +1 -0
- package/dist/codec-utils.js +1225 -0
- package/dist/codec-utils.js.map +7 -0
- package/dist/fec-codec.d.ts +32 -0
- package/dist/fec-codec.d.ts.map +1 -0
- package/dist/fec-codec.js +47 -0
- package/dist/fec-codec.js.map +7 -0
- package/dist/fec-manager.d.ts +266 -0
- package/dist/fec-manager.d.ts.map +1 -0
- package/dist/fec-manager.js +1447 -0
- package/dist/fec-manager.js.map +7 -0
- package/dist/fec-starvation-detector.d.ts +59 -0
- package/dist/fec-starvation-detector.d.ts.map +1 -0
- package/dist/fec-starvation-detector.js +75 -0
- package/dist/fec-starvation-detector.js.map +7 -0
- package/dist/fec-worker-setup.d.ts +76 -0
- package/dist/fec-worker-setup.d.ts.map +1 -0
- package/dist/fec-worker-setup.js +603 -0
- package/dist/fec-worker-setup.js.map +7 -0
- package/dist/fmp4-completion.d.ts +30 -0
- package/dist/fmp4-completion.d.ts.map +1 -0
- package/dist/fmp4-completion.js +21 -0
- package/dist/fmp4-completion.js.map +7 -0
- package/dist/fmp4-reader.d.ts +37 -0
- package/dist/fmp4-reader.d.ts.map +1 -0
- package/dist/fmp4-reader.js +100 -0
- package/dist/fmp4-reader.js.map +7 -0
- package/dist/index.d.ts +47 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +330 -0
- package/dist/index.js.map +7 -0
- package/dist/iso-bmff-timing.d.ts +47 -0
- package/dist/iso-bmff-timing.d.ts.map +1 -0
- package/dist/iso-bmff-timing.js +526 -0
- package/dist/iso-bmff-timing.js.map +7 -0
- package/dist/loc.d.ts +68 -0
- package/dist/loc.d.ts.map +1 -0
- package/dist/loc.js +143 -0
- package/dist/loc.js.map +7 -0
- package/dist/manifest-auth-plan.d.ts +30 -0
- package/dist/manifest-auth-plan.d.ts.map +1 -0
- package/dist/manifest-auth-plan.js +1267 -0
- package/dist/manifest-auth-plan.js.map +7 -0
- package/dist/media-router.d.ts +338 -0
- package/dist/media-router.d.ts.map +1 -0
- package/dist/media-router.js +802 -0
- package/dist/media-router.js.map +7 -0
- package/dist/mfu-reassembler.d.ts +264 -0
- package/dist/mfu-reassembler.d.ts.map +1 -0
- package/dist/mfu-reassembler.js +2668 -0
- package/dist/mfu-reassembler.js.map +7 -0
- package/dist/mfu-reassembly-policy.d.ts +24 -0
- package/dist/mfu-reassembly-policy.d.ts.map +1 -0
- package/dist/mfu-reassembly-policy.js +99 -0
- package/dist/mfu-reassembly-policy.js.map +7 -0
- package/dist/mmtp-container-parser.d.ts +304 -0
- package/dist/mmtp-container-parser.d.ts.map +1 -0
- package/dist/mmtp-container-parser.js +5378 -0
- package/dist/mmtp-container-parser.js.map +7 -0
- package/dist/mmtp-container-parser.no-modules.js +7853 -0
- package/dist/mmtp-container-parser.no-modules.js.map +7 -0
- package/dist/mmtp-decode-pipeline.d.ts +96 -0
- package/dist/mmtp-decode-pipeline.d.ts.map +1 -0
- package/dist/mmtp-decode-pipeline.js +5589 -0
- package/dist/mmtp-decode-pipeline.js.map +7 -0
- package/dist/mmtp-router.d.ts +383 -0
- package/dist/mmtp-router.d.ts.map +1 -0
- package/dist/mmtp-router.js +8384 -0
- package/dist/mmtp-router.js.map +7 -0
- package/dist/mmtp-to-cmaf.d.ts +166 -0
- package/dist/mmtp-to-cmaf.d.ts.map +1 -0
- package/dist/mmtp-to-cmaf.js +781 -0
- package/dist/mmtp-to-cmaf.js.map +7 -0
- package/dist/multicast-auth-catalog.d.ts +115 -0
- package/dist/multicast-auth-catalog.d.ts.map +1 -0
- package/dist/multicast-auth-catalog.js +202 -0
- package/dist/multicast-auth-catalog.js.map +7 -0
- package/dist/multicast-input.d.ts +107 -0
- package/dist/multicast-input.d.ts.map +1 -0
- package/dist/multicast-input.js +256 -0
- package/dist/multicast-input.js.map +7 -0
- package/dist/multicast-manager.d.ts +330 -0
- package/dist/multicast-manager.d.ts.map +1 -0
- package/dist/multicast-manager.js +11032 -0
- package/dist/multicast-manager.js.map +7 -0
- package/dist/multicast-transport.d.ts +62 -0
- package/dist/multicast-transport.d.ts.map +1 -0
- package/dist/multicast-transport.js +338 -0
- package/dist/multicast-transport.js.map +7 -0
- package/dist/multicast-unwrap.d.ts +57 -0
- package/dist/multicast-unwrap.d.ts.map +1 -0
- package/dist/multicast-unwrap.js +384 -0
- package/dist/multicast-unwrap.js.map +7 -0
- package/dist/no-modules.d.ts +9 -0
- package/dist/no-modules.d.ts.map +1 -0
- package/dist/no-modules.js +7819 -0
- package/dist/no-modules.js.map +7 -0
- package/dist/phase14-catalog-override.d.ts +126 -0
- package/dist/phase14-catalog-override.d.ts.map +1 -0
- package/dist/phase14-catalog-override.js +155 -0
- package/dist/phase14-catalog-override.js.map +7 -0
- package/dist/repair-fetch.d.ts +58 -0
- package/dist/repair-fetch.d.ts.map +1 -0
- package/dist/repair-fetch.js +117 -0
- package/dist/repair-fetch.js.map +7 -0
- package/dist/sample-combiner.d.ts +182 -0
- package/dist/sample-combiner.d.ts.map +1 -0
- package/dist/sample-combiner.js +571 -0
- package/dist/sample-combiner.js.map +7 -0
- package/dist/signaling.d.ts +29 -0
- package/dist/signaling.d.ts.map +1 -0
- package/dist/signaling.js +232 -0
- package/dist/signaling.js.map +7 -0
- package/dist/source-auth.d.ts +2 -0
- package/dist/source-auth.d.ts.map +1 -0
- package/dist/source-auth.js +1220 -0
- package/dist/source-auth.js.map +7 -0
- package/dist/switching-set-alignment.d.ts +61 -0
- package/dist/switching-set-alignment.d.ts.map +1 -0
- package/dist/switching-set-alignment.js +85 -0
- package/dist/switching-set-alignment.js.map +7 -0
- package/dist/timestamp-codec.d.ts +34 -0
- package/dist/timestamp-codec.d.ts.map +1 -0
- package/dist/timestamp-codec.js +456 -0
- package/dist/timestamp-codec.js.map +7 -0
- package/dist/track-pipeline-setup.d.ts +72 -0
- package/dist/track-pipeline-setup.d.ts.map +1 -0
- package/dist/track-pipeline-setup.js +306 -0
- package/dist/track-pipeline-setup.js.map +7 -0
- package/dist/track-pipeline.d.ts +121 -0
- package/dist/track-pipeline.d.ts.map +1 -0
- package/dist/track-pipeline.js +229 -0
- package/dist/track-pipeline.js.map +7 -0
- package/dist/track-session.d.ts +269 -0
- package/dist/track-session.d.ts.map +1 -0
- package/dist/track-session.js +597 -0
- package/dist/track-session.js.map +7 -0
- package/dist/transport-pool.d.ts +69 -0
- package/dist/transport-pool.d.ts.map +1 -0
- package/dist/transport-pool.js +88 -0
- package/dist/transport-pool.js.map +7 -0
- package/dist/wasm-mfu-reassembler.d.ts +81 -0
- package/dist/wasm-mfu-reassembler.d.ts.map +1 -0
- package/dist/wasm-mfu-reassembler.js +1915 -0
- package/dist/wasm-mfu-reassembler.js.map +7 -0
- package/dist/wasm-mmtp-container-parser.d.ts +10 -0
- package/dist/wasm-mmtp-container-parser.d.ts.map +1 -0
- package/dist/wasm-mmtp-container-parser.js +5635 -0
- package/dist/wasm-mmtp-container-parser.js.map +7 -0
- package/node_modules/@blockcast/fec-worker/README.md +213 -0
- package/node_modules/@blockcast/fec-worker/dist/.build-stamp +0 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.d.ts +80 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.d.ts.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.js +270 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.js.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.d.ts +252 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.d.ts.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.js +11 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.js.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker.d.ts +14 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker.d.ts.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker.js +565 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker.js.map +7 -0
- package/node_modules/@blockcast/fec-worker/dist/index.d.ts +10 -0
- package/node_modules/@blockcast/fec-worker/dist/index.d.ts.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/index.js +8 -0
- package/node_modules/@blockcast/fec-worker/dist/index.js.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.d.ts +20 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.d.ts.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.js +349 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.js.map +7 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.d.ts +104 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.d.ts.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.js +181 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.js.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.d.ts +179 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.d.ts.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.js +47 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.js.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/transfer.d.ts +9 -0
- package/node_modules/@blockcast/fec-worker/dist/transfer.d.ts.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/transfer.js +13 -0
- package/node_modules/@blockcast/fec-worker/dist/transfer.js.map +1 -0
- package/node_modules/@blockcast/fec-worker/package.json +59 -0
- package/node_modules/@blockcast/fec-worker/src/fec-worker-client.ts +309 -0
- package/node_modules/@blockcast/fec-worker/src/fec-worker-types.ts +268 -0
- package/node_modules/@blockcast/fec-worker/src/fec-worker.ts +1048 -0
- package/node_modules/@blockcast/fec-worker/src/index.ts +32 -0
- package/node_modules/@blockcast/fec-worker/src/shred-fec-worker.ts +558 -0
- package/node_modules/@blockcast/fec-worker/src/shred-worker-client.ts +222 -0
- package/node_modules/@blockcast/fec-worker/src/shred-worker-types.ts +194 -0
- package/node_modules/@blockcast/fec-worker/src/transfer.ts +12 -0
- package/node_modules/@blockcast/mmt-alta-parse/README.md +181 -0
- package/node_modules/@blockcast/mmt-alta-parse/dist/.build-stamp +0 -0
- package/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts +57 -0
- package/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-alta-parse/dist/index.js +115 -0
- package/node_modules/@blockcast/mmt-alta-parse/dist/index.js.map +1 -0
- package/node_modules/@blockcast/mmt-alta-parse/package.json +50 -0
- package/node_modules/@blockcast/mmt-alta-parse/src/index.ts +136 -0
- package/node_modules/@blockcast/mmt-base/README.md +120 -0
- package/node_modules/@blockcast/mmt-base/dist/.build-stamp +0 -0
- package/node_modules/@blockcast/mmt-base/dist/index.d.ts +2 -0
- package/node_modules/@blockcast/mmt-base/dist/index.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-base/dist/index.js +2 -0
- package/node_modules/@blockcast/mmt-base/dist/index.js.map +1 -0
- package/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts +275 -0
- package/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-base/dist/mmtp.js +644 -0
- package/node_modules/@blockcast/mmt-base/dist/mmtp.js.map +1 -0
- package/node_modules/@blockcast/mmt-base/package.json +49 -0
- package/node_modules/@blockcast/mmt-base/src/index.ts +1 -0
- package/node_modules/@blockcast/mmt-base/src/mmtp.ts +898 -0
- package/node_modules/@blockcast/mmt-fec/README.md +270 -0
- package/node_modules/@blockcast/mmt-fec/dist/.build-stamp +0 -0
- package/node_modules/@blockcast/mmt-fec/dist/block-manager.d.ts +80 -0
- package/node_modules/@blockcast/mmt-fec/dist/block-manager.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/block-manager.js +294 -0
- package/node_modules/@blockcast/mmt-fec/dist/block-manager.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/block-processor.d.ts +72 -0
- package/node_modules/@blockcast/mmt-fec/dist/block-processor.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/block-processor.js +192 -0
- package/node_modules/@blockcast/mmt-fec/dist/block-processor.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.d.ts +46 -0
- package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.js +96 -0
- package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.d.ts +33 -0
- package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.js +57 -0
- package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.d.ts +185 -0
- package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.js +273 -0
- package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/index.d.ts +22 -0
- package/node_modules/@blockcast/mmt-fec/dist/index.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/index.js +22 -0
- package/node_modules/@blockcast/mmt-fec/dist/index.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.d.ts +20 -0
- package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.js +28 -0
- package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/oti.d.ts +174 -0
- package/node_modules/@blockcast/mmt-fec/dist/oti.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/oti.js +256 -0
- package/node_modules/@blockcast/mmt-fec/dist/oti.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.d.ts +41 -0
- package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.js +81 -0
- package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/README.md +181 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/.build-stamp +0 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts +57 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.js +115 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/package.json +50 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/src/index.ts +136 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/README.md +120 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/.build-stamp +0 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.d.ts +2 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.js +2 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts +275 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.js +644 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/package.json +49 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/index.ts +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/mmtp.ts +898 -0
- package/node_modules/@blockcast/mmt-fec/package.json +79 -0
- package/node_modules/@blockcast/mmt-fec/src/block-manager.ts +369 -0
- package/node_modules/@blockcast/mmt-fec/src/block-processor.ts +277 -0
- package/node_modules/@blockcast/mmt-fec/src/cmaf-recovery.ts +127 -0
- package/node_modules/@blockcast/mmt-fec/src/cmaf-symbols.ts +68 -0
- package/node_modules/@blockcast/mmt-fec/src/fec-block-mapper.ts +332 -0
- package/node_modules/@blockcast/mmt-fec/src/index.ts +77 -0
- package/node_modules/@blockcast/mmt-fec/src/loc-symbols.ts +34 -0
- package/node_modules/@blockcast/mmt-fec/src/oti.ts +319 -0
- package/node_modules/@blockcast/mmt-fec/src/reorder-buffer.ts +101 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/.build-stamp +0 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.d.ts +28 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.js +128 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.js.map +1 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/index.d.ts +4 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/index.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/index.js +4 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/index.js.map +1 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.d.ts +37 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.js +179 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.js.map +1 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.d.ts +90 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.js +462 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.js.map +1 -0
- package/node_modules/@blockcast/mmt-manifest-verify/package.json +45 -0
- package/node_modules/@blockcast/mmt-manifest-verify/src/admission.ts +171 -0
- package/node_modules/@blockcast/mmt-manifest-verify/src/index.ts +3 -0
- package/node_modules/@blockcast/mmt-manifest-verify/src/source-auth.ts +230 -0
- package/node_modules/@blockcast/mmt-manifest-verify/src/verifier.ts +636 -0
- package/node_modules/@noble/hashes/LICENSE +21 -0
- package/node_modules/@noble/hashes/README.md +521 -0
- package/node_modules/@noble/hashes/_assert.d.ts +17 -0
- package/node_modules/@noble/hashes/_assert.d.ts.map +1 -0
- package/node_modules/@noble/hashes/_assert.js +18 -0
- package/node_modules/@noble/hashes/_assert.js.map +1 -0
- package/node_modules/@noble/hashes/_blake.d.ts +14 -0
- package/node_modules/@noble/hashes/_blake.d.ts.map +1 -0
- package/node_modules/@noble/hashes/_blake.js +50 -0
- package/node_modules/@noble/hashes/_blake.js.map +1 -0
- package/node_modules/@noble/hashes/_md.d.ts +51 -0
- package/node_modules/@noble/hashes/_md.d.ts.map +1 -0
- package/node_modules/@noble/hashes/_md.js +162 -0
- package/node_modules/@noble/hashes/_md.js.map +1 -0
- package/node_modules/@noble/hashes/_u64.d.ts +55 -0
- package/node_modules/@noble/hashes/_u64.d.ts.map +1 -0
- package/node_modules/@noble/hashes/_u64.js +90 -0
- package/node_modules/@noble/hashes/_u64.js.map +1 -0
- package/node_modules/@noble/hashes/argon2.d.ts +32 -0
- package/node_modules/@noble/hashes/argon2.d.ts.map +1 -0
- package/node_modules/@noble/hashes/argon2.js +401 -0
- package/node_modules/@noble/hashes/argon2.js.map +1 -0
- package/node_modules/@noble/hashes/blake1.d.ts +106 -0
- package/node_modules/@noble/hashes/blake1.d.ts.map +1 -0
- package/node_modules/@noble/hashes/blake1.js +459 -0
- package/node_modules/@noble/hashes/blake1.js.map +1 -0
- package/node_modules/@noble/hashes/blake2.d.ts +116 -0
- package/node_modules/@noble/hashes/blake2.d.ts.map +1 -0
- package/node_modules/@noble/hashes/blake2.js +420 -0
- package/node_modules/@noble/hashes/blake2.js.map +1 -0
- package/node_modules/@noble/hashes/blake2b.d.ts +11 -0
- package/node_modules/@noble/hashes/blake2b.d.ts.map +1 -0
- package/node_modules/@noble/hashes/blake2b.js +14 -0
- package/node_modules/@noble/hashes/blake2b.js.map +1 -0
- package/node_modules/@noble/hashes/blake2s.d.ts +20 -0
- package/node_modules/@noble/hashes/blake2s.d.ts.map +1 -0
- package/node_modules/@noble/hashes/blake2s.js +24 -0
- package/node_modules/@noble/hashes/blake2s.js.map +1 -0
- package/node_modules/@noble/hashes/blake3.d.ts +54 -0
- package/node_modules/@noble/hashes/blake3.d.ts.map +1 -0
- package/node_modules/@noble/hashes/blake3.js +255 -0
- package/node_modules/@noble/hashes/blake3.js.map +1 -0
- package/node_modules/@noble/hashes/crypto.d.ts +2 -0
- package/node_modules/@noble/hashes/crypto.d.ts.map +1 -0
- package/node_modules/@noble/hashes/crypto.js +5 -0
- package/node_modules/@noble/hashes/crypto.js.map +1 -0
- package/node_modules/@noble/hashes/cryptoNode.d.ts +2 -0
- package/node_modules/@noble/hashes/cryptoNode.d.ts.map +1 -0
- package/node_modules/@noble/hashes/cryptoNode.js +18 -0
- package/node_modules/@noble/hashes/cryptoNode.js.map +1 -0
- package/node_modules/@noble/hashes/eskdf.d.ts +47 -0
- package/node_modules/@noble/hashes/eskdf.d.ts.map +1 -0
- package/node_modules/@noble/hashes/eskdf.js +166 -0
- package/node_modules/@noble/hashes/eskdf.js.map +1 -0
- package/node_modules/@noble/hashes/esm/_assert.d.ts +17 -0
- package/node_modules/@noble/hashes/esm/_assert.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/_assert.js +15 -0
- package/node_modules/@noble/hashes/esm/_assert.js.map +1 -0
- package/node_modules/@noble/hashes/esm/_blake.d.ts +14 -0
- package/node_modules/@noble/hashes/esm/_blake.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/_blake.js +45 -0
- package/node_modules/@noble/hashes/esm/_blake.js.map +1 -0
- package/node_modules/@noble/hashes/esm/_md.d.ts +51 -0
- package/node_modules/@noble/hashes/esm/_md.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/_md.js +155 -0
- package/node_modules/@noble/hashes/esm/_md.js.map +1 -0
- package/node_modules/@noble/hashes/esm/_u64.d.ts +55 -0
- package/node_modules/@noble/hashes/esm/_u64.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/_u64.js +67 -0
- package/node_modules/@noble/hashes/esm/_u64.js.map +1 -0
- package/node_modules/@noble/hashes/esm/argon2.d.ts +32 -0
- package/node_modules/@noble/hashes/esm/argon2.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/argon2.js +392 -0
- package/node_modules/@noble/hashes/esm/argon2.js.map +1 -0
- package/node_modules/@noble/hashes/esm/blake1.d.ts +106 -0
- package/node_modules/@noble/hashes/esm/blake1.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/blake1.js +452 -0
- package/node_modules/@noble/hashes/esm/blake1.js.map +1 -0
- package/node_modules/@noble/hashes/esm/blake2.d.ts +116 -0
- package/node_modules/@noble/hashes/esm/blake2.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/blake2.js +413 -0
- package/node_modules/@noble/hashes/esm/blake2.js.map +1 -0
- package/node_modules/@noble/hashes/esm/blake2b.d.ts +11 -0
- package/node_modules/@noble/hashes/esm/blake2b.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/blake2b.js +11 -0
- package/node_modules/@noble/hashes/esm/blake2b.js.map +1 -0
- package/node_modules/@noble/hashes/esm/blake2s.d.ts +20 -0
- package/node_modules/@noble/hashes/esm/blake2s.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/blake2s.js +21 -0
- package/node_modules/@noble/hashes/esm/blake2s.js.map +1 -0
- package/node_modules/@noble/hashes/esm/blake3.d.ts +54 -0
- package/node_modules/@noble/hashes/esm/blake3.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/blake3.js +251 -0
- package/node_modules/@noble/hashes/esm/blake3.js.map +1 -0
- package/node_modules/@noble/hashes/esm/crypto.d.ts +2 -0
- package/node_modules/@noble/hashes/esm/crypto.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/crypto.js +2 -0
- package/node_modules/@noble/hashes/esm/crypto.js.map +1 -0
- package/node_modules/@noble/hashes/esm/cryptoNode.d.ts +2 -0
- package/node_modules/@noble/hashes/esm/cryptoNode.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/cryptoNode.js +15 -0
- package/node_modules/@noble/hashes/esm/cryptoNode.js.map +1 -0
- package/node_modules/@noble/hashes/esm/eskdf.d.ts +47 -0
- package/node_modules/@noble/hashes/esm/eskdf.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/eskdf.js +160 -0
- package/node_modules/@noble/hashes/esm/eskdf.js.map +1 -0
- package/node_modules/@noble/hashes/esm/hkdf.d.ts +36 -0
- package/node_modules/@noble/hashes/esm/hkdf.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/hkdf.js +82 -0
- package/node_modules/@noble/hashes/esm/hkdf.js.map +1 -0
- package/node_modules/@noble/hashes/esm/hmac.d.ts +35 -0
- package/node_modules/@noble/hashes/esm/hmac.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/hmac.js +86 -0
- package/node_modules/@noble/hashes/esm/hmac.js.map +1 -0
- package/node_modules/@noble/hashes/esm/index.d.ts +2 -0
- package/node_modules/@noble/hashes/esm/index.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/index.js +33 -0
- package/node_modules/@noble/hashes/esm/index.js.map +1 -0
- package/node_modules/@noble/hashes/esm/legacy.d.ts +71 -0
- package/node_modules/@noble/hashes/esm/legacy.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/legacy.js +281 -0
- package/node_modules/@noble/hashes/esm/legacy.js.map +1 -0
- package/node_modules/@noble/hashes/esm/package.json +10 -0
- package/node_modules/@noble/hashes/esm/pbkdf2.d.ts +23 -0
- package/node_modules/@noble/hashes/esm/pbkdf2.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/pbkdf2.js +97 -0
- package/node_modules/@noble/hashes/esm/pbkdf2.js.map +1 -0
- package/node_modules/@noble/hashes/esm/ripemd160.d.ts +13 -0
- package/node_modules/@noble/hashes/esm/ripemd160.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/ripemd160.js +13 -0
- package/node_modules/@noble/hashes/esm/ripemd160.js.map +1 -0
- package/node_modules/@noble/hashes/esm/scrypt.d.ts +34 -0
- package/node_modules/@noble/hashes/esm/scrypt.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/scrypt.js +228 -0
- package/node_modules/@noble/hashes/esm/scrypt.js.map +1 -0
- package/node_modules/@noble/hashes/esm/sha1.d.ts +11 -0
- package/node_modules/@noble/hashes/esm/sha1.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/sha1.js +11 -0
- package/node_modules/@noble/hashes/esm/sha1.js.map +1 -0
- package/node_modules/@noble/hashes/esm/sha2.d.ts +159 -0
- package/node_modules/@noble/hashes/esm/sha2.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/sha2.js +375 -0
- package/node_modules/@noble/hashes/esm/sha2.js.map +1 -0
- package/node_modules/@noble/hashes/esm/sha256.d.ts +20 -0
- package/node_modules/@noble/hashes/esm/sha256.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/sha256.js +20 -0
- package/node_modules/@noble/hashes/esm/sha256.js.map +1 -0
- package/node_modules/@noble/hashes/esm/sha3-addons.d.ts +142 -0
- package/node_modules/@noble/hashes/esm/sha3-addons.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/sha3-addons.js +393 -0
- package/node_modules/@noble/hashes/esm/sha3-addons.js.map +1 -0
- package/node_modules/@noble/hashes/esm/sha3.d.ts +53 -0
- package/node_modules/@noble/hashes/esm/sha3.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/sha3.js +234 -0
- package/node_modules/@noble/hashes/esm/sha3.js.map +1 -0
- package/node_modules/@noble/hashes/esm/sha512.d.ts +26 -0
- package/node_modules/@noble/hashes/esm/sha512.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/sha512.js +26 -0
- package/node_modules/@noble/hashes/esm/sha512.js.map +1 -0
- package/node_modules/@noble/hashes/esm/utils.d.ts +161 -0
- package/node_modules/@noble/hashes/esm/utils.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/utils.js +281 -0
- package/node_modules/@noble/hashes/esm/utils.js.map +1 -0
- package/node_modules/@noble/hashes/hkdf.d.ts +36 -0
- package/node_modules/@noble/hashes/hkdf.d.ts.map +1 -0
- package/node_modules/@noble/hashes/hkdf.js +88 -0
- package/node_modules/@noble/hashes/hkdf.js.map +1 -0
- package/node_modules/@noble/hashes/hmac.d.ts +35 -0
- package/node_modules/@noble/hashes/hmac.d.ts.map +1 -0
- package/node_modules/@noble/hashes/hmac.js +91 -0
- package/node_modules/@noble/hashes/hmac.js.map +1 -0
- package/node_modules/@noble/hashes/index.d.ts +1 -0
- package/node_modules/@noble/hashes/index.d.ts.map +1 -0
- package/node_modules/@noble/hashes/index.js +33 -0
- package/node_modules/@noble/hashes/index.js.map +1 -0
- package/node_modules/@noble/hashes/legacy.d.ts +71 -0
- package/node_modules/@noble/hashes/legacy.d.ts.map +1 -0
- package/node_modules/@noble/hashes/legacy.js +287 -0
- package/node_modules/@noble/hashes/legacy.js.map +1 -0
- package/node_modules/@noble/hashes/package.json +266 -0
- package/node_modules/@noble/hashes/pbkdf2.d.ts +23 -0
- package/node_modules/@noble/hashes/pbkdf2.d.ts.map +1 -0
- package/node_modules/@noble/hashes/pbkdf2.js +101 -0
- package/node_modules/@noble/hashes/pbkdf2.js.map +1 -0
- package/node_modules/@noble/hashes/ripemd160.d.ts +13 -0
- package/node_modules/@noble/hashes/ripemd160.d.ts.map +1 -0
- package/node_modules/@noble/hashes/ripemd160.js +16 -0
- package/node_modules/@noble/hashes/ripemd160.js.map +1 -0
- package/node_modules/@noble/hashes/scrypt.d.ts +34 -0
- package/node_modules/@noble/hashes/scrypt.d.ts.map +1 -0
- package/node_modules/@noble/hashes/scrypt.js +232 -0
- package/node_modules/@noble/hashes/scrypt.js.map +1 -0
- package/node_modules/@noble/hashes/sha1.d.ts +11 -0
- package/node_modules/@noble/hashes/sha1.d.ts.map +1 -0
- package/node_modules/@noble/hashes/sha1.js +14 -0
- package/node_modules/@noble/hashes/sha1.js.map +1 -0
- package/node_modules/@noble/hashes/sha2.d.ts +159 -0
- package/node_modules/@noble/hashes/sha2.d.ts.map +1 -0
- package/node_modules/@noble/hashes/sha2.js +384 -0
- package/node_modules/@noble/hashes/sha2.js.map +1 -0
- package/node_modules/@noble/hashes/sha256.d.ts +20 -0
- package/node_modules/@noble/hashes/sha256.d.ts.map +1 -0
- package/node_modules/@noble/hashes/sha256.js +23 -0
- package/node_modules/@noble/hashes/sha256.js.map +1 -0
- package/node_modules/@noble/hashes/sha3-addons.d.ts +142 -0
- package/node_modules/@noble/hashes/sha3-addons.d.ts.map +1 -0
- package/node_modules/@noble/hashes/sha3-addons.js +402 -0
- package/node_modules/@noble/hashes/sha3-addons.js.map +1 -0
- package/node_modules/@noble/hashes/sha3.d.ts +53 -0
- package/node_modules/@noble/hashes/sha3.d.ts.map +1 -0
- package/node_modules/@noble/hashes/sha3.js +239 -0
- package/node_modules/@noble/hashes/sha3.js.map +1 -0
- package/node_modules/@noble/hashes/sha512.d.ts +26 -0
- package/node_modules/@noble/hashes/sha512.d.ts.map +1 -0
- package/node_modules/@noble/hashes/sha512.js +29 -0
- package/node_modules/@noble/hashes/sha512.js.map +1 -0
- package/node_modules/@noble/hashes/src/_assert.ts +22 -0
- package/node_modules/@noble/hashes/src/_blake.ts +50 -0
- package/node_modules/@noble/hashes/src/_md.ts +176 -0
- package/node_modules/@noble/hashes/src/_u64.ts +91 -0
- package/node_modules/@noble/hashes/src/argon2.ts +497 -0
- package/node_modules/@noble/hashes/src/blake1.ts +534 -0
- package/node_modules/@noble/hashes/src/blake2.ts +486 -0
- package/node_modules/@noble/hashes/src/blake2b.ts +10 -0
- package/node_modules/@noble/hashes/src/blake2s.ts +20 -0
- package/node_modules/@noble/hashes/src/blake3.ts +272 -0
- package/node_modules/@noble/hashes/src/crypto.ts +9 -0
- package/node_modules/@noble/hashes/src/cryptoNode.ts +15 -0
- package/node_modules/@noble/hashes/src/eskdf.ts +187 -0
- package/node_modules/@noble/hashes/src/hkdf.ts +88 -0
- package/node_modules/@noble/hashes/src/hmac.ts +94 -0
- package/node_modules/@noble/hashes/src/index.ts +31 -0
- package/node_modules/@noble/hashes/src/legacy.ts +293 -0
- package/node_modules/@noble/hashes/src/pbkdf2.ts +122 -0
- package/node_modules/@noble/hashes/src/ripemd160.ts +12 -0
- package/node_modules/@noble/hashes/src/scrypt.ts +257 -0
- package/node_modules/@noble/hashes/src/sha1.ts +10 -0
- package/node_modules/@noble/hashes/src/sha2.ts +402 -0
- package/node_modules/@noble/hashes/src/sha256.ts +24 -0
- package/node_modules/@noble/hashes/src/sha3-addons.ts +499 -0
- package/node_modules/@noble/hashes/src/sha3.ts +258 -0
- package/node_modules/@noble/hashes/src/sha512.ts +34 -0
- package/node_modules/@noble/hashes/src/utils.ts +395 -0
- package/node_modules/@noble/hashes/utils.d.ts +161 -0
- package/node_modules/@noble/hashes/utils.d.ts.map +1 -0
- package/node_modules/@noble/hashes/utils.js +313 -0
- package/node_modules/@noble/hashes/utils.js.map +1 -0
- package/package.json +203 -0
- package/schemas/catalog.schema.json +283 -0
- package/src/align.ts +235 -0
- package/src/audio-init-parser.ts +189 -0
- package/src/audio-ring-buffer.ts +120 -0
- package/src/authored-timing.ts +63 -0
- package/src/carp-catalog.ts +776 -0
- package/src/catalog-fec-params.ts +167 -0
- package/src/catalog-network-source.ts +49 -0
- package/src/catalog-validator.ts +34 -0
- package/src/cmaf-block-assembler.ts +1058 -0
- package/src/cmaf-group-batcher.ts +104 -0
- package/src/cmcd-producer.ts +329 -0
- package/src/codec-utils.ts +1539 -0
- package/src/fec-codec.ts +61 -0
- package/src/fec-manager.ts +1939 -0
- package/src/fec-starvation-detector.ts +128 -0
- package/src/fec-worker-setup.ts +177 -0
- package/src/fmp4-completion.ts +47 -0
- package/src/fmp4-reader.ts +112 -0
- package/src/index.ts +443 -0
- package/src/iso-bmff-timing.ts +688 -0
- package/src/loc.ts +181 -0
- package/src/manifest-auth-plan.ts +107 -0
- package/src/media-router.ts +1185 -0
- package/src/mfu-reassembler.ts +2842 -0
- package/src/mfu-reassembly-policy.ts +134 -0
- package/src/mmtp-container-parser.ts +1498 -0
- package/src/mmtp-decode-pipeline.ts +315 -0
- package/src/mmtp-router.ts +3027 -0
- package/src/mmtp-to-cmaf.ts +956 -0
- package/src/multicast-auth-catalog.ts +340 -0
- package/src/multicast-input.ts +439 -0
- package/src/multicast-manager.ts +1503 -0
- package/src/multicast-transport.ts +320 -0
- package/src/multicast-unwrap.ts +132 -0
- package/src/no-modules.ts +20 -0
- package/src/phase14-catalog-override.ts +336 -0
- package/src/repair-fetch.ts +217 -0
- package/src/sample-combiner.ts +846 -0
- package/src/signaling.ts +78 -0
- package/src/source-auth.ts +1 -0
- package/src/switching-set-alignment.ts +109 -0
- package/src/timestamp-codec.ts +265 -0
- package/src/track-pipeline-setup.ts +189 -0
- package/src/track-pipeline.ts +332 -0
- package/src/track-session.ts +778 -0
- package/src/transport-pool.ts +128 -0
- package/src/wasm-mfu-reassembler.ts +372 -0
- package/src/wasm-mmtp-container-parser.ts +23 -0
- package/test-vectors/align.json +199 -0
- package/test-vectors/catalog/README.md +25 -0
- package/test-vectors/catalog/negative/legacy-selection-params.json +15 -0
- package/test-vectors/catalog/negative/missing-mmtp-fields.json +12 -0
- package/test-vectors/catalog/negative/multicast-auth-padded-key.json +37 -0
- package/test-vectors/catalog/negative/multicast-auth-reused-track-format.json +53 -0
- package/test-vectors/catalog/negative/multicast-auth-trailing-pad-bits.json +37 -0
- package/test-vectors/catalog/negative/multicast-endpoint-missing-protocol-and-source.json +24 -0
- package/test-vectors/catalog/negative/network-source-object.json +25 -0
- package/test-vectors/catalog/negative/raptorq-unaligned-symbol.json +26 -0
- package/test-vectors/catalog/negative/repair-track-legacy-shape.json +18 -0
- package/test-vectors/catalog/negative/track-role-empty.json +16 -0
- package/test-vectors/catalog/negative/track-role-non-string.json +16 -0
- package/test-vectors/catalog/positive/fec-multicast.json +51 -0
- package/test-vectors/catalog/positive/flat-av.json +30 -0
- package/test-vectors/catalog/positive/multicast-auth-rotation.json +55 -0
- package/test-vectors/catalog/positive/ticks-and-mixed-timescales.json +39 -0
- package/test-vectors/catalog/positive/track-role.json +49 -0
- package/test-vectors/catalog/releases/moqcast-native-v16-v1/catalog.json +65 -0
- package/test-vectors/catalog/releases/moqcast-native-v16-v1.archive.sha256 +1 -0
- package/test-vectors/catalog-multicast-auth-v1.json +26 -0
- package/test-vectors/catalog-validation.json +148 -0
- package/test-vectors/catalog-validator-public-api.mjs +25 -0
- package/test-vectors/generate-source-auth-fixture.mjs +114 -0
- package/test-vectors/source-auth-v1.json +61 -0
- package/test-vectors/subsample-placement-v1.json +230 -0
package/README.md
ADDED
|
@@ -0,0 +1,432 @@
|
|
|
1
|
+
# @blockcast/mmt-container
|
|
2
|
+
|
|
3
|
+
MMTP / LOC container parsing for MMT over MoQ and SSM multicast. This package sits one layer above the wire decoder: given raw MMTP packets from any transport (WebTransport, Direct Sockets API, AMT tunnel), it produces reassembled MFUs, decoded CMSF catalogs, FEC-decoded source blocks, and CMAF segments ready for `MediaSource.appendBuffer()`. It is the TypeScript counterpart of the Rust `mmt-container` crate and is used by the moqtail and hang-mmt-fec reference players.
|
|
4
|
+
|
|
5
|
+
This package is **container-agnostic about the codec** (H.264/AVC, HEVC, AAC, Opus) and **transport-agnostic about how packets arrive** — `MmtpContainerParser` accepts any `Uint8Array`. FEC decode is delegated to `@blockcast/mmt-fec` (synchronous WASM) or `@blockcast/fec-worker` (off-main-thread).
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pnpm add @blockcast/mmt-container
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
ESM-only (`"type": "module"`). Node 18+ or any modern browser. No CommonJS build is shipped — consumers must use `import`.
|
|
14
|
+
|
|
15
|
+
## Quick start
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import {
|
|
19
|
+
MmtpContainerParser,
|
|
20
|
+
MmtpToCmaf,
|
|
21
|
+
FECManager,
|
|
22
|
+
parseTrackRole,
|
|
23
|
+
resolveGroupDurationTicks,
|
|
24
|
+
} from "@blockcast/mmt-container"
|
|
25
|
+
|
|
26
|
+
// 1. Validate the catalog and pull track roles (Phase 14 convention)
|
|
27
|
+
const role = parseTrackRole("video/base") // → "base"
|
|
28
|
+
|
|
29
|
+
// 2. Wire the parser. mfuTimeoutMs is REQUIRED — derive from FEC
|
|
30
|
+
// interleaveDepthMs or frame duration; do not let it default.
|
|
31
|
+
const parser = new MmtpContainerParser({
|
|
32
|
+
mfuTimeoutMs: 500,
|
|
33
|
+
defaultTrack: { type: "video", codec: "avc1.640033" },
|
|
34
|
+
reorderWindow: 8,
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
// 3. Optional: per-track FEC decoder (RaptorQ via @blockcast/mmt-fec)
|
|
38
|
+
const fec = new FECManager()
|
|
39
|
+
fec.configure({ k: 32, symbolSize: 1312, interleaveDepthMs: 1000, fps: 30 })
|
|
40
|
+
|
|
41
|
+
// 4. CMAF wrapper for MSE
|
|
42
|
+
const cmaf = new MmtpToCmaf()
|
|
43
|
+
parser.onFrame((data, meta) => {
|
|
44
|
+
if (meta.trackType === "video") {
|
|
45
|
+
const segment = cmaf.wrapVideoSample(data, meta.timestamp, meta.keyframe)
|
|
46
|
+
sourceBuffer.appendBuffer(segment)
|
|
47
|
+
}
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
// 5. Feed raw MMTP packets from any transport
|
|
51
|
+
transport.onPacket = (pkt: Uint8Array) => parser.feed(pkt)
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
For two-phase operation (parse header → feed FEC → emit frame) see `MmtpRouter` and `MmtpDecodePipeline`; both are exported from this package.
|
|
55
|
+
|
|
56
|
+
## Exports
|
|
57
|
+
|
|
58
|
+
The package exposes a wide subpath surface so consumers can tree-shake aggressively. Every entry mirrors `package.json#exports`.
|
|
59
|
+
|
|
60
|
+
| Subpath | What you get |
|
|
61
|
+
|---------|--------------|
|
|
62
|
+
| `@blockcast/mmt-container` | Container, reassembly, catalog, and routing APIs (`src/index.ts`) |
|
|
63
|
+
| `./browser-runtime` | Self-contained browser ESM bundle for pages that do not provide an import map |
|
|
64
|
+
| `./mfu` | `MFUReassembler` for fragmented MFUs (FI=1/2/3) |
|
|
65
|
+
| `./loc` | LOC FEC extension headers (`FecSourceInfo`, `AuthTag`) |
|
|
66
|
+
| `./codec-utils` | H.264 helpers — Annex-B ↔ AVCC, SPS/PPS extraction, `mmtpTimestampToMicros`, ADTS wrap |
|
|
67
|
+
| `./fec-manager` | `FECManager` — per-track FEC decoder lifecycle (sync WASM + Worker variants) |
|
|
68
|
+
| `./mmtp-router` | `MmtpRouter` — packet routing with two-phase FEC feed |
|
|
69
|
+
| `./multicast-transport` | `MulticastTransport` — `window.multicast` gateway `subscribe({ consume: 'bytes' })` wrapper |
|
|
70
|
+
| `./multicast-manager` | `MulticastManager` — backwards-compat facade composing transport + router + FEC |
|
|
71
|
+
| `./media-router` | `MediaRouter` — MoQ ↔ multicast source arbitration + base/delta migration |
|
|
72
|
+
| `./multicast-unwrap` | Container-aware MMTP dispatch (LOC vs raw MMTP) |
|
|
73
|
+
| `./signaling` | Packet-type classifier (`isSignalingPacket`, `isSourcePacket`, `classifyPacket`) |
|
|
74
|
+
| `./mmtp-container-parser` | `MmtpContainerParser` (the unified, transport-agnostic parser) |
|
|
75
|
+
| `./fec-codec` | Algorithm-pluggable codec interface — `NoneCodec`, `ReedSolomonCodec`, `createFecCodec` |
|
|
76
|
+
| `./cmcd-producer` | `CmcdProducer` — RFC 9559 CMCD with `x-bc-*` vendor keys |
|
|
77
|
+
| `./cmaf-block-assembler` | `CmafBlockAssembler` — assembles one CMAF segment per FEC source block |
|
|
78
|
+
| `./cmaf-group-batcher` | `CmafGroupBatcher` — MoQ group → CMAF segment batcher |
|
|
79
|
+
| `./carp-catalog` | CARP / CMSF catalog types, track-role parser, switching-set validator, track-timing |
|
|
80
|
+
| `./catalog-validator` | `createCatalogSchemaValidator` — compiles the published schema with package-defined semantic keywords installed |
|
|
81
|
+
| `./switching-set-alignment` | Cross-track group alignment helpers |
|
|
82
|
+
| `./phase14-catalog-override` | Test-harness catalog override hook (`globalThis.__PHASE14_CATALOG_OVERRIDE`) |
|
|
83
|
+
| `./align` | Group-id derivation (`groupIdForTicks`, `groupIdFor`, `driftCheck`) — shared with Go sender + Rust relay |
|
|
84
|
+
| `./mmtp-decode-pipeline` | `MmtpDecodePipeline` — unified MoQ + multicast decode path |
|
|
85
|
+
| `./mmtp-to-cmaf` | `MmtpToCmaf` + standalone segment builders (`encodeMultiSampleSegment`, `buildVideoInitSegment`, `generateGreenFillNAL`, `generateSilenceFrame`) |
|
|
86
|
+
| `./track-pipeline-setup` | `setupTrackPipeline` — shared wiring for both reference players |
|
|
87
|
+
| `./track-session` | `TrackSession` + `SessionManager` — per-track state machine (Patent Claim 9) |
|
|
88
|
+
|
|
89
|
+
## Components
|
|
90
|
+
|
|
91
|
+
### MMTP parser (`@blockcast/mmt-base`)
|
|
92
|
+
|
|
93
|
+
The low-level ISO/IEC 23008-1 packet parser belongs to the dependency leaf
|
|
94
|
+
`@blockcast/mmt-base`, not this package. Import it directly for MMTP headers,
|
|
95
|
+
MPU/MFU extraction, payload IDs, and AL-FEC signaling. Import strict RFC 6330
|
|
96
|
+
OTI helpers from `@blockcast/mmt-fec`; the obsolete container and mmt-base OTI
|
|
97
|
+
paths have been removed.
|
|
98
|
+
|
|
99
|
+
Key exports:
|
|
100
|
+
|
|
101
|
+
```ts
|
|
102
|
+
interface MMTPHeader {
|
|
103
|
+
version: number
|
|
104
|
+
packetType: number // 0x00=MPU, 0x02=Signaling, 0x03=Repair
|
|
105
|
+
packetId: number
|
|
106
|
+
timestamp: bigint
|
|
107
|
+
sequenceNumber: number
|
|
108
|
+
payloadLength: number
|
|
109
|
+
fecType: number // 0=none, 1=src+payloadId, 2=repair-mode-0, 3=repair-mode-1
|
|
110
|
+
rapFlag: boolean // Random-access-point bit (keyframe)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function parseMMTPHeader(buf: Uint8Array): MMTPHeader
|
|
114
|
+
function parseMPUHeader(buf: Uint8Array, offset: number): MPUHeader
|
|
115
|
+
function extractMFUPayload(packet: Uint8Array): MFUExtraction | null
|
|
116
|
+
function extractFecPayloadId(packet: Uint8Array): { ssId: number } | null
|
|
117
|
+
function extractRepairFecPayloadId(packet: Uint8Array): RepairFecId | null
|
|
118
|
+
function parseAlFecMessage(buf: Uint8Array): AlFecConfig
|
|
119
|
+
function parseMoqRepairFrame(buf: Uint8Array): MoqRepairFrame
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Constants worth knowing: `MMTP_HEADER_SIZE = 12`, `MPU_HEADER_SIZE = 8`, `MFU_DU_HEADER_SIZE_TIMED = 14`, `PACKET_TYPE_MPU = 0x00`, `PACKET_TYPE_REPAIR = 0x03`, `ALFEC_MESSAGE_ID = 0x0203`, `FEC_CODE_RAPTORQ = 2`.
|
|
123
|
+
|
|
124
|
+
```ts
|
|
125
|
+
import { parseMMTPHeader, extractMFUPayload } from "@blockcast/mmt-base"
|
|
126
|
+
|
|
127
|
+
const hdr = parseMMTPHeader(packet)
|
|
128
|
+
if (hdr.packetType === 0x00) { // MPU
|
|
129
|
+
const mfu = extractMFUPayload(packet)
|
|
130
|
+
console.log(`pkt ${hdr.packetId} seq=${hdr.sequenceNumber} keyframe=${hdr.rapFlag}`)
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### MFU reassembler (`./mfu`)
|
|
135
|
+
|
|
136
|
+
Stateful reassembler for fragmented MFUs per ISO/IEC 23008-1:2023 §9.2.3.3 and the repository's contiguous-source producer profile. It partitions bounded continuation state by physical stream, MPU, and wrapping terminal source-packet sequence (`packet_sequence + fragment_counter`), queues FI=2/FI=3 by run and counter until FI=1 and any missing predecessor arrive, then propagates FI=1's intrinsic DU identity while draining the exact countdown. The terminal sequence is transport association only. ISO-permitted interleaving remains separated and incomplete; there is no scope, timestamp, SS_ID, or arrival-order fallback. Recovered packets use the authored u32 sequence from the reconstructed MMTP header.
|
|
137
|
+
|
|
138
|
+
```ts
|
|
139
|
+
interface MFUReassemblerOptions {
|
|
140
|
+
/** REQUIRED. null is clock-free reliable MoQ; otherwise derive a positive
|
|
141
|
+
* deadline from datagram/FEC timing. */
|
|
142
|
+
timeoutMs: number | null
|
|
143
|
+
maxBuffered?: number // default 100; shared active/continuation-only run cap
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
class MFUReassembler {
|
|
147
|
+
constructor(opts: MFUReassemblerOptions)
|
|
148
|
+
// null means valid incomplete input. Strict rejection throws
|
|
149
|
+
// MfuReassemblyError with a stable kebab-case code.
|
|
150
|
+
addFragment(frag: MFUFragment): ReassembledMFU | null
|
|
151
|
+
readonly stats: ReassemblerStats
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
The constructor rejects non-null, non-finite, or non-positive deadlines. Reliable MoQ deliberately passes `null`; it does not invent a wall-clock timeout.
|
|
156
|
+
|
|
157
|
+
### CARP / CMSF catalog (`./carp-catalog`)
|
|
158
|
+
|
|
159
|
+
Validate the published catalog schema through the package API. The schema uses
|
|
160
|
+
the package-defined `uniqueMulticastAuthTrackBindings` keyword to reject reused
|
|
161
|
+
`(mediaTrack, sourceSymbolFormat)` bindings, so compiling the JSON with a bare
|
|
162
|
+
JSON Schema validator is not supported.
|
|
163
|
+
|
|
164
|
+
```ts
|
|
165
|
+
import schema from "@blockcast/mmt-container/catalog.schema.json" with { type: "json" }
|
|
166
|
+
import { createCatalogSchemaValidator } from "@blockcast/mmt-container/catalog-validator"
|
|
167
|
+
|
|
168
|
+
const validateCatalog = createCatalogSchemaValidator(schema)
|
|
169
|
+
if (!validateCatalog(catalog)) {
|
|
170
|
+
throw new Error(JSON.stringify(validateCatalog.errors))
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Implements `draft-law-ramadan-moq-carp-reliability` §3 (FEC), §4 (multicast endpoints), and `draft-ramadan-moq-mmt-00` §4.4.4 (track timing). Plain TypeScript interfaces with type guards — no Zod, no runtime schema dependency. Upstream Zod schemas should derive from these via `z.infer<>`.
|
|
175
|
+
|
|
176
|
+
```ts
|
|
177
|
+
type FecAlgorithm = "none" | "raptorq" | "reed-solomon"
|
|
178
|
+
|
|
179
|
+
interface FecCatalogConfig {
|
|
180
|
+
algorithm: FecAlgorithm // §3.1
|
|
181
|
+
sourceSymbols: number // K (REQUIRED)
|
|
182
|
+
repairSymbols: number // P (REQUIRED)
|
|
183
|
+
symbolSize: number // T, 8-byte aligned (REQUIRED)
|
|
184
|
+
interleaveDepthMs?: number // FEC block span in MILLISECONDS, default 0 (single-group blocks)
|
|
185
|
+
repairTrack: string // §6.1 — required
|
|
186
|
+
mode?: "interleaved" | "object"
|
|
187
|
+
uep?: { keyRatio: number; deltaRatio: number } // §9.1 — Unequal Error Protection
|
|
188
|
+
deltaFailWindowBlocks?: number // D-11, base track only
|
|
189
|
+
deltaProbeIntervalMs?: number // D-13, base track only
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
interface MulticastEndpoint {
|
|
193
|
+
protocol: "ssm" | "asm" | "amt"
|
|
194
|
+
sourceAddress?: string // REQUIRED for SSM
|
|
195
|
+
groupAddress: string
|
|
196
|
+
port: number
|
|
197
|
+
tracks: string[]
|
|
198
|
+
relayAddress?: string // REQUIRED for AMT
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
interface TrackTimingConfig {
|
|
202
|
+
groupDurationMs: number // REQUIRED, positive integer
|
|
203
|
+
groupDurationTicks?: number // override when ms × timescale isn't integer
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function isFecCatalogConfig(x: unknown): x is FecCatalogConfig
|
|
207
|
+
function isMulticastCatalogConfig(x: unknown): x is MulticastCatalogConfig
|
|
208
|
+
function resolveGroupDurationTicks(timing: TrackTimingConfig, timescale: number): number
|
|
209
|
+
function validateSwitchingSetTiming(...): { ok: true } | { ok: false; ... }
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
#### Track-role convention (Phase 14)
|
|
213
|
+
|
|
214
|
+
This is **project-specific**, not in any IETF draft yet. The container's switching-set parser derives its internal role from the last `/`-segment of a track name. MMTP catalogs may also carry the publisher-owned `trackRole` dispatch tag; the canonical schema validates it as a non-empty string. `parseTrackRole` remains the name-based helper for base/delta/repair switching sets (`carp-catalog.ts:41-79`):
|
|
215
|
+
|
|
216
|
+
| Track name suffix | Role | Use |
|
|
217
|
+
|-------------------|------|-----|
|
|
218
|
+
| `video/base` | `base` | I-frame-only leg, always-on multicast |
|
|
219
|
+
| `video/delta` | `delta` | P/B-frame leg, multicast + NACK repair |
|
|
220
|
+
| `video/repair` | `repair` | FEC repair-symbol leg, cross-CDN federated |
|
|
221
|
+
| `video` (no slash) | `single` | Legacy single-track stream (D-04) |
|
|
222
|
+
|
|
223
|
+
Empty names, unknown suffixes, trailing slashes, and any non-ASCII / control characters all throw at parse time (T-14-01 fuzz hardening at `carp-catalog.ts:49-57`). Multi-track switching sets must include all three roles or `validateSwitchingSet` reports the missing roles.
|
|
224
|
+
|
|
225
|
+
```ts
|
|
226
|
+
import { parseTrackRole, validateSwitchingSet } from "@blockcast/mmt-container/carp-catalog"
|
|
227
|
+
|
|
228
|
+
parseTrackRole("video/base") // "base"
|
|
229
|
+
parseTrackRole("video") // "single" (legacy)
|
|
230
|
+
parseTrackRole("video/foo") // throws "unknown role suffix"
|
|
231
|
+
|
|
232
|
+
validateSwitchingSet(["v/base", "v/delta", "v/repair"]) // { ok: true }
|
|
233
|
+
validateSwitchingSet(["v/base", "v/delta"]) // { ok: false, missing: ["repair"] }
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### FEC manager (`./fec-manager`)
|
|
237
|
+
|
|
238
|
+
Codec-agnostic FEC decode service. Owns per-track decoder instances (sync WASM via `@blockcast/mmt-fec`, async via `@blockcast/fec-worker`), tracks per-block source-symbol counts, manages block timeouts, and emits `onBlockComplete` / `onBlockFailed` / `onBlockRecovered`.
|
|
239
|
+
|
|
240
|
+
```ts
|
|
241
|
+
interface FECManagerConfig {
|
|
242
|
+
k?: number
|
|
243
|
+
symbolSize?: number // T (bytes per symbol). NOT repair count.
|
|
244
|
+
interleaveDepthMs?: number // FEC block span in MILLISECONDS — see MIN_INTERLEAVE_DEPTH_MS in fec-manager.ts
|
|
245
|
+
fps?: number
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
class FECManager {
|
|
249
|
+
configure(cfg: FECManagerConfig): void
|
|
250
|
+
setFecDecoder(packetId: number, client: WasmFecDecoder, k: number): void
|
|
251
|
+
setWorkerDecoder(packetId: number, worker: FecWorkerClient): void
|
|
252
|
+
feedSourceSymbol(packetId: number, ssId: number, data: Uint8Array, ts: number): Uint8Array | null
|
|
253
|
+
feedRepairSymbol(packetId: number, ssStart: number, ssbLen: number, rsId: number, data: Uint8Array, ts: number): Uint8Array | null
|
|
254
|
+
readonly fecStats: FecStats
|
|
255
|
+
getBlockStates(): Array<{ sbn: number; state: "collecting" | "complete" | "failed"; ... }>
|
|
256
|
+
onBlockComplete: ((sbn: number, packetId: number) => void) | null
|
|
257
|
+
onBlockFailed: ((sbn: number) => void) | null
|
|
258
|
+
onBlockRecovered: ((sbn: number, pid: number, data: ArrayBuffer, meta: FrameMeta) => void) | null
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
`FECManager.configure()` takes `symbolSize` (bytes per symbol, T). Repair count is a distinct parameter and must never be passed in its place.
|
|
263
|
+
|
|
264
|
+
`interleaveDepthMs` is the full FEC block span in **milliseconds** per CARP §5.1, valid range 33 ms (interactive / gaming, `MIN_INTERLEAVE_DEPTH_MS`) to 10 000 ms (broadcast ATSC 3.0). `configure()` warns if a positive value below `MIN_INTERLEAVE_DEPTH_MS` (33) is passed — that is almost certainly a raw frame count, not milliseconds — and such sub-floor values never drive the block timeout (the established timeout is preserved instead of collapsing to ~0).
|
|
265
|
+
|
|
266
|
+
This package depends on the FEC primitives from:
|
|
267
|
+
- **`@blockcast/mmt-fec`** — RaptorQ WASM decoder + OTI codec + `computeFecTimeout`
|
|
268
|
+
- **`@blockcast/fec-worker`** — Web Worker host, `FecWorkerClient`, `FecTrackStats`
|
|
269
|
+
|
|
270
|
+
### MMTP → CMAF demux (`./mmtp-to-cmaf`)
|
|
271
|
+
|
|
272
|
+
Converts reassembled MFU samples (raw codec data: AVCC NALUs, AAC ADTS-stripped, Opus packets) into ISO/IEC 14496-12 fMP4 segments (`moof` + `mdat`) suitable for `MediaSource.appendBuffer()`. ISOBMFF box construction is inline — no `mp4-muxer` / `mp4box.js` dependency.
|
|
273
|
+
|
|
274
|
+
```ts
|
|
275
|
+
class MmtpToCmaf {
|
|
276
|
+
setInitSegmentFromMpu(data: Uint8Array, isAudio: boolean): void
|
|
277
|
+
buildVideoInit(avcC: Uint8Array, w: number, h: number): void
|
|
278
|
+
buildAudioInit(sampleRate: number, channels: number, asc?: Uint8Array, timescale?: number): void
|
|
279
|
+
setAudioTimescale(timescale: number): void
|
|
280
|
+
wrapVideoSample(data: Uint8Array, ts: number, keyframe: boolean): Uint8Array
|
|
281
|
+
wrapAudioSample(data: Uint8Array, ts: number, sampleDuration?: number, compositionTimeOffset?: number): Uint8Array
|
|
282
|
+
wrapAudioSamples(samples: Array<{ data: Uint8Array; duration: number; compositionTimeOffset?: number }>, baseDecodeTime: number, trackId?: number): Uint8Array
|
|
283
|
+
readonly videoInitSegment: Uint8Array | null
|
|
284
|
+
readonly audioInitSegment: Uint8Array | null
|
|
285
|
+
}
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
Standalone helpers exported from the same module:
|
|
289
|
+
|
|
290
|
+
| Function | Purpose |
|
|
291
|
+
|----------|---------|
|
|
292
|
+
| `encodeDataSegment(...)` | Single-sample moof+mdat |
|
|
293
|
+
| `encodeMultiSampleSegment(...)` | Multi-sample moof+mdat (one per FEC block — used by `CmafBlockAssembler`) |
|
|
294
|
+
| `buildVideoInitSegment(avcC, w, h)` | ftyp + moov for AVC |
|
|
295
|
+
| `buildAudioInitSegment(sampleRate, channels, asc?, timescale?)` | ftyp + moov for AAC / Opus |
|
|
296
|
+
| `generateGreenFillNAL(avcC, w, h)` | Green-fill NAL when a FEC block fails (loss visible) |
|
|
297
|
+
| `generateSilenceFrame(codec, sampleRate, channels)` | Audio silence frame for FEC-failed audio blocks |
|
|
298
|
+
|
|
299
|
+
Per-track timestamp rebase (`#videoBaseTs` / `#audioBaseTs` at `mmtp-to-cmaf.ts:550-562`) prevents the negative-uint64 `tfdt` bug that kills Chromium MediaSource (`CHUNK_DEMUXER_ERROR_APPEND_FAILED`).
|
|
300
|
+
|
|
301
|
+
### CMCD producer (`./cmcd-producer`)
|
|
302
|
+
|
|
303
|
+
Transport-agnostic CMCD (Common Media Client Data) telemetry per **RFC 9559**. Maps `FecTrackStats` snapshots and `TransportSnapshot` state to `x-bc-*` vendor keys (proto tags 70-99). Does NOT call `fetch()` or write to QUIC — emits via two callbacks (`onCmcdParams` for MoQ SUBSCRIBE params; `onCmcdPost` for HTTP POST query strings).
|
|
304
|
+
|
|
305
|
+
```ts
|
|
306
|
+
class CmcdProducer {
|
|
307
|
+
constructor(opts: CmcdProducerOptions)
|
|
308
|
+
updateTransport(snapshot: TransportSnapshot): void
|
|
309
|
+
updatePlayMode(mode: "full" | "base-only" | "single-track"): void
|
|
310
|
+
updateDeltaFailRate(rate: number): void
|
|
311
|
+
incrementSwitchMiscount(): void
|
|
312
|
+
emitSwitchDrift(driftUs: number): void
|
|
313
|
+
onSnapshot(data: SnapshotData): void
|
|
314
|
+
onTransition(event: TransportTransitionEvent): void
|
|
315
|
+
}
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
Vendor keys emitted (BLO-1044):
|
|
319
|
+
|
|
320
|
+
| Key | Source | Notes |
|
|
321
|
+
|-----|--------|-------|
|
|
322
|
+
| `x-bc-fec-algo` | FEC config | `none` / `raptorq` / `reed-solomon` |
|
|
323
|
+
| `x-bc-fec-k`, `x-bc-fec-p` | FEC config | source / repair counts |
|
|
324
|
+
| `x-bc-fec-recovery` | `recoveryRate` | Block-level recovery, 4 decimal places |
|
|
325
|
+
| `x-bc-scu` | green-fill count | Omitted when 0 |
|
|
326
|
+
| `x-bc-alta-verified`, `x-bc-alta-failures` | ALTA stats | Omitted when ALTA disabled (D-09) |
|
|
327
|
+
| `x-bc-transport` | `TransportSnapshot.transport` | `native` / `amt` / `moq` |
|
|
328
|
+
| `x-bc-multicast-group`, `x-bc-multicast-source`, `x-bc-amt-relay` | endpoint | Omitted when null |
|
|
329
|
+
| `x-bc-play-mode` | Phase 14 D-12 | `full` / `base-only` / `single-track` |
|
|
330
|
+
| `x-bc-delta-fail-rate` | Phase 14 D-15 | 0..1, omitted on single-track |
|
|
331
|
+
| `x-bc-switch-miscount`, `x-bc-switch-drift-us` | switching-set drift | One-shot for drift |
|
|
332
|
+
| `x-bc-ct` | transport transition | `mc-start` / `mc-to-uc` / `amt-start` |
|
|
333
|
+
|
|
334
|
+
All string values pass through `sanitize()` (T-06-01) — commas, `\r`, `\n` are stripped to prevent header injection.
|
|
335
|
+
|
|
336
|
+
### Multicast transport (`./multicast-transport`)
|
|
337
|
+
|
|
338
|
+
Thin wrapper around the lowercase `window.multicast` gateway. Calls `globalThis.multicast.subscribe({ group, source, port, consume: 'bytes' })`, listens for `"bytes"` events (`CustomEvent<ArrayBuffer>`) on the returned `EventTarget` subscription, pumps packets to a callback, runs a 5-second watchdog, and fires `onTakeover` once both video and audio are confirmed receiving.
|
|
339
|
+
|
|
340
|
+
```ts
|
|
341
|
+
class MulticastTransport {
|
|
342
|
+
static isAvailable(): boolean // tests for window.multicast
|
|
343
|
+
constructor(onPacket: (pkt: Uint8Array) => void)
|
|
344
|
+
join(cfg: MulticastTransportConfig): Promise<boolean>
|
|
345
|
+
feedPacket(data: ArrayBuffer | Uint8Array): void // for AMT / ASM injection
|
|
346
|
+
confirmVideo(): void
|
|
347
|
+
confirmAudio(): void
|
|
348
|
+
onTakeover(cb: () => void): void
|
|
349
|
+
onFailback(cb: () => void): void
|
|
350
|
+
dispose(): void
|
|
351
|
+
readonly stats: { packetsReceived: number; bytesReceived: number }
|
|
352
|
+
}
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
Direct Sockets is Chrome-IWA-only. Outside an IWA context `isAvailable()` returns false and join() warns + returns false. AMT tunneling and unicast fallback are handled by `@blockcast/mmt-transport`, not by this transport class.
|
|
356
|
+
|
|
357
|
+
## Track-role convention summary (Phase 14)
|
|
358
|
+
|
|
359
|
+
The role suffix → role mapping is the load-bearing convention for every multi-track Blockcast stream. Quick reference:
|
|
360
|
+
|
|
361
|
+
```
|
|
362
|
+
{name}/base → base (always-on multicast, I-frames)
|
|
363
|
+
{name}/delta → delta (multicast + NACK, P/B-frames)
|
|
364
|
+
{name}/repair → repair (FEC repair-symbol track, cross-CDN federated)
|
|
365
|
+
{name} → single (legacy single-track)
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
Why a name-based convention rather than a catalog field?
|
|
369
|
+
- D-01: keeps CMSF wire format unchanged (no new field upstream of IETF MOQ)
|
|
370
|
+
- D-02: subscription URLs and track names already encode the role
|
|
371
|
+
- D-03: parsers fail loudly on unknown suffixes (`error on bad init`, no silent fallback)
|
|
372
|
+
- D-05: a track has exactly one role — no multi-role arrays
|
|
373
|
+
|
|
374
|
+
Roles are required by:
|
|
375
|
+
- `MediaRouter` for base/delta source arbitration and base-only fallback (D-11)
|
|
376
|
+
- `setupTrackPipeline` for per-role transport selection
|
|
377
|
+
- The FEC pipeline for routing repair-track packets to repair-symbol decoders
|
|
378
|
+
|
|
379
|
+
## DRM extension (planned, M7)
|
|
380
|
+
|
|
381
|
+
`CMSFTrack` will gain an optional `contentProtection?: Array<{ schemeIdUri: string; value?: string; pssh?: string; defaultKeyId?: string }>` field as part of the v4 M7 milestone (Shaka MoQ-CMSF + DRM). It is additive — no wire-format change, no decoder change. Signaled values support Widevine / PlayReady / FairPlay / ClearKey via the standard DASH-IF `schemeIdUri` mapping. Decryption happens in browser MSE (Encrypted Media Extensions) or mobile MediaDrm; this package's job is signaling only.
|
|
382
|
+
|
|
383
|
+
> **Upstream gap:** at the time of writing, the parent monorepo's
|
|
384
|
+
> `.planning/reliable-multicast-M7-spec.md` referenced by the libmmt
|
|
385
|
+
> README has not yet landed. M1-M4 specs exist; M7 is tracked in
|
|
386
|
+
> `MILESTONES.md` and `ROADMAP.md` only.
|
|
387
|
+
|
|
388
|
+
## Specifications
|
|
389
|
+
|
|
390
|
+
- **ISO/IEC 23008-1:2023** — MPEG-H Part 1 (MMT)
|
|
391
|
+
- **ISO/IEC 23008-1:2023/Amd 1:2025** — AL-FEC framework for MMT (`ALFEC_MESSAGE_ID = 0x0203`)
|
|
392
|
+
- **ISO/IEC 14496-12** — ISOBMFF (consumed for fMP4 box construction in `mmtp-to-cmaf.ts`)
|
|
393
|
+
- **draft-ietf-moq-catalogformat** — CMSF catalog (IETF MOQ WG)
|
|
394
|
+
- **draft-law-ramadan-moq-carp-reliability** — CARP §3 (FEC) + §4 (multicast endpoints) + §5.1 (interleave units) + §6.1 (repair track)
|
|
395
|
+
- **draft-ramadan-moq-mmt-00** — MMT-over-MoQ wire format (§4.4.4 group-duration signaling, §5.3 MMTP→CMAF mapping)
|
|
396
|
+
- **draft-ramadan-moq-fec** — AL-FEC over MoQ (§7.1 LOC FEC Source Info: SBN(32)+ESI(32)+optional QUIC-varint length)
|
|
397
|
+
- **RFC 6330** — RaptorQ Forward Error Correction (strict OTI codec in `@blockcast/mmt-fec`)
|
|
398
|
+
- **RFC 9559** — CMCD (used by `CmcdProducer`)
|
|
399
|
+
- **ATSC A/331** — Signaling, Delivery, Synchronization, Error Protection
|
|
400
|
+
|
|
401
|
+
## Related packages
|
|
402
|
+
|
|
403
|
+
| Package | Relationship |
|
|
404
|
+
|---------|--------------|
|
|
405
|
+
| `@blockcast/mmt-fec` | RaptorQ geometry, timeout, and OTI helpers. Direct dependency. |
|
|
406
|
+
| `@blockcast/fec-worker` | Web-Worker-hosted FEC client (`FecWorkerClient`, `FecTrackStats`, `FrameMeta`, `FecBlockSnapshot`). Direct dependency. |
|
|
407
|
+
| `@blockcast/mmt-transport` | Higher-level transport manager (MoQ + SSM + AMT + DRIAD). Consumes this package's parser. |
|
|
408
|
+
| `@blockcast/mmt-base` | Canonical MMTP/MPU/MFU, AL-FEC signaling, and payload-boundary parser leaf. Direct dependency. |
|
|
409
|
+
| `@blockcast/mmt-alta-parse` | ALTA sender-authentication trailer parser. Direct dependency. |
|
|
410
|
+
| `@blockcast/mmt-render` | Reference renderer + `AudioRingBuffer` (canonical location). The `audio-ring-buffer` re-export here is deprecated. |
|
|
411
|
+
|
|
412
|
+
## Testing
|
|
413
|
+
|
|
414
|
+
```bash
|
|
415
|
+
npm test # vitest run
|
|
416
|
+
npm run test:watch
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
Tests live in `src/__tests__/` and as inline `if (import.meta.vitest) {…}` blocks (e.g. `loc.ts:166`). Coverage includes:
|
|
420
|
+
|
|
421
|
+
- MFU reassembly and container integration with the `@blockcast/mmt-base` parser
|
|
422
|
+
- CARP catalog ingest + role parser (with T-14-01 fuzz cases)
|
|
423
|
+
- Switching-set timing alignment
|
|
424
|
+
- CMCD producer with synthesized `FecTrackStats`
|
|
425
|
+
- `MmtpContainerParser` end-to-end with mock packets
|
|
426
|
+
- `MmtpRouter` two-phase parsing + FEC feed
|
|
427
|
+
- `MediaRouter` source arbitration + group drift
|
|
428
|
+
- Worker-pipeline tests (`fec-manager.test.ts` exercises `FecWorkerClient` mocks for the Worker decode path)
|
|
429
|
+
|
|
430
|
+
## License
|
|
431
|
+
|
|
432
|
+
Apache-2.0 — see `LICENSE`.
|
|
File without changes
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build a minimal MMTP source packet for testing.
|
|
3
|
+
* MMTP header (12 bytes) + MPU header (8 bytes) + optional MFU DU header (14 bytes) + video data + optional FEC ID (4 bytes)
|
|
4
|
+
*/
|
|
5
|
+
export interface BuildMmtpPacketOptions {
|
|
6
|
+
packetId?: number;
|
|
7
|
+
packetType?: number;
|
|
8
|
+
fecType?: number;
|
|
9
|
+
rapFlag?: boolean;
|
|
10
|
+
timestamp?: number;
|
|
11
|
+
sequenceNumber?: number;
|
|
12
|
+
fi?: number;
|
|
13
|
+
fragmentCounter?: number;
|
|
14
|
+
mpuSeq?: number;
|
|
15
|
+
fragmentType?: number;
|
|
16
|
+
timedFlag?: number;
|
|
17
|
+
includeMfuDuHeader?: boolean;
|
|
18
|
+
payloadLength?: number;
|
|
19
|
+
videoData?: Uint8Array;
|
|
20
|
+
appendFecId?: boolean;
|
|
21
|
+
ssId?: number;
|
|
22
|
+
movieFragmentSequenceNumber?: number;
|
|
23
|
+
sampleNumber?: number;
|
|
24
|
+
sampleOffset?: number;
|
|
25
|
+
priority?: number;
|
|
26
|
+
}
|
|
27
|
+
export declare function buildMmtpPacket(opts: BuildMmtpPacketOptions): Uint8Array;
|
|
28
|
+
/** Build AVCC NAL unit: 4-byte length prefix + NAL header byte + payload.
|
|
29
|
+
* nalType=5 → IDR (keyframe), nalType=1 → P-frame (delta). */
|
|
30
|
+
export declare function makeAvcc(nalType: number, payloadSize?: number): Uint8Array;
|
|
31
|
+
/** Build HEVC NAL unit: 4-byte length prefix + 2-byte NAL header.
|
|
32
|
+
* hevcType in range 16-21 → IRAP (keyframe). */
|
|
33
|
+
export declare function makeHevc(hevcType: number, payloadSize?: number): Uint8Array;
|
|
34
|
+
export interface TestIsoBmffInitializationOptions {
|
|
35
|
+
trackId?: number;
|
|
36
|
+
timescale?: number;
|
|
37
|
+
defaultSampleDuration?: number;
|
|
38
|
+
defaultSampleSize?: number;
|
|
39
|
+
handlerType?: 'vide' | 'soun';
|
|
40
|
+
}
|
|
41
|
+
/** Build current-profile single-track FT=0 timing metadata for parser tests. */
|
|
42
|
+
export declare function buildTestIsoBmffInitialization(options?: TestIsoBmffInitializationOptions): Uint8Array;
|
|
43
|
+
export interface TestIsoBmffMovieFragmentOptions {
|
|
44
|
+
trackId?: number;
|
|
45
|
+
movieFragmentSequenceNumber?: number;
|
|
46
|
+
decodeTime?: bigint;
|
|
47
|
+
sampleSizes: readonly number[];
|
|
48
|
+
sampleDurations?: readonly number[];
|
|
49
|
+
compositionOffsets?: readonly number[];
|
|
50
|
+
mdatPrefix?: Uint8Array;
|
|
51
|
+
}
|
|
52
|
+
/** Build current-profile FT=1 moof + declared mdat prefix for parser tests. */
|
|
53
|
+
export declare function buildTestIsoBmffMovieFragment(options: TestIsoBmffMovieFragmentOptions): Uint8Array;
|
|
54
|
+
export interface TestMmtpTimingPacketOptions {
|
|
55
|
+
packetId?: number;
|
|
56
|
+
mpuSequenceNumber?: number;
|
|
57
|
+
movieFragmentSequenceNumber?: number;
|
|
58
|
+
sampleSizes: readonly number[];
|
|
59
|
+
decodeTime?: bigint;
|
|
60
|
+
timescale?: number;
|
|
61
|
+
defaultSampleDuration?: number;
|
|
62
|
+
sampleDurations?: readonly number[];
|
|
63
|
+
compositionOffsets?: readonly number[];
|
|
64
|
+
handlerType?: 'vide' | 'soun';
|
|
65
|
+
}
|
|
66
|
+
/** Build the canonical FT=0 and FT=1 packets required before timed FT=2. */
|
|
67
|
+
export declare function buildTestMmtpTimingPackets(options: TestMmtpTimingPacketOptions): {
|
|
68
|
+
initialization: Uint8Array;
|
|
69
|
+
movieFragment: Uint8Array;
|
|
70
|
+
};
|
|
71
|
+
//# sourceMappingURL=test-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-utils.d.ts","sourceRoot":"","sources":["../../src/__tests__/test-utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,SAAS,CAAC,EAAE,UAAU,CAAA;IACtB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,2BAA2B,CAAC,EAAE,MAAM,CAAA;IACpC,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,sBAAsB,GAAG,UAAU,CAkExE;AAED;+DAC+D;AAC/D,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,SAAI,GAAG,UAAU,CASrE;AAED;iDACiD;AACjD,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,SAAI,GAAG,UAAU,CAOtE;AA8CD,MAAM,WAAW,gCAAgC;IAC/C,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;CAC9B;AAED,gFAAgF;AAChF,wBAAgB,8BAA8B,CAC5C,OAAO,GAAE,gCAAqC,GAC7C,UAAU,CA+BZ;AAED,MAAM,WAAW,+BAA+B;IAC9C,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,2BAA2B,CAAC,EAAE,MAAM,CAAA;IACpC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,SAAS,MAAM,EAAE,CAAA;IAC9B,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACnC,kBAAkB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACtC,UAAU,CAAC,EAAE,UAAU,CAAA;CACxB;AAED,+EAA+E;AAC/E,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,+BAA+B,GACvC,UAAU,CAoDZ;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,2BAA2B,CAAC,EAAE,MAAM,CAAA;IACpC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAA;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACnC,kBAAkB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACtC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;CAC9B;AAED,4EAA4E;AAC5E,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,2BAA2B,GAAG;IAChF,cAAc,EAAE,UAAU,CAAA;IAC1B,aAAa,EAAE,UAAU,CAAA;CAC1B,CA+BA"}
|
package/dist/align.d.ts
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared group-alignment primitive for MMT over MoQ switching sets.
|
|
3
|
+
*
|
|
4
|
+
* Pure math — no MMT wire parsing, no CMCD, no I/O. Callers wire the output
|
|
5
|
+
* into their own drift-observation plumbing (see media-router.ts for the
|
|
6
|
+
* libmmt wiring).
|
|
7
|
+
*
|
|
8
|
+
* ──────────────────────────────────────────────────────────────────────────
|
|
9
|
+
* Contract (integer-ticks form, authoritative):
|
|
10
|
+
*
|
|
11
|
+
* groupId = ticks < 0 ? 0 : floor(ticks / groupDurationTicks)
|
|
12
|
+
*
|
|
13
|
+
* Where `ticks` is a media timestamp expressed at the catalog's `timescale`
|
|
14
|
+
* (Hz), and `groupDurationTicks = groupDurationSec * timescale`.
|
|
15
|
+
*
|
|
16
|
+
* Integer math means there is no epsilon and no float rounding to reason
|
|
17
|
+
* about. The seconds-form wrapper `groupIdFor(Seconds, seconds)` exists for
|
|
18
|
+
* legacy callers but converts to ticks internally.
|
|
19
|
+
*
|
|
20
|
+
* Every sender/receiver that emits or consumes MoQ groups from an MMT or
|
|
21
|
+
* CMAF switching set MUST derive groupId from this formula so that base,
|
|
22
|
+
* delta, and repair tracks agree on the group boundary for a given media
|
|
23
|
+
* timestamp across languages and processes.
|
|
24
|
+
*
|
|
25
|
+
* Test vectors that exercise the contract live at
|
|
26
|
+
* `packages/container/test-vectors/align.json`; the Go and Rust siblings
|
|
27
|
+
* load the same fixture so cross-language agreement is executable, not
|
|
28
|
+
* prose. **Formula changes require updating the fixture AND all three
|
|
29
|
+
* sibling implementations in the same release** — divergence between
|
|
30
|
+
* sender/relay/receiver is worse than any formula change.
|
|
31
|
+
*
|
|
32
|
+
* Canonical implementations:
|
|
33
|
+
* Go: Blockcast/multicast `cmd/caddy/sender/group_align.go`
|
|
34
|
+
* (commit 104eeff) — sender-side groupId stamping on egress.
|
|
35
|
+
* Rust: moqtail/moqtail `apps/relay/src/server/abr.rs`
|
|
36
|
+
* (commit 39accbf; experimental branch, may be rebased — rely
|
|
37
|
+
* on the SHA, not the branch name) — relay-side check.
|
|
38
|
+
* TS: THIS FILE (libmmt) — consumed by moq-lib + moqtail-ts via
|
|
39
|
+
* @blockcast/mmt-container.
|
|
40
|
+
* ──────────────────────────────────────────────────────────────────────────
|
|
41
|
+
*/
|
|
42
|
+
/**
|
|
43
|
+
* Branded seconds type. Construct only via `secondsFromTicks(ticks, timescale)`
|
|
44
|
+
* or `asSeconds(n)` (the latter exists solely for tests and bring-up). The
|
|
45
|
+
* brand prevents accidentally passing a raw tick count — or a Date.now()
|
|
46
|
+
* millisecond — to an API that expects a media-time in seconds.
|
|
47
|
+
*/
|
|
48
|
+
export type Seconds = number & {
|
|
49
|
+
readonly __brand: 'Seconds';
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Explicit conversion constructor: ticks at `timescale` Hz → Seconds.
|
|
53
|
+
*
|
|
54
|
+
* Call this at the wire/catalog boundary so the brand flows with the value
|
|
55
|
+
* through the rest of the system. Throws on non-finite inputs or
|
|
56
|
+
* non-positive timescale (CLAUDE.md §Architectural Principles: error on
|
|
57
|
+
* bad init).
|
|
58
|
+
*/
|
|
59
|
+
export declare function secondsFromTicks(ticks: number, timescale: number): Seconds;
|
|
60
|
+
/**
|
|
61
|
+
* Escape hatch for tests / bring-up code that holds a raw seconds number
|
|
62
|
+
* (e.g. a catalog field that ships as float seconds). Production code
|
|
63
|
+
* should prefer `secondsFromTicks` so the conversion site is explicit.
|
|
64
|
+
*/
|
|
65
|
+
export declare function asSeconds(n: number): Seconds;
|
|
66
|
+
/**
|
|
67
|
+
* Deterministic groupId from integer ticks. Authoritative form of the
|
|
68
|
+
* contract (see module docstring).
|
|
69
|
+
*
|
|
70
|
+
* @param ticks — media presentation time in ticks (integer).
|
|
71
|
+
* Negative values clamp to group 0 (matches
|
|
72
|
+
* the Go sibling's base-clamp).
|
|
73
|
+
* @param groupDurationTicks — group duration in ticks (positive integer).
|
|
74
|
+
* @returns non-negative integer groupId.
|
|
75
|
+
*
|
|
76
|
+
* Throws on non-integer/non-finite inputs or non-positive duration. These
|
|
77
|
+
* are init-time errors, not packet-hot-path errors — callers ingesting
|
|
78
|
+
* wire data should validate once at catalog load, not once per packet.
|
|
79
|
+
*/
|
|
80
|
+
export declare function groupIdForTicks(ticks: number, groupDurationTicks: number): number;
|
|
81
|
+
/**
|
|
82
|
+
* Seconds-form wrapper around `groupIdForTicks`. Kept for backwards
|
|
83
|
+
* compatibility with existing callers that hold `Seconds` (or a raw
|
|
84
|
+
* `number` that semantically represents seconds).
|
|
85
|
+
*
|
|
86
|
+
* Internally converts to ticks using a synthetic 1e9 Hz timescale so the
|
|
87
|
+
* integer-math contract is the single source of truth. The `| number`
|
|
88
|
+
* branch of the parameter type is a migration ramp — new code should
|
|
89
|
+
* pass `Seconds` explicitly (via `secondsFromTicks` or `asSeconds`).
|
|
90
|
+
*
|
|
91
|
+
* @param mediaTimeSec — finite number of seconds; negatives clamp to 0.
|
|
92
|
+
* @param groupDurationSec — positive finite seconds.
|
|
93
|
+
*
|
|
94
|
+
* @deprecated Use `groupIdForTicks(ticks, groupDurationTicks)` with
|
|
95
|
+
* tick-space inputs from the catalog. The seconds wrapper rounds to the
|
|
96
|
+
* nearest nanosecond and throws above ~104 days of media time; the
|
|
97
|
+
* integer-ticks form has no rounding and a much wider safe range.
|
|
98
|
+
*
|
|
99
|
+
* The rounding is not benign: when `groupDurationTicks / timescale` is not
|
|
100
|
+
* ns-exact (33333@90k, 1001@30k, 1024@44.1k — all real catalog cadences)
|
|
101
|
+
* the quantized duration under-counts and `expected` slips a whole group.
|
|
102
|
+
* See the divergence fixture in `__tests__/align.test.ts`.
|
|
103
|
+
*
|
|
104
|
+
* No non-test caller remains in this package: `MediaRouter` now takes
|
|
105
|
+
* `GroupBoundaryTicks` (PCL-2211). Removal is tracked by BLO-21176.
|
|
106
|
+
*/
|
|
107
|
+
export declare function groupIdFor(mediaTimeSec: Seconds | number, groupDurationSec: number): number;
|
|
108
|
+
/**
|
|
109
|
+
* Result of a drift check between expected and actual groupIds.
|
|
110
|
+
*
|
|
111
|
+
* Discriminated on `kind` so callers must handle both outcomes explicitly
|
|
112
|
+
* (the previous `{ drifted: boolean, deltaGroups: number }` shape let a
|
|
113
|
+
* drifted result slip through with a silent `if (result.drifted)` gate).
|
|
114
|
+
*/
|
|
115
|
+
export type DriftCheckResult = {
|
|
116
|
+
readonly kind: 'aligned';
|
|
117
|
+
readonly deltaGroups: 0;
|
|
118
|
+
} | {
|
|
119
|
+
readonly kind: 'drifted';
|
|
120
|
+
readonly deltaGroups: number;
|
|
121
|
+
};
|
|
122
|
+
/**
|
|
123
|
+
* Compare a packet-stamped groupId against the formula-derived expectation.
|
|
124
|
+
*
|
|
125
|
+
* Pure observer — does not throw on drift, does not mutate anything.
|
|
126
|
+
* Callers decide how to react (e.g. bump a CMCD counter, log, ignore).
|
|
127
|
+
*
|
|
128
|
+
* @param expected — groupId as derived via `groupIdForTicks` or `groupIdFor`.
|
|
129
|
+
* @param actual — groupId as stamped on the incoming packet/group.
|
|
130
|
+
*/
|
|
131
|
+
export declare function driftCheck(expected: number, actual: number): DriftCheckResult;
|
|
132
|
+
export type MmtpSubgroupKeyInput = {
|
|
133
|
+
readonly kind: 'mpu-metadata';
|
|
134
|
+
} | {
|
|
135
|
+
readonly kind: 'timed';
|
|
136
|
+
readonly movieFragmentSequenceNumber: number;
|
|
137
|
+
readonly sampleNumber: number;
|
|
138
|
+
} | {
|
|
139
|
+
readonly kind: 'non-timed';
|
|
140
|
+
readonly itemId: number;
|
|
141
|
+
};
|
|
142
|
+
/**
|
|
143
|
+
* Canonical, domain-separated key for MMTP payloads sharing one MoQ subgroup.
|
|
144
|
+
* This is a map/storage key, not the scalar MoQ subgroup ID. MPU metadata is
|
|
145
|
+
* carried in subgroup 0; media identity remains explicit and collision-free.
|
|
146
|
+
*/
|
|
147
|
+
export declare function subgroupKeyFor(input: MmtpSubgroupKeyInput): string;
|
|
148
|
+
//# sourceMappingURL=align.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"align.d.ts","sourceRoot":"","sources":["../src/align.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH;;;;;GAKG;AACH,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAA;CAAE,CAAA;AAE9D;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAU1E;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAK5C;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,GAAG,MAAM,CAajF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,UAAU,CACxB,YAAY,EAAE,OAAO,GAAG,MAAM,EAC9B,gBAAgB,EAAE,MAAM,GACvB,MAAM,CA+BR;AAED;;;;;;GAMG;AACH,MAAM,MAAM,gBAAgB,GACxB;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAA;CAAE,GACrD;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAA;AAE9D;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,gBAAgB,CAS7E;AAED,MAAM,MAAM,oBAAoB,GAC5B;IAAE,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAA;CAAE,GACjC;IACE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;IACtB,QAAQ,CAAC,2BAA2B,EAAE,MAAM,CAAA;IAC5C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;CAC9B,GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AAE3D;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,oBAAoB,GAAG,MAAM,CAgBlE"}
|