@blockcast/mmt-container 0.1.0 → 0.3.0-main.ef68de90edb3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (799) hide show
  1. package/README.md +524 -0
  2. package/dist/.build-stamp +0 -0
  3. package/dist/__tests__/test-utils.d.ts +71 -0
  4. package/dist/__tests__/test-utils.d.ts.map +1 -0
  5. package/dist/align.d.ts +152 -0
  6. package/dist/align.d.ts.map +1 -0
  7. package/dist/align.js +88 -0
  8. package/dist/align.js.map +7 -0
  9. package/dist/audio-init-parser.d.ts +66 -0
  10. package/dist/audio-init-parser.d.ts.map +1 -0
  11. package/dist/audio-init-parser.js +118 -0
  12. package/dist/audio-init-parser.js.map +7 -0
  13. package/dist/audio-ring-buffer.d.ts +50 -0
  14. package/dist/audio-ring-buffer.d.ts.map +1 -0
  15. package/dist/audio-ring-buffer.js +80 -0
  16. package/dist/audio-ring-buffer.js.map +7 -0
  17. package/dist/authored-timing.d.ts +32 -0
  18. package/dist/authored-timing.d.ts.map +1 -0
  19. package/dist/authored-timing.js +32 -0
  20. package/dist/authored-timing.js.map +7 -0
  21. package/dist/block-policy.d.ts +314 -0
  22. package/dist/block-policy.d.ts.map +1 -0
  23. package/dist/block-policy.js +466 -0
  24. package/dist/block-policy.js.map +7 -0
  25. package/dist/browser-runtime.js +26549 -0
  26. package/dist/browser-runtime.js.map +7 -0
  27. package/dist/carp-catalog.d.ts +429 -0
  28. package/dist/carp-catalog.d.ts.map +1 -0
  29. package/dist/carp-catalog.js +985 -0
  30. package/dist/carp-catalog.js.map +7 -0
  31. package/dist/catalog-fec-params.d.ts +275 -0
  32. package/dist/catalog-fec-params.d.ts.map +1 -0
  33. package/dist/catalog-fec-params.js +702 -0
  34. package/dist/catalog-fec-params.js.map +7 -0
  35. package/dist/catalog-network-source.d.ts +42 -0
  36. package/dist/catalog-network-source.d.ts.map +1 -0
  37. package/dist/catalog-network-source.js +47 -0
  38. package/dist/catalog-network-source.js.map +7 -0
  39. package/dist/catalog-validator.d.ts +18 -0
  40. package/dist/catalog-validator.d.ts.map +1 -0
  41. package/dist/catalog-validator.js +7747 -0
  42. package/dist/catalog-validator.js.map +7 -0
  43. package/dist/cmaf-block-assembler.d.ts +285 -0
  44. package/dist/cmaf-block-assembler.d.ts.map +1 -0
  45. package/dist/cmaf-block-assembler.js +1966 -0
  46. package/dist/cmaf-block-assembler.js.map +7 -0
  47. package/dist/cmaf-group-batcher.d.ts +38 -0
  48. package/dist/cmaf-group-batcher.d.ts.map +1 -0
  49. package/dist/cmaf-group-batcher.js +176 -0
  50. package/dist/cmaf-group-batcher.js.map +7 -0
  51. package/dist/cmcd-producer.d.ts +104 -0
  52. package/dist/cmcd-producer.d.ts.map +1 -0
  53. package/dist/cmcd-producer.js +183 -0
  54. package/dist/cmcd-producer.js.map +7 -0
  55. package/dist/codec-utils.d.ts +384 -0
  56. package/dist/codec-utils.d.ts.map +1 -0
  57. package/dist/codec-utils.js +1546 -0
  58. package/dist/codec-utils.js.map +7 -0
  59. package/dist/conceal-timeline.d.ts +146 -0
  60. package/dist/conceal-timeline.d.ts.map +1 -0
  61. package/dist/conceal-timeline.js +137 -0
  62. package/dist/conceal-timeline.js.map +7 -0
  63. package/dist/delivery-gap.d.ts +75 -0
  64. package/dist/delivery-gap.d.ts.map +1 -0
  65. package/dist/delivery-gap.js +88 -0
  66. package/dist/delivery-gap.js.map +7 -0
  67. package/dist/duplicate-ledger.d.ts +197 -0
  68. package/dist/duplicate-ledger.d.ts.map +1 -0
  69. package/dist/duplicate-ledger.js +226 -0
  70. package/dist/duplicate-ledger.js.map +7 -0
  71. package/dist/fec-codec.d.ts +32 -0
  72. package/dist/fec-codec.d.ts.map +1 -0
  73. package/dist/fec-codec.js +47 -0
  74. package/dist/fec-codec.js.map +7 -0
  75. package/dist/fec-manager.d.ts +583 -0
  76. package/dist/fec-manager.d.ts.map +1 -0
  77. package/dist/fec-manager.js +3899 -0
  78. package/dist/fec-manager.js.map +7 -0
  79. package/dist/fec-starvation-detector.d.ts +59 -0
  80. package/dist/fec-starvation-detector.d.ts.map +1 -0
  81. package/dist/fec-starvation-detector.js +60 -0
  82. package/dist/fec-starvation-detector.js.map +7 -0
  83. package/dist/fec-state.d.ts +131 -0
  84. package/dist/fec-state.d.ts.map +1 -0
  85. package/dist/fec-state.js +87 -0
  86. package/dist/fec-state.js.map +7 -0
  87. package/dist/fec-worker-setup.d.ts +94 -0
  88. package/dist/fec-worker-setup.d.ts.map +1 -0
  89. package/dist/fec-worker-setup.js +673 -0
  90. package/dist/fec-worker-setup.js.map +7 -0
  91. package/dist/fmp4-completion.d.ts +30 -0
  92. package/dist/fmp4-completion.d.ts.map +1 -0
  93. package/dist/fmp4-completion.js +21 -0
  94. package/dist/fmp4-completion.js.map +7 -0
  95. package/dist/fmp4-reader.d.ts +37 -0
  96. package/dist/fmp4-reader.d.ts.map +1 -0
  97. package/dist/fmp4-reader.js +100 -0
  98. package/dist/fmp4-reader.js.map +7 -0
  99. package/dist/index.d.ts +44 -3
  100. package/dist/index.d.ts.map +1 -1
  101. package/dist/index.js +460 -14
  102. package/dist/index.js.map +7 -1
  103. package/dist/iso-block-locator.d.ts +118 -0
  104. package/dist/iso-block-locator.d.ts.map +1 -0
  105. package/dist/iso-block-locator.js +289 -0
  106. package/dist/iso-block-locator.js.map +7 -0
  107. package/dist/iso-bmff-timing.d.ts +78 -0
  108. package/dist/iso-bmff-timing.d.ts.map +1 -0
  109. package/dist/iso-bmff-timing.js +593 -0
  110. package/dist/iso-bmff-timing.js.map +7 -0
  111. package/dist/loc.d.ts +70 -75
  112. package/dist/loc.d.ts.map +1 -1
  113. package/dist/loc.js +106 -192
  114. package/dist/loc.js.map +7 -1
  115. package/dist/manifest-auth-plan.d.ts +30 -0
  116. package/dist/manifest-auth-plan.d.ts.map +1 -0
  117. package/dist/manifest-auth-plan.js +1266 -0
  118. package/dist/manifest-auth-plan.js.map +7 -0
  119. package/dist/media-router.d.ts +262 -0
  120. package/dist/media-router.d.ts.map +1 -0
  121. package/dist/media-router.js +584 -0
  122. package/dist/media-router.js.map +7 -0
  123. package/dist/mfu-reassembler.d.ts +313 -9
  124. package/dist/mfu-reassembler.d.ts.map +1 -1
  125. package/dist/mfu-reassembler.js +3051 -285
  126. package/dist/mfu-reassembler.js.map +7 -1
  127. package/dist/mfu-reassembly-policy.d.ts +24 -0
  128. package/dist/mfu-reassembly-policy.d.ts.map +1 -0
  129. package/dist/mfu-reassembly-policy.js +99 -0
  130. package/dist/mfu-reassembly-policy.js.map +7 -0
  131. package/dist/mmtp-container-parser.d.ts +568 -0
  132. package/dist/mmtp-container-parser.d.ts.map +1 -0
  133. package/dist/mmtp-container-parser.js +6580 -0
  134. package/dist/mmtp-container-parser.js.map +7 -0
  135. package/dist/mmtp-container-parser.no-modules.js +9616 -0
  136. package/dist/mmtp-container-parser.no-modules.js.map +7 -0
  137. package/dist/mmtp-decode-pipeline.d.ts +138 -0
  138. package/dist/mmtp-decode-pipeline.d.ts.map +1 -0
  139. package/dist/mmtp-decode-pipeline.js +6814 -0
  140. package/dist/mmtp-decode-pipeline.js.map +7 -0
  141. package/dist/mmtp-router.d.ts +679 -0
  142. package/dist/mmtp-router.d.ts.map +1 -0
  143. package/dist/mmtp-router.js +11278 -0
  144. package/dist/mmtp-router.js.map +7 -0
  145. package/dist/mmtp-to-cmaf.d.ts +187 -0
  146. package/dist/mmtp-to-cmaf.d.ts.map +1 -0
  147. package/dist/mmtp-to-cmaf.js +716 -0
  148. package/dist/mmtp-to-cmaf.js.map +7 -0
  149. package/dist/multicast-auth-catalog.d.ts +115 -0
  150. package/dist/multicast-auth-catalog.d.ts.map +1 -0
  151. package/dist/multicast-auth-catalog.js +202 -0
  152. package/dist/multicast-auth-catalog.js.map +7 -0
  153. package/dist/multicast-input.d.ts +141 -0
  154. package/dist/multicast-input.d.ts.map +1 -0
  155. package/dist/multicast-input.js +390 -0
  156. package/dist/multicast-input.js.map +7 -0
  157. package/dist/multicast-manager.d.ts +669 -0
  158. package/dist/multicast-manager.d.ts.map +1 -0
  159. package/dist/multicast-manager.js +19101 -0
  160. package/dist/multicast-manager.js.map +7 -0
  161. package/dist/multicast-transport.d.ts +271 -0
  162. package/dist/multicast-transport.d.ts.map +1 -0
  163. package/dist/multicast-transport.js +2264 -0
  164. package/dist/multicast-transport.js.map +7 -0
  165. package/dist/multicast-unwrap.d.ts +57 -0
  166. package/dist/multicast-unwrap.d.ts.map +1 -0
  167. package/dist/multicast-unwrap.js +418 -0
  168. package/dist/multicast-unwrap.js.map +7 -0
  169. package/dist/no-modules.d.ts +10 -0
  170. package/dist/no-modules.d.ts.map +1 -0
  171. package/dist/no-modules.js +9491 -0
  172. package/dist/no-modules.js.map +7 -0
  173. package/dist/phase14-catalog-override.d.ts +126 -0
  174. package/dist/phase14-catalog-override.d.ts.map +1 -0
  175. package/dist/phase14-catalog-override.js +155 -0
  176. package/dist/phase14-catalog-override.js.map +7 -0
  177. package/dist/repair-fetch.d.ts +270 -0
  178. package/dist/repair-fetch.d.ts.map +1 -0
  179. package/dist/repair-fetch.js +381 -0
  180. package/dist/repair-fetch.js.map +7 -0
  181. package/dist/repair-layers.d.ts +158 -0
  182. package/dist/repair-layers.d.ts.map +1 -0
  183. package/dist/repair-layers.js +344 -0
  184. package/dist/repair-layers.js.map +7 -0
  185. package/dist/sample-combiner.d.ts +212 -0
  186. package/dist/sample-combiner.d.ts.map +1 -0
  187. package/dist/sample-combiner.js +595 -0
  188. package/dist/sample-combiner.js.map +7 -0
  189. package/dist/signaling.d.ts +29 -0
  190. package/dist/signaling.d.ts.map +1 -0
  191. package/dist/signaling.js +572 -0
  192. package/dist/signaling.js.map +7 -0
  193. package/dist/source-auth.d.ts +2 -0
  194. package/dist/source-auth.d.ts.map +1 -0
  195. package/dist/source-auth.js +1209 -0
  196. package/dist/source-auth.js.map +7 -0
  197. package/dist/switching-set-alignment.d.ts +61 -0
  198. package/dist/switching-set-alignment.d.ts.map +1 -0
  199. package/dist/switching-set-alignment.js +70 -0
  200. package/dist/switching-set-alignment.js.map +7 -0
  201. package/dist/timestamp-codec.d.ts +34 -0
  202. package/dist/timestamp-codec.d.ts.map +1 -0
  203. package/dist/timestamp-codec.js +473 -0
  204. package/dist/timestamp-codec.js.map +7 -0
  205. package/dist/track-pipeline-setup.d.ts +83 -0
  206. package/dist/track-pipeline-setup.d.ts.map +1 -0
  207. package/dist/track-pipeline-setup.js +291 -0
  208. package/dist/track-pipeline-setup.js.map +7 -0
  209. package/dist/track-pipeline.d.ts +121 -0
  210. package/dist/track-pipeline.d.ts.map +1 -0
  211. package/dist/track-pipeline.js +209 -0
  212. package/dist/track-pipeline.js.map +7 -0
  213. package/dist/track-session.d.ts +414 -0
  214. package/dist/track-session.d.ts.map +1 -0
  215. package/dist/track-session.js +754 -0
  216. package/dist/track-session.js.map +7 -0
  217. package/dist/transport-pool.d.ts +69 -0
  218. package/dist/transport-pool.d.ts.map +1 -0
  219. package/dist/transport-pool.js +74 -0
  220. package/dist/transport-pool.js.map +7 -0
  221. package/dist/wasm-mfu-reassembler.d.ts +97 -0
  222. package/dist/wasm-mfu-reassembler.d.ts.map +1 -0
  223. package/dist/wasm-mfu-reassembler.js +2133 -0
  224. package/dist/wasm-mfu-reassembler.js.map +7 -0
  225. package/dist/wasm-mmtp-container-parser.d.ts +10 -0
  226. package/dist/wasm-mmtp-container-parser.d.ts.map +1 -0
  227. package/dist/wasm-mmtp-container-parser.js +6834 -0
  228. package/dist/wasm-mmtp-container-parser.js.map +7 -0
  229. package/node_modules/@blockcast/fec-worker/README.md +223 -0
  230. package/node_modules/@blockcast/fec-worker/dist/.build-stamp +0 -0
  231. package/node_modules/@blockcast/fec-worker/dist/block-order.d.ts +38 -0
  232. package/node_modules/@blockcast/fec-worker/dist/block-order.d.ts.map +1 -0
  233. package/node_modules/@blockcast/fec-worker/dist/block-order.js +78 -0
  234. package/node_modules/@blockcast/fec-worker/dist/block-order.js.map +1 -0
  235. package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.d.ts +93 -0
  236. package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.d.ts.map +1 -0
  237. package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.js +346 -0
  238. package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.js.map +1 -0
  239. package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.d.ts +380 -0
  240. package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.d.ts.map +1 -0
  241. package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.js +11 -0
  242. package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.js.map +1 -0
  243. package/node_modules/@blockcast/fec-worker/dist/fec-worker.d.ts +14 -0
  244. package/node_modules/@blockcast/fec-worker/dist/fec-worker.d.ts.map +1 -0
  245. package/node_modules/@blockcast/fec-worker/dist/fec-worker.js +859 -0
  246. package/node_modules/@blockcast/fec-worker/dist/fec-worker.js.map +7 -0
  247. package/node_modules/@blockcast/fec-worker/dist/index.d.ts +10 -0
  248. package/node_modules/@blockcast/fec-worker/dist/index.d.ts.map +1 -0
  249. package/node_modules/@blockcast/fec-worker/dist/index.js +8 -0
  250. package/node_modules/@blockcast/fec-worker/dist/index.js.map +1 -0
  251. package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.d.ts +20 -0
  252. package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.d.ts.map +1 -0
  253. package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.js +370 -0
  254. package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.js.map +7 -0
  255. package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.d.ts +104 -0
  256. package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.d.ts.map +1 -0
  257. package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.js +181 -0
  258. package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.js.map +1 -0
  259. package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.d.ts +194 -0
  260. package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.d.ts.map +1 -0
  261. package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.js +62 -0
  262. package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.js.map +1 -0
  263. package/node_modules/@blockcast/fec-worker/dist/transfer.d.ts +9 -0
  264. package/node_modules/@blockcast/fec-worker/dist/transfer.d.ts.map +1 -0
  265. package/node_modules/@blockcast/fec-worker/dist/transfer.js +13 -0
  266. package/node_modules/@blockcast/fec-worker/dist/transfer.js.map +1 -0
  267. package/node_modules/@blockcast/fec-worker/package.json +59 -0
  268. package/node_modules/@blockcast/fec-worker/src/block-order.ts +93 -0
  269. package/node_modules/@blockcast/fec-worker/src/fec-worker-client.ts +392 -0
  270. package/node_modules/@blockcast/fec-worker/src/fec-worker-types.ts +399 -0
  271. package/node_modules/@blockcast/fec-worker/src/fec-worker.ts +1502 -0
  272. package/node_modules/@blockcast/fec-worker/src/index.ts +35 -0
  273. package/node_modules/@blockcast/fec-worker/src/shred-fec-worker.ts +589 -0
  274. package/node_modules/@blockcast/fec-worker/src/shred-worker-client.ts +222 -0
  275. package/node_modules/@blockcast/fec-worker/src/shred-worker-types.ts +209 -0
  276. package/node_modules/@blockcast/fec-worker/src/transfer.ts +12 -0
  277. package/node_modules/@blockcast/mmt-alta-parse/README.md +181 -0
  278. package/node_modules/@blockcast/mmt-alta-parse/dist/.build-stamp +0 -0
  279. package/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts +57 -0
  280. package/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts.map +1 -0
  281. package/node_modules/@blockcast/mmt-alta-parse/dist/index.js +115 -0
  282. package/node_modules/@blockcast/mmt-alta-parse/dist/index.js.map +1 -0
  283. package/node_modules/@blockcast/mmt-alta-parse/package.json +50 -0
  284. package/node_modules/@blockcast/mmt-alta-parse/src/index.ts +136 -0
  285. package/node_modules/@blockcast/mmt-base/README.md +134 -0
  286. package/node_modules/@blockcast/mmt-base/dist/.build-stamp +0 -0
  287. package/node_modules/@blockcast/mmt-base/dist/fec-block-profile.d.ts +55 -0
  288. package/node_modules/@blockcast/mmt-base/dist/fec-block-profile.d.ts.map +1 -0
  289. package/node_modules/@blockcast/mmt-base/dist/fec-block-profile.js +128 -0
  290. package/node_modules/@blockcast/mmt-base/dist/fec-block-profile.js.map +1 -0
  291. package/node_modules/@blockcast/mmt-base/dist/index.d.ts +7 -0
  292. package/node_modules/@blockcast/mmt-base/dist/index.d.ts.map +1 -0
  293. package/node_modules/@blockcast/mmt-base/dist/index.js +7 -0
  294. package/node_modules/@blockcast/mmt-base/dist/index.js.map +1 -0
  295. package/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts +292 -0
  296. package/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts.map +1 -0
  297. package/node_modules/@blockcast/mmt-base/dist/mmtp.js +612 -0
  298. package/node_modules/@blockcast/mmt-base/dist/mmtp.js.map +1 -0
  299. package/node_modules/@blockcast/mmt-base/dist/net-constants.d.ts +18 -0
  300. package/node_modules/@blockcast/mmt-base/dist/net-constants.d.ts.map +1 -0
  301. package/node_modules/@blockcast/mmt-base/dist/net-constants.js +18 -0
  302. package/node_modules/@blockcast/mmt-base/dist/net-constants.js.map +1 -0
  303. package/node_modules/@blockcast/mmt-base/dist/ntp-short.d.ts +47 -0
  304. package/node_modules/@blockcast/mmt-base/dist/ntp-short.d.ts.map +1 -0
  305. package/node_modules/@blockcast/mmt-base/dist/ntp-short.js +54 -0
  306. package/node_modules/@blockcast/mmt-base/dist/ntp-short.js.map +1 -0
  307. package/node_modules/@blockcast/mmt-base/dist/serial-number.d.ts +57 -0
  308. package/node_modules/@blockcast/mmt-base/dist/serial-number.d.ts.map +1 -0
  309. package/node_modules/@blockcast/mmt-base/dist/serial-number.js +98 -0
  310. package/node_modules/@blockcast/mmt-base/dist/serial-number.js.map +1 -0
  311. package/node_modules/@blockcast/mmt-base/dist/signalling.d.ts +312 -0
  312. package/node_modules/@blockcast/mmt-base/dist/signalling.d.ts.map +1 -0
  313. package/node_modules/@blockcast/mmt-base/dist/signalling.js +637 -0
  314. package/node_modules/@blockcast/mmt-base/dist/signalling.js.map +1 -0
  315. package/node_modules/@blockcast/mmt-base/package.json +49 -0
  316. package/node_modules/@blockcast/mmt-base/src/fec-block-profile.ts +145 -0
  317. package/node_modules/@blockcast/mmt-base/src/index.ts +6 -0
  318. package/node_modules/@blockcast/mmt-base/src/mmtp.ts +892 -0
  319. package/node_modules/@blockcast/mmt-base/src/net-constants.ts +17 -0
  320. package/node_modules/@blockcast/mmt-base/src/ntp-short.ts +67 -0
  321. package/node_modules/@blockcast/mmt-base/src/serial-number.ts +107 -0
  322. package/node_modules/@blockcast/mmt-base/src/signalling.ts +862 -0
  323. package/node_modules/@blockcast/mmt-fec/README.md +271 -0
  324. package/node_modules/@blockcast/mmt-fec/dist/.build-stamp +0 -0
  325. package/node_modules/@blockcast/mmt-fec/dist/block-manager.d.ts +82 -0
  326. package/node_modules/@blockcast/mmt-fec/dist/block-manager.d.ts.map +1 -0
  327. package/node_modules/@blockcast/mmt-fec/dist/block-manager.js +296 -0
  328. package/node_modules/@blockcast/mmt-fec/dist/block-manager.js.map +1 -0
  329. package/node_modules/@blockcast/mmt-fec/dist/block-processor.d.ts +106 -0
  330. package/node_modules/@blockcast/mmt-fec/dist/block-processor.d.ts.map +1 -0
  331. package/node_modules/@blockcast/mmt-fec/dist/block-processor.js +288 -0
  332. package/node_modules/@blockcast/mmt-fec/dist/block-processor.js.map +1 -0
  333. package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.d.ts +46 -0
  334. package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.d.ts.map +1 -0
  335. package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.js +96 -0
  336. package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.js.map +1 -0
  337. package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.d.ts +33 -0
  338. package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.d.ts.map +1 -0
  339. package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.js +57 -0
  340. package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.js.map +1 -0
  341. package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.d.ts +205 -0
  342. package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.d.ts.map +1 -0
  343. package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.js +240 -0
  344. package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.js.map +1 -0
  345. package/node_modules/@blockcast/mmt-fec/dist/index.d.ts +28 -0
  346. package/node_modules/@blockcast/mmt-fec/dist/index.d.ts.map +1 -0
  347. package/node_modules/@blockcast/mmt-fec/dist/index.js +28 -0
  348. package/node_modules/@blockcast/mmt-fec/dist/index.js.map +1 -0
  349. package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.d.ts +20 -0
  350. package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.d.ts.map +1 -0
  351. package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.js +28 -0
  352. package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.js.map +1 -0
  353. package/node_modules/@blockcast/mmt-fec/dist/oti.d.ts +258 -0
  354. package/node_modules/@blockcast/mmt-fec/dist/oti.d.ts.map +1 -0
  355. package/node_modules/@blockcast/mmt-fec/dist/oti.js +382 -0
  356. package/node_modules/@blockcast/mmt-fec/dist/oti.js.map +1 -0
  357. package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.d.ts +41 -0
  358. package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.d.ts.map +1 -0
  359. package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.js +81 -0
  360. package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.js.map +1 -0
  361. package/node_modules/@blockcast/mmt-fec/dist/repair-group.d.ts +82 -0
  362. package/node_modules/@blockcast/mmt-fec/dist/repair-group.d.ts.map +1 -0
  363. package/node_modules/@blockcast/mmt-fec/dist/repair-group.js +170 -0
  364. package/node_modules/@blockcast/mmt-fec/dist/repair-group.js.map +1 -0
  365. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/README.md +181 -0
  366. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/.build-stamp +0 -0
  367. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts +57 -0
  368. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts.map +1 -0
  369. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.js +115 -0
  370. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.js.map +1 -0
  371. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/package.json +50 -0
  372. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/src/index.ts +136 -0
  373. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/README.md +134 -0
  374. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/.build-stamp +0 -0
  375. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/fec-block-profile.d.ts +55 -0
  376. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/fec-block-profile.d.ts.map +1 -0
  377. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/fec-block-profile.js +128 -0
  378. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/fec-block-profile.js.map +1 -0
  379. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.d.ts +7 -0
  380. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.d.ts.map +1 -0
  381. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.js +7 -0
  382. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.js.map +1 -0
  383. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts +292 -0
  384. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts.map +1 -0
  385. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.js +612 -0
  386. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.js.map +1 -0
  387. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/net-constants.d.ts +18 -0
  388. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/net-constants.d.ts.map +1 -0
  389. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/net-constants.js +18 -0
  390. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/net-constants.js.map +1 -0
  391. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/ntp-short.d.ts +47 -0
  392. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/ntp-short.d.ts.map +1 -0
  393. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/ntp-short.js +54 -0
  394. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/ntp-short.js.map +1 -0
  395. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/serial-number.d.ts +57 -0
  396. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/serial-number.d.ts.map +1 -0
  397. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/serial-number.js +98 -0
  398. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/serial-number.js.map +1 -0
  399. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/signalling.d.ts +312 -0
  400. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/signalling.d.ts.map +1 -0
  401. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/signalling.js +637 -0
  402. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/signalling.js.map +1 -0
  403. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/package.json +49 -0
  404. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/fec-block-profile.ts +145 -0
  405. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/index.ts +6 -0
  406. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/mmtp.ts +892 -0
  407. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/net-constants.ts +17 -0
  408. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/ntp-short.ts +67 -0
  409. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/serial-number.ts +107 -0
  410. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/signalling.ts +862 -0
  411. package/node_modules/@blockcast/mmt-fec/package.json +79 -0
  412. package/node_modules/@blockcast/mmt-fec/src/block-manager.ts +371 -0
  413. package/node_modules/@blockcast/mmt-fec/src/block-processor.ts +439 -0
  414. package/node_modules/@blockcast/mmt-fec/src/cmaf-recovery.ts +127 -0
  415. package/node_modules/@blockcast/mmt-fec/src/cmaf-symbols.ts +68 -0
  416. package/node_modules/@blockcast/mmt-fec/src/fec-block-mapper.ts +310 -0
  417. package/node_modules/@blockcast/mmt-fec/src/index.ts +94 -0
  418. package/node_modules/@blockcast/mmt-fec/src/loc-symbols.ts +34 -0
  419. package/node_modules/@blockcast/mmt-fec/src/oti.ts +463 -0
  420. package/node_modules/@blockcast/mmt-fec/src/reorder-buffer.ts +101 -0
  421. package/node_modules/@blockcast/mmt-fec/src/repair-group.ts +195 -0
  422. package/node_modules/@blockcast/mmt-manifest-verify/dist/.build-stamp +0 -0
  423. package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.d.ts +28 -0
  424. package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.d.ts.map +1 -0
  425. package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.js +128 -0
  426. package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.js.map +1 -0
  427. package/node_modules/@blockcast/mmt-manifest-verify/dist/index.d.ts +4 -0
  428. package/node_modules/@blockcast/mmt-manifest-verify/dist/index.d.ts.map +1 -0
  429. package/node_modules/@blockcast/mmt-manifest-verify/dist/index.js +4 -0
  430. package/node_modules/@blockcast/mmt-manifest-verify/dist/index.js.map +1 -0
  431. package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.d.ts +37 -0
  432. package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.d.ts.map +1 -0
  433. package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.js +179 -0
  434. package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.js.map +1 -0
  435. package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.d.ts +99 -0
  436. package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.d.ts.map +1 -0
  437. package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.js +492 -0
  438. package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.js.map +1 -0
  439. package/node_modules/@blockcast/mmt-manifest-verify/package.json +45 -0
  440. package/node_modules/@blockcast/mmt-manifest-verify/src/admission.ts +171 -0
  441. package/node_modules/@blockcast/mmt-manifest-verify/src/index.ts +3 -0
  442. package/node_modules/@blockcast/mmt-manifest-verify/src/source-auth.ts +230 -0
  443. package/node_modules/@blockcast/mmt-manifest-verify/src/verifier.ts +669 -0
  444. package/node_modules/@noble/hashes/LICENSE +21 -0
  445. package/node_modules/@noble/hashes/README.md +521 -0
  446. package/node_modules/@noble/hashes/_assert.d.ts +17 -0
  447. package/node_modules/@noble/hashes/_assert.d.ts.map +1 -0
  448. package/node_modules/@noble/hashes/_assert.js +18 -0
  449. package/node_modules/@noble/hashes/_assert.js.map +1 -0
  450. package/node_modules/@noble/hashes/_blake.d.ts +14 -0
  451. package/node_modules/@noble/hashes/_blake.d.ts.map +1 -0
  452. package/node_modules/@noble/hashes/_blake.js +50 -0
  453. package/node_modules/@noble/hashes/_blake.js.map +1 -0
  454. package/node_modules/@noble/hashes/_md.d.ts +51 -0
  455. package/node_modules/@noble/hashes/_md.d.ts.map +1 -0
  456. package/node_modules/@noble/hashes/_md.js +162 -0
  457. package/node_modules/@noble/hashes/_md.js.map +1 -0
  458. package/node_modules/@noble/hashes/_u64.d.ts +55 -0
  459. package/node_modules/@noble/hashes/_u64.d.ts.map +1 -0
  460. package/node_modules/@noble/hashes/_u64.js +90 -0
  461. package/node_modules/@noble/hashes/_u64.js.map +1 -0
  462. package/node_modules/@noble/hashes/argon2.d.ts +32 -0
  463. package/node_modules/@noble/hashes/argon2.d.ts.map +1 -0
  464. package/node_modules/@noble/hashes/argon2.js +401 -0
  465. package/node_modules/@noble/hashes/argon2.js.map +1 -0
  466. package/node_modules/@noble/hashes/blake1.d.ts +106 -0
  467. package/node_modules/@noble/hashes/blake1.d.ts.map +1 -0
  468. package/node_modules/@noble/hashes/blake1.js +459 -0
  469. package/node_modules/@noble/hashes/blake1.js.map +1 -0
  470. package/node_modules/@noble/hashes/blake2.d.ts +116 -0
  471. package/node_modules/@noble/hashes/blake2.d.ts.map +1 -0
  472. package/node_modules/@noble/hashes/blake2.js +420 -0
  473. package/node_modules/@noble/hashes/blake2.js.map +1 -0
  474. package/node_modules/@noble/hashes/blake2b.d.ts +11 -0
  475. package/node_modules/@noble/hashes/blake2b.d.ts.map +1 -0
  476. package/node_modules/@noble/hashes/blake2b.js +14 -0
  477. package/node_modules/@noble/hashes/blake2b.js.map +1 -0
  478. package/node_modules/@noble/hashes/blake2s.d.ts +20 -0
  479. package/node_modules/@noble/hashes/blake2s.d.ts.map +1 -0
  480. package/node_modules/@noble/hashes/blake2s.js +24 -0
  481. package/node_modules/@noble/hashes/blake2s.js.map +1 -0
  482. package/node_modules/@noble/hashes/blake3.d.ts +54 -0
  483. package/node_modules/@noble/hashes/blake3.d.ts.map +1 -0
  484. package/node_modules/@noble/hashes/blake3.js +255 -0
  485. package/node_modules/@noble/hashes/blake3.js.map +1 -0
  486. package/node_modules/@noble/hashes/crypto.d.ts +2 -0
  487. package/node_modules/@noble/hashes/crypto.d.ts.map +1 -0
  488. package/node_modules/@noble/hashes/crypto.js +5 -0
  489. package/node_modules/@noble/hashes/crypto.js.map +1 -0
  490. package/node_modules/@noble/hashes/cryptoNode.d.ts +2 -0
  491. package/node_modules/@noble/hashes/cryptoNode.d.ts.map +1 -0
  492. package/node_modules/@noble/hashes/cryptoNode.js +18 -0
  493. package/node_modules/@noble/hashes/cryptoNode.js.map +1 -0
  494. package/node_modules/@noble/hashes/eskdf.d.ts +47 -0
  495. package/node_modules/@noble/hashes/eskdf.d.ts.map +1 -0
  496. package/node_modules/@noble/hashes/eskdf.js +166 -0
  497. package/node_modules/@noble/hashes/eskdf.js.map +1 -0
  498. package/node_modules/@noble/hashes/esm/_assert.d.ts +17 -0
  499. package/node_modules/@noble/hashes/esm/_assert.d.ts.map +1 -0
  500. package/node_modules/@noble/hashes/esm/_assert.js +15 -0
  501. package/node_modules/@noble/hashes/esm/_assert.js.map +1 -0
  502. package/node_modules/@noble/hashes/esm/_blake.d.ts +14 -0
  503. package/node_modules/@noble/hashes/esm/_blake.d.ts.map +1 -0
  504. package/node_modules/@noble/hashes/esm/_blake.js +45 -0
  505. package/node_modules/@noble/hashes/esm/_blake.js.map +1 -0
  506. package/node_modules/@noble/hashes/esm/_md.d.ts +51 -0
  507. package/node_modules/@noble/hashes/esm/_md.d.ts.map +1 -0
  508. package/node_modules/@noble/hashes/esm/_md.js +155 -0
  509. package/node_modules/@noble/hashes/esm/_md.js.map +1 -0
  510. package/node_modules/@noble/hashes/esm/_u64.d.ts +55 -0
  511. package/node_modules/@noble/hashes/esm/_u64.d.ts.map +1 -0
  512. package/node_modules/@noble/hashes/esm/_u64.js +67 -0
  513. package/node_modules/@noble/hashes/esm/_u64.js.map +1 -0
  514. package/node_modules/@noble/hashes/esm/argon2.d.ts +32 -0
  515. package/node_modules/@noble/hashes/esm/argon2.d.ts.map +1 -0
  516. package/node_modules/@noble/hashes/esm/argon2.js +392 -0
  517. package/node_modules/@noble/hashes/esm/argon2.js.map +1 -0
  518. package/node_modules/@noble/hashes/esm/blake1.d.ts +106 -0
  519. package/node_modules/@noble/hashes/esm/blake1.d.ts.map +1 -0
  520. package/node_modules/@noble/hashes/esm/blake1.js +452 -0
  521. package/node_modules/@noble/hashes/esm/blake1.js.map +1 -0
  522. package/node_modules/@noble/hashes/esm/blake2.d.ts +116 -0
  523. package/node_modules/@noble/hashes/esm/blake2.d.ts.map +1 -0
  524. package/node_modules/@noble/hashes/esm/blake2.js +413 -0
  525. package/node_modules/@noble/hashes/esm/blake2.js.map +1 -0
  526. package/node_modules/@noble/hashes/esm/blake2b.d.ts +11 -0
  527. package/node_modules/@noble/hashes/esm/blake2b.d.ts.map +1 -0
  528. package/node_modules/@noble/hashes/esm/blake2b.js +11 -0
  529. package/node_modules/@noble/hashes/esm/blake2b.js.map +1 -0
  530. package/node_modules/@noble/hashes/esm/blake2s.d.ts +20 -0
  531. package/node_modules/@noble/hashes/esm/blake2s.d.ts.map +1 -0
  532. package/node_modules/@noble/hashes/esm/blake2s.js +21 -0
  533. package/node_modules/@noble/hashes/esm/blake2s.js.map +1 -0
  534. package/node_modules/@noble/hashes/esm/blake3.d.ts +54 -0
  535. package/node_modules/@noble/hashes/esm/blake3.d.ts.map +1 -0
  536. package/node_modules/@noble/hashes/esm/blake3.js +251 -0
  537. package/node_modules/@noble/hashes/esm/blake3.js.map +1 -0
  538. package/node_modules/@noble/hashes/esm/crypto.d.ts +2 -0
  539. package/node_modules/@noble/hashes/esm/crypto.d.ts.map +1 -0
  540. package/node_modules/@noble/hashes/esm/crypto.js +2 -0
  541. package/node_modules/@noble/hashes/esm/crypto.js.map +1 -0
  542. package/node_modules/@noble/hashes/esm/cryptoNode.d.ts +2 -0
  543. package/node_modules/@noble/hashes/esm/cryptoNode.d.ts.map +1 -0
  544. package/node_modules/@noble/hashes/esm/cryptoNode.js +15 -0
  545. package/node_modules/@noble/hashes/esm/cryptoNode.js.map +1 -0
  546. package/node_modules/@noble/hashes/esm/eskdf.d.ts +47 -0
  547. package/node_modules/@noble/hashes/esm/eskdf.d.ts.map +1 -0
  548. package/node_modules/@noble/hashes/esm/eskdf.js +160 -0
  549. package/node_modules/@noble/hashes/esm/eskdf.js.map +1 -0
  550. package/node_modules/@noble/hashes/esm/hkdf.d.ts +36 -0
  551. package/node_modules/@noble/hashes/esm/hkdf.d.ts.map +1 -0
  552. package/node_modules/@noble/hashes/esm/hkdf.js +82 -0
  553. package/node_modules/@noble/hashes/esm/hkdf.js.map +1 -0
  554. package/node_modules/@noble/hashes/esm/hmac.d.ts +35 -0
  555. package/node_modules/@noble/hashes/esm/hmac.d.ts.map +1 -0
  556. package/node_modules/@noble/hashes/esm/hmac.js +86 -0
  557. package/node_modules/@noble/hashes/esm/hmac.js.map +1 -0
  558. package/node_modules/@noble/hashes/esm/index.d.ts +2 -0
  559. package/node_modules/@noble/hashes/esm/index.d.ts.map +1 -0
  560. package/node_modules/@noble/hashes/esm/index.js +33 -0
  561. package/node_modules/@noble/hashes/esm/index.js.map +1 -0
  562. package/node_modules/@noble/hashes/esm/legacy.d.ts +71 -0
  563. package/node_modules/@noble/hashes/esm/legacy.d.ts.map +1 -0
  564. package/node_modules/@noble/hashes/esm/legacy.js +281 -0
  565. package/node_modules/@noble/hashes/esm/legacy.js.map +1 -0
  566. package/node_modules/@noble/hashes/esm/package.json +10 -0
  567. package/node_modules/@noble/hashes/esm/pbkdf2.d.ts +23 -0
  568. package/node_modules/@noble/hashes/esm/pbkdf2.d.ts.map +1 -0
  569. package/node_modules/@noble/hashes/esm/pbkdf2.js +97 -0
  570. package/node_modules/@noble/hashes/esm/pbkdf2.js.map +1 -0
  571. package/node_modules/@noble/hashes/esm/ripemd160.d.ts +13 -0
  572. package/node_modules/@noble/hashes/esm/ripemd160.d.ts.map +1 -0
  573. package/node_modules/@noble/hashes/esm/ripemd160.js +13 -0
  574. package/node_modules/@noble/hashes/esm/ripemd160.js.map +1 -0
  575. package/node_modules/@noble/hashes/esm/scrypt.d.ts +34 -0
  576. package/node_modules/@noble/hashes/esm/scrypt.d.ts.map +1 -0
  577. package/node_modules/@noble/hashes/esm/scrypt.js +228 -0
  578. package/node_modules/@noble/hashes/esm/scrypt.js.map +1 -0
  579. package/node_modules/@noble/hashes/esm/sha1.d.ts +11 -0
  580. package/node_modules/@noble/hashes/esm/sha1.d.ts.map +1 -0
  581. package/node_modules/@noble/hashes/esm/sha1.js +11 -0
  582. package/node_modules/@noble/hashes/esm/sha1.js.map +1 -0
  583. package/node_modules/@noble/hashes/esm/sha2.d.ts +159 -0
  584. package/node_modules/@noble/hashes/esm/sha2.d.ts.map +1 -0
  585. package/node_modules/@noble/hashes/esm/sha2.js +375 -0
  586. package/node_modules/@noble/hashes/esm/sha2.js.map +1 -0
  587. package/node_modules/@noble/hashes/esm/sha256.d.ts +20 -0
  588. package/node_modules/@noble/hashes/esm/sha256.d.ts.map +1 -0
  589. package/node_modules/@noble/hashes/esm/sha256.js +20 -0
  590. package/node_modules/@noble/hashes/esm/sha256.js.map +1 -0
  591. package/node_modules/@noble/hashes/esm/sha3-addons.d.ts +142 -0
  592. package/node_modules/@noble/hashes/esm/sha3-addons.d.ts.map +1 -0
  593. package/node_modules/@noble/hashes/esm/sha3-addons.js +393 -0
  594. package/node_modules/@noble/hashes/esm/sha3-addons.js.map +1 -0
  595. package/node_modules/@noble/hashes/esm/sha3.d.ts +53 -0
  596. package/node_modules/@noble/hashes/esm/sha3.d.ts.map +1 -0
  597. package/node_modules/@noble/hashes/esm/sha3.js +234 -0
  598. package/node_modules/@noble/hashes/esm/sha3.js.map +1 -0
  599. package/node_modules/@noble/hashes/esm/sha512.d.ts +26 -0
  600. package/node_modules/@noble/hashes/esm/sha512.d.ts.map +1 -0
  601. package/node_modules/@noble/hashes/esm/sha512.js +26 -0
  602. package/node_modules/@noble/hashes/esm/sha512.js.map +1 -0
  603. package/node_modules/@noble/hashes/esm/utils.d.ts +161 -0
  604. package/node_modules/@noble/hashes/esm/utils.d.ts.map +1 -0
  605. package/node_modules/@noble/hashes/esm/utils.js +281 -0
  606. package/node_modules/@noble/hashes/esm/utils.js.map +1 -0
  607. package/node_modules/@noble/hashes/hkdf.d.ts +36 -0
  608. package/node_modules/@noble/hashes/hkdf.d.ts.map +1 -0
  609. package/node_modules/@noble/hashes/hkdf.js +88 -0
  610. package/node_modules/@noble/hashes/hkdf.js.map +1 -0
  611. package/node_modules/@noble/hashes/hmac.d.ts +35 -0
  612. package/node_modules/@noble/hashes/hmac.d.ts.map +1 -0
  613. package/node_modules/@noble/hashes/hmac.js +91 -0
  614. package/node_modules/@noble/hashes/hmac.js.map +1 -0
  615. package/node_modules/@noble/hashes/index.d.ts +1 -0
  616. package/node_modules/@noble/hashes/index.d.ts.map +1 -0
  617. package/node_modules/@noble/hashes/index.js +33 -0
  618. package/node_modules/@noble/hashes/index.js.map +1 -0
  619. package/node_modules/@noble/hashes/legacy.d.ts +71 -0
  620. package/node_modules/@noble/hashes/legacy.d.ts.map +1 -0
  621. package/node_modules/@noble/hashes/legacy.js +287 -0
  622. package/node_modules/@noble/hashes/legacy.js.map +1 -0
  623. package/node_modules/@noble/hashes/package.json +266 -0
  624. package/node_modules/@noble/hashes/pbkdf2.d.ts +23 -0
  625. package/node_modules/@noble/hashes/pbkdf2.d.ts.map +1 -0
  626. package/node_modules/@noble/hashes/pbkdf2.js +101 -0
  627. package/node_modules/@noble/hashes/pbkdf2.js.map +1 -0
  628. package/node_modules/@noble/hashes/ripemd160.d.ts +13 -0
  629. package/node_modules/@noble/hashes/ripemd160.d.ts.map +1 -0
  630. package/node_modules/@noble/hashes/ripemd160.js +16 -0
  631. package/node_modules/@noble/hashes/ripemd160.js.map +1 -0
  632. package/node_modules/@noble/hashes/scrypt.d.ts +34 -0
  633. package/node_modules/@noble/hashes/scrypt.d.ts.map +1 -0
  634. package/node_modules/@noble/hashes/scrypt.js +232 -0
  635. package/node_modules/@noble/hashes/scrypt.js.map +1 -0
  636. package/node_modules/@noble/hashes/sha1.d.ts +11 -0
  637. package/node_modules/@noble/hashes/sha1.d.ts.map +1 -0
  638. package/node_modules/@noble/hashes/sha1.js +14 -0
  639. package/node_modules/@noble/hashes/sha1.js.map +1 -0
  640. package/node_modules/@noble/hashes/sha2.d.ts +159 -0
  641. package/node_modules/@noble/hashes/sha2.d.ts.map +1 -0
  642. package/node_modules/@noble/hashes/sha2.js +384 -0
  643. package/node_modules/@noble/hashes/sha2.js.map +1 -0
  644. package/node_modules/@noble/hashes/sha256.d.ts +20 -0
  645. package/node_modules/@noble/hashes/sha256.d.ts.map +1 -0
  646. package/node_modules/@noble/hashes/sha256.js +23 -0
  647. package/node_modules/@noble/hashes/sha256.js.map +1 -0
  648. package/node_modules/@noble/hashes/sha3-addons.d.ts +142 -0
  649. package/node_modules/@noble/hashes/sha3-addons.d.ts.map +1 -0
  650. package/node_modules/@noble/hashes/sha3-addons.js +402 -0
  651. package/node_modules/@noble/hashes/sha3-addons.js.map +1 -0
  652. package/node_modules/@noble/hashes/sha3.d.ts +53 -0
  653. package/node_modules/@noble/hashes/sha3.d.ts.map +1 -0
  654. package/node_modules/@noble/hashes/sha3.js +239 -0
  655. package/node_modules/@noble/hashes/sha3.js.map +1 -0
  656. package/node_modules/@noble/hashes/sha512.d.ts +26 -0
  657. package/node_modules/@noble/hashes/sha512.d.ts.map +1 -0
  658. package/node_modules/@noble/hashes/sha512.js +29 -0
  659. package/node_modules/@noble/hashes/sha512.js.map +1 -0
  660. package/node_modules/@noble/hashes/src/_assert.ts +22 -0
  661. package/node_modules/@noble/hashes/src/_blake.ts +50 -0
  662. package/node_modules/@noble/hashes/src/_md.ts +176 -0
  663. package/node_modules/@noble/hashes/src/_u64.ts +91 -0
  664. package/node_modules/@noble/hashes/src/argon2.ts +497 -0
  665. package/node_modules/@noble/hashes/src/blake1.ts +534 -0
  666. package/node_modules/@noble/hashes/src/blake2.ts +486 -0
  667. package/node_modules/@noble/hashes/src/blake2b.ts +10 -0
  668. package/node_modules/@noble/hashes/src/blake2s.ts +20 -0
  669. package/node_modules/@noble/hashes/src/blake3.ts +272 -0
  670. package/node_modules/@noble/hashes/src/crypto.ts +9 -0
  671. package/node_modules/@noble/hashes/src/cryptoNode.ts +15 -0
  672. package/node_modules/@noble/hashes/src/eskdf.ts +187 -0
  673. package/node_modules/@noble/hashes/src/hkdf.ts +88 -0
  674. package/node_modules/@noble/hashes/src/hmac.ts +94 -0
  675. package/node_modules/@noble/hashes/src/index.ts +31 -0
  676. package/node_modules/@noble/hashes/src/legacy.ts +293 -0
  677. package/node_modules/@noble/hashes/src/pbkdf2.ts +122 -0
  678. package/node_modules/@noble/hashes/src/ripemd160.ts +12 -0
  679. package/node_modules/@noble/hashes/src/scrypt.ts +257 -0
  680. package/node_modules/@noble/hashes/src/sha1.ts +10 -0
  681. package/node_modules/@noble/hashes/src/sha2.ts +402 -0
  682. package/node_modules/@noble/hashes/src/sha256.ts +24 -0
  683. package/node_modules/@noble/hashes/src/sha3-addons.ts +499 -0
  684. package/node_modules/@noble/hashes/src/sha3.ts +258 -0
  685. package/node_modules/@noble/hashes/src/sha512.ts +34 -0
  686. package/node_modules/@noble/hashes/src/utils.ts +395 -0
  687. package/node_modules/@noble/hashes/utils.d.ts +161 -0
  688. package/node_modules/@noble/hashes/utils.d.ts.map +1 -0
  689. package/node_modules/@noble/hashes/utils.js +313 -0
  690. package/node_modules/@noble/hashes/utils.js.map +1 -0
  691. package/package.json +179 -8
  692. package/schemas/catalog.schema.json +357 -0
  693. package/src/align.ts +239 -0
  694. package/src/audio-init-parser.ts +189 -0
  695. package/src/audio-ring-buffer.ts +120 -0
  696. package/src/authored-timing.ts +63 -0
  697. package/src/block-policy.ts +903 -0
  698. package/src/carp-catalog.ts +1065 -0
  699. package/src/catalog-fec-params.ts +729 -0
  700. package/src/catalog-network-source.ts +74 -0
  701. package/src/catalog-validator.ts +34 -0
  702. package/src/cmaf-block-assembler.ts +1255 -0
  703. package/src/cmaf-group-batcher.ts +104 -0
  704. package/src/cmcd-producer.ts +329 -0
  705. package/src/codec-utils.ts +1984 -0
  706. package/src/conceal-timeline.ts +293 -0
  707. package/src/delivery-gap.ts +147 -0
  708. package/src/duplicate-ledger.ts +372 -0
  709. package/src/fec-codec.ts +61 -0
  710. package/src/fec-manager.ts +4298 -0
  711. package/src/fec-starvation-detector.ts +128 -0
  712. package/src/fec-state.ts +219 -0
  713. package/src/fec-worker-setup.ts +283 -0
  714. package/src/fmp4-completion.ts +47 -0
  715. package/src/fmp4-reader.ts +112 -0
  716. package/src/index.ts +590 -21
  717. package/src/iso-block-locator.ts +329 -0
  718. package/src/iso-bmff-timing.ts +813 -0
  719. package/src/loc.ts +128 -154
  720. package/src/manifest-auth-plan.ts +107 -0
  721. package/src/media-router.ts +841 -0
  722. package/src/mfu-reassembler.ts +3480 -155
  723. package/src/mfu-reassembly-policy.ts +134 -0
  724. package/src/mmtp-container-parser.ts +2380 -0
  725. package/src/mmtp-decode-pipeline.ts +406 -0
  726. package/src/mmtp-router.ts +4860 -0
  727. package/src/mmtp-to-cmaf.ts +977 -0
  728. package/src/multicast-auth-catalog.ts +340 -0
  729. package/src/multicast-input.ts +793 -0
  730. package/src/multicast-manager.ts +2783 -0
  731. package/src/multicast-transport.ts +1058 -0
  732. package/src/multicast-unwrap.ts +132 -0
  733. package/src/no-modules.ts +21 -0
  734. package/src/phase14-catalog-override.ts +336 -0
  735. package/src/repair-fetch.ts +772 -0
  736. package/src/repair-layers.ts +533 -0
  737. package/src/sample-combiner.ts +938 -0
  738. package/src/signaling.ts +78 -0
  739. package/src/source-auth.ts +1 -0
  740. package/src/switching-set-alignment.ts +109 -0
  741. package/src/timestamp-codec.ts +265 -0
  742. package/src/track-pipeline-setup.ts +205 -0
  743. package/src/track-pipeline.ts +332 -0
  744. package/src/track-session.ts +1010 -0
  745. package/src/transport-pool.ts +128 -0
  746. package/src/wasm-mfu-reassembler.ts +405 -0
  747. package/src/wasm-mmtp-container-parser.ts +23 -0
  748. package/test-vectors/align.json +199 -0
  749. package/test-vectors/catalog/README.md +106 -0
  750. package/test-vectors/catalog/negative/archive-origin-with-path.json +33 -0
  751. package/test-vectors/catalog/negative/archive-unknown-field.json +34 -0
  752. package/test-vectors/catalog/negative/fec-block-profile-missing.json +51 -0
  753. package/test-vectors/catalog/negative/fec-block-profile-unknown.json +52 -0
  754. package/test-vectors/catalog/negative/fec-enhancement-repair-removed.json +28 -0
  755. package/test-vectors/catalog/negative/fec-repair-layer-geometry.json +33 -0
  756. package/test-vectors/catalog/negative/fec-repair-layer-missing-symbols.json +31 -0
  757. package/test-vectors/catalog/negative/fec-repair-multiple-depends.json +32 -0
  758. package/test-vectors/catalog/negative/fec-repair-overlay-with-layer.json +34 -0
  759. package/test-vectors/catalog/negative/fec-repair-priority-out-of-band.json +24 -0
  760. package/test-vectors/catalog/negative/fec-repair-source-symbols-without-scope.json +33 -0
  761. package/test-vectors/catalog/negative/legacy-selection-params.json +15 -0
  762. package/test-vectors/catalog/negative/media-track-repair-layer.json +16 -0
  763. package/test-vectors/catalog/negative/missing-mmtp-fields.json +12 -0
  764. package/test-vectors/catalog/negative/multicast-auth-padded-key.json +37 -0
  765. package/test-vectors/catalog/negative/multicast-auth-reused-track-format.json +53 -0
  766. package/test-vectors/catalog/negative/multicast-auth-trailing-pad-bits.json +37 -0
  767. package/test-vectors/catalog/negative/multicast-endpoint-missing-protocol-and-source.json +24 -0
  768. package/test-vectors/catalog/negative/multicast-network-source-empty.json +44 -0
  769. package/test-vectors/catalog/negative/multicast-packet-id-signaling.json +26 -0
  770. package/test-vectors/catalog/negative/network-source-object.json +25 -0
  771. package/test-vectors/catalog/negative/raptorq-source-symbols-over-max.json +24 -0
  772. package/test-vectors/catalog/negative/raptorq-unaligned-symbol.json +27 -0
  773. package/test-vectors/catalog/negative/repair-track-legacy-shape.json +19 -0
  774. package/test-vectors/catalog/negative/track-role-empty.json +16 -0
  775. package/test-vectors/catalog/negative/track-role-non-string.json +16 -0
  776. package/test-vectors/catalog/positive/archive-origin.json +34 -0
  777. package/test-vectors/catalog/positive/fec-iso-ssbg1.json +52 -0
  778. package/test-vectors/catalog/positive/fec-layered-repair.json +106 -0
  779. package/test-vectors/catalog/positive/fec-multicast.json +52 -0
  780. package/test-vectors/catalog/positive/flat-av.json +30 -0
  781. package/test-vectors/catalog/positive/multicast-auth-rotation.json +55 -0
  782. package/test-vectors/catalog/positive/multicast-native-ssm-no-network-source.json +43 -0
  783. package/test-vectors/catalog/positive/ticks-and-mixed-timescales.json +39 -0
  784. package/test-vectors/catalog/positive/track-role.json +49 -0
  785. package/test-vectors/catalog/releases/moqcast-native-v16-v1/catalog.json +65 -0
  786. package/test-vectors/catalog/releases/moqcast-native-v16-v1.archive.sha256 +1 -0
  787. package/test-vectors/catalog-multicast-auth-v1.json +26 -0
  788. package/test-vectors/catalog-validation.json +732 -0
  789. package/test-vectors/catalog-validator-public-api.mjs +25 -0
  790. package/test-vectors/generate-source-auth-fixture.mjs +114 -0
  791. package/test-vectors/hevc-x265-repeat-headers-v1.json +40 -0
  792. package/test-vectors/source-auth-v1.json +61 -0
  793. package/test-vectors/source-contiguity-v1.json +131 -0
  794. package/test-vectors/subsample-placement-v1.json +230 -0
  795. package/dist/mmtp.d.ts +0 -73
  796. package/dist/mmtp.d.ts.map +0 -1
  797. package/dist/mmtp.js +0 -210
  798. package/dist/mmtp.js.map +0 -1
  799. package/src/mmtp.ts +0 -277
@@ -0,0 +1,152 @@
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` took tick-space
105
+ * inputs from PCL-2211, and its group-alignment observer was then removed
106
+ * outright as unwired telemetry (BLO-34141). Removal of this wrapper is
107
+ * tracked by BLO-21176; the exported `groupIdForTicks` / `driftCheck` stay
108
+ * regardless — they are the formula shared with the Go sender and the Rust
109
+ * relay, not internals of the deleted observer.
110
+ */
111
+ export declare function groupIdFor(mediaTimeSec: Seconds | number, groupDurationSec: number): number;
112
+ /**
113
+ * Result of a drift check between expected and actual groupIds.
114
+ *
115
+ * Discriminated on `kind` so callers must handle both outcomes explicitly
116
+ * (the previous `{ drifted: boolean, deltaGroups: number }` shape let a
117
+ * drifted result slip through with a silent `if (result.drifted)` gate).
118
+ */
119
+ export type DriftCheckResult = {
120
+ readonly kind: 'aligned';
121
+ readonly deltaGroups: 0;
122
+ } | {
123
+ readonly kind: 'drifted';
124
+ readonly deltaGroups: number;
125
+ };
126
+ /**
127
+ * Compare a packet-stamped groupId against the formula-derived expectation.
128
+ *
129
+ * Pure observer — does not throw on drift, does not mutate anything.
130
+ * Callers decide how to react (e.g. bump a CMCD counter, log, ignore).
131
+ *
132
+ * @param expected — groupId as derived via `groupIdForTicks` or `groupIdFor`.
133
+ * @param actual — groupId as stamped on the incoming packet/group.
134
+ */
135
+ export declare function driftCheck(expected: number, actual: number): DriftCheckResult;
136
+ export type MmtpSubgroupKeyInput = {
137
+ readonly kind: 'mpu-metadata';
138
+ } | {
139
+ readonly kind: 'timed';
140
+ readonly movieFragmentSequenceNumber: number;
141
+ readonly sampleNumber: number;
142
+ } | {
143
+ readonly kind: 'non-timed';
144
+ readonly itemId: number;
145
+ };
146
+ /**
147
+ * Canonical, domain-separated key for MMTP payloads sharing one MoQ subgroup.
148
+ * This is a map/storage key, not the scalar MoQ subgroup ID. MPU metadata is
149
+ * carried in subgroup 0; media identity remains explicit and collision-free.
150
+ */
151
+ export declare function subgroupKeyFor(input: MmtpSubgroupKeyInput): string;
152
+ //# 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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;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"}
package/dist/align.js ADDED
@@ -0,0 +1,88 @@
1
+ // src/align.ts
2
+ function secondsFromTicks(ticks, timescale) {
3
+ if (!Number.isFinite(ticks)) {
4
+ throw new Error(`[align] secondsFromTicks: ticks must be finite, got ${ticks}`);
5
+ }
6
+ if (!Number.isFinite(timescale) || timescale <= 0) {
7
+ throw new Error(
8
+ `[align] secondsFromTicks: timescale must be positive and finite, got ${timescale}`
9
+ );
10
+ }
11
+ return ticks / timescale;
12
+ }
13
+ function asSeconds(n) {
14
+ if (!Number.isFinite(n)) {
15
+ throw new Error(`[align] asSeconds: value must be finite, got ${n}`);
16
+ }
17
+ return n;
18
+ }
19
+ function groupIdForTicks(ticks, groupDurationTicks) {
20
+ if (!Number.isInteger(ticks)) {
21
+ throw new Error(
22
+ `[align] groupIdForTicks: ticks must be an integer, got ${ticks}`
23
+ );
24
+ }
25
+ if (!Number.isInteger(groupDurationTicks) || groupDurationTicks <= 0) {
26
+ throw new Error(
27
+ `[align] groupIdForTicks: groupDurationTicks must be a positive integer, got ${groupDurationTicks}`
28
+ );
29
+ }
30
+ if (ticks < 0) return 0;
31
+ return Math.floor(ticks / groupDurationTicks);
32
+ }
33
+ function groupIdFor(mediaTimeSec, groupDurationSec) {
34
+ if (!Number.isFinite(mediaTimeSec)) {
35
+ throw new Error(
36
+ `[align] groupIdFor: mediaTimeSec must be a finite number, got ${mediaTimeSec}`
37
+ );
38
+ }
39
+ if (!Number.isFinite(groupDurationSec) || groupDurationSec <= 0) {
40
+ throw new Error(
41
+ `[align] groupIdFor: groupDurationSec must be a positive finite number, got ${groupDurationSec}`
42
+ );
43
+ }
44
+ if (mediaTimeSec < 0) return 0;
45
+ const TS = 1e9;
46
+ const ticks = Math.round(mediaTimeSec * TS);
47
+ const durTicks = Math.round(groupDurationSec * TS);
48
+ if (durTicks <= 0) {
49
+ throw new Error(
50
+ `[align] groupIdFor: groupDurationSec=${groupDurationSec} rounds to <1 tick at 1e9 Hz; pass groupIdForTicks directly for sub-nanosecond durations`
51
+ );
52
+ }
53
+ if (!Number.isSafeInteger(ticks)) {
54
+ throw new Error(
55
+ `[align] groupIdFor: mediaTimeSec=${mediaTimeSec} overflows safe-integer ticks at 1e9 Hz (>~104 days); use groupIdForTicks with a narrower timescale`
56
+ );
57
+ }
58
+ return groupIdForTicks(ticks, durTicks);
59
+ }
60
+ function driftCheck(expected, actual) {
61
+ if (!Number.isInteger(expected) || !Number.isInteger(actual)) {
62
+ throw new Error(
63
+ `[align] driftCheck: both arguments must be integer groupIds, got expected=${expected} actual=${actual}`
64
+ );
65
+ }
66
+ const deltaGroups = actual - expected;
67
+ if (deltaGroups === 0) return { kind: "aligned", deltaGroups: 0 };
68
+ return { kind: "drifted", deltaGroups };
69
+ }
70
+ function subgroupKeyFor(input) {
71
+ if (input.kind === "mpu-metadata") return "metadata:0";
72
+ const values = input.kind === "timed" ? [input.movieFragmentSequenceNumber, input.sampleNumber] : [input.itemId];
73
+ for (const value of values) {
74
+ if (!Number.isInteger(value) || value < 0 || value > 4294967295) {
75
+ throw new Error(`[align] subgroup key coordinates must be uint32, got ${value}`);
76
+ }
77
+ }
78
+ return input.kind === "timed" ? `timed:${input.movieFragmentSequenceNumber}:${input.sampleNumber}` : `non-timed:${input.itemId}`;
79
+ }
80
+ export {
81
+ asSeconds,
82
+ driftCheck,
83
+ groupIdFor,
84
+ groupIdForTicks,
85
+ secondsFromTicks,
86
+ subgroupKeyFor
87
+ };
88
+ //# sourceMappingURL=align.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/align.ts"],
4
+ "sourcesContent": ["/**\n * Shared group-alignment primitive for MMT over MoQ switching sets.\n *\n * Pure math \u2014 no MMT wire parsing, no CMCD, no I/O. Callers wire the output\n * into their own drift-observation plumbing (see media-router.ts for the\n * libmmt wiring).\n *\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * Contract (integer-ticks form, authoritative):\n *\n * groupId = ticks < 0 ? 0 : floor(ticks / groupDurationTicks)\n *\n * Where `ticks` is a media timestamp expressed at the catalog's `timescale`\n * (Hz), and `groupDurationTicks = groupDurationSec * timescale`.\n *\n * Integer math means there is no epsilon and no float rounding to reason\n * about. The seconds-form wrapper `groupIdFor(Seconds, seconds)` exists for\n * legacy callers but converts to ticks internally.\n *\n * Every sender/receiver that emits or consumes MoQ groups from an MMT or\n * CMAF switching set MUST derive groupId from this formula so that base,\n * delta, and repair tracks agree on the group boundary for a given media\n * timestamp across languages and processes.\n *\n * Test vectors that exercise the contract live at\n * `packages/container/test-vectors/align.json`; the Go and Rust siblings\n * load the same fixture so cross-language agreement is executable, not\n * prose. **Formula changes require updating the fixture AND all three\n * sibling implementations in the same release** \u2014 divergence between\n * sender/relay/receiver is worse than any formula change.\n *\n * Canonical implementations:\n * Go: Blockcast/multicast `cmd/caddy/sender/group_align.go`\n * (commit 104eeff) \u2014 sender-side groupId stamping on egress.\n * Rust: moqtail/moqtail `apps/relay/src/server/abr.rs`\n * (commit 39accbf; experimental branch, may be rebased \u2014 rely\n * on the SHA, not the branch name) \u2014 relay-side check.\n * TS: THIS FILE (libmmt) \u2014 consumed by moq-lib + moqtail-ts via\n * @blockcast/mmt-container.\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n */\n\n/**\n * Branded seconds type. Construct only via `secondsFromTicks(ticks, timescale)`\n * or `asSeconds(n)` (the latter exists solely for tests and bring-up). The\n * brand prevents accidentally passing a raw tick count \u2014 or a Date.now()\n * millisecond \u2014 to an API that expects a media-time in seconds.\n */\nexport type Seconds = number & { readonly __brand: 'Seconds' }\n\n/**\n * Explicit conversion constructor: ticks at `timescale` Hz \u2192 Seconds.\n *\n * Call this at the wire/catalog boundary so the brand flows with the value\n * through the rest of the system. Throws on non-finite inputs or\n * non-positive timescale (CLAUDE.md \u00A7Architectural Principles: error on\n * bad init).\n */\nexport function secondsFromTicks(ticks: number, timescale: number): Seconds {\n if (!Number.isFinite(ticks)) {\n throw new Error(`[align] secondsFromTicks: ticks must be finite, got ${ticks}`)\n }\n if (!Number.isFinite(timescale) || timescale <= 0) {\n throw new Error(\n `[align] secondsFromTicks: timescale must be positive and finite, got ${timescale}`,\n )\n }\n return (ticks / timescale) as Seconds\n}\n\n/**\n * Escape hatch for tests / bring-up code that holds a raw seconds number\n * (e.g. a catalog field that ships as float seconds). Production code\n * should prefer `secondsFromTicks` so the conversion site is explicit.\n */\nexport function asSeconds(n: number): Seconds {\n if (!Number.isFinite(n)) {\n throw new Error(`[align] asSeconds: value must be finite, got ${n}`)\n }\n return n as Seconds\n}\n\n/**\n * Deterministic groupId from integer ticks. Authoritative form of the\n * contract (see module docstring).\n *\n * @param ticks \u2014 media presentation time in ticks (integer).\n * Negative values clamp to group 0 (matches\n * the Go sibling's base-clamp).\n * @param groupDurationTicks \u2014 group duration in ticks (positive integer).\n * @returns non-negative integer groupId.\n *\n * Throws on non-integer/non-finite inputs or non-positive duration. These\n * are init-time errors, not packet-hot-path errors \u2014 callers ingesting\n * wire data should validate once at catalog load, not once per packet.\n */\nexport function groupIdForTicks(ticks: number, groupDurationTicks: number): number {\n if (!Number.isInteger(ticks)) {\n throw new Error(\n `[align] groupIdForTicks: ticks must be an integer, got ${ticks}`,\n )\n }\n if (!Number.isInteger(groupDurationTicks) || groupDurationTicks <= 0) {\n throw new Error(\n `[align] groupIdForTicks: groupDurationTicks must be a positive integer, got ${groupDurationTicks}`,\n )\n }\n if (ticks < 0) return 0\n return Math.floor(ticks / groupDurationTicks)\n}\n\n/**\n * Seconds-form wrapper around `groupIdForTicks`. Kept for backwards\n * compatibility with existing callers that hold `Seconds` (or a raw\n * `number` that semantically represents seconds).\n *\n * Internally converts to ticks using a synthetic 1e9 Hz timescale so the\n * integer-math contract is the single source of truth. The `| number`\n * branch of the parameter type is a migration ramp \u2014 new code should\n * pass `Seconds` explicitly (via `secondsFromTicks` or `asSeconds`).\n *\n * @param mediaTimeSec \u2014 finite number of seconds; negatives clamp to 0.\n * @param groupDurationSec \u2014 positive finite seconds.\n *\n * @deprecated Use `groupIdForTicks(ticks, groupDurationTicks)` with\n * tick-space inputs from the catalog. The seconds wrapper rounds to the\n * nearest nanosecond and throws above ~104 days of media time; the\n * integer-ticks form has no rounding and a much wider safe range.\n *\n * The rounding is not benign: when `groupDurationTicks / timescale` is not\n * ns-exact (33333@90k, 1001@30k, 1024@44.1k \u2014 all real catalog cadences)\n * the quantized duration under-counts and `expected` slips a whole group.\n * See the divergence fixture in `__tests__/align.test.ts`.\n *\n * No non-test caller remains in this package: `MediaRouter` took tick-space\n * inputs from PCL-2211, and its group-alignment observer was then removed\n * outright as unwired telemetry (BLO-34141). Removal of this wrapper is\n * tracked by BLO-21176; the exported `groupIdForTicks` / `driftCheck` stay\n * regardless \u2014 they are the formula shared with the Go sender and the Rust\n * relay, not internals of the deleted observer.\n */\nexport function groupIdFor(\n mediaTimeSec: Seconds | number,\n groupDurationSec: number,\n): number {\n if (!Number.isFinite(mediaTimeSec as number)) {\n throw new Error(\n `[align] groupIdFor: mediaTimeSec must be a finite number, got ${mediaTimeSec}`,\n )\n }\n if (!Number.isFinite(groupDurationSec) || groupDurationSec <= 0) {\n throw new Error(\n `[align] groupIdFor: groupDurationSec must be a positive finite number, got ${groupDurationSec}`,\n )\n }\n if ((mediaTimeSec as number) < 0) return 0\n // 1e9 Hz keeps both operands inside Number.MAX_SAFE_INTEGER (2^53-1)\n // for ~104 days of media time. Beyond that, Math.round returns a\n // non-safe-integer float that Number.isInteger still accepts \u2014 throw\n // explicitly so the caller picks a narrower timescale rather than\n // silently quantizing.\n const TS = 1_000_000_000\n const ticks = Math.round((mediaTimeSec as number) * TS)\n const durTicks = Math.round(groupDurationSec * TS)\n if (durTicks <= 0) {\n throw new Error(\n `[align] groupIdFor: groupDurationSec=${groupDurationSec} rounds to <1 tick at 1e9 Hz; pass groupIdForTicks directly for sub-nanosecond durations`,\n )\n }\n if (!Number.isSafeInteger(ticks)) {\n throw new Error(\n `[align] groupIdFor: mediaTimeSec=${mediaTimeSec} overflows safe-integer ticks at 1e9 Hz (>~104 days); use groupIdForTicks with a narrower timescale`,\n )\n }\n return groupIdForTicks(ticks, durTicks)\n}\n\n/**\n * Result of a drift check between expected and actual groupIds.\n *\n * Discriminated on `kind` so callers must handle both outcomes explicitly\n * (the previous `{ drifted: boolean, deltaGroups: number }` shape let a\n * drifted result slip through with a silent `if (result.drifted)` gate).\n */\nexport type DriftCheckResult =\n | { readonly kind: 'aligned'; readonly deltaGroups: 0 }\n | { readonly kind: 'drifted'; readonly deltaGroups: number }\n\n/**\n * Compare a packet-stamped groupId against the formula-derived expectation.\n *\n * Pure observer \u2014 does not throw on drift, does not mutate anything.\n * Callers decide how to react (e.g. bump a CMCD counter, log, ignore).\n *\n * @param expected \u2014 groupId as derived via `groupIdForTicks` or `groupIdFor`.\n * @param actual \u2014 groupId as stamped on the incoming packet/group.\n */\nexport function driftCheck(expected: number, actual: number): DriftCheckResult {\n if (!Number.isInteger(expected) || !Number.isInteger(actual)) {\n throw new Error(\n `[align] driftCheck: both arguments must be integer groupIds, got expected=${expected} actual=${actual}`,\n )\n }\n const deltaGroups = actual - expected\n if (deltaGroups === 0) return { kind: 'aligned', deltaGroups: 0 }\n return { kind: 'drifted', deltaGroups }\n}\n\nexport type MmtpSubgroupKeyInput =\n | { readonly kind: 'mpu-metadata' }\n | {\n readonly kind: 'timed'\n readonly movieFragmentSequenceNumber: number\n readonly sampleNumber: number\n }\n | { readonly kind: 'non-timed'; readonly itemId: number }\n\n/**\n * Canonical, domain-separated key for MMTP payloads sharing one MoQ subgroup.\n * This is a map/storage key, not the scalar MoQ subgroup ID. MPU metadata is\n * carried in subgroup 0; media identity remains explicit and collision-free.\n */\nexport function subgroupKeyFor(input: MmtpSubgroupKeyInput): string {\n if (input.kind === 'mpu-metadata') return 'metadata:0'\n\n const values =\n input.kind === 'timed'\n ? [input.movieFragmentSequenceNumber, input.sampleNumber]\n : [input.itemId]\n for (const value of values) {\n if (!Number.isInteger(value) || value < 0 || value > 0xffff_ffff) {\n throw new Error(`[align] subgroup key coordinates must be uint32, got ${value}`)\n }\n }\n\n return input.kind === 'timed'\n ? `timed:${input.movieFragmentSequenceNumber}:${input.sampleNumber}`\n : `non-timed:${input.itemId}`\n}\n"],
5
+ "mappings": ";AA0DO,SAAS,iBAAiB,OAAe,WAA4B;AAC1E,MAAI,CAAC,OAAO,SAAS,KAAK,GAAG;AAC3B,UAAM,IAAI,MAAM,uDAAuD,KAAK,EAAE;AAAA,EAChF;AACA,MAAI,CAAC,OAAO,SAAS,SAAS,KAAK,aAAa,GAAG;AACjD,UAAM,IAAI;AAAA,MACR,wEAAwE,SAAS;AAAA,IACnF;AAAA,EACF;AACA,SAAQ,QAAQ;AAClB;AAOO,SAAS,UAAU,GAAoB;AAC5C,MAAI,CAAC,OAAO,SAAS,CAAC,GAAG;AACvB,UAAM,IAAI,MAAM,gDAAgD,CAAC,EAAE;AAAA,EACrE;AACA,SAAO;AACT;AAgBO,SAAS,gBAAgB,OAAe,oBAAoC;AACjF,MAAI,CAAC,OAAO,UAAU,KAAK,GAAG;AAC5B,UAAM,IAAI;AAAA,MACR,0DAA0D,KAAK;AAAA,IACjE;AAAA,EACF;AACA,MAAI,CAAC,OAAO,UAAU,kBAAkB,KAAK,sBAAsB,GAAG;AACpE,UAAM,IAAI;AAAA,MACR,+EAA+E,kBAAkB;AAAA,IACnG;AAAA,EACF;AACA,MAAI,QAAQ,EAAG,QAAO;AACtB,SAAO,KAAK,MAAM,QAAQ,kBAAkB;AAC9C;AAgCO,SAAS,WACd,cACA,kBACQ;AACR,MAAI,CAAC,OAAO,SAAS,YAAsB,GAAG;AAC5C,UAAM,IAAI;AAAA,MACR,iEAAiE,YAAY;AAAA,IAC/E;AAAA,EACF;AACA,MAAI,CAAC,OAAO,SAAS,gBAAgB,KAAK,oBAAoB,GAAG;AAC/D,UAAM,IAAI;AAAA,MACR,8EAA8E,gBAAgB;AAAA,IAChG;AAAA,EACF;AACA,MAAK,eAA0B,EAAG,QAAO;AAMzC,QAAM,KAAK;AACX,QAAM,QAAQ,KAAK,MAAO,eAA0B,EAAE;AACtD,QAAM,WAAW,KAAK,MAAM,mBAAmB,EAAE;AACjD,MAAI,YAAY,GAAG;AACjB,UAAM,IAAI;AAAA,MACR,wCAAwC,gBAAgB;AAAA,IAC1D;AAAA,EACF;AACA,MAAI,CAAC,OAAO,cAAc,KAAK,GAAG;AAChC,UAAM,IAAI;AAAA,MACR,oCAAoC,YAAY;AAAA,IAClD;AAAA,EACF;AACA,SAAO,gBAAgB,OAAO,QAAQ;AACxC;AAsBO,SAAS,WAAW,UAAkB,QAAkC;AAC7E,MAAI,CAAC,OAAO,UAAU,QAAQ,KAAK,CAAC,OAAO,UAAU,MAAM,GAAG;AAC5D,UAAM,IAAI;AAAA,MACR,6EAA6E,QAAQ,WAAW,MAAM;AAAA,IACxG;AAAA,EACF;AACA,QAAM,cAAc,SAAS;AAC7B,MAAI,gBAAgB,EAAG,QAAO,EAAE,MAAM,WAAW,aAAa,EAAE;AAChE,SAAO,EAAE,MAAM,WAAW,YAAY;AACxC;AAgBO,SAAS,eAAe,OAAqC;AAClE,MAAI,MAAM,SAAS,eAAgB,QAAO;AAE1C,QAAM,SACJ,MAAM,SAAS,UACX,CAAC,MAAM,6BAA6B,MAAM,YAAY,IACtD,CAAC,MAAM,MAAM;AACnB,aAAW,SAAS,QAAQ;AAC1B,QAAI,CAAC,OAAO,UAAU,KAAK,KAAK,QAAQ,KAAK,QAAQ,YAAa;AAChE,YAAM,IAAI,MAAM,wDAAwD,KAAK,EAAE;AAAA,IACjF;AAAA,EACF;AAEA,SAAO,MAAM,SAAS,UAClB,SAAS,MAAM,2BAA2B,IAAI,MAAM,YAAY,KAChE,aAAa,MAAM,MAAM;AAC/B;",
6
+ "names": []
7
+ }
@@ -0,0 +1,66 @@
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
+ * Parse AAC AudioSpecificConfig (ASC) to extract frame samples.
27
+ *
28
+ * ASC is a bit-packed structure (ISO 14496-3 §1.6.2.1):
29
+ * audioObjectType (5 bits, or 5+6 if ==31)
30
+ * samplingFrequencyIndex (4 bits, explicit rate if ==0xf)
31
+ * channelConfiguration (4 bits)
32
+ * ... (SBR/PS extensions follow)
33
+ *
34
+ * The audioObjectType determines frame samples:
35
+ * LC-AAC → 1024, HE-AAC(SBR) → 2048, AAC-LD → 512, AAC-ELD → 480
36
+ *
37
+ * @param asc - Raw AudioSpecificConfig bytes (NOT ADTS, NOT fMP4 esds box)
38
+ * @returns frame samples, or null if ASC is invalid/too short
39
+ */
40
+ export declare function parseAacFrameSamples(asc: Uint8Array): number | null;
41
+ /**
42
+ * Parse AAC ASC to extract sample rate.
43
+ * Useful when catalog samplerate is missing but initData is available.
44
+ */
45
+ export declare function parseAacSampleRate(asc: Uint8Array): number | null;
46
+ /**
47
+ * Opus frame samples: 960 at 48kHz (20ms) per RFC 6716 §2.1.4.
48
+ *
49
+ * Opus supports variable frame sizes (2.5, 5, 10, 20, 40, 60, 80, 100, 120ms)
50
+ * but the frame size is per-packet (in the TOC byte), not in the init data.
51
+ * OpusHead (RFC 7845) carries sample_rate and channel_count only.
52
+ *
53
+ * 960 samples at 48kHz = 20ms is the normative default per RFC 6716.
54
+ */
55
+ export declare function parseOpusFrameSamples(_opusHead?: Uint8Array): number;
56
+ /**
57
+ * Extract frame samples from a bare codec descriptor based on codec string.
58
+ *
59
+ * @param codec - Codec string from catalog (e.g., "mp4a.40.2", "opus")
60
+ * @param codecConfig - Raw codec descriptor bytes: AudioSpecificConfig for
61
+ * AAC, OpusHead for Opus. This is the catalog `description` field, NOT the
62
+ * catalog `initData` (ftyp+moov) field — see the file header.
63
+ * @returns frame samples, or null if codec unsupported or the descriptor is invalid
64
+ */
65
+ export declare function frameSamplesFromInit(codec: string, codecConfig: Uint8Array): number | null;
66
+ //# sourceMappingURL=audio-init-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audio-init-parser.d.ts","sourceRoot":"","sources":["../src/audio-init-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AA+BH;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,CAuDnE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,CA0BjE;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,CAAC,EAAE,UAAU,GAAG,MAAM,CAEpE;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,CAQ1F"}
@@ -0,0 +1,118 @@
1
+ // src/audio-init-parser.ts
2
+ var AAC_SAMPLE_RATES = [
3
+ 96e3,
4
+ 88200,
5
+ 64e3,
6
+ 48e3,
7
+ 44100,
8
+ 32e3,
9
+ 24e3,
10
+ 22050,
11
+ 16e3,
12
+ 12e3,
13
+ 11025,
14
+ 8e3,
15
+ 7350
16
+ ];
17
+ function aacFrameSamplesForObjectType(objectType) {
18
+ switch (objectType) {
19
+ case 5:
20
+ return 2048;
21
+ // SBR (HE-AAC v1)
22
+ case 29:
23
+ return 2048;
24
+ // PS (HE-AAC v2, implies SBR)
25
+ case 23:
26
+ return 512;
27
+ // ER AAC-LD
28
+ case 39:
29
+ return 480;
30
+ // ER AAC-ELD
31
+ default:
32
+ return 1024;
33
+ }
34
+ }
35
+ function parseAacFrameSamples(asc) {
36
+ if (asc.length < 2) return null;
37
+ let bitPos = 0;
38
+ const readBits = (n) => {
39
+ let val = 0;
40
+ for (let i = 0; i < n; i++) {
41
+ const byteIdx = bitPos + i >> 3;
42
+ const bitIdx = 7 - (bitPos + i & 7);
43
+ if (byteIdx >= asc.length) return -1;
44
+ val = val << 1 | asc[byteIdx] >> bitIdx & 1;
45
+ }
46
+ bitPos += n;
47
+ return val;
48
+ };
49
+ let objectType = readBits(5);
50
+ if (objectType === 31) {
51
+ objectType = 32 + readBits(6);
52
+ }
53
+ if (objectType < 0) return null;
54
+ const freqIndex = readBits(4);
55
+ if (freqIndex < 0) return null;
56
+ if (freqIndex === 15) {
57
+ readBits(24);
58
+ }
59
+ readBits(4);
60
+ if (objectType === 2 && asc.length >= 4) {
61
+ const remaining = asc.length * 8 - bitPos;
62
+ if (remaining >= 11) {
63
+ const syncExt = readBits(11);
64
+ if (syncExt === 695) {
65
+ const extObjectType = readBits(5);
66
+ if (extObjectType === 5 || extObjectType === 22) {
67
+ return 2048;
68
+ }
69
+ if (extObjectType === 29) {
70
+ return 2048;
71
+ }
72
+ }
73
+ }
74
+ }
75
+ return aacFrameSamplesForObjectType(objectType);
76
+ }
77
+ function parseAacSampleRate(asc) {
78
+ if (asc.length < 2) return null;
79
+ let bitPos = 0;
80
+ const readBits = (n) => {
81
+ let val = 0;
82
+ for (let i = 0; i < n; i++) {
83
+ const byteIdx = bitPos + i >> 3;
84
+ const bitIdx = 7 - (bitPos + i & 7);
85
+ if (byteIdx >= asc.length) return -1;
86
+ val = val << 1 | asc[byteIdx] >> bitIdx & 1;
87
+ }
88
+ bitPos += n;
89
+ return val;
90
+ };
91
+ let objectType = readBits(5);
92
+ if (objectType === 31) readBits(6);
93
+ const freqIndex = readBits(4);
94
+ if (freqIndex < 0) return null;
95
+ if (freqIndex === 15) {
96
+ return readBits(24);
97
+ }
98
+ return AAC_SAMPLE_RATES[freqIndex] ?? null;
99
+ }
100
+ function parseOpusFrameSamples(_opusHead) {
101
+ return 960;
102
+ }
103
+ function frameSamplesFromInit(codec, codecConfig) {
104
+ if (codec.startsWith("mp4a")) {
105
+ return parseAacFrameSamples(codecConfig);
106
+ }
107
+ if (codec.startsWith("opus") || codec === "Opus") {
108
+ return parseOpusFrameSamples(codecConfig);
109
+ }
110
+ return null;
111
+ }
112
+ export {
113
+ frameSamplesFromInit,
114
+ parseAacFrameSamples,
115
+ parseAacSampleRate,
116
+ parseOpusFrameSamples
117
+ };
118
+ //# sourceMappingURL=audio-init-parser.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/audio-init-parser.ts"],
4
+ "sourcesContent": ["/**\n * Audio Init Data Parser \u2014 extract frame samples from a codec descriptor.\n *\n * Consumes the RAW codec configuration bytes (AudioSpecificConfig for AAC,\n * OpusHead for Opus) \u2014 i.e. the catalog `description` field (hang\n * `AudioConfig.description`), NOT the catalog `initData` field.\n *\n * Since BLO-9884 these are two distinct catalog fields: `initData` is a\n * base64 ISOBMFF init segment (ftyp + moov) per draft-ietf-moq-cmsf-00 \u00A73.1,\n * while `description` carries the bare codec descriptor. Hang's `root.ts`\n * parses a CMSF `initData` segment with `decodeInitSegment()` and routes the\n * descriptor it recovers (`init.description`) into `description`; the bytes\n * that reach this parser are therefore always the bare descriptor. Do NOT\n * pass a ftyp+moov `initData` blob here \u2014 the ASC bit-reader would interpret\n * the ftyp box size word as an audioObjectType and return a garbage frame\n * count (the audio analogue of the \"Failed to parse avcC\" CMAF regression\n * documented in root.ts).\n *\n * Supported codecs:\n * - AAC (mp4a.40.*): AudioSpecificConfig per ISO 14496-3 \u00A71.6.2.1\n * - Opus: fixed 960 samples per RFC 6716 \u00A72.1.4\n *\n * Reference: hang-mmt-fec/rs/moq-mux/src/import/aac.rs:AacConfig::parse()\n */\n\n// ISO 14496-3 Table 1.14: samplingFrequencyIndex \u2192 Hz\nconst AAC_SAMPLE_RATES = [\n 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,\n 16000, 12000, 11025, 8000, 7350,\n] as const\n\n/**\n * AAC Audio Object Types that determine frame size.\n * ISO 14496-3 Table 1.3:\n * 1 = AAC-Main \u2192 1024 samples\n * 2 = AAC-LC \u2192 1024 samples\n * 3 = AAC-SSR \u2192 1024 samples\n * 4 = AAC-LTP \u2192 1024 samples\n * 5 = SBR \u2192 2048 samples (HE-AAC v1)\n * 6 = AAC-Scalable \u2192 1024 samples\n * 23 = ER AAC-LD \u2192 512 samples\n * 39 = ER AAC-ELD \u2192 480 samples\n * 29 = PS \u2192 2048 samples (HE-AAC v2, implies SBR)\n */\nfunction aacFrameSamplesForObjectType(objectType: number): number {\n switch (objectType) {\n case 5: return 2048 // SBR (HE-AAC v1)\n case 29: return 2048 // PS (HE-AAC v2, implies SBR)\n case 23: return 512 // ER AAC-LD\n case 39: return 480 // ER AAC-ELD\n default: return 1024 // LC, Main, SSR, LTP, Scalable, etc.\n }\n}\n\n/**\n * Parse AAC AudioSpecificConfig (ASC) to extract frame samples.\n *\n * ASC is a bit-packed structure (ISO 14496-3 \u00A71.6.2.1):\n * audioObjectType (5 bits, or 5+6 if ==31)\n * samplingFrequencyIndex (4 bits, explicit rate if ==0xf)\n * channelConfiguration (4 bits)\n * ... (SBR/PS extensions follow)\n *\n * The audioObjectType determines frame samples:\n * LC-AAC \u2192 1024, HE-AAC(SBR) \u2192 2048, AAC-LD \u2192 512, AAC-ELD \u2192 480\n *\n * @param asc - Raw AudioSpecificConfig bytes (NOT ADTS, NOT fMP4 esds box)\n * @returns frame samples, or null if ASC is invalid/too short\n */\nexport function parseAacFrameSamples(asc: Uint8Array): number | null {\n if (asc.length < 2) return null\n\n // Bit reader\n let bitPos = 0\n const readBits = (n: number): number => {\n let val = 0\n for (let i = 0; i < n; i++) {\n const byteIdx = (bitPos + i) >> 3\n const bitIdx = 7 - ((bitPos + i) & 7)\n if (byteIdx >= asc.length) return -1\n val = (val << 1) | ((asc[byteIdx]! >> bitIdx) & 1)\n }\n bitPos += n\n return val\n }\n\n // audioObjectType: 5 bits, extended to 5+6=11 bits if ==31\n let objectType = readBits(5)\n if (objectType === 31) {\n objectType = 32 + readBits(6)\n }\n if (objectType < 0) return null\n\n // samplingFrequencyIndex: 4 bits\n const freqIndex = readBits(4)\n if (freqIndex < 0) return null\n if (freqIndex === 0xf) {\n // Explicit 24-bit sample rate follows\n readBits(24)\n }\n\n // channelConfiguration: 4 bits\n readBits(4)\n\n // Check for SBR/PS signaling (implicit in HE-AAC)\n // If base objectType is AAC-LC and SBR extension is present, frame size doubles\n if (objectType === 2 /* AAC-LC */ && asc.length >= 4) {\n // Check for SBR extension: 11-bit sync word 0x2b7\n const remaining = (asc.length * 8) - bitPos\n if (remaining >= 11) {\n const syncExt = readBits(11)\n if (syncExt === 0x2b7) {\n const extObjectType = readBits(5)\n if (extObjectType === 5 /* SBR */ || extObjectType === 22 /* ER SBR */) {\n return 2048 // SBR present \u2192 2048 samples\n }\n if (extObjectType === 29 /* PS */) {\n return 2048 // PS implies SBR \u2192 2048 samples\n }\n }\n }\n }\n\n return aacFrameSamplesForObjectType(objectType)\n}\n\n/**\n * Parse AAC ASC to extract sample rate.\n * Useful when catalog samplerate is missing but initData is available.\n */\nexport function parseAacSampleRate(asc: Uint8Array): number | null {\n if (asc.length < 2) return null\n\n let bitPos = 0\n const readBits = (n: number): number => {\n let val = 0\n for (let i = 0; i < n; i++) {\n const byteIdx = (bitPos + i) >> 3\n const bitIdx = 7 - ((bitPos + i) & 7)\n if (byteIdx >= asc.length) return -1\n val = (val << 1) | ((asc[byteIdx]! >> bitIdx) & 1)\n }\n bitPos += n\n return val\n }\n\n // Skip audioObjectType (5 or 11 bits)\n let objectType = readBits(5)\n if (objectType === 31) readBits(6)\n\n const freqIndex = readBits(4)\n if (freqIndex < 0) return null\n if (freqIndex === 0xf) {\n return readBits(24)\n }\n return AAC_SAMPLE_RATES[freqIndex] ?? null\n}\n\n/**\n * Opus frame samples: 960 at 48kHz (20ms) per RFC 6716 \u00A72.1.4.\n *\n * Opus supports variable frame sizes (2.5, 5, 10, 20, 40, 60, 80, 100, 120ms)\n * but the frame size is per-packet (in the TOC byte), not in the init data.\n * OpusHead (RFC 7845) carries sample_rate and channel_count only.\n *\n * 960 samples at 48kHz = 20ms is the normative default per RFC 6716.\n */\nexport function parseOpusFrameSamples(_opusHead?: Uint8Array): number {\n return 960\n}\n\n/**\n * Extract frame samples from a bare codec descriptor based on codec string.\n *\n * @param codec - Codec string from catalog (e.g., \"mp4a.40.2\", \"opus\")\n * @param codecConfig - Raw codec descriptor bytes: AudioSpecificConfig for\n * AAC, OpusHead for Opus. This is the catalog `description` field, NOT the\n * catalog `initData` (ftyp+moov) field \u2014 see the file header.\n * @returns frame samples, or null if codec unsupported or the descriptor is invalid\n */\nexport function frameSamplesFromInit(codec: string, codecConfig: Uint8Array): number | null {\n if (codec.startsWith('mp4a')) {\n return parseAacFrameSamples(codecConfig)\n }\n if (codec.startsWith('opus') || codec === 'Opus') {\n return parseOpusFrameSamples(codecConfig)\n }\n return null\n}\n"],
5
+ "mappings": ";AA0BA,IAAM,mBAAmB;AAAA,EACvB;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EACjD;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAM;AAC7B;AAeA,SAAS,6BAA6B,YAA4B;AAChE,UAAQ,YAAY;AAAA,IAClB,KAAK;AAAI,aAAO;AAAA;AAAA,IAChB,KAAK;AAAI,aAAO;AAAA;AAAA,IAChB,KAAK;AAAI,aAAO;AAAA;AAAA,IAChB,KAAK;AAAI,aAAO;AAAA;AAAA,IAChB;AAAS,aAAO;AAAA,EAClB;AACF;AAiBO,SAAS,qBAAqB,KAAgC;AACnE,MAAI,IAAI,SAAS,EAAG,QAAO;AAG3B,MAAI,SAAS;AACb,QAAM,WAAW,CAAC,MAAsB;AACtC,QAAI,MAAM;AACV,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,YAAM,UAAW,SAAS,KAAM;AAChC,YAAM,SAAS,KAAM,SAAS,IAAK;AACnC,UAAI,WAAW,IAAI,OAAQ,QAAO;AAClC,YAAO,OAAO,IAAO,IAAI,OAAO,KAAM,SAAU;AAAA,IAClD;AACA,cAAU;AACV,WAAO;AAAA,EACT;AAGA,MAAI,aAAa,SAAS,CAAC;AAC3B,MAAI,eAAe,IAAI;AACrB,iBAAa,KAAK,SAAS,CAAC;AAAA,EAC9B;AACA,MAAI,aAAa,EAAG,QAAO;AAG3B,QAAM,YAAY,SAAS,CAAC;AAC5B,MAAI,YAAY,EAAG,QAAO;AAC1B,MAAI,cAAc,IAAK;AAErB,aAAS,EAAE;AAAA,EACb;AAGA,WAAS,CAAC;AAIV,MAAI,eAAe,KAAkB,IAAI,UAAU,GAAG;AAEpD,UAAM,YAAa,IAAI,SAAS,IAAK;AACrC,QAAI,aAAa,IAAI;AACnB,YAAM,UAAU,SAAS,EAAE;AAC3B,UAAI,YAAY,KAAO;AACrB,cAAM,gBAAgB,SAAS,CAAC;AAChC,YAAI,kBAAkB,KAAe,kBAAkB,IAAiB;AACtE,iBAAO;AAAA,QACT;AACA,YAAI,kBAAkB,IAAa;AACjC,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO,6BAA6B,UAAU;AAChD;AAMO,SAAS,mBAAmB,KAAgC;AACjE,MAAI,IAAI,SAAS,EAAG,QAAO;AAE3B,MAAI,SAAS;AACb,QAAM,WAAW,CAAC,MAAsB;AACtC,QAAI,MAAM;AACV,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,YAAM,UAAW,SAAS,KAAM;AAChC,YAAM,SAAS,KAAM,SAAS,IAAK;AACnC,UAAI,WAAW,IAAI,OAAQ,QAAO;AAClC,YAAO,OAAO,IAAO,IAAI,OAAO,KAAM,SAAU;AAAA,IAClD;AACA,cAAU;AACV,WAAO;AAAA,EACT;AAGA,MAAI,aAAa,SAAS,CAAC;AAC3B,MAAI,eAAe,GAAI,UAAS,CAAC;AAEjC,QAAM,YAAY,SAAS,CAAC;AAC5B,MAAI,YAAY,EAAG,QAAO;AAC1B,MAAI,cAAc,IAAK;AACrB,WAAO,SAAS,EAAE;AAAA,EACpB;AACA,SAAO,iBAAiB,SAAS,KAAK;AACxC;AAWO,SAAS,sBAAsB,WAAgC;AACpE,SAAO;AACT;AAWO,SAAS,qBAAqB,OAAe,aAAwC;AAC1F,MAAI,MAAM,WAAW,MAAM,GAAG;AAC5B,WAAO,qBAAqB,WAAW;AAAA,EACzC;AACA,MAAI,MAAM,WAAW,MAAM,KAAK,UAAU,QAAQ;AAChD,WAAO,sBAAsB,WAAW;AAAA,EAC1C;AACA,SAAO;AACT;",
6
+ "names": []
7
+ }
@@ -0,0 +1,50 @@
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
+ export interface AudioRingBufferConfig {
20
+ /** Number of audio channels */
21
+ channels: number;
22
+ /** Sample rate in Hz */
23
+ rate: number;
24
+ /** Buffer latency in milliseconds */
25
+ latencyMs: number;
26
+ /** Start in unstalled state (for source switching) */
27
+ startUnstalled?: boolean;
28
+ }
29
+ export declare class AudioRingBuffer {
30
+ #private;
31
+ readonly channels: number;
32
+ readonly rate: number;
33
+ constructor(config: AudioRingBufferConfig);
34
+ get stalled(): boolean;
35
+ get capacity(): number;
36
+ get length(): number;
37
+ /**
38
+ * Append decoded audio samples to the FIFO.
39
+ * Timestamp parameter retained for API compatibility but is ignored —
40
+ * FIFO is sequence-based, not time-based.
41
+ */
42
+ write(_timestampUs: number, data: Float32Array[]): void;
43
+ /**
44
+ * Read samples into output buffers — plain FIFO, no clock recovery.
45
+ * FEC + MoQ delivery guarantees no gaps, so skip/dup is unnecessary.
46
+ * Underrun → zero-fill.
47
+ */
48
+ read(output: Float32Array[]): number;
49
+ }
50
+ //# sourceMappingURL=audio-ring-buffer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audio-ring-buffer.d.ts","sourceRoot":"","sources":["../src/audio-ring-buffer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,WAAW,qBAAqB;IACpC,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,wBAAwB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,qCAAqC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,sDAAsD;IACtD,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,qBAAa,eAAe;;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAOV,MAAM,EAAE,qBAAqB;IAYzC,IAAI,OAAO,IAAI,OAAO,CAA0B;IAChD,IAAI,QAAQ,IAAI,MAAM,CAAmC;IACzD,IAAI,MAAM,IAAI,MAAM,CAA+C;IAEnE;;;;OAIG;IACH,KAAK,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,IAAI;IA8BvD;;;;OAIG;IACH,IAAI,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM;CAwBrC"}
@@ -0,0 +1,80 @@
1
+ // src/audio-ring-buffer.ts
2
+ var AudioRingBuffer = class {
3
+ #buffer;
4
+ #writeIndex = 0;
5
+ #readIndex = 0;
6
+ #stalled;
7
+ constructor(config) {
8
+ this.channels = config.channels;
9
+ this.rate = config.rate;
10
+ this.#stalled = !(config.startUnstalled ?? false);
11
+ const samples = Math.ceil(config.rate * (config.latencyMs / 1e3));
12
+ this.#buffer = [];
13
+ for (let i = 0; i < config.channels; i++) {
14
+ this.#buffer[i] = new Float32Array(samples);
15
+ }
16
+ }
17
+ get stalled() {
18
+ return this.#stalled;
19
+ }
20
+ get capacity() {
21
+ return this.#buffer[0].length;
22
+ }
23
+ get length() {
24
+ return this.#writeIndex - this.#readIndex;
25
+ }
26
+ /**
27
+ * Append decoded audio samples to the FIFO.
28
+ * Timestamp parameter retained for API compatibility but is ignored —
29
+ * FIFO is sequence-based, not time-based.
30
+ */
31
+ write(_timestampUs, data) {
32
+ const samples = data[0].length;
33
+ const start = this.#writeIndex;
34
+ const end = start + samples;
35
+ const overflow = end - this.#readIndex - this.#buffer[0].length;
36
+ if (overflow >= 0) {
37
+ this.#stalled = false;
38
+ this.#readIndex += overflow;
39
+ }
40
+ if (this.#stalled && end - this.#readIndex >= Math.floor(this.#buffer[0].length / 2)) {
41
+ this.#stalled = false;
42
+ }
43
+ for (let ch = 0; ch < this.channels; ch++) {
44
+ const src = data[ch];
45
+ const dst = this.#buffer[ch];
46
+ for (let i = 0; i < samples; i++) {
47
+ dst[(start + i) % dst.length] = src[i];
48
+ }
49
+ }
50
+ this.#writeIndex = end;
51
+ }
52
+ /**
53
+ * Read samples into output buffers — plain FIFO, no clock recovery.
54
+ * FEC + MoQ delivery guarantees no gaps, so skip/dup is unnecessary.
55
+ * Underrun → zero-fill.
56
+ */
57
+ read(output) {
58
+ if (this.#stalled) return 0;
59
+ const available = this.#writeIndex - this.#readIndex;
60
+ if (available === 0) return 0;
61
+ const requested = output[0].length;
62
+ const readSamples = Math.min(available, requested);
63
+ for (let ch = 0; ch < this.channels; ch++) {
64
+ const dst = output[ch];
65
+ const src = this.#buffer[ch];
66
+ for (let i = 0; i < readSamples; i++) {
67
+ dst[i] = src[(this.#readIndex + i) % src.length];
68
+ }
69
+ for (let i = readSamples; i < requested; i++) {
70
+ dst[i] = 0;
71
+ }
72
+ }
73
+ this.#readIndex += readSamples;
74
+ return readSamples;
75
+ }
76
+ };
77
+ export {
78
+ AudioRingBuffer
79
+ };
80
+ //# sourceMappingURL=audio-ring-buffer.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/audio-ring-buffer.ts"],
4
+ "sourcesContent": ["/**\n * AudioRingBuffer \u2014 plain FIFO audio buffer (no clock recovery).\n *\n * Source of truth for the audio buffer algorithm used in both moq-lib and\n * moqtail AudioWorklet processors. AudioWorklet isolation requires the\n * worklet copy to be self-contained (no imports), so changes here must be\n * manually synced to:\n * - moqtail-private/apps/client-js/src/lib/audio-worklet-processor.js\n * - hang-mmt-fec/js/watch/src/audio/ring-buffer.ts (uses @moq/lite Time types)\n *\n * Rationale: FEC guarantees gap-free, ordered audio on multicast; MoQ\n * delivers ordered audio without drops. The decoder output rate matches\n * the AudioContext destination rate closely enough that skip/dup clock\n * recovery is unnecessary and harmful \u2014 a single sample skip at 48 kHz is\n * a ~21 \u00B5s phase glitch, and repeated skip/dup produces audible pitch\n * wobble on pure tones (measured: 16 Hz offset + \u00B111 Hz spread on a 1 kHz\n * test tone before this refactor).\n */\n\nexport interface AudioRingBufferConfig {\n /** Number of audio channels */\n channels: number;\n /** Sample rate in Hz */\n rate: number;\n /** Buffer latency in milliseconds */\n latencyMs: number;\n /** Start in unstalled state (for source switching) */\n startUnstalled?: boolean;\n}\n\nexport class AudioRingBuffer {\n readonly channels: number;\n readonly rate: number;\n\n #buffer: Float32Array[];\n #writeIndex = 0;\n #readIndex = 0;\n #stalled: boolean;\n\n constructor(config: AudioRingBufferConfig) {\n this.channels = config.channels;\n this.rate = config.rate;\n this.#stalled = !(config.startUnstalled ?? false);\n\n const samples = Math.ceil(config.rate * (config.latencyMs / 1000));\n this.#buffer = [];\n for (let i = 0; i < config.channels; i++) {\n this.#buffer[i] = new Float32Array(samples);\n }\n }\n\n get stalled(): boolean { return this.#stalled; }\n get capacity(): number { return this.#buffer[0].length; }\n get length(): number { return this.#writeIndex - this.#readIndex; }\n\n /**\n * Append decoded audio samples to the FIFO.\n * Timestamp parameter retained for API compatibility but is ignored \u2014\n * FIFO is sequence-based, not time-based.\n */\n write(_timestampUs: number, data: Float32Array[]): void {\n const samples = data[0].length;\n\n const start = this.#writeIndex;\n const end = start + samples;\n\n // Overflow: discard oldest samples (protects against encoder/AudioContext\n // clock drift when one runs faster than the other).\n const overflow = end - this.#readIndex - this.#buffer[0].length;\n if (overflow >= 0) {\n this.#stalled = false;\n this.#readIndex += overflow;\n }\n\n // Unstall at half capacity \u2014 enough prebuffer for bounded jitter.\n if (this.#stalled && (end - this.#readIndex) >= Math.floor(this.#buffer[0].length / 2)) {\n this.#stalled = false;\n }\n\n // Append samples sequentially\n for (let ch = 0; ch < this.channels; ch++) {\n const src = data[ch];\n const dst = this.#buffer[ch];\n for (let i = 0; i < samples; i++) {\n dst[(start + i) % dst.length] = src[i];\n }\n }\n this.#writeIndex = end;\n }\n\n /**\n * Read samples into output buffers \u2014 plain FIFO, no clock recovery.\n * FEC + MoQ delivery guarantees no gaps, so skip/dup is unnecessary.\n * Underrun \u2192 zero-fill.\n */\n read(output: Float32Array[]): number {\n if (this.#stalled) return 0;\n\n const available = this.#writeIndex - this.#readIndex;\n if (available === 0) return 0;\n\n const requested = output[0].length;\n const readSamples = Math.min(available, requested);\n\n for (let ch = 0; ch < this.channels; ch++) {\n const dst = output[ch];\n const src = this.#buffer[ch];\n for (let i = 0; i < readSamples; i++) {\n dst[i] = src[(this.#readIndex + i) % src.length];\n }\n // Zero-fill remainder on underrun\n for (let i = readSamples; i < requested; i++) {\n dst[i] = 0;\n }\n }\n\n this.#readIndex += readSamples;\n return readSamples;\n }\n}\n"],
5
+ "mappings": ";AA8BO,IAAM,kBAAN,MAAsB;AAAA,EAI3B;AAAA,EACA,cAAc;AAAA,EACd,aAAa;AAAA,EACb;AAAA,EAEA,YAAY,QAA+B;AACzC,SAAK,WAAW,OAAO;AACvB,SAAK,OAAO,OAAO;AACnB,SAAK,WAAW,EAAE,OAAO,kBAAkB;AAE3C,UAAM,UAAU,KAAK,KAAK,OAAO,QAAQ,OAAO,YAAY,IAAK;AACjE,SAAK,UAAU,CAAC;AAChB,aAAS,IAAI,GAAG,IAAI,OAAO,UAAU,KAAK;AACxC,WAAK,QAAQ,CAAC,IAAI,IAAI,aAAa,OAAO;AAAA,IAC5C;AAAA,EACF;AAAA,EAEA,IAAI,UAAmB;AAAE,WAAO,KAAK;AAAA,EAAU;AAAA,EAC/C,IAAI,WAAmB;AAAE,WAAO,KAAK,QAAQ,CAAC,EAAE;AAAA,EAAQ;AAAA,EACxD,IAAI,SAAiB;AAAE,WAAO,KAAK,cAAc,KAAK;AAAA,EAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOlE,MAAM,cAAsB,MAA4B;AACtD,UAAM,UAAU,KAAK,CAAC,EAAE;AAExB,UAAM,QAAQ,KAAK;AACnB,UAAM,MAAM,QAAQ;AAIpB,UAAM,WAAW,MAAM,KAAK,aAAa,KAAK,QAAQ,CAAC,EAAE;AACzD,QAAI,YAAY,GAAG;AACjB,WAAK,WAAW;AAChB,WAAK,cAAc;AAAA,IACrB;AAGA,QAAI,KAAK,YAAa,MAAM,KAAK,cAAe,KAAK,MAAM,KAAK,QAAQ,CAAC,EAAE,SAAS,CAAC,GAAG;AACtF,WAAK,WAAW;AAAA,IAClB;AAGA,aAAS,KAAK,GAAG,KAAK,KAAK,UAAU,MAAM;AACzC,YAAM,MAAM,KAAK,EAAE;AACnB,YAAM,MAAM,KAAK,QAAQ,EAAE;AAC3B,eAAS,IAAI,GAAG,IAAI,SAAS,KAAK;AAChC,aAAK,QAAQ,KAAK,IAAI,MAAM,IAAI,IAAI,CAAC;AAAA,MACvC;AAAA,IACF;AACA,SAAK,cAAc;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,KAAK,QAAgC;AACnC,QAAI,KAAK,SAAU,QAAO;AAE1B,UAAM,YAAY,KAAK,cAAc,KAAK;AAC1C,QAAI,cAAc,EAAG,QAAO;AAE5B,UAAM,YAAY,OAAO,CAAC,EAAE;AAC5B,UAAM,cAAc,KAAK,IAAI,WAAW,SAAS;AAEjD,aAAS,KAAK,GAAG,KAAK,KAAK,UAAU,MAAM;AACzC,YAAM,MAAM,OAAO,EAAE;AACrB,YAAM,MAAM,KAAK,QAAQ,EAAE;AAC3B,eAAS,IAAI,GAAG,IAAI,aAAa,KAAK;AACpC,YAAI,CAAC,IAAI,KAAK,KAAK,aAAa,KAAK,IAAI,MAAM;AAAA,MACjD;AAEA,eAAS,IAAI,aAAa,IAAI,WAAW,KAAK;AAC5C,YAAI,CAAC,IAAI;AAAA,MACX;AAAA,IACF;AAEA,SAAK,cAAc;AACnB,WAAO;AAAA,EACT;AACF;",
6
+ "names": []
7
+ }