@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/src/align.ts
ADDED
|
@@ -0,0 +1,235 @@
|
|
|
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
|
+
/**
|
|
44
|
+
* Branded seconds type. Construct only via `secondsFromTicks(ticks, timescale)`
|
|
45
|
+
* or `asSeconds(n)` (the latter exists solely for tests and bring-up). The
|
|
46
|
+
* brand prevents accidentally passing a raw tick count — or a Date.now()
|
|
47
|
+
* millisecond — to an API that expects a media-time in seconds.
|
|
48
|
+
*/
|
|
49
|
+
export type Seconds = number & { 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 function secondsFromTicks(ticks: number, timescale: number): Seconds {
|
|
60
|
+
if (!Number.isFinite(ticks)) {
|
|
61
|
+
throw new Error(`[align] secondsFromTicks: ticks must be finite, got ${ticks}`)
|
|
62
|
+
}
|
|
63
|
+
if (!Number.isFinite(timescale) || timescale <= 0) {
|
|
64
|
+
throw new Error(
|
|
65
|
+
`[align] secondsFromTicks: timescale must be positive and finite, got ${timescale}`,
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
return (ticks / timescale) as Seconds
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Escape hatch for tests / bring-up code that holds a raw seconds number
|
|
73
|
+
* (e.g. a catalog field that ships as float seconds). Production code
|
|
74
|
+
* should prefer `secondsFromTicks` so the conversion site is explicit.
|
|
75
|
+
*/
|
|
76
|
+
export function asSeconds(n: number): Seconds {
|
|
77
|
+
if (!Number.isFinite(n)) {
|
|
78
|
+
throw new Error(`[align] asSeconds: value must be finite, got ${n}`)
|
|
79
|
+
}
|
|
80
|
+
return n as Seconds
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Deterministic groupId from integer ticks. Authoritative form of the
|
|
85
|
+
* contract (see module docstring).
|
|
86
|
+
*
|
|
87
|
+
* @param ticks — media presentation time in ticks (integer).
|
|
88
|
+
* Negative values clamp to group 0 (matches
|
|
89
|
+
* the Go sibling's base-clamp).
|
|
90
|
+
* @param groupDurationTicks — group duration in ticks (positive integer).
|
|
91
|
+
* @returns non-negative integer groupId.
|
|
92
|
+
*
|
|
93
|
+
* Throws on non-integer/non-finite inputs or non-positive duration. These
|
|
94
|
+
* are init-time errors, not packet-hot-path errors — callers ingesting
|
|
95
|
+
* wire data should validate once at catalog load, not once per packet.
|
|
96
|
+
*/
|
|
97
|
+
export function groupIdForTicks(ticks: number, groupDurationTicks: number): number {
|
|
98
|
+
if (!Number.isInteger(ticks)) {
|
|
99
|
+
throw new Error(
|
|
100
|
+
`[align] groupIdForTicks: ticks must be an integer, got ${ticks}`,
|
|
101
|
+
)
|
|
102
|
+
}
|
|
103
|
+
if (!Number.isInteger(groupDurationTicks) || groupDurationTicks <= 0) {
|
|
104
|
+
throw new Error(
|
|
105
|
+
`[align] groupIdForTicks: groupDurationTicks must be a positive integer, got ${groupDurationTicks}`,
|
|
106
|
+
)
|
|
107
|
+
}
|
|
108
|
+
if (ticks < 0) return 0
|
|
109
|
+
return Math.floor(ticks / groupDurationTicks)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Seconds-form wrapper around `groupIdForTicks`. Kept for backwards
|
|
114
|
+
* compatibility with existing callers that hold `Seconds` (or a raw
|
|
115
|
+
* `number` that semantically represents seconds).
|
|
116
|
+
*
|
|
117
|
+
* Internally converts to ticks using a synthetic 1e9 Hz timescale so the
|
|
118
|
+
* integer-math contract is the single source of truth. The `| number`
|
|
119
|
+
* branch of the parameter type is a migration ramp — new code should
|
|
120
|
+
* pass `Seconds` explicitly (via `secondsFromTicks` or `asSeconds`).
|
|
121
|
+
*
|
|
122
|
+
* @param mediaTimeSec — finite number of seconds; negatives clamp to 0.
|
|
123
|
+
* @param groupDurationSec — positive finite seconds.
|
|
124
|
+
*
|
|
125
|
+
* @deprecated Use `groupIdForTicks(ticks, groupDurationTicks)` with
|
|
126
|
+
* tick-space inputs from the catalog. The seconds wrapper rounds to the
|
|
127
|
+
* nearest nanosecond and throws above ~104 days of media time; the
|
|
128
|
+
* integer-ticks form has no rounding and a much wider safe range.
|
|
129
|
+
*
|
|
130
|
+
* The rounding is not benign: when `groupDurationTicks / timescale` is not
|
|
131
|
+
* ns-exact (33333@90k, 1001@30k, 1024@44.1k — all real catalog cadences)
|
|
132
|
+
* the quantized duration under-counts and `expected` slips a whole group.
|
|
133
|
+
* See the divergence fixture in `__tests__/align.test.ts`.
|
|
134
|
+
*
|
|
135
|
+
* No non-test caller remains in this package: `MediaRouter` now takes
|
|
136
|
+
* `GroupBoundaryTicks` (PCL-2211). Removal is tracked by BLO-21176.
|
|
137
|
+
*/
|
|
138
|
+
export function groupIdFor(
|
|
139
|
+
mediaTimeSec: Seconds | number,
|
|
140
|
+
groupDurationSec: number,
|
|
141
|
+
): number {
|
|
142
|
+
if (!Number.isFinite(mediaTimeSec as number)) {
|
|
143
|
+
throw new Error(
|
|
144
|
+
`[align] groupIdFor: mediaTimeSec must be a finite number, got ${mediaTimeSec}`,
|
|
145
|
+
)
|
|
146
|
+
}
|
|
147
|
+
if (!Number.isFinite(groupDurationSec) || groupDurationSec <= 0) {
|
|
148
|
+
throw new Error(
|
|
149
|
+
`[align] groupIdFor: groupDurationSec must be a positive finite number, got ${groupDurationSec}`,
|
|
150
|
+
)
|
|
151
|
+
}
|
|
152
|
+
if ((mediaTimeSec as number) < 0) return 0
|
|
153
|
+
// 1e9 Hz keeps both operands inside Number.MAX_SAFE_INTEGER (2^53-1)
|
|
154
|
+
// for ~104 days of media time. Beyond that, Math.round returns a
|
|
155
|
+
// non-safe-integer float that Number.isInteger still accepts — throw
|
|
156
|
+
// explicitly so the caller picks a narrower timescale rather than
|
|
157
|
+
// silently quantizing.
|
|
158
|
+
const TS = 1_000_000_000
|
|
159
|
+
const ticks = Math.round((mediaTimeSec as number) * TS)
|
|
160
|
+
const durTicks = Math.round(groupDurationSec * TS)
|
|
161
|
+
if (durTicks <= 0) {
|
|
162
|
+
throw new Error(
|
|
163
|
+
`[align] groupIdFor: groupDurationSec=${groupDurationSec} rounds to <1 tick at 1e9 Hz; pass groupIdForTicks directly for sub-nanosecond durations`,
|
|
164
|
+
)
|
|
165
|
+
}
|
|
166
|
+
if (!Number.isSafeInteger(ticks)) {
|
|
167
|
+
throw new Error(
|
|
168
|
+
`[align] groupIdFor: mediaTimeSec=${mediaTimeSec} overflows safe-integer ticks at 1e9 Hz (>~104 days); use groupIdForTicks with a narrower timescale`,
|
|
169
|
+
)
|
|
170
|
+
}
|
|
171
|
+
return groupIdForTicks(ticks, durTicks)
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Result of a drift check between expected and actual groupIds.
|
|
176
|
+
*
|
|
177
|
+
* Discriminated on `kind` so callers must handle both outcomes explicitly
|
|
178
|
+
* (the previous `{ drifted: boolean, deltaGroups: number }` shape let a
|
|
179
|
+
* drifted result slip through with a silent `if (result.drifted)` gate).
|
|
180
|
+
*/
|
|
181
|
+
export type DriftCheckResult =
|
|
182
|
+
| { readonly kind: 'aligned'; readonly deltaGroups: 0 }
|
|
183
|
+
| { readonly kind: 'drifted'; readonly deltaGroups: number }
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Compare a packet-stamped groupId against the formula-derived expectation.
|
|
187
|
+
*
|
|
188
|
+
* Pure observer — does not throw on drift, does not mutate anything.
|
|
189
|
+
* Callers decide how to react (e.g. bump a CMCD counter, log, ignore).
|
|
190
|
+
*
|
|
191
|
+
* @param expected — groupId as derived via `groupIdForTicks` or `groupIdFor`.
|
|
192
|
+
* @param actual — groupId as stamped on the incoming packet/group.
|
|
193
|
+
*/
|
|
194
|
+
export function driftCheck(expected: number, actual: number): DriftCheckResult {
|
|
195
|
+
if (!Number.isInteger(expected) || !Number.isInteger(actual)) {
|
|
196
|
+
throw new Error(
|
|
197
|
+
`[align] driftCheck: both arguments must be integer groupIds, got expected=${expected} actual=${actual}`,
|
|
198
|
+
)
|
|
199
|
+
}
|
|
200
|
+
const deltaGroups = actual - expected
|
|
201
|
+
if (deltaGroups === 0) return { kind: 'aligned', deltaGroups: 0 }
|
|
202
|
+
return { kind: 'drifted', deltaGroups }
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export type MmtpSubgroupKeyInput =
|
|
206
|
+
| { readonly kind: 'mpu-metadata' }
|
|
207
|
+
| {
|
|
208
|
+
readonly kind: 'timed'
|
|
209
|
+
readonly movieFragmentSequenceNumber: number
|
|
210
|
+
readonly sampleNumber: number
|
|
211
|
+
}
|
|
212
|
+
| { readonly kind: 'non-timed'; readonly itemId: number }
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Canonical, domain-separated key for MMTP payloads sharing one MoQ subgroup.
|
|
216
|
+
* This is a map/storage key, not the scalar MoQ subgroup ID. MPU metadata is
|
|
217
|
+
* carried in subgroup 0; media identity remains explicit and collision-free.
|
|
218
|
+
*/
|
|
219
|
+
export function subgroupKeyFor(input: MmtpSubgroupKeyInput): string {
|
|
220
|
+
if (input.kind === 'mpu-metadata') return 'metadata:0'
|
|
221
|
+
|
|
222
|
+
const values =
|
|
223
|
+
input.kind === 'timed'
|
|
224
|
+
? [input.movieFragmentSequenceNumber, input.sampleNumber]
|
|
225
|
+
: [input.itemId]
|
|
226
|
+
for (const value of values) {
|
|
227
|
+
if (!Number.isInteger(value) || value < 0 || value > 0xffff_ffff) {
|
|
228
|
+
throw new Error(`[align] subgroup key coordinates must be uint32, got ${value}`)
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
return input.kind === 'timed'
|
|
233
|
+
? `timed:${input.movieFragmentSequenceNumber}:${input.sampleNumber}`
|
|
234
|
+
: `non-timed:${input.itemId}`
|
|
235
|
+
}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audio Init Data Parser — extract frame samples from a codec descriptor.
|
|
3
|
+
*
|
|
4
|
+
* Consumes the RAW codec configuration bytes (AudioSpecificConfig for AAC,
|
|
5
|
+
* OpusHead for Opus) — i.e. the catalog `description` field (hang
|
|
6
|
+
* `AudioConfig.description`), NOT the catalog `initData` field.
|
|
7
|
+
*
|
|
8
|
+
* Since BLO-9884 these are two distinct catalog fields: `initData` is a
|
|
9
|
+
* base64 ISOBMFF init segment (ftyp + moov) per draft-ietf-moq-cmsf-00 §3.1,
|
|
10
|
+
* while `description` carries the bare codec descriptor. Hang's `root.ts`
|
|
11
|
+
* parses a CMSF `initData` segment with `decodeInitSegment()` and routes the
|
|
12
|
+
* descriptor it recovers (`init.description`) into `description`; the bytes
|
|
13
|
+
* that reach this parser are therefore always the bare descriptor. Do NOT
|
|
14
|
+
* pass a ftyp+moov `initData` blob here — the ASC bit-reader would interpret
|
|
15
|
+
* the ftyp box size word as an audioObjectType and return a garbage frame
|
|
16
|
+
* count (the audio analogue of the "Failed to parse avcC" CMAF regression
|
|
17
|
+
* documented in root.ts).
|
|
18
|
+
*
|
|
19
|
+
* Supported codecs:
|
|
20
|
+
* - AAC (mp4a.40.*): AudioSpecificConfig per ISO 14496-3 §1.6.2.1
|
|
21
|
+
* - Opus: fixed 960 samples per RFC 6716 §2.1.4
|
|
22
|
+
*
|
|
23
|
+
* Reference: hang-mmt-fec/rs/moq-mux/src/import/aac.rs:AacConfig::parse()
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
// ISO 14496-3 Table 1.14: samplingFrequencyIndex → Hz
|
|
27
|
+
const AAC_SAMPLE_RATES = [
|
|
28
|
+
96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
|
|
29
|
+
16000, 12000, 11025, 8000, 7350,
|
|
30
|
+
] as const
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* AAC Audio Object Types that determine frame size.
|
|
34
|
+
* ISO 14496-3 Table 1.3:
|
|
35
|
+
* 1 = AAC-Main → 1024 samples
|
|
36
|
+
* 2 = AAC-LC → 1024 samples
|
|
37
|
+
* 3 = AAC-SSR → 1024 samples
|
|
38
|
+
* 4 = AAC-LTP → 1024 samples
|
|
39
|
+
* 5 = SBR → 2048 samples (HE-AAC v1)
|
|
40
|
+
* 6 = AAC-Scalable → 1024 samples
|
|
41
|
+
* 23 = ER AAC-LD → 512 samples
|
|
42
|
+
* 39 = ER AAC-ELD → 480 samples
|
|
43
|
+
* 29 = PS → 2048 samples (HE-AAC v2, implies SBR)
|
|
44
|
+
*/
|
|
45
|
+
function aacFrameSamplesForObjectType(objectType: number): number {
|
|
46
|
+
switch (objectType) {
|
|
47
|
+
case 5: return 2048 // SBR (HE-AAC v1)
|
|
48
|
+
case 29: return 2048 // PS (HE-AAC v2, implies SBR)
|
|
49
|
+
case 23: return 512 // ER AAC-LD
|
|
50
|
+
case 39: return 480 // ER AAC-ELD
|
|
51
|
+
default: return 1024 // LC, Main, SSR, LTP, Scalable, etc.
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Parse AAC AudioSpecificConfig (ASC) to extract frame samples.
|
|
57
|
+
*
|
|
58
|
+
* ASC is a bit-packed structure (ISO 14496-3 §1.6.2.1):
|
|
59
|
+
* audioObjectType (5 bits, or 5+6 if ==31)
|
|
60
|
+
* samplingFrequencyIndex (4 bits, explicit rate if ==0xf)
|
|
61
|
+
* channelConfiguration (4 bits)
|
|
62
|
+
* ... (SBR/PS extensions follow)
|
|
63
|
+
*
|
|
64
|
+
* The audioObjectType determines frame samples:
|
|
65
|
+
* LC-AAC → 1024, HE-AAC(SBR) → 2048, AAC-LD → 512, AAC-ELD → 480
|
|
66
|
+
*
|
|
67
|
+
* @param asc - Raw AudioSpecificConfig bytes (NOT ADTS, NOT fMP4 esds box)
|
|
68
|
+
* @returns frame samples, or null if ASC is invalid/too short
|
|
69
|
+
*/
|
|
70
|
+
export function parseAacFrameSamples(asc: Uint8Array): number | null {
|
|
71
|
+
if (asc.length < 2) return null
|
|
72
|
+
|
|
73
|
+
// Bit reader
|
|
74
|
+
let bitPos = 0
|
|
75
|
+
const readBits = (n: number): number => {
|
|
76
|
+
let val = 0
|
|
77
|
+
for (let i = 0; i < n; i++) {
|
|
78
|
+
const byteIdx = (bitPos + i) >> 3
|
|
79
|
+
const bitIdx = 7 - ((bitPos + i) & 7)
|
|
80
|
+
if (byteIdx >= asc.length) return -1
|
|
81
|
+
val = (val << 1) | ((asc[byteIdx]! >> bitIdx) & 1)
|
|
82
|
+
}
|
|
83
|
+
bitPos += n
|
|
84
|
+
return val
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// audioObjectType: 5 bits, extended to 5+6=11 bits if ==31
|
|
88
|
+
let objectType = readBits(5)
|
|
89
|
+
if (objectType === 31) {
|
|
90
|
+
objectType = 32 + readBits(6)
|
|
91
|
+
}
|
|
92
|
+
if (objectType < 0) return null
|
|
93
|
+
|
|
94
|
+
// samplingFrequencyIndex: 4 bits
|
|
95
|
+
const freqIndex = readBits(4)
|
|
96
|
+
if (freqIndex < 0) return null
|
|
97
|
+
if (freqIndex === 0xf) {
|
|
98
|
+
// Explicit 24-bit sample rate follows
|
|
99
|
+
readBits(24)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// channelConfiguration: 4 bits
|
|
103
|
+
readBits(4)
|
|
104
|
+
|
|
105
|
+
// Check for SBR/PS signaling (implicit in HE-AAC)
|
|
106
|
+
// If base objectType is AAC-LC and SBR extension is present, frame size doubles
|
|
107
|
+
if (objectType === 2 /* AAC-LC */ && asc.length >= 4) {
|
|
108
|
+
// Check for SBR extension: 11-bit sync word 0x2b7
|
|
109
|
+
const remaining = (asc.length * 8) - bitPos
|
|
110
|
+
if (remaining >= 11) {
|
|
111
|
+
const syncExt = readBits(11)
|
|
112
|
+
if (syncExt === 0x2b7) {
|
|
113
|
+
const extObjectType = readBits(5)
|
|
114
|
+
if (extObjectType === 5 /* SBR */ || extObjectType === 22 /* ER SBR */) {
|
|
115
|
+
return 2048 // SBR present → 2048 samples
|
|
116
|
+
}
|
|
117
|
+
if (extObjectType === 29 /* PS */) {
|
|
118
|
+
return 2048 // PS implies SBR → 2048 samples
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return aacFrameSamplesForObjectType(objectType)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Parse AAC ASC to extract sample rate.
|
|
129
|
+
* Useful when catalog samplerate is missing but initData is available.
|
|
130
|
+
*/
|
|
131
|
+
export function parseAacSampleRate(asc: Uint8Array): number | null {
|
|
132
|
+
if (asc.length < 2) return null
|
|
133
|
+
|
|
134
|
+
let bitPos = 0
|
|
135
|
+
const readBits = (n: number): number => {
|
|
136
|
+
let val = 0
|
|
137
|
+
for (let i = 0; i < n; i++) {
|
|
138
|
+
const byteIdx = (bitPos + i) >> 3
|
|
139
|
+
const bitIdx = 7 - ((bitPos + i) & 7)
|
|
140
|
+
if (byteIdx >= asc.length) return -1
|
|
141
|
+
val = (val << 1) | ((asc[byteIdx]! >> bitIdx) & 1)
|
|
142
|
+
}
|
|
143
|
+
bitPos += n
|
|
144
|
+
return val
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Skip audioObjectType (5 or 11 bits)
|
|
148
|
+
let objectType = readBits(5)
|
|
149
|
+
if (objectType === 31) readBits(6)
|
|
150
|
+
|
|
151
|
+
const freqIndex = readBits(4)
|
|
152
|
+
if (freqIndex < 0) return null
|
|
153
|
+
if (freqIndex === 0xf) {
|
|
154
|
+
return readBits(24)
|
|
155
|
+
}
|
|
156
|
+
return AAC_SAMPLE_RATES[freqIndex] ?? null
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Opus frame samples: 960 at 48kHz (20ms) per RFC 6716 §2.1.4.
|
|
161
|
+
*
|
|
162
|
+
* Opus supports variable frame sizes (2.5, 5, 10, 20, 40, 60, 80, 100, 120ms)
|
|
163
|
+
* but the frame size is per-packet (in the TOC byte), not in the init data.
|
|
164
|
+
* OpusHead (RFC 7845) carries sample_rate and channel_count only.
|
|
165
|
+
*
|
|
166
|
+
* 960 samples at 48kHz = 20ms is the normative default per RFC 6716.
|
|
167
|
+
*/
|
|
168
|
+
export function parseOpusFrameSamples(_opusHead?: Uint8Array): number {
|
|
169
|
+
return 960
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Extract frame samples from a bare codec descriptor based on codec string.
|
|
174
|
+
*
|
|
175
|
+
* @param codec - Codec string from catalog (e.g., "mp4a.40.2", "opus")
|
|
176
|
+
* @param codecConfig - Raw codec descriptor bytes: AudioSpecificConfig for
|
|
177
|
+
* AAC, OpusHead for Opus. This is the catalog `description` field, NOT the
|
|
178
|
+
* catalog `initData` (ftyp+moov) field — see the file header.
|
|
179
|
+
* @returns frame samples, or null if codec unsupported or the descriptor is invalid
|
|
180
|
+
*/
|
|
181
|
+
export function frameSamplesFromInit(codec: string, codecConfig: Uint8Array): number | null {
|
|
182
|
+
if (codec.startsWith('mp4a')) {
|
|
183
|
+
return parseAacFrameSamples(codecConfig)
|
|
184
|
+
}
|
|
185
|
+
if (codec.startsWith('opus') || codec === 'Opus') {
|
|
186
|
+
return parseOpusFrameSamples(codecConfig)
|
|
187
|
+
}
|
|
188
|
+
return null
|
|
189
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AudioRingBuffer — plain FIFO audio buffer (no clock recovery).
|
|
3
|
+
*
|
|
4
|
+
* Source of truth for the audio buffer algorithm used in both moq-lib and
|
|
5
|
+
* moqtail AudioWorklet processors. AudioWorklet isolation requires the
|
|
6
|
+
* worklet copy to be self-contained (no imports), so changes here must be
|
|
7
|
+
* manually synced to:
|
|
8
|
+
* - moqtail-private/apps/client-js/src/lib/audio-worklet-processor.js
|
|
9
|
+
* - hang-mmt-fec/js/watch/src/audio/ring-buffer.ts (uses @moq/lite Time types)
|
|
10
|
+
*
|
|
11
|
+
* Rationale: FEC guarantees gap-free, ordered audio on multicast; MoQ
|
|
12
|
+
* delivers ordered audio without drops. The decoder output rate matches
|
|
13
|
+
* the AudioContext destination rate closely enough that skip/dup clock
|
|
14
|
+
* recovery is unnecessary and harmful — a single sample skip at 48 kHz is
|
|
15
|
+
* a ~21 µs phase glitch, and repeated skip/dup produces audible pitch
|
|
16
|
+
* wobble on pure tones (measured: 16 Hz offset + ±11 Hz spread on a 1 kHz
|
|
17
|
+
* test tone before this refactor).
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
export interface AudioRingBufferConfig {
|
|
21
|
+
/** Number of audio channels */
|
|
22
|
+
channels: number;
|
|
23
|
+
/** Sample rate in Hz */
|
|
24
|
+
rate: number;
|
|
25
|
+
/** Buffer latency in milliseconds */
|
|
26
|
+
latencyMs: number;
|
|
27
|
+
/** Start in unstalled state (for source switching) */
|
|
28
|
+
startUnstalled?: boolean;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export class AudioRingBuffer {
|
|
32
|
+
readonly channels: number;
|
|
33
|
+
readonly rate: number;
|
|
34
|
+
|
|
35
|
+
#buffer: Float32Array[];
|
|
36
|
+
#writeIndex = 0;
|
|
37
|
+
#readIndex = 0;
|
|
38
|
+
#stalled: boolean;
|
|
39
|
+
|
|
40
|
+
constructor(config: AudioRingBufferConfig) {
|
|
41
|
+
this.channels = config.channels;
|
|
42
|
+
this.rate = config.rate;
|
|
43
|
+
this.#stalled = !(config.startUnstalled ?? false);
|
|
44
|
+
|
|
45
|
+
const samples = Math.ceil(config.rate * (config.latencyMs / 1000));
|
|
46
|
+
this.#buffer = [];
|
|
47
|
+
for (let i = 0; i < config.channels; i++) {
|
|
48
|
+
this.#buffer[i] = new Float32Array(samples);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
get stalled(): boolean { return this.#stalled; }
|
|
53
|
+
get capacity(): number { return this.#buffer[0].length; }
|
|
54
|
+
get length(): number { return this.#writeIndex - this.#readIndex; }
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Append decoded audio samples to the FIFO.
|
|
58
|
+
* Timestamp parameter retained for API compatibility but is ignored —
|
|
59
|
+
* FIFO is sequence-based, not time-based.
|
|
60
|
+
*/
|
|
61
|
+
write(_timestampUs: number, data: Float32Array[]): void {
|
|
62
|
+
const samples = data[0].length;
|
|
63
|
+
|
|
64
|
+
const start = this.#writeIndex;
|
|
65
|
+
const end = start + samples;
|
|
66
|
+
|
|
67
|
+
// Overflow: discard oldest samples (protects against encoder/AudioContext
|
|
68
|
+
// clock drift when one runs faster than the other).
|
|
69
|
+
const overflow = end - this.#readIndex - this.#buffer[0].length;
|
|
70
|
+
if (overflow >= 0) {
|
|
71
|
+
this.#stalled = false;
|
|
72
|
+
this.#readIndex += overflow;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Unstall at half capacity — enough prebuffer for bounded jitter.
|
|
76
|
+
if (this.#stalled && (end - this.#readIndex) >= Math.floor(this.#buffer[0].length / 2)) {
|
|
77
|
+
this.#stalled = false;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Append samples sequentially
|
|
81
|
+
for (let ch = 0; ch < this.channels; ch++) {
|
|
82
|
+
const src = data[ch];
|
|
83
|
+
const dst = this.#buffer[ch];
|
|
84
|
+
for (let i = 0; i < samples; i++) {
|
|
85
|
+
dst[(start + i) % dst.length] = src[i];
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
this.#writeIndex = end;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Read samples into output buffers — plain FIFO, no clock recovery.
|
|
93
|
+
* FEC + MoQ delivery guarantees no gaps, so skip/dup is unnecessary.
|
|
94
|
+
* Underrun → zero-fill.
|
|
95
|
+
*/
|
|
96
|
+
read(output: Float32Array[]): number {
|
|
97
|
+
if (this.#stalled) return 0;
|
|
98
|
+
|
|
99
|
+
const available = this.#writeIndex - this.#readIndex;
|
|
100
|
+
if (available === 0) return 0;
|
|
101
|
+
|
|
102
|
+
const requested = output[0].length;
|
|
103
|
+
const readSamples = Math.min(available, requested);
|
|
104
|
+
|
|
105
|
+
for (let ch = 0; ch < this.channels; ch++) {
|
|
106
|
+
const dst = output[ch];
|
|
107
|
+
const src = this.#buffer[ch];
|
|
108
|
+
for (let i = 0; i < readSamples; i++) {
|
|
109
|
+
dst[i] = src[(this.#readIndex + i) % src.length];
|
|
110
|
+
}
|
|
111
|
+
// Zero-fill remainder on underrun
|
|
112
|
+
for (let i = readSamples; i < requested; i++) {
|
|
113
|
+
dst[i] = 0;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
this.#readIndex += readSamples;
|
|
118
|
+
return readSamples;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exact timing authored by an ISO-BMFF media fragment.
|
|
3
|
+
*
|
|
4
|
+
* `timestamp`/`duration` fields on the browser-facing APIs are converted to
|
|
5
|
+
* microseconds for legacy callers. This value remains in the media track's
|
|
6
|
+
* native timescale so consumers that own a CMAF/WebCodecs timeline do not
|
|
7
|
+
* have to reconstruct integer ticks from rounded wall-clock values.
|
|
8
|
+
*/
|
|
9
|
+
export interface AuthoredTiming {
|
|
10
|
+
/** Exact decode time in the media track's timescale. */
|
|
11
|
+
decodeTime: bigint
|
|
12
|
+
/** Exact presentation time in the media track's timescale, including CTS. */
|
|
13
|
+
presentationTime: bigint
|
|
14
|
+
/**
|
|
15
|
+
* Exact sample duration in the media track's timescale. This remains a
|
|
16
|
+
* number because ISO-BMFF stores sample_duration as an unsigned 32-bit
|
|
17
|
+
* field, whose full range is exactly representable by JavaScript numbers.
|
|
18
|
+
*/
|
|
19
|
+
durationTicks: number
|
|
20
|
+
/** `mdhd` timescale for all values above. */
|
|
21
|
+
mediaTimescale: number
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** Convert authored media ticks to an integer target timescale without first
|
|
25
|
+
* narrowing the authored tick value to a wall-clock float. */
|
|
26
|
+
export function scaleAuthoredTicks(
|
|
27
|
+
ticks: bigint,
|
|
28
|
+
mediaTimescale: number,
|
|
29
|
+
targetTimescale: number,
|
|
30
|
+
): number | null {
|
|
31
|
+
if (!Number.isSafeInteger(mediaTimescale) || mediaTimescale <= 0 ||
|
|
32
|
+
!Number.isSafeInteger(targetTimescale) || targetTimescale <= 0) return null
|
|
33
|
+
|
|
34
|
+
const negative = ticks < 0n
|
|
35
|
+
const numerator = (negative ? -ticks : ticks) * BigInt(targetTimescale)
|
|
36
|
+
const denominator = BigInt(mediaTimescale)
|
|
37
|
+
const whole = numerator / denominator
|
|
38
|
+
const remainder = numerator % denominator
|
|
39
|
+
if (whole > BigInt(Number.MAX_SAFE_INTEGER)) return null
|
|
40
|
+
const value = Number(whole) + Number(remainder) / mediaTimescale
|
|
41
|
+
return Number.isFinite(value) ? (negative ? -value : value) : null
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** Convert exact authored presentation time and duration to an assembler's
|
|
45
|
+
* public timestamp scale. */
|
|
46
|
+
export function scaleAuthoredTiming(
|
|
47
|
+
timing: AuthoredTiming,
|
|
48
|
+
targetTimescale: number,
|
|
49
|
+
): { timestamp: number; duration: number } | null {
|
|
50
|
+
if (!Number.isSafeInteger(timing.durationTicks) || timing.durationTicks <= 0) return null
|
|
51
|
+
const timestamp = scaleAuthoredTicks(
|
|
52
|
+
timing.presentationTime,
|
|
53
|
+
timing.mediaTimescale,
|
|
54
|
+
targetTimescale,
|
|
55
|
+
)
|
|
56
|
+
const duration = scaleAuthoredTicks(
|
|
57
|
+
BigInt(timing.durationTicks),
|
|
58
|
+
timing.mediaTimescale,
|
|
59
|
+
targetTimescale,
|
|
60
|
+
)
|
|
61
|
+
if (timestamp === null || duration === null || duration <= 0) return null
|
|
62
|
+
return { timestamp, duration }
|
|
63
|
+
}
|