@omnimedia/omnitool 1.1.0-1 → 1.1.0-100

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 (468) hide show
  1. package/README.md +556 -72
  2. package/package.json +20 -15
  3. package/s/context.ts +0 -7
  4. package/s/demo/demo.bundle.ts +104 -39
  5. package/s/demo/demo.css +246 -11
  6. package/s/demo/routines/export-test.ts +16 -0
  7. package/s/demo/routines/filmstrip-test.ts +23 -19
  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 +81 -0
  11. package/s/demo/routines/transcode-test.ts +21 -5
  12. package/s/demo/routines/transcriber-test.ts +34 -0
  13. package/s/demo/routines/transitions-test.ts +43 -0
  14. package/s/demo/routines/waveform-test.ts +35 -8
  15. package/s/driver/driver-worker.ts +9 -0
  16. package/s/driver/driver.test.ts +1 -1
  17. package/s/driver/driver.ts +52 -43
  18. package/s/driver/fns/host.ts +7 -6
  19. package/s/driver/fns/schematic.ts +69 -25
  20. package/s/driver/fns/work.ts +102 -214
  21. package/s/driver/parts/compositor.ts +319 -0
  22. package/s/driver/parts/machina.ts +19 -20
  23. package/s/driver/utils/find-pixi-filter.ts +24 -0
  24. package/s/driver/utils/load-decoder-source.ts +3 -4
  25. package/s/features/bg-remover/bg-remover.ts +26 -0
  26. package/s/features/bg-remover/default-spec.ts +11 -0
  27. package/s/features/bg-remover/types.ts +27 -0
  28. package/s/features/bg-remover/worker.bundle.ts +52 -0
  29. package/s/features/parts/expose-errors.ts +41 -0
  30. package/s/features/parts/load-pipe.ts +17 -0
  31. package/s/features/parts/types.ts +19 -0
  32. package/s/features/speech/transcribe/default-spec.ts +11 -0
  33. package/s/features/speech/transcribe/parts/prep-audio.ts +23 -0
  34. package/s/features/speech/transcribe/parts/transcribe.ts +70 -0
  35. package/s/features/speech/transcribe/transcriber.ts +46 -0
  36. package/s/features/speech/transcribe/types.ts +76 -0
  37. package/s/features/speech/transcribe/worker.bundle.ts +42 -0
  38. package/s/features/transition/parts/fragment.ts +24 -0
  39. package/s/features/transition/parts/types.ts +27 -0
  40. package/s/features/transition/parts/uniforms.ts +29 -0
  41. package/s/features/transition/parts/vertex.ts +31 -0
  42. package/s/features/transition/transition.ts +60 -0
  43. package/s/index.html.ts +103 -20
  44. package/s/index.ts +1 -0
  45. package/s/tests.bundle.ts +11 -0
  46. package/s/tests.html.ts +28 -0
  47. package/s/timeline/index.ts +17 -1
  48. package/s/timeline/parts/animations/make.ts +38 -0
  49. package/s/timeline/parts/animations/presets.ts +138 -0
  50. package/s/timeline/parts/animations/properties.ts +30 -0
  51. package/s/timeline/parts/animations/registry.ts +13 -0
  52. package/s/timeline/parts/animations/types.ts +80 -0
  53. package/s/timeline/parts/basics.ts +1 -1
  54. package/s/timeline/parts/captions.ts +91 -0
  55. package/s/timeline/parts/filmstrip.ts +43 -16
  56. package/s/timeline/parts/filters.ts +453 -0
  57. package/s/timeline/parts/item.ts +124 -11
  58. package/s/timeline/parts/media.ts +43 -1
  59. package/s/timeline/parts/resource-pool.ts +8 -5
  60. package/s/timeline/parts/resource.ts +3 -0
  61. package/s/timeline/parts/transitions.ts +102 -0
  62. package/s/timeline/parts/waveform/parts/collect.ts +72 -0
  63. package/s/timeline/parts/waveform/parts/render.ts +45 -0
  64. package/s/timeline/parts/waveform/parts/types.ts +24 -0
  65. package/s/timeline/parts/waveform/waveform.ts +161 -0
  66. package/s/timeline/renderers/export/parts/audio-gain.ts +17 -0
  67. package/s/timeline/renderers/export/parts/audio-mix.ts +133 -0
  68. package/s/timeline/renderers/export/parts/cursor.ts +291 -0
  69. package/s/timeline/renderers/export/parts/produce-audio.ts +64 -0
  70. package/s/timeline/renderers/export/parts/produce-video.ts +49 -0
  71. package/s/timeline/renderers/export/parts/resamplers.ts +48 -0
  72. package/s/timeline/renderers/export/produce.ts +28 -0
  73. package/s/timeline/renderers/parts/handy.ts +441 -0
  74. package/s/timeline/renderers/parts/samplers/audio/parts/find.ts +19 -0
  75. package/s/timeline/renderers/parts/samplers/audio/parts/init.ts +60 -0
  76. package/s/timeline/renderers/parts/samplers/audio/parts/sink.ts +38 -0
  77. package/s/timeline/renderers/parts/samplers/audio/parts/types.ts +16 -0
  78. package/s/timeline/renderers/parts/samplers/audio/sampler.ts +35 -0
  79. package/s/timeline/renderers/parts/samplers/visual/parts/defaults.ts +23 -0
  80. package/s/timeline/renderers/parts/samplers/visual/parts/image-sink.ts +51 -0
  81. package/s/timeline/renderers/parts/samplers/visual/parts/sample.ts +99 -0
  82. package/s/timeline/renderers/parts/samplers/visual/parts/sequence.ts +97 -0
  83. package/s/timeline/renderers/parts/samplers/visual/parts/transition.ts +28 -0
  84. package/s/timeline/renderers/parts/samplers/visual/parts/types.ts +11 -0
  85. package/s/timeline/renderers/parts/samplers/visual/parts/video-sink.ts +38 -0
  86. package/s/timeline/renderers/parts/samplers/visual/sampler.ts +31 -0
  87. package/s/timeline/renderers/parts/schedulers.ts +96 -0
  88. package/s/timeline/renderers/player/parts/playback.ts +213 -0
  89. package/s/timeline/renderers/player/player.ts +86 -0
  90. package/s/timeline/renderers/renderers.test.ts +403 -0
  91. package/s/timeline/sugar/helpers.ts +239 -0
  92. package/s/timeline/sugar/o.ts +443 -48
  93. package/s/timeline/sugar/omni.test.ts +210 -0
  94. package/s/timeline/sugar/omni.ts +38 -12
  95. package/s/timeline/types.ts +62 -0
  96. package/s/timeline/utils/anim.ts +63 -0
  97. package/s/timeline/utils/checksum.ts +5 -2
  98. package/s/timeline/utils/datafile.ts +15 -4
  99. package/s/timeline/utils/dummy-data.ts +3 -3
  100. package/s/timeline/utils/matrix.ts +54 -0
  101. package/s/timeline/utils/terps.ts +81 -0
  102. package/s/units/fps.ts +8 -0
  103. package/s/units/ms.ts +8 -0
  104. package/s/units/seconds.ts +8 -0
  105. package/x/WebGLRenderer-4CHIZDHY.js +2 -0
  106. package/x/WebGLRenderer-4CHIZDHY.js.map +7 -0
  107. package/x/WebGPURenderer-O6WXU2QR.js +2 -0
  108. package/x/WebGPURenderer-O6WXU2QR.js.map +7 -0
  109. package/x/browserAll-WNIOTNNP.js +2 -0
  110. package/x/browserAll-WNIOTNNP.js.map +7 -0
  111. package/x/chunk-23FOBGX6.js +2 -0
  112. package/x/chunk-23FOBGX6.js.map +7 -0
  113. package/x/chunk-73XOWA4F.js +393 -0
  114. package/x/chunk-73XOWA4F.js.map +7 -0
  115. package/x/chunk-IAWJKNX5.js +42 -0
  116. package/x/chunk-IAWJKNX5.js.map +7 -0
  117. package/x/chunk-KCMVLWBS.js +157 -0
  118. package/x/chunk-KCMVLWBS.js.map +7 -0
  119. package/x/chunk-MR32SQ27.js +2 -0
  120. package/x/chunk-MR32SQ27.js.map +7 -0
  121. package/x/chunk-VCUJJYRJ.js +327 -0
  122. package/x/chunk-VCUJJYRJ.js.map +7 -0
  123. package/x/chunk-XNIZ4L5W.js +269 -0
  124. package/x/chunk-XNIZ4L5W.js.map +7 -0
  125. package/x/chunk-ZLGNQFUI.js +15 -0
  126. package/x/chunk-ZLGNQFUI.js.map +7 -0
  127. package/x/context.d.ts +1 -4
  128. package/x/context.js +1 -5
  129. package/x/context.js.map +1 -1
  130. package/x/demo/WebGLRenderer-RSJAHIG2.js +2 -0
  131. package/x/demo/WebGLRenderer-RSJAHIG2.js.map +7 -0
  132. package/x/demo/WebGPURenderer-MGFAJCYY.js +2 -0
  133. package/x/demo/WebGPURenderer-MGFAJCYY.js.map +7 -0
  134. package/x/demo/browserAll-PTRBXBRP.js +2 -0
  135. package/x/demo/browserAll-PTRBXBRP.js.map +7 -0
  136. package/x/demo/chunk-CUYOGHWU.js +42 -0
  137. package/x/demo/chunk-CUYOGHWU.js.map +7 -0
  138. package/x/demo/chunk-DGTDNJ7W.js +2 -0
  139. package/x/demo/chunk-DGTDNJ7W.js.map +7 -0
  140. package/x/demo/chunk-FZ5BYF63.js +15 -0
  141. package/x/demo/chunk-FZ5BYF63.js.map +7 -0
  142. package/x/demo/chunk-KWN4NNES.js +269 -0
  143. package/x/demo/chunk-KWN4NNES.js.map +7 -0
  144. package/x/demo/chunk-OJ3FPXW7.js +157 -0
  145. package/x/demo/chunk-OJ3FPXW7.js.map +7 -0
  146. package/x/demo/chunk-PSLUOGTZ.js +393 -0
  147. package/x/demo/chunk-PSLUOGTZ.js.map +7 -0
  148. package/x/demo/chunk-VLCVEIFU.js +327 -0
  149. package/x/demo/chunk-VLCVEIFU.js.map +7 -0
  150. package/x/demo/chunk-ZWCPT5FR.js +2 -0
  151. package/x/demo/chunk-ZWCPT5FR.js.map +7 -0
  152. package/x/demo/demo.bundle.js +94 -36
  153. package/x/demo/demo.bundle.js.map +1 -1
  154. package/x/demo/demo.bundle.min.js +7359 -107
  155. package/x/demo/demo.bundle.min.js.map +4 -4
  156. package/x/demo/demo.css +246 -11
  157. package/x/demo/routines/export-test.d.ts +2 -0
  158. package/x/demo/routines/export-test.js +10 -0
  159. package/x/demo/routines/export-test.js.map +1 -0
  160. package/x/demo/routines/filmstrip-test.d.ts +1 -1
  161. package/x/demo/routines/filmstrip-test.js +21 -18
  162. package/x/demo/routines/filmstrip-test.js.map +1 -1
  163. package/x/demo/routines/load-video.d.ts +1 -1
  164. package/x/demo/routines/load-video.js +1 -2
  165. package/x/demo/routines/load-video.js.map +1 -1
  166. package/x/demo/routines/playback-test.d.ts +2 -0
  167. package/x/demo/routines/playback-test.js +51 -0
  168. package/x/demo/routines/playback-test.js.map +1 -0
  169. package/x/demo/routines/timeline-setup.d.ts +6 -0
  170. package/x/demo/routines/timeline-setup.js +59 -0
  171. package/x/demo/routines/timeline-setup.js.map +1 -0
  172. package/x/demo/routines/transcode-test.js +17 -5
  173. package/x/demo/routines/transcode-test.js.map +1 -1
  174. package/x/demo/routines/transcriber-test.d.ts +4 -0
  175. package/x/demo/routines/transcriber-test.js +33 -0
  176. package/x/demo/routines/transcriber-test.js.map +1 -0
  177. package/x/demo/routines/transitions-test.d.ts +5 -0
  178. package/x/demo/routines/transitions-test.js +35 -0
  179. package/x/demo/routines/transitions-test.js.map +1 -0
  180. package/x/demo/routines/waveform-test.d.ts +2 -1
  181. package/x/demo/routines/waveform-test.js +29 -8
  182. package/x/demo/routines/waveform-test.js.map +1 -1
  183. package/x/demo/webworkerAll-JENRT6BT.js +2 -0
  184. package/x/demo/webworkerAll-JENRT6BT.js.map +7 -0
  185. package/x/driver/driver-worker.d.ts +1 -0
  186. package/x/driver/driver-worker.js +6 -0
  187. package/x/driver/driver-worker.js.map +1 -0
  188. package/x/driver/driver.d.ts +24 -9
  189. package/x/driver/driver.js +51 -40
  190. package/x/driver/driver.js.map +1 -1
  191. package/x/driver/driver.test.js +1 -1
  192. package/x/driver/driver.test.js.map +1 -1
  193. package/x/driver/driver.worker.bundle.min.js +137 -1137
  194. package/x/driver/driver.worker.bundle.min.js.map +4 -4
  195. package/x/driver/fns/host.d.ts +12 -4
  196. package/x/driver/fns/host.js +3 -3
  197. package/x/driver/fns/host.js.map +1 -1
  198. package/x/driver/fns/schematic.d.ts +65 -25
  199. package/x/driver/fns/work.d.ts +14 -7
  200. package/x/driver/fns/work.js +83 -174
  201. package/x/driver/fns/work.js.map +1 -1
  202. package/x/driver/parts/compositor.d.ts +39 -0
  203. package/x/driver/parts/compositor.js +264 -0
  204. package/x/driver/parts/compositor.js.map +1 -0
  205. package/x/driver/parts/machina.d.ts +0 -20
  206. package/x/driver/parts/machina.js +6 -10
  207. package/x/driver/parts/machina.js.map +1 -1
  208. package/x/driver/utils/find-pixi-filter.d.ts +5 -0
  209. package/x/driver/utils/find-pixi-filter.js +13 -0
  210. package/x/driver/utils/find-pixi-filter.js.map +1 -0
  211. package/x/driver/utils/load-decoder-source.d.ts +2 -1
  212. package/x/driver/utils/load-decoder-source.js +2 -3
  213. package/x/driver/utils/load-decoder-source.js.map +1 -1
  214. package/x/features/bg-remover/bg-remover.d.ts +5 -0
  215. package/x/features/bg-remover/bg-remover.js +18 -0
  216. package/x/features/bg-remover/bg-remover.js.map +1 -0
  217. package/x/features/bg-remover/default-spec.d.ts +2 -0
  218. package/x/features/bg-remover/default-spec.js +6 -0
  219. package/x/features/bg-remover/default-spec.js.map +1 -0
  220. package/x/features/bg-remover/types.d.ts +20 -0
  221. package/x/features/bg-remover/types.js +2 -0
  222. package/x/features/bg-remover/types.js.map +1 -0
  223. package/x/features/bg-remover/worker.bundle.js +39 -0
  224. package/x/features/bg-remover/worker.bundle.js.map +1 -0
  225. package/x/features/bg-remover/worker.bundle.min.js +2916 -0
  226. package/x/features/bg-remover/worker.bundle.min.js.map +7 -0
  227. package/x/features/parts/expose-errors.d.ts +3 -0
  228. package/x/features/parts/expose-errors.js +32 -0
  229. package/x/features/parts/expose-errors.js.map +1 -0
  230. package/x/features/parts/load-pipe.d.ts +2 -0
  231. package/x/features/parts/load-pipe.js +13 -0
  232. package/x/features/parts/load-pipe.js.map +1 -0
  233. package/x/features/parts/types.d.ts +15 -0
  234. package/x/features/parts/types.js +2 -0
  235. package/x/features/parts/types.js.map +1 -0
  236. package/x/features/speech/transcribe/default-spec.d.ts +2 -0
  237. package/x/features/speech/transcribe/default-spec.js +8 -0
  238. package/x/features/speech/transcribe/default-spec.js.map +1 -0
  239. package/x/features/speech/transcribe/parts/prep-audio.d.ts +5 -0
  240. package/x/features/speech/transcribe/parts/prep-audio.js +21 -0
  241. package/x/features/speech/transcribe/parts/prep-audio.js.map +1 -0
  242. package/x/features/speech/transcribe/parts/transcribe.d.ts +5 -0
  243. package/x/features/speech/transcribe/parts/transcribe.js +56 -0
  244. package/x/features/speech/transcribe/parts/transcribe.js.map +1 -0
  245. package/x/features/speech/transcribe/transcriber.d.ts +5 -0
  246. package/x/features/speech/transcribe/transcriber.js +33 -0
  247. package/x/features/speech/transcribe/transcriber.js.map +1 -0
  248. package/x/features/speech/transcribe/types.d.ts +59 -0
  249. package/x/features/speech/transcribe/types.js +2 -0
  250. package/x/features/speech/transcribe/types.js.map +1 -0
  251. package/x/features/speech/transcribe/worker.bundle.js +35 -0
  252. package/x/features/speech/transcribe/worker.bundle.js.map +1 -0
  253. package/x/features/speech/transcribe/worker.bundle.min.js +2916 -0
  254. package/x/features/speech/transcribe/worker.bundle.min.js.map +7 -0
  255. package/x/features/transition/parts/fragment.d.ts +1 -0
  256. package/x/features/transition/parts/fragment.js +25 -0
  257. package/x/features/transition/parts/fragment.js.map +1 -0
  258. package/x/features/transition/parts/types.d.ts +23 -0
  259. package/x/features/transition/parts/types.js +2 -0
  260. package/x/features/transition/parts/types.js.map +1 -0
  261. package/x/features/transition/parts/uniforms.d.ts +31 -0
  262. package/x/features/transition/parts/uniforms.js +27 -0
  263. package/x/features/transition/parts/uniforms.js.map +1 -0
  264. package/x/features/transition/parts/vertex.d.ts +1 -0
  265. package/x/features/transition/parts/vertex.js +32 -0
  266. package/x/features/transition/parts/vertex.js.map +1 -0
  267. package/x/features/transition/transition.d.ts +5 -0
  268. package/x/features/transition/transition.js +50 -0
  269. package/x/features/transition/transition.js.map +1 -0
  270. package/x/index.d.ts +1 -0
  271. package/x/index.html +349 -30
  272. package/x/index.html.js +103 -19
  273. package/x/index.html.js.map +1 -1
  274. package/x/index.js +1 -0
  275. package/x/index.js.map +1 -1
  276. package/x/tests.bundle.d.ts +1 -0
  277. package/x/tests.bundle.js +8 -0
  278. package/x/tests.bundle.js.map +1 -0
  279. package/x/tests.bundle.min.js +7374 -0
  280. package/x/tests.bundle.min.js.map +7 -0
  281. package/x/tests.html +316 -0
  282. package/x/tests.html.d.ts +2 -0
  283. package/x/tests.html.js +22 -0
  284. package/x/tests.html.js.map +1 -0
  285. package/x/timeline/index.d.ts +16 -0
  286. package/x/timeline/index.js +16 -0
  287. package/x/timeline/index.js.map +1 -1
  288. package/x/timeline/parts/animations/make.d.ts +3 -0
  289. package/x/timeline/parts/animations/make.js +29 -0
  290. package/x/timeline/parts/animations/make.js.map +1 -0
  291. package/x/timeline/parts/animations/presets.d.ts +170 -0
  292. package/x/timeline/parts/animations/presets.js +135 -0
  293. package/x/timeline/parts/animations/presets.js.map +1 -0
  294. package/x/timeline/parts/animations/properties.d.ts +84 -0
  295. package/x/timeline/parts/animations/properties.js +25 -0
  296. package/x/timeline/parts/animations/properties.js.map +1 -0
  297. package/x/timeline/parts/animations/registry.d.ts +218 -0
  298. package/x/timeline/parts/animations/registry.js +11 -0
  299. package/x/timeline/parts/animations/registry.js.map +1 -0
  300. package/x/timeline/parts/animations/types.d.ts +60 -0
  301. package/x/timeline/parts/animations/types.js +2 -0
  302. package/x/timeline/parts/animations/types.js.map +1 -0
  303. package/x/timeline/parts/basics.d.ts +1 -1
  304. package/x/timeline/parts/captions.d.ts +41 -0
  305. package/x/timeline/parts/captions.js +55 -0
  306. package/x/timeline/parts/captions.js.map +1 -0
  307. package/x/timeline/parts/filmstrip.d.ts +4 -3
  308. package/x/timeline/parts/filmstrip.js +29 -10
  309. package/x/timeline/parts/filmstrip.js.map +1 -1
  310. package/x/timeline/parts/filters.d.ts +108 -0
  311. package/x/timeline/parts/filters.js +340 -0
  312. package/x/timeline/parts/filters.js.map +1 -0
  313. package/x/timeline/parts/item.d.ts +106 -12
  314. package/x/timeline/parts/item.js +11 -7
  315. package/x/timeline/parts/item.js.map +1 -1
  316. package/x/timeline/parts/media.d.ts +6 -0
  317. package/x/timeline/parts/media.js +35 -1
  318. package/x/timeline/parts/media.js.map +1 -1
  319. package/x/timeline/parts/resource-pool.d.ts +3 -0
  320. package/x/timeline/parts/resource-pool.js +7 -4
  321. package/x/timeline/parts/resource-pool.js.map +1 -1
  322. package/x/timeline/parts/resource.d.ts +3 -0
  323. package/x/timeline/parts/transitions.d.ts +15 -0
  324. package/x/timeline/parts/transitions.js +81 -0
  325. package/x/timeline/parts/transitions.js.map +1 -0
  326. package/x/timeline/parts/waveform/parts/collect.d.ts +11 -0
  327. package/x/timeline/parts/waveform/parts/collect.js +56 -0
  328. package/x/timeline/parts/waveform/parts/collect.js.map +1 -0
  329. package/x/timeline/parts/waveform/parts/render.d.ts +5 -0
  330. package/x/timeline/parts/waveform/parts/render.js +29 -0
  331. package/x/timeline/parts/waveform/parts/render.js.map +1 -0
  332. package/x/timeline/parts/waveform/parts/types.d.ts +21 -0
  333. package/x/timeline/parts/waveform/parts/types.js +2 -0
  334. package/x/timeline/parts/waveform/parts/types.js.map +1 -0
  335. package/x/timeline/parts/waveform/waveform.d.ts +19 -0
  336. package/x/timeline/parts/waveform/waveform.js +133 -0
  337. package/x/timeline/parts/waveform/waveform.js.map +1 -0
  338. package/x/timeline/renderers/export/parts/audio-gain.d.ts +1 -0
  339. package/x/timeline/renderers/export/parts/audio-gain.js +13 -0
  340. package/x/timeline/renderers/export/parts/audio-gain.js.map +1 -0
  341. package/x/timeline/renderers/export/parts/audio-mix.d.ts +21 -0
  342. package/x/timeline/renderers/export/parts/audio-mix.js +89 -0
  343. package/x/timeline/renderers/export/parts/audio-mix.js.map +1 -0
  344. package/x/timeline/renderers/export/parts/cursor.d.ts +35 -0
  345. package/x/timeline/renderers/export/parts/cursor.js +236 -0
  346. package/x/timeline/renderers/export/parts/cursor.js.map +1 -0
  347. package/x/timeline/renderers/export/parts/produce-audio.d.ts +6 -0
  348. package/x/timeline/renderers/export/parts/produce-audio.js +41 -0
  349. package/x/timeline/renderers/export/parts/produce-audio.js.map +1 -0
  350. package/x/timeline/renderers/export/parts/produce-video.d.ts +10 -0
  351. package/x/timeline/renderers/export/parts/produce-video.js +26 -0
  352. package/x/timeline/renderers/export/parts/produce-video.js.map +1 -0
  353. package/x/timeline/renderers/export/parts/resamplers.d.ts +12 -0
  354. package/x/timeline/renderers/export/parts/resamplers.js +29 -0
  355. package/x/timeline/renderers/export/parts/resamplers.js.map +1 -0
  356. package/x/timeline/renderers/export/produce.d.ts +13 -0
  357. package/x/timeline/renderers/export/produce.js +15 -0
  358. package/x/timeline/renderers/export/produce.js.map +1 -0
  359. package/x/timeline/renderers/parts/handy.d.ts +38 -0
  360. package/x/timeline/renderers/parts/handy.js +263 -0
  361. package/x/timeline/renderers/parts/handy.js.map +1 -0
  362. package/x/timeline/renderers/parts/samplers/audio/parts/find.d.ts +6 -0
  363. package/x/timeline/renderers/parts/samplers/audio/parts/find.js +15 -0
  364. package/x/timeline/renderers/parts/samplers/audio/parts/find.js.map +1 -0
  365. package/x/timeline/renderers/parts/samplers/audio/parts/init.d.ts +5 -0
  366. package/x/timeline/renderers/parts/samplers/audio/parts/init.js +40 -0
  367. package/x/timeline/renderers/parts/samplers/audio/parts/init.js.map +1 -0
  368. package/x/timeline/renderers/parts/samplers/audio/parts/sink.d.ts +8 -0
  369. package/x/timeline/renderers/parts/samplers/audio/parts/sink.js +24 -0
  370. package/x/timeline/renderers/parts/samplers/audio/parts/sink.js.map +1 -0
  371. package/x/timeline/renderers/parts/samplers/audio/parts/types.d.ts +14 -0
  372. package/x/timeline/renderers/parts/samplers/audio/parts/types.js +2 -0
  373. package/x/timeline/renderers/parts/samplers/audio/parts/types.js.map +1 -0
  374. package/x/timeline/renderers/parts/samplers/audio/sampler.d.ts +11 -0
  375. package/x/timeline/renderers/parts/samplers/audio/sampler.js +22 -0
  376. package/x/timeline/renderers/parts/samplers/audio/sampler.js.map +1 -0
  377. package/x/timeline/renderers/parts/samplers/visual/parts/defaults.d.ts +8 -0
  378. package/x/timeline/renderers/parts/samplers/visual/parts/defaults.js +14 -0
  379. package/x/timeline/renderers/parts/samplers/visual/parts/defaults.js.map +1 -0
  380. package/x/timeline/renderers/parts/samplers/visual/parts/image-sink.d.ts +11 -0
  381. package/x/timeline/renderers/parts/samplers/visual/parts/image-sink.js +36 -0
  382. package/x/timeline/renderers/parts/samplers/visual/parts/image-sink.js.map +1 -0
  383. package/x/timeline/renderers/parts/samplers/visual/parts/sample.d.ts +9 -0
  384. package/x/timeline/renderers/parts/samplers/visual/parts/sample.js +70 -0
  385. package/x/timeline/renderers/parts/samplers/visual/parts/sample.js.map +1 -0
  386. package/x/timeline/renderers/parts/samplers/visual/parts/sequence.d.ts +6 -0
  387. package/x/timeline/renderers/parts/samplers/visual/parts/sequence.js +63 -0
  388. package/x/timeline/renderers/parts/samplers/visual/parts/sequence.js.map +1 -0
  389. package/x/timeline/renderers/parts/samplers/visual/parts/transition.d.ts +3 -0
  390. package/x/timeline/renderers/parts/samplers/visual/parts/transition.js +18 -0
  391. package/x/timeline/renderers/parts/samplers/visual/parts/transition.js.map +1 -0
  392. package/x/timeline/renderers/parts/samplers/visual/parts/types.d.ts +9 -0
  393. package/x/timeline/renderers/parts/samplers/visual/parts/types.js +2 -0
  394. package/x/timeline/renderers/parts/samplers/visual/parts/types.js.map +1 -0
  395. package/x/timeline/renderers/parts/samplers/visual/parts/video-sink.d.ts +8 -0
  396. package/x/timeline/renderers/parts/samplers/visual/parts/video-sink.js +24 -0
  397. package/x/timeline/renderers/parts/samplers/visual/parts/video-sink.js.map +1 -0
  398. package/x/timeline/renderers/parts/samplers/visual/sampler.d.ts +7 -0
  399. package/x/timeline/renderers/parts/samplers/visual/sampler.js +20 -0
  400. package/x/timeline/renderers/parts/samplers/visual/sampler.js.map +1 -0
  401. package/x/timeline/renderers/parts/schedulers.d.ts +17 -0
  402. package/x/timeline/renderers/parts/schedulers.js +64 -0
  403. package/x/timeline/renderers/parts/schedulers.js.map +1 -0
  404. package/x/timeline/renderers/player/parts/playback.d.ts +39 -0
  405. package/x/timeline/renderers/player/parts/playback.js +160 -0
  406. package/x/timeline/renderers/player/parts/playback.js.map +1 -0
  407. package/x/timeline/renderers/player/player.d.ts +27 -0
  408. package/x/timeline/renderers/player/player.js +64 -0
  409. package/x/timeline/renderers/player/player.js.map +1 -0
  410. package/x/timeline/renderers/renderers.test.d.ts +33 -0
  411. package/x/timeline/renderers/renderers.test.js +321 -0
  412. package/x/timeline/renderers/renderers.test.js.map +1 -0
  413. package/x/timeline/sugar/helpers.d.ts +72 -0
  414. package/x/timeline/sugar/helpers.js +122 -0
  415. package/x/timeline/sugar/helpers.js.map +1 -0
  416. package/x/timeline/sugar/o.d.ts +59 -8
  417. package/x/timeline/sugar/o.js +326 -40
  418. package/x/timeline/sugar/o.js.map +1 -1
  419. package/x/timeline/sugar/omni.d.ts +11 -2
  420. package/x/timeline/sugar/omni.js +30 -9
  421. package/x/timeline/sugar/omni.js.map +1 -1
  422. package/x/timeline/sugar/omni.test.d.ts +27 -0
  423. package/x/timeline/sugar/omni.test.js +128 -0
  424. package/x/timeline/sugar/omni.test.js.map +1 -0
  425. package/x/timeline/types.d.ts +37 -0
  426. package/x/timeline/types.js +2 -0
  427. package/x/timeline/types.js.map +1 -0
  428. package/x/timeline/utils/anim.d.ts +3 -0
  429. package/x/timeline/utils/anim.js +40 -0
  430. package/x/timeline/utils/anim.js.map +1 -0
  431. package/x/timeline/utils/checksum.d.ts +3 -2
  432. package/x/timeline/utils/checksum.js +2 -1
  433. package/x/timeline/utils/checksum.js.map +1 -1
  434. package/x/timeline/utils/datafile.d.ts +5 -3
  435. package/x/timeline/utils/datafile.js +18 -5
  436. package/x/timeline/utils/datafile.js.map +1 -1
  437. package/x/timeline/utils/dummy-data.d.ts +1 -2
  438. package/x/timeline/utils/dummy-data.js +4 -2
  439. package/x/timeline/utils/dummy-data.js.map +1 -1
  440. package/x/timeline/utils/matrix.d.ts +17 -0
  441. package/x/timeline/utils/matrix.js +36 -0
  442. package/x/timeline/utils/matrix.js.map +1 -0
  443. package/x/timeline/utils/terps.d.ts +11 -0
  444. package/x/timeline/utils/terps.js +57 -0
  445. package/x/timeline/utils/terps.js.map +1 -0
  446. package/x/units/fps.d.ts +6 -0
  447. package/x/units/fps.js +2 -0
  448. package/x/units/fps.js.map +1 -0
  449. package/x/units/ms.d.ts +6 -0
  450. package/x/units/ms.js +2 -0
  451. package/x/units/ms.js.map +1 -0
  452. package/x/units/seconds.d.ts +6 -0
  453. package/x/units/seconds.js +2 -0
  454. package/x/units/seconds.js.map +1 -0
  455. package/x/webworkerAll-RLCTMSDD.js +2 -0
  456. package/x/webworkerAll-RLCTMSDD.js.map +7 -0
  457. package/s/tests.test.ts +0 -8
  458. package/s/timeline/parts/waveform.ts +0 -62
  459. package/s/timeline/sugar/omni-test.ts +0 -38
  460. package/x/tests.test.js +0 -6
  461. package/x/tests.test.js.map +0 -1
  462. package/x/timeline/parts/waveform.d.ts +0 -8
  463. package/x/timeline/parts/waveform.js +0 -51
  464. package/x/timeline/parts/waveform.js.map +0 -1
  465. package/x/timeline/sugar/omni-test.js +0 -22
  466. package/x/timeline/sugar/omni-test.js.map +0 -1
  467. /package/x/{tests.test.d.ts → features/bg-remover/worker.bundle.d.ts} +0 -0
  468. /package/x/{timeline/sugar/omni-test.d.ts → features/speech/transcribe/worker.bundle.d.ts} +0 -0
@@ -0,0 +1,133 @@
1
+
2
+ export type AudioPlanesInput = {
3
+ planes: Float32Array[]
4
+ sampleRate: number
5
+ timestamp: number
6
+ }
7
+
8
+ export type MixedChunk = {
9
+ planar: Float32Array
10
+ sampleRate: number
11
+ channels: number
12
+ frames: number
13
+ startFrame: number
14
+ }
15
+
16
+ type ActiveSample = {
17
+ startFrame: number
18
+ endFrame: number
19
+ data: Float32Array[]
20
+ }
21
+
22
+ export type AudioMixOptions = {
23
+ chunkFrames?: number
24
+ clamp?: boolean
25
+ }
26
+
27
+ export class AudioMix {
28
+ readonly #chunkFrames: number
29
+ readonly #clamp: boolean
30
+
31
+ constructor(options: AudioMixOptions = {}) {
32
+ this.#chunkFrames = options.chunkFrames ?? 1024
33
+ this.#clamp = options.clamp ?? true
34
+ }
35
+
36
+ async *mix(samples: AsyncIterable<AudioPlanesInput>): AsyncGenerator<MixedChunk> {
37
+ const chunkFrames = this.#chunkFrames
38
+ let sampleRate: number | null = null
39
+ let channels: number | null = null
40
+ const active: ActiveSample[] = []
41
+ let nextFrame = 0
42
+ let maxEnd = 0
43
+
44
+ for await (const input of samples) {
45
+ if (channels === null) {
46
+ channels = input.planes.length
47
+ sampleRate = input.sampleRate
48
+ } else {
49
+ if (input.planes.length !== channels) throw new Error(`Channel count changed`)
50
+ if (input.sampleRate !== sampleRate) throw new Error(`Sample rate changed`)
51
+ }
52
+
53
+ const inputStart = Math.round(input.timestamp * sampleRate)
54
+ const frames = input.planes[0]?.length ?? 0
55
+
56
+ while (nextFrame + chunkFrames <= inputStart) {
57
+ yield this.#processChunk(active, nextFrame, channels, sampleRate)
58
+ nextFrame += chunkFrames
59
+ }
60
+
61
+ active.push({
62
+ startFrame: inputStart,
63
+ endFrame: inputStart + frames,
64
+ data: input.planes
65
+ })
66
+
67
+ maxEnd = Math.max(maxEnd, inputStart + frames)
68
+ }
69
+
70
+ if (channels !== null && sampleRate !== null) {
71
+ while (nextFrame < maxEnd) {
72
+ yield this.#processChunk(active, nextFrame, channels, sampleRate)
73
+ nextFrame += chunkFrames
74
+ }
75
+ }
76
+ }
77
+
78
+ #processChunk(
79
+ active: ActiveSample[],
80
+ currentStartFrame: number,
81
+ channels: number,
82
+ sampleRate: number
83
+ ): MixedChunk {
84
+ const chunkFrames = this.#chunkFrames
85
+ const outputBuffer = new Float32Array(channels * chunkFrames)
86
+ const chunkEnd = currentStartFrame + chunkFrames
87
+
88
+ for (let ch = 0; ch < channels; ch++) {
89
+ const channelOffset = ch * chunkFrames
90
+ const outChannelView = outputBuffer.subarray(channelOffset, channelOffset + chunkFrames)
91
+
92
+ for (const sample of active) {
93
+ const data = sample.data[ch]
94
+ if (!data) continue
95
+
96
+ const start = Math.max(currentStartFrame, sample.startFrame)
97
+ const end = Math.min(chunkEnd, sample.endFrame)
98
+
99
+ if (start >= end) continue
100
+
101
+ const dstIdx = start - currentStartFrame
102
+ const srcIdx = start - sample.startFrame
103
+ const len = end - start
104
+
105
+ for (let i = 0; i < len; i++) {
106
+ outChannelView[dstIdx + i] += data[srcIdx + i]
107
+ }
108
+ }
109
+
110
+ if (this.#clamp) {
111
+ for (let i = 0; i < chunkFrames; i++) {
112
+ const v = outChannelView[i]
113
+ outChannelView[i] = v < -1.0 ? -1.0 : (v > 1.0 ? 1.0 : v)
114
+ }
115
+ }
116
+ }
117
+
118
+ for (let i = active.length - 1; i >= 0; i--) {
119
+ if (active[i].endFrame <= chunkEnd) {
120
+ active.splice(i, 1)
121
+ }
122
+ }
123
+
124
+ return {
125
+ planar: outputBuffer,
126
+ sampleRate,
127
+ channels,
128
+ frames: chunkFrames,
129
+ startFrame: currentStartFrame
130
+ }
131
+ }
132
+ }
133
+
@@ -0,0 +1,291 @@
1
+
2
+ import {ALL_FORMATS, Input, VideoSampleSink} from "mediabunny"
3
+
4
+ import {ms, Ms} from "../../../../units/ms.js"
5
+ import {Driver} from "../../../../driver/driver.js"
6
+ import {TimelineFile} from "../../../parts/basics.js"
7
+ import {DecoderSource} from "../../../../driver/fns/schematic.js"
8
+ import {loadDecoderSource} from "../../../../driver/utils/load-decoder-source.js"
9
+ import {createVisualSampler} from "../../parts/samplers/visual/sampler.js"
10
+
11
+ type StreamCursor<T> = {
12
+ next(target: number): Promise<T | undefined>
13
+ cancel(): Promise<void>
14
+ }
15
+
16
+ type VideoFrameCursor = StreamCursor<VideoFrame>
17
+
18
+ abstract class BaseVisualSampler {
19
+ readonly #videoCursors = new Map<number, VideoFrameCursor>()
20
+ readonly #sampler
21
+
22
+ constructor(
23
+ protected driver: Driver,
24
+ protected resolveMedia: (hash: string) => DecoderSource,
25
+ protected timeline: TimelineFile
26
+ ) {
27
+ this.#sampler = createVisualSampler(this.resolveMedia, (item, time) => {
28
+ const targetUs = toUs(ms(item.start + time))
29
+ let cursor = this.#videoCursors.get(item.id)
30
+
31
+ if (!cursor) {
32
+ const source = this.resolveMedia(item.mediaHash)
33
+ const endUs = toUs(ms(item.start + item.duration))
34
+ cursor = this.createCursor(source, targetUs, endUs)
35
+ this.#videoCursors.set(item.id, cursor)
36
+ }
37
+
38
+ return cursor.next(targetUs)
39
+ })
40
+ }
41
+
42
+ protected abstract createCursor(source: DecoderSource, startUs: number, endUs: number): VideoFrameCursor
43
+
44
+ protected sample(timecode: Ms) {
45
+ return this.#sampler.sample(this.timeline, timecode)
46
+ }
47
+
48
+ async cancel() {
49
+ await Promise.all([...this.#videoCursors.values()].map(c => c.cancel()))
50
+ this.#videoCursors.clear()
51
+ }
52
+ }
53
+
54
+ /**
55
+ * forward-only frame cursor optimized for export purposes.
56
+ * it uses mediabunny internally so the support for non-clients
57
+ * should be done from mediabunny custom decoder/encoder
58
+ */
59
+
60
+ export class CursorVisualSampler extends BaseVisualSampler {
61
+ #lastTimecode = -Infinity
62
+
63
+ next(timecode: Ms) {
64
+ if (timecode < this.#lastTimecode)
65
+ throw new Error(`Forward-only cursor regression: ${timecode}ms < ${this.#lastTimecode}ms`)
66
+
67
+ this.#lastTimecode = timecode
68
+ return this.sample(timecode)
69
+ }
70
+
71
+ protected createCursor(source: DecoderSource, startUs: number, endUs: number): VideoFrameCursor {
72
+ const video = this.driver.decodeVideo({source, start: startUs / 1_000_000, end: endUs / 1_000_000})
73
+ const reader = video.readable.getReader()
74
+
75
+ let current: VideoFrame | null = null
76
+ let nextPromise: Promise<VideoFrame | null> | null = null
77
+ let ended = false
78
+
79
+ const readNext = async () => {
80
+ if (ended) return null
81
+ const {done, value} = await reader.read()
82
+ if (done) return (ended = true, null)
83
+
84
+ const frame = new VideoFrame(value)
85
+ value.close()
86
+ return frame
87
+ }
88
+
89
+ return {
90
+ async next(targetUs: number): Promise<VideoFrame | undefined> {
91
+ current ??= await readNext()
92
+ if (!current) return undefined
93
+
94
+ while (true) {
95
+ nextPromise ??= readNext()
96
+ const nextFrame = await nextPromise
97
+
98
+ if (!nextFrame) return new VideoFrame(current)
99
+
100
+ const currentUs = current.timestamp ?? -Infinity
101
+ const nextUs = nextFrame.timestamp ?? currentUs
102
+
103
+ if (nextUs < targetUs) {
104
+ current.close()
105
+ current = nextFrame
106
+ nextPromise = null
107
+ continue
108
+ }
109
+
110
+ const useNext = Math.abs(nextUs - targetUs) < Math.abs(currentUs - targetUs)
111
+
112
+ if (useNext) {
113
+ current.close()
114
+ current = nextFrame
115
+ nextPromise = null
116
+ continue
117
+ }
118
+
119
+ return new VideoFrame(current)
120
+ }
121
+ },
122
+
123
+ async cancel() {
124
+ const pending = nextPromise
125
+ nextPromise = null
126
+ ended = true
127
+
128
+ const buffered = await pending?.catch(() => null)
129
+ buffered?.close()
130
+
131
+ current?.close()
132
+ current = null
133
+
134
+ video.cancel()
135
+ }
136
+ }
137
+ }
138
+ }
139
+
140
+ export class ReverseCursorVisualSampler extends BaseVisualSampler {
141
+ #lastTimecode = Infinity
142
+
143
+ next(timecode: Ms) {
144
+ if (timecode > this.#lastTimecode)
145
+ throw new Error(`Reverse-only cursor regression: ${timecode}ms > ${this.#lastTimecode}ms`)
146
+
147
+ this.#lastTimecode = timecode
148
+ return this.sample(timecode)
149
+ }
150
+
151
+ protected createCursor(source: DecoderSource, startUs: number, endUs: number): VideoFrameCursor {
152
+ const windowUs = 1_000_000
153
+ const prefetchThreshold = windowUs * 0.5
154
+
155
+ let frames: VideoFrame[] = []
156
+ let windowStart = Infinity
157
+ let windowEnd = -Infinity
158
+ let input: Input | null = null
159
+ let sink: VideoSampleSink | null = null
160
+ let prefetchPromise: Promise<{frames: VideoFrame[], windowStart: number, windowEnd: number}> | null = null
161
+ let activeFetches = 0
162
+ let idle: Promise<void> = Promise.resolve()
163
+ let resolveIdle: (() => void) | null = null
164
+ let canceled = false
165
+
166
+ const clear = () => {
167
+ for (const frame of frames)
168
+ frame.close()
169
+ frames = []
170
+ }
171
+
172
+ const startFetch = () => {
173
+ if (activeFetches++ === 0)
174
+ idle = new Promise<void>(resolve => resolveIdle = resolve)
175
+ }
176
+
177
+ const endFetch = () => {
178
+ if (--activeFetches === 0) {
179
+ resolveIdle?.()
180
+ resolveIdle = null
181
+ }
182
+ }
183
+
184
+ const getSink = async () => {
185
+ if (sink) return sink
186
+
187
+ input = new Input({
188
+ source: await loadDecoderSource(source),
189
+ formats: ALL_FORMATS,
190
+ })
191
+
192
+ const track = await input.getPrimaryVideoTrack()
193
+ sink = track && await track.canDecode()
194
+ ? new VideoSampleSink(track)
195
+ : null
196
+
197
+ return sink
198
+ }
199
+
200
+ const fetchFrames = async (targetUs: number) => {
201
+ startFetch()
202
+ const wEnd = Math.min(endUs, targetUs + 1)
203
+ const wStart = Math.max(startUs, wEnd - windowUs)
204
+ const newFrames: VideoFrame[] = []
205
+
206
+ const videoSink = await getSink()
207
+ if (videoSink) {
208
+ for await (const sample of videoSink.samples(wStart / 1_000_000, wEnd / 1_000_000)) {
209
+ newFrames.push(sample.toVideoFrame())
210
+ sample.close()
211
+ }
212
+ }
213
+
214
+ endFetch()
215
+ return {frames: newFrames, windowStart: wStart, windowEnd: wEnd}
216
+ }
217
+
218
+ const loadWindow = async (targetUs: number) => {
219
+ clear()
220
+ const result = await fetchFrames(targetUs)
221
+ frames = result.frames
222
+ windowStart = result.windowStart
223
+ windowEnd = result.windowEnd
224
+ }
225
+
226
+ return {
227
+ async next(targetUs: number): Promise<VideoFrame | undefined> {
228
+ if (canceled)
229
+ return undefined
230
+
231
+ if (targetUs < windowStart || targetUs > windowEnd) {
232
+ if (prefetchPromise) {
233
+ const prefetched = await prefetchPromise
234
+ prefetchPromise = null
235
+
236
+ if (canceled) {
237
+ for (const f of prefetched.frames) f.close()
238
+ return undefined
239
+ }
240
+
241
+ if (targetUs >= prefetched.windowStart && targetUs <= prefetched.windowEnd) {
242
+ clear()
243
+ frames = prefetched.frames
244
+ windowStart = prefetched.windowStart
245
+ windowEnd = prefetched.windowEnd
246
+ } else {
247
+ for (const f of prefetched.frames) f.close()
248
+ await loadWindow(targetUs)
249
+ }
250
+ } else {
251
+ await loadWindow(targetUs)
252
+ }
253
+ }
254
+
255
+ if (!prefetchPromise && targetUs < windowStart + prefetchThreshold && windowStart > startUs)
256
+ prefetchPromise = fetchFrames(windowStart - 1)
257
+
258
+ let best: VideoFrame | undefined
259
+ let bestDistance = Infinity
260
+
261
+ for (const frame of frames) {
262
+ const distance = Math.abs((frame.timestamp ?? targetUs) - targetUs)
263
+ if (distance < bestDistance) {
264
+ best = frame
265
+ bestDistance = distance
266
+ }
267
+ }
268
+
269
+ return best ? new VideoFrame(best) : undefined
270
+ },
271
+
272
+ async cancel() {
273
+ canceled = true
274
+ const pending = prefetchPromise
275
+ prefetchPromise = null
276
+
277
+ const prefetched = await pending?.catch(() => null)
278
+ if (prefetched)
279
+ for (const f of prefetched.frames) f.close()
280
+
281
+ await idle
282
+ clear()
283
+ input?.dispose()
284
+ input = null
285
+ sink = null
286
+ }
287
+ }
288
+ }
289
+ }
290
+
291
+ const toUs = (ms: Ms) => Math.round(ms * 1_000)
@@ -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
+