hyperframes 0.8.191 → 0.8.193

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 (213) hide show
  1. package/dist/{add-S2ZQYG52.js → add-JC6DKZKC.js} +17 -17
  2. package/dist/{animatedGifPrep-3JA2CQ3U.js → animatedGifPrep-S6KXJGEL.js} +11 -10
  3. package/dist/api.js +24 -23
  4. package/dist/{appHistory-TH3TL6N6.js → appHistory-QVCSAOI4.js} +1 -1
  5. package/dist/{asset-2CNTAPOC.js → asset-XITFIFE6.js} +2 -2
  6. package/dist/{assetCataloger-5HXLXL7C.js → assetCataloger-K5FNKG35.js} +13 -12
  7. package/dist/{audio-DZTSYHXS.js → audio-364UHTY4.js} +22 -21
  8. package/dist/{auth-GX3M6TJ4.js → auth-5JEESRE6.js} +4 -4
  9. package/dist/{autoUpdate-EDIWE4Z5.js → autoUpdate-RVVYEHAA.js} +5 -5
  10. package/dist/{backgroundChecks-VPUPJ7UI.js → backgroundChecks-DCBIYWIQ.js} +5 -5
  11. package/dist/backgroundChecksWorker.js +5 -5
  12. package/dist/{batchRender-JHIIDBJR.js → batchRender-ZZ4QMBAA.js} +14 -7
  13. package/dist/{beats-PZRVTRYW.js → beats-YEL65M6G.js} +53 -15
  14. package/dist/{benchmark-22UFDW2N.js → benchmark-RBTRPA76.js} +18 -14
  15. package/dist/{browser-VRDWYIUM.js → browser-BVAYXT4R.js} +7 -7
  16. package/dist/{bundleWithLocalizedFonts-23QDKFSN.js → bundleWithLocalizedFonts-JLB2OYMT.js} +3 -3
  17. package/dist/{capture-TOCLXYMJ.js → capture-GBXTMYLZ.js} +76 -68
  18. package/dist/{capture-NFCBXHDE.js → capture-NIFX6IRS.js} +3 -3
  19. package/dist/{captureCompositionFrame-BEM6MF7F.js → captureCompositionFrame-ATNNKUL5.js} +17 -16
  20. package/dist/{catalog-NXS35KM7.js → catalog-AGIF5SM5.js} +18 -18
  21. package/dist/{catch-up-6WJBUI2C.js → catch-up-SZ3ULDTI.js} +7 -7
  22. package/dist/{check-WVEBMWN5.js → check-YLQS3TF4.js} +43 -42
  23. package/dist/{checkBrowser-RT45HJ36.js → checkBrowser-QH4FMCBO.js} +38 -37
  24. package/dist/{chunk-JOLZ3BSL.js → chunk-2LSCYS2H.js} +2 -2
  25. package/dist/{chunk-B2A56S5C.js → chunk-2MCXIY4B.js} +13 -10
  26. package/dist/{chunk-TADJOIFW.js → chunk-2NERNYCJ.js} +4 -4
  27. package/dist/{chunk-KGMHMYWI.js → chunk-2SFDWMSW.js} +2 -2
  28. package/dist/{chunk-DCAI5DBR.js → chunk-2ST4WAFY.js} +9 -1
  29. package/dist/{chunk-3NRB7YXW.js → chunk-2VXY3PEF.js} +96 -67
  30. package/dist/{chunk-IXLUTE6N.js → chunk-3422KMTD.js} +5 -1
  31. package/dist/{chunk-VYQYVYQ5.js → chunk-3W4B6G7Y.js} +83 -45
  32. package/dist/{chunk-JYSSPQDT.js → chunk-4LXZJIVY.js} +11 -11
  33. package/dist/{chunk-WHAEJX26.js → chunk-4PPWAQYV.js} +17 -12
  34. package/dist/{chunk-COWQITWP.js → chunk-4TKJWWPL.js} +1 -1
  35. package/dist/{chunk-NXMYHJAL.js → chunk-4VYPICIA.js} +29 -1
  36. package/dist/{chunk-RE3EEBWC.js → chunk-5J6TWLFG.js} +4 -4
  37. package/dist/{chunk-TFMZ4RKM.js → chunk-6DLCOQR4.js} +474 -429
  38. package/dist/{chunk-KV72BP7O.js → chunk-6LWUPIKD.js} +11 -11
  39. package/dist/{chunk-HRPWRZGF.js → chunk-6N65ZMC5.js} +1 -1
  40. package/dist/{chunk-XUXGIA7H.js → chunk-6NLPPKBO.js} +1 -2
  41. package/dist/{chunk-JJJCFKMF.js → chunk-6XUJVEY2.js} +17 -6
  42. package/dist/{chunk-GM3WIOO6.js → chunk-7HTH5PFK.js} +2 -2
  43. package/dist/{chunk-LBNEH6IQ.js → chunk-7QNIXBQD.js} +1 -1
  44. package/dist/{chunk-OV6KHXLX.js → chunk-7YKJF5JV.js} +1 -1
  45. package/dist/{chunk-COETAXRN.js → chunk-7YSFE4SZ.js} +2 -2
  46. package/dist/{chunk-3WJT2JCX.js → chunk-AR3DQYRR.js} +52 -23
  47. package/dist/{chunk-HYW6HTAK.js → chunk-BJAS2JLW.js} +2 -2
  48. package/dist/{chunk-RWYUK7LM.js → chunk-BP4EMEGH.js} +2 -2
  49. package/dist/{chunk-XGHHVYC7.js → chunk-BY6OQ6XP.js} +2 -2
  50. package/dist/{chunk-TMBUBLZB.js → chunk-C4Y3ZREE.js} +185 -46
  51. package/dist/{chunk-JQYJXUJW.js → chunk-C6KE4AFW.js} +1 -1
  52. package/dist/{chunk-TMK4Q7JA.js → chunk-CFUCHO4T.js} +20 -5
  53. package/dist/{chunk-JGTRVG32.js → chunk-CGTZOY53.js} +1 -1
  54. package/dist/chunk-CZGHFATT.js +31 -0
  55. package/dist/{chunk-NJGTNWQY.js → chunk-D625D4TV.js} +6 -6
  56. package/dist/{chunk-CYBXXSC4.js → chunk-DIKAPMMF.js} +2 -2
  57. package/dist/{chunk-CXMXJEVY.js → chunk-DSQ72G5I.js} +1 -1
  58. package/dist/{chunk-GLG5JWLI.js → chunk-DYNHVCBF.js} +2 -2
  59. package/dist/{chunk-7L37AB57.js → chunk-E3P3LJG6.js} +9 -9
  60. package/dist/{chunk-EFCKV7MY.js → chunk-E77ALFLW.js} +1 -1
  61. package/dist/{chunk-WQ3X5OH4.js → chunk-EFXMETRK.js} +2 -2
  62. package/dist/{chunk-7KVVNF7B.js → chunk-ELP5QZWL.js} +1 -1
  63. package/dist/{chunk-QH3T4WI2.js → chunk-EXAX37XR.js} +8 -2
  64. package/dist/{chunk-7A65UCMI.js → chunk-F5LLORBP.js} +2 -2
  65. package/dist/{chunk-EI7FP7F3.js → chunk-FBVUAH7N.js} +12 -2
  66. package/dist/{chunk-XWOCXIKR.js → chunk-GKHMSSGY.js} +1 -1
  67. package/dist/{chunk-DOOSC34Z.js → chunk-GR5DQKDR.js} +8 -8
  68. package/dist/{chunk-W64L7IFS.js → chunk-IW5G323T.js} +1 -1
  69. package/dist/{chunk-NAUKCKCJ.js → chunk-KU3UFQN7.js} +9 -12
  70. package/dist/{chunk-NMDUSCCE.js → chunk-L4JB7LI4.js} +478 -129
  71. package/dist/{chunk-ALEF2F5N.js → chunk-L5YLA54L.js} +2 -2
  72. package/dist/{chunk-MSM6VRQ4.js → chunk-LFUVTS6V.js} +2 -2
  73. package/dist/{chunk-7ZJEQY7Q.js → chunk-LMNZLZMJ.js} +23 -3
  74. package/dist/{chunk-AQB5M53R.js → chunk-M3KZBDPB.js} +3 -3
  75. package/dist/{chunk-BFFLKQVB.js → chunk-MFUNDJEV.js} +4 -4
  76. package/dist/{chunk-7NKJS5KM.js → chunk-OFV3WSOE.js} +1 -1
  77. package/dist/{chunk-CINKQY6M.js → chunk-OFYW4J7Y.js} +3 -3
  78. package/dist/{chunk-5C7R55BJ.js → chunk-P2I4RLJE.js} +1 -1
  79. package/dist/{chunk-RUOG4VB7.js → chunk-PKZ7RK5N.js} +5 -4
  80. package/dist/{chunk-LLFQA7XF.js → chunk-QFPBRZJD.js} +1 -1
  81. package/dist/{chunk-TRZVS6TL.js → chunk-QKX7ITER.js} +3 -3
  82. package/dist/{chunk-46HEFGXJ.js → chunk-REUL2KH2.js} +1 -1
  83. package/dist/{chunk-TFGO5YMI.js → chunk-RTLPWOO6.js} +2 -2
  84. package/dist/{chunk-DYAPHNV6.js → chunk-RWGASWT7.js} +1 -1
  85. package/dist/chunk-RXATE6FZ.js +385 -0
  86. package/dist/{chunk-U5GTDAQL.js → chunk-SOY2FPOR.js} +7 -7
  87. package/dist/{chunk-KNU5COPB.js → chunk-T2EUWCJE.js} +1 -1
  88. package/dist/{chunk-RQBB7PYT.js → chunk-TY3LDJA3.js} +5 -12
  89. package/dist/{chunk-KAC2WR7P.js → chunk-TZEKVLPV.js} +3 -3
  90. package/dist/{chunk-TJKE4EYX.js → chunk-UB7BIDBS.js} +3 -3
  91. package/dist/{chunk-WY3TQ2PT.js → chunk-UIC7B5KW.js} +2 -2
  92. package/dist/{chunk-2WNVHZHA.js → chunk-UNATIAOT.js} +13 -13
  93. package/dist/chunk-USWPZXEA.js +3897 -0
  94. package/dist/{chunk-FBDOHH3Q.js → chunk-V7ZA2BNW.js} +29 -59
  95. package/dist/{chunk-7LUJE3II.js → chunk-VLLFORE2.js} +1 -1
  96. package/dist/{chunk-T5YF32WV.js → chunk-VPC4XIVI.js} +6 -5
  97. package/dist/{chunk-7FF36MAD.js → chunk-VW63MHQU.js} +9 -6
  98. package/dist/{chunk-ZHKUIC7X.js → chunk-WFS6S65A.js} +21 -14
  99. package/dist/{chunk-UNR3P7IF.js → chunk-WIVOXGEP.js} +3 -3
  100. package/dist/{chunk-3XI7MIZB.js → chunk-X5CECNCK.js} +1 -1
  101. package/dist/{chunk-KHCTBZGJ.js → chunk-XQPA4W3M.js} +4 -4
  102. package/dist/{chunk-XMSQRDAK.js → chunk-YS4JUGNI.js} +2 -2
  103. package/dist/{chunk-SMEF3TRJ.js → chunk-ZH7J2ZUL.js} +15 -15
  104. package/dist/{chunk-WJEVUPVD.js → chunk-ZT45TCY3.js} +1 -1
  105. package/dist/{chunk-JTPHFYZI.js → chunk-ZTKFRXJB.js} +68 -7
  106. package/dist/{chunk-W3CS2KFV.js → chunk-ZZPBXRYQ.js} +2 -2
  107. package/dist/{clean-3VIU2BSK.js → clean-5HGESK5A.js} +40 -27
  108. package/dist/cli.js +70 -68
  109. package/dist/{cloud-NA3J4XW2.js → cloud-746PHS32.js} +4 -4
  110. package/dist/{cloudrun-4MHOF7UT.js → cloudrun-DO7WFLSM.js} +9 -9
  111. package/dist/commands/contrast-audit.browser.js +1 -1
  112. package/dist/{compare-ZR7XRPPT.js → compare-66YPRNG2.js} +76 -47
  113. package/dist/{compiler-MA2ELZPG.js → compiler-R4UYDWXO.js} +8 -7
  114. package/dist/{component-ZJSOPUAM.js → component-EQ3H6RFP.js} +3 -3
  115. package/dist/{compositions-WA5V2SHF.js → compositions-ZZ7P5HT2.js} +19 -17
  116. package/dist/{contactSheet-CAGMKI3E.js → contactSheet-SZBJDOMT.js} +2 -2
  117. package/dist/{delete-UC427UEA.js → delete-Z5MSLJSR.js} +7 -7
  118. package/dist/{deploy-B5UO4UIK.js → deploy-RGSAC2K5.js} +1 -1
  119. package/dist/{deterministicFonts-EGAAE7QL.js → deterministicFonts-RO2TCMLZ.js} +3 -3
  120. package/dist/{dist-XGPSPKKP.js → dist-QQ26RUDV.js} +5 -4
  121. package/dist/{dist-BPK37SAB.js → dist-RKK4YLAD.js} +5 -5
  122. package/dist/{doctor-ZERCTKEK.js → doctor-W4ZZDRTU.js} +20 -19
  123. package/dist/{events-DCOZQERS.js → events-BSSL4A4W.js} +4 -4
  124. package/dist/{events-CNIXB2QK.js → events-UACT7PX3.js} +5 -5
  125. package/dist/{feedback-YBD5ITTY.js → feedback-47ILDLQG.js} +16 -16
  126. package/dist/{ffmpeg-V4BBFDTG.js → ffmpeg-IEHSUNUT.js} +13 -12
  127. package/dist/{figma-Z45ZYVGE.js → figma-PLFIIYRU.js} +3 -3
  128. package/dist/fontLocalizeCli.js +14 -13
  129. package/dist/{get-23NXQWCD.js → get-PDWGJYNL.js} +7 -7
  130. package/dist/{gpuPolicy-H6ABHVEB.js → gpuPolicy-6UBXO6ME.js} +11 -10
  131. package/dist/{grade-compare-ZPX2G3UV.js → grade-compare-5VWLQGM7.js} +38 -37
  132. package/dist/{gsapParserAcorn-SKODXC2N.js → gsapParserAcorn-OOTY2MVN.js} +2 -2
  133. package/dist/{help-EP4CDPLO.js → help-DS3KMWYO.js} +1 -1
  134. package/dist/{history-E5OSXO74.js → history-OC326NVZ.js} +41 -17
  135. package/dist/hyperframe.manifest.json +1 -1
  136. package/dist/hyperframe.runtime.iife.js +62 -62
  137. package/dist/hyperframes-player.global.js +3 -3
  138. package/dist/hyperframes-slideshow.global.js +1 -1
  139. package/dist/{info-2HHGSW5H.js → info-AUIFV6MX.js} +56 -22
  140. package/dist/{init-ENEG6RZT.js → init-MRTWWDFW.js} +38 -45
  141. package/dist/{inspect-PVQK4E2A.js → inspect-55NOAXI2.js} +36 -35
  142. package/dist/{installer-YGGLEOSF.js → installer-YSFFGBBV.js} +8 -8
  143. package/dist/{keyframes-UWSYS2SL.js → keyframes-OO2BX2IB.js} +13 -14
  144. package/dist/{lambda-L3LPXC2M.js → lambda-CXXY6QT3.js} +11 -11
  145. package/dist/{layout-JVL4QREC.js → layout-57GJXKDK.js} +36 -35
  146. package/dist/{lint-JXQ72DDB.js → lint-J4FK3Z6G.js} +23 -16
  147. package/dist/{lintProject-F7IC7WY4.js → lintProject-52SLJPRC.js} +5 -4
  148. package/dist/{list-UFMLM3VV.js → list-VDQUJ76B.js} +7 -7
  149. package/dist/{login-CKGMWQJN.js → login-TJSEALWW.js} +7 -7
  150. package/dist/{logout-DDC4QLVK.js → logout-JYFWWUGK.js} +3 -3
  151. package/dist/{manager-U6OP3EXB.js → manager-4PLYEEWP.js} +14 -13
  152. package/dist/{manager-UHWEKPXC.js → manager-MZIJY73J.js} +3 -3
  153. package/dist/{media-treatment-MFMEWCDY.js → media-treatment-GXP4PMJH.js} +20 -19
  154. package/dist/{models-QA3TJ75Y.js → models-HQQQKEEP.js} +18 -17
  155. package/dist/{motionShot-NV2OPJHD.js → motionShot-2BT5D7DC.js} +21 -20
  156. package/dist/{normalize-3AYFSN2F.js → normalize-FASIPBUM.js} +1 -1
  157. package/dist/{normalize-audio-JWJRUKK2.js → normalize-audio-SOLFMHNP.js} +12 -8
  158. package/dist/{open-PTJNDRER.js → open-KHEUODFQ.js} +18 -18
  159. package/dist/{parakeetRunner-B5FCWWOO.js → parakeetRunner-BHU5NCAX.js} +20 -19
  160. package/dist/{pipeline-N26NA6ZG.js → pipeline-WFV5HDTD.js} +15 -14
  161. package/dist/{play-45D6X6TV.js → play-GB34CANJ.js} +27 -26
  162. package/dist/{policies-MBWGLMWB.js → policies-GHVXA5PE.js} +1 -1
  163. package/dist/{preflight-MFOHPUOI.js → preflight-REF3VSJ7.js} +15 -14
  164. package/dist/{present-IFBUDI4D.js → present-SIUTA7TD.js} +24 -23
  165. package/dist/{preview-MQRLXQOV.js → preview-T2GE7Z4A.js} +27 -26
  166. package/dist/{producer-2QG7HLAW.js → producer-23KVQZAB.js} +1 -1
  167. package/dist/{projectConfig-I4FTZXHB.js → projectConfig-DBSNBPNP.js} +10 -10
  168. package/dist/{publication-3GOFXCGU.js → publication-IXPUKYWJ.js} +5 -5
  169. package/dist/{publish-3B2TZCFH.js → publish-3BA5VHXJ.js} +18 -17
  170. package/dist/{refresh-RXTOPRBB.js → refresh-USSFPJAU.js} +3 -3
  171. package/dist/{remove-background-RK4BJDBF.js → remove-background-RMSCJVVQ.js} +16 -15
  172. package/dist/{render-SJ4HFPFU.js → render-6RNE2MLU.js} +26 -25
  173. package/dist/{render-PW3XGS7B.js → render-XGOZMMWX.js} +42 -41
  174. package/dist/{render-BV6FWFX3.js → render-Y6CTQ3YW.js} +8 -8
  175. package/dist/{render-batch-GKX54O6N.js → render-batch-VUR6N6EY.js} +9 -9
  176. package/dist/renderSetupWorker.js +9 -8
  177. package/dist/{resolver-RQJ7CNXD.js → resolver-GJCUH57W.js} +7 -7
  178. package/dist/{screenshotCapture-UBY6TT75.js → screenshotCapture-I5EDCITF.js} +6 -3
  179. package/dist/{sherpa-XZPG7QFF.js → sherpa-VVAKRCPL.js} +19 -18
  180. package/dist/skills/hyperframes/references/format.md +1 -0
  181. package/dist/skills/hyperframes/references/skill-lifecycle.md +8 -4
  182. package/dist/skills/hyperframes-cli/references/init-and-scaffold.md +1 -1
  183. package/dist/{skills-EYLB2V6F.js → skills-ZHBURVQG.js} +13 -75
  184. package/dist/{skillsUpdateCheck-TE6K5ROM.js → skillsUpdateCheck-VMDAL2O2.js} +5 -5
  185. package/dist/{slideshow-YTWATJRT.js → slideshow-SJGK4RQS.js} +1 -1
  186. package/dist/{snapshot-FE4T3SCN.js → snapshot-KEOG56SL.js} +61 -53
  187. package/dist/{src-ZOXSEJCD.js → src-BH5NICGQ.js} +24 -9
  188. package/dist/{src-SEJ7LNNB.js → src-TZLGFRRX.js} +13 -12
  189. package/dist/{staticProjectServer-LSVIRDRO.js → staticProjectServer-BKXL5CXB.js} +22 -21
  190. package/dist/{status-CM7IQTU2.js → status-H5WLKQDS.js} +3 -3
  191. package/dist/studio/assets/{hyperframes-player-Bv9hQ3v7.js → hyperframes-player-BMcUdmDb.js} +3 -3
  192. package/dist/studio/assets/{index-CBO8uz7-.css → index-CYbvOVp-.css} +1 -1
  193. package/dist/studio/assets/{index-D_QqfWhx.js → index-Ca-mgTnS.js} +122 -122
  194. package/dist/studio/assets/{index-Df14bh-L.js → index-Ci6GuloR.js} +1 -1
  195. package/dist/studio/index.html +2 -2
  196. package/dist/{studio-api-SL2Z76NU.js → studio-api-A5U6QAMC.js} +19 -14
  197. package/dist/{studioServer-BADWVIHU.js → studioServer-5EC5CP4W.js} +60 -59
  198. package/dist/{telemetry-QG5AANZ4.js → telemetry-4K6CPMNT.js} +2 -2
  199. package/dist/{telemetry-RN6VYEID.js → telemetry-BCKJXDSW.js} +5 -5
  200. package/dist/{timeline-JBTCIPLU.js → timeline-AZWAXTAY.js} +65 -43
  201. package/dist/{tokens-A7V7UHNK.js → tokens-X7NC3V7C.js} +2 -2
  202. package/dist/{transcribe-E4BOSNM4.js → transcribe-7NCY7QZ2.js} +17 -16
  203. package/dist/{transcribe-NTUCJGFI.js → transcribe-SH26H755.js} +26 -25
  204. package/dist/{tts-A2WILYGN.js → tts-5I2AJNLM.js} +1 -1
  205. package/dist/{updateCheck-M7UAYLUR.js → updateCheck-Y7FUWQM4.js} +4 -4
  206. package/dist/{upgrade-A2COSIMB.js → upgrade-ZHGEVL65.js} +4 -4
  207. package/dist/{urlDownloader-MBSQYART.js → urlDownloader-FPILIT7M.js} +10 -9
  208. package/dist/{validate-NODZYBHY.js → validate-KQOZR4F6.js} +30 -29
  209. package/dist/{video-LBCUUYK7.js → video-N2QAETFB.js} +12 -11
  210. package/dist/warmCheck.js +43 -42
  211. package/package.json +2 -1
  212. package/dist/chunk-I5JRXMCV.js +0 -6077
  213. package/dist/chunk-LM265QNK.js +0 -3896
@@ -8,7 +8,7 @@ import {
8
8
  EncoderInterruptedError,
9
9
  encoderFailureError,
10
10
  prepareAnimatedGifInputs
11
- } from "./chunk-RQBB7PYT.js";
11
+ } from "./chunk-TY3LDJA3.js";
12
12
  import {
13
13
  GENERIC_FAMILIES,
14
14
  collectFontFamilyCustomProperties,
@@ -16,7 +16,7 @@ import {
16
16
  iterateFontFamilyDeclarations,
17
17
  normalizeSystemFontPrimaryFamilies,
18
18
  resolveFontFamilyDeclarationFamilies
19
- } from "./chunk-LLFQA7XF.js";
19
+ } from "./chunk-QFPBRZJD.js";
20
20
  import {
21
21
  parseEncoderOptions
22
22
  } from "./chunk-KLIKCX6Q.js";
@@ -73,6 +73,8 @@ import {
73
73
  createFrameLookupTable,
74
74
  createFrameReorderBuffer,
75
75
  createVideoFrameInjector,
76
+ declareContentAddressedUrl,
77
+ declareProbeFactsUrl,
76
78
  decodePng,
77
79
  decodePngToRgb48le,
78
80
  deriveBeginFrameProbeTimeTicks,
@@ -136,6 +138,7 @@ import {
136
138
  readWebGlVendorInfoFromCanvas,
137
139
  recaptureDrawElementFrameForVerify,
138
140
  removeDomLayerMask,
141
+ renameWithRetry,
139
142
  resampleRgb48leObjectFit,
140
143
  resolveBrowserGpuMode,
141
144
  resolveConfig,
@@ -156,7 +159,7 @@ import {
156
159
  validateEngineConfigSnapshot,
157
160
  verifyDiskDrawElementSamples,
158
161
  writeCapturedFrame
159
- } from "./chunk-NMDUSCCE.js";
162
+ } from "./chunk-L4JB7LI4.js";
160
163
  import {
161
164
  DISTRIBUTED_FPS,
162
165
  HF_VFX_ATTR,
@@ -171,7 +174,7 @@ import {
171
174
  parseVfxChain,
172
175
  resolveAuthoredTimingWindow,
173
176
  toFps
174
- } from "./chunk-GM3WIOO6.js";
177
+ } from "./chunk-7HTH5PFK.js";
175
178
  import {
176
179
  assignBundledRuntimeCompositionIds,
177
180
  buildVariablesByCompScript,
@@ -184,7 +187,7 @@ import {
184
187
  isTemplateEntry,
185
188
  parsesAsScript,
186
189
  prepareFlattenedInnerRoot
187
- } from "./chunk-VYQYVYQ5.js";
190
+ } from "./chunk-3W4B6G7Y.js";
188
191
  import {
189
192
  COMPOSITION_SOURCE_URL,
190
193
  HF_COLOR_GRADING_ATTR,
@@ -212,7 +215,7 @@ import {
212
215
  shouldClampResolvedMediaDuration,
213
216
  sourceTimeAt,
214
217
  styleElementsFor
215
- } from "./chunk-LM265QNK.js";
218
+ } from "./chunk-USWPZXEA.js";
216
219
  import {
217
220
  MAX_AUDIO_GAIN
218
221
  } from "./chunk-X7HBSTCZ.js";
@@ -226,7 +229,7 @@ import {
226
229
  isAspectAgnosticResolutionAlias,
227
230
  normalizeResolutionFlag,
228
231
  suggestMatchingPreset
229
- } from "./chunk-B2A56S5C.js";
232
+ } from "./chunk-2MCXIY4B.js";
230
233
  import {
231
234
  TRANSITIONS,
232
235
  convertTransfer,
@@ -242,7 +245,7 @@ import {
242
245
  import {
243
246
  lintHyperframeHtml,
244
247
  resolveReferencedStart
245
- } from "./chunk-3NRB7YXW.js";
248
+ } from "./chunk-2VXY3PEF.js";
246
249
  import {
247
250
  isUnresolvedAssetPlaceholder,
248
251
  readProjectFile,
@@ -1569,16 +1572,7 @@ var RenderExecutionContext = class {
1569
1572
  };
1570
1573
 
1571
1574
  // ../producer/src/services/render/artifactTransaction.ts
1572
- import {
1573
- closeSync as closeSync2,
1574
- existsSync as existsSync5,
1575
- fstatSync as fstatSync2,
1576
- openSync as openSync2,
1577
- readSync,
1578
- readdirSync as readdirSync2,
1579
- renameSync,
1580
- rmSync as rmSync3
1581
- } from "fs";
1575
+ import { closeSync as closeSync2, existsSync as existsSync5, fstatSync as fstatSync2, openSync as openSync2, readSync, readdirSync as readdirSync2, rmSync as rmSync3 } from "fs";
1582
1576
  import { basename as basename3, dirname as dirname4, extname as extname2, join as join5, resolve as resolve4 } from "path";
1583
1577
 
1584
1578
  // ../producer/src/services/render/renderDirOwner.ts
@@ -1691,7 +1685,7 @@ function createRenderWorkDir(prefix, outputDir) {
1691
1685
  // ../producer/src/services/render/artifactTransaction.ts
1692
1686
  var defaultFileSystem = {
1693
1687
  existsSync: existsSync5,
1694
- renameSync,
1688
+ renameSync: (source, destination) => renameWithRetry(source, destination),
1695
1689
  rmSync: rmSync3
1696
1690
  };
1697
1691
  async function defaultArtifactDurationProbe(path) {
@@ -2078,36 +2072,8 @@ function replanAfterFailure(plan2, failure) {
2078
2072
  import { existsSync as existsSync6, mkdirSync as mkdirSync3, rmSync as rmSync5, statSync as statSync2 } from "fs";
2079
2073
  import { join as join9 } from "path";
2080
2074
 
2081
- // ../producer/src/services/render/captureStageError.ts
2082
- var CaptureStageError = class extends CaptureFailure {
2083
- browserConsole;
2084
- constructor(input) {
2085
- const classified = classifyCaptureFailure(input.cause);
2086
- super({
2087
- kind: classified.kind,
2088
- message: normalizeErrorMessage(input.cause),
2089
- cause: input.cause,
2090
- workerDiagnostics: classified.workerDiagnostics
2091
- });
2092
- this.name = "CaptureStageError";
2093
- this.browserConsole = input.browserConsole.slice();
2094
- if (input.cause instanceof Error && input.cause.stack) {
2095
- this.stack = input.cause.stack;
2096
- }
2097
- }
2098
- };
2099
- function wrapCaptureStageError(error, browserConsole) {
2100
- if (error instanceof CaptureStageError || error instanceof EncoderInterruptedError) return error;
2101
- return new CaptureStageError({ cause: error, browserConsole });
2102
- }
2103
- function getCaptureStageBrowserConsole(error) {
2104
- if (error instanceof CaptureStageError) return error.browserConsole;
2105
- return [];
2106
- }
2107
-
2108
- // ../producer/src/services/hdrCompositor.ts
2109
- import { readSync as readSync2, closeSync as closeSync3 } from "fs";
2110
- import { join as join6 } from "path";
2075
+ // ../producer/src/services/render/perfSummary.ts
2076
+ import { arch, cpus, platform, totalmem } from "os";
2111
2077
 
2112
2078
  // ../producer/src/services/render/hdrPerf.ts
2113
2079
  function createHdrPerfCollector() {
@@ -2213,7 +2179,257 @@ function finalizeHdrPerf(perf) {
2213
2179
  };
2214
2180
  }
2215
2181
 
2182
+ // ../producer/src/services/render/perfSummary.ts
2183
+ function worstSubTimelineWaitOutcome(perfs) {
2184
+ const outcomes = perfs.map((p) => p.subTimelineWaitOutcome).filter((o) => !!o);
2185
+ if (outcomes.length === 0) return void 0;
2186
+ if (outcomes.includes("script_failure")) return "script_failure";
2187
+ if (outcomes.includes("timeout")) return "timeout";
2188
+ return "ready";
2189
+ }
2190
+ function pushWorkerDedupPerfs(results, sink) {
2191
+ for (const r of results) {
2192
+ if (r.perf) sink.push(r.perf);
2193
+ }
2194
+ }
2195
+ function pushWorkerPageErrors(results, sink) {
2196
+ for (const result of results) {
2197
+ for (const line of result.pageErrorLines ?? []) if (!sink.includes(line)) sink.push(line);
2198
+ }
2199
+ }
2200
+ function withWorkerPageErrors(consoleLines, workerLines) {
2201
+ return [...consoleLines, ...workerLines.filter((line) => !consoleLines.includes(line))];
2202
+ }
2203
+ function roundDb(value) {
2204
+ return value === void 0 ? void 0 : Math.round(Math.min(value, 999) * 10) / 10;
2205
+ }
2206
+ function aggregateDrawElement(perfs, de) {
2207
+ if (perfs.length === 0) return void 0;
2208
+ const modes = [...new Set(perfs.map((p) => p.captureMode).filter(Boolean))].sort();
2209
+ const gateReasons = [
2210
+ ...new Set(
2211
+ [de.probeGateReason, ...perfs.map((p) => p.deGateReason)].filter((r) => !!r)
2212
+ )
2213
+ ].sort();
2214
+ const gpuRenderers = [
2215
+ ...new Set(perfs.map((p) => p.gpuRenderer).filter((r) => !!r))
2216
+ ].sort();
2217
+ const drain = de.drainStats;
2218
+ return {
2219
+ mode: modes.join("|") || "unknown",
2220
+ compileGate: de.compileGate,
2221
+ clampReason: de.clampReason,
2222
+ workerInversion: de.workerInversion ?? "none",
2223
+ preInversionWorkers: de.preInversionWorkers,
2224
+ compositionElementCount: de.compositionElementCount,
2225
+ compositionElementCountSource: de.compositionElementCountSource,
2226
+ compositionElementTags: de.compositionElementTags,
2227
+ arollVideoCount: de.arollVideoCount,
2228
+ heygenVideoCount: de.heygenVideoCount,
2229
+ adaptersUsed: de.adaptersUsed,
2230
+ audioCount: de.audioCount,
2231
+ imageCount: de.imageCount,
2232
+ subCompositionCount: de.subCompositionCount,
2233
+ audioGroupCount: de.audioGroupCount,
2234
+ colorGradingCount: de.colorGradingCount,
2235
+ hasLut: de.hasLut,
2236
+ rootBodyMismatch: de.rootBodyMismatch,
2237
+ rootBodyDeltaPxBucket: de.rootBodyDeltaPxBucket,
2238
+ vfxHostCount: de.vfxHostCount,
2239
+ vfxCapture: de.vfxCapture,
2240
+ vfxTypes: de.vfxTypes,
2241
+ shortBand: de.shortBand,
2242
+ parallelRouter: de.parallelRouter ?? "none",
2243
+ preRouterWorkers: de.preRouterWorkers,
2244
+ gateReason: gateReasons.length > 0 ? gateReasons.join("|") : void 0,
2245
+ gpuRenderer: gpuRenderers.length > 0 ? gpuRenderers.join("|") : void 0,
2246
+ workerEncode: perfs.some((p) => p.deWorkerEncode),
2247
+ verifyArmed: perfs.reduce((sum2, p) => sum2 + (p.deVerifyArmed ?? 0), 0),
2248
+ verifyChecked: drain?.verifyChecked ?? 0,
2249
+ verifyMinDb: roundDb(drain?.verifyMinDb),
2250
+ verifyInitMs: perfs.reduce((sum2, p) => sum2 + (p.deVerifyInitMs ?? 0), 0),
2251
+ selfVerifyFallback: de.selfVerifyFallback,
2252
+ fallbackReason: de.fallbackReason,
2253
+ fallbackFailedDb: roundDb(de.fallbackFailedDb),
2254
+ fallbackFrameIndex: de.fallbackFrameIndex,
2255
+ fallbackThresholdDb: roundDb(de.fallbackThresholdDb),
2256
+ blankSuspects: drain?.blankSuspects ?? 0,
2257
+ blankDeterministicAccepts: drain?.blankDeterministicAccepts ?? 0,
2258
+ blankRecaptures: drain?.blankRecaptures ?? 0,
2259
+ boundaryFrames: perfs.reduce((sum2, p) => sum2 + (p.deBoundaryFrames ?? 0), 0),
2260
+ ncprFallbacks: perfs.reduce((sum2, p) => sum2 + (p.deNcprFallbacks ?? 0), 0),
2261
+ frameTimeouts: perfs.reduce((sum2, p) => sum2 + (p.deFrameTimeouts ?? 0), 0)
2262
+ };
2263
+ }
2264
+ function maxDefined(values) {
2265
+ const present = values.filter((v) => typeof v === "number");
2266
+ return present.length > 0 ? Math.max(...present) : void 0;
2267
+ }
2268
+ function aggregateChromeMemory(perfs) {
2269
+ const sampled = perfs.filter((p) => (p.chromeMemorySamples ?? 0) > 0);
2270
+ if (sampled.length === 0) return void 0;
2271
+ return {
2272
+ browserRssPeakMb: maxDefined(sampled.map((p) => p.chromeBrowserRssPeakMb)),
2273
+ rendererRssPeakMb: maxDefined(sampled.map((p) => p.chromeRendererRssPeakMb)),
2274
+ // Last samples are per session; summing approximates the whole fleet's
2275
+ // footprint at the end of capture (workers run concurrently).
2276
+ rssLastMb: sampled.reduce((sum2, p) => sum2 + (p.chromeRssLastMb ?? 0), 0),
2277
+ gpuProcessSeenLastSample: sampled.some((p) => p.chromeGpuProcessSeenLastSample === true),
2278
+ samples: sampled.reduce((sum2, p) => sum2 + (p.chromeMemorySamples ?? 0), 0)
2279
+ };
2280
+ }
2281
+ function aggregateDedup(perfs) {
2282
+ if (perfs.length === 0) return void 0;
2283
+ const armed = perfs.some((p) => p.staticDedupArmed);
2284
+ const skipReasons = armed ? [] : [
2285
+ ...new Set(perfs.map((p) => p.staticDedupSkipReason).filter((r) => !!r))
2286
+ ].sort();
2287
+ const verificationPerfs = perfs.filter((perf) => perf.staticDedupVerificationOutcome);
2288
+ const verificationOutcomes = [
2289
+ ...new Set(
2290
+ verificationPerfs.map((perf) => perf.staticDedupVerificationOutcome).filter((outcome) => outcome != null)
2291
+ )
2292
+ ].sort();
2293
+ return {
2294
+ enabled: perfs.some((p) => p.staticDedupEnabled),
2295
+ armed,
2296
+ predictedFrames: perfs.reduce((sum2, p) => sum2 + (p.staticDedupPredicted ?? 0), 0),
2297
+ reusedFrames: perfs.reduce((sum2, p) => sum2 + (p.staticDedupReused ?? 0), 0),
2298
+ skipReason: skipReasons.length > 0 ? skipReasons.join("|") : void 0,
2299
+ ...verificationPerfs.length === 0 ? {} : {
2300
+ verifiedFrames: verificationPerfs.reduce(
2301
+ (sum2, perf) => sum2 + (perf.staticDedupVerified ?? 0),
2302
+ 0
2303
+ ),
2304
+ verificationOutcomes,
2305
+ plannedRuns: verificationPerfs.reduce(
2306
+ (sum2, perf) => sum2 + (perf.staticDedupVerificationPlannedRuns ?? 0),
2307
+ 0
2308
+ ),
2309
+ completedRuns: verificationPerfs.reduce(
2310
+ (sum2, perf) => sum2 + (perf.staticDedupVerificationCompletedRuns ?? 0),
2311
+ 0
2312
+ ),
2313
+ screenshots: verificationPerfs.reduce(
2314
+ (sum2, perf) => sum2 + (perf.staticDedupVerificationScreenshots ?? 0),
2315
+ 0
2316
+ ),
2317
+ seeks: verificationPerfs.reduce(
2318
+ (sum2, perf) => sum2 + (perf.staticDedupVerificationSeeks ?? 0),
2319
+ 0
2320
+ ),
2321
+ comparisons: verificationPerfs.reduce(
2322
+ (sum2, perf) => sum2 + (perf.staticDedupVerificationComparisons ?? 0),
2323
+ 0
2324
+ ),
2325
+ verificationElapsedMs: verificationPerfs.reduce(
2326
+ (sum2, perf) => sum2 + (perf.staticDedupVerificationElapsedMs ?? 0),
2327
+ 0
2328
+ )
2329
+ }
2330
+ };
2331
+ }
2332
+ function aggregateBeginFrameReuse(perfs) {
2333
+ const noDamageFrames = perfs.reduce((sum2, p) => sum2 + (p.beginFrameNoDamage ?? 0), 0);
2334
+ const hasDamageFrames = perfs.reduce((sum2, p) => sum2 + (p.beginFrameHasDamage ?? 0), 0);
2335
+ if (noDamageFrames + hasDamageFrames === 0) return void 0;
2336
+ return { noDamageFrames, hasDamageFrames };
2337
+ }
2338
+ function buildRenderPerfSummary(input) {
2339
+ return {
2340
+ renderId: input.job.id,
2341
+ totalElapsedMs: input.totalElapsedMs,
2342
+ // RenderPerfSummary surfaces fps as a decimal because it lands in JSON
2343
+ // payloads (CLI telemetry, regression-harness reports) where a single
2344
+ // number is friendlier than `{num,den}`. Callers needing the rational
2345
+ // back can read `job.config.fps`.
2346
+ fps: fpsToNumber(input.job.config.fps),
2347
+ quality: input.job.config.quality,
2348
+ workers: input.workerCount,
2349
+ workerSizing: input.workerSizing,
2350
+ chunkedEncode: input.enableChunkedEncode,
2351
+ chunkSizeFrames: input.enableChunkedEncode ? input.chunkedEncodeSize : null,
2352
+ compositionDurationSeconds: input.compositionDurationSeconds,
2353
+ totalFrames: input.totalFrames,
2354
+ resolution: { width: input.outputWidth, height: input.outputHeight },
2355
+ videoCount: input.videoCount,
2356
+ audioCount: input.audioCount,
2357
+ stages: input.perfStages,
2358
+ videoExtractBreakdown: input.videoExtractBreakdown,
2359
+ tmpPeakBytes: input.tmpPeakBytes,
2360
+ captureCalibration: input.captureCalibration ? {
2361
+ sampledFrames: input.captureCalibration.samples.map((sample) => sample.frameIndex),
2362
+ p95Ms: input.captureCalibration.estimate.p95Ms,
2363
+ multiplier: input.captureCalibration.estimate.multiplier,
2364
+ reasons: input.captureCalibration.estimate.reasons
2365
+ } : void 0,
2366
+ captureAttempts: input.captureAttempts.length > 0 ? input.captureAttempts : void 0,
2367
+ hdrDiagnostics: input.hdrDiagnostics.videoExtractionFailures > 0 || input.hdrDiagnostics.imageDecodeFailures > 0 ? { ...input.hdrDiagnostics } : void 0,
2368
+ hdrPerf: input.hdrPerf ? finalizeHdrPerf(input.hdrPerf) : void 0,
2369
+ observability: input.observability,
2370
+ captureAvgMs: input.totalFrames > 0 ? Math.round(
2371
+ (input.perfStages.captureFrameMs ?? input.perfStages.captureMs ?? 0) / input.totalFrames
2372
+ ) : void 0,
2373
+ subTimelineWait: worstSubTimelineWaitOutcome(input.dedupPerfs),
2374
+ captureP50Ms: (() => {
2375
+ const withSamples = input.dedupPerfs.filter((p) => (p.p50TotalMs ?? 0) > 0);
2376
+ if (withSamples.length === 0) return void 0;
2377
+ return withSamples.reduce((a, b) => b.frames > a.frames ? b : a).p50TotalMs;
2378
+ })(),
2379
+ peakRssMb: Math.round(input.peakRssBytes / (1024 * 1024)),
2380
+ peakHeapUsedMb: Math.round(input.peakHeapUsedBytes / (1024 * 1024)),
2381
+ staticDedup: aggregateDedup(input.dedupPerfs),
2382
+ chromeMemory: aggregateChromeMemory(input.dedupPerfs),
2383
+ beginFrameReuse: aggregateBeginFrameReuse(input.dedupPerfs),
2384
+ drawElement: aggregateDrawElement(
2385
+ input.dedupPerfs,
2386
+ input.drawElement ?? { selfVerifyFallback: false }
2387
+ ),
2388
+ host: {
2389
+ platform: platform(),
2390
+ arch: arch(),
2391
+ cpuCount: cpus().length,
2392
+ totalMemMb: Math.round(totalmem() / (1024 * 1024)),
2393
+ nodeVersion: process.version,
2394
+ gpuDisabled: input.gpuDisabled
2395
+ }
2396
+ };
2397
+ }
2398
+
2399
+ // ../producer/src/services/render/captureStageError.ts
2400
+ var CaptureStageError = class extends CaptureFailure {
2401
+ browserConsole;
2402
+ constructor(input) {
2403
+ const classified = classifyCaptureFailure(input.cause);
2404
+ super({
2405
+ kind: classified.kind,
2406
+ message: normalizeErrorMessage(input.cause),
2407
+ cause: input.cause,
2408
+ workerDiagnostics: classified.workerDiagnostics,
2409
+ pageErrorLines: classified.pageErrorLines
2410
+ });
2411
+ this.name = "CaptureStageError";
2412
+ this.browserConsole = withWorkerPageErrors(input.browserConsole, [
2413
+ ...classified.pageErrorLines
2414
+ ]);
2415
+ if (input.cause instanceof Error && input.cause.stack) {
2416
+ this.stack = input.cause.stack;
2417
+ }
2418
+ }
2419
+ };
2420
+ function wrapCaptureStageError(error, browserConsole) {
2421
+ if (error instanceof CaptureStageError || error instanceof EncoderInterruptedError) return error;
2422
+ return new CaptureStageError({ cause: error, browserConsole });
2423
+ }
2424
+ function getCaptureStageBrowserConsole(error) {
2425
+ if (error instanceof CaptureStageError) return error.browserConsole;
2426
+ if (error instanceof CaptureFailure) return [...error.pageErrorLines];
2427
+ return [];
2428
+ }
2429
+
2216
2430
  // ../producer/src/services/hdrCompositor.ts
2431
+ import { readSync as readSync2, closeSync as closeSync3 } from "fs";
2432
+ import { join as join6 } from "path";
2217
2433
  function countNonZeroAlpha(rgba) {
2218
2434
  let n = 0;
2219
2435
  for (let p = 3; p < rgba.length; p += 4) {
@@ -3250,307 +3466,98 @@ function ensureFrameWritten(frameWritten, frameIndex, encoder) {
3250
3466
  const reason = encoder?.getExitError();
3251
3467
  const base = `Streaming encoder exited before frame ${frameIndex} was written`;
3252
3468
  throw encoderFailureError(base, {
3253
- error: reason,
3254
- failureReason: encoder?.getExitFailureReason?.()
3255
- });
3256
- }
3257
- function cleanupEndedHdrVideos(args) {
3258
- if (process.env.KEEP_TEMP === "1") return;
3259
- const {
3260
- time,
3261
- activeTransition,
3262
- hdrVideoEndTimes,
3263
- cleanedUpVideos,
3264
- hdrVideoFrameSources,
3265
- sceneElements,
3266
- log
3267
- } = args;
3268
- for (const [videoId, endTime] of hdrVideoEndTimes) {
3269
- if (time > endTime && !cleanedUpVideos.has(videoId)) {
3270
- const stillNeeded = activeTransition && (sceneElements[activeTransition.fromScene]?.includes(videoId) || sceneElements[activeTransition.toScene]?.includes(videoId));
3271
- if (!stillNeeded) {
3272
- const frameSource = hdrVideoFrameSources.get(videoId);
3273
- if (frameSource) {
3274
- cleanupHdrVideoFrameSource(frameSource, log);
3275
- hdrVideoFrameSources.delete(videoId);
3276
- }
3277
- cleanedUpVideos.add(videoId);
3278
- }
3279
- }
3280
- }
3281
- }
3282
-
3283
- // ../producer/src/services/render/segmentPlan.ts
3284
- var DEFAULT_SEGMENT_FRAMES = 3e3;
3285
- var MIN_SEGMENT_FRAMES = 30;
3286
- function assertPositiveInteger(name, value) {
3287
- if (!Number.isInteger(value) || value <= 0) {
3288
- throw new Error(`[segmentPlan] ${name} must be a positive integer (got ${String(value)})`);
3289
- }
3290
- }
3291
- function planSegments(totalFrames, segmentFrames) {
3292
- assertPositiveInteger("totalFrames", totalFrames);
3293
- assertPositiveInteger("segmentFrames", segmentFrames);
3294
- const slices = [];
3295
- for (let start = 0, index = 0; start < totalFrames; start += segmentFrames, index += 1) {
3296
- slices.push({
3297
- index,
3298
- startFrame: start,
3299
- endFrame: Math.min(totalFrames, start + segmentFrames)
3300
- });
3301
- }
3302
- return slices;
3303
- }
3304
- function resolveSegmentFrames(env) {
3305
- const raw = env.HF_SEGMENT_FRAMES;
3306
- if (raw === void 0 || raw.trim() === "") return DEFAULT_SEGMENT_FRAMES;
3307
- const parsed = Number(raw);
3308
- if (!Number.isInteger(parsed)) return DEFAULT_SEGMENT_FRAMES;
3309
- return Math.max(MIN_SEGMENT_FRAMES, parsed);
3310
- }
3311
-
3312
- // ../producer/src/services/render/segmentQueue.ts
3313
- function createSegmentQueue(slices) {
3314
- let cursor = 0;
3315
- return {
3316
- next: () => slices[cursor++],
3317
- remaining: () => Math.max(0, slices.length - cursor)
3318
- };
3319
- }
3320
-
3321
- // ../producer/src/services/render/segmentRecycle.ts
3322
- var DEFAULT_SEGMENT_BROWSER_RECYCLE = 3;
3323
- function resolveSegmentBrowserRecycle(env) {
3324
- const raw = env.HF_SEGMENT_BROWSER_RECYCLE;
3325
- if (raw === void 0 || raw.trim() === "") return DEFAULT_SEGMENT_BROWSER_RECYCLE;
3326
- const parsed = Number(raw);
3327
- return Number.isInteger(parsed) && parsed >= 0 ? parsed : DEFAULT_SEGMENT_BROWSER_RECYCLE;
3328
- }
3329
- var TARGET_LOSS_PATTERNS = [/target closed/i, /detached frame/i, /session closed/i];
3330
- function isTargetLossError(error) {
3331
- if (!(error instanceof Error)) return false;
3332
- return TARGET_LOSS_PATTERNS.some((re) => re.test(error.message));
3333
- }
3334
-
3335
- // ../producer/src/services/render/stages/captureStreamingStage.ts
3336
- import { mkdtemp, writeFile } from "fs/promises";
3337
- import { tmpdir } from "os";
3338
- import { join as join8 } from "path";
3339
-
3340
- // ../producer/src/services/render/perfSummary.ts
3341
- import { arch, cpus, platform, totalmem } from "os";
3342
- function worstSubTimelineWaitOutcome(perfs) {
3343
- const outcomes = perfs.map((p) => p.subTimelineWaitOutcome).filter((o) => !!o);
3344
- if (outcomes.length === 0) return void 0;
3345
- if (outcomes.includes("script_failure")) return "script_failure";
3346
- if (outcomes.includes("timeout")) return "timeout";
3347
- return "ready";
3348
- }
3349
- function pushWorkerDedupPerfs(results, sink) {
3350
- for (const r of results) {
3351
- if (r.perf) sink.push(r.perf);
3352
- }
3353
- }
3354
- function roundDb(value) {
3355
- return value === void 0 ? void 0 : Math.round(Math.min(value, 999) * 10) / 10;
3356
- }
3357
- function aggregateDrawElement(perfs, de) {
3358
- if (perfs.length === 0) return void 0;
3359
- const modes = [...new Set(perfs.map((p) => p.captureMode).filter(Boolean))].sort();
3360
- const gateReasons = [
3361
- ...new Set(
3362
- [de.probeGateReason, ...perfs.map((p) => p.deGateReason)].filter((r) => !!r)
3363
- )
3364
- ].sort();
3365
- const gpuRenderers = [
3366
- ...new Set(perfs.map((p) => p.gpuRenderer).filter((r) => !!r))
3367
- ].sort();
3368
- const drain = de.drainStats;
3369
- return {
3370
- mode: modes.join("|") || "unknown",
3371
- compileGate: de.compileGate,
3372
- clampReason: de.clampReason,
3373
- workerInversion: de.workerInversion ?? "none",
3374
- preInversionWorkers: de.preInversionWorkers,
3375
- compositionElementCount: de.compositionElementCount,
3376
- compositionElementCountSource: de.compositionElementCountSource,
3377
- compositionElementTags: de.compositionElementTags,
3378
- arollVideoCount: de.arollVideoCount,
3379
- heygenVideoCount: de.heygenVideoCount,
3380
- adaptersUsed: de.adaptersUsed,
3381
- audioCount: de.audioCount,
3382
- imageCount: de.imageCount,
3383
- subCompositionCount: de.subCompositionCount,
3384
- audioGroupCount: de.audioGroupCount,
3385
- colorGradingCount: de.colorGradingCount,
3386
- hasLut: de.hasLut,
3387
- rootBodyMismatch: de.rootBodyMismatch,
3388
- rootBodyDeltaPxBucket: de.rootBodyDeltaPxBucket,
3389
- vfxHostCount: de.vfxHostCount,
3390
- vfxCapture: de.vfxCapture,
3391
- vfxTypes: de.vfxTypes,
3392
- shortBand: de.shortBand,
3393
- parallelRouter: de.parallelRouter ?? "none",
3394
- preRouterWorkers: de.preRouterWorkers,
3395
- gateReason: gateReasons.length > 0 ? gateReasons.join("|") : void 0,
3396
- gpuRenderer: gpuRenderers.length > 0 ? gpuRenderers.join("|") : void 0,
3397
- workerEncode: perfs.some((p) => p.deWorkerEncode),
3398
- verifyArmed: perfs.reduce((sum2, p) => sum2 + (p.deVerifyArmed ?? 0), 0),
3399
- verifyChecked: drain?.verifyChecked ?? 0,
3400
- verifyMinDb: roundDb(drain?.verifyMinDb),
3401
- verifyInitMs: perfs.reduce((sum2, p) => sum2 + (p.deVerifyInitMs ?? 0), 0),
3402
- selfVerifyFallback: de.selfVerifyFallback,
3403
- fallbackReason: de.fallbackReason,
3404
- fallbackFailedDb: roundDb(de.fallbackFailedDb),
3405
- fallbackFrameIndex: de.fallbackFrameIndex,
3406
- fallbackThresholdDb: roundDb(de.fallbackThresholdDb),
3407
- blankSuspects: drain?.blankSuspects ?? 0,
3408
- blankDeterministicAccepts: drain?.blankDeterministicAccepts ?? 0,
3409
- blankRecaptures: drain?.blankRecaptures ?? 0,
3410
- boundaryFrames: perfs.reduce((sum2, p) => sum2 + (p.deBoundaryFrames ?? 0), 0),
3411
- ncprFallbacks: perfs.reduce((sum2, p) => sum2 + (p.deNcprFallbacks ?? 0), 0),
3412
- frameTimeouts: perfs.reduce((sum2, p) => sum2 + (p.deFrameTimeouts ?? 0), 0)
3413
- };
3414
- }
3415
- function maxDefined(values) {
3416
- const present = values.filter((v) => typeof v === "number");
3417
- return present.length > 0 ? Math.max(...present) : void 0;
3418
- }
3419
- function aggregateChromeMemory(perfs) {
3420
- const sampled = perfs.filter((p) => (p.chromeMemorySamples ?? 0) > 0);
3421
- if (sampled.length === 0) return void 0;
3422
- return {
3423
- browserRssPeakMb: maxDefined(sampled.map((p) => p.chromeBrowserRssPeakMb)),
3424
- rendererRssPeakMb: maxDefined(sampled.map((p) => p.chromeRendererRssPeakMb)),
3425
- // Last samples are per session; summing approximates the whole fleet's
3426
- // footprint at the end of capture (workers run concurrently).
3427
- rssLastMb: sampled.reduce((sum2, p) => sum2 + (p.chromeRssLastMb ?? 0), 0),
3428
- gpuProcessSeenLastSample: sampled.some((p) => p.chromeGpuProcessSeenLastSample === true),
3429
- samples: sampled.reduce((sum2, p) => sum2 + (p.chromeMemorySamples ?? 0), 0)
3430
- };
3431
- }
3432
- function aggregateDedup(perfs) {
3433
- if (perfs.length === 0) return void 0;
3434
- const armed = perfs.some((p) => p.staticDedupArmed);
3435
- const skipReasons = armed ? [] : [
3436
- ...new Set(perfs.map((p) => p.staticDedupSkipReason).filter((r) => !!r))
3437
- ].sort();
3438
- const verificationPerfs = perfs.filter((perf) => perf.staticDedupVerificationOutcome);
3439
- const verificationOutcomes = [
3440
- ...new Set(
3441
- verificationPerfs.map((perf) => perf.staticDedupVerificationOutcome).filter((outcome) => outcome != null)
3442
- )
3443
- ].sort();
3444
- return {
3445
- enabled: perfs.some((p) => p.staticDedupEnabled),
3446
- armed,
3447
- predictedFrames: perfs.reduce((sum2, p) => sum2 + (p.staticDedupPredicted ?? 0), 0),
3448
- reusedFrames: perfs.reduce((sum2, p) => sum2 + (p.staticDedupReused ?? 0), 0),
3449
- skipReason: skipReasons.length > 0 ? skipReasons.join("|") : void 0,
3450
- ...verificationPerfs.length === 0 ? {} : {
3451
- verifiedFrames: verificationPerfs.reduce(
3452
- (sum2, perf) => sum2 + (perf.staticDedupVerified ?? 0),
3453
- 0
3454
- ),
3455
- verificationOutcomes,
3456
- plannedRuns: verificationPerfs.reduce(
3457
- (sum2, perf) => sum2 + (perf.staticDedupVerificationPlannedRuns ?? 0),
3458
- 0
3459
- ),
3460
- completedRuns: verificationPerfs.reduce(
3461
- (sum2, perf) => sum2 + (perf.staticDedupVerificationCompletedRuns ?? 0),
3462
- 0
3463
- ),
3464
- screenshots: verificationPerfs.reduce(
3465
- (sum2, perf) => sum2 + (perf.staticDedupVerificationScreenshots ?? 0),
3466
- 0
3467
- ),
3468
- seeks: verificationPerfs.reduce(
3469
- (sum2, perf) => sum2 + (perf.staticDedupVerificationSeeks ?? 0),
3470
- 0
3471
- ),
3472
- comparisons: verificationPerfs.reduce(
3473
- (sum2, perf) => sum2 + (perf.staticDedupVerificationComparisons ?? 0),
3474
- 0
3475
- ),
3476
- verificationElapsedMs: verificationPerfs.reduce(
3477
- (sum2, perf) => sum2 + (perf.staticDedupVerificationElapsedMs ?? 0),
3478
- 0
3479
- )
3469
+ error: reason,
3470
+ failureReason: encoder?.getExitFailureReason?.()
3471
+ });
3472
+ }
3473
+ function cleanupEndedHdrVideos(args) {
3474
+ if (process.env.KEEP_TEMP === "1") return;
3475
+ const {
3476
+ time,
3477
+ activeTransition,
3478
+ hdrVideoEndTimes,
3479
+ cleanedUpVideos,
3480
+ hdrVideoFrameSources,
3481
+ sceneElements,
3482
+ log
3483
+ } = args;
3484
+ for (const [videoId, endTime] of hdrVideoEndTimes) {
3485
+ if (time > endTime && !cleanedUpVideos.has(videoId)) {
3486
+ const stillNeeded = activeTransition && (sceneElements[activeTransition.fromScene]?.includes(videoId) || sceneElements[activeTransition.toScene]?.includes(videoId));
3487
+ if (!stillNeeded) {
3488
+ const frameSource = hdrVideoFrameSources.get(videoId);
3489
+ if (frameSource) {
3490
+ cleanupHdrVideoFrameSource(frameSource, log);
3491
+ hdrVideoFrameSources.delete(videoId);
3492
+ }
3493
+ cleanedUpVideos.add(videoId);
3494
+ }
3480
3495
  }
3481
- };
3496
+ }
3482
3497
  }
3483
- function aggregateBeginFrameReuse(perfs) {
3484
- const noDamageFrames = perfs.reduce((sum2, p) => sum2 + (p.beginFrameNoDamage ?? 0), 0);
3485
- const hasDamageFrames = perfs.reduce((sum2, p) => sum2 + (p.beginFrameHasDamage ?? 0), 0);
3486
- if (noDamageFrames + hasDamageFrames === 0) return void 0;
3487
- return { noDamageFrames, hasDamageFrames };
3498
+
3499
+ // ../producer/src/services/render/segmentPlan.ts
3500
+ var DEFAULT_SEGMENT_FRAMES = 3e3;
3501
+ var MIN_SEGMENT_FRAMES = 30;
3502
+ function assertPositiveInteger(name, value) {
3503
+ if (!Number.isInteger(value) || value <= 0) {
3504
+ throw new Error(`[segmentPlan] ${name} must be a positive integer (got ${String(value)})`);
3505
+ }
3488
3506
  }
3489
- function buildRenderPerfSummary(input) {
3507
+ function planSegments(totalFrames, segmentFrames) {
3508
+ assertPositiveInteger("totalFrames", totalFrames);
3509
+ assertPositiveInteger("segmentFrames", segmentFrames);
3510
+ const slices = [];
3511
+ for (let start = 0, index = 0; start < totalFrames; start += segmentFrames, index += 1) {
3512
+ slices.push({
3513
+ index,
3514
+ startFrame: start,
3515
+ endFrame: Math.min(totalFrames, start + segmentFrames)
3516
+ });
3517
+ }
3518
+ return slices;
3519
+ }
3520
+ function resolveSegmentFrames(env) {
3521
+ const raw = env.HF_SEGMENT_FRAMES;
3522
+ if (raw === void 0 || raw.trim() === "") return DEFAULT_SEGMENT_FRAMES;
3523
+ const parsed = Number(raw);
3524
+ if (!Number.isInteger(parsed)) return DEFAULT_SEGMENT_FRAMES;
3525
+ return Math.max(MIN_SEGMENT_FRAMES, parsed);
3526
+ }
3527
+
3528
+ // ../producer/src/services/render/segmentQueue.ts
3529
+ function createSegmentQueue(slices) {
3530
+ let cursor = 0;
3490
3531
  return {
3491
- renderId: input.job.id,
3492
- totalElapsedMs: input.totalElapsedMs,
3493
- // RenderPerfSummary surfaces fps as a decimal because it lands in JSON
3494
- // payloads (CLI telemetry, regression-harness reports) where a single
3495
- // number is friendlier than `{num,den}`. Callers needing the rational
3496
- // back can read `job.config.fps`.
3497
- fps: fpsToNumber(input.job.config.fps),
3498
- quality: input.job.config.quality,
3499
- workers: input.workerCount,
3500
- workerSizing: input.workerSizing,
3501
- chunkedEncode: input.enableChunkedEncode,
3502
- chunkSizeFrames: input.enableChunkedEncode ? input.chunkedEncodeSize : null,
3503
- compositionDurationSeconds: input.compositionDurationSeconds,
3504
- totalFrames: input.totalFrames,
3505
- resolution: { width: input.outputWidth, height: input.outputHeight },
3506
- videoCount: input.videoCount,
3507
- audioCount: input.audioCount,
3508
- stages: input.perfStages,
3509
- videoExtractBreakdown: input.videoExtractBreakdown,
3510
- tmpPeakBytes: input.tmpPeakBytes,
3511
- captureCalibration: input.captureCalibration ? {
3512
- sampledFrames: input.captureCalibration.samples.map((sample) => sample.frameIndex),
3513
- p95Ms: input.captureCalibration.estimate.p95Ms,
3514
- multiplier: input.captureCalibration.estimate.multiplier,
3515
- reasons: input.captureCalibration.estimate.reasons
3516
- } : void 0,
3517
- captureAttempts: input.captureAttempts.length > 0 ? input.captureAttempts : void 0,
3518
- hdrDiagnostics: input.hdrDiagnostics.videoExtractionFailures > 0 || input.hdrDiagnostics.imageDecodeFailures > 0 ? { ...input.hdrDiagnostics } : void 0,
3519
- hdrPerf: input.hdrPerf ? finalizeHdrPerf(input.hdrPerf) : void 0,
3520
- observability: input.observability,
3521
- captureAvgMs: input.totalFrames > 0 ? Math.round(
3522
- (input.perfStages.captureFrameMs ?? input.perfStages.captureMs ?? 0) / input.totalFrames
3523
- ) : void 0,
3524
- subTimelineWait: worstSubTimelineWaitOutcome(input.dedupPerfs),
3525
- captureP50Ms: (() => {
3526
- const withSamples = input.dedupPerfs.filter((p) => (p.p50TotalMs ?? 0) > 0);
3527
- if (withSamples.length === 0) return void 0;
3528
- return withSamples.reduce((a, b) => b.frames > a.frames ? b : a).p50TotalMs;
3529
- })(),
3530
- peakRssMb: Math.round(input.peakRssBytes / (1024 * 1024)),
3531
- peakHeapUsedMb: Math.round(input.peakHeapUsedBytes / (1024 * 1024)),
3532
- staticDedup: aggregateDedup(input.dedupPerfs),
3533
- chromeMemory: aggregateChromeMemory(input.dedupPerfs),
3534
- beginFrameReuse: aggregateBeginFrameReuse(input.dedupPerfs),
3535
- drawElement: aggregateDrawElement(
3536
- input.dedupPerfs,
3537
- input.drawElement ?? { selfVerifyFallback: false }
3538
- ),
3539
- host: {
3540
- platform: platform(),
3541
- arch: arch(),
3542
- cpuCount: cpus().length,
3543
- totalMemMb: Math.round(totalmem() / (1024 * 1024)),
3544
- nodeVersion: process.version,
3545
- gpuDisabled: input.gpuDisabled
3546
- }
3532
+ next: () => slices[cursor++],
3533
+ remaining: () => Math.max(0, slices.length - cursor)
3547
3534
  };
3548
3535
  }
3549
3536
 
3537
+ // ../producer/src/services/render/segmentRecycle.ts
3538
+ var DEFAULT_SEGMENT_BROWSER_RECYCLE = 3;
3539
+ function resolveSegmentBrowserRecycle(env) {
3540
+ const raw = env.HF_SEGMENT_BROWSER_RECYCLE;
3541
+ if (raw === void 0 || raw.trim() === "") return DEFAULT_SEGMENT_BROWSER_RECYCLE;
3542
+ const parsed = Number(raw);
3543
+ return Number.isInteger(parsed) && parsed >= 0 ? parsed : DEFAULT_SEGMENT_BROWSER_RECYCLE;
3544
+ }
3545
+ var TARGET_LOSS_PATTERNS = [/target closed/i, /detached frame/i, /session closed/i];
3546
+ function isTargetLossError(error) {
3547
+ if (!(error instanceof Error)) return false;
3548
+ return TARGET_LOSS_PATTERNS.some((re) => re.test(error.message));
3549
+ }
3550
+
3550
3551
  // ../producer/src/services/render/stages/captureStreamingStage.ts
3552
+ import { mkdtemp, writeFile } from "fs/promises";
3553
+ import { tmpdir } from "os";
3554
+ import { join as join8 } from "path";
3551
3555
  var DEFAULT_CAPTURE_STALL_MS = 6e4;
3552
3556
  var DE_STALL_POLL_MS = 5e3;
3553
3557
  var STALL_ADVICE = "Chrome stopped answering. If another app is keeping the GPU or CPU busy (a 3D render, a game, another export), let it finish or render one job at a time, then retry.";
3558
+ function poolFailure(error, probeSession) {
3559
+ return wrapCaptureStageError(error, probeSession?.browserConsoleBuffer ?? []);
3560
+ }
3554
3561
  var ParallelCaptureStallError = class extends Error {
3555
3562
  variant;
3556
3563
  constructor(args) {
@@ -3997,7 +4004,7 @@ async function runCaptureStreamingStage(input) {
3997
4004
  }
3998
4005
  );
3999
4006
  } catch (err) {
4000
- if (parallelDrainError) throw parallelDrainError;
4007
+ if (parallelDrainError) throw poolFailure(parallelDrainError, probeSession);
4001
4008
  if (stalled && abortSignal?.aborted !== true) {
4002
4009
  throw new ParallelCaptureStallError({
4003
4010
  variant: "pool",
@@ -4008,13 +4015,15 @@ async function runCaptureStreamingStage(input) {
4008
4015
  phaseSummary: phaseSummary()
4009
4016
  });
4010
4017
  }
4011
- throw err;
4018
+ throw poolFailure(err, probeSession);
4012
4019
  } finally {
4013
4020
  clearInterval(stallTimer);
4014
4021
  abortSignal?.removeEventListener("abort", forwardParentAbort);
4015
4022
  }
4016
- if (parallelDrainError) throw parallelDrainError;
4023
+ if (parallelDrainError) throw poolFailure(parallelDrainError, probeSession);
4017
4024
  pushWorkerDedupPerfs(workerResults, dedupPerfs);
4025
+ const workerPageErrors = [];
4026
+ pushWorkerPageErrors(workerResults, workerPageErrors);
4018
4027
  if (parallelGuardRan) {
4019
4028
  deDrainStats = parallelStats;
4020
4029
  }
@@ -4024,6 +4033,7 @@ async function runCaptureStreamingStage(input) {
4024
4033
  await closeCaptureSession(probeSession);
4025
4034
  probeSession = null;
4026
4035
  }
4036
+ lastBrowserConsole = withWorkerPageErrors(lastBrowserConsole, workerPageErrors);
4027
4037
  } else {
4028
4038
  const videoInjector = createRenderVideoFrameInjector();
4029
4039
  const session = probeSession ?? await createCaptureSession(
@@ -4470,7 +4480,7 @@ async function runCaptureSegmentedStage(input) {
4470
4480
 
4471
4481
  // ../producer/src/services/render/segmentManifest.ts
4472
4482
  import { createHash as createHash2 } from "crypto";
4473
- import { existsSync as existsSync7, mkdirSync as mkdirSync4, readFileSync as readFileSync4, renameSync as renameSync2, statSync as statSync3, writeFileSync as writeFileSync3 } from "fs";
4483
+ import { existsSync as existsSync7, mkdirSync as mkdirSync4, readFileSync as readFileSync4, statSync as statSync3, writeFileSync as writeFileSync3 } from "fs";
4474
4484
  import { join as join10 } from "path";
4475
4485
  var MANIFEST_FILENAME = "segments.json";
4476
4486
  function computeSegmentPlanHash(input) {
@@ -4527,7 +4537,7 @@ function writeSegmentManifest(segmentDir, manifest) {
4527
4537
  mkdirSync4(segmentDir, { recursive: true });
4528
4538
  const tmp = join10(segmentDir, `${MANIFEST_FILENAME}.${process.pid}.tmp`);
4529
4539
  writeFileSync3(tmp, JSON.stringify(manifest, null, 2), "utf-8");
4530
- renameSync2(tmp, join10(segmentDir, MANIFEST_FILENAME));
4540
+ renameWithRetry(tmp, join10(segmentDir, MANIFEST_FILENAME));
4531
4541
  }
4532
4542
  async function probeSegmentFrameCount(path, probe) {
4533
4543
  try {
@@ -6641,7 +6651,7 @@ async function readLocalFont(absPath) {
6641
6651
  return { kind: "inline", buffer: Buffer.concat(chunks, totalBytes) };
6642
6652
  }
6643
6653
  async function embedLocalFontFaces(html, projectDir) {
6644
- const { fontToDataUri: toDataUri } = await import("./deterministicFonts-EGAAE7QL.js");
6654
+ const { fontToDataUri: toDataUri } = await import("./deterministicFonts-RO2TCMLZ.js");
6645
6655
  const styleBlockRe = /<style\b[^>]*>([\s\S]*?)<\/style>/gi;
6646
6656
  const fontFaceRe = /@font-face\s*\{([^}]*)\}/gi;
6647
6657
  let result = html;
@@ -7728,6 +7738,10 @@ async function runProbeStage(input) {
7728
7738
  if (el.loop && !existing.loop) {
7729
7739
  existing.loop = true;
7730
7740
  }
7741
+ const audio = composition.audios.find(
7742
+ (audio2) => audio2.type === "video" && audio2.id === `${el.id}-audio`
7743
+ );
7744
+ if (audio) audio.loop = existing.loop;
7731
7745
  }
7732
7746
  } else if (!compiled.droppedMediaIds.has(el.id)) {
7733
7747
  composition.videos.push({
@@ -7765,6 +7779,7 @@ async function runProbeStage(input) {
7765
7779
  el,
7766
7780
  authoredStarts.get(el.id) ?? existing.mediaStart
7767
7781
  );
7782
+ existing.loop = el.loop;
7768
7783
  if (el.volume > 0 && Math.abs((existing.volume ?? 1) - el.volume) > BROWSER_MEDIA_EPSILON) {
7769
7784
  existing.volume = el.volume;
7770
7785
  }
@@ -7776,6 +7791,7 @@ async function runProbeStage(input) {
7776
7791
  start: el.start,
7777
7792
  end: resolveBrowserMediaEnd(el.start, el.end, el.duration),
7778
7793
  mediaStart: el.mediaStart,
7794
+ loop: el.loop,
7779
7795
  layer: 0,
7780
7796
  volume: el.volume,
7781
7797
  type: "audio"
@@ -8378,6 +8394,8 @@ function appendAutoDetectedVideoAudio(composition, extracted) {
8378
8394
  start: video.start,
8379
8395
  end: video.end,
8380
8396
  mediaStart: video.mediaStart,
8397
+ playbackRate: video.playbackRate,
8398
+ loop: video.loop,
8381
8399
  layer: 0,
8382
8400
  volume: 1,
8383
8401
  type: "video"
@@ -8392,7 +8410,7 @@ import { rmSync as rmSync7 } from "fs";
8392
8410
 
8393
8411
  // ../producer/src/services/render/audioPadTrim.ts
8394
8412
  import { spawn } from "child_process";
8395
- import { mkdtempSync as mkdtempSync3, renameSync as renameSync3, rmSync as rmSync6 } from "fs";
8413
+ import { mkdtempSync as mkdtempSync3, rmSync as rmSync6 } from "fs";
8396
8414
  import { dirname as dirname6, join as join16 } from "path";
8397
8415
 
8398
8416
  // ../producer/src/services/render/audioTruePeak.ts
@@ -8639,7 +8657,7 @@ async function enforceAacTruePeak(input) {
8639
8657
  }
8640
8658
  if (truePeakDbfs <= AAC_DELIVERY_TRUE_PEAK_DBFS) {
8641
8659
  if (measuredPath !== correctedPath) return { success: true };
8642
- renameSync3(correctedPath, input.audioPath);
8660
+ renameWithRetry(correctedPath, input.audioPath);
8643
8661
  return { success: true, loweredDb: Number((-attenuationDb).toFixed(2)) };
8644
8662
  }
8645
8663
  if (pass === MAX_TRUE_PEAK_CORRECTION_PASSES) break;
@@ -8829,6 +8847,7 @@ async function runAudioStage(input) {
8829
8847
  const result = await mixAudioForDelivery(input, duration, pcmSourcePath);
8830
8848
  let audioLoweredDb;
8831
8849
  if (result.hasAudio) {
8850
+ const guardStart = Date.now();
8832
8851
  const peak = await constrainAacTruePeak({
8833
8852
  audioPath: result.audioOutputPath,
8834
8853
  sourcePath: pcmSourcePath,
@@ -8838,6 +8857,7 @@ async function runAudioStage(input) {
8838
8857
  });
8839
8858
  if (!peak.success) throw encoderFailureError("Audio true-peak check failed", peak);
8840
8859
  audioLoweredDb = peak.loweredDb;
8860
+ input.log?.info("[audio] phases", { ...result.audioPhaseMs, guard: Date.now() - guardStart });
8841
8861
  }
8842
8862
  return { ...result, audioLoweredDb, audioProcessMs: Date.now() - stageStart };
8843
8863
  } finally {
@@ -8863,6 +8883,7 @@ async function mixAudioForDelivery(input, duration, pcmSourcePath) {
8863
8883
  let hasAudio = false;
8864
8884
  let audioError;
8865
8885
  let audioFailures;
8886
+ let audioPhaseMs;
8866
8887
  if (audios.length > 0) {
8867
8888
  let audioResult;
8868
8889
  try {
@@ -8912,6 +8933,7 @@ async function mixAudioForDelivery(input, duration, pcmSourcePath) {
8912
8933
  assertAudioNotInterrupted(audioResult.failures);
8913
8934
  hasAudio = audioResult.success;
8914
8935
  audioFailures = audioResult.failures;
8936
+ audioPhaseMs = audioResult.phaseMs;
8915
8937
  if (!hasAudio) {
8916
8938
  audioError = audioResult.error ?? "audio mix failed for an unknown reason";
8917
8939
  for (const failure of audioResult.failures ?? []) {
@@ -8930,7 +8952,8 @@ async function mixAudioForDelivery(input, duration, pcmSourcePath) {
8930
8952
  audioOutputPath,
8931
8953
  hasAudio,
8932
8954
  audioError,
8933
- audioFailures
8955
+ audioFailures,
8956
+ audioPhaseMs
8934
8957
  };
8935
8958
  }
8936
8959
 
@@ -9045,6 +9068,7 @@ async function runCaptureStage(input) {
9045
9068
  let { workerCount } = plan2;
9046
9069
  const { forceScreenshot } = plan2;
9047
9070
  let lastBrowserConsole = [];
9071
+ const workerPageErrors = [];
9048
9072
  let captureBeyondViewport = probeSession?.options.captureBeyondViewport;
9049
9073
  const captureCfg = cfg.forceScreenshot === forceScreenshot ? cfg : { ...cfg, forceScreenshot };
9050
9074
  if (frameRange !== void 0) {
@@ -9082,6 +9106,7 @@ async function runCaptureStage(input) {
9082
9106
  abortSignal,
9083
9107
  frameRangeStart: frameRange?.startFrame,
9084
9108
  dedupPerfs,
9109
+ pageErrorLines: workerPageErrors,
9085
9110
  onProgress: (progress) => {
9086
9111
  if (progress.latestWorkerPhase) {
9087
9112
  if (progress.capturedFrames === 0) reportWorkerStartup(job, progress, onProgress);
@@ -9102,6 +9127,11 @@ async function runCaptureStage(input) {
9102
9127
  },
9103
9128
  cfg: captureCfg,
9104
9129
  log
9130
+ }).catch((error) => {
9131
+ throw wrapCaptureStageError(
9132
+ error,
9133
+ withWorkerPageErrors(probeSession?.browserConsoleBuffer ?? [], workerPageErrors)
9134
+ );
9105
9135
  });
9106
9136
  captureAttempts.push(...attempts);
9107
9137
  const lastAttempt = attempts[attempts.length - 1];
@@ -9114,6 +9144,7 @@ async function runCaptureStage(input) {
9114
9144
  await closeCaptureSession(probeSession);
9115
9145
  probeSession = null;
9116
9146
  }
9147
+ lastBrowserConsole = withWorkerPageErrors(lastBrowserConsole, workerPageErrors);
9117
9148
  } else {
9118
9149
  const sequential = await runSequentialDiskCapture(
9119
9150
  input,
@@ -10025,6 +10056,7 @@ async function runCaptureHdrStage(input) {
10025
10056
  width,
10026
10057
  height,
10027
10058
  codec: preset.codec,
10059
+ useGpu: job.config.useGpu,
10028
10060
  preset: preset.preset,
10029
10061
  quality: effectiveQuality,
10030
10062
  bitrate: effectiveBitrate,
@@ -10390,7 +10422,7 @@ function videoEncoderOptions(input, engineCfg) {
10390
10422
  };
10391
10423
  }
10392
10424
  function canEncodeWhileCapturing(input, workerCount, cpuCount) {
10393
- return workerCount > 1 && workerCount < cpuCount && !input.isPngSequence && !input.isGif && !input.enableChunkedEncode && input.preset.codec === "h264" && !input.preset.hdr && input.job.config.useGpu !== true && input.captureImageFormat === "jpeg" && input.lockGopForChunkConcat !== true;
10425
+ return workerCount > 1 && workerCount < cpuCount && !input.isPngSequence && !input.isGif && !input.enableChunkedEncode && input.preset.codec === "h264" && !input.preset.hdr && input.job.config.useGpu !== true && input.captureImageFormat === "jpeg";
10394
10426
  }
10395
10427
  async function readLandedFrame(workerPath, mergedPath) {
10396
10428
  if (workerPath !== void 0) {
@@ -11045,6 +11077,7 @@ async function executeDiskCaptureWithAdaptiveRetry(options) {
11045
11077
  options.cfg
11046
11078
  );
11047
11079
  pushWorkerDedupPerfs(workerResults, options.dedupPerfs);
11080
+ if (options.pageErrorLines) pushWorkerPageErrors(workerResults, options.pageErrorLines);
11048
11081
  } finally {
11049
11082
  await mergeWorkerFrames(attemptWorkDir, tasks, options.framesDir);
11050
11083
  }
@@ -13423,7 +13456,6 @@ import {
13423
13456
  existsSync as existsSync20,
13424
13457
  linkSync,
13425
13458
  mkdirSync as mkdirSync12,
13426
- renameSync as renameSync5,
13427
13459
  rmSync as rmSync11,
13428
13460
  writeFileSync as writeFileSync8
13429
13461
  } from "fs";
@@ -14350,14 +14382,7 @@ import { writeFileSync as writeFileSync7, writeSync } from "fs";
14350
14382
  import { join as join30 } from "path";
14351
14383
 
14352
14384
  // ../producer/src/services/distributed/mp4Stitch.ts
14353
- import {
14354
- createReadStream as createReadStream4,
14355
- createWriteStream,
14356
- mkdirSync as mkdirSync10,
14357
- mkdtempSync as mkdtempSync4,
14358
- renameSync as renameSync4,
14359
- rmSync as rmSync10
14360
- } from "fs";
14385
+ import { createReadStream as createReadStream4, createWriteStream, mkdirSync as mkdirSync10, mkdtempSync as mkdtempSync4, rmSync as rmSync10 } from "fs";
14361
14386
  import { open } from "fs/promises";
14362
14387
  import { dirname as dirname11, join as join29 } from "path";
14363
14388
  import { finished, pipeline } from "stream/promises";
@@ -14731,7 +14756,7 @@ async function writeStitchedMp4(chunkPaths, outputPath, audioPath) {
14731
14756
  for (const [i, path] of sourcePaths.entries()) await copyPayload(path, layouts[i], i, out);
14732
14757
  out.end();
14733
14758
  await finished(out);
14734
- renameSync4(join29(workDir, "out.mp4"), outputPath);
14759
+ renameWithRetry(join29(workDir, "out.mp4"), outputPath);
14735
14760
  } finally {
14736
14761
  out.destroy();
14737
14762
  rmSync10(workDir, { recursive: true, force: true });
@@ -15457,6 +15482,10 @@ async function compilePlanComposition(projectDir, config, planDir, options) {
15457
15482
  const needsAlpha = outputNeedsAlpha(config.format);
15458
15483
  const remoteFiles = Object.entries(options.remoteFiles ?? {});
15459
15484
  const remoteLocalPath = (rel) => join32(projectDir, ...rel.split("/"));
15485
+ for (const [, file] of remoteFiles) {
15486
+ declareContentAddressedUrl(file.url, file.sha256);
15487
+ if (file.probeFactsUrl) declareProbeFactsUrl(file.url, file.probeFactsUrl);
15488
+ }
15460
15489
  const urlByAbsentLocalPath = new Map(
15461
15490
  remoteFiles.map(([rel, file]) => [remoteLocalPath(rel), file.url])
15462
15491
  );
@@ -15531,7 +15560,7 @@ async function compilePlanComposition(projectDir, config, planDir, options) {
15531
15560
  if (probeResult.fileServer) closeFileServerSafely(probeResult.fileServer, "plan", log);
15532
15561
  if (probeResult.probeSession) {
15533
15562
  try {
15534
- const { closeCaptureSession: closeCaptureSession2 } = await import("./src-ZOXSEJCD.js");
15563
+ const { closeCaptureSession: closeCaptureSession2 } = await import("./src-BH5NICGQ.js");
15535
15564
  await closeCaptureSession2(probeResult.probeSession);
15536
15565
  } catch (err) {
15537
15566
  log.warn("[plan] probe session close failed", {
@@ -15578,7 +15607,8 @@ function mixPlanAudio(c, compiledDir) {
15578
15607
  audios: c.composition.audios,
15579
15608
  masterFxChain: c.composition.masterFxChain,
15580
15609
  abortSignal: c.abortSignal,
15581
- assertNotAborted: c.assertNotAborted
15610
+ assertNotAborted: c.assertNotAborted,
15611
+ log: c.log
15582
15612
  });
15583
15613
  }
15584
15614
  async function extractPlanVideos(c, deferRangeExtraction) {
@@ -15597,6 +15627,7 @@ async function extractPlanVideos(c, deferRangeExtraction) {
15597
15627
  if (extractResult.failureToEnforce) throw extractResult.failureToEnforce;
15598
15628
  if (extractResult.extractionResult) {
15599
15629
  assertVideoExtractionSucceeded(extractResult.extractionResult);
15630
+ c.log.info("[plan] extract phases", { ...extractResult.extractionResult.phaseBreakdown });
15600
15631
  }
15601
15632
  return extractResult;
15602
15633
  }
@@ -15642,12 +15673,12 @@ async function buildLocalExecutionPlan(projectDir, config, executionPlanDir, opt
15642
15673
  const videoSourcesDir = join32(planDir, "video-sources");
15643
15674
  rmSync11(videoSourcesDir, { recursive: true, force: true });
15644
15675
  if (existsSync20(stagedVideoFrames)) {
15645
- renameSync5(stagedVideoFrames, videoFramesDst);
15676
+ renameWithRetry(stagedVideoFrames, videoFramesDst);
15646
15677
  } else {
15647
15678
  mkdirSync12(videoFramesDst, { recursive: true });
15648
15679
  }
15649
15680
  if (existsSync20(finalCompiledDir)) rmSync11(finalCompiledDir, { recursive: true, force: true });
15650
- renameSync5(compiledDir, finalCompiledDir);
15681
+ renameWithRetry(compiledDir, finalCompiledDir);
15651
15682
  const shipVideoSource = createVideoSourceShipper({
15652
15683
  planDir,
15653
15684
  projectDir,
@@ -15750,7 +15781,7 @@ async function buildLocalExecutionPlan(projectDir, config, executionPlanDir, opt
15750
15781
  }
15751
15782
  const planAudioPath = join32(planDir, PLAN_AUDIO_RELATIVE_PATH);
15752
15783
  if (audioResult?.hasAudio && existsSync20(audioResult.audioOutputPath)) {
15753
- renameSync5(audioResult.audioOutputPath, planAudioPath);
15784
+ renameWithRetry(audioResult.audioOutputPath, planAudioPath);
15754
15785
  }
15755
15786
  if (chunksCarryAudio && existsSync20(planAudioPath)) {
15756
15787
  if (options.sliceChunkAudio) {
@@ -17182,7 +17213,7 @@ function startServer(options = {}) {
17182
17213
  });
17183
17214
  async function shutdown(signal) {
17184
17215
  log.info(`Received ${signal}, shutting down`);
17185
- const { drainBrowserPool } = await import("./src-ZOXSEJCD.js");
17216
+ const { drainBrowserPool } = await import("./src-BH5NICGQ.js");
17186
17217
  await drainBrowserPool().catch(() => {
17187
17218
  });
17188
17219
  const handle = await Promise.race([
@@ -17226,7 +17257,6 @@ import {
17226
17257
  mkdtempSync as mkdtempSync7,
17227
17258
  readFileSync as readFileSync12,
17228
17259
  readdirSync as readdirSync9,
17229
- renameSync as renameSync7,
17230
17260
  rmSync as rmSync14,
17231
17261
  statSync as statSync9,
17232
17262
  writeFileSync as writeFileSync11
@@ -17241,7 +17271,6 @@ import {
17241
17271
  linkSync as linkSync2,
17242
17272
  mkdirSync as mkdirSync14,
17243
17273
  mkdtempSync as mkdtempSync6,
17244
- renameSync as renameSync6,
17245
17274
  rmSync as rmSync13,
17246
17275
  statSync as statSync8,
17247
17276
  writeFileSync as writeFileSync10
@@ -17334,7 +17363,7 @@ var LocalPlanV2ArtifactPublisher = class {
17334
17363
  if (!canFallbackToCopy(error)) throw error;
17335
17364
  copyFileSync5(blob.sourcePath, temporaryPath);
17336
17365
  }
17337
- renameSync6(temporaryPath, destinationPath);
17366
+ renameWithRetry(temporaryPath, destinationPath);
17338
17367
  } finally {
17339
17368
  rmSync13(stagingDir, { recursive: true, force: true });
17340
17369
  }
@@ -17348,7 +17377,7 @@ var LocalPlanV2ArtifactPublisher = class {
17348
17377
  }
17349
17378
  }
17350
17379
  writeFileSync10(join37(this.temporaryDir, "plan.json"), manifestBytes, "utf-8");
17351
- renameSync6(this.temporaryDir, this.destinationDir);
17380
+ renameWithRetry(this.temporaryDir, this.destinationDir);
17352
17381
  this.#committed = true;
17353
17382
  }
17354
17383
  async abort() {
@@ -17615,7 +17644,7 @@ function writeBlob(sourcePath, destinationPath) {
17615
17644
  const temporaryPath = join38(temporaryDir, "blob");
17616
17645
  try {
17617
17646
  copyFileSync6(sourcePath, temporaryPath);
17618
- renameSync7(temporaryPath, destinationPath);
17647
+ renameWithRetry(temporaryPath, destinationPath);
17619
17648
  } finally {
17620
17649
  rmSync14(temporaryDir, { recursive: true, force: true });
17621
17650
  }
@@ -17747,7 +17776,7 @@ function createPlanV2FromExecutionPlan(executionPlanDir, planV2Dir) {
17747
17776
  canonicalJsonStringify(publication.manifest),
17748
17777
  "utf-8"
17749
17778
  );
17750
- renameSync7(tempDir, planV2Dir);
17779
+ renameWithRetry(tempDir, planV2Dir);
17751
17780
  return resultFromManifest(planV2Dir, publication.manifest);
17752
17781
  } catch (error) {
17753
17782
  rmSync14(tempDir, { recursive: true, force: true });
@@ -18032,7 +18061,7 @@ function materializePlanV2Target(planV2Dir, target, destinationDir, options = {}
18032
18061
  }),
18033
18062
  "utf-8"
18034
18063
  );
18035
- renameSync7(tempDir, destinationDir);
18064
+ renameWithRetry(tempDir, destinationDir);
18036
18065
  } catch (error) {
18037
18066
  rmSync14(tempDir, { recursive: true, force: true });
18038
18067
  throw error;
@@ -18110,7 +18139,6 @@ import {
18110
18139
  mkdtempSync as mkdtempSync8,
18111
18140
  readFileSync as readFileSync13,
18112
18141
  readdirSync as readdirSync10,
18113
- renameSync as renameSync8,
18114
18142
  rmSync as rmSync15,
18115
18143
  statSync as statSync10,
18116
18144
  writeFileSync as writeFileSync12
@@ -18170,7 +18198,7 @@ async function assemble(planDir, chunkOutputs, audioPath, outputPath, options) {
18170
18198
  const finalPath = join39(workDir, `output.${format}`);
18171
18199
  const audio = audioPath !== null && existsSync26(audioPath) ? audioPath : null;
18172
18200
  await writeJoined(ctx, videoSources, audio, finalPath);
18173
- renameSync8(finalPath, outputPath);
18201
+ renameWithRetry(finalPath, outputPath);
18174
18202
  log.info("[assemble] stage timings", {
18175
18203
  ...stageMs,
18176
18204
  chunks: chunkPaths.length,
@@ -18240,7 +18268,7 @@ function cfrEncodeArgs(inputArgs, encoder, fpsArg) {
18240
18268
  "-r",
18241
18269
  fpsArg
18242
18270
  ];
18243
- appendSoftwareEncoderThreadsArg(args);
18271
+ appendSoftwareEncoderThreadsArg(args, "libx264");
18244
18272
  return args;
18245
18273
  }
18246
18274
  async function reencodeCfr(ctx, chunkPaths, encoder) {
@@ -18422,6 +18450,7 @@ function mergePngFrameDirs(chunkPaths, outputPath, totalFrames, audioPath, start
18422
18450
  // ../producer/src/services/distributed/renderChunk.ts
18423
18451
  import { randomBytes } from "crypto";
18424
18452
  import { existsSync as existsSync27, mkdirSync as mkdirSync17, readFileSync as readFileSync14, readdirSync as readdirSync11, rmSync as rmSync16, writeFileSync as writeFileSync13 } from "fs";
18453
+ import { cpus as cpus3 } from "os";
18425
18454
  import { join as join40 } from "path";
18426
18455
  var LEGACY_DISTRIBUTED_VP9_CPU_USED = 2;
18427
18456
  function validatePlanVideosForChunk(value) {
@@ -18710,6 +18739,7 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath, options) {
18710
18739
  let forceScreenshotForChunk = encoder.forceScreenshot;
18711
18740
  let shownBoxes;
18712
18741
  let extraction;
18742
+ const overlap = { current: null };
18713
18743
  try {
18714
18744
  if (chunkWorkerCount === 1 || !forceScreenshotForChunk) {
18715
18745
  const bootStarted = Date.now();
@@ -18797,6 +18827,59 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath, options) {
18797
18827
  videoFrameLookup,
18798
18828
  frameCacheOptions(cfg, chunkWorkerCount)
18799
18829
  );
18830
+ const isPngSequence = plan2.dimensions.format === "png-sequence";
18831
+ outputKind = isPngSequence ? "frame-dir" : "file";
18832
+ const presetFormat = isPngSequence ? "mp4" : plan2.dimensions.format;
18833
+ const basePreset = getEncoderPreset(job.config.quality, presetFormat, void 0);
18834
+ const preset = resolvePresetForLockedEncoder(basePreset, encoder.encoder);
18835
+ const effectiveQuality = encoder.crf ?? preset.quality;
18836
+ const effectiveBitrate = encoder.crf != null ? void 0 : encoder.bitrate;
18837
+ const videoOnlyPath = encoder.chunksCarryAudio ? `${outputChunkPath}.video.mp4` : outputChunkPath;
18838
+ if (isPngSequence) {
18839
+ if (!existsSync27(outputChunkPath)) mkdirSync17(outputChunkPath, { recursive: true });
18840
+ } else {
18841
+ const outDir = join40(outputChunkPath, "..");
18842
+ if (!existsSync27(outDir)) mkdirSync17(outDir, { recursive: true });
18843
+ }
18844
+ const encodeInput = {
18845
+ job,
18846
+ log,
18847
+ outputPath: videoOnlyPath,
18848
+ framesDir,
18849
+ videoOnlyPath,
18850
+ width: Math.round(plan2.dimensions.width * encoder.deviceScaleFactor),
18851
+ height: Math.round(plan2.dimensions.height * encoder.deviceScaleFactor),
18852
+ needsAlpha: plan2.dimensions.format !== "mp4",
18853
+ captureImageFormat: captureOptions.format ?? "jpeg",
18854
+ // The encoder writes video only; audio joins at assemble time or in the
18855
+ // chunk that carries audio. Suppressing `hasAudio` skips the png-sequence audio
18856
+ // sidecar AND the mp4 audio mux.
18857
+ hasAudio: false,
18858
+ isPngSequence,
18859
+ // `DistributedFormat` has no "gif" member — distributed chunks are
18860
+ // always video segments (gif renders in-process only).
18861
+ isGif: false,
18862
+ preset,
18863
+ effectiveQuality,
18864
+ effectiveBitrate,
18865
+ engineConfig: {
18866
+ ffmpegEncodeTimeout: cfg.ffmpegEncodeTimeout,
18867
+ vp9CpuUsed: resolveLockedVp9CpuUsed(encoder) ?? cfg.vp9CpuUsed
18868
+ },
18869
+ // Distributed chunks emit a single ffmpeg call per chunk; the
18870
+ // in-process per-chunk-within-chunk path would re-split our
18871
+ // already-chunked work.
18872
+ enableChunkedEncode: false,
18873
+ chunkedEncodeSize: framesInChunk,
18874
+ abortSignal: void 0,
18875
+ assertNotAborted: () => {
18876
+ },
18877
+ // GOP === framesInChunk + force-keyframe at frame 0 → the chunk's
18878
+ // first frame is an IDR keyframe and concat-copy at assemble time
18879
+ // round-trips losslessly.
18880
+ lockGopForChunkConcat: !isPngSequence,
18881
+ gopSize: framesInChunk
18882
+ };
18800
18883
  const captureStarted = Date.now();
18801
18884
  captureMode = await runCaptureWithScreenshotFallback({
18802
18885
  forceScreenshot: forceScreenshotForChunk,
@@ -18829,6 +18912,7 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath, options) {
18829
18912
  }
18830
18913
  const captureSession = session;
18831
18914
  session = null;
18915
+ overlap.current = canEncodeWhileCapturing(encodeInput, chunkWorkerCount, cpus3().length) ? encodeWhileCapturing(encodeInput, framesInChunk) : null;
18832
18916
  await runCaptureStage({
18833
18917
  fileServer,
18834
18918
  workDir,
@@ -18848,7 +18932,12 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath, options) {
18848
18932
  abortSignal: void 0,
18849
18933
  assertNotAborted: () => {
18850
18934
  },
18851
- frameRange: range
18935
+ frameRange: range,
18936
+ onFrameLanded: (frame) => overlap.current?.onFrameLanded(frame)
18937
+ }).catch(async (captureError) => {
18938
+ await overlap.current?.abort();
18939
+ overlap.current = null;
18940
+ throw captureError;
18852
18941
  });
18853
18942
  return observedChunkCaptureMode(capturePerfs);
18854
18943
  },
@@ -18880,60 +18969,10 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath, options) {
18880
18969
  log
18881
18970
  );
18882
18971
  framesEncoded = framesInChunk;
18883
- const isPngSequence = plan2.dimensions.format === "png-sequence";
18884
- outputKind = isPngSequence ? "frame-dir" : "file";
18885
- const presetFormat = isPngSequence ? "mp4" : plan2.dimensions.format;
18886
- const basePreset = getEncoderPreset(job.config.quality, presetFormat, void 0);
18887
- const preset = resolvePresetForLockedEncoder(basePreset, encoder.encoder);
18888
- const effectiveQuality = encoder.crf ?? preset.quality;
18889
- const effectiveBitrate = encoder.crf != null ? void 0 : encoder.bitrate;
18890
- const videoOnlyPath = encoder.chunksCarryAudio ? `${outputChunkPath}.video.mp4` : outputChunkPath;
18891
- if (isPngSequence) {
18892
- if (!existsSync27(outputChunkPath)) mkdirSync17(outputChunkPath, { recursive: true });
18893
- } else {
18894
- const outDir = join40(outputChunkPath, "..");
18895
- if (!existsSync27(outDir)) mkdirSync17(outDir, { recursive: true });
18896
- }
18897
18972
  const encodeStarted = Date.now();
18898
- await runEncodeStage({
18899
- job,
18900
- log,
18901
- outputPath: videoOnlyPath,
18902
- framesDir,
18903
- videoOnlyPath,
18904
- width: Math.round(plan2.dimensions.width * encoder.deviceScaleFactor),
18905
- height: Math.round(plan2.dimensions.height * encoder.deviceScaleFactor),
18906
- needsAlpha: plan2.dimensions.format !== "mp4",
18907
- captureImageFormat: captureOptions.format ?? "jpeg",
18908
- // The encoder writes video only; audio joins at assemble time or in the
18909
- // chunk that carries audio. Suppressing `hasAudio` skips the png-sequence audio
18910
- // sidecar AND the mp4 audio mux.
18911
- hasAudio: false,
18912
- isPngSequence,
18913
- // `DistributedFormat` has no "gif" member — distributed chunks are
18914
- // always video segments (gif renders in-process only).
18915
- isGif: false,
18916
- preset,
18917
- effectiveQuality,
18918
- effectiveBitrate,
18919
- engineConfig: {
18920
- ffmpegEncodeTimeout: cfg.ffmpegEncodeTimeout,
18921
- vp9CpuUsed: resolveLockedVp9CpuUsed(encoder) ?? cfg.vp9CpuUsed
18922
- },
18923
- // Distributed chunks emit a single ffmpeg call per chunk; the
18924
- // in-process per-chunk-within-chunk path would re-split our
18925
- // already-chunked work.
18926
- enableChunkedEncode: false,
18927
- chunkedEncodeSize: framesInChunk,
18928
- abortSignal: void 0,
18929
- assertNotAborted: () => {
18930
- },
18931
- // GOP === framesInChunk + force-keyframe at frame 0 → the chunk's
18932
- // first frame is an IDR keyframe and concat-copy at assemble time
18933
- // round-trips losslessly.
18934
- lockGopForChunkConcat: !isPngSequence,
18935
- gopSize: framesInChunk
18936
- });
18973
+ const overlapped = overlap.current;
18974
+ overlap.current = null;
18975
+ await (overlapped ? overlapped.finish() : runEncodeStage(encodeInput));
18937
18976
  if (encoder.chunksCarryAudio) {
18938
18977
  const audioScratchPath = `${outputChunkPath}.audio.m4a`;
18939
18978
  const audioChunks = options?.frameRange ? chunksWithSubRange(chunks, chunkIndex, range) : { chunks, index: chunkIndex };
@@ -18951,6 +18990,8 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath, options) {
18951
18990
  }
18952
18991
  encodeStageMs = Date.now() - encodeStarted;
18953
18992
  } finally {
18993
+ await overlap.current?.abort().catch(() => {
18994
+ });
18954
18995
  await extraction?.catch(() => {
18955
18996
  });
18956
18997
  if (session) {
@@ -19063,6 +19104,10 @@ var READ_CHUNK_BYTES = 256 * 1024;
19063
19104
  import { extname as extname7 } from "path";
19064
19105
  var AUDIO_SIDECAR_MIN_BYTES = 32 * 1024 * 1024;
19065
19106
 
19107
+ // ../producer/src/services/distributed/probeFacts.ts
19108
+ import { writeFileSync as writeFileSync14 } from "fs";
19109
+ import { extname as extname8 } from "path";
19110
+
19066
19111
  export {
19067
19112
  createConsoleLogger,
19068
19113
  defaultLogger,