@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,385 @@
1
+
2
+ import {Science, test, expect} from "@e280/science"
3
+
4
+ import {O} from "../sugar/o.js"
5
+ import {ms} from "../../units/ms.js"
6
+ import {Omni} from "../sugar/omni.js"
7
+ import {fps} from "../../units/fps.js"
8
+ import {Datafile} from "../utils/datafile.js"
9
+ import {Driver} from "../../driver/driver.js"
10
+ import {AudioMix} from "./export/parts/audio-mix.js"
11
+ import {produceAudio} from "./export/parts/produce-audio.js"
12
+ import {resampleToPlanar} from "./export/parts/resamplers.js"
13
+ import {loadVideo} from "../../demo/routines/load-video.js"
14
+ import {produceVideo} from "./export/parts/produce-video.js"
15
+ import {CursorVisualSampler} from "./export/parts/cursor.js"
16
+ import {applyGainToPlanar} from "./export/parts/audio-gain.js"
17
+ import {createVisualSampler} from "./parts/samplers/visual/sampler.js"
18
+
19
+ const workerUrl = new URL("../driver/driver.worker.bundle.min.js", import.meta.url)
20
+ export async function setupTest() {
21
+ const driver = await Driver.setup({workerUrl})
22
+ const omni = new Omni(driver)
23
+
24
+ const testVideo = await loadVideo("/assets/temp/test.mp4")
25
+ const {videoA} = await omni.load({videoA: Datafile.make(testVideo, "test.mp4")})
26
+
27
+ const resolveMedia = (hash: string) => omni.resources.require(hash).blob
28
+
29
+ return {driver, omni, testVideo, videoA, resolveMedia}
30
+ }
31
+
32
+ async function collect<T>(iterable: AsyncIterable<T>) {
33
+ const out: T[] = []
34
+ for await (const item of iterable)
35
+ out.push(item)
36
+ return out
37
+ }
38
+
39
+ const near = (actual: number, expected: number, eps = 1e-6) =>
40
+ Math.abs(actual - expected) < eps
41
+
42
+ export default Science.suite({
43
+
44
+ "cursor visual sampler cannot get previous samples": test(async () => {
45
+ const {omni, videoA, resolveMedia, driver} = await setupTest()
46
+ const {timeline} = new O({timeline: omni.timeline(o => o.sequence(
47
+ o.video(videoA, {duration: 2000}),
48
+ o.gap(500),
49
+ o.video(videoA, {duration: 2000}),
50
+ o.audio(videoA, {duration: 500}),
51
+ ))})
52
+ const cursor = new CursorVisualSampler(driver, resolveMedia, timeline)
53
+ await cursor.next(ms(1000))
54
+ await expect(async () => await cursor.next(ms(100))).throwsAsync()
55
+ }),
56
+
57
+ "visual sampler gives correct layer at x time": test(async () => {
58
+ const {omni, videoA, resolveMedia} = await setupTest()
59
+ const {timeline} = new O({timeline: omni.timeline(o => o.sequence(
60
+ o.video(videoA, {duration: 2000}),
61
+ o.gap(500),
62
+ o.video(videoA, {duration: 2000}),
63
+ o.audio(videoA, {duration: 500}),
64
+ o.text("123", {duration: 1000})
65
+ ))})
66
+ const sampler = createVisualSampler(resolveMedia)
67
+ const imgLayer = await sampler.sample(timeline, ms(1000))
68
+ expect(imgLayer[0].kind).is("image")
69
+ const gapLayer = await sampler.sample(timeline, ms(2300))
70
+ expect(gapLayer[0].kind).is("gap")
71
+ const imgLayer1 = await sampler.sample(timeline, ms(2700))
72
+ expect(imgLayer1[0].kind).is("image")
73
+ const textLayer = await sampler.sample(timeline, ms(5500))
74
+ expect(textLayer[0].kind).is("text")
75
+ }),
76
+
77
+ "audio mix sums overlapping chunks": test(async () => {
78
+ const mixer = new AudioMix({chunkFrames: 4, clamp: false})
79
+ async function *samples() {
80
+ yield {
81
+ planes: [new Float32Array([0.25, 0.25, 0.25, 0.25])],
82
+ sampleRate: 4,
83
+ timestamp: 0
84
+ }
85
+ yield {
86
+ planes: [new Float32Array([0.5, 0.5, 0.5, 0.5])],
87
+ sampleRate: 4,
88
+ timestamp: 0.5
89
+ }
90
+ }
91
+
92
+ const mixed = await collect(mixer.mix(samples()))
93
+ expect(mixed.length).is(2)
94
+ expect(mixed[0].startFrame).is(0)
95
+ expect(mixed[0].frames).is(4)
96
+ expect(mixed[0].channels).is(1)
97
+ expect(mixed[0].planar[0]).is(0.25)
98
+ expect(mixed[0].planar[1]).is(0.25)
99
+ expect(mixed[0].planar[2]).is(0.75)
100
+ expect(mixed[0].planar[3]).is(0.75)
101
+ expect(mixed[1].startFrame).is(4)
102
+ expect(mixed[1].planar[0]).is(0.5)
103
+ expect(mixed[1].planar[1]).is(0.5)
104
+ expect(mixed[1].planar[2]).is(0)
105
+ expect(mixed[1].planar[3]).is(0)
106
+ }),
107
+
108
+ "audio mix clamps output to [-1, 1]": test(async () => {
109
+ const mixer = new AudioMix({chunkFrames: 4, clamp: true})
110
+ async function *samples() {
111
+ yield {
112
+ planes: [new Float32Array([0.9, 0.9, 0.9, 0.9])],
113
+ sampleRate: 4,
114
+ timestamp: 0
115
+ }
116
+ yield {
117
+ planes: [new Float32Array([0.8, 0.8, 0.8, 0.8])],
118
+ sampleRate: 4,
119
+ timestamp: 0
120
+ }
121
+ }
122
+
123
+ const mixed = await collect(mixer.mix(samples()))
124
+ expect(mixed.length).is(1)
125
+ expect(mixed[0].planar[0]).is(1)
126
+ expect(mixed[0].planar[1]).is(1)
127
+ expect(mixed[0].planar[2]).is(1)
128
+ expect(mixed[0].planar[3]).is(1)
129
+ }),
130
+
131
+ "audio mix fills gaps with silence": test(async () => {
132
+ const mixer = new AudioMix({chunkFrames: 4, clamp: false})
133
+ async function *samples() {
134
+ yield {
135
+ planes: [new Float32Array([1, 1, 1, 1])],
136
+ sampleRate: 4,
137
+ timestamp: 0
138
+ }
139
+ yield {
140
+ planes: [new Float32Array([2, 2, 2, 2])],
141
+ sampleRate: 4,
142
+ timestamp: 2
143
+ }
144
+ }
145
+
146
+ const mixed = await collect(mixer.mix(samples()))
147
+ expect(mixed.length).is(3)
148
+ expect(mixed[0].startFrame).is(0)
149
+ expect(mixed[0].planar[0]).is(1)
150
+
151
+ expect(mixed[1].startFrame).is(4)
152
+ expect(mixed[1].planar[0]).is(0)
153
+ expect(mixed[1].planar[3]).is(0)
154
+
155
+ expect(mixed[2].startFrame).is(8)
156
+ expect(mixed[2].planar[0]).is(2)
157
+ }),
158
+
159
+ "audio mix truncates negative timestamps": test(async () => {
160
+ const mixer = new AudioMix({chunkFrames: 4, clamp: false})
161
+ async function *samples() {
162
+ yield {
163
+ planes: [new Float32Array([1, 2, 3, 4])],
164
+ sampleRate: 4,
165
+ timestamp: -0.5
166
+ }
167
+ }
168
+
169
+ const mixed = await collect(mixer.mix(samples()))
170
+ expect(mixed.length).is(1)
171
+ expect(mixed[0].startFrame).is(0)
172
+ expect(mixed[0].planar[0]).is(3)
173
+ expect(mixed[0].planar[1]).is(4)
174
+ expect(mixed[0].planar[2]).is(0)
175
+ expect(mixed[0].planar[3]).is(0)
176
+ }),
177
+
178
+ "audio mix handles stereo planar layout": test(async () => {
179
+ const mixer = new AudioMix({chunkFrames: 4, clamp: false})
180
+ async function *samples() {
181
+ yield {
182
+ planes: [
183
+ new Float32Array([1, 1, 1, 1]),
184
+ new Float32Array([2, 2, 2, 2])
185
+ ],
186
+ sampleRate: 4,
187
+ timestamp: 0
188
+ }
189
+ }
190
+
191
+ const mixed = await collect(mixer.mix(samples()))
192
+ expect(mixed.length).is(1)
193
+ expect(mixed[0].channels).is(2)
194
+ expect(mixed[0].planar.length).is(8)
195
+ expect(mixed[0].planar[0]).is(1)
196
+ expect(mixed[0].planar[4]).is(2)
197
+ }),
198
+
199
+ "applyGainToPlanar scales values across multiple channels": test(async () => {
200
+ const planes = [
201
+ new Float32Array([0.2, -0.4]),
202
+ new Float32Array([0.6, -0.8])
203
+ ]
204
+
205
+ applyGainToPlanar(planes, 0.5)
206
+
207
+ expect(near(planes[0][0], 0.1)).ok()
208
+ expect(near(planes[0][1], -0.2)).ok()
209
+ expect(near(planes[1][0], 0.3)).ok()
210
+ expect(near(planes[1][1], -0.4)).ok()
211
+ }),
212
+
213
+ "applyGainToPlanar does not mutate when gain is 1": test(async () => {
214
+ const planes = [new Float32Array([0.5, -0.5])]
215
+
216
+ applyGainToPlanar(planes, 1)
217
+
218
+ expect(near(planes[0][0], 0.5)).ok()
219
+ expect(near(planes[0][1], -0.5)).ok()
220
+ }),
221
+
222
+ "applyGainToPlanar mutes entirely when gain is 0": test(async () => {
223
+ const planes = [new Float32Array([0.9, -0.9])]
224
+
225
+ applyGainToPlanar(planes, 0)
226
+
227
+ expect(planes[0][0]).is(0)
228
+ expect(planes[0][1]).is(0)
229
+ }),
230
+
231
+ "resampleToPlanar returns original data when sample rates match": test(async () => {
232
+ const sample = {
233
+ numberOfFrames: 3,
234
+ numberOfChannels: 1,
235
+ sampleRate: 48000,
236
+ copyTo: (dest: Float32Array) => dest.set([0.1, 0.2, 0.3])
237
+ }
238
+
239
+ const result = resampleToPlanar(sample, 48000)
240
+
241
+ expect(result.frames).is(3)
242
+ expect(result.data.length).is(1)
243
+ expect(near(result.data[0][0], 0.1)).ok()
244
+ expect(near(result.data[0][1], 0.2)).ok()
245
+ expect(near(result.data[0][2], 0.3)).ok()
246
+ }),
247
+
248
+ "resampleToPlanar upsamples using linear interpolation": test(async () => {
249
+ const sample = {
250
+ numberOfFrames: 2,
251
+ numberOfChannels: 1,
252
+ sampleRate: 1,
253
+ copyTo: (dest: Float32Array) => dest.set([10, 20])
254
+ }
255
+
256
+ const result = resampleToPlanar(sample as any, 2)
257
+
258
+ expect(result.frames).is(4)
259
+ expect(near(result.data[0][0], 10)).ok()
260
+ expect(near(result.data[0][1], 15)).ok()
261
+ expect(near(result.data[0][2], 20)).ok()
262
+ expect(near(result.data[0][3], 20)).ok()
263
+ }),
264
+
265
+ "resampleToPlanar downsamples correctly": test(async () => {
266
+ const sample = {
267
+ numberOfFrames: 4,
268
+ numberOfChannels: 1,
269
+ sampleRate: 4,
270
+ copyTo: (dest: Float32Array) => dest.set([1, 2, 3, 4])
271
+ }
272
+
273
+ const result = resampleToPlanar(sample, 2)
274
+
275
+ expect(result.frames).is(2)
276
+ expect(near(result.data[0][0], 1)).ok()
277
+ expect(near(result.data[0][1], 3)).ok()
278
+ }),
279
+
280
+ "resampleToPlanar processes multi-channel planar data": test(async () => {
281
+ const planes = [
282
+ new Float32Array([1, 2]),
283
+ new Float32Array([3, 4])
284
+ ]
285
+
286
+ const sample = {
287
+ numberOfFrames: 2,
288
+ numberOfChannels: 2,
289
+ sampleRate: 1,
290
+ copyTo: (dest: Float32Array, options: { planeIndex: number }) => {
291
+ dest.set(planes[options.planeIndex])
292
+ }
293
+ }
294
+
295
+ const result = resampleToPlanar(sample, 2)
296
+
297
+ expect(result.data.length).is(2)
298
+ expect(near(result.data[0][1], 1.5)).ok()
299
+ expect(near(result.data[1][1], 3.5)).ok()
300
+ }),
301
+
302
+ "resampleToPlanar handles zero channels gracefully": test(async () => {
303
+ const sample = {
304
+ numberOfFrames: 10,
305
+ numberOfChannels: 0,
306
+ sampleRate: 48000,
307
+ copyTo: () => { throw new Error("Should not be called") }
308
+ }
309
+
310
+ const result = resampleToPlanar(sample, 44100)
311
+
312
+ expect(result.data.length).is(0)
313
+ expect(result.frames).is(0)
314
+ }),
315
+
316
+ "resampleToPlanar enforces minimum of 1 frame on aggressive downsample": test(async () => {
317
+ const sample = {
318
+ numberOfFrames: 1,
319
+ numberOfChannels: 1,
320
+ sampleRate: 48000,
321
+ copyTo: (dest: Float32Array) => dest.set([0.8])
322
+ }
323
+
324
+ const result = resampleToPlanar(sample, 8000)
325
+
326
+ expect(result.frames).is(1)
327
+ expect(result.data[0].length).is(1)
328
+ expect(near(result.data[0][0], 0.8)).ok()
329
+ }),
330
+
331
+ "resampleToPlanar calls copyTo with strict contract shape": test(async () => {
332
+ let passedOptions: any = null
333
+ const sample = {
334
+ numberOfFrames: 2,
335
+ numberOfChannels: 1,
336
+ sampleRate: 48000,
337
+ copyTo: (dest: Float32Array, options: any) => {
338
+ passedOptions = options
339
+ }
340
+ }
341
+
342
+ resampleToPlanar(sample, 44100)
343
+
344
+ expect(passedOptions).not.is(null)
345
+ expect(passedOptions.planeIndex).is(0)
346
+ expect(passedOptions.format).is("f32-planar")
347
+ }),
348
+
349
+ "5s long export at 30fps renders exacly 150 frames": test(async () => {
350
+ const {omni, videoA, driver, resolveMedia} = await setupTest()
351
+ const {timeline} = new O({timeline: omni.timeline(o => o.sequence(
352
+ o.video(videoA, {duration: 2000}),
353
+ o.gap(500),
354
+ o.video(videoA, {duration: 2000}),
355
+ o.audio(videoA, {duration: 500})
356
+ ))})
357
+ const readable = produceVideo({timeline, fps: fps(30), driver, resolveMedia})
358
+ let frames = 0
359
+ for await (const frame of readable) {
360
+ frame.close()
361
+ frames++
362
+ }
363
+ expect(frames).is(150)
364
+ }),
365
+
366
+ "5s long audio export at 48000Hz renders exactly 240000 frames": test(async () => {
367
+ const {omni, videoA, resolveMedia} = await setupTest()
368
+ const {timeline} = new O({timeline: omni.timeline(o => o.sequence(
369
+ o.video(videoA, {duration: 2000}),
370
+ o.gap(500),
371
+ o.video(videoA, {duration: 2000}),
372
+ o.audio(videoA, {duration: 500})
373
+ ))})
374
+
375
+ const readable = produceAudio({timeline, resolveMedia})
376
+ let totalFrames = 0
377
+
378
+ for await (const chunk of readable) {
379
+ totalFrames += chunk.numberOfFrames
380
+ chunk.close()
381
+ }
382
+
383
+ expect(totalFrames).is(240000)
384
+ })
385
+ })
@@ -0,0 +1,190 @@
1
+
2
+ import {TextStyleOptions} from "pixi.js"
3
+
4
+ import {O} from "./o.js"
5
+ import {Media} from "../parts/media.js"
6
+ import {TimelineFile} from "../parts/basics.js"
7
+ import {FilterAction} from "../parts/filters.js"
8
+ import {visualAnimations} from "../parts/animations.js"
9
+ import {filters, FilterParams, FilterType} from "../parts/filters.js"
10
+ import {Crop, FilterableItem, Item, VisualAnimatableItem} from "../parts/item.js"
11
+ import {Anim, AnimateAction, Interpolation, Keyframes, TrackTransform, Transform, Vec2, VisualAnimations} from "../types.js"
12
+
13
+ export type Build<T extends Item.Any = Item.Any> = (o: O) => T
14
+ type BuildVisualAnimateActions = {
15
+ [TKey in keyof VisualAnimations]-?: BuildAnimateAction
16
+ }
17
+
18
+ function createTimeline(): TimelineFile {
19
+ return {
20
+ format: "timeline",
21
+ info: "https://omniclip.app/",
22
+ version: 0,
23
+ items: [],
24
+ rootId: 0
25
+ }
26
+ }
27
+
28
+ export function timeline(root: Build): TimelineFile {
29
+ const o = new O({timeline: createTimeline()})
30
+ const item = root(o)
31
+ o.timeline.rootId = item.id
32
+ return o.timeline
33
+ }
34
+
35
+ export function sequence(...items: Build[]): Build<Item.Sequence> {
36
+ return o => o.sequence(...items.map(item => item(o)))
37
+ }
38
+
39
+ export function stack(...items: Build[]): Build<Item.Stack> {
40
+ return o => o.stack(...items.map(item => item(o)))
41
+ }
42
+
43
+ export function video(
44
+ media: Media,
45
+ options?: {
46
+ start?: number,
47
+ duration?: number
48
+ }
49
+ ): Build<Item.Video> {
50
+ return o => o.video(media, options)
51
+ }
52
+
53
+ export function audio(
54
+ media: Media,
55
+ options?: {
56
+ start?: number,
57
+ duration?: number,
58
+ gain?: number
59
+ }
60
+ ): Build<Item.Audio> {
61
+ return o => o.audio(media, options)
62
+ }
63
+
64
+ export function text(
65
+ content: string,
66
+ options?: {
67
+ duration?: number,
68
+ styles?: TextStyleOptions
69
+ }
70
+ ): Build<Item.Text> {
71
+ return o => o.text(content, options)
72
+ }
73
+
74
+ export function gap(duration: number): Build<Item.Gap> {
75
+ return o => o.gap(duration)
76
+ }
77
+
78
+ export function spatial(transform?: Transform, crop?: Crop): Build<Item.Spatial> {
79
+ return o => o.spatial(transform, crop)
80
+ }
81
+
82
+ export function animatedSpatial(anim: Anim<TrackTransform>, crop?: Crop): Build<Item.AnimatedSpatial> {
83
+ return o => o.animatedSpatial(anim, crop)
84
+ }
85
+
86
+ export const anim = {
87
+ scalar(terp: Interpolation, track: Keyframes): Anim<Keyframes> {
88
+ return {terp, track}
89
+ },
90
+
91
+ vec2(terp: Interpolation, source: Keyframes<Vec2>): Anim<{x: Keyframes, y: Keyframes}> {
92
+ const track = {x: [] as Keyframes, y: [] as Keyframes}
93
+
94
+ for (const [time, [x, y]] of source) {
95
+ track.x.push([time, x])
96
+ track.y.push([time, y])
97
+ }
98
+
99
+ return {terp, track}
100
+ },
101
+
102
+ transform(terp: Interpolation, source: Keyframes<Transform>): Anim<TrackTransform> {
103
+ const track: TrackTransform = {
104
+ position: {x: [], y: []},
105
+ scale: {x: [], y: []},
106
+ rotation: [],
107
+ }
108
+
109
+ for (const [time, [position, scale, rotation]] of source) {
110
+ track.position.x.push([time, position[0]])
111
+ track.position.y.push([time, position[1]])
112
+ track.scale.x.push([time, scale[0]])
113
+ track.scale.y.push([time, scale[1]])
114
+ track.rotation.push([time, rotation])
115
+ }
116
+
117
+ return {terp, track}
118
+ },
119
+ }
120
+
121
+ interface BuildFilterAction<TFilter extends FilterType> {
122
+ <T extends FilterableItem>(item: Build<T>, params?: FilterParams<TFilter>): Build<T>
123
+ make(params?: FilterParams<TFilter>): Build<Item.Filter<TFilter>>
124
+ }
125
+
126
+ interface BuildAnimateAction {
127
+ <T extends VisualAnimatableItem>(
128
+ item: Build<T>,
129
+ terp: Interpolation,
130
+ track: Keyframes
131
+ ): Build<T>
132
+ make(terp: Interpolation, track: Keyframes): Build<Item.Animation>
133
+ }
134
+
135
+ type BuildFilterActions = {
136
+ [TName in keyof typeof filters]: BuildFilterAction<(typeof filters)[TName]["type"]>
137
+ }
138
+
139
+ function makeFilter<TFilter extends FilterType>(
140
+ get: (o: O) => FilterAction<TFilter>
141
+ ): BuildFilterAction<TFilter> {
142
+ const action = (<T extends FilterableItem>(
143
+ item: Build<T>,
144
+ params?: FilterParams<TFilter>
145
+ ): Build<T> => o => get(o)(item(o), params)) as BuildFilterAction<TFilter>
146
+ action.make = (params?: FilterParams<TFilter>) => o => get(o).make(params)
147
+ return action
148
+ }
149
+
150
+ function makeFilters(): BuildFilterActions {
151
+ const names = Object.keys(filters) as (keyof typeof filters)[]
152
+ const entries = names.map(name => [
153
+ name,
154
+ makeFilter(o => o.filter[name] as FilterAction<any>)
155
+ ])
156
+ return Object.fromEntries(entries) as BuildFilterActions
157
+ }
158
+
159
+ export const filter = makeFilters()
160
+
161
+ function makeAnimate(
162
+ get: (o: O) => AnimateAction
163
+ ): BuildAnimateAction {
164
+ const action = (<T extends VisualAnimatableItem>(
165
+ item: Build<T>,
166
+ terp: Interpolation,
167
+ track: Keyframes
168
+ ): Build<T> => o => get(o)(item(o), terp, track)) as BuildAnimateAction
169
+ action.make = (terp: Interpolation, track: Keyframes) => o => get(o).make(terp, track)
170
+ return action
171
+ }
172
+
173
+ function makeAnimateActions(): BuildVisualAnimateActions {
174
+ const entries = Object.keys(visualAnimations)
175
+ .map(key => [key, makeAnimate(o => o.animate[key as keyof VisualAnimations] as AnimateAction)])
176
+ return Object.fromEntries(entries) as BuildVisualAnimateActions
177
+ }
178
+
179
+ export const animate = makeAnimateActions()
180
+
181
+ export function textStyle(style: TextStyleOptions): Build<Item.TextStyle> {
182
+ return o => o.textStyle(style)
183
+ }
184
+
185
+ export const transition = {
186
+ crossfade(duration: number): Build<Item.Transition> {
187
+ return o => o.transition.crossfade(duration)
188
+ }
189
+ }
190
+