@omnimedia/omnitool 1.1.0-8 → 1.1.0-80

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 (436) hide show
  1. package/README.md +293 -76
  2. package/package.json +19 -17
  3. package/s/context.ts +0 -7
  4. package/s/demo/demo.bundle.ts +104 -43
  5. package/s/demo/demo.css +244 -14
  6. package/s/demo/routines/export-test.ts +16 -0
  7. package/s/demo/routines/filmstrip-test.ts +22 -18
  8. package/s/demo/routines/load-video.ts +2 -3
  9. package/s/demo/routines/playback-test.ts +61 -0
  10. package/s/demo/routines/timeline-setup.ts +50 -0
  11. package/s/demo/routines/transcode-test.ts +19 -5
  12. package/s/demo/routines/transitions-test.ts +2 -2
  13. package/s/demo/routines/waveform-test.ts +35 -8
  14. package/s/driver/driver-worker.ts +9 -0
  15. package/s/driver/driver.test.ts +1 -1
  16. package/s/driver/driver.ts +43 -42
  17. package/s/driver/fns/schematic.ts +26 -6
  18. package/s/driver/fns/work.ts +65 -189
  19. package/s/driver/parts/compositor.ts +316 -0
  20. package/s/driver/parts/machina.ts +19 -20
  21. package/s/driver/utils/find-pixi-filter.ts +24 -0
  22. package/s/index.html.ts +103 -25
  23. package/s/index.ts +1 -0
  24. package/s/tests.bundle.ts +11 -0
  25. package/s/tests.html.ts +28 -0
  26. package/s/timeline/index.ts +8 -2
  27. package/s/timeline/parts/animations.ts +56 -0
  28. package/s/timeline/parts/filmstrip.ts +43 -16
  29. package/s/timeline/parts/filters.ts +453 -0
  30. package/s/timeline/parts/item.ts +70 -7
  31. package/s/timeline/parts/media.ts +12 -2
  32. package/s/timeline/parts/resource-pool.ts +8 -5
  33. package/s/timeline/parts/resource.ts +3 -0
  34. package/s/timeline/parts/waveform/parts/collect.ts +72 -0
  35. package/s/timeline/parts/waveform/parts/render.ts +45 -0
  36. package/s/timeline/parts/waveform/parts/types.ts +24 -0
  37. package/s/timeline/parts/waveform/waveform.ts +161 -0
  38. package/s/timeline/renderers/export/parts/audio-gain.ts +17 -0
  39. package/s/timeline/renderers/export/parts/audio-mix.ts +133 -0
  40. package/s/timeline/renderers/export/parts/cursor.ts +129 -0
  41. package/s/timeline/renderers/export/parts/produce-audio.ts +64 -0
  42. package/s/timeline/renderers/export/parts/produce-video.ts +49 -0
  43. package/s/timeline/renderers/export/parts/resamplers.ts +48 -0
  44. package/s/timeline/renderers/export/produce.ts +28 -0
  45. package/s/timeline/renderers/parts/handy.ts +377 -0
  46. package/s/timeline/renderers/parts/samplers/audio/parts/find.ts +19 -0
  47. package/s/timeline/renderers/parts/samplers/audio/parts/init.ts +60 -0
  48. package/s/timeline/renderers/parts/samplers/audio/parts/sink.ts +38 -0
  49. package/s/timeline/renderers/parts/samplers/audio/parts/types.ts +16 -0
  50. package/s/timeline/renderers/parts/samplers/audio/sampler.ts +35 -0
  51. package/s/timeline/renderers/parts/samplers/visual/parts/defaults.ts +16 -0
  52. package/s/timeline/renderers/parts/samplers/visual/parts/sample.ts +69 -0
  53. package/s/timeline/renderers/parts/samplers/visual/parts/sequence.ts +111 -0
  54. package/s/timeline/renderers/parts/samplers/visual/parts/sink.ts +38 -0
  55. package/s/timeline/renderers/parts/samplers/visual/parts/transition.ts +28 -0
  56. package/s/timeline/renderers/parts/samplers/visual/parts/types.ts +10 -0
  57. package/s/timeline/renderers/parts/samplers/visual/sampler.ts +28 -0
  58. package/s/timeline/renderers/parts/schedulers.ts +96 -0
  59. package/s/timeline/renderers/player/parts/playback.ts +159 -0
  60. package/s/timeline/renderers/player/player.ts +77 -0
  61. package/s/timeline/renderers/renderers.test.ts +385 -0
  62. package/s/timeline/sugar/helpers.ts +190 -0
  63. package/s/timeline/sugar/o.ts +271 -59
  64. package/s/timeline/sugar/omni.test.ts +210 -0
  65. package/s/timeline/sugar/omni.ts +35 -12
  66. package/s/timeline/types.ts +28 -3
  67. package/s/timeline/utils/anim.ts +71 -0
  68. package/s/timeline/utils/checksum.ts +3 -1
  69. package/s/timeline/utils/datafile.ts +15 -4
  70. package/s/timeline/utils/dummy-data.ts +3 -3
  71. package/s/timeline/utils/matrix.ts +21 -0
  72. package/s/timeline/utils/terps.ts +81 -0
  73. package/s/units/fps.ts +8 -0
  74. package/s/units/ms.ts +8 -0
  75. package/s/units/seconds.ts +8 -0
  76. package/x/WebGLRenderer-4CHIZDHY.js +2 -0
  77. package/x/WebGLRenderer-4CHIZDHY.js.map +7 -0
  78. package/x/WebGPURenderer-O6WXU2QR.js +2 -0
  79. package/x/WebGPURenderer-O6WXU2QR.js.map +7 -0
  80. package/x/browserAll-WNIOTNNP.js +2 -0
  81. package/x/browserAll-WNIOTNNP.js.map +7 -0
  82. package/x/chunk-23FOBGX6.js +2 -0
  83. package/x/chunk-23FOBGX6.js.map +7 -0
  84. package/x/chunk-73XOWA4F.js +393 -0
  85. package/x/chunk-73XOWA4F.js.map +7 -0
  86. package/x/chunk-IAWJKNX5.js +42 -0
  87. package/x/chunk-IAWJKNX5.js.map +7 -0
  88. package/x/chunk-KCMVLWBS.js +157 -0
  89. package/x/chunk-KCMVLWBS.js.map +7 -0
  90. package/x/chunk-MR32SQ27.js +2 -0
  91. package/x/chunk-MR32SQ27.js.map +7 -0
  92. package/x/chunk-VCUJJYRJ.js +327 -0
  93. package/x/chunk-VCUJJYRJ.js.map +7 -0
  94. package/x/chunk-XNIZ4L5W.js +269 -0
  95. package/x/chunk-XNIZ4L5W.js.map +7 -0
  96. package/x/chunk-ZLGNQFUI.js +15 -0
  97. package/x/chunk-ZLGNQFUI.js.map +7 -0
  98. package/x/context.d.ts +1 -4
  99. package/x/context.js +1 -5
  100. package/x/context.js.map +1 -1
  101. package/x/demo/WebGLRenderer-RSJAHIG2.js +2 -0
  102. package/x/demo/WebGLRenderer-RSJAHIG2.js.map +7 -0
  103. package/x/demo/WebGPURenderer-MGFAJCYY.js +2 -0
  104. package/x/demo/WebGPURenderer-MGFAJCYY.js.map +7 -0
  105. package/x/demo/browserAll-PTRBXBRP.js +2 -0
  106. package/x/demo/browserAll-PTRBXBRP.js.map +7 -0
  107. package/x/demo/chunk-CUYOGHWU.js +42 -0
  108. package/x/demo/chunk-CUYOGHWU.js.map +7 -0
  109. package/x/demo/chunk-DGTDNJ7W.js +2 -0
  110. package/x/demo/chunk-DGTDNJ7W.js.map +7 -0
  111. package/x/demo/chunk-FZ5BYF63.js +15 -0
  112. package/x/demo/chunk-FZ5BYF63.js.map +7 -0
  113. package/x/demo/chunk-KWN4NNES.js +269 -0
  114. package/x/demo/chunk-KWN4NNES.js.map +7 -0
  115. package/x/demo/chunk-OJ3FPXW7.js +157 -0
  116. package/x/demo/chunk-OJ3FPXW7.js.map +7 -0
  117. package/x/demo/chunk-PSLUOGTZ.js +393 -0
  118. package/x/demo/chunk-PSLUOGTZ.js.map +7 -0
  119. package/x/demo/chunk-VLCVEIFU.js +327 -0
  120. package/x/demo/chunk-VLCVEIFU.js.map +7 -0
  121. package/x/demo/chunk-ZWCPT5FR.js +2 -0
  122. package/x/demo/chunk-ZWCPT5FR.js.map +7 -0
  123. package/x/demo/demo.bundle.js +94 -40
  124. package/x/demo/demo.bundle.js.map +1 -1
  125. package/x/demo/demo.bundle.min.js +7340 -90
  126. package/x/demo/demo.bundle.min.js.map +4 -4
  127. package/x/demo/demo.css +244 -14
  128. package/x/demo/routines/export-test.d.ts +2 -0
  129. package/x/demo/routines/export-test.js +10 -0
  130. package/x/demo/routines/export-test.js.map +1 -0
  131. package/x/demo/routines/filmstrip-test.d.ts +1 -1
  132. package/x/demo/routines/filmstrip-test.js +20 -17
  133. package/x/demo/routines/filmstrip-test.js.map +1 -1
  134. package/x/demo/routines/load-video.d.ts +1 -1
  135. package/x/demo/routines/load-video.js +1 -2
  136. package/x/demo/routines/load-video.js.map +1 -1
  137. package/x/demo/routines/playback-test.d.ts +2 -0
  138. package/x/demo/routines/playback-test.js +51 -0
  139. package/x/demo/routines/playback-test.js.map +1 -0
  140. package/x/demo/routines/timeline-setup.d.ts +6 -0
  141. package/x/demo/routines/timeline-setup.js +32 -0
  142. package/x/demo/routines/timeline-setup.js.map +1 -0
  143. package/x/demo/routines/transcode-test.js +15 -5
  144. package/x/demo/routines/transcode-test.js.map +1 -1
  145. package/x/demo/routines/transitions-test.js +2 -2
  146. package/x/demo/routines/transitions-test.js.map +1 -1
  147. package/x/demo/routines/waveform-test.d.ts +2 -1
  148. package/x/demo/routines/waveform-test.js +29 -8
  149. package/x/demo/routines/waveform-test.js.map +1 -1
  150. package/x/demo/webworkerAll-JENRT6BT.js +2 -0
  151. package/x/demo/webworkerAll-JENRT6BT.js.map +7 -0
  152. package/x/driver/driver-worker.d.ts +1 -0
  153. package/x/driver/driver-worker.js +6 -0
  154. package/x/driver/driver-worker.js.map +1 -0
  155. package/x/driver/driver.d.ts +25 -8
  156. package/x/driver/driver.js +43 -39
  157. package/x/driver/driver.js.map +1 -1
  158. package/x/driver/driver.test.js +1 -1
  159. package/x/driver/driver.test.js.map +1 -1
  160. package/x/driver/driver.worker.bundle.min.js +117 -3506
  161. package/x/driver/driver.worker.bundle.min.js.map +4 -4
  162. package/x/driver/fns/host.d.ts +3 -2
  163. package/x/driver/fns/schematic.d.ts +25 -4
  164. package/x/driver/fns/work.d.ts +4 -4
  165. package/x/driver/fns/work.js +55 -155
  166. package/x/driver/fns/work.js.map +1 -1
  167. package/x/driver/parts/compositor.d.ts +39 -0
  168. package/x/driver/parts/compositor.js +261 -0
  169. package/x/driver/parts/compositor.js.map +1 -0
  170. package/x/driver/parts/machina.d.ts +0 -20
  171. package/x/driver/parts/machina.js +6 -10
  172. package/x/driver/parts/machina.js.map +1 -1
  173. package/x/driver/utils/find-pixi-filter.d.ts +5 -0
  174. package/x/driver/utils/find-pixi-filter.js +13 -0
  175. package/x/driver/utils/find-pixi-filter.js.map +1 -0
  176. package/x/features/speech/transcribe/parts/prep-audio.d.ts +1 -1
  177. package/x/features/speech/transcribe/worker.bundle.min.js +899 -899
  178. package/x/features/speech/transcribe/worker.bundle.min.js.map +4 -4
  179. package/x/index.d.ts +1 -0
  180. package/x/index.html +347 -38
  181. package/x/index.html.js +103 -24
  182. package/x/index.html.js.map +1 -1
  183. package/x/index.js +1 -0
  184. package/x/index.js.map +1 -1
  185. package/x/tests.bundle.js +8 -0
  186. package/x/tests.bundle.js.map +1 -0
  187. package/x/tests.bundle.min.js +7374 -0
  188. package/x/tests.bundle.min.js.map +7 -0
  189. package/x/tests.html +316 -0
  190. package/x/tests.html.d.ts +2 -0
  191. package/x/tests.html.js +22 -0
  192. package/x/tests.html.js.map +1 -0
  193. package/x/timeline/index.d.ts +7 -1
  194. package/x/timeline/index.js +7 -1
  195. package/x/timeline/index.js.map +1 -1
  196. package/x/timeline/parts/animations.d.ts +105 -0
  197. package/x/timeline/parts/animations.js +28 -0
  198. package/x/timeline/parts/animations.js.map +1 -0
  199. package/x/timeline/parts/filmstrip.d.ts +4 -3
  200. package/x/timeline/parts/filmstrip.js +29 -10
  201. package/x/timeline/parts/filmstrip.js.map +1 -1
  202. package/x/timeline/parts/filters.d.ts +108 -0
  203. package/x/timeline/parts/filters.js +340 -0
  204. package/x/timeline/parts/filters.js.map +1 -0
  205. package/x/timeline/parts/item.d.ts +56 -4
  206. package/x/timeline/parts/item.js +5 -1
  207. package/x/timeline/parts/item.js.map +1 -1
  208. package/x/timeline/parts/media.d.ts +2 -0
  209. package/x/timeline/parts/media.js +11 -2
  210. package/x/timeline/parts/media.js.map +1 -1
  211. package/x/timeline/parts/resource-pool.d.ts +3 -0
  212. package/x/timeline/parts/resource-pool.js +7 -4
  213. package/x/timeline/parts/resource-pool.js.map +1 -1
  214. package/x/timeline/parts/resource.d.ts +3 -0
  215. package/x/timeline/parts/waveform/parts/collect.d.ts +11 -0
  216. package/x/timeline/parts/waveform/parts/collect.js +56 -0
  217. package/x/timeline/parts/waveform/parts/collect.js.map +1 -0
  218. package/x/timeline/parts/waveform/parts/render.d.ts +5 -0
  219. package/x/timeline/parts/waveform/parts/render.js +29 -0
  220. package/x/timeline/parts/waveform/parts/render.js.map +1 -0
  221. package/x/timeline/parts/waveform/parts/types.d.ts +21 -0
  222. package/x/timeline/parts/waveform/parts/types.js.map +1 -0
  223. package/x/timeline/parts/waveform/waveform.d.ts +19 -0
  224. package/x/timeline/parts/waveform/waveform.js +133 -0
  225. package/x/timeline/parts/waveform/waveform.js.map +1 -0
  226. package/x/timeline/renderers/export/parts/audio-gain.d.ts +1 -0
  227. package/x/timeline/renderers/export/parts/audio-gain.js +13 -0
  228. package/x/timeline/renderers/export/parts/audio-gain.js.map +1 -0
  229. package/x/timeline/renderers/export/parts/audio-mix.d.ts +21 -0
  230. package/x/timeline/renderers/export/parts/audio-mix.js +89 -0
  231. package/x/timeline/renderers/export/parts/audio-mix.js.map +1 -0
  232. package/x/timeline/renderers/export/parts/cursor.d.ts +18 -0
  233. package/x/timeline/renderers/export/parts/cursor.js +99 -0
  234. package/x/timeline/renderers/export/parts/cursor.js.map +1 -0
  235. package/x/timeline/renderers/export/parts/produce-audio.d.ts +6 -0
  236. package/x/timeline/renderers/export/parts/produce-audio.js +41 -0
  237. package/x/timeline/renderers/export/parts/produce-audio.js.map +1 -0
  238. package/x/timeline/renderers/export/parts/produce-video.d.ts +10 -0
  239. package/x/timeline/renderers/export/parts/produce-video.js +26 -0
  240. package/x/timeline/renderers/export/parts/produce-video.js.map +1 -0
  241. package/x/timeline/renderers/export/parts/resamplers.d.ts +12 -0
  242. package/x/timeline/renderers/export/parts/resamplers.js +29 -0
  243. package/x/timeline/renderers/export/parts/resamplers.js.map +1 -0
  244. package/x/timeline/renderers/export/produce.d.ts +13 -0
  245. package/x/timeline/renderers/export/produce.js +15 -0
  246. package/x/timeline/renderers/export/produce.js.map +1 -0
  247. package/x/timeline/renderers/parts/handy.d.ts +36 -0
  248. package/x/timeline/renderers/parts/handy.js +221 -0
  249. package/x/timeline/renderers/parts/handy.js.map +1 -0
  250. package/x/timeline/renderers/parts/samplers/audio/parts/find.d.ts +6 -0
  251. package/x/timeline/renderers/parts/samplers/audio/parts/find.js +15 -0
  252. package/x/timeline/renderers/parts/samplers/audio/parts/find.js.map +1 -0
  253. package/x/timeline/renderers/parts/samplers/audio/parts/init.d.ts +5 -0
  254. package/x/timeline/renderers/parts/samplers/audio/parts/init.js +40 -0
  255. package/x/timeline/renderers/parts/samplers/audio/parts/init.js.map +1 -0
  256. package/x/timeline/renderers/parts/samplers/audio/parts/sink.d.ts +8 -0
  257. package/x/timeline/renderers/parts/samplers/audio/parts/sink.js +24 -0
  258. package/x/timeline/renderers/parts/samplers/audio/parts/sink.js.map +1 -0
  259. package/x/timeline/renderers/parts/samplers/audio/parts/types.d.ts +14 -0
  260. package/x/timeline/renderers/parts/samplers/audio/parts/types.js +2 -0
  261. package/x/timeline/renderers/parts/samplers/audio/parts/types.js.map +1 -0
  262. package/x/timeline/renderers/parts/samplers/audio/sampler.d.ts +11 -0
  263. package/x/timeline/renderers/parts/samplers/audio/sampler.js +22 -0
  264. package/x/timeline/renderers/parts/samplers/audio/sampler.js.map +1 -0
  265. package/x/timeline/renderers/parts/samplers/visual/parts/defaults.d.ts +5 -0
  266. package/x/timeline/renderers/parts/samplers/visual/parts/defaults.js +10 -0
  267. package/x/timeline/renderers/parts/samplers/visual/parts/defaults.js.map +1 -0
  268. package/x/timeline/renderers/parts/samplers/visual/parts/sample.d.ts +6 -0
  269. package/x/timeline/renderers/parts/samplers/visual/parts/sample.js +48 -0
  270. package/x/timeline/renderers/parts/samplers/visual/parts/sample.js.map +1 -0
  271. package/x/timeline/renderers/parts/samplers/visual/parts/sequence.d.ts +6 -0
  272. package/x/timeline/renderers/parts/samplers/visual/parts/sequence.js +75 -0
  273. package/x/timeline/renderers/parts/samplers/visual/parts/sequence.js.map +1 -0
  274. package/x/timeline/renderers/parts/samplers/visual/parts/sink.d.ts +8 -0
  275. package/x/timeline/renderers/parts/samplers/visual/parts/sink.js +24 -0
  276. package/x/timeline/renderers/parts/samplers/visual/parts/sink.js.map +1 -0
  277. package/x/timeline/renderers/parts/samplers/visual/parts/transition.d.ts +3 -0
  278. package/x/timeline/renderers/parts/samplers/visual/parts/transition.js +18 -0
  279. package/x/timeline/renderers/parts/samplers/visual/parts/transition.js.map +1 -0
  280. package/x/timeline/renderers/parts/samplers/visual/parts/types.d.ts +8 -0
  281. package/x/timeline/renderers/parts/samplers/visual/parts/types.js +2 -0
  282. package/x/timeline/renderers/parts/samplers/visual/parts/types.js.map +1 -0
  283. package/x/timeline/renderers/parts/samplers/visual/sampler.d.ts +7 -0
  284. package/x/timeline/renderers/parts/samplers/visual/sampler.js +17 -0
  285. package/x/timeline/renderers/parts/samplers/visual/sampler.js.map +1 -0
  286. package/x/timeline/renderers/parts/schedulers.d.ts +17 -0
  287. package/x/timeline/renderers/parts/schedulers.js +64 -0
  288. package/x/timeline/renderers/parts/schedulers.js.map +1 -0
  289. package/x/timeline/renderers/player/parts/playback.d.ts +36 -0
  290. package/x/timeline/renderers/player/parts/playback.js +113 -0
  291. package/x/timeline/renderers/player/parts/playback.js.map +1 -0
  292. package/x/timeline/renderers/player/player.d.ts +25 -0
  293. package/x/timeline/renderers/player/player.js +56 -0
  294. package/x/timeline/renderers/player/player.js.map +1 -0
  295. package/x/timeline/renderers/renderers.test.d.ts +32 -0
  296. package/x/timeline/renderers/renderers.test.js +305 -0
  297. package/x/timeline/renderers/renderers.test.js.map +1 -0
  298. package/x/timeline/sugar/helpers.d.ts +56 -0
  299. package/x/timeline/sugar/helpers.js +104 -0
  300. package/x/timeline/sugar/helpers.js.map +1 -0
  301. package/x/timeline/sugar/o.d.ts +48 -14
  302. package/x/timeline/sugar/o.js +213 -54
  303. package/x/timeline/sugar/o.js.map +1 -1
  304. package/x/timeline/sugar/omni.d.ts +11 -6
  305. package/x/timeline/sugar/omni.js +28 -8
  306. package/x/timeline/sugar/omni.js.map +1 -1
  307. package/x/timeline/sugar/omni.test.d.ts +27 -0
  308. package/x/timeline/sugar/omni.test.js +128 -0
  309. package/x/timeline/sugar/omni.test.js.map +1 -0
  310. package/x/timeline/types.d.ts +12 -2
  311. package/x/timeline/utils/anim.d.ts +5 -0
  312. package/x/timeline/utils/anim.js +44 -0
  313. package/x/timeline/utils/anim.js.map +1 -0
  314. package/x/timeline/utils/checksum.d.ts +3 -2
  315. package/x/timeline/utils/checksum.js.map +1 -1
  316. package/x/timeline/utils/datafile.d.ts +5 -3
  317. package/x/timeline/utils/datafile.js +18 -5
  318. package/x/timeline/utils/datafile.js.map +1 -1
  319. package/x/timeline/utils/dummy-data.d.ts +1 -2
  320. package/x/timeline/utils/dummy-data.js +4 -2
  321. package/x/timeline/utils/dummy-data.js.map +1 -1
  322. package/x/timeline/utils/matrix.d.ts +9 -0
  323. package/x/timeline/utils/matrix.js +10 -0
  324. package/x/timeline/utils/matrix.js.map +1 -1
  325. package/x/timeline/utils/terps.d.ts +11 -0
  326. package/x/timeline/utils/terps.js +57 -0
  327. package/x/timeline/utils/terps.js.map +1 -0
  328. package/x/units/fps.d.ts +6 -0
  329. package/x/units/fps.js +2 -0
  330. package/x/units/fps.js.map +1 -0
  331. package/x/units/ms.d.ts +6 -0
  332. package/x/units/ms.js +2 -0
  333. package/x/units/ms.js.map +1 -0
  334. package/x/units/seconds.d.ts +6 -0
  335. package/x/units/seconds.js +2 -0
  336. package/x/units/seconds.js.map +1 -0
  337. package/x/webworkerAll-RLCTMSDD.js +2 -0
  338. package/x/webworkerAll-RLCTMSDD.js.map +7 -0
  339. package/s/tests.test.ts +0 -8
  340. package/s/timeline/parts/compositor/export.ts +0 -77
  341. package/s/timeline/parts/compositor/parts/html-tree.ts +0 -37
  342. package/s/timeline/parts/compositor/parts/schedulers.ts +0 -85
  343. package/s/timeline/parts/compositor/parts/tree-builder.ts +0 -184
  344. package/s/timeline/parts/compositor/parts/webcodecs-tree.ts +0 -30
  345. package/s/timeline/parts/compositor/playback.ts +0 -81
  346. package/s/timeline/parts/compositor/samplers/html.ts +0 -115
  347. package/s/timeline/parts/compositor/samplers/webcodecs.ts +0 -60
  348. package/s/timeline/parts/waveform.ts +0 -62
  349. package/s/timeline/sugar/builders.ts +0 -102
  350. package/s/timeline/sugar/omni-test.ts +0 -38
  351. package/s/timeline/timeline.ts +0 -22
  352. package/s/timeline/utils/audio-stream.ts +0 -15
  353. package/s/timeline/utils/video-cursor.ts +0 -40
  354. package/s/tools/common/loader.ts +0 -26
  355. package/s/tools/common/transformer-pipeline.ts +0 -26
  356. package/s/tools/speech-recognition/common/model.ts +0 -26
  357. package/s/tools/speech-recognition/whisper/fns/host.ts +0 -25
  358. package/s/tools/speech-recognition/whisper/fns/schematic.ts +0 -23
  359. package/s/tools/speech-recognition/whisper/fns/work.ts +0 -91
  360. package/s/tools/speech-recognition/whisper/parts/types.ts +0 -38
  361. package/s/tools/speech-recognition/whisper/parts/worker.bundle.ts +0 -7
  362. package/s/tools/speech-recognition/whisper/tool.ts +0 -70
  363. package/x/tests.test.js +0 -6
  364. package/x/tests.test.js.map +0 -1
  365. package/x/timeline/parts/compositor/export.d.ts +0 -9
  366. package/x/timeline/parts/compositor/export.js +0 -64
  367. package/x/timeline/parts/compositor/export.js.map +0 -1
  368. package/x/timeline/parts/compositor/parts/html-tree.d.ts +0 -3
  369. package/x/timeline/parts/compositor/parts/html-tree.js +0 -40
  370. package/x/timeline/parts/compositor/parts/html-tree.js.map +0 -1
  371. package/x/timeline/parts/compositor/parts/schedulers.d.ts +0 -15
  372. package/x/timeline/parts/compositor/parts/schedulers.js +0 -64
  373. package/x/timeline/parts/compositor/parts/schedulers.js.map +0 -1
  374. package/x/timeline/parts/compositor/parts/tree-builder.d.ts +0 -37
  375. package/x/timeline/parts/compositor/parts/tree-builder.js +0 -147
  376. package/x/timeline/parts/compositor/parts/tree-builder.js.map +0 -1
  377. package/x/timeline/parts/compositor/parts/webcodecs-tree.d.ts +0 -3
  378. package/x/timeline/parts/compositor/parts/webcodecs-tree.js +0 -28
  379. package/x/timeline/parts/compositor/parts/webcodecs-tree.js.map +0 -1
  380. package/x/timeline/parts/compositor/playback.d.ts +0 -19
  381. package/x/timeline/parts/compositor/playback.js +0 -71
  382. package/x/timeline/parts/compositor/playback.js.map +0 -1
  383. package/x/timeline/parts/compositor/samplers/html.d.ts +0 -3
  384. package/x/timeline/parts/compositor/samplers/html.js +0 -106
  385. package/x/timeline/parts/compositor/samplers/html.js.map +0 -1
  386. package/x/timeline/parts/compositor/samplers/webcodecs.d.ts +0 -2
  387. package/x/timeline/parts/compositor/samplers/webcodecs.js +0 -55
  388. package/x/timeline/parts/compositor/samplers/webcodecs.js.map +0 -1
  389. package/x/timeline/parts/waveform.d.ts +0 -8
  390. package/x/timeline/parts/waveform.js +0 -51
  391. package/x/timeline/parts/waveform.js.map +0 -1
  392. package/x/timeline/sugar/builders.d.ts +0 -96
  393. package/x/timeline/sugar/builders.js +0 -108
  394. package/x/timeline/sugar/builders.js.map +0 -1
  395. package/x/timeline/sugar/omni-test.d.ts +0 -1
  396. package/x/timeline/sugar/omni-test.js +0 -22
  397. package/x/timeline/sugar/omni-test.js.map +0 -1
  398. package/x/timeline/timeline.d.ts +0 -9
  399. package/x/timeline/timeline.js +0 -22
  400. package/x/timeline/timeline.js.map +0 -1
  401. package/x/timeline/utils/audio-stream.d.ts +0 -6
  402. package/x/timeline/utils/audio-stream.js +0 -17
  403. package/x/timeline/utils/audio-stream.js.map +0 -1
  404. package/x/timeline/utils/video-cursor.d.ts +0 -10
  405. package/x/timeline/utils/video-cursor.js +0 -36
  406. package/x/timeline/utils/video-cursor.js.map +0 -1
  407. package/x/tools/common/loader.d.ts +0 -19
  408. package/x/tools/common/loader.js +0 -18
  409. package/x/tools/common/loader.js.map +0 -1
  410. package/x/tools/common/transformer-pipeline.d.ts +0 -8
  411. package/x/tools/common/transformer-pipeline.js +0 -24
  412. package/x/tools/common/transformer-pipeline.js.map +0 -1
  413. package/x/tools/speech-recognition/common/model.d.ts +0 -14
  414. package/x/tools/speech-recognition/common/model.js +0 -16
  415. package/x/tools/speech-recognition/common/model.js.map +0 -1
  416. package/x/tools/speech-recognition/whisper/fns/host.d.ts +0 -13
  417. package/x/tools/speech-recognition/whisper/fns/host.js +0 -19
  418. package/x/tools/speech-recognition/whisper/fns/host.js.map +0 -1
  419. package/x/tools/speech-recognition/whisper/fns/schematic.d.ts +0 -19
  420. package/x/tools/speech-recognition/whisper/fns/schematic.js +0 -2
  421. package/x/tools/speech-recognition/whisper/fns/schematic.js.map +0 -1
  422. package/x/tools/speech-recognition/whisper/fns/work.d.ts +0 -12
  423. package/x/tools/speech-recognition/whisper/fns/work.js +0 -74
  424. package/x/tools/speech-recognition/whisper/fns/work.js.map +0 -1
  425. package/x/tools/speech-recognition/whisper/parts/types.d.ts +0 -31
  426. package/x/tools/speech-recognition/whisper/parts/types.js.map +0 -1
  427. package/x/tools/speech-recognition/whisper/parts/worker.bundle.d.ts +0 -1
  428. package/x/tools/speech-recognition/whisper/parts/worker.bundle.js +0 -4
  429. package/x/tools/speech-recognition/whisper/parts/worker.bundle.js.map +0 -1
  430. package/x/tools/speech-recognition/whisper/parts/worker.bundle.min.js +0 -8
  431. package/x/tools/speech-recognition/whisper/parts/worker.bundle.min.js.map +0 -7
  432. package/x/tools/speech-recognition/whisper/tool.d.ts +0 -12
  433. package/x/tools/speech-recognition/whisper/tool.js +0 -63
  434. package/x/tools/speech-recognition/whisper/tool.js.map +0 -1
  435. /package/x/{tests.test.d.ts → tests.bundle.d.ts} +0 -0
  436. /package/x/{tools/speech-recognition/whisper → timeline/parts/waveform}/parts/types.js +0 -0
@@ -0,0 +1,64 @@
1
+
2
+ import {AudioMix} from "./audio-mix.js"
3
+ import {ms} from "../../../../units/ms.js"
4
+ import {resampleToPlanar} from "./resamplers.js"
5
+ import {applyGainToPlanar} from "./audio-gain.js"
6
+ import {TimelineFile} from "../../../parts/basics.js"
7
+ import {DecoderSource} from "../../../../driver/fns/schematic.js"
8
+ import {createAudioSampler} from "../../parts/samplers/audio/sampler.js"
9
+
10
+ export function produceAudio({
11
+ timeline,
12
+ resolveMedia
13
+ }: {
14
+ timeline: TimelineFile,
15
+ resolveMedia: (hash: string) => DecoderSource
16
+ }) {
17
+ const mixer = new AudioMix()
18
+ const audio = streamAudio(timeline, resolveMedia)
19
+ const stream = new TransformStream<AudioData, AudioData>()
20
+ const writer = stream.writable.getWriter()
21
+
22
+ async function produce() {
23
+ for await (const chunk of mixer.mix(audio)) {
24
+ const data = new AudioData({
25
+ format: 'f32-planar',
26
+ sampleRate: chunk.sampleRate,
27
+ numberOfFrames: chunk.frames,
28
+ numberOfChannels: chunk.channels,
29
+ timestamp: Math.round(
30
+ (chunk.startFrame / chunk.sampleRate) * 1_000_000
31
+ ),
32
+ data: new Float32Array(chunk.planar)
33
+ })
34
+
35
+ await writer.write(data)
36
+ }
37
+
38
+ await writer.close()
39
+ }
40
+
41
+ produce()
42
+
43
+ return stream.readable
44
+ }
45
+
46
+ async function *streamAudio(timeline: TimelineFile, resolveMedia: (hash: string) => DecoderSource) {
47
+ const audioSampler = createAudioSampler(resolveMedia)
48
+
49
+ for await (const {sample, timestamp, gain}
50
+ of audioSampler.sampleAudio(timeline, ms(0))) {
51
+
52
+ const {data} = resampleToPlanar(sample, 48000)
53
+ applyGainToPlanar(data, gain)
54
+
55
+ yield {
56
+ planes: data,
57
+ sampleRate: 48000,
58
+ timestamp
59
+ }
60
+
61
+ sample.close()
62
+ }
63
+ }
64
+
@@ -0,0 +1,49 @@
1
+
2
+ import {Fps} from "../../../../units/fps.js"
3
+ import {CursorVisualSampler} from "./cursor.js"
4
+ import {Driver} from "../../../../driver/driver.js"
5
+ import {fixedStep} from "../../parts/schedulers.js"
6
+ import {TimelineFile} from "../../../parts/basics.js"
7
+ import {computeItemDuration} from "../../parts/handy.js"
8
+ import {DecoderSource} from "../../../../driver/fns/schematic.js"
9
+
10
+ export function produceVideo({
11
+ timeline,
12
+ fps,
13
+ driver,
14
+ resolveMedia,
15
+ }: {
16
+ driver: Driver
17
+ resolveMedia: (hash: string) => DecoderSource
18
+ timeline: TimelineFile
19
+ fps: Fps
20
+ }) {
21
+
22
+ const stream = new TransformStream<VideoFrame, VideoFrame>()
23
+ const writer = stream.writable.getWriter()
24
+ const sampler = new CursorVisualSampler(driver, resolveMedia, timeline)
25
+ const dt = 1 / fps
26
+ const duration = computeItemDuration(timeline.rootId, timeline)
27
+
28
+ async function produce() {
29
+ await fixedStep({fps, duration}, async (timecode, i) => {
30
+ const layers = await sampler.next(timecode)
31
+ const composed = await driver.composite(layers)
32
+
33
+ const frame = new VideoFrame(composed, {
34
+ timestamp: Math.round(i * dt * 1_000_000),
35
+ duration: Math.round(dt * 1_000_000)
36
+ })
37
+
38
+ await writer.write(frame)
39
+ composed.close()
40
+ })
41
+
42
+ await writer.close()
43
+ }
44
+
45
+ produce()
46
+
47
+ return stream.readable
48
+ }
49
+
@@ -0,0 +1,48 @@
1
+
2
+ const resampleLinear = (
3
+ src: Float32Array,
4
+ fromRate: number,
5
+ targetRate: number
6
+ ) => {
7
+ if (fromRate === targetRate)
8
+ return src
9
+
10
+ const ratio = targetRate / fromRate
11
+ const outFrames = Math.max(1, Math.round(src.length * ratio))
12
+ const out = new Float32Array(outFrames)
13
+
14
+ for (let i = 0; i < outFrames; i++) {
15
+ const t = i / ratio
16
+ const i0 = Math.floor(t)
17
+ const i1 = Math.min(i0 + 1, src.length - 1)
18
+ const frac = t - i0
19
+ out[i] = src[i0] * (1 - frac) + src[i1] * frac
20
+ }
21
+
22
+ return out
23
+ }
24
+
25
+ export const resampleToPlanar = (
26
+ sample: {
27
+ numberOfFrames: number
28
+ numberOfChannels: number
29
+ sampleRate: number
30
+ copyTo: (dest: Float32Array, options: {planeIndex: number; format: 'f32-planar'}) => void
31
+ },
32
+ targetRate: number
33
+ ): {data: Float32Array[]; frames: number} => {
34
+ const channels = sample.numberOfChannels
35
+ const data = new Array<Float32Array>(channels)
36
+ let frames = 0
37
+
38
+ for (let ch = 0; ch < channels; ch++) {
39
+ const plane = new Float32Array(sample.numberOfFrames)
40
+ sample.copyTo(plane, {planeIndex: ch, format: 'f32-planar'})
41
+ const resampled = resampleLinear(plane, sample.sampleRate, targetRate)
42
+ data[ch] = resampled
43
+ frames = resampled.length
44
+ }
45
+
46
+ return {data, frames}
47
+ }
48
+
@@ -0,0 +1,28 @@
1
+
2
+ import {Fps} from "../../../units/fps.js"
3
+ import {Driver} from "../../../driver/driver.js"
4
+ import {TimelineFile} from "../../parts/basics.js"
5
+ import {produceAudio} from "./parts/produce-audio.js"
6
+ import {produceVideo} from "./parts/produce-video.js"
7
+ import {DecoderSource} from "../../../driver/fns/schematic.js"
8
+
9
+ export function produce(opts: {
10
+ timeline: TimelineFile
11
+ fps: Fps
12
+ driver: Driver
13
+ resolveMedia: (hash: string) => DecoderSource
14
+ }) {
15
+
16
+ const audio = produceAudio({...opts})
17
+ const video = produceVideo({...opts})
18
+
19
+ return opts.driver.encode({
20
+ video,
21
+ audio,
22
+ config: {
23
+ audio: {codec: 'opus', bitrate: 128000},
24
+ video: {codec: 'vp9', bitrate: 1000000}
25
+ }
26
+ })
27
+ }
28
+
@@ -0,0 +1,377 @@
1
+
2
+ import {ms, Ms} from '../../../units/ms.js'
3
+ import {Id, TimelineFile} from '../../parts/basics.js'
4
+ import { SampleContext } from './samplers/visual/parts/types.js'
5
+ import {I6, Mat6, mul6, transformToMat6} from '../../utils/matrix.js'
6
+ import {resolveScalarAnimation, resolveSpatialTransform} from '../../utils/anim.js'
7
+ import {ContainerItem, Item, Kind, PlayableItem, SpatialItem} from '../../parts/item.js'
8
+
9
+ function isPlayableItem(item: Item.Any): item is PlayableItem {
10
+ return 'duration' in item
11
+ }
12
+
13
+ type WalkAtCallbacks = {
14
+ sequence: (x: Item.Sequence, localTime: Ms, ancestors: AncestorAt[]) => void
15
+ stack: (x: Item.Stack, localTime: Ms, ancestors: AncestorAt[]) => void
16
+ video: (x: Item.Video, localTime: Ms, ancestors: AncestorAt[]) => void
17
+ text: (x: Item.Text, localTime: Ms, ancestors: AncestorAt[]) => void
18
+ audio: (x: Item.Audio, localTime: Ms, ancestors: AncestorAt[]) => void
19
+ }
20
+
21
+ type WalkCallbacks = {
22
+ sequence?: (x: Item.Sequence, matrix: Mat6, ancestors: AncestorAt[]) => void
23
+ stack?: (x: Item.Stack, matrix: Mat6, ancestors: AncestorAt[]) => void
24
+ video?: (x: Item.Video, matrix: Mat6, ancestors: AncestorAt[]) => void
25
+ text?: (x: Item.Text, matrix: Mat6, ancestors: AncestorAt[]) => void
26
+ audio?: (x: Item.Audio) => void
27
+ }
28
+
29
+ interface Props {
30
+ timeline: TimelineFile
31
+ timecode: Ms
32
+ }
33
+
34
+ export interface AncestorAt {
35
+ item: ContainerItem
36
+ localTime: Ms
37
+ }
38
+
39
+ interface At {
40
+ item: Item.Any
41
+ localTime: Ms
42
+ ancestors: AncestorAt[]
43
+ }
44
+
45
+ export function itemsAt(p: Props): At[] {
46
+ const results: At[] = []
47
+ const itemMap = new Map(p.timeline.items.map(item => [item.id, item]))
48
+
49
+ walkAt(p.timeline.rootId, itemMap, p.timecode, {
50
+ sequence: () => { },
51
+ stack: () => { },
52
+ video: (item, localTime, ancestors) => results.push({ item, localTime, ancestors }),
53
+ text: (item, localTime, ancestors) => results.push({ item, localTime, ancestors }),
54
+ audio: (item, localTime, ancestors) => results.push({ item, localTime, ancestors })
55
+ })
56
+
57
+ return results
58
+ }
59
+
60
+ interface FromProps {
61
+ timeline: TimelineFile
62
+ from: Ms
63
+ }
64
+
65
+ export function itemsFrom(p: FromProps): At[] {
66
+ const results: At[] = []
67
+ const itemMap = new Map(p.timeline.items.map(item => [item.id, item]))
68
+
69
+ walkFrom(p.timeline.rootId, itemMap, p.from, {
70
+ sequence: () => { },
71
+ stack: () => { },
72
+ video: (item, localTime, ancestors) => results.push({ item, localTime, ancestors }),
73
+ text: (item, localTime, ancestors) => results.push({ item, localTime, ancestors }),
74
+ audio: (item, localTime, ancestors) => results.push({ item, localTime, ancestors })
75
+ })
76
+
77
+ return results
78
+ }
79
+
80
+ export function computeWorldMatrix(
81
+ items: Map<Id, Item.Any>,
82
+ ancestors: AncestorAt[],
83
+ item: Item.Any,
84
+ localTime: Ms,
85
+ ): Mat6 {
86
+ let world = I6
87
+
88
+ for (const ancestor of ancestors) {
89
+ world = applySpatialIfAny(items, ancestor.item, world, ancestor.localTime)
90
+ }
91
+
92
+ return applySpatialIfAny(items, item, world, localTime)
93
+ }
94
+
95
+ function applySpatialIfAny(
96
+ items: Map<Id, Item.Any>,
97
+ item: Item.Any,
98
+ parentMatrix: Mat6,
99
+ time: Ms,
100
+ ) {
101
+ if ("spatialId" in item && item.spatialId) {
102
+ const spatial = items.get(item.spatialId) as SpatialItem | undefined
103
+ if (spatial?.enabled) {
104
+ const local = transformToMat6(resolveSpatialTransform(spatial, time))
105
+ return mul6(local, parentMatrix)
106
+ }
107
+ }
108
+ return parentMatrix
109
+ }
110
+
111
+ export function walk(
112
+ id: Id,
113
+ items: Map<Id, Item.Any>,
114
+ parentMatrix: Mat6,
115
+ localTime: Ms,
116
+ callbacks: WalkCallbacks,
117
+ ancestors: AncestorAt[] = []
118
+ ) {
119
+ const item = items.get(id)
120
+ if (!item) return
121
+
122
+ const currentMatrix = applySpatialIfAny(items, item, parentMatrix, localTime)
123
+
124
+ switch (item.kind) {
125
+ case Kind.Stack:
126
+ callbacks.stack?.(item, currentMatrix, ancestors)
127
+ for (const childId of item.childrenIds) {
128
+ walk(childId, items, currentMatrix, localTime, callbacks, [...ancestors, {item, localTime}])
129
+ }
130
+ break
131
+
132
+ case Kind.Sequence: {
133
+ callbacks.sequence?.(item, currentMatrix, ancestors)
134
+
135
+ for (const childId of item.childrenIds) {
136
+ const child = items.get(childId)
137
+
138
+ if (!child)
139
+ continue
140
+ if (!isPlayableItem(child)) {
141
+ continue
142
+ }
143
+
144
+ walk(
145
+ childId,
146
+ items,
147
+ currentMatrix,
148
+ localTime,
149
+ callbacks,
150
+ [...ancestors, {item, localTime}]
151
+ )
152
+ }
153
+
154
+ break
155
+ }
156
+
157
+ case Kind.Video:
158
+ callbacks.video?.(item, currentMatrix, ancestors)
159
+ break
160
+
161
+ case Kind.Text:
162
+ callbacks.text?.(item, currentMatrix, ancestors)
163
+ break
164
+
165
+ case Kind.Audio:
166
+ callbacks.audio?.(item)
167
+ break
168
+ }
169
+ }
170
+
171
+
172
+ function walkAt(
173
+ id: Id,
174
+ items: Map<Id, Item.Any>,
175
+ time: Ms,
176
+ callbacks: WalkAtCallbacks,
177
+ ancestors: AncestorAt[] = []
178
+ ) {
179
+ const item = items.get(id)
180
+ if (!item) return
181
+
182
+ switch (item.kind) {
183
+ case Kind.Stack:
184
+ callbacks.stack(item, time, ancestors)
185
+ for (const childId of item.childrenIds) {
186
+ walkAt(childId, items, time, callbacks, [...ancestors, {item, localTime: time}])
187
+ }
188
+ break
189
+
190
+ case Kind.Sequence: {
191
+ callbacks.sequence(item, time, ancestors)
192
+
193
+ let offset = ms(0)
194
+
195
+ for (const childId of item.childrenIds) {
196
+ const child = items.get(childId)
197
+
198
+ if (!child)
199
+ continue
200
+ if (!isPlayableItem(child)) {
201
+ continue
202
+ }
203
+
204
+ if (time >= offset && time < offset + child.duration) {
205
+ const localTime = ms(time - offset)
206
+ walkAt(
207
+ childId,
208
+ items,
209
+ localTime,
210
+ callbacks,
211
+ [...ancestors, {item, localTime: time}]
212
+ )
213
+ break
214
+ }
215
+
216
+ offset = ms(offset + child.duration)
217
+ }
218
+
219
+ break
220
+ }
221
+
222
+ case Kind.Video:
223
+ callbacks.video(item, time, ancestors)
224
+ break
225
+
226
+ case Kind.Text:
227
+ callbacks.text(item, time, ancestors)
228
+ break
229
+
230
+ case Kind.Audio:
231
+ callbacks.audio(item, time, ancestors)
232
+ break
233
+ }
234
+ }
235
+
236
+ function walkFrom(
237
+ id: Id,
238
+ items: Map<Id, Item.Any>,
239
+ from: Ms,
240
+ callbacks: WalkAtCallbacks,
241
+ ancestors: AncestorAt[] = []
242
+ ) {
243
+ const item = items.get(id)
244
+ if (!item) return
245
+
246
+ switch (item.kind) {
247
+ case Kind.Stack:
248
+ callbacks.stack(item, from, ancestors)
249
+ for (const childId of item.childrenIds) {
250
+ walkFrom(childId, items, from, callbacks, [...ancestors, {item, localTime: from}])
251
+ }
252
+ break
253
+
254
+ case Kind.Sequence: {
255
+ callbacks.sequence(item, from, ancestors)
256
+
257
+ let offset = ms(0)
258
+
259
+ for (const childId of item.childrenIds) {
260
+ const child = items.get(childId)
261
+
262
+ if (!child)
263
+ continue
264
+ if (!isPlayableItem(child)) {
265
+ continue
266
+ }
267
+
268
+ const end = ms(offset + child.duration)
269
+ if (from >= end) {
270
+ offset = end
271
+ continue
272
+ }
273
+
274
+ const localTime = ms(Math.max(0, from - offset))
275
+ walkFrom(
276
+ childId,
277
+ items,
278
+ localTime,
279
+ callbacks,
280
+ [...ancestors, {item, localTime: from}]
281
+ )
282
+
283
+ offset = end
284
+ }
285
+
286
+ break
287
+ }
288
+
289
+ case Kind.Video:
290
+ callbacks.video(item, from, ancestors)
291
+ break
292
+
293
+ case Kind.Text:
294
+ callbacks.text(item, from, ancestors)
295
+ break
296
+
297
+ case Kind.Audio:
298
+ callbacks.audio(item, from, ancestors)
299
+ break
300
+ }
301
+ }
302
+
303
+ export function computeItemDuration(
304
+ id: number,
305
+ timeline: TimelineFile
306
+ ): Ms {
307
+ const item = timeline.items.find(item => item.id === id)
308
+
309
+ if (!item) return ms(0)
310
+
311
+ switch (item.kind) {
312
+ case Kind.Sequence: {
313
+ const children = item.childrenIds
314
+ .map(childId => timeline.items.find(x => x.id === childId))
315
+ .filter(Boolean) as Item.Any[]
316
+
317
+ let total = ms(0)
318
+
319
+ for (let i = 0; i < children.length; i++) {
320
+ const child = children[i]
321
+
322
+ if (child.kind === Kind.Transition) {
323
+ const prev = children[i - 1]
324
+ const next = children[i + 1]
325
+
326
+ if (prev && next && prev.kind !== Kind.Transition && next.kind !== Kind.Transition) {
327
+ const prevDur = computeItemDuration(prev.id, timeline)
328
+ const nextDur = computeItemDuration(next.id, timeline)
329
+ const overlap = Math.max(0, Math.min(child.duration, prevDur, nextDur))
330
+
331
+ total = ms(total - overlap)
332
+ }
333
+ continue
334
+ }
335
+
336
+ total = ms(total + computeItemDuration(child.id, timeline))
337
+ }
338
+
339
+ return total
340
+ }
341
+
342
+ case Kind.Stack: {
343
+ let longest = ms(0)
344
+
345
+ for (const childId of item.childrenIds) {
346
+ const duration = computeItemDuration(childId, timeline)
347
+ if (duration > longest) {
348
+ longest = duration
349
+ }
350
+ }
351
+
352
+ return longest
353
+ }
354
+
355
+ default: {
356
+ if (!isPlayableItem(item))
357
+ return ms(0)
358
+
359
+ return item.duration
360
+ }
361
+ }
362
+ }
363
+
364
+ export function computeOpacity(
365
+ ctx: SampleContext,
366
+ item: Item.Any,
367
+ time: Ms,
368
+ ) {
369
+ if (!("animationId" in item) || item.animationId === undefined)
370
+ return 1
371
+
372
+ const animation = ctx.items.get(item.animationId) as Item.Animation | undefined
373
+ return animation?.enabled && animation.anims.opacity
374
+ ? resolveScalarAnimation(time, animation.anims.opacity)
375
+ : 1
376
+ }
377
+
@@ -0,0 +1,19 @@
1
+
2
+ import {ActiveStream} from "./types.js"
3
+
4
+ export function findEarliestStream(streams: ActiveStream[]) {
5
+ let earliest = {
6
+ index: 0,
7
+ stream: streams[0],
8
+ time: streams[0].timelineTime()
9
+ }
10
+
11
+ for (const [index, stream] of streams.entries()) {
12
+ const time = stream.timelineTime()
13
+ if (time < earliest.time) {
14
+ earliest = {time, stream, index}
15
+ }
16
+ }
17
+
18
+ return earliest
19
+ }
@@ -0,0 +1,60 @@
1
+
2
+ import {AudioSinkPool} from "./sink.js"
3
+ import {ActiveStream} from "./types.js"
4
+ import {itemsFrom} from "../../../handy.js"
5
+ import {Ms} from "../../../../../../units/ms.js"
6
+ import {Kind} from "../../../../../parts/item.js"
7
+ import {seconds} from "../../../../../../units/seconds.js"
8
+
9
+ export async function initStreams(
10
+ pool: AudioSinkPool,
11
+ items: ReturnType<typeof itemsFrom>,
12
+ from: Ms
13
+ ): Promise<ActiveStream[]> {
14
+ const streams = await Promise.all(
15
+ items.map(async ({item, localTime}) => {
16
+ if (item.kind !== Kind.Audio)
17
+ return
18
+
19
+ const sink = await pool.getSink(item.mediaHash)
20
+ if (!sink)
21
+ return
22
+
23
+ const mediaTime = item.start + localTime
24
+ const offset = seconds((from - mediaTime) / 1000)
25
+ const iter = sink.samples(mediaTime / 1000)
26
+
27
+ const first = await iter.next()
28
+ if (first.done)
29
+ return
30
+
31
+ let currentSample = first.value
32
+ let nextPromise = iter.next()
33
+
34
+ return {
35
+ offset,
36
+ gain: item.gain ?? 1,
37
+ get currentSample() {return currentSample},
38
+ timelineTime: () => seconds(offset + currentSample.timestamp),
39
+ output: () => ({
40
+ sample: currentSample,
41
+ timestamp: offset + currentSample.timestamp,
42
+ gain: item.gain ?? 1
43
+ }),
44
+ advance: async () => {
45
+ const result = await nextPromise
46
+ if (result.done)
47
+ return false
48
+
49
+ currentSample = result.value
50
+ nextPromise = iter.next()
51
+
52
+ return true
53
+ }
54
+ }
55
+ })
56
+ )
57
+
58
+ return streams.filter((stream): stream is ActiveStream => !!stream)
59
+ }
60
+
@@ -0,0 +1,38 @@
1
+
2
+ import {ALL_FORMATS, Input, AudioSampleSink} from "mediabunny"
3
+
4
+ import {DecoderSource} from "../../../../../../driver/fns/schematic.js"
5
+ import {loadDecoderSource} from "../../../../../../driver/utils/load-decoder-source.js"
6
+
7
+ type SinkState = {
8
+ input: Input
9
+ sink: AudioSampleSink | null
10
+ }
11
+
12
+ export class AudioSinkPool {
13
+ readonly #sinks = new Map<string, SinkState>()
14
+
15
+ constructor(
16
+ private resolveMedia: (hash: string) => DecoderSource
17
+ ) {}
18
+
19
+ async getSink(hash: string) {
20
+ const existing = this.#sinks.get(hash)
21
+
22
+ if (existing)
23
+ return existing.sink
24
+
25
+ const input = new Input({
26
+ formats: ALL_FORMATS,
27
+ source: await loadDecoderSource(this.resolveMedia(hash)),
28
+ })
29
+
30
+ const audioTrack = await input.getPrimaryAudioTrack()
31
+ const canDecodeAudio = !!audioTrack && await audioTrack.canDecode()
32
+ const sink = canDecodeAudio && audioTrack ? new AudioSampleSink(audioTrack) : null
33
+
34
+ this.#sinks.set(hash, {input, sink})
35
+
36
+ return sink
37
+ }
38
+ }
@@ -0,0 +1,16 @@
1
+
2
+ import {AudioSample} from "mediabunny"
3
+ import {Seconds} from "../../../../../../units/seconds.js"
4
+
5
+ export type ActiveStream = {
6
+ offset: Seconds
7
+ gain: number
8
+ currentSample: AudioSample
9
+ timelineTime: () => Seconds
10
+ output: () => {
11
+ sample: AudioSample
12
+ timestamp: number
13
+ gain: number
14
+ }
15
+ advance: () => Promise<boolean>
16
+ }