hyperframes 0.8.139 → 0.8.141

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 (200) hide show
  1. package/dist/{add-VYJQ4S3P.js → add-KH2CF4FD.js} +20 -22
  2. package/dist/{animatedGifPrep-IBMW6FZB.js → animatedGifPrep-QO4BSKR7.js} +15 -8
  3. package/dist/{asset-FLSUS73X.js → asset-4RDZILVJ.js} +3 -3
  4. package/dist/{assetCataloger-TGD7TRCR.js → assetCataloger-WGR4LYYN.js} +6 -3
  5. package/dist/{auth-EZXIN4M4.js → auth-WYQCOYE5.js} +7 -7
  6. package/dist/{autoUpdate-ZPMY5T3X.js → autoUpdate-PC5TN3NL.js} +2 -2
  7. package/dist/{backgroundChecks-JIDTAUFE.js → backgroundChecks-7M3T44EP.js} +3 -3
  8. package/dist/backgroundChecksWorker.js +3 -3
  9. package/dist/{batchRender-FNZ6TJYY.js → batchRender-GOLLOE4V.js} +11 -8
  10. package/dist/beat-analyzer.global.js +5 -2
  11. package/dist/{beats-EAA4U3YN.js → beats-XJ7WP6QS.js} +24 -17
  12. package/dist/{benchmark-KKZQVK2Y.js → benchmark-HCGFBEZJ.js} +20 -23
  13. package/dist/{browser-ZIVVJLJT.js → browser-VQKO2FKG.js} +14 -28
  14. package/dist/{bundleWithLocalizedFonts-2XWC3PEM.js → bundleWithLocalizedFonts-FH7PHTTX.js} +5 -5
  15. package/dist/{capture-EFYPXI42.js → capture-TFZZSF6F.js} +22 -15
  16. package/dist/{capture-MKJHABUL.js → capture-XD3P3YQR.js} +2 -2
  17. package/dist/{catalog-EWX4BBI2.js → catalog-4S33QWJJ.js} +28 -30
  18. package/dist/{catch-up-FJFH7T4W.js → catch-up-RW7YXXNT.js} +11 -25
  19. package/dist/{check-YJNVDCBP.js → check-XVTRRN4Y.js} +72 -54
  20. package/dist/{checkBrowser-I6SPPEGD.js → checkBrowser-HZXJ2EDU.js} +81 -36
  21. package/dist/chunk-24OWOBQH.js +3656 -0
  22. package/dist/{chunk-OENM2JVZ.js → chunk-34TXESM7.js} +3 -3
  23. package/dist/{chunk-GWV2Y36Q.js → chunk-35RSNI77.js} +5 -106
  24. package/dist/{chunk-BC3OY2ED.js → chunk-3A5AAPMP.js} +1 -1
  25. package/dist/{chunk-U3HX7WE6.js → chunk-3NBKW2QJ.js} +1 -1
  26. package/dist/{chunk-A4X2YWNQ.js → chunk-4BB7V6AI.js} +38 -301
  27. package/dist/{chunk-EJ7OWYF2.js → chunk-6E6CM7WS.js} +19 -163
  28. package/dist/{chunk-CDMB3PRC.js → chunk-6IFXWJDX.js} +7 -7
  29. package/dist/{chunk-Z67RZ4XO.js → chunk-6Q6FR4KH.js} +279 -1968
  30. package/dist/{chunk-R4QIE6UY.js → chunk-7M4KAPAA.js} +92 -31
  31. package/dist/{chunk-25DHUDOK.js → chunk-7XTZVLE6.js} +12 -3
  32. package/dist/chunk-A4KQZXZI.js +116 -0
  33. package/dist/{chunk-DUQJF7FK.js → chunk-A7YQNIQT.js} +8 -8
  34. package/dist/{chunk-XOZ3J3LB.js → chunk-AVWEIOEN.js} +1 -1
  35. package/dist/{chunk-UQXOHEQ7.js → chunk-BM5PX3DJ.js} +4 -4
  36. package/dist/{chunk-SHB5VDMH.js → chunk-BRITLL56.js} +1 -1
  37. package/dist/{chunk-JX7Y57YY.js → chunk-E4BSCXMU.js} +1 -1
  38. package/dist/{chunk-QXOFUKBF.js → chunk-E6SDW5FV.js} +168 -165
  39. package/dist/{chunk-JH556Q42.js → chunk-EDYBFSPE.js} +2 -2
  40. package/dist/{chunk-R7LWDIKB.js → chunk-EKA4ZZBI.js} +1 -1
  41. package/dist/chunk-FXMKHHPO.js +123 -0
  42. package/dist/chunk-G75ENCEZ.js +283 -0
  43. package/dist/{chunk-PLNWWGE7.js → chunk-GQJZORQP.js} +1 -1
  44. package/dist/{chunk-U3GEXWI5.js → chunk-GS6FE3IW.js} +1 -1
  45. package/dist/{chunk-Y6W4DVPS.js → chunk-HKCNZITN.js} +1 -1
  46. package/dist/{chunk-HOIHGPWO.js → chunk-IKVBTDLO.js} +1 -1
  47. package/dist/{chunk-YOL4QRSL.js → chunk-INI3TM6I.js} +2 -2
  48. package/dist/{chunk-SIKMUO45.js → chunk-IO7ZIDRP.js} +12 -12
  49. package/dist/{chunk-W7SAWBQC.js → chunk-IV7EI5E2.js} +1 -1
  50. package/dist/{chunk-TCWL4BKK.js → chunk-IYFKBFTW.js} +1 -1
  51. package/dist/{chunk-JIIIBTN2.js → chunk-J5IPIQU2.js} +1 -1
  52. package/dist/chunk-JFKL3WAE.js +161 -0
  53. package/dist/{chunk-IBRZUVTH.js → chunk-K2GOFLTX.js} +2 -2
  54. package/dist/{chunk-X3TMMIDP.js → chunk-KFH6UD26.js} +8 -8
  55. package/dist/{chunk-O6K5DWXM.js → chunk-KOEWEFHK.js} +1 -1
  56. package/dist/{chunk-VTVS4IIP.js → chunk-L3JSAB4L.js} +2 -2
  57. package/dist/{chunk-3RT6D4P6.js → chunk-N77KD7ZZ.js} +1 -1
  58. package/dist/{chunk-FLRCVYNE.js → chunk-NORZWWLK.js} +2 -2
  59. package/dist/{chunk-4VZBKOQJ.js → chunk-O3SKIXQK.js} +1 -1
  60. package/dist/{chunk-PFI3VD77.js → chunk-OLDDJS3S.js} +10 -10
  61. package/dist/{chunk-UGI77E35.js → chunk-P6E4HFFU.js} +167 -61
  62. package/dist/{chunk-GIDHR5OL.js → chunk-Q65ZQFF2.js} +1 -1
  63. package/dist/chunk-QZ3AZTXI.js +1740 -0
  64. package/dist/{chunk-NTIOLSFE.js → chunk-R7UDXKI3.js} +3 -3
  65. package/dist/{chunk-7SI7GCX6.js → chunk-RCFCZT5O.js} +6 -6
  66. package/dist/{chunk-DW32KBHN.js → chunk-RPYPW5NN.js} +13 -13
  67. package/dist/chunk-SYKKFAUW.js +3711 -0
  68. package/dist/chunk-T76PLPD6.js +57 -0
  69. package/dist/{chunk-JTAYFSLO.js → chunk-TC2FBZJZ.js} +1 -1
  70. package/dist/{chunk-Q73ISOVQ.js → chunk-U7E736AJ.js} +1 -1
  71. package/dist/chunk-USDEMXXL.js +110 -0
  72. package/dist/{chunk-UMWROSIP.js → chunk-W6HTOVHU.js} +2 -2
  73. package/dist/{chunk-STA43FMY.js → chunk-WY5OODN5.js} +71 -3855
  74. package/dist/{chunk-EZ2P7LAP.js → chunk-XDSOIJC3.js} +8 -8
  75. package/dist/{chunk-ZTZ7NCJT.js → chunk-XTFJOR3K.js} +1 -1
  76. package/dist/{chunk-CDJ7FPPJ.js → chunk-XWVGSEUT.js} +1 -1
  77. package/dist/chunk-YA62XGXS.js +45 -0
  78. package/dist/{chunk-EH4VUY27.js → chunk-YURXPGAM.js} +2 -2
  79. package/dist/{clean-P4KTCOUA.js → clean-L2E4VD57.js} +29 -20
  80. package/dist/cli.js +55 -55
  81. package/dist/{cloud-PDY7S4HU.js → cloud-IDUQRYLO.js} +7 -7
  82. package/dist/{cloudrun-54MA2W5H.js → cloudrun-R3JXWXGG.js} +11 -8
  83. package/dist/commands/layout-audit.browser.js +37 -8
  84. package/dist/commands/motion-signature.browser.js +51 -2
  85. package/dist/{compare-LDWVSPC5.js → compare-VYBWSP3Y.js} +40 -31
  86. package/dist/{compiler-CWSZ4W7J.js → compiler-ACHWOU5N.js} +7 -3
  87. package/dist/{component-FIEGC22U.js → component-PYYV2V3F.js} +4 -4
  88. package/dist/{compositions-JR7PX356.js → compositions-B5GQSXH7.js} +23 -16
  89. package/dist/{delete-FXA2IHOS.js → delete-EAX2U3WI.js} +8 -8
  90. package/dist/{deterministicFonts-GTITFRSJ.js → deterministicFonts-F6WIVL2W.js} +1 -1
  91. package/dist/{dist-OJTEVNJR.js → dist-NZSQCYOF.js} +3 -1
  92. package/dist/{dist-4JZWRWS6.js → dist-ROUDWGLO.js} +27 -15
  93. package/dist/{doctor-OTDHPM6K.js → doctor-PJX7MLFG.js} +20 -13
  94. package/dist/{events-UAFTI24U.js → events-SBC54MHO.js} +6 -22
  95. package/dist/{events-6T7M2VCO.js → events-YFFXKAQQ.js} +10 -23
  96. package/dist/{feedback-ZGZODHB6.js → feedback-UETLWREV.js} +67 -45
  97. package/dist/{figma-D26EJ7ZB.js → figma-QDSJPIRW.js} +6 -6
  98. package/dist/fontLocalizeCli.js +18 -11
  99. package/dist/{get-IAREU7IK.js → get-B5TS6C7H.js} +8 -8
  100. package/dist/{gpuPolicy-NS7WZRDJ.js → gpuPolicy-LYOVBAJP.js} +15 -8
  101. package/dist/{grade-compare-ZXHFHCD2.js → grade-compare-LBIHMAUN.js} +40 -31
  102. package/dist/{help-RVNYHW3N.js → help-XBP6A6LT.js} +4 -4
  103. package/dist/{history-THP4VNMF.js → history-2S42ZXKL.js} +12 -30
  104. package/dist/hyperframe-runtime.js +59 -59
  105. package/dist/hyperframe.manifest.json +1 -1
  106. package/dist/hyperframe.runtime.iife.js +59 -59
  107. package/dist/hyperframes-player.global.js +3 -3
  108. package/dist/{info-EOFRHN5A.js → info-I2VDAWT7.js} +17 -20
  109. package/dist/{init-YLIJE4CG.js → init-BGHSDODI.js} +48 -41
  110. package/dist/{inspect-3D56ONJD.js → inspect-MZK5B5RP.js} +39 -30
  111. package/dist/{installer-GRR2GDZK.js → installer-LL4QAKFW.js} +8 -5
  112. package/dist/{keyframes-NXNCTQPK.js → keyframes-2EBF7OSS.js} +14 -25
  113. package/dist/{lambda-VGRZD7TR.js → lambda-XKFPAOFE.js} +16 -13
  114. package/dist/{layout-Z5DOS6DU.js → layout-TP5ERKEF.js} +39 -30
  115. package/dist/{lint-YD6NJGR2.js → lint-FQ6CEI7E.js} +17 -23
  116. package/dist/{lintProject-ANMPLBIT.js → lintProject-LM3XZRPZ.js} +3 -1
  117. package/dist/{list-XGDKILYN.js → list-FRNUJXZ3.js} +8 -8
  118. package/dist/{login-GD5SA4RD.js → login-C25QU3BQ.js} +9 -9
  119. package/dist/{logout-Q654A3SI.js → logout-GJXZQKOA.js} +5 -5
  120. package/dist/{media-treatment-TY4X4GQQ.js → media-treatment-DCANGWSV.js} +21 -20
  121. package/dist/{models-MXRDH4WJ.js → models-GOD6ARB3.js} +19 -12
  122. package/dist/{motionShot-6LKR3C2E.js → motionShot-FSKETANX.js} +22 -15
  123. package/dist/{normalize-O76AC4HE.js → normalize-IGLHCWTF.js} +0 -4
  124. package/dist/{normalize-audio-5ADDZKPJ.js → normalize-audio-C2IM7OID.js} +13 -26
  125. package/dist/{open-JXAMO325.js → open-VVISXIII.js} +11 -25
  126. package/dist/{pipeline-Q5MOPIIX.js → pipeline-7YHZPYIS.js} +15 -8
  127. package/dist/{play-3SPH5GWZ.js → play-DSELK7G3.js} +38 -32
  128. package/dist/{preflight-2PWAPKWC.js → preflight-Y5DN5D37.js} +3 -18
  129. package/dist/{present-ZTJQDKXZ.js → present-N72YFDKP.js} +32 -26
  130. package/dist/{preview-4A3XZR6J.js → preview-XTYN4NJ2.js} +33 -26
  131. package/dist/{producer-5ZKKKQPB.js → producer-NDCU3MHK.js} +1 -1
  132. package/dist/{projectConfig-WA4CS4SN.js → projectConfig-MH4QU4AC.js} +10 -7
  133. package/dist/{publication-CLG2FRRI.js → publication-KUSHI5MG.js} +6 -3
  134. package/dist/{publish-YTT2WMXO.js → publish-3XEEFWMF.js} +27 -20
  135. package/dist/{refresh-K24ETHMA.js → refresh-MFITBIKV.js} +5 -5
  136. package/dist/{remove-background-W35INR3B.js → remove-background-2QKJ7XOD.js} +22 -15
  137. package/dist/{render-WUBFQMAH.js → render-2DVYTVLQ.js} +52 -32
  138. package/dist/{render-7A4P5WMU.js → render-75E342ZU.js} +10 -7
  139. package/dist/{render-KICXUPNR.js → render-S73DW4KK.js} +23 -26
  140. package/dist/{render-batch-N7EFGE6S.js → render-batch-YURBS54Q.js} +11 -8
  141. package/dist/{renderCancellation-LYQPPFAO.js → renderCancellation-373ASJTO.js} +15 -8
  142. package/dist/renderSetupWorker.js +4 -2
  143. package/dist/{resolver-YTT2NENF.js → resolver-FE3GBZ4T.js} +8 -5
  144. package/dist/{sherpa-353MW4UV.js → sherpa-B2D3AGP6.js} +16 -9
  145. package/dist/skills/hyperframes/references/capability-menu.md +1 -1
  146. package/dist/skills/hyperframes-cli/SKILL.md +5 -0
  147. package/dist/skills/hyperframes-cli/references/lint-validate-inspect.md +1 -1
  148. package/dist/skills/hyperframes-cli/references/preview-render.md +1 -1
  149. package/dist/skills/media-use/SKILL.md +9 -5
  150. package/dist/skills/media-use/audio/scripts/lib/heygen.mjs +47 -4
  151. package/dist/skills/media-use/audio/scripts/lib/heygen.test.mjs +125 -18
  152. package/dist/skills/media-use/audio/scripts/lib/host-audio.mjs +28 -0
  153. package/dist/skills/media-use/audio/scripts/lib/host-audio.test.mjs +106 -0
  154. package/dist/skills/media-use/references/setup-providers.md +16 -2
  155. package/dist/skills/media-use/scripts/lib/heygen-cli.mjs +21 -1
  156. package/dist/skills/media-use/scripts/lib/heygen-cli.test.mjs +14 -0
  157. package/dist/skills/media-use/scripts/resolve.mjs +11 -6
  158. package/dist/{skills-2XJIOEBT.js → skills-ICJ22CZZ.js} +15 -30
  159. package/dist/{skillsUpdateCheck-LMCCWGNO.js → skillsUpdateCheck-GXZN56I5.js} +3 -3
  160. package/dist/{snapshot-WBRSTLJ2.js → snapshot-XHKOAWF4.js} +41 -32
  161. package/dist/{src-ZS3BLTZ5.js → src-74PFDTDX.js} +17 -10
  162. package/dist/{src-YWFJILQF.js → src-I7UC3JTL.js} +19 -11
  163. package/dist/{staticProjectServer-4VKVHPNG.js → staticProjectServer-2DGKD6TF.js} +24 -16
  164. package/dist/{status-73MBN37B.js → status-JA6SKQVH.js} +7 -24
  165. package/dist/studio/assets/hyperframes-player-5Vx2AiUz.js +473 -0
  166. package/dist/studio/assets/{index-DsEkE5_G.js → index-BAnh7cSQ.js} +1 -1
  167. package/dist/studio/assets/{index-Br1Whc0f.js → index-C0thd4eM.js} +204 -204
  168. package/dist/studio/assets/{index-BmIPrb8I.js → index-P8fgj_Xa.js} +1 -1
  169. package/dist/studio/{chunk-E422JDF5.js → chunk-H2DUOXTF.js} +2 -1
  170. package/dist/studio/index.d.ts +19 -3
  171. package/dist/studio/index.html +1 -1
  172. package/dist/studio/index.js +6518 -5813
  173. package/dist/studio/index.js.map +1 -1
  174. package/dist/studio/player.js +1 -1
  175. package/dist/{studio-api-5V4TVSQV.js → studio-api-PROBO7JG.js} +40 -28
  176. package/dist/{studioServer-M5XY3HYC.js → studioServer-ID6UV2NE.js} +100 -69
  177. package/dist/{system-RCRNX5VF.js → system-OQLOGGPJ.js} +2 -19
  178. package/dist/{telemetry-LOBRQGUD.js → telemetry-65LFHIWH.js} +8 -23
  179. package/dist/{timeline-3JCP6PXU.js → timeline-6UV3JJXD.js} +32 -22
  180. package/dist/{tokens-MLMIJBVF.js → tokens-HIL4TZXI.js} +3 -3
  181. package/dist/{transcribe-KNFXDEAX.js → transcribe-TIO6W3EQ.js} +16 -9
  182. package/dist/{transcribe-POH25ZPX.js → transcribe-V7F6QDSN.js} +20 -44
  183. package/dist/{updateCheck-5ITBSBST.js → updateCheck-GZELANMA.js} +2 -2
  184. package/dist/{upgrade-K6OK4FKT.js → upgrade-BX3KDDZJ.js} +5 -5
  185. package/dist/{urlDownloader-TJJQKADT.js → urlDownloader-R76OHFIE.js} +14 -7
  186. package/dist/{validate-PPPOBJHB.js → validate-7UX4I443.js} +26 -19
  187. package/dist/{video-OB22HWXZ.js → video-RVGYEFQU.js} +18 -11
  188. package/package.json +1 -1
  189. package/dist/chunk-HYYSJI5D.js +0 -3742
  190. package/dist/studio/assets/hyperframes-player-CckOoCJ8.js +0 -473
  191. package/dist/{chunk-I465DBM6.js → chunk-246MOR5U.js} +3 -3
  192. package/dist/{deploy-MX76RZ36.js → deploy-5G4Z6LPA.js} +1 -1
  193. package/dist/{destroy-H2TZBYHH.js → destroy-GFQLTIY3.js} +1 -1
  194. package/dist/{docs-QAPJEGLS.js → docs-MPOM3PHH.js} +3 -3
  195. package/dist/{policies-FSDZVS2E.js → policies-4FEXMXPK.js} +3 -3
  196. package/dist/{progress-FBIEEB7Y.js → progress-5AM2MZ7V.js} +3 -3
  197. package/dist/{sites-TNVKZS73.js → sites-HZMADOA3.js} +1 -1
  198. package/dist/studio/{chunk-E422JDF5.js.map → chunk-H2DUOXTF.js.map} +0 -0
  199. package/dist/{telemetry-2YC4SGQU.js → telemetry-W5AKPI4R.js} +3 -3
  200. package/dist/{tts-FU35O6YB.js → tts-TOHSPWEG.js} +4 -4
@@ -4,6 +4,11 @@ import { dirname as __hf_dirname } from "node:path";
4
4
  var require = __hf_createRequire(import.meta.url);
5
5
  var __filename = __hf_fileURLToPath(import.meta.url);
6
6
  var __dirname = __hf_dirname(__filename);
7
+ import {
8
+ LOW_MEMORY_TOTAL_MB_THRESHOLD,
9
+ getSystemTotalMb,
10
+ isLowMemorySystem
11
+ } from "./chunk-USDEMXXL.js";
7
12
  import {
8
13
  MEDIA_VISUAL_STYLE_PROPERTIES,
9
14
  RENDER_FRAME_ID_PREFIX,
@@ -18,11 +23,10 @@ import {
18
23
  parseFirstFrameColour,
19
24
  quantizeSeekTime,
20
25
  quantizeTimeToFrame,
21
- redactTelemetryString,
22
26
  renderFrameIdForRenderId,
23
27
  resolveAuthoredTimingWindow,
24
28
  toFps
25
- } from "./chunk-EJ7OWYF2.js";
29
+ } from "./chunk-6E6CM7WS.js";
26
30
  import {
27
31
  AUDIO_GROUP_RENDER_ID_ATTR,
28
32
  COLOR_GRADING_SOURCE_HIDDEN_ATTR,
@@ -33,11 +37,9 @@ import {
33
37
  MEDIA_DURATION_CLAMP_EPSILON_SECONDS,
34
38
  MEDIA_RENDER_ID_ATTR,
35
39
  VOLUME_TARGET,
36
- clampAudioGain,
37
40
  enabledAudioFxNodes,
38
41
  fxAutomationTarget,
39
42
  injectScriptsIntoHtml,
40
- isAudibleVideoElement,
41
43
  normalizeAudioFxParams,
42
44
  normalizePlaybackRate,
43
45
  normalizeRateSpec,
@@ -53,7 +55,14 @@ import {
53
55
  shiftRateLane,
54
56
  sourceTimeAt,
55
57
  timeAtSourceTime
56
- } from "./chunk-HYYSJI5D.js";
58
+ } from "./chunk-SYKKFAUW.js";
59
+ import {
60
+ clampAudioGain,
61
+ isAudibleVideoElement
62
+ } from "./chunk-YA62XGXS.js";
63
+ import {
64
+ redactTelemetryString
65
+ } from "./chunk-T76PLPD6.js";
57
66
  import {
58
67
  chromeMajorCeiling,
59
68
  exceedsChromeCeiling
@@ -61,7 +70,7 @@ import {
61
70
  import {
62
71
  isWithinProjectRoot,
63
72
  resolveProjectRelativeSrc
64
- } from "./chunk-STA43FMY.js";
73
+ } from "./chunk-JFKL3WAE.js";
65
74
  import {
66
75
  FFMPEG_PATH_ENV,
67
76
  FFPROBE_PATH_ENV,
@@ -79,103 +88,6 @@ import {
79
88
  import { tmpdir } from "os";
80
89
  import { join } from "path";
81
90
 
82
- // ../engine/src/services/systemMemory.ts
83
- import { readFileSync } from "fs";
84
- import { totalmem } from "os";
85
- var BYTES_PER_MIB = 1024 * 1024;
86
- var BYTES_PER_MIB_BIGINT = BigInt(BYTES_PER_MIB);
87
- var CGROUP_V2_MEMORY_MAX_PATH = "/sys/fs/cgroup/memory.max";
88
- var CGROUP_V1_MEMORY_LIMIT_PATH = "/sys/fs/cgroup/memory/memory.limit_in_bytes";
89
- var CGROUP_V1_NO_LIMIT_CUTOFF_BYTES = 2n ** 60n;
90
- var _cachedCgroupLimitMb;
91
- var _warnedCgroupReadFailure = false;
92
- function parseCgroupLimitMb(v2Content, v1Content) {
93
- if (v2Content !== null) {
94
- return parseCgroupV2LimitMb(v2Content);
95
- }
96
- return parseCgroupV1LimitMb(v1Content);
97
- }
98
- function parseCgroupV2LimitMb(content) {
99
- const trimmed = content.trim();
100
- if (trimmed === "max") {
101
- return null;
102
- }
103
- return parsePositiveByteLimitMb(trimmed);
104
- }
105
- function parseCgroupV1LimitMb(content) {
106
- if (content === null) {
107
- return null;
108
- }
109
- return parsePositiveByteLimitMb(content.trim(), CGROUP_V1_NO_LIMIT_CUTOFF_BYTES);
110
- }
111
- function parsePositiveByteLimitMb(content, noLimitCutoffBytes) {
112
- if (!/^\d+$/.test(content)) {
113
- return null;
114
- }
115
- const bytes = BigInt(content);
116
- if (bytes <= 0n) {
117
- return null;
118
- }
119
- if (noLimitCutoffBytes !== void 0 && bytes >= noLimitCutoffBytes) {
120
- return null;
121
- }
122
- return Number(bytes / BYTES_PER_MIB_BIGINT);
123
- }
124
- function getCgroupMemoryLimitMb() {
125
- if (_cachedCgroupLimitMb !== void 0) return _cachedCgroupLimitMb;
126
- if (process.platform !== "linux") {
127
- _cachedCgroupLimitMb = null;
128
- return null;
129
- }
130
- const v2Content = readCgroupFile(CGROUP_V2_MEMORY_MAX_PATH);
131
- const v1Content = v2Content === null ? readCgroupFile(CGROUP_V1_MEMORY_LIMIT_PATH) : null;
132
- _cachedCgroupLimitMb = parseCgroupLimitMb(v2Content, v1Content);
133
- if (_cachedCgroupLimitMb !== null) {
134
- console.warn(
135
- `[SystemMemory] cgroup memory limit detected: ${_cachedCgroupLimitMb} MiB \u2014 it governs memory-adaptive render behaviour instead of host RAM.`
136
- );
137
- }
138
- return _cachedCgroupLimitMb;
139
- }
140
- function readCgroupFile(path) {
141
- try {
142
- return readFileSync(path, "utf8");
143
- } catch (error) {
144
- const code = getErrorCode(error);
145
- if (code !== "ENOENT" && code !== "ENOTDIR") {
146
- warnCgroupReadFailure(path, error);
147
- }
148
- return null;
149
- }
150
- }
151
- function getErrorCode(error) {
152
- if (typeof error !== "object" || error === null || !("code" in error)) {
153
- return void 0;
154
- }
155
- return typeof error.code === "string" ? error.code : void 0;
156
- }
157
- function formatCgroupReadError(error) {
158
- const message = error instanceof Error ? error.message : String(error);
159
- const code = getErrorCode(error);
160
- return code ? `${code}: ${message}` : message;
161
- }
162
- function warnCgroupReadFailure(path, error) {
163
- if (_warnedCgroupReadFailure) return;
164
- _warnedCgroupReadFailure = true;
165
- console.warn(
166
- `[SystemMemory] Unable to read cgroup memory limit at ${path} (${formatCgroupReadError(error)}); falling back to host RAM.`
167
- );
168
- }
169
- function getSystemTotalMb() {
170
- const hostTotalMb = Math.floor(totalmem() / BYTES_PER_MIB);
171
- const cgroupLimitMb = getCgroupMemoryLimitMb();
172
- return cgroupLimitMb === null ? hostTotalMb : Math.min(hostTotalMb, cgroupLimitMb);
173
- }
174
- var LOW_MEMORY_TOTAL_MB_THRESHOLD = 8192;
175
- function isLowMemorySystem(totalMb = getSystemTotalMb()) {
176
- return totalMb <= LOW_MEMORY_TOTAL_MB_THRESHOLD;
177
- }
178
-
179
91
  // ../engine/src/services/vp9Options.ts
180
92
  var DEFAULT_VP9_CPU_USED = 4;
181
93
  var MIN_VP9_CPU_USED = -8;
@@ -201,6 +113,7 @@ var DEFAULT_CONFIG = {
201
113
  largeRenderThreshold: 1e3,
202
114
  disableGpu: false,
203
115
  browserGpuMode: "software",
116
+ allowSoftwareWebGpu: false,
204
117
  enableBrowserPool: true,
205
118
  browserTimeout: 12e4,
206
119
  protocolTimeout: 3e5,
@@ -244,6 +157,7 @@ var OPTIONAL_ENGINE_CONFIG_FIELDS = [
244
157
  ];
245
158
  var BOOLEAN_ENGINE_CONFIG_FIELDS = [
246
159
  "disableGpu",
160
+ "allowSoftwareWebGpu",
247
161
  "enableBrowserPool",
248
162
  "forceScreenshot",
249
163
  "staticFrameDedup",
@@ -495,6 +409,10 @@ function resolveConfig(overrides) {
495
409
  chromePath: env("PRODUCER_HEADLESS_SHELL_PATH"),
496
410
  disableGpu: envBool("PRODUCER_DISABLE_GPU", DEFAULT_CONFIG.disableGpu),
497
411
  browserGpuMode: envBrowserGpuMode(),
412
+ allowSoftwareWebGpu: envBool(
413
+ "PRODUCER_ALLOW_SOFTWARE_WEBGPU",
414
+ DEFAULT_CONFIG.allowSoftwareWebGpu
415
+ ),
498
416
  enableBrowserPool: envBool("PRODUCER_ENABLE_BROWSER_POOL", DEFAULT_CONFIG.enableBrowserPool),
499
417
  browserTimeout: envNum("PRODUCER_PUPPETEER_LAUNCH_TIMEOUT_MS", DEFAULT_CONFIG.browserTimeout),
500
418
  protocolTimeout: envNum(
@@ -1358,15 +1276,19 @@ function getLowMemoryFlags() {
1358
1276
  }
1359
1277
  var CANVAS_DRAW_ELEMENT_FEATURE_FLAG = "--enable-features=CanvasDrawElement";
1360
1278
  var WEBGPU_FLAG = "--enable-unsafe-webgpu";
1279
+ function usesSoftwareWebGpu(requiresWebGpu, config) {
1280
+ return !!requiresWebGpu && !!config?.allowSoftwareWebGpu && !(config.disableGpu ?? DEFAULT_CONFIG.disableGpu) && (config.browserGpuMode ?? DEFAULT_CONFIG.browserGpuMode) === "software";
1281
+ }
1361
1282
  function buildChromeArgs(options, config) {
1362
1283
  const platform = options.platform ?? process.platform;
1363
1284
  const gpuDisabled = config?.disableGpu ?? DEFAULT_CONFIG.disableGpu;
1364
1285
  const browserGpuMode = gpuDisabled ? "software" : config?.browserGpuMode ?? DEFAULT_CONFIG.browserGpuMode;
1286
+ const softwareWebGpu = usesSoftwareWebGpu(options.requiresWebGpu, config);
1365
1287
  const chromeArgs = [
1366
1288
  "--no-sandbox",
1367
1289
  "--disable-setuid-sandbox",
1368
1290
  "--disable-dev-shm-usage",
1369
- CANVAS_DRAW_ELEMENT_FEATURE_FLAG,
1291
+ softwareWebGpu ? `${CANVAS_DRAW_ELEMENT_FEATURE_FLAG},Vulkan` : CANVAS_DRAW_ELEMENT_FEATURE_FLAG,
1370
1292
  "--enable-webgl",
1371
1293
  "--ignore-gpu-blocklist",
1372
1294
  ...getBrowserGpuArgs(browserGpuMode, platform),
@@ -1410,7 +1332,8 @@ function buildChromeArgs(options, config) {
1410
1332
  if (browserGpuMode !== "software" || options.requiresWebGpu) {
1411
1333
  chromeArgs.push(WEBGPU_FLAG);
1412
1334
  }
1413
- if (browserGpuMode === "software") {
1335
+ if (softwareWebGpu) chromeArgs.push("--use-vulkan=swiftshader");
1336
+ if (browserGpuMode === "software" && !softwareWebGpu) {
1414
1337
  chromeArgs.push("--disable-gpu-compositing");
1415
1338
  }
1416
1339
  if (options.captureMode !== "screenshot") {
@@ -1440,26 +1363,30 @@ function compositionRequiresWebGpu(html) {
1440
1363
  var WebGpuUnavailableError = class extends Error {
1441
1364
  constructor() {
1442
1365
  super(
1443
- "This composition declares data-requires-webgpu, but no hardware WebGPU adapter could be obtained on this browser launch (a software fallback adapter such as swiftshader reports one but cannot render it). Run on a host with a GPU, or remove data-requires-webgpu."
1366
+ "This composition declares data-requires-webgpu, but no hardware WebGPU adapter could be obtained on this browser launch. Run on a host with a GPU, set PRODUCER_ALLOW_SOFTWARE_WEBGPU=true to render it on SwiftShader (slow), or remove data-requires-webgpu."
1444
1367
  );
1445
1368
  this.name = "WebGpuUnavailableError";
1446
1369
  }
1447
1370
  };
1448
1371
  var WEBGPU_ADAPTER_PROBE_TIMEOUT_MS = 1e4;
1449
- async function assertWebGpuAdapterAvailable(page, requiresWebGpu) {
1372
+ async function assertWebGpuAdapterAvailable(page, requiresWebGpu, softwareWebGpu = false) {
1450
1373
  if (!requiresWebGpu) return;
1451
- const hasUsableAdapter = await page.evaluate(async (timeoutMs) => {
1452
- if (typeof navigator === "undefined" || !navigator.gpu) return false;
1453
- try {
1454
- const adapter = await Promise.race([
1455
- navigator.gpu.requestAdapter(),
1456
- new Promise((resolve) => setTimeout(() => resolve(null), timeoutMs))
1457
- ]);
1458
- return !!adapter && !adapter.info.isFallbackAdapter;
1459
- } catch {
1460
- return false;
1461
- }
1462
- }, WEBGPU_ADAPTER_PROBE_TIMEOUT_MS);
1374
+ const hasUsableAdapter = await page.evaluate(
1375
+ async (timeoutMs, acceptFallback) => {
1376
+ if (typeof navigator === "undefined" || !navigator.gpu) return false;
1377
+ try {
1378
+ const adapter = await Promise.race([
1379
+ navigator.gpu.requestAdapter(),
1380
+ new Promise((resolve) => setTimeout(() => resolve(null), timeoutMs))
1381
+ ]);
1382
+ return !!adapter && (acceptFallback || !adapter.info.isFallbackAdapter);
1383
+ } catch {
1384
+ return false;
1385
+ }
1386
+ },
1387
+ WEBGPU_ADAPTER_PROBE_TIMEOUT_MS,
1388
+ softwareWebGpu
1389
+ );
1463
1390
  if (!hasUsableAdapter) throw new WebGpuUnavailableError();
1464
1391
  }
1465
1392
  function getBrowserGpuArgs(mode, platform) {
@@ -5105,9 +5032,10 @@ async function createCaptureSession(serverUrl, outputDir, options, onBeforeCaptu
5105
5032
  );
5106
5033
  const preMode = headlessShell && isLinux && !effectiveForceScreenshot && !supersampling && !drawElementTransparent ? "beginframe" : "screenshot";
5107
5034
  const requiresWebGpu = options.requiresWebGpu ?? await fetch(`${serverUrl}/index.html`, { signal: AbortSignal.timeout(5e3) }).then((res) => res.text()).then(compositionRequiresWebGpu).catch(() => false);
5035
+ const gpuConfig = { ...config, browserGpuMode: resolvedGpuMode };
5108
5036
  const chromeArgs = buildChromeArgs(
5109
5037
  { width: options.width, height: options.height, captureMode: preMode, requiresWebGpu },
5110
- { ...config, browserGpuMode: resolvedGpuMode }
5038
+ gpuConfig
5111
5039
  );
5112
5040
  const browserLease = await acquireBrowser(chromeArgs, config);
5113
5041
  return constructCaptureSessionWithRollback({
@@ -5118,7 +5046,8 @@ async function createCaptureSession(serverUrl, outputDir, options, onBeforeCaptu
5118
5046
  onBeforeCapture,
5119
5047
  config,
5120
5048
  useDrawElement,
5121
- requiresWebGpu
5049
+ requiresWebGpu,
5050
+ softwareWebGpu: usesSoftwareWebGpu(requiresWebGpu, gpuConfig)
5122
5051
  });
5123
5052
  }
5124
5053
  async function constructCaptureSessionWithRollback(input) {
@@ -5168,6 +5097,7 @@ async function constructCaptureSession(input) {
5168
5097
  config,
5169
5098
  useDrawElement,
5170
5099
  requiresWebGpu,
5100
+ softwareWebGpu,
5171
5101
  onPageCreated
5172
5102
  } = input;
5173
5103
  const { browser, captureMode } = browserLease;
@@ -5231,6 +5161,7 @@ async function constructCaptureSession(input) {
5231
5161
  outputDir,
5232
5162
  onBeforeCapture,
5233
5163
  requiresWebGpu,
5164
+ softwareWebGpu,
5234
5165
  isInitialized: false,
5235
5166
  browserConsoleBuffer: [],
5236
5167
  scriptLoadFailures: [],
@@ -5790,7 +5721,11 @@ async function initializeSession(session) {
5790
5721
  );
5791
5722
  throw error;
5792
5723
  }
5793
- await assertWebGpuAdapterAvailable(page, session.requiresWebGpu ?? false);
5724
+ await assertWebGpuAdapterAvailable(
5725
+ page,
5726
+ session.requiresWebGpu ?? false,
5727
+ session.softwareWebGpu
5728
+ );
5794
5729
  };
5795
5730
  if (session.captureMode === "screenshot") {
5796
5731
  await gotoEntryPage();
@@ -6036,7 +5971,7 @@ async function seekPageTimeline(page, time, seekOptions) {
6036
5971
  seekOptions
6037
5972
  );
6038
5973
  }
6039
- async function prepareFrameForCapture(session, frameIndex, time, seekOptions) {
5974
+ async function prepareFrameForCapture(session, frameIndex, time, seekOptions, heldVideoTime) {
6040
5975
  const { page, options } = session;
6041
5976
  if (!session.isInitialized) {
6042
5977
  throw new Error("[FrameCapture] Session not initialized");
@@ -6053,7 +5988,7 @@ async function prepareFrameForCapture(session, frameIndex, time, seekOptions) {
6053
5988
  const seekMs = Date.now() - seekStart;
6054
5989
  const beforeCaptureStart = Date.now();
6055
5990
  if (session.onBeforeCapture) {
6056
- await session.onBeforeCapture(page, quantizedTime);
5991
+ await session.onBeforeCapture(page, quantizedTime, heldVideoTime);
6057
5992
  }
6058
5993
  await waitForPendingSeekCompletion(page);
6059
5994
  await page.evaluate(async () => {
@@ -6157,6 +6092,8 @@ async function computeStaticFrameSet(page, fps) {
6157
6092
  }
6158
6093
  const hasVideo2 = !!document.querySelector("video");
6159
6094
  const hasCanvas2 = !!document.querySelector("canvas");
6095
+ const hasFrameSources2 = w.__hfHasFrameSources?.() ?? false;
6096
+ const hasIframe2 = !!document.querySelector("iframe");
6160
6097
  const hasUnresolvableClipStart2 = Array.from(document.querySelectorAll("[data-start]")).some(
6161
6098
  (el) => {
6162
6099
  const v = el.dataset.start;
@@ -6181,6 +6118,8 @@ async function computeStaticFrameSet(page, fps) {
6181
6118
  duration: w.__hf?.duration ?? 0,
6182
6119
  hasVideo: hasVideo2,
6183
6120
  hasCanvas: hasCanvas2,
6121
+ hasFrameSources: hasFrameSources2,
6122
+ hasIframe: hasIframe2,
6184
6123
  hasNonGsapAnim: hasNonGsapAnim2,
6185
6124
  hasUnresolvableClipStart: hasUnresolvableClipStart2,
6186
6125
  hasTimelineCall: hasTimelineCall2
@@ -6192,6 +6131,8 @@ async function computeStaticFrameSet(page, fps) {
6192
6131
  duration,
6193
6132
  hasVideo,
6194
6133
  hasCanvas,
6134
+ hasFrameSources,
6135
+ hasIframe,
6195
6136
  hasNonGsapAnim,
6196
6137
  hasUnresolvableClipStart,
6197
6138
  hasTimelineCall
@@ -6225,6 +6166,8 @@ async function computeStaticFrameSet(page, fps) {
6225
6166
  if (!(duration > 0)) reasons.push("unknown/zero duration");
6226
6167
  if (hasVideo) reasons.push("video");
6227
6168
  if (hasCanvas) reasons.push("canvas/webgl");
6169
+ if (hasFrameSources) reasons.push("registered frame source");
6170
+ if (hasIframe) reasons.push("iframe");
6228
6171
  if (tweenCount === 0) reasons.push("no GSAP tweens (non-GSAP animation)");
6229
6172
  if (hasNonGsapAnim) reasons.push("running CSS/WAAPI animation");
6230
6173
  if (hasTimelineCall) reasons.push("tl.call() side effect (not seek-safe)");
@@ -6651,20 +6594,16 @@ function resolveSessionMotionBlur(session) {
6651
6594
  `[MotionBlur] sub-frame motion blur requires format "png", got "${session.options.format ?? "jpeg"}"`
6652
6595
  );
6653
6596
  }
6654
- if (session.onBeforeCapture) {
6655
- throw new Error(
6656
- "[MotionBlur] sub-frame motion blur cannot run with injected video frames: video content is extracted per output frame and does not follow a sub-frame seek"
6657
- );
6658
- }
6659
6597
  return plan;
6660
6598
  }
6661
- async function captureFrameSurface(session, frameIndex, time, seekOptions) {
6599
+ async function captureFrameSurface(session, frameIndex, time, seekOptions, heldVideoTime) {
6662
6600
  const { page, options } = session;
6663
6601
  const { quantizedTime, seekMs, beforeCaptureMs } = await prepareFrameForCapture(
6664
6602
  session,
6665
6603
  frameIndex,
6666
6604
  time,
6667
- seekOptions
6605
+ seekOptions,
6606
+ heldVideoTime
6668
6607
  );
6669
6608
  const screenshotStart = Date.now();
6670
6609
  let screenshotBuffer;
@@ -6781,7 +6720,7 @@ function startChromeMemorySampler(session) {
6781
6720
  session.chromeMemory = sampler;
6782
6721
  sampler.start();
6783
6722
  }
6784
- async function resolveAdaptiveSampleCount(session, frameIndex, absFrameIndex, plan, fps, sampleSeek) {
6723
+ async function resolveAdaptiveSampleCount(session, frameIndex, absFrameIndex, plan, fps, sampleSeek, frameTime) {
6785
6724
  if (session.motionBlurNonSpatialFrames?.has(absFrameIndex)) {
6786
6725
  return {
6787
6726
  samplesPerFrame: DEFAULT_SAMPLES_PER_FRAME,
@@ -6791,8 +6730,8 @@ async function resolveAdaptiveSampleCount(session, frameIndex, absFrameIndex, pl
6791
6730
  };
6792
6731
  }
6793
6732
  const { windowStart, windowEnd } = motionBlurProbeTimes(plan, absFrameIndex, fps);
6794
- const probeA = await captureFrameSurface(session, frameIndex, windowStart, sampleSeek);
6795
- const probeB = await captureFrameSurface(session, frameIndex, windowEnd, sampleSeek);
6733
+ const probeA = await captureFrameSurface(session, frameIndex, windowStart, sampleSeek, frameTime);
6734
+ const probeB = await captureFrameSurface(session, frameIndex, windowEnd, sampleSeek, frameTime);
6796
6735
  return {
6797
6736
  samplesPerFrame: adaptiveSampleCount(probeDiffMagnitude(probeA.buffer, probeB.buffer)),
6798
6737
  seekMs: probeA.seekMs + probeB.seekMs,
@@ -6806,6 +6745,11 @@ async function captureAccumulatedFrame(session, frameIndex, absFrameIndex, plan)
6806
6745
  const eventfulSeekStart = Date.now();
6807
6746
  await seekPageTimeline(session.page, frameTime, void 0);
6808
6747
  const totals = { seekMs: Date.now() - eventfulSeekStart, beforeCaptureMs: 0, screenshotMs: 0 };
6748
+ if (session.onBeforeCapture) {
6749
+ const injectStart = Date.now();
6750
+ await session.onBeforeCapture(session.page, frameTime, frameTime);
6751
+ totals.beforeCaptureMs += Date.now() - injectStart;
6752
+ }
6809
6753
  const sampleSeek = {
6810
6754
  suppressEvents: true,
6811
6755
  subFrameDivisions: plan.subFrameDivisions
@@ -6818,7 +6762,8 @@ async function captureAccumulatedFrame(session, frameIndex, absFrameIndex, plan)
6818
6762
  absFrameIndex,
6819
6763
  plan,
6820
6764
  fps,
6821
- sampleSeek
6765
+ sampleSeek,
6766
+ frameTime
6822
6767
  );
6823
6768
  samplesPerFrame = chosen.samplesPerFrame;
6824
6769
  totals.seekMs += chosen.seekMs;
@@ -6827,7 +6772,13 @@ async function captureAccumulatedFrame(session, frameIndex, absFrameIndex, plan)
6827
6772
  }
6828
6773
  const accumulator = new MotionBlurAccumulator(plan.blend);
6829
6774
  for (const sampleTime of motionBlurSampleTimes(plan, absFrameIndex, fps, samplesPerFrame)) {
6830
- const sample = await captureFrameSurface(session, frameIndex, sampleTime, sampleSeek);
6775
+ const sample = await captureFrameSurface(
6776
+ session,
6777
+ frameIndex,
6778
+ sampleTime,
6779
+ sampleSeek,
6780
+ frameTime
6781
+ );
6831
6782
  totals.seekMs += sample.seekMs;
6832
6783
  totals.beforeCaptureMs += sample.beforeCaptureMs;
6833
6784
  totals.screenshotMs += sample.screenshotMs;
@@ -7274,7 +7225,7 @@ import {
7274
7225
  mkdirSync as mkdirSync2,
7275
7226
  mkdtempSync,
7276
7227
  openSync,
7277
- readFileSync as readFileSync4,
7228
+ readFileSync as readFileSync3,
7278
7229
  readdirSync as readdirSync2,
7279
7230
  statSync as statSync2,
7280
7231
  writeFileSync as writeFileSync2,
@@ -7722,6 +7673,22 @@ function isExternalFfmpegInterruption(result) {
7722
7673
  if (result.signal === "SIGTERM") return true;
7723
7674
  return result.exitCode === 255 && FFMPEG_SIGTERM_EXIT_LINE.test(result.stderr);
7724
7675
  }
7676
+ function ffmpegStatsReader(onStats) {
7677
+ let rest = "";
7678
+ return (chunk) => {
7679
+ const lines = (rest + chunk).split(/[\r\n]/);
7680
+ rest = lines.pop() ?? "";
7681
+ for (const line of lines) {
7682
+ const frame = /frame=\s*(\d+)/.exec(line)?.[1];
7683
+ const time = /time=\s*(\d+):(\d+):(\d+(?:\.\d+)?)/.exec(line);
7684
+ if (frame === void 0 && !time) continue;
7685
+ onStats({
7686
+ frames: frame === void 0 ? void 0 : Number(frame),
7687
+ seconds: time ? Math.round((Number(time[1]) * 3600 + Number(time[2]) * 60 + Number(time[3])) * 100) / 100 : void 0
7688
+ });
7689
+ }
7690
+ };
7691
+ }
7725
7692
  var DEFAULT_TIMEOUT = 3e5;
7726
7693
  var DEFAULT_STDERR_TAIL_LINES = 15;
7727
7694
  function formatWindowsFfmpegExit(exitCode) {
@@ -7816,7 +7783,7 @@ async function runFfmpegPipeline(producerArgs, consumerArgs, opts) {
7816
7783
 
7817
7784
  // ../engine/src/utils/ffprobe.ts
7818
7785
  import { spawn as spawn3 } from "child_process";
7819
- import { createReadStream, readFileSync as readFileSync2, statSync } from "fs";
7786
+ import { createReadStream, readFileSync, statSync } from "fs";
7820
7787
  import { StringDecoder } from "string_decoder";
7821
7788
  import { basename } from "path";
7822
7789
  var FFPROBE_STDERR_MAX_BYTES = 8 * 1024;
@@ -8129,7 +8096,7 @@ function pixelFormatHasAlpha(pixelFormat) {
8129
8096
  }
8130
8097
  function extractStillImageMetadata(filePath) {
8131
8098
  try {
8132
- return extractPngMetadataFromBuffer(readFileSync2(filePath));
8099
+ return extractPngMetadataFromBuffer(readFileSync(filePath));
8133
8100
  } catch {
8134
8101
  return null;
8135
8102
  }
@@ -8438,7 +8405,7 @@ async function analyzeKeyframeIntervalsUncached(filePath, videoStreamStartSecond
8438
8405
  }
8439
8406
 
8440
8407
  // ../engine/src/utils/renderProvenance.ts
8441
- import { readFileSync as readFileSync3 } from "fs";
8408
+ import { readFileSync as readFileSync2 } from "fs";
8442
8409
  import { dirname, join as join4 } from "path";
8443
8410
  import { fileURLToPath } from "url";
8444
8411
  var PROVENANCE_RENDERER_TAG = "hyperframes_renderer";
@@ -8453,7 +8420,7 @@ function resolveOwnVersionFrom(startDir) {
8453
8420
  const candidate = join4(dir, "package.json");
8454
8421
  let pkg;
8455
8422
  try {
8456
- pkg = JSON.parse(readFileSync3(candidate, "utf8"));
8423
+ pkg = JSON.parse(readFileSync2(candidate, "utf8"));
8457
8424
  } catch {
8458
8425
  pkg = void 0;
8459
8426
  }
@@ -8758,7 +8725,9 @@ function buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder = null) {
8758
8725
  args.push("-y", outputPath);
8759
8726
  return args;
8760
8727
  }
8761
- async function encodeFramesFromDir(framesDir, framePattern, outputPath, options, signal, config) {
8728
+ var framesReader = (onFrames) => onFrames && ffmpegStatsReader(({ frames }) => frames !== void 0 && onFrames(frames));
8729
+ var secondsReader = (onSeconds) => onSeconds && ffmpegStatsReader(({ seconds }) => seconds !== void 0 && onSeconds(seconds));
8730
+ async function encodeFramesFromDir(framesDir, framePattern, outputPath, options, signal, config, onFramesEncoded) {
8762
8731
  const startTime = Date.now();
8763
8732
  const outputDir = dirname2(outputPath);
8764
8733
  if (!existsSync4(outputDir)) mkdirSync2(outputDir, { recursive: true });
@@ -8782,7 +8751,11 @@ async function encodeFramesFromDir(framesDir, framePattern, outputPath, options,
8782
8751
  const inputArgs = ["-framerate", fpsToFfmpegArg(options.fps), "-i", inputPath];
8783
8752
  const args = buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder);
8784
8753
  const encodeTimeout = config?.ffmpegEncodeTimeout ?? DEFAULT_CONFIG.ffmpegEncodeTimeout;
8785
- const result = await runFfmpeg(args, { signal, timeout: encodeTimeout });
8754
+ const result = await runFfmpeg(args, {
8755
+ signal,
8756
+ timeout: encodeTimeout,
8757
+ onStderr: framesReader(onFramesEncoded)
8758
+ });
8786
8759
  if (result.terminationReason === "abort") {
8787
8760
  return {
8788
8761
  success: false,
@@ -8854,7 +8827,7 @@ async function concatVideoFiles(inputPaths, outputPath, signal, config) {
8854
8827
  externalInterruption: isExternalFfmpegInterruption(result)
8855
8828
  };
8856
8829
  }
8857
- async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, options, chunkSizeFrames, signal, config) {
8830
+ async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, options, chunkSizeFrames, signal, config, onFramesEncoded) {
8858
8831
  const start = Date.now();
8859
8832
  const files = readdirSync2(framesDir).filter((f) => f.match(/\.(jpg|jpeg|png)$/i)).sort();
8860
8833
  if (files.length === 0) {
@@ -8902,7 +8875,13 @@ async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, op
8902
8875
  if (options.useGpu) gpuEncoder = await getCachedGpuEncoder();
8903
8876
  const args = buildEncoderArgs(options, inputArgs, chunkPath, gpuEncoder);
8904
8877
  const encodeTimeout = config?.ffmpegEncodeTimeout ?? DEFAULT_CONFIG.ffmpegEncodeTimeout;
8905
- const processResult = await runFfmpeg(args, { signal, timeout: encodeTimeout });
8878
+ const processResult = await runFfmpeg(args, {
8879
+ signal,
8880
+ timeout: encodeTimeout,
8881
+ onStderr: framesReader(
8882
+ onFramesEncoded && ((frames) => onFramesEncoded(startNumber + frames))
8883
+ )
8884
+ });
8906
8885
  const chunkResult = {
8907
8886
  success: processResult.success,
8908
8887
  error: processResult.success ? void 0 : appendEncodeTimeoutMessage(
@@ -8945,7 +8924,7 @@ async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, op
8945
8924
  fileSize
8946
8925
  };
8947
8926
  }
8948
- async function muxVideoWithAudio(videoPath, audioPath, outputPath, signal, config, fps) {
8927
+ async function muxVideoWithAudio(videoPath, audioPath, outputPath, signal, config, fps, onSecondsWritten) {
8949
8928
  const outputDir = dirname2(outputPath);
8950
8929
  if (!existsSync4(outputDir)) mkdirSync2(outputDir, { recursive: true });
8951
8930
  const isWebm = outputPath.endsWith(".webm");
@@ -8973,7 +8952,11 @@ async function muxVideoWithAudio(videoPath, audioPath, outputPath, signal, confi
8973
8952
  }
8974
8953
  args.push("-y", outputPath);
8975
8954
  const processTimeout = config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG.ffmpegProcessTimeout;
8976
- const result = await runFfmpeg(args, { signal, timeout: processTimeout });
8955
+ const result = await runFfmpeg(args, {
8956
+ signal,
8957
+ timeout: processTimeout,
8958
+ onStderr: secondsReader(onSecondsWritten)
8959
+ });
8977
8960
  if (signal?.aborted) {
8978
8961
  return {
8979
8962
  success: false,
@@ -9066,7 +9049,7 @@ async function packageHls(videoPath, audioPath, outputDir, options) {
9066
9049
  }
9067
9050
  if (master !== void 0) {
9068
9051
  try {
9069
- const stripped = stripAudioOnlyVariants(readFileSync4(master, "utf-8"));
9052
+ const stripped = stripAudioOnlyVariants(readFileSync3(master, "utf-8"));
9070
9053
  ftruncateSync(master, 0);
9071
9054
  writeSync(master, stripped, 0, "utf-8");
9072
9055
  } finally {
@@ -9082,7 +9065,7 @@ async function packageHls(videoPath, audioPath, outputDir, options) {
9082
9065
  failureReason: result.failureReason
9083
9066
  };
9084
9067
  }
9085
- async function applyFaststart(inputPath, outputPath, signal, config, fps) {
9068
+ async function applyFaststart(inputPath, outputPath, signal, config, fps, onSecondsWritten) {
9086
9069
  if (outputPath.endsWith(".webm") || outputPath.endsWith(".mov")) {
9087
9070
  if (inputPath !== outputPath) copyFileSync(inputPath, outputPath);
9088
9071
  return { success: true, outputPath, durationMs: 0 };
@@ -9094,7 +9077,11 @@ async function applyFaststart(inputPath, outputPath, signal, config, fps) {
9094
9077
  }
9095
9078
  args.push("-y", outputPath);
9096
9079
  const processTimeout = config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG.ffmpegProcessTimeout;
9097
- const result = await runFfmpeg(args, { signal, timeout: processTimeout });
9080
+ const result = await runFfmpeg(args, {
9081
+ signal,
9082
+ timeout: processTimeout,
9083
+ onStderr: secondsReader(onSecondsWritten)
9084
+ });
9098
9085
  if (signal?.aborted) {
9099
9086
  return {
9100
9087
  success: false,
@@ -9416,9 +9403,16 @@ async function spawnStreamingEncoder(outputPath, options, signal, config) {
9416
9403
  ffmpeg.stdout?.on("error", () => {
9417
9404
  });
9418
9405
  const streamingTimeout = config?.ffmpegStreamingTimeout ?? DEFAULT_CONFIG.ffmpegStreamingTimeout;
9406
+ let framesEncoded = 0;
9407
+ let onFramesEncoded;
9419
9408
  const managed = new ManagedChildProcess(ffmpeg, {
9420
9409
  signal,
9421
- inactivityTimeoutMs: streamingTimeout
9410
+ inactivityTimeoutMs: streamingTimeout,
9411
+ onStderr: ffmpegStatsReader(({ frames }) => {
9412
+ if (frames === void 0) return;
9413
+ framesEncoded = frames;
9414
+ onFramesEncoded?.(frames);
9415
+ })
9422
9416
  });
9423
9417
  const exitPromise = managed.wait().then((outcome) => {
9424
9418
  exitCode = outcome.exitCode;
@@ -9481,7 +9475,11 @@ async function spawnStreamingEncoder(outputPath, options, signal, config) {
9481
9475
  managed.markActivity();
9482
9476
  return true;
9483
9477
  },
9484
- close: async () => {
9478
+ close: async (onEncoded) => {
9479
+ if (onEncoded && exitStatus === "running") {
9480
+ onFramesEncoded = onEncoded;
9481
+ onEncoded(framesEncoded);
9482
+ }
9485
9483
  const stdin = ffmpeg.stdin;
9486
9484
  if (stdin && !stdin.destroyed) {
9487
9485
  await new Promise((resolve) => {
@@ -9666,7 +9664,7 @@ function isKnownInactiveTimelineWindow(element, resolvedStart) {
9666
9664
  }
9667
9665
 
9668
9666
  // ../engine/src/utils/alphaPlaneProbe.ts
9669
- import { mkdtempSync as mkdtempSync2, readFileSync as readFileSync5, rmSync } from "fs";
9667
+ import { mkdtempSync as mkdtempSync2, readFileSync as readFileSync4, rmSync } from "fs";
9670
9668
  import { tmpdir as tmpdir2 } from "os";
9671
9669
  import { join as join6 } from "path";
9672
9670
  var BYTES_PER_SAMPLE_FRAME = 8 * 8 * 4;
@@ -9706,7 +9704,7 @@ async function probeInputAlphaPlane(videoPath, decoder, signal) {
9706
9704
  { timeout: 3e4, signal }
9707
9705
  );
9708
9706
  if (!result.success) return void 0;
9709
- return sampledRgbaAlphaIsFullyOpaque(readFileSync5(samplePath));
9707
+ return sampledRgbaAlphaIsFullyOpaque(readFileSync4(samplePath));
9710
9708
  } catch {
9711
9709
  return void 0;
9712
9710
  } finally {
@@ -12763,9 +12761,14 @@ function createVideoFrameInjector(frameLookup, config) {
12763
12761
  touchCacheDir(cacheDir);
12764
12762
  lastCacheTouchByDir.set(cacheDir, now);
12765
12763
  }
12766
- return async (page, time) => {
12764
+ return async (page, time, heldVideoTime) => {
12767
12765
  for (const cacheDir of frameLookup.frameDirs()) renewCacheLease(cacheDir);
12768
12766
  const activePayloads = frameLookup.getActiveFramePayloads(time);
12767
+ if (heldVideoTime !== void 0) {
12768
+ for (const [videoId, payload] of frameLookup.getActiveFramePayloads(heldVideoTime)) {
12769
+ if (activePayloads.has(videoId)) activePayloads.set(videoId, payload);
12770
+ }
12771
+ }
12769
12772
  const updates = [];
12770
12773
  const activeIds = /* @__PURE__ */ new Set();
12771
12774
  if (activePayloads.size > 0) {
@@ -13215,7 +13218,7 @@ function clampFadesToDuration(fades, duration) {
13215
13218
  }
13216
13219
 
13217
13220
  // ../engine/src/services/audioVolumeEnvelope.ts
13218
- import { mkdtempSync as mkdtempSync4, readFileSync as readFileSync6, renameSync as renameSync2, rmSync as rmSync5, writeFileSync as writeFileSync4 } from "fs";
13221
+ import { mkdtempSync as mkdtempSync4, readFileSync as readFileSync5, renameSync as renameSync2, rmSync as rmSync5, writeFileSync as writeFileSync4 } from "fs";
13219
13222
  import { dirname as dirname5, join as join11 } from "path";
13220
13223
 
13221
13224
  // ../core/dist/runtime/mediaVolumeEnvelope.js
@@ -13338,7 +13341,7 @@ function applyVolumeEnvelopeToWav(wavPath, keyframes, trackStart, baseVolume) {
13338
13341
  if (!gainAt) return false;
13339
13342
  let stagingDir;
13340
13343
  try {
13341
- const buffer = readFileSync6(wavPath);
13344
+ const buffer = readFileSync5(wavPath);
13342
13345
  const layout = parseWavLayout(buffer);
13343
13346
  if (!layout) return false;
13344
13347
  scaleSamples(buffer, layout, gainAt);
@@ -13414,7 +13417,7 @@ function chainTailSeconds(chain, automation) {
13414
13417
  }
13415
13418
 
13416
13419
  // ../engine/src/services/audioFxRender.ts
13417
- import { existsSync as existsSync9, mkdtempSync as mkdtempSync5, readFileSync as readFileSync7, rmSync as rmSync6, writeFileSync as writeFileSync5 } from "fs";
13420
+ import { existsSync as existsSync9, mkdtempSync as mkdtempSync5, readFileSync as readFileSync6, rmSync as rmSync6, writeFileSync as writeFileSync5 } from "fs";
13418
13421
  import { tmpdir as tmpdir3 } from "os";
13419
13422
  import { join as join12 } from "path";
13420
13423
  import { pathToFileURL } from "url";
@@ -13451,7 +13454,7 @@ function readWavChunks(buf) {
13451
13454
  return { ...head, data };
13452
13455
  }
13453
13456
  function readWav(path) {
13454
- const buf = readFileSync7(path);
13457
+ const buf = readFileSync6(path);
13455
13458
  if (buf.length < 44 || buf.toString("ascii", 0, 4) !== "RIFF") {
13456
13459
  throw new AudioFxRenderError(`Not a WAV file: ${path}`);
13457
13460
  }
@@ -14939,6 +14942,10 @@ function computeWorkerSizing(totalFrames, requested, config) {
14939
14942
  boundBy = "contention";
14940
14943
  }
14941
14944
  }
14945
+ if (finalWorkers > heapBasedWorkers) {
14946
+ finalWorkers = heapBasedWorkers;
14947
+ boundBy = "heap";
14948
+ }
14942
14949
  return finish(finalWorkers, boundBy, effectiveMaxWorkers);
14943
14950
  }
14944
14951
  function calculateOptimalWorkers(totalFrames, requested, config) {
@@ -15437,7 +15444,7 @@ function getSystemResources() {
15437
15444
  // ../engine/src/services/fileServer.ts
15438
15445
  import { Hono } from "hono";
15439
15446
  import { serve } from "@hono/node-server";
15440
- import { readFileSync as readFileSync8, openSync as openSync4, fstatSync, closeSync as closeSync4, statSync as statSync6, constants } from "fs";
15447
+ import { readFileSync as readFileSync7, openSync as openSync4, fstatSync, closeSync as closeSync4, statSync as statSync6, constants } from "fs";
15441
15448
  import { join as join16, extname as extname3 } from "path";
15442
15449
  var MIME_TYPES = {
15443
15450
  ".html": "text/html; charset=utf-8",
@@ -15479,7 +15486,7 @@ function readRegularFile(filePath) {
15479
15486
  }
15480
15487
  try {
15481
15488
  if (!fstatSync(fd).isFile()) return null;
15482
- return readFileSync8(fd);
15489
+ return readFileSync7(fd);
15483
15490
  } finally {
15484
15491
  closeSync4(fd);
15485
15492
  }
@@ -15888,10 +15895,6 @@ function buildHdrChromeArgs(width, height) {
15888
15895
  }
15889
15896
 
15890
15897
  export {
15891
- getCgroupMemoryLimitMb,
15892
- getSystemTotalMb,
15893
- LOW_MEMORY_TOTAL_MB_THRESHOLD,
15894
- isLowMemorySystem,
15895
15898
  DEFAULT_VP9_CPU_USED,
15896
15899
  MIN_VP9_CPU_USED,
15897
15900
  MAX_VP9_CPU_USED,