@omnimedia/omnitool 1.1.0-7 → 1.1.0-70

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 (410) hide show
  1. package/README.md +143 -80
  2. package/package.json +18 -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 +24 -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 +11 -5
  18. package/s/driver/fns/work.ts +65 -189
  19. package/s/driver/parts/compositor.ts +187 -0
  20. package/s/driver/parts/machina.ts +19 -20
  21. package/s/index.html.ts +103 -25
  22. package/s/index.ts +1 -0
  23. package/s/tests.bundle.ts +11 -0
  24. package/s/tests.html.ts +28 -0
  25. package/s/timeline/index.ts +5 -0
  26. package/s/timeline/parts/filmstrip.ts +43 -16
  27. package/s/timeline/parts/item.ts +27 -6
  28. package/s/timeline/parts/media.ts +12 -2
  29. package/s/timeline/parts/resource-pool.ts +8 -5
  30. package/s/timeline/parts/resource.ts +3 -0
  31. package/s/timeline/parts/waveform/parts/collect.ts +72 -0
  32. package/s/timeline/parts/waveform/parts/render.ts +45 -0
  33. package/s/timeline/parts/waveform/parts/types.ts +24 -0
  34. package/s/timeline/parts/waveform/waveform.ts +161 -0
  35. package/s/timeline/renderers/export/parts/audio-gain.ts +17 -0
  36. package/s/timeline/renderers/export/parts/audio-mix.ts +133 -0
  37. package/s/timeline/renderers/export/parts/cursor.ts +129 -0
  38. package/s/timeline/renderers/export/parts/produce-audio.ts +64 -0
  39. package/s/timeline/renderers/export/parts/produce-video.ts +49 -0
  40. package/s/timeline/renderers/export/parts/resamplers.ts +48 -0
  41. package/s/timeline/renderers/export/produce.ts +28 -0
  42. package/s/timeline/renderers/parts/handy.ts +360 -0
  43. package/s/timeline/renderers/parts/samplers/audio/parts/find.ts +19 -0
  44. package/s/timeline/renderers/parts/samplers/audio/parts/init.ts +60 -0
  45. package/s/timeline/renderers/parts/samplers/audio/parts/sink.ts +38 -0
  46. package/s/timeline/renderers/parts/samplers/audio/parts/types.ts +16 -0
  47. package/s/timeline/renderers/parts/samplers/audio/sampler.ts +35 -0
  48. package/s/timeline/renderers/parts/samplers/visual/parts/defaults.ts +16 -0
  49. package/s/timeline/renderers/parts/samplers/visual/parts/sample.ts +59 -0
  50. package/s/timeline/renderers/parts/samplers/visual/parts/sequence.ts +111 -0
  51. package/s/timeline/renderers/parts/samplers/visual/parts/sink.ts +38 -0
  52. package/s/timeline/renderers/parts/samplers/visual/parts/transition.ts +28 -0
  53. package/s/timeline/renderers/parts/samplers/visual/parts/types.ts +10 -0
  54. package/s/timeline/renderers/parts/samplers/visual/sampler.ts +28 -0
  55. package/s/timeline/renderers/parts/schedulers.ts +96 -0
  56. package/s/timeline/renderers/player/parts/playback.ts +159 -0
  57. package/s/timeline/renderers/player/player.ts +77 -0
  58. package/s/timeline/renderers/renderers.test.ts +385 -0
  59. package/s/timeline/sugar/helpers.ts +85 -0
  60. package/s/timeline/sugar/o.ts +138 -57
  61. package/s/timeline/sugar/omni.test.ts +210 -0
  62. package/s/timeline/sugar/omni.ts +35 -12
  63. package/s/timeline/utils/checksum.ts +3 -1
  64. package/s/timeline/utils/datafile.ts +15 -4
  65. package/s/timeline/utils/dummy-data.ts +3 -3
  66. package/s/units/fps.ts +8 -0
  67. package/s/units/ms.ts +8 -0
  68. package/s/units/seconds.ts +8 -0
  69. package/x/WebGLRenderer-7X274AYV.js +2 -0
  70. package/x/WebGLRenderer-7X274AYV.js.map +7 -0
  71. package/x/WebGPURenderer-XMCMEXAO.js +2 -0
  72. package/x/WebGPURenderer-XMCMEXAO.js.map +7 -0
  73. package/x/browserAll-6TVTCHHE.js +2 -0
  74. package/x/browserAll-6TVTCHHE.js.map +7 -0
  75. package/x/chunk-4ONWQOPX.js +157 -0
  76. package/x/chunk-4ONWQOPX.js.map +7 -0
  77. package/x/chunk-63NSCXPX.js +2 -0
  78. package/x/chunk-63NSCXPX.js.map +7 -0
  79. package/x/chunk-A45M2HJC.js +2 -0
  80. package/x/chunk-A45M2HJC.js.map +7 -0
  81. package/x/chunk-OTQK6FAJ.js +15 -0
  82. package/x/chunk-OTQK6FAJ.js.map +7 -0
  83. package/x/chunk-Q7JBQNE4.js +42 -0
  84. package/x/chunk-Q7JBQNE4.js.map +7 -0
  85. package/x/chunk-W33LM336.js +393 -0
  86. package/x/chunk-W33LM336.js.map +7 -0
  87. package/x/chunk-W5CN46AR.js +327 -0
  88. package/x/chunk-W5CN46AR.js.map +7 -0
  89. package/x/chunk-WFT3KTZG.js +269 -0
  90. package/x/chunk-WFT3KTZG.js.map +7 -0
  91. package/x/context.d.ts +1 -4
  92. package/x/context.js +1 -5
  93. package/x/context.js.map +1 -1
  94. package/x/demo/WebGLRenderer-NLGJGAXK.js +2 -0
  95. package/x/demo/WebGLRenderer-NLGJGAXK.js.map +7 -0
  96. package/x/demo/WebGPURenderer-RBOFXPL5.js +2 -0
  97. package/x/demo/WebGPURenderer-RBOFXPL5.js.map +7 -0
  98. package/x/demo/browserAll-5AZHDDG6.js +2 -0
  99. package/x/demo/browserAll-5AZHDDG6.js.map +7 -0
  100. package/x/demo/chunk-5ZZYIILO.js +393 -0
  101. package/x/demo/chunk-5ZZYIILO.js.map +7 -0
  102. package/x/demo/chunk-P3PTHHFE.js +42 -0
  103. package/x/demo/chunk-P3PTHHFE.js.map +7 -0
  104. package/x/demo/chunk-PYG4RZZ2.js +269 -0
  105. package/x/demo/chunk-PYG4RZZ2.js.map +7 -0
  106. package/x/demo/chunk-Q4MWBZHL.js +157 -0
  107. package/x/demo/chunk-Q4MWBZHL.js.map +7 -0
  108. package/x/demo/chunk-T3METYEY.js +15 -0
  109. package/x/demo/chunk-T3METYEY.js.map +7 -0
  110. package/x/demo/chunk-USLRKDKD.js +2 -0
  111. package/x/demo/chunk-USLRKDKD.js.map +7 -0
  112. package/x/demo/chunk-YISSXWBT.js +327 -0
  113. package/x/demo/chunk-YISSXWBT.js.map +7 -0
  114. package/x/demo/chunk-YJQWVIHX.js +2 -0
  115. package/x/demo/chunk-YJQWVIHX.js.map +7 -0
  116. package/x/demo/demo.bundle.js +94 -40
  117. package/x/demo/demo.bundle.js.map +1 -1
  118. package/x/demo/demo.bundle.min.js +2421 -81
  119. package/x/demo/demo.bundle.min.js.map +4 -4
  120. package/x/demo/demo.css +244 -14
  121. package/x/demo/routines/export-test.d.ts +2 -0
  122. package/x/demo/routines/export-test.js +10 -0
  123. package/x/demo/routines/export-test.js.map +1 -0
  124. package/x/demo/routines/filmstrip-test.d.ts +1 -1
  125. package/x/demo/routines/filmstrip-test.js +20 -17
  126. package/x/demo/routines/filmstrip-test.js.map +1 -1
  127. package/x/demo/routines/load-video.d.ts +1 -1
  128. package/x/demo/routines/load-video.js +1 -2
  129. package/x/demo/routines/load-video.js.map +1 -1
  130. package/x/demo/routines/playback-test.d.ts +2 -0
  131. package/x/demo/routines/playback-test.js +51 -0
  132. package/x/demo/routines/playback-test.js.map +1 -0
  133. package/x/demo/routines/timeline-setup.d.ts +6 -0
  134. package/x/demo/routines/timeline-setup.js +13 -0
  135. package/x/demo/routines/timeline-setup.js.map +1 -0
  136. package/x/demo/routines/transcode-test.js +15 -5
  137. package/x/demo/routines/transcode-test.js.map +1 -1
  138. package/x/demo/routines/transitions-test.js +2 -2
  139. package/x/demo/routines/transitions-test.js.map +1 -1
  140. package/x/demo/routines/waveform-test.d.ts +2 -1
  141. package/x/demo/routines/waveform-test.js +29 -8
  142. package/x/demo/routines/waveform-test.js.map +1 -1
  143. package/x/demo/webworkerAll-QKIC5O27.js +2 -0
  144. package/x/demo/webworkerAll-QKIC5O27.js.map +7 -0
  145. package/x/driver/driver-worker.d.ts +1 -0
  146. package/x/driver/driver-worker.js +6 -0
  147. package/x/driver/driver-worker.js.map +1 -0
  148. package/x/driver/driver.d.ts +25 -8
  149. package/x/driver/driver.js +43 -39
  150. package/x/driver/driver.js.map +1 -1
  151. package/x/driver/driver.test.js +1 -1
  152. package/x/driver/driver.test.js.map +1 -1
  153. package/x/driver/driver.worker.bundle.min.js +117 -3506
  154. package/x/driver/driver.worker.bundle.min.js.map +4 -4
  155. package/x/driver/fns/host.d.ts +3 -2
  156. package/x/driver/fns/schematic.d.ts +11 -4
  157. package/x/driver/fns/work.d.ts +4 -4
  158. package/x/driver/fns/work.js +55 -155
  159. package/x/driver/fns/work.js.map +1 -1
  160. package/x/driver/parts/compositor.d.ts +20 -0
  161. package/x/driver/parts/compositor.js +159 -0
  162. package/x/driver/parts/compositor.js.map +1 -0
  163. package/x/driver/parts/machina.d.ts +0 -20
  164. package/x/driver/parts/machina.js +6 -10
  165. package/x/driver/parts/machina.js.map +1 -1
  166. package/x/features/speech/transcribe/parts/prep-audio.d.ts +1 -1
  167. package/x/features/speech/transcribe/worker.bundle.min.js +899 -899
  168. package/x/features/speech/transcribe/worker.bundle.min.js.map +4 -4
  169. package/x/index.d.ts +1 -0
  170. package/x/index.html +347 -38
  171. package/x/index.html.js +103 -24
  172. package/x/index.html.js.map +1 -1
  173. package/x/index.js +1 -0
  174. package/x/index.js.map +1 -1
  175. package/x/tests.bundle.js +8 -0
  176. package/x/tests.bundle.js.map +1 -0
  177. package/x/tests.bundle.min.js +2464 -0
  178. package/x/tests.bundle.min.js.map +7 -0
  179. package/x/tests.html +316 -0
  180. package/x/tests.html.d.ts +2 -0
  181. package/x/tests.html.js +22 -0
  182. package/x/tests.html.js.map +1 -0
  183. package/x/timeline/index.d.ts +4 -0
  184. package/x/timeline/index.js +4 -0
  185. package/x/timeline/index.js.map +1 -1
  186. package/x/timeline/parts/filmstrip.d.ts +4 -3
  187. package/x/timeline/parts/filmstrip.js +29 -10
  188. package/x/timeline/parts/filmstrip.js.map +1 -1
  189. package/x/timeline/parts/item.d.ts +20 -3
  190. package/x/timeline/parts/item.js +1 -0
  191. package/x/timeline/parts/item.js.map +1 -1
  192. package/x/timeline/parts/media.d.ts +2 -0
  193. package/x/timeline/parts/media.js +11 -2
  194. package/x/timeline/parts/media.js.map +1 -1
  195. package/x/timeline/parts/resource-pool.d.ts +3 -0
  196. package/x/timeline/parts/resource-pool.js +7 -4
  197. package/x/timeline/parts/resource-pool.js.map +1 -1
  198. package/x/timeline/parts/resource.d.ts +3 -0
  199. package/x/timeline/parts/waveform/parts/collect.d.ts +11 -0
  200. package/x/timeline/parts/waveform/parts/collect.js +56 -0
  201. package/x/timeline/parts/waveform/parts/collect.js.map +1 -0
  202. package/x/timeline/parts/waveform/parts/render.d.ts +5 -0
  203. package/x/timeline/parts/waveform/parts/render.js +29 -0
  204. package/x/timeline/parts/waveform/parts/render.js.map +1 -0
  205. package/x/timeline/parts/waveform/parts/types.d.ts +21 -0
  206. package/x/timeline/parts/waveform/parts/types.js.map +1 -0
  207. package/x/timeline/parts/waveform/waveform.d.ts +19 -0
  208. package/x/timeline/parts/waveform/waveform.js +133 -0
  209. package/x/timeline/parts/waveform/waveform.js.map +1 -0
  210. package/x/timeline/renderers/export/parts/audio-gain.d.ts +1 -0
  211. package/x/timeline/renderers/export/parts/audio-gain.js +13 -0
  212. package/x/timeline/renderers/export/parts/audio-gain.js.map +1 -0
  213. package/x/timeline/renderers/export/parts/audio-mix.d.ts +21 -0
  214. package/x/timeline/renderers/export/parts/audio-mix.js +89 -0
  215. package/x/timeline/renderers/export/parts/audio-mix.js.map +1 -0
  216. package/x/timeline/renderers/export/parts/cursor.d.ts +18 -0
  217. package/x/timeline/renderers/export/parts/cursor.js +99 -0
  218. package/x/timeline/renderers/export/parts/cursor.js.map +1 -0
  219. package/x/timeline/renderers/export/parts/produce-audio.d.ts +6 -0
  220. package/x/timeline/renderers/export/parts/produce-audio.js +41 -0
  221. package/x/timeline/renderers/export/parts/produce-audio.js.map +1 -0
  222. package/x/timeline/renderers/export/parts/produce-video.d.ts +10 -0
  223. package/x/timeline/renderers/export/parts/produce-video.js +26 -0
  224. package/x/timeline/renderers/export/parts/produce-video.js.map +1 -0
  225. package/x/timeline/renderers/export/parts/resamplers.d.ts +12 -0
  226. package/x/timeline/renderers/export/parts/resamplers.js +29 -0
  227. package/x/timeline/renderers/export/parts/resamplers.js.map +1 -0
  228. package/x/timeline/renderers/export/produce.d.ts +13 -0
  229. package/x/timeline/renderers/export/produce.js +15 -0
  230. package/x/timeline/renderers/export/produce.js.map +1 -0
  231. package/x/timeline/renderers/parts/handy.d.ts +30 -0
  232. package/x/timeline/renderers/parts/handy.js +219 -0
  233. package/x/timeline/renderers/parts/handy.js.map +1 -0
  234. package/x/timeline/renderers/parts/samplers/audio/parts/find.d.ts +6 -0
  235. package/x/timeline/renderers/parts/samplers/audio/parts/find.js +15 -0
  236. package/x/timeline/renderers/parts/samplers/audio/parts/find.js.map +1 -0
  237. package/x/timeline/renderers/parts/samplers/audio/parts/init.d.ts +5 -0
  238. package/x/timeline/renderers/parts/samplers/audio/parts/init.js +40 -0
  239. package/x/timeline/renderers/parts/samplers/audio/parts/init.js.map +1 -0
  240. package/x/timeline/renderers/parts/samplers/audio/parts/sink.d.ts +8 -0
  241. package/x/timeline/renderers/parts/samplers/audio/parts/sink.js +24 -0
  242. package/x/timeline/renderers/parts/samplers/audio/parts/sink.js.map +1 -0
  243. package/x/timeline/renderers/parts/samplers/audio/parts/types.d.ts +14 -0
  244. package/x/timeline/renderers/parts/samplers/audio/parts/types.js +2 -0
  245. package/x/timeline/renderers/parts/samplers/audio/parts/types.js.map +1 -0
  246. package/x/timeline/renderers/parts/samplers/audio/sampler.d.ts +11 -0
  247. package/x/timeline/renderers/parts/samplers/audio/sampler.js +22 -0
  248. package/x/timeline/renderers/parts/samplers/audio/sampler.js.map +1 -0
  249. package/x/timeline/renderers/parts/samplers/visual/parts/defaults.d.ts +5 -0
  250. package/x/timeline/renderers/parts/samplers/visual/parts/defaults.js +10 -0
  251. package/x/timeline/renderers/parts/samplers/visual/parts/defaults.js.map +1 -0
  252. package/x/timeline/renderers/parts/samplers/visual/parts/sample.d.ts +5 -0
  253. package/x/timeline/renderers/parts/samplers/visual/parts/sample.js +38 -0
  254. package/x/timeline/renderers/parts/samplers/visual/parts/sample.js.map +1 -0
  255. package/x/timeline/renderers/parts/samplers/visual/parts/sequence.d.ts +5 -0
  256. package/x/timeline/renderers/parts/samplers/visual/parts/sequence.js +75 -0
  257. package/x/timeline/renderers/parts/samplers/visual/parts/sequence.js.map +1 -0
  258. package/x/timeline/renderers/parts/samplers/visual/parts/sink.d.ts +8 -0
  259. package/x/timeline/renderers/parts/samplers/visual/parts/sink.js +24 -0
  260. package/x/timeline/renderers/parts/samplers/visual/parts/sink.js.map +1 -0
  261. package/x/timeline/renderers/parts/samplers/visual/parts/transition.d.ts +3 -0
  262. package/x/timeline/renderers/parts/samplers/visual/parts/transition.js +18 -0
  263. package/x/timeline/renderers/parts/samplers/visual/parts/transition.js.map +1 -0
  264. package/x/timeline/renderers/parts/samplers/visual/parts/types.d.ts +8 -0
  265. package/x/timeline/renderers/parts/samplers/visual/parts/types.js +2 -0
  266. package/x/timeline/renderers/parts/samplers/visual/parts/types.js.map +1 -0
  267. package/x/timeline/renderers/parts/samplers/visual/sampler.d.ts +7 -0
  268. package/x/timeline/renderers/parts/samplers/visual/sampler.js +17 -0
  269. package/x/timeline/renderers/parts/samplers/visual/sampler.js.map +1 -0
  270. package/x/timeline/renderers/parts/schedulers.d.ts +17 -0
  271. package/x/timeline/renderers/parts/schedulers.js +64 -0
  272. package/x/timeline/renderers/parts/schedulers.js.map +1 -0
  273. package/x/timeline/renderers/player/parts/playback.d.ts +36 -0
  274. package/x/timeline/renderers/player/parts/playback.js +113 -0
  275. package/x/timeline/renderers/player/parts/playback.js.map +1 -0
  276. package/x/timeline/renderers/player/player.d.ts +25 -0
  277. package/x/timeline/renderers/player/player.js +56 -0
  278. package/x/timeline/renderers/player/player.js.map +1 -0
  279. package/x/timeline/renderers/renderers.test.d.ts +32 -0
  280. package/x/timeline/renderers/renderers.test.js +305 -0
  281. package/x/timeline/renderers/renderers.test.js.map +1 -0
  282. package/x/timeline/sugar/helpers.d.ts +30 -0
  283. package/x/timeline/sugar/helpers.js +46 -0
  284. package/x/timeline/sugar/helpers.js.map +1 -0
  285. package/x/timeline/sugar/o.d.ts +28 -13
  286. package/x/timeline/sugar/o.js +108 -51
  287. package/x/timeline/sugar/o.js.map +1 -1
  288. package/x/timeline/sugar/omni.d.ts +11 -6
  289. package/x/timeline/sugar/omni.js +28 -8
  290. package/x/timeline/sugar/omni.js.map +1 -1
  291. package/x/timeline/sugar/omni.test.d.ts +27 -0
  292. package/x/timeline/sugar/omni.test.js +128 -0
  293. package/x/timeline/sugar/omni.test.js.map +1 -0
  294. package/x/timeline/utils/checksum.d.ts +3 -2
  295. package/x/timeline/utils/checksum.js.map +1 -1
  296. package/x/timeline/utils/datafile.d.ts +5 -3
  297. package/x/timeline/utils/datafile.js +18 -5
  298. package/x/timeline/utils/datafile.js.map +1 -1
  299. package/x/timeline/utils/dummy-data.d.ts +1 -2
  300. package/x/timeline/utils/dummy-data.js +4 -2
  301. package/x/timeline/utils/dummy-data.js.map +1 -1
  302. package/x/units/fps.d.ts +6 -0
  303. package/x/units/fps.js +2 -0
  304. package/x/units/fps.js.map +1 -0
  305. package/x/units/ms.d.ts +6 -0
  306. package/x/units/ms.js +2 -0
  307. package/x/units/ms.js.map +1 -0
  308. package/x/units/seconds.d.ts +6 -0
  309. package/x/units/seconds.js +2 -0
  310. package/x/units/seconds.js.map +1 -0
  311. package/x/webworkerAll-VVIU3M54.js +2 -0
  312. package/x/webworkerAll-VVIU3M54.js.map +7 -0
  313. package/s/tests.test.ts +0 -8
  314. package/s/timeline/parts/compositor/export.ts +0 -77
  315. package/s/timeline/parts/compositor/parts/html-tree.ts +0 -37
  316. package/s/timeline/parts/compositor/parts/schedulers.ts +0 -85
  317. package/s/timeline/parts/compositor/parts/tree-builder.ts +0 -184
  318. package/s/timeline/parts/compositor/parts/webcodecs-tree.ts +0 -30
  319. package/s/timeline/parts/compositor/playback.ts +0 -81
  320. package/s/timeline/parts/compositor/samplers/html.ts +0 -115
  321. package/s/timeline/parts/compositor/samplers/webcodecs.ts +0 -60
  322. package/s/timeline/parts/waveform.ts +0 -62
  323. package/s/timeline/sugar/builders.ts +0 -102
  324. package/s/timeline/sugar/omni-test.ts +0 -38
  325. package/s/timeline/timeline.ts +0 -22
  326. package/s/timeline/utils/audio-stream.ts +0 -15
  327. package/s/timeline/utils/video-cursor.ts +0 -40
  328. package/s/tools/common/loader.ts +0 -26
  329. package/s/tools/common/transformer-pipeline.ts +0 -26
  330. package/s/tools/speech-recognition/common/model.ts +0 -26
  331. package/s/tools/speech-recognition/whisper/fns/host.ts +0 -25
  332. package/s/tools/speech-recognition/whisper/fns/schematic.ts +0 -23
  333. package/s/tools/speech-recognition/whisper/fns/work.ts +0 -91
  334. package/s/tools/speech-recognition/whisper/parts/types.ts +0 -38
  335. package/s/tools/speech-recognition/whisper/parts/worker.bundle.ts +0 -7
  336. package/s/tools/speech-recognition/whisper/tool.ts +0 -70
  337. package/x/tests.test.js +0 -6
  338. package/x/tests.test.js.map +0 -1
  339. package/x/timeline/parts/compositor/export.d.ts +0 -9
  340. package/x/timeline/parts/compositor/export.js +0 -64
  341. package/x/timeline/parts/compositor/export.js.map +0 -1
  342. package/x/timeline/parts/compositor/parts/html-tree.d.ts +0 -3
  343. package/x/timeline/parts/compositor/parts/html-tree.js +0 -40
  344. package/x/timeline/parts/compositor/parts/html-tree.js.map +0 -1
  345. package/x/timeline/parts/compositor/parts/schedulers.d.ts +0 -15
  346. package/x/timeline/parts/compositor/parts/schedulers.js +0 -64
  347. package/x/timeline/parts/compositor/parts/schedulers.js.map +0 -1
  348. package/x/timeline/parts/compositor/parts/tree-builder.d.ts +0 -37
  349. package/x/timeline/parts/compositor/parts/tree-builder.js +0 -147
  350. package/x/timeline/parts/compositor/parts/tree-builder.js.map +0 -1
  351. package/x/timeline/parts/compositor/parts/webcodecs-tree.d.ts +0 -3
  352. package/x/timeline/parts/compositor/parts/webcodecs-tree.js +0 -28
  353. package/x/timeline/parts/compositor/parts/webcodecs-tree.js.map +0 -1
  354. package/x/timeline/parts/compositor/playback.d.ts +0 -19
  355. package/x/timeline/parts/compositor/playback.js +0 -71
  356. package/x/timeline/parts/compositor/playback.js.map +0 -1
  357. package/x/timeline/parts/compositor/samplers/html.d.ts +0 -3
  358. package/x/timeline/parts/compositor/samplers/html.js +0 -106
  359. package/x/timeline/parts/compositor/samplers/html.js.map +0 -1
  360. package/x/timeline/parts/compositor/samplers/webcodecs.d.ts +0 -2
  361. package/x/timeline/parts/compositor/samplers/webcodecs.js +0 -55
  362. package/x/timeline/parts/compositor/samplers/webcodecs.js.map +0 -1
  363. package/x/timeline/parts/waveform.d.ts +0 -8
  364. package/x/timeline/parts/waveform.js +0 -51
  365. package/x/timeline/parts/waveform.js.map +0 -1
  366. package/x/timeline/sugar/builders.d.ts +0 -96
  367. package/x/timeline/sugar/builders.js +0 -108
  368. package/x/timeline/sugar/builders.js.map +0 -1
  369. package/x/timeline/sugar/omni-test.d.ts +0 -1
  370. package/x/timeline/sugar/omni-test.js +0 -22
  371. package/x/timeline/sugar/omni-test.js.map +0 -1
  372. package/x/timeline/timeline.d.ts +0 -9
  373. package/x/timeline/timeline.js +0 -22
  374. package/x/timeline/timeline.js.map +0 -1
  375. package/x/timeline/utils/audio-stream.d.ts +0 -6
  376. package/x/timeline/utils/audio-stream.js +0 -17
  377. package/x/timeline/utils/audio-stream.js.map +0 -1
  378. package/x/timeline/utils/video-cursor.d.ts +0 -10
  379. package/x/timeline/utils/video-cursor.js +0 -36
  380. package/x/timeline/utils/video-cursor.js.map +0 -1
  381. package/x/tools/common/loader.d.ts +0 -19
  382. package/x/tools/common/loader.js +0 -18
  383. package/x/tools/common/loader.js.map +0 -1
  384. package/x/tools/common/transformer-pipeline.d.ts +0 -8
  385. package/x/tools/common/transformer-pipeline.js +0 -24
  386. package/x/tools/common/transformer-pipeline.js.map +0 -1
  387. package/x/tools/speech-recognition/common/model.d.ts +0 -14
  388. package/x/tools/speech-recognition/common/model.js +0 -16
  389. package/x/tools/speech-recognition/common/model.js.map +0 -1
  390. package/x/tools/speech-recognition/whisper/fns/host.d.ts +0 -13
  391. package/x/tools/speech-recognition/whisper/fns/host.js +0 -19
  392. package/x/tools/speech-recognition/whisper/fns/host.js.map +0 -1
  393. package/x/tools/speech-recognition/whisper/fns/schematic.d.ts +0 -19
  394. package/x/tools/speech-recognition/whisper/fns/schematic.js +0 -2
  395. package/x/tools/speech-recognition/whisper/fns/schematic.js.map +0 -1
  396. package/x/tools/speech-recognition/whisper/fns/work.d.ts +0 -12
  397. package/x/tools/speech-recognition/whisper/fns/work.js +0 -74
  398. package/x/tools/speech-recognition/whisper/fns/work.js.map +0 -1
  399. package/x/tools/speech-recognition/whisper/parts/types.d.ts +0 -31
  400. package/x/tools/speech-recognition/whisper/parts/types.js.map +0 -1
  401. package/x/tools/speech-recognition/whisper/parts/worker.bundle.d.ts +0 -1
  402. package/x/tools/speech-recognition/whisper/parts/worker.bundle.js +0 -4
  403. package/x/tools/speech-recognition/whisper/parts/worker.bundle.js.map +0 -1
  404. package/x/tools/speech-recognition/whisper/parts/worker.bundle.min.js +0 -8
  405. package/x/tools/speech-recognition/whisper/parts/worker.bundle.min.js.map +0 -7
  406. package/x/tools/speech-recognition/whisper/tool.d.ts +0 -12
  407. package/x/tools/speech-recognition/whisper/tool.js +0 -63
  408. package/x/tools/speech-recognition/whisper/tool.js.map +0 -1
  409. /package/x/{tests.test.d.ts → tests.bundle.d.ts} +0 -0
  410. /package/x/{tools/speech-recognition/whisper → timeline/parts/waveform}/parts/types.js +0 -0
@@ -0,0 +1,187 @@
1
+ import {autoDetectRenderer, Container, Renderer, Sprite, Text, Texture} from "pixi.js"
2
+
3
+ import {Id} from "../../timeline/index.js"
4
+ import {Composition, Layer} from "../fns/schematic.js"
5
+ import {Mat6, mat6ToMatrix} from "../../timeline/utils/matrix.js"
6
+ import {makeTransition} from "../../features/transition/transition.js"
7
+
8
+ export class Compositor {
9
+
10
+ static async setup() {
11
+ const renderer = await autoDetectRenderer({
12
+ width: 1920,
13
+ height: 1080,
14
+ preference: "webgl", // webgl and webgl2 causes memory leaks on chrome
15
+ background: "black",
16
+ preferWebGLVersion: 2
17
+ })
18
+ const stage = new Container()
19
+ stage.interactive = true
20
+ return new this({renderer, stage})
21
+ }
22
+
23
+ constructor(public pixi: {renderer: Renderer, stage: Container}) {}
24
+
25
+ #transitions: Map<string, ReturnType<typeof makeTransition>> = new Map()
26
+ // objects rendered for current Composition
27
+ #activeObjects = new Map<number, Container>()
28
+
29
+ async composite(
30
+ composition: Composition,
31
+ ) {
32
+ const {stage, renderer} = this.pixi
33
+
34
+ this.#cleanup(this.#collectIds(composition))
35
+ const {dispose} = await this.#renderLayer(composition, stage)
36
+ renderer.render(stage)
37
+
38
+ // make sure browser support webgl/webgpu otherwise it might take much longer to construct frame
39
+ // if its very slow on eg edge try chrome
40
+ const frame = new VideoFrame(renderer.canvas, {
41
+ timestamp: 0,
42
+ duration: 0,
43
+ })
44
+
45
+ dispose()
46
+
47
+ return frame
48
+ }
49
+
50
+ /**
51
+ * get object for current Composition
52
+ * */
53
+ getActiveObject(id: Id) {
54
+ return this.#activeObjects.get(id)
55
+ }
56
+
57
+ async #renderLayer(
58
+ layer: Layer | Composition,
59
+ parent: Container,
60
+ ) {
61
+ if (Array.isArray(layer)) {
62
+ layer.reverse()
63
+ const disposers: (() => void)[] = []
64
+ for (const child of layer) {
65
+ const result = await this.#renderLayer(child, parent)
66
+ disposers.push(result.dispose)
67
+ }
68
+ return {dispose: () => disposers.forEach(d => d())}
69
+ }
70
+
71
+ switch (layer.kind) {
72
+ case 'text':
73
+ return this.#renderTextLayer(layer, parent)
74
+ case 'image':
75
+ return this.#renderImageLayer(layer, parent)
76
+ case 'transition':
77
+ return this.#renderTransitionLayer(layer, parent)
78
+ case 'gap': {
79
+ this.pixi?.renderer.clear()
80
+ return {dispose: () => {}}
81
+ }
82
+ default:
83
+ console.warn('Unknown layer kind', (layer as any).kind)
84
+ return {dispose: () => {}}
85
+ }
86
+ }
87
+
88
+ #renderTextLayer(
89
+ layer: Extract<Layer, {kind: 'text'}>,
90
+ parent: Container,
91
+ ) {
92
+ const text = this.#findOrCreate<Text>(layer)!
93
+ this.#applyTransform(text, layer.matrix)
94
+ parent.addChild(text)
95
+ return {
96
+ dispose: () => {}
97
+ }
98
+ }
99
+
100
+ #renderImageLayer(
101
+ layer: Extract<Layer, {kind: 'image'}>,
102
+ parent: Container,
103
+ ) {
104
+ const texture = Texture.from(layer.frame)
105
+ const sprite = this.#findOrCreate<Sprite>(layer)!
106
+ sprite.texture = texture
107
+ this.#applyTransform(sprite, layer.matrix)
108
+ parent.addChild(sprite)
109
+ return {
110
+ dispose: () => {
111
+ texture.destroy(true)
112
+ layer.frame.close()
113
+ }
114
+ }
115
+ }
116
+
117
+ #renderTransitionLayer(
118
+ {from, to, progress, name}: Extract<Layer, {kind: 'transition'}>,
119
+ parent: Container,
120
+ ) {
121
+ const transition = this.#transitions.get(name) ??
122
+ (this.#transitions.set(name, makeTransition({
123
+ name: "circle",
124
+ renderer: this.pixi.renderer
125
+ })),
126
+ this.#transitions.get(name)!
127
+ )
128
+ const texture = transition.render({from, to, progress, width: from.displayWidth, height: from.displayHeight})
129
+ const sprite = new Sprite(texture)
130
+ parent.addChild(sprite)
131
+ return {dispose: () => sprite.destroy(false)}
132
+ }
133
+
134
+ #applyTransform(target: Sprite | Text, worldMatrix?: Mat6) {
135
+ if (!worldMatrix) return
136
+ const mx = mat6ToMatrix(worldMatrix)
137
+ target.setFromMatrix(mx)
138
+ }
139
+
140
+ #findOrCreate<T = Container>(layer: Layer) {
141
+ const object = this.#activeObjects.get(layer.id)
142
+ if(!object) {
143
+ switch (layer.kind) {
144
+ case 'text': {
145
+ const text = new Text({
146
+ text: layer.content,
147
+ style: layer.style
148
+ })
149
+ text.onmouseenter = () => console.log("enter text")
150
+ return this.#activeObjects
151
+ .set(layer.id, text)
152
+ .get(layer.id) as T
153
+ }
154
+ case 'image': {
155
+ const sprite = new Sprite()
156
+ sprite.onmouseenter = () => console.log("enter")
157
+ return this.#activeObjects
158
+ .set(layer.id, sprite)
159
+ .get(layer.id) as T
160
+ }
161
+ }
162
+ } else return object as T
163
+ }
164
+
165
+ #collectIds(layers: Layer | Composition): Set<number> {
166
+ const result = new Set<number>()
167
+ const traverse = (node: Layer | Composition) => {
168
+ if (Array.isArray(node)) {
169
+ for (const child of node) traverse(child)
170
+ } else {
171
+ result.add(node.id)
172
+ }
173
+ }
174
+ traverse(layers)
175
+ return result
176
+ }
177
+
178
+ #cleanup(activeIds: Set<number>) {
179
+ for (const id of this.#activeObjects.keys()) {
180
+ if (!activeIds.has(id)) {
181
+ const obj = this.#activeObjects.get(id)!
182
+ obj.destroy(true)
183
+ this.#activeObjects.delete(id)
184
+ }
185
+ }
186
+ }
187
+ }
@@ -1,27 +1,26 @@
1
- import {WebMediaInfo} from "web-demuxer"
2
1
 
3
- type Events =
4
- | {type: "config", config: {audio: AudioDecoderConfig, video: VideoDecoderConfig}}
5
- | {type: "info", data: WebMediaInfo}
6
- | {type: "encoderQueueSize", size: number}
7
-
8
- type Handler = (event: Events) => void
2
+ // type Events =
3
+ // | {type: "config", config: {audio: AudioDecoderConfig, video: VideoDecoderConfig}}
4
+ // | {type: "info", data: WebMediaInfo}
5
+ // | {type: "encoderQueueSize", size: number}
6
+ //
7
+ // type Handler = (event: Events) => void
9
8
 
10
9
  export class Machina {
11
10
  count = 0
12
11
 
13
- #handlers = new Map<number, Handler>()
14
-
15
- register(id: number, handler: Handler) {
16
- this.#handlers.set(id, handler)
17
- }
18
-
19
- unregister(id: number) {
20
- this.#handlers.delete(id)
21
- }
22
-
23
- dispatch(id: number, event: Events) {
24
- this.#handlers.get(id)?.(event)
25
- }
12
+ // #handlers = new Map<number, Handler>()
13
+ //
14
+ // register(id: number, handler: Handler) {
15
+ // this.#handlers.set(id, handler)
16
+ // }
17
+ //
18
+ // unregister(id: number) {
19
+ // this.#handlers.delete(id)
20
+ // }
21
+ //
22
+ // dispatch(id: number, event: Events) {
23
+ // this.#handlers.get(id)?.(event)
24
+ // }
26
25
  }
27
26
 
package/s/index.html.ts CHANGED
@@ -15,7 +15,7 @@ export default ssg.page(import.meta.url, async orb => ({
15
15
  head: html`
16
16
  <link rel="preconnect" href="https://fonts.googleapis.com">
17
17
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
18
- <link href="https://fonts.googleapis.com/css2?family=Share+Tech&display=swap" rel="stylesheet">
18
+ <link href="https://fonts.googleapis.com/css2?family=Share+Tech&family=Space+Grotesk:wght@400;600&display=swap" rel="stylesheet">
19
19
  `,
20
20
 
21
21
  socialCard: {
@@ -28,31 +28,109 @@ export default ssg.page(import.meta.url, async orb => ({
28
28
 
29
29
  body: html`
30
30
  <section>
31
- <h1>Omnitool <small>v${orb.packageVersion()}</small></h1>
32
- <button class=fetch>fetch</button>
33
- <input type="file" class="file-input">
34
- <div class=results></div>
35
- <div class=filmstrip-demo>
36
- <label for="viewable-range">viewable range:</label>
37
- <input type="range" min="0" max="100" step="1" value="10" class="range" id="viewable-range" name="viewable-range">
38
- <div class="range-view"></div>
39
- <label for="range-size">viewable range size:</label>
40
- <input type="range" class="range-size" min="0.1" max="10" step="0.1" value="0.5" id="range-size" name="range-size">
41
- <label for="frequency">frequency:</label>
42
- <input type="range" class="frequency" min="0.1" max="120" step="0.1" value="10" id="frequency" name="frequency">
43
- <div class="frequency-view">10 (fps)</div>
44
- <div id=filmstrip></div>
45
- </div>
46
- <div class=waveform-demo>
47
- <label for="width">width:</label>
48
- <input class="width" id="width" name="width" type="range" min="100" max="1000000" value="1000" />
49
- </div>
50
- <div class=player>
51
- <input class="seek" type="number" min="0">
52
- <button class=play>play</button>
53
- <button class=stop>stop</button>
31
+ <header class="hero">
32
+ <div>
33
+ <h1>Omnitool <small>v${orb.packageVersion()}</small></h1>
34
+ <p>Developer demos for decoding, preview, waveform, playback, and export.</p>
35
+ </div>
36
+ </header>
37
+
38
+ <div class="demo-grid">
39
+ <article class="demo-card" data-demo="transcode">
40
+ <header>
41
+ <h2>Transcode Test</h2>
42
+ <p>Full decode + composite + encode pipeline.</p>
43
+ </header>
44
+ <div class="demo-controls">
45
+ <input type="file" accept="video/*" />
46
+ <button data-action="run">Run Transcode</button>
47
+ </div>
48
+ <div class="demo-progress">
49
+ <progress class="progress"></progress>
50
+ <span class="status">idle</span>
51
+ </div>
52
+ <div class="demo-preview"></div>
53
+ </article>
54
+
55
+ <article class="demo-card" data-demo="filmstrip">
56
+ <header>
57
+ <h2>Filmstrip</h2>
58
+ <p>Thumbnail sampling across a time range.</p>
59
+ </header>
60
+ <div class="demo-controls">
61
+ <input type="file" accept="video/*" />
62
+ <button data-action="run">Generate Filmstrip</button>
63
+ </div>
64
+ <div class="filmstrip-controls">
65
+ <label>viewable range</label>
66
+ <input type="range" min="0" max="100" step="1" value="10" class="range">
67
+ <div class="range-view"></div>
68
+ <label>range size</label>
69
+ <input type="range" class="range-size" min="0.1" max="10" step="0.1" value="0.5">
70
+ <label>frequency</label>
71
+ <input type="range" class="frequency" min="0.1" max="120" step="0.1" value="10">
72
+ <div class="frequency-view">10 (fps)</div>
73
+ </div>
74
+ <div class="filmstrip"></div>
75
+ </article>
76
+
77
+ <article class="demo-card" data-demo="waveform">
78
+ <header>
79
+ <h2>Waveform</h2>
80
+ <p>Audio peak rendering with adjustable width.</p>
81
+ </header>
82
+ <div class="demo-controls">
83
+ <input type="file" accept="audio/*,video/*" />
84
+ <button data-action="run">Build Waveform</button>
85
+ </div>
86
+ <div class="waveform-controls">
87
+ <label>width</label>
88
+ <input class="width" type="range" min="100" max="1000000" value="1000" step="100" />
89
+ </div>
90
+ <div class="waveform-canvas"></div>
91
+ </article>
92
+
93
+ <article class="demo-card" data-demo="playback">
94
+ <header>
95
+ <h2>Timeline Playback</h2>
96
+ <p>Build timeline and run the playback engine.</p>
97
+ </header>
98
+ <div class="demo-controls">
99
+ <input type="file" accept="video/*,audio/*" />
100
+ </div>
101
+ <div class="player-canvas"></div>
102
+ <div class="player">
103
+ <div class="timeline">
104
+ <div class="track">
105
+ <div class="playhead"></div>
106
+ </div>
107
+ <input class="scrub" type="range" min="0" max="0" step="1" value="0">
108
+ </div>
109
+ <div class="timecode">0:00.000 / 0:00.000</div>
110
+ <div class="controls">
111
+ <button class=play disabled>play</button>
112
+ <button class=stop disabled>stop</button>
113
+ </div>
114
+ </div>
115
+ </article>
116
+
117
+ <article class="demo-card" data-demo="export">
118
+ <header>
119
+ <h2>Timeline Export</h2>
120
+ <p>Build timeline and export a render.</p>
121
+ </header>
122
+ <div class="demo-controls">
123
+ <input type="file" accept="video/*,audio/*" />
124
+ <button data-action="export" disabled>Export</button>
125
+ </div>
126
+ <div class="demo-progress">
127
+ <progress class="progress"></progress>
128
+ <span class="status">idle</span>
129
+ </div>
130
+ <div class="demo-preview"></div>
131
+ </article>
54
132
  </div>
133
+
55
134
  </section>
56
135
  `,
57
136
  }))
58
-
package/s/index.ts CHANGED
@@ -1,4 +1,5 @@
1
1
 
2
2
  export * from "./driver/driver.js"
3
+ export * from "./driver/driver-worker.js"
3
4
  export * from "./timeline/index.js"
4
5
 
@@ -0,0 +1,11 @@
1
+
2
+ import {Science} from "@e280/science"
3
+ import omniTest from "./timeline/sugar/omni.test.js"
4
+ import renderersTest from "./timeline/renderers/renderers.test.js"
5
+
6
+ await Science.run
7
+ ({
8
+ omniTest,
9
+ renderersTest
10
+ })
11
+
@@ -0,0 +1,28 @@
1
+
2
+ import {ssg, html} from "@e280/scute"
3
+
4
+ const title = "omnitool"
5
+ const domain = "omnitool.omniclip.app"
6
+ const favicon = "/assets/favicon.png"
7
+
8
+ export default ssg.page(import.meta.url, async orb => ({
9
+ title,
10
+ dark: true,
11
+ css: "demo/demo.css",
12
+ js: "tests.bundle.min.js",
13
+
14
+ head: html`
15
+ `,
16
+
17
+ socialCard: {
18
+ title,
19
+ description: "video processing toolkit",
20
+ themeColor: "#3cff9c",
21
+ siteName: domain,
22
+ image: `https://${domain}${favicon}`,
23
+ },
24
+
25
+ body: html`
26
+ `,
27
+ }))
28
+
@@ -6,7 +6,12 @@ export * from "./parts/resource-pool.js"
6
6
  export * from "./parts/resource.js"
7
7
  export * from "./parts/filmstrip.js"
8
8
 
9
+ export * from "./parts/waveform/waveform.js"
10
+ export * from "./parts/waveform/parts/types.js"
11
+ export * from "./renderers/player/player.js"
12
+
9
13
  export * from "./sugar/o.js"
14
+ export * from "./sugar/helpers.js"
10
15
  export * from "./sugar/omni.js"
11
16
 
12
17
  export * from "./utils/checksum.js"
@@ -17,7 +17,7 @@ export class Filmstrip {
17
17
 
18
18
  private constructor(
19
19
  private videoTrack: InputVideoTrack,
20
- private options: Required<FilmstripOptions>
20
+ private options: FilmstripOptions
21
21
  ) {
22
22
  this.#sink = new CanvasSink(videoTrack, options.canvasSinkOptions)
23
23
  }
@@ -33,7 +33,8 @@ export class Filmstrip {
33
33
  videoTrack, {
34
34
  frequency: options.frequency ?? 1,
35
35
  canvasSinkOptions: options.canvasSinkOptions ?? {width: 80, height: 50, fit: "fill"},
36
- onChange: options.onChange
36
+ onChange: options.onChange,
37
+ onPlaceholders: options.onPlaceholders
37
38
  })
38
39
  else throw new Error("Source has no video track")
39
40
  }
@@ -54,9 +55,28 @@ export class Filmstrip {
54
55
  return this.options.frequency
55
56
  }
56
57
 
57
- #computeActiveRange([start, end]: TimeRange): TimeRange {
58
+ #computeActiveRange([start, end]: TimeRange, margin = 1): TimeRange {
58
59
  const tileSize = end - start
59
- return [start - tileSize, end + tileSize]
60
+ return [start - tileSize * margin, end + tileSize * margin]
61
+ }
62
+
63
+ async #generatePlaceholders() {
64
+ const [rangeStart, rangeEnd] = this.#activeRange
65
+ const neededTimestamps = new Set<number>()
66
+
67
+ // duration should be computed but with trim etc also
68
+ const duration = await this.videoTrack.computeDuration()
69
+ for (
70
+ let timestamp = Math.max(0, rangeStart);
71
+ timestamp <= rangeEnd;
72
+ timestamp += this.options.frequency
73
+ ) {
74
+ // Clamp to valid time range
75
+ if (timestamp >= 0 && timestamp <= duration)
76
+ neededTimestamps.add(timestamp)
77
+ }
78
+
79
+ this.options.onPlaceholders?.([...neededTimestamps])
60
80
  }
61
81
 
62
82
  async #generateTiles() {
@@ -66,13 +86,13 @@ export class Filmstrip {
66
86
  // duration should be computed but with trim etc also
67
87
  const duration = await this.videoTrack.computeDuration()
68
88
  for (
69
- let timestamp = rangeStart;
89
+ let timestamp = Math.max(0, rangeStart);
70
90
  timestamp <= rangeEnd;
71
91
  timestamp += this.options.frequency
72
92
  ) {
73
93
  // Clamp to valid time range
74
94
  if (timestamp >= 0 && timestamp <= duration)
75
- neededTimestamps.add(+timestamp.toFixed(3))
95
+ neededTimestamps.add(timestamp)
76
96
  }
77
97
 
78
98
  const missingTimestamps = [...neededTimestamps]
@@ -106,15 +126,20 @@ export class Filmstrip {
106
126
  * @param visibleRange - The current timeline viewport as a [start, end] tuple in seconds.
107
127
  */
108
128
  set range(visibleRange: TimeRange) {
109
- const newRange = this.#computeActiveRange(visibleRange)
110
- // Avoid redundant updates
111
- if (
112
- this.#activeRange[0] === newRange[0] &&
113
- this.#activeRange[1] === newRange[1]
114
- )
115
- return
129
+ const [visStart, visEnd] = visibleRange
130
+ const visibleSize = visEnd - visStart
131
+ const [actStart, actEnd] = this.#activeRange
132
+
133
+ // trigger when we're 1x visible width away from margin edges
134
+ const leftTrigger = actStart + visibleSize
135
+ const rightTrigger = actEnd - visibleSize
136
+
137
+ const nearLeftEdge = visStart < leftTrigger
138
+ const nearRightEdge = visEnd > rightTrigger
139
+
140
+ if (!nearLeftEdge && !nearRightEdge) return
116
141
 
117
- this.#activeRange = newRange
142
+ this.#activeRange = this.#computeActiveRange(visibleRange, 2)
118
143
  this.#update()
119
144
  }
120
145
 
@@ -122,6 +147,7 @@ export class Filmstrip {
122
147
  #shouldRunAgain = false
123
148
 
124
149
  async #update() {
150
+ this.#generatePlaceholders()
125
151
  // Perform update immediately. If multiple updates are requested while updating,
126
152
  // only the latest one will run after the current finishes (skips intermediate ones).
127
153
  if(this.#updating) {
@@ -147,11 +173,12 @@ export class Filmstrip {
147
173
  }
148
174
  }
149
175
 
150
- type TimeRange = [number, number]
176
+ export type TimeRange = [start: number, end: number]
151
177
 
152
178
  interface FilmstripOptions {
153
- frequency?: number
179
+ frequency: number
154
180
  canvasSinkOptions?: CanvasSinkOptions
181
+ onPlaceholders?: (timestamps: number[]) => void
155
182
  onChange: (tiles: {
156
183
  time: number
157
184
  canvas: WrappedCanvas
@@ -1,6 +1,9 @@
1
1
 
2
+ import {TextStyleOptions} from "pixi.js"
3
+
2
4
  import {Id, Hash} from "./basics.js"
3
5
  import {Transform} from "../types.js"
6
+ import {Ms} from "../../units/ms.js"
4
7
 
5
8
  export enum Kind {
6
9
  Sequence,
@@ -11,6 +14,7 @@ export enum Kind {
11
14
  Gap,
12
15
  Spatial,
13
16
  Transition,
17
+ TextStyle
14
18
  }
15
19
 
16
20
  export enum Effect {
@@ -18,11 +22,18 @@ export enum Effect {
18
22
  }
19
23
 
20
24
  export namespace Item {
21
- export type Spatial = {
22
- id: Id
23
- kind: Kind.Spatial
24
- transform: Transform
25
- }
25
+ export type TextStyle = {
26
+ id: Id
27
+ kind: Kind.TextStyle
28
+ style: TextStyleOptions
29
+ }
30
+
31
+ export type Spatial = {
32
+ id: Id
33
+ kind: Kind.Spatial
34
+ transform: Transform
35
+ enabled: boolean
36
+ }
26
37
 
27
38
  export type Gap = {
28
39
  id: Id
@@ -59,14 +70,16 @@ export namespace Item {
59
70
  mediaHash: Hash
60
71
  start: number
61
72
  duration: number
73
+ gain?: number
62
74
  }
63
75
 
64
76
  export type Text = {
65
77
  id: Id
66
78
  kind: Kind.Text
67
79
  content: string
80
+ duration: number
68
81
  spatialId?: Id
69
- color: string
82
+ styleId?: Id
70
83
  }
71
84
 
72
85
  export type Transition = {
@@ -85,6 +98,14 @@ export namespace Item {
85
98
  | Gap
86
99
  | Transition
87
100
  | Spatial
101
+ | TextStyle
88
102
  )
89
103
  }
90
104
 
105
+ export type ContainerItem = Item.Sequence | Item.Stack
106
+ export type NonContainerItem = Exclude<Item.Any, ContainerItem>
107
+
108
+ export type PlayableItem = Item.Any & {
109
+ start: Ms
110
+ duration: Ms
111
+ }
@@ -14,13 +14,23 @@ export class Media {
14
14
 
15
15
  static async analyze(datafile: Datafile) {
16
16
  const media = new this(datafile)
17
- media.duration = 10
18
- const {video, audio} = await this.#has("/assets/temp/gl.mp4")
17
+ const duration = (await this.duration(datafile.url)) * 1000
18
+ media.duration = duration
19
+ const {video, audio} = await this.#has(datafile.url)
19
20
  media.hasAudio = audio
20
21
  media.hasVideo = video
21
22
  return media
22
23
  }
23
24
 
25
+ static async duration(source: DecoderSource) {
26
+ const input = new Input({
27
+ formats: ALL_FORMATS,
28
+ source: await loadDecoderSource(source)
29
+ })
30
+ const duration = await input.computeDuration()
31
+ return Number(duration.toFixed(5)) // fix weird floating points
32
+ }
33
+
24
34
  static async #has(source: DecoderSource) {
25
35
  const input = new Input({
26
36
  formats: ALL_FORMATS,