hyperframes 0.8.144 → 0.8.146
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.
- package/README.md +3 -2
- package/dist/{add-CWRTVGDB.js → add-6J4TLUDW.js} +15 -15
- package/dist/{animatedGifPrep-JTOHIWI4.js → animatedGifPrep-TPYA45ZZ.js} +10 -10
- package/dist/{asset-KU2Z4UFM.js → asset-B4C6ZU4V.js} +2 -2
- package/dist/{assetCataloger-3CS2P7PA.js → assetCataloger-GX4B55VB.js} +4 -4
- package/dist/{auth-IDSOIQWG.js → auth-T2V3URGO.js} +2 -2
- package/dist/{autoUpdate-373B4BA2.js → autoUpdate-O4R7IOYP.js} +2 -2
- package/dist/{backgroundChecks-53Q3NAMG.js → backgroundChecks-SQHGZCSH.js} +3 -3
- package/dist/backgroundChecksWorker.js +3 -3
- package/dist/{batchRender-UKZA6BME.js → batchRender-T7S2CGJE.js} +5 -5
- package/dist/{beats-N5JGEOFR.js → beats-RNEXDM7U.js} +16 -16
- package/dist/{benchmark-CUN3LN4V.js → benchmark-IVK6FCEU.js} +12 -12
- package/dist/{browser-NCZT5AP6.js → browser-WUE6VK2N.js} +5 -5
- package/dist/{bundleWithLocalizedFonts-FWC7PE2D.js → bundleWithLocalizedFonts-EEIRL7FT.js} +2 -2
- package/dist/{capture-YLS32UHT.js → capture-K3EONGGU.js} +2 -2
- package/dist/{capture-QBLG3VJR.js → capture-LEKIGJ4G.js} +13 -13
- package/dist/{catalog-HIWNAFHW.js → catalog-IXYQ2KXW.js} +15 -15
- package/dist/{catch-up-HGS7KIAC.js → catch-up-IIF7HKR6.js} +6 -6
- package/dist/{check-FH6UYYLO.js → check-W7CDOXNP.js} +38 -38
- package/dist/{checkBrowser-RNWNOMCZ.js → checkBrowser-5VSXEHBZ.js} +118 -61
- package/dist/{chunk-XU5GGV6R.js → chunk-2NAUEDA6.js} +2 -2
- package/dist/{chunk-GZM2EFOE.js → chunk-3HSWLZ6S.js} +1 -1
- package/dist/{chunk-YUAXFWSQ.js → chunk-4RUILXS6.js} +5 -5
- package/dist/{chunk-MXNDKDFT.js → chunk-54UXJKFF.js} +1 -1
- package/dist/{chunk-DIRJ322I.js → chunk-66SAATRI.js} +3 -3
- package/dist/{chunk-RI53TS2Y.js → chunk-6TTAXMDG.js} +2 -2
- package/dist/{chunk-YJXHMIZA.js → chunk-A72OAGNB.js} +6 -6
- package/dist/{chunk-G75ENCEZ.js → chunk-AIJS74LG.js} +3 -3
- package/dist/{chunk-GEWKFRFI.js → chunk-AJ5R4GM6.js} +1 -1
- package/dist/{chunk-3VYNNWVA.js → chunk-BAKPN2D2.js} +101 -94
- package/dist/{chunk-3XTEXWNN.js → chunk-CVPWZ5LY.js} +3 -3
- package/dist/{chunk-AUBOF2PN.js → chunk-DDNS2674.js} +1 -1
- package/dist/{chunk-QFSCCQIR.js → chunk-DMKI64EZ.js} +1 -1
- package/dist/{chunk-NOPBBSLA.js → chunk-DUU77E2S.js} +69 -64
- package/dist/{chunk-RVFEDAUV.js → chunk-EGO6Z24R.js} +3 -3
- package/dist/{chunk-KC5XXX3X.js → chunk-EOOEC32M.js} +1 -1
- package/dist/{chunk-2DA2BBNY.js → chunk-ETNQF37F.js} +10 -10
- package/dist/{chunk-54QISXOC.js → chunk-FDL4HV44.js} +2 -2
- package/dist/{chunk-VYSUZEJG.js → chunk-FJLHVAPO.js} +6 -6
- package/dist/{chunk-QZ3AZTXI.js → chunk-FJWEYVEM.js} +42 -16
- package/dist/{chunk-EX6C672Y.js → chunk-FKLYMV3U.js} +1 -1
- package/dist/{chunk-PUGIRFPX.js → chunk-FMNVTKX2.js} +4 -4
- package/dist/{chunk-L5TUCXWR.js → chunk-HBGJYBGE.js} +2 -2
- package/dist/{chunk-SLCFKB3Y.js → chunk-HTM4CIFS.js} +11 -8
- package/dist/{chunk-T42U2W2R.js → chunk-IXLUTE6N.js} +1 -1
- package/dist/{chunk-OUSLVRO4.js → chunk-JBQJKC23.js} +76 -6
- package/dist/{chunk-IEIJRMLZ.js → chunk-JDB65PPT.js} +62 -63
- package/dist/{chunk-USDEMXXL.js → chunk-JYVGYKXG.js} +1 -1
- package/dist/{chunk-P6WH6QTV.js → chunk-K7ES5RSK.js} +1 -1
- package/dist/{chunk-LC3RQURJ.js → chunk-KFZUUXUN.js} +3 -3
- package/dist/{chunk-OIDN7G42.js → chunk-KG265HQ7.js} +2 -2
- package/dist/{chunk-7RAYSCYT.js → chunk-KPJMBC4K.js} +2 -2
- package/dist/{chunk-MAYCCGMQ.js → chunk-KVGDFUVO.js} +1 -1
- package/dist/{chunk-JEHFZQYT.js → chunk-LE7T4ML7.js} +1 -1
- package/dist/{chunk-MQZVBHEY.js → chunk-LFNQDTSH.js} +1 -1
- package/dist/{chunk-ZOA2SC4P.js → chunk-MOL32UKR.js} +45 -11
- package/dist/{chunk-RG3QWWIE.js → chunk-QSSPIATO.js} +2 -2
- package/dist/{chunk-F2SMS24Q.js → chunk-R6R74HNZ.js} +117 -139
- package/dist/{chunk-7SDCIWHQ.js → chunk-SYMSKGXI.js} +2 -2
- package/dist/{chunk-ZEUONDQG.js → chunk-SYUGVPYH.js} +1 -1
- package/dist/{chunk-4OC7MQNB.js → chunk-TBOMPYG6.js} +2 -2
- package/dist/{chunk-KFKZ3ISO.js → chunk-TH4OXAWY.js} +1 -1
- package/dist/{chunk-4LAR447G.js → chunk-UOBYRLDD.js} +1 -1
- package/dist/{chunk-NV4RXIQ7.js → chunk-UZUUVYAO.js} +3 -3
- package/dist/{chunk-PJ3HDUCY.js → chunk-VAS6HQX3.js} +39 -9
- package/dist/{chunk-LFX2HEYP.js → chunk-VT563F4O.js} +7 -7
- package/dist/{chunk-5VMR4WBS.js → chunk-WU2B74TL.js} +363 -103
- package/dist/{chunk-5HJ343GH.js → chunk-WUZ6TMAO.js} +1 -1
- package/dist/{chunk-GQJZORQP.js → chunk-XBSPQ52S.js} +1 -1
- package/dist/{chunk-5WADG7PR.js → chunk-XJUZEB44.js} +1 -1
- package/dist/{chunk-I5KY7EZP.js → chunk-XVIYZU3D.js} +1 -1
- package/dist/{chunk-XGFHYAYN.js → chunk-Z5C4LEAD.js} +33 -28
- package/dist/chunk-Z6FLHIDV.js +3795 -0
- package/dist/{chunk-DDIVWXN7.js → chunk-ZFN6GQU4.js} +4 -4
- package/dist/{chunk-Y6UPYWJS.js → chunk-ZVZSFDW3.js} +2 -2
- package/dist/{chunk-A53CBD24.js → chunk-ZZ7H4IJ6.js} +9 -9
- package/dist/{clean-KPX27IKJ.js → clean-2GDD2B4F.js} +23 -23
- package/dist/cli.js +52 -52
- package/dist/{cloud-P7DAOISN.js → cloud-LUKGDTTE.js} +4 -4
- package/dist/{cloudrun-XM56TBOH.js → cloudrun-NQF5KFQI.js} +6 -6
- package/dist/{compare-F6YAFZZM.js → compare-4P6O4ONG.js} +32 -32
- package/dist/{compiler-JZ4GNFMG.js → compiler-ACCPOZMQ.js} +10 -6
- package/dist/{component-3CFOGIQA.js → component-SDDOLNJD.js} +3 -3
- package/dist/{compositions-CPCMWF24.js → compositions-P2L6HUVQ.js} +15 -15
- package/dist/{delete-GYVKOKB6.js → delete-Q6S4BJ3F.js} +2 -2
- package/dist/{deterministicFonts-U2BIMGPG.js → deterministicFonts-C5JQLCTS.js} +2 -2
- package/dist/{dist-YPWQDWJ4.js → dist-GPDOV3IQ.js} +4 -4
- package/dist/{dist-KDJTFJHA.js → dist-HUMFCJ6T.js} +3 -3
- package/dist/{doctor-GWI3B6JT.js → doctor-NL73UKHV.js} +15 -15
- package/dist/{events-BRRUDPPT.js → events-AVOPOKO3.js} +5 -5
- package/dist/{events-V2QFN4YM.js → events-X7KPU7LG.js} +4 -4
- package/dist/{feedback-CXMD7FWL.js → feedback-GJZ5NXSH.js} +10 -10
- package/dist/{ffmpeg-T5SH2EFJ.js → ffmpeg-5V4FP3R6.js} +2 -2
- package/dist/{figma-YABDWD66.js → figma-V7SVQQI5.js} +3 -3
- package/dist/fontLocalizeCli.js +14 -14
- package/dist/{get-L2SOQKHX.js → get-FO3YZYEU.js} +2 -2
- package/dist/{gpuPolicy-NBJNWHYS.js → gpuPolicy-QGS4TFWP.js} +10 -10
- package/dist/{grade-compare-STXQPKYQ.js → grade-compare-7ICSN7KE.js} +33 -33
- package/dist/{help-4H6BSFLB.js → help-Y5LYZG7K.js} +2 -2
- package/dist/{history-4IQOLTHJ.js → history-RKGBRNLD.js} +49 -22
- package/dist/hyperframe-runtime.js +214 -68
- package/dist/hyperframe.manifest.json +1 -1
- package/dist/hyperframe.runtime.iife.js +214 -68
- package/dist/hyperframes-player.global.js +4 -5
- package/dist/hyperframes-slideshow.global.js +3 -4
- package/dist/{info-2CZOTNBC.js → info-GGUTL2NR.js} +11 -11
- package/dist/{init-6BXK42VS.js → init-PG7NA5SQ.js} +31 -31
- package/dist/{inspect-VKU47TBH.js → inspect-FCXUB6DE.js} +33 -33
- package/dist/{installer-T2BSSUDY.js → installer-LZ4X5TZZ.js} +6 -6
- package/dist/{keyframes-IEYVHRPI.js → keyframes-R3K6WJ3N.js} +8 -8
- package/dist/{lambda-TIKG25CK.js → lambda-3GAKHMC3.js} +7 -7
- package/dist/{layout-XOI4PT7A.js → layout-XNIZIGA2.js} +33 -33
- package/dist/{lint-DWCMVIX5.js → lint-4KDS2F4O.js} +11 -11
- package/dist/{lintProject-UBZ3TDHU.js → lintProject-SSEXWCH6.js} +3 -3
- package/dist/{list-7GXKG5QM.js → list-OVPURFPK.js} +2 -2
- package/dist/{login-BQ5L2UHX.js → login-EE2AX2PE.js} +4 -4
- package/dist/{manager-YKMHR6LN.js → manager-5ORDVWJB.js} +3 -3
- package/dist/{media-treatment-IFB7OSZ3.js → media-treatment-UDUEOP67.js} +86 -55
- package/dist/{models-TY4PJ545.js → models-LPK2O4B2.js} +14 -14
- package/dist/{motionShot-WXMFHICW.js → motionShot-G76XBOYI.js} +35 -29
- package/dist/{normalize-audio-RFD776HQ.js → normalize-audio-TUKWZ3OR.js} +10 -10
- package/dist/{open-7IXXGO2E.js → open-7XB2TGVB.js} +6 -6
- package/dist/{parakeetRunner-IHLYYMTZ.js → parakeetRunner-DL556HXL.js} +14 -14
- package/dist/{pipeline-TXKPLL2U.js → pipeline-34N5DLWU.js} +11 -11
- package/dist/{play-J2KP64UK.js → play-DDA2UUQF.js} +26 -26
- package/dist/{preflight-B4AFK3RG.js → preflight-ONF5AJNO.js} +5 -5
- package/dist/{present-MHHNRVRA.js → present-LLNRKXF5.js} +23 -23
- package/dist/{preview-CONUOFFQ.js → preview-H3ZZS46F.js} +57 -26
- package/dist/{producer-ZI46K7HH.js → producer-IFQOZK2G.js} +1 -1
- package/dist/{projectConfig-FGGVG5MV.js → projectConfig-SBRMQZGG.js} +8 -8
- package/dist/{publication-TXFBMW6B.js → publication-5BQICRZO.js} +4 -4
- package/dist/{publish-YZSPBFRD.js → publish-XDUZA3E3.js} +27 -26
- package/dist/{remove-background-4ATVLHLG.js → remove-background-GNKRMFQS.js} +12 -12
- package/dist/{render-MH4IUPWB.js → render-JM6KNRIA.js} +27 -27
- package/dist/{render-6FBYLYGJ.js → render-KTTC3EE5.js} +12 -12
- package/dist/{render-GFW5BPES.js → render-PCFO45RK.js} +5 -5
- package/dist/{render-batch-XUCZ2PUJ.js → render-batch-7R2NRNVJ.js} +5 -5
- package/dist/{renderCancellation-XF7M7IUP.js → renderCancellation-GP3XD2FS.js} +10 -10
- package/dist/renderSetupWorker.js +3 -3
- package/dist/{resolver-W7AYCQGS.js → resolver-C4FPX72I.js} +6 -6
- package/dist/{sherpa-LDUB5NLY.js → sherpa-MZP3MV2X.js} +14 -14
- package/dist/skills/hyperframes/scripts/lib/frame-packets-core.mjs +2 -20
- package/dist/skills/hyperframes/scripts/lib/main-module.mjs +13 -0
- package/dist/skills/hyperframes/scripts/lib/main-module.test.mjs +51 -0
- package/dist/skills/hyperframes/scripts/plugin-cli.mjs +4 -3
- package/dist/skills/hyperframes/scripts/plugin-cli.test.mjs +5 -1
- package/dist/skills/hyperframes-cli/SKILL.md +2 -0
- package/dist/skills/media-use/audio/scripts/heygen-voice.mjs +2 -2
- package/dist/skills/media-use/audio/scripts/lib/main-module.mjs +13 -0
- package/dist/skills/media-use/references/media-treatments.md +5 -1
- package/dist/skills/media-use/scripts/lib/cube-validate.mjs +2 -3
- package/dist/skills/media-use/scripts/lib/main-module.mjs +13 -0
- package/dist/{skills-VENERS5X.js → skills-OET4XSHR.js} +7 -7
- package/dist/{skillsUpdateCheck-UXFYTACG.js → skillsUpdateCheck-IPFSKKJD.js} +3 -3
- package/dist/{slideshow-4OJEPWNZ.js → slideshow-YTWATJRT.js} +1 -1
- package/dist/{snapshot-C6T74HTI.js → snapshot-EC4N75MS.js} +34 -34
- package/dist/{src-VUJ2FUFK.js → src-LIERUCFW.js} +13 -9
- package/dist/{src-FS5RSVEI.js → src-ZZQJOKO6.js} +13 -13
- package/dist/{staticProjectServer-V2RZ4DWD.js → staticProjectServer-YH2RHYKW.js} +20 -20
- package/dist/{status-LXPGSSKY.js → status-PTKNQD2E.js} +2 -2
- package/dist/studio/assets/{hyperframes-player-Bw_jIaSX.js → hyperframes-player-tkxyWf5H.js} +3 -3
- package/dist/studio/assets/{index-Cj7W_c7p.js → index-BrdqOkqP.js} +1 -1
- package/dist/studio/assets/{index-BVM9NuWl.js → index-Cg48BxAo.js} +145 -145
- package/dist/studio/assets/{index-DyH9dT7b.js → index-Dllxg4aU.js} +1 -1
- package/dist/studio/index.html +1 -1
- package/dist/{studio-api-TQE7KWKO.js → studio-api-T2TS2CHL.js} +16 -14
- package/dist/{studioServer-CYKSQK7L.js → studioServer-GJVVJUEL.js} +54 -52
- package/dist/{system-OQLOGGPJ.js → system-OXRG57F2.js} +2 -2
- package/dist/{telemetry-A23PPRD6.js → telemetry-ZQ5XVE6Z.js} +5 -5
- package/dist/{timeline-T3QSGT3A.js → timeline-I2T5WIPD.js} +34 -25
- package/dist/{tokens-RT5HWA6C.js → tokens-ONUWOXEX.js} +2 -2
- package/dist/{transcribe-FOLNOC5G.js → transcribe-BCQMA537.js} +12 -12
- package/dist/{transcribe-HCF64LQK.js → transcribe-ZLJF7V5Y.js} +13 -13
- package/dist/{updateCheck-27PIP3AA.js → updateCheck-ZWHDXF73.js} +2 -2
- package/dist/{upgrade-TVGXBUPJ.js → upgrade-32JGFZWS.js} +2 -2
- package/dist/{urlDownloader-KBLBJKRL.js → urlDownloader-EVDP43GM.js} +9 -9
- package/dist/{validate-ZMYGK4QI.js → validate-G4PUGQCI.js} +27 -27
- package/dist/{video-AVE5GIGM.js → video-TILEY3VJ.js} +10 -10
- package/package.json +3 -2
- package/dist/chunk-WJB7WI4J.js +0 -3753
- package/dist/studio/chunk-3GHTHPZD.js +0 -1105
- package/dist/studio/chunk-3GHTHPZD.js.map +0 -1
- package/dist/studio/chunk-EEXSYY5F.js +0 -190
- package/dist/studio/chunk-EEXSYY5F.js.map +0 -1
- package/dist/studio/chunk-G3EDKRZH.js +0 -1442
- package/dist/studio/chunk-G3EDKRZH.js.map +0 -1
- package/dist/studio/chunk-PEAKCOUW.js +0 -942
- package/dist/studio/chunk-PEAKCOUW.js.map +0 -1
- package/dist/studio/chunk-PZ5AY32C.js +0 -10
- package/dist/studio/chunk-PZ5AY32C.js.map +0 -1
- package/dist/studio/chunk-Y2OHHNM2.js +0 -970
- package/dist/studio/chunk-Y2OHHNM2.js.map +0 -1
- package/dist/studio/domEditingLayers-PYST4G45.js +0 -47
- package/dist/studio/domEditingLayers-PYST4G45.js.map +0 -1
- package/dist/studio/index.css +0 -165
- package/dist/studio/index.css.map +0 -1
- package/dist/studio/index.d.ts +0 -4315
- package/dist/studio/index.js +0 -100971
- package/dist/studio/index.js.map +0 -1
- package/dist/studio/player.d.ts +0 -30
- package/dist/studio/player.js +0 -10
- package/dist/studio/player.js.map +0 -1
- package/dist/studio/styles/tailwind-preset.d.ts +0 -39
- package/dist/studio/styles/tailwind-preset.js +0 -50
- package/dist/studio/styles/tailwind-preset.js.map +0 -1
- package/dist/studio/styles.css +0 -1
- package/dist/studio/ui.d.ts +0 -297
- package/dist/studio/ui.js +0 -66
- package/dist/studio/ui.js.map +0 -1
|
@@ -11,18 +11,19 @@ import {
|
|
|
11
11
|
iterateFontFamilyDeclarations,
|
|
12
12
|
normalizeSystemFontPrimaryFamilies,
|
|
13
13
|
resolveFontFamilyDeclarationFamilies
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-FMNVTKX2.js";
|
|
15
15
|
import {
|
|
16
16
|
EncoderInterruptedError,
|
|
17
17
|
encoderFailureError,
|
|
18
18
|
prepareAnimatedGifInputs
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-KG265HQ7.js";
|
|
20
20
|
import {
|
|
21
21
|
createStudioPositionSeekReapplyScript
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-EOOEC32M.js";
|
|
23
23
|
import {
|
|
24
24
|
BROWSER_GPU_NOT_SOFTWARE,
|
|
25
25
|
CaptureFailure,
|
|
26
|
+
DEFAULT_CONFIG,
|
|
26
27
|
DrawElementVerificationError,
|
|
27
28
|
HDR_AUTO_PROMOTION_PIPELINE,
|
|
28
29
|
HF_AUDIO_GROUP_TAG,
|
|
@@ -68,6 +69,7 @@ import {
|
|
|
68
69
|
decodePng,
|
|
69
70
|
decodePngToRgb48le,
|
|
70
71
|
deriveBeginFrameProbeTimeTicks,
|
|
72
|
+
describeFfmpegFailure,
|
|
71
73
|
detectTransfer,
|
|
72
74
|
distributeFrames,
|
|
73
75
|
distributeFramesInterleaved,
|
|
@@ -103,6 +105,7 @@ import {
|
|
|
103
105
|
isNotMediaPayload,
|
|
104
106
|
isTransientBrowserError,
|
|
105
107
|
isVideoFrameFormat,
|
|
108
|
+
isVideoPastTimelineEnd,
|
|
106
109
|
mergeWorkerFrames,
|
|
107
110
|
muxVideoWithAudio,
|
|
108
111
|
normalizeObjectFit,
|
|
@@ -142,7 +145,7 @@ import {
|
|
|
142
145
|
validateEngineConfigSnapshot,
|
|
143
146
|
verifyDiskDrawElementSamples,
|
|
144
147
|
writeCapturedFrame
|
|
145
|
-
} from "./chunk-
|
|
148
|
+
} from "./chunk-WU2B74TL.js";
|
|
146
149
|
import {
|
|
147
150
|
assignBundledRuntimeCompositionIds,
|
|
148
151
|
buildVariablesByCompScript,
|
|
@@ -150,15 +153,17 @@ import {
|
|
|
150
153
|
emitRootCompositionVariableStyles,
|
|
151
154
|
ensureExternalLinkTag,
|
|
152
155
|
ensureExternalScriptTag,
|
|
156
|
+
extractStandaloneEntryFromIndex,
|
|
153
157
|
inlineSubCompositions,
|
|
158
|
+
isTemplateEntry,
|
|
154
159
|
parsesAsScript,
|
|
155
160
|
prepareFlattenedInnerRoot
|
|
156
|
-
} from "./chunk-
|
|
161
|
+
} from "./chunk-JBQJKC23.js";
|
|
157
162
|
import {
|
|
158
163
|
LOW_MEMORY_TOTAL_MB_THRESHOLD,
|
|
159
164
|
getCgroupMemoryLimitMb,
|
|
160
165
|
getSystemTotalMb
|
|
161
|
-
} from "./chunk-
|
|
166
|
+
} from "./chunk-JYVGYKXG.js";
|
|
162
167
|
import {
|
|
163
168
|
HF_VFX_ATTR,
|
|
164
169
|
MEDIA_START_BASIS_ATTR,
|
|
@@ -174,7 +179,7 @@ import {
|
|
|
174
179
|
resolveAbsoluteMediaStartSeconds,
|
|
175
180
|
resolveAuthoredTimingWindow,
|
|
176
181
|
toFps
|
|
177
|
-
} from "./chunk-
|
|
182
|
+
} from "./chunk-BAKPN2D2.js";
|
|
178
183
|
import {
|
|
179
184
|
COMPOSITION_SOURCE_URL,
|
|
180
185
|
HF_COLOR_GRADING_ATTR,
|
|
@@ -201,7 +206,7 @@ import {
|
|
|
201
206
|
shouldClampResolvedMediaDuration,
|
|
202
207
|
sourceTimeAt,
|
|
203
208
|
styleElementsFor
|
|
204
|
-
} from "./chunk-
|
|
209
|
+
} from "./chunk-Z6FLHIDV.js";
|
|
205
210
|
import {
|
|
206
211
|
MAX_AUDIO_GAIN
|
|
207
212
|
} from "./chunk-YA62XGXS.js";
|
|
@@ -215,7 +220,7 @@ import {
|
|
|
215
220
|
isAspectAgnosticResolutionAlias,
|
|
216
221
|
normalizeResolutionFlag,
|
|
217
222
|
suggestMatchingPreset
|
|
218
|
-
} from "./chunk-
|
|
223
|
+
} from "./chunk-LFNQDTSH.js";
|
|
219
224
|
import {
|
|
220
225
|
redactKnownPaths,
|
|
221
226
|
redactTelemetryString
|
|
@@ -225,7 +230,7 @@ import {
|
|
|
225
230
|
} from "./chunk-TWWSYAKJ.js";
|
|
226
231
|
import {
|
|
227
232
|
lintHyperframeHtml
|
|
228
|
-
} from "./chunk-
|
|
233
|
+
} from "./chunk-JDB65PPT.js";
|
|
229
234
|
import {
|
|
230
235
|
isUnresolvedAssetPlaceholder,
|
|
231
236
|
readProjectFile,
|
|
@@ -482,7 +487,7 @@ function buildVirtualTimeShim(options) {
|
|
|
482
487
|
const seedRandomFromFrame = options.seedRandomFromFrame === true;
|
|
483
488
|
const seededRandomBlock = seedRandomFromFrame ? String.raw`
|
|
484
489
|
// Seeded Math.random / crypto.getRandomValues, keyed by virtual time.
|
|
485
|
-
// Mulberry32
|
|
490
|
+
// Mulberry32: single uint32 state, deterministic, fast.
|
|
486
491
|
var rngState = 0;
|
|
487
492
|
function mulberry32() {
|
|
488
493
|
rngState |= 0; rngState = (rngState + 0x6D2B79F5) | 0;
|
|
@@ -493,7 +498,7 @@ function buildVirtualTimeShim(options) {
|
|
|
493
498
|
}
|
|
494
499
|
function reseedRngFromTime(ms) {
|
|
495
500
|
var ms32 = Math.max(0, Math.floor(Number(ms) || 0)) | 0;
|
|
496
|
-
// Knuth's multiplicative hash + golden-ratio offset
|
|
501
|
+
// Knuth's multiplicative hash + golden-ratio offset gives a well-
|
|
497
502
|
// distributed seed even for frame 0 (otherwise rngState=0 degenerates
|
|
498
503
|
// the PRNG's first few outputs).
|
|
499
504
|
rngState = (Math.imul(ms32, -1640531527) + 0x9E3779B9) | 0;
|
|
@@ -735,7 +740,7 @@ function buildRenderModeScript(fps) {
|
|
|
735
740
|
};
|
|
736
741
|
window.__playerReady = true;
|
|
737
742
|
// Media-fallback player has no timeline to bind, so render-ready is immediate.
|
|
738
|
-
// init.ts defers __renderReady until the timeline is bound
|
|
743
|
+
// init.ts defers __renderReady until the timeline is bound (a different runtime).
|
|
739
744
|
window.__renderReady = true;
|
|
740
745
|
return true;
|
|
741
746
|
}
|
|
@@ -2262,7 +2267,7 @@ function blitHdrVideoLayer(canvas, el, time, fps, hdrVideoFrameSources, hdrStart
|
|
|
2262
2267
|
if (matrix && !isTranslationOnly) {
|
|
2263
2268
|
if (clipped && log) {
|
|
2264
2269
|
log.debug(
|
|
2265
|
-
`HDR clip rect on affine-transformed element ${el.id}
|
|
2270
|
+
`HDR clip rect on affine-transformed element ${el.id}: clip not applied (affine scissor not yet supported)`
|
|
2266
2271
|
);
|
|
2267
2272
|
}
|
|
2268
2273
|
blitRgb48leAffine(
|
|
@@ -2319,7 +2324,7 @@ function blitHdrImageLayer(canvas, el, hdrImageBuffers, hdrImageTransferCache, w
|
|
|
2319
2324
|
return;
|
|
2320
2325
|
}
|
|
2321
2326
|
if (el.clipRect && log) {
|
|
2322
|
-
log.debug(`HDR clip rect on image element ${el.id}
|
|
2327
|
+
log.debug(`HDR clip rect on image element ${el.id}: clip not yet supported for images`);
|
|
2323
2328
|
}
|
|
2324
2329
|
try {
|
|
2325
2330
|
if (hdrPerf) hdrPerf.hdrImageLayerBlits += 1;
|
|
@@ -4470,7 +4475,7 @@ async function validateCompletedSegments(manifest, expectedHash, probeFrames) {
|
|
|
4470
4475
|
function formatDowngradeWarning(outputFormat, forcedHdrWithoutSources) {
|
|
4471
4476
|
const hdrSourceReason = forcedHdrWithoutSources ? "HDR was forced without detected HDR sources" : "HDR source detected";
|
|
4472
4477
|
const formatReason = outputFormat === "hls" ? "HLS output is SDR-only (H.264 in MPEG-TS)" : "HDR + alpha is not supported";
|
|
4473
|
-
return `[Render] ${hdrSourceReason}, but format is "${outputFormat}"
|
|
4478
|
+
return `[Render] ${hdrSourceReason}, but format is "${outputFormat}", so falling back to SDR. ${formatReason}. Use --format mp4 for HDR10 output.`;
|
|
4474
4479
|
}
|
|
4475
4480
|
function findRenderHdrAutoPromotionTrigger(input) {
|
|
4476
4481
|
for (const extracted of input.extractionResult?.extracted ?? []) {
|
|
@@ -4483,12 +4488,12 @@ function findRenderHdrAutoPromotionTrigger(input) {
|
|
|
4483
4488
|
function logHdrResolution(input, hdrMode, effectiveHdr, forcedHdrWithoutSources) {
|
|
4484
4489
|
if (forcedHdrWithoutSources) {
|
|
4485
4490
|
input.log.warn(
|
|
4486
|
-
"[Render] HDR forced by --hdr flag, but no HDR sources were detected
|
|
4491
|
+
"[Render] HDR forced by --hdr flag, but no HDR sources were detected, defaulting to HLG. SDR-only compositions may look perceptually wrong on HDR displays."
|
|
4487
4492
|
);
|
|
4488
4493
|
}
|
|
4489
4494
|
if (!effectiveHdr) {
|
|
4490
4495
|
input.log.info(
|
|
4491
|
-
hdrMode === "force-sdr" ? "[Render] SDR forced by --sdr flag" : "[Render] No HDR sources detected
|
|
4496
|
+
hdrMode === "force-sdr" ? "[Render] SDR forced by --sdr flag" : "[Render] No HDR sources detected, rendering SDR"
|
|
4492
4497
|
);
|
|
4493
4498
|
return;
|
|
4494
4499
|
}
|
|
@@ -4503,9 +4508,9 @@ function logHdrResolution(input, hdrMode, effectiveHdr, forcedHdrWithoutSources)
|
|
|
4503
4508
|
);
|
|
4504
4509
|
return;
|
|
4505
4510
|
}
|
|
4506
|
-
const reason = forcedHdrWithoutSources ? "forced by --hdr flag (no HDR sources detected
|
|
4511
|
+
const reason = forcedHdrWithoutSources ? "forced by --hdr flag (no HDR sources detected, defaulting to HLG)" : "forced by --hdr flag";
|
|
4507
4512
|
input.log.info(
|
|
4508
|
-
`[Render] HDR ${reason}
|
|
4513
|
+
`[Render] HDR ${reason}, output: ${effectiveHdr.transfer.toUpperCase()} (BT.2020, 10-bit H.265)`
|
|
4509
4514
|
);
|
|
4510
4515
|
}
|
|
4511
4516
|
function resolveEffectiveHdrMode(input) {
|
|
@@ -4592,14 +4597,14 @@ function resolveRenderWorkerCount(totalFrames, requestedWorkers, cfg, compiled,
|
|
|
4592
4597
|
const reasonCodes = new Set(compiled.renderModeHints.reasons.map((r) => r.code));
|
|
4593
4598
|
if (reasonCodes.has("htmlInCanvas")) {
|
|
4594
4599
|
log.warn(
|
|
4595
|
-
"[Render] html-in-canvas (drawElementImage) detected
|
|
4600
|
+
"[Render] html-in-canvas (drawElementImage) detected, pinning to 1 worker (Chrome concurrency limitation).",
|
|
4596
4601
|
{ requestedWorkers }
|
|
4597
4602
|
);
|
|
4598
4603
|
return 1;
|
|
4599
4604
|
}
|
|
4600
4605
|
if (cfg.lowMemoryMode && requestedWorkers === void 0) {
|
|
4601
4606
|
log.info(
|
|
4602
|
-
"[Render] Low-memory profile
|
|
4607
|
+
"[Render] Low-memory profile, pinning to 1 capture worker (auto-worker calibration skipped)."
|
|
4603
4608
|
);
|
|
4604
4609
|
return 1;
|
|
4605
4610
|
}
|
|
@@ -5223,7 +5228,7 @@ function assertVideoFrameCoverage(reports, threshold) {
|
|
|
5223
5228
|
const thresholdPct = (threshold * 100).toFixed(1);
|
|
5224
5229
|
const suffix = sorted.length > 1 ? ` (+${sorted.length - 1} more clip(s) below threshold)` : "";
|
|
5225
5230
|
throw new VideoFrameCoverageError(
|
|
5226
|
-
`Video "${worst.videoId}" captured ${worst.capturedFrames} of expected ${worst.expectedFrames} frames (coverage ${pct}%, threshold ${thresholdPct}%). check/snapshot may pass while the encoded MP4 renders this clip blank
|
|
5231
|
+
`Video "${worst.videoId}" captured ${worst.capturedFrames} of expected ${worst.expectedFrames} frames (coverage ${pct}%, threshold ${thresholdPct}%). check/snapshot may pass while the encoded MP4 renders this clip blank, so the render is aborted to prevent shipping a wrong MP4.${suffix} Set HF_VIDEO_COVERAGE_THRESHOLD=0 to disable this gate.`,
|
|
5227
5232
|
{ threshold, worst, failedReports: sorted }
|
|
5228
5233
|
);
|
|
5229
5234
|
}
|
|
@@ -5330,7 +5335,7 @@ function collectRenderMedia(html) {
|
|
|
5330
5335
|
}
|
|
5331
5336
|
|
|
5332
5337
|
// ../core/dist/generated/position-edits-render-inline.js
|
|
5333
|
-
var POSITION_EDITS_RENDER_IIFE = '"use strict";(()=>{function T(){return globalThis}function P(e,t){if(typeof window>"u")return;let o=T(),r=o.__hf?.onSwallowed;if(r)try{r({label:e,error:t})}catch(s){}(o.__hfDebug||o.__HYPERFRAMES_DEBUG)&&console.debug(`[hyperframes] ${e} swallowed:`,t)}var x=null;function R(e,t){if(x)try{x({source:"hf-preview",type:"analytics",event:e,properties:t??{}})}catch(o){P("runtime.analytics.site1",o)}}var W="http://www.w3.org/1999/xhtml";function N(e){return e!=null&&e.nodeType===1}function
|
|
5338
|
+
var POSITION_EDITS_RENDER_IIFE = '"use strict";(()=>{function T(){return globalThis}function P(e,t){if(typeof window>"u")return;let o=T(),r=o.__hf?.onSwallowed;if(r)try{r({label:e,error:t})}catch(s){}(o.__hfDebug||o.__HYPERFRAMES_DEBUG)&&console.debug(`[hyperframes] ${e} swallowed:`,t)}var x=null;function R(e,t){if(x)try{x({source:"hf-preview",type:"analytics",event:e,properties:t??{}})}catch(o){P("runtime.analytics.site1",o)}}var W="http://www.w3.org/1999/xhtml";function N(e){return e!=null&&e.nodeType===1}function k(e){return N(e)&&(e.namespaceURI===W||e.namespaceURI==="http://www.w3.org/2000/svg")}var w="data-hf-edit-base-x",y="data-hf-edit-base-y",m="data-hf-edit-original-translate",_=e=>{let t=parseFloat(e??"");return Number.isFinite(t)?t:0},O=e=>{let t=[],o=0,r="";for(let s of e.trim())s==="("&&(o+=1),s===")"&&(o=Math.max(0,o-1)),/\\s/.test(s)&&o===0?(r&&t.push(r),r=""):r+=s;return r&&t.push(r),t},L=/^-?(?:\\d+(?:\\.\\d+)?|\\.\\d+)px$/,E=(e,t)=>L.test(e)&&L.test(t)?`${parseFloat(e)+parseFloat(t)}px`:`calc(${e} + ${t})`,V=(e,t,o)=>{if(!e||e==="none")return`${t} ${o}`;let[r,s,a]=O(e);if(r===void 0)return`${t} ${o}`;if(s===void 0)return`${E(r,t)} ${o}`;let i=a===void 0?"":` ${a}`;return`${E(r,t)} ${E(s,o)}${i}`},j=e=>{try{e.ownerDocument.defaultView?.gsap?.getProperty?.(e,"x")}catch{}},C=e=>{let t=e.style.getPropertyValue("translate").trim();if(t)return t==="none"?"":t;try{let o=e.ownerDocument.defaultView,r=o?o.getComputedStyle(e).getPropertyValue("translate").trim():"";return r==="none"?"":r}catch{return""}},b=new WeakMap;function G(e,t){let o=b.get(e);if(!t?.force&&o!==void 0&&e.style.getPropertyValue("translate")!==o){R("position_edit_fold_skipped",{hfId:e.getAttribute("data-hf-id")});return}let r=_(e.getAttribute("data-x"))-_(e.getAttribute(w)),s=_(e.getAttribute("data-y"))-_(e.getAttribute(y));e.hasAttribute(m)||e.setAttribute(m,C(e)),o===void 0&&j(e);let a=e.getAttribute(m)??"",i=V(a,`${r}px`,`${s}px`);e.style.setProperty("translate",i),b.set(e,e.style.getPropertyValue("translate"))}function S(e,t){let o=e.querySelectorAll(`[${m}]:not([${w}]):not([${y}])`);for(let a=0;a<o.length;a++){let i=o[a];if(i===void 0||!k(i))continue;let g=i.getAttribute(m)??"";g===""?i.style.removeProperty("translate"):i.style.setProperty("translate",g),i.removeAttribute(m),b.delete(i)}let r=e.querySelectorAll(`[${w}], [${y}]`),s=0;for(let a=0;a<r.length;a++){let i=r[a];i===void 0||!k(i)||(G(i,t),s+=1)}return s}var $="__hfPositionEditsSeekReapplyWrapped",D=new WeakSet,M=new WeakMap,H=new WeakMap;function F(e){let t=e,o=()=>{try{S(t.document)}catch{}},r=n=>typeof n=="function"&&(D.has(n)||!!n[$]),s=n=>{D.add(n);try{Object.defineProperty(n,$,{value:!0})}catch{}},a=n=>{if(typeof n!="function"||r(n))return n;let l=function(...u){let d=n.apply(this,u);return o(),d};return s(l),l},i=(n,l)=>{let u=M.get(n);if(u?.has(l))return!0;let d=Object.getOwnPropertyDescriptor(n,l);if(d?.configurable===!1){let c=n[l];return typeof c=="function"&&(n[l]=a(c),o()),!1}let p=n[l],f=d?.set;return Object.defineProperty(n,l,{configurable:!0,enumerable:d?.enumerable??!0,get:()=>p,set:c=>{p=a(c),f?.call(n,c)}}),p=a(p),u??(u=new Set),u.add(l),M.set(n,u),o(),!0},g=(n,l)=>{let u=H.get(t),d=Object.getOwnPropertyDescriptor(t,n);if(!u?.has(n)){if(d?.configurable===!1){let c=t[n];return c?i(c,l):!1}let f=t[n];Object.defineProperty(t,n,{configurable:!0,enumerable:d?.enumerable??!0,get:()=>f,set:c=>{f=c,f&&i(f,l)}}),u??(u=new Set),u.add(n),H.set(t,u)}let p=t[n];return p?i(p,l):!1},h=()=>{let n=g("__hf","seek"),l=g("__player","renderSeek");return n&&l};if(h())return;let v=120,A=t.setInterval(()=>{if(h()){t.clearInterval(A);return}v-=1,v<=0&&t.clearInterval(A)},50)}function I(){document.querySelector(`[${w}], [${y}]`)&&(S(document),F(window))}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",I,{once:!0}):I();})();\n';
|
|
5334
5339
|
function getPositionEditsRenderScript() {
|
|
5335
5340
|
return POSITION_EDITS_RENDER_IIFE;
|
|
5336
5341
|
}
|
|
@@ -5720,7 +5725,7 @@ async function resolveMediaDuration(src, mediaStart, playbackRate, baseDir, down
|
|
|
5720
5725
|
if (tagName !== "video") {
|
|
5721
5726
|
if (error instanceof NotMediaPayloadError) {
|
|
5722
5727
|
log?.warn(
|
|
5723
|
-
`[compile] Audio "${elementIdentity}" (${src}) is a text document, not a media file
|
|
5728
|
+
`[compile] Audio "${elementIdentity}" (${src}) is a text document, not a media file, so the element is dropped from the render. Point it at a rendered media file.`
|
|
5724
5729
|
);
|
|
5725
5730
|
}
|
|
5726
5731
|
return { duration: null, resolvedPath: filePath };
|
|
@@ -5809,7 +5814,7 @@ async function compileHtmlFile(html, baseDir, downloadDir, log) {
|
|
|
5809
5814
|
if (r.maxDuration != null && shouldClampResolvedMediaDuration(r.tagName, r.duration, r.maxDuration)) {
|
|
5810
5815
|
clampList.push({ id: r.id, duration: r.maxDuration });
|
|
5811
5816
|
log?.warn(
|
|
5812
|
-
`[compile] Audio "${r.id}" (${r.src}) is ${r.maxDuration.toFixed(2)}s but its data-duration is ${r.duration.toFixed(2)}s
|
|
5817
|
+
`[compile] Audio "${r.id}" (${r.src}) is ${r.maxDuration.toFixed(2)}s but its data-duration is ${r.duration.toFixed(2)}s, so the slot is shortened to the media length. Set data-duration to ~${r.maxDuration.toFixed(2)}s, trim data-media-start, or use a longer/looping source if that isn't intended.`
|
|
5813
5818
|
);
|
|
5814
5819
|
}
|
|
5815
5820
|
}
|
|
@@ -6198,7 +6203,7 @@ ${safeText}
|
|
|
6198
6203
|
} else {
|
|
6199
6204
|
if (download.reason instanceof ScriptIntegrityError) throw download.reason;
|
|
6200
6205
|
defaultLogger.warn(
|
|
6201
|
-
`[Compiler] WARNING: Failed to download CDN script: ${src}
|
|
6206
|
+
`[Compiler] WARNING: Failed to download CDN script: ${src} (${download.reason}). The render may fail if this script is required (e.g. GSAP). Consider bundling it locally in your project.`
|
|
6202
6207
|
);
|
|
6203
6208
|
}
|
|
6204
6209
|
}
|
|
@@ -6250,7 +6255,7 @@ function collectExternalAssets(html, projectDir) {
|
|
|
6250
6255
|
}
|
|
6251
6256
|
if (externalAssets.size > 0) {
|
|
6252
6257
|
defaultLogger.info(
|
|
6253
|
-
`[Compiler] Found ${externalAssets.size} asset(s) outside project directory
|
|
6258
|
+
`[Compiler] Found ${externalAssets.size} asset(s) outside project directory, will copy to render output`
|
|
6254
6259
|
);
|
|
6255
6260
|
}
|
|
6256
6261
|
return {
|
|
@@ -6275,7 +6280,7 @@ async function downloadAndRewriteUrls(urlSet, html, remoteDir, warnLabel, logLab
|
|
|
6275
6280
|
urlToLocal.set(url, localPath);
|
|
6276
6281
|
} catch (err) {
|
|
6277
6282
|
const identity = safeDownloadUrlIdentity(url);
|
|
6278
|
-
defaultLogger.warn(`[Compiler] ${warnLabel}
|
|
6283
|
+
defaultLogger.warn(`[Compiler] ${warnLabel}, using original URL as fallback.`, {
|
|
6279
6284
|
urlFingerprint: identity.urlFingerprint,
|
|
6280
6285
|
host: identity.host,
|
|
6281
6286
|
error: err instanceof Error ? err.message : String(err)
|
|
@@ -6368,7 +6373,7 @@ async function fetchExternalStylesheetCss(href) {
|
|
|
6368
6373
|
timeoutMs: 15e3
|
|
6369
6374
|
});
|
|
6370
6375
|
} catch (err) {
|
|
6371
|
-
defaultLogger.warn("[Compiler] External stylesheet fetch failed
|
|
6376
|
+
defaultLogger.warn("[Compiler] External stylesheet fetch failed, preserving link tag.", {
|
|
6372
6377
|
urlFingerprint: identity.urlFingerprint,
|
|
6373
6378
|
host: identity.host,
|
|
6374
6379
|
error: err instanceof Error ? err.message : String(err)
|
|
@@ -6503,7 +6508,7 @@ async function readLocalFont(absPath) {
|
|
|
6503
6508
|
return { kind: "inline", buffer: Buffer.concat(chunks, totalBytes) };
|
|
6504
6509
|
}
|
|
6505
6510
|
async function embedLocalFontFaces(html, projectDir) {
|
|
6506
|
-
const { fontToDataUri: toDataUri } = await import("./deterministicFonts-
|
|
6511
|
+
const { fontToDataUri: toDataUri } = await import("./deterministicFonts-C5JQLCTS.js");
|
|
6507
6512
|
const styleBlockRe = /<style\b[^>]*>([\s\S]*?)<\/style>/gi;
|
|
6508
6513
|
const fontFaceRe = /@font-face\s*\{([^}]*)\}/gi;
|
|
6509
6514
|
let result = html;
|
|
@@ -7012,12 +7017,15 @@ async function resolveCompositionDurations(page, unresolved) {
|
|
|
7012
7017
|
const resolved = [];
|
|
7013
7018
|
for (const id of compIds) {
|
|
7014
7019
|
const tl = timelines[id];
|
|
7015
|
-
|
|
7016
|
-
|
|
7017
|
-
|
|
7018
|
-
|
|
7019
|
-
|
|
7020
|
-
|
|
7020
|
+
let dur = 0;
|
|
7021
|
+
try {
|
|
7022
|
+
dur = typeof tl?.duration === "function" ? Number(tl.duration()) : 0;
|
|
7023
|
+
} catch {
|
|
7024
|
+
dur = 0;
|
|
7025
|
+
}
|
|
7026
|
+
if (dur > 0) {
|
|
7027
|
+
resolved.push({ id, duration: dur, source: "__timelines" });
|
|
7028
|
+
continue;
|
|
7021
7029
|
}
|
|
7022
7030
|
const el = document.getElementById(id);
|
|
7023
7031
|
if (el) {
|
|
@@ -7113,28 +7121,28 @@ async function runCompileStage(input) {
|
|
|
7113
7121
|
cfg.useDrawElement = false;
|
|
7114
7122
|
deCompileGate = "3d";
|
|
7115
7123
|
log.info(
|
|
7116
|
-
"[Render] Fast capture: composition uses a CSS 3D rendering context (perspective / preserve-3d / backface-visibility)
|
|
7124
|
+
"[Render] Fast capture: composition uses a CSS 3D rendering context (perspective / preserve-3d / backface-visibility), so disabling drawElementImage for this render. Capture uses the platform's baseline route."
|
|
7117
7125
|
);
|
|
7118
7126
|
}
|
|
7119
7127
|
if (cfg.useDrawElement && process.env.HF_FAST_CAPTURE_BLEND !== "true" && compiled.usesMixBlendMode) {
|
|
7120
7128
|
cfg.useDrawElement = false;
|
|
7121
7129
|
deCompileGate = "mix_blend_mode";
|
|
7122
7130
|
log.info(
|
|
7123
|
-
"[Render] Fast capture: composition uses mix-blend-mode
|
|
7131
|
+
"[Render] Fast capture: composition uses mix-blend-mode, so disabling drawElementImage for this render. Capture uses the platform's baseline route."
|
|
7124
7132
|
);
|
|
7125
7133
|
}
|
|
7126
7134
|
if (cfg.useDrawElement && process.env.HF_FAST_CAPTURE_ANCESTOR_BG !== "true" && compiled.hasAncestorBackgroundImage) {
|
|
7127
7135
|
cfg.useDrawElement = false;
|
|
7128
7136
|
deCompileGate = "ancestor_background_image";
|
|
7129
7137
|
log.info(
|
|
7130
|
-
"[Render] Fast capture: composition root's ancestors (body/html/wrapper) carry a background-image
|
|
7138
|
+
"[Render] Fast capture: composition root's ancestors (body/html/wrapper) carry a background-image, so disabling drawElementImage for this render. Capture uses the platform's baseline route."
|
|
7131
7139
|
);
|
|
7132
7140
|
}
|
|
7133
7141
|
if (cfg.useDrawElement && process.env.PRODUCER_EXPERIMENTAL_FAST_CAPTURE !== "true" && compiled.hasShaderTransitions) {
|
|
7134
7142
|
cfg.useDrawElement = false;
|
|
7135
7143
|
deCompileGate = "shader_transitions";
|
|
7136
7144
|
log.info(
|
|
7137
|
-
"[Render] Fast capture: composition uses shader transitions
|
|
7145
|
+
"[Render] Fast capture: composition uses shader transitions, so disabling drawElementImage so page-side compositing stays available."
|
|
7138
7146
|
);
|
|
7139
7147
|
}
|
|
7140
7148
|
if (!cfg.useDrawElement && cfg.pageSideCompositingAutoDisabled) {
|
|
@@ -7449,7 +7457,7 @@ async function runProbeStage(input) {
|
|
|
7449
7457
|
} else {
|
|
7450
7458
|
beginFrameStalled = true;
|
|
7451
7459
|
log.warn(
|
|
7452
|
-
"[Render] BeginFrame liveness probe timed out
|
|
7460
|
+
"[Render] BeginFrame liveness probe timed out: this composition stalls BeginFrame on this host (SwiftShader heavy-layer pattern). Relaunching the probe browser in screenshot capture mode; the render will use screenshot capture throughout.",
|
|
7453
7461
|
{ probeTimeoutMs }
|
|
7454
7462
|
);
|
|
7455
7463
|
lastBrowserConsole = probeSession.browserConsoleBuffer;
|
|
@@ -7663,7 +7671,7 @@ async function runProbeStage(input) {
|
|
|
7663
7671
|
video.start = win.visibleStart;
|
|
7664
7672
|
video.end = win.visibleEnd;
|
|
7665
7673
|
log.info(
|
|
7666
|
-
`[Probe] Runtime video discovery: ${video.id} visible ${win.visibleStart.toFixed(2)}s
|
|
7674
|
+
`[Probe] Runtime video discovery: ${video.id} visible ${win.visibleStart.toFixed(2)}s to ${win.visibleEnd.toFixed(2)}s`
|
|
7667
7675
|
);
|
|
7668
7676
|
}
|
|
7669
7677
|
}
|
|
@@ -7711,7 +7719,7 @@ async function runProbeStage(input) {
|
|
|
7711
7719
|
});
|
|
7712
7720
|
if (!timelinesInfo.gsapLoaded) {
|
|
7713
7721
|
diagnostics.push(
|
|
7714
|
-
"GSAP is not loaded
|
|
7722
|
+
"GSAP is not loaded. The CDN script may have failed to download. Bundle GSAP locally in your project instead of using a CDN <script src>."
|
|
7715
7723
|
);
|
|
7716
7724
|
} else if (timelinesInfo.timelineKeys.length === 0) {
|
|
7717
7725
|
diagnostics.push(
|
|
@@ -7728,10 +7736,10 @@ async function runProbeStage(input) {
|
|
|
7728
7736
|
log.warn("Failed to gather browser diagnostics for zero-duration composition", {
|
|
7729
7737
|
error: err instanceof Error ? err.message : String(err)
|
|
7730
7738
|
});
|
|
7731
|
-
diagnostics.push("(Could not gather browser diagnostics
|
|
7739
|
+
diagnostics.push("(Could not gather browser diagnostics. The page may have crashed.)");
|
|
7732
7740
|
}
|
|
7733
7741
|
const hint = diagnostics.length > 0 ? "\n\nDiagnostics:\n - " + diagnostics.join("\n - ") : "\n\nCheck that GSAP timelines are registered on window.__timelines.";
|
|
7734
|
-
throw new Error("Composition duration is 0
|
|
7742
|
+
throw new Error("Composition duration is 0, so this would produce a black video." + hint);
|
|
7735
7743
|
}
|
|
7736
7744
|
if (probeSession) {
|
|
7737
7745
|
const failedRequests = probeSession.browserConsoleBuffer.filter(isActionableProbeFailure);
|
|
@@ -7787,7 +7795,7 @@ function validateNoGpuEncode(config) {
|
|
|
7787
7795
|
if (config.useGpu === true) {
|
|
7788
7796
|
throw new PlanValidationError(
|
|
7789
7797
|
BROWSER_GPU_NOT_SOFTWARE,
|
|
7790
|
-
"[planValidation] GPU encode is banned in distributed mode: config.useGpu === true. Distributed retries must be byte-identical, but NVENC/QSV/VAAPI produce different output across machines. Set useGpu=false (the default)
|
|
7798
|
+
"[planValidation] GPU encode is banned in distributed mode: config.useGpu === true. Distributed retries must be byte-identical, but NVENC/QSV/VAAPI produce different output across machines. Set useGpu=false (the default): software libx264/libx265 is the only supported encoder in distributed mode."
|
|
7791
7799
|
);
|
|
7792
7800
|
}
|
|
7793
7801
|
if (config.browserGpuMode !== void 0 && config.browserGpuMode !== "software") {
|
|
@@ -8046,6 +8054,9 @@ async function runExtractVideosStage(input) {
|
|
|
8046
8054
|
} = input;
|
|
8047
8055
|
const stage2Start = Date.now();
|
|
8048
8056
|
const extractionPolicy = resolveVideoExtractionPolicy();
|
|
8057
|
+
composition.videos = composition.videos.filter(
|
|
8058
|
+
(video) => !isVideoPastTimelineEnd(video, composition.duration)
|
|
8059
|
+
);
|
|
8049
8060
|
let frameLookup = null;
|
|
8050
8061
|
let extractionResult = null;
|
|
8051
8062
|
let failureToEnforce = null;
|
|
@@ -8132,7 +8143,8 @@ async function runExtractVideosStage(input) {
|
|
|
8132
8143
|
timelineEnd: composition.duration,
|
|
8133
8144
|
maxTransientRetries: extractionPolicy.maxTransientRetries,
|
|
8134
8145
|
collectProbeFailures: extractionPolicy.failureMode === "enforce",
|
|
8135
|
-
deferRangeExtraction
|
|
8146
|
+
deferRangeExtraction,
|
|
8147
|
+
contentKeyedDirs: [join15(compiledDir, REMOTE_MEDIA_SUBDIR)]
|
|
8136
8148
|
},
|
|
8137
8149
|
abortSignal,
|
|
8138
8150
|
cfg,
|
|
@@ -9936,8 +9948,9 @@ function sanitizeProbeFailure(reason, paths) {
|
|
|
9936
9948
|
async function padOrTrimAudioToVideoFrameCount(input) {
|
|
9937
9949
|
const probeVideo = input.probeVideoFrameInfo ?? ((videoPath) => defaultProbeVideoFrameInfo(videoPath, input.signal));
|
|
9938
9950
|
const probeAudio = input.probeAudioInfo ?? defaultProbeAudioInfo;
|
|
9939
|
-
const
|
|
9940
|
-
const
|
|
9951
|
+
const timeoutMs = input.timeoutMs ?? DEFAULT_CONFIG.ffmpegProcessTimeout;
|
|
9952
|
+
const runner = input.runFfmpeg ?? ((args) => defaultRunFfmpeg(args, timeoutMs, input.signal));
|
|
9953
|
+
const probeTruePeak = input.probeAudioTruePeakDbfs ?? (input.runFfmpeg ? void 0 : (audioPath, signal) => defaultProbeAudioTruePeakDbfs(audioPath, timeoutMs, signal));
|
|
9941
9954
|
const [videoResult, audioResult] = await Promise.allSettled([
|
|
9942
9955
|
probeVideo(input.videoPath),
|
|
9943
9956
|
probeAudio(input.audioPath, input.signal)
|
|
@@ -10173,13 +10186,13 @@ async function defaultProbeAudioInfo(audioPath, signal) {
|
|
|
10173
10186
|
audioCodec: metadata.audioCodec
|
|
10174
10187
|
};
|
|
10175
10188
|
}
|
|
10176
|
-
async function defaultProbeAudioTruePeakDbfs(audioPath, signal) {
|
|
10189
|
+
async function defaultProbeAudioTruePeakDbfs(audioPath, timeoutMs, signal) {
|
|
10177
10190
|
const result = await runFfmpeg(
|
|
10178
10191
|
["-i", audioPath, "-map", "0:a:0", "-vn", "-af", "ebur128=peak=true", "-f", "null", "-"],
|
|
10179
|
-
{ signal }
|
|
10192
|
+
{ signal, timeout: timeoutMs }
|
|
10180
10193
|
);
|
|
10181
10194
|
if (!result.success) {
|
|
10182
|
-
throw new Error(`[audioPadTrim] ${
|
|
10195
|
+
throw new Error(`[audioPadTrim] ${describeFfmpegFailure(result, timeoutMs)}`);
|
|
10183
10196
|
}
|
|
10184
10197
|
const matches = [...result.stderr.matchAll(/^\s*Peak:\s*([+-]?(?:[\d.]+|inf)) dBFS$/gim)];
|
|
10185
10198
|
const token = matches.at(-1)?.[1]?.toLowerCase();
|
|
@@ -10189,12 +10202,12 @@ async function defaultProbeAudioTruePeakDbfs(audioPath, signal) {
|
|
|
10189
10202
|
}
|
|
10190
10203
|
return value;
|
|
10191
10204
|
}
|
|
10192
|
-
async function defaultRunFfmpeg(args, signal) {
|
|
10193
|
-
const result = await runFfmpeg(args, { signal });
|
|
10205
|
+
async function defaultRunFfmpeg(args, timeoutMs, signal) {
|
|
10206
|
+
const result = await runFfmpeg(args, { signal, timeout: timeoutMs });
|
|
10194
10207
|
if (result.success) return { success: true };
|
|
10195
10208
|
return {
|
|
10196
10209
|
success: false,
|
|
10197
|
-
error: `[audioPadTrim] ${
|
|
10210
|
+
error: `[audioPadTrim] ${describeFfmpegFailure(result, timeoutMs)}`,
|
|
10198
10211
|
failureReason: result.failureReason
|
|
10199
10212
|
};
|
|
10200
10213
|
}
|
|
@@ -10267,6 +10280,7 @@ async function assembleOutput(input, onSecondsWritten) {
|
|
|
10267
10280
|
outputPath,
|
|
10268
10281
|
hasAudio,
|
|
10269
10282
|
format,
|
|
10283
|
+
ffmpegProcessTimeout,
|
|
10270
10284
|
abortSignal,
|
|
10271
10285
|
assertNotAborted
|
|
10272
10286
|
} = input;
|
|
@@ -10280,7 +10294,8 @@ async function assembleOutput(input, onSecondsWritten) {
|
|
|
10280
10294
|
videoPath: videoOnlyPath,
|
|
10281
10295
|
audioPath: audioOutputPath,
|
|
10282
10296
|
outputPath: normalizedAudioPath,
|
|
10283
|
-
signal: abortSignal
|
|
10297
|
+
signal: abortSignal,
|
|
10298
|
+
timeoutMs: ffmpegProcessTimeout
|
|
10284
10299
|
});
|
|
10285
10300
|
assertNotAborted();
|
|
10286
10301
|
if (!normalizeResult.success) {
|
|
@@ -10296,7 +10311,8 @@ async function assembleOutput(input, onSecondsWritten) {
|
|
|
10296
10311
|
outputPath,
|
|
10297
10312
|
abortSignal,
|
|
10298
10313
|
{
|
|
10299
|
-
audioCodec: "aac"
|
|
10314
|
+
audioCodec: "aac",
|
|
10315
|
+
ffmpegProcessTimeout
|
|
10300
10316
|
},
|
|
10301
10317
|
job.config.fps,
|
|
10302
10318
|
onSecondsWritten
|
|
@@ -10313,7 +10329,7 @@ async function assembleOutput(input, onSecondsWritten) {
|
|
|
10313
10329
|
videoOnlyPath,
|
|
10314
10330
|
outputPath,
|
|
10315
10331
|
abortSignal,
|
|
10316
|
-
|
|
10332
|
+
{ ffmpegProcessTimeout },
|
|
10317
10333
|
job.config.fps,
|
|
10318
10334
|
onSecondsWritten
|
|
10319
10335
|
);
|
|
@@ -10331,7 +10347,8 @@ async function runHlsPackaging(input, normalizedAudioPath) {
|
|
|
10331
10347
|
input.outputPath,
|
|
10332
10348
|
{
|
|
10333
10349
|
segmentSeconds: input.hlsSegmentSeconds ?? DEFAULT_HLS_SEGMENT_SECONDS,
|
|
10334
|
-
signal: input.abortSignal
|
|
10350
|
+
signal: input.abortSignal,
|
|
10351
|
+
ffmpegProcessTimeout: input.ffmpegProcessTimeout
|
|
10335
10352
|
}
|
|
10336
10353
|
);
|
|
10337
10354
|
input.assertNotAborted();
|
|
@@ -10689,7 +10706,7 @@ async function executeDiskCaptureWithAdaptiveRetry(options) {
|
|
|
10689
10706
|
const madeProgress = captureAttemptMadeProgress(frameCount, remainingCount);
|
|
10690
10707
|
if (!madeProgress) {
|
|
10691
10708
|
options.log.warn(
|
|
10692
|
-
"[Render] Capture attempt made no forward progress; composition is likely structurally broken
|
|
10709
|
+
"[Render] Capture attempt made no forward progress; composition is likely structurally broken, not retrying.",
|
|
10693
10710
|
{ attempt, frameCount, remainingCount, workers: currentWorkers }
|
|
10694
10711
|
);
|
|
10695
10712
|
}
|
|
@@ -10758,7 +10775,7 @@ async function executeDiskCaptureWithAdaptiveRetry(options) {
|
|
|
10758
10775
|
}
|
|
10759
10776
|
if (!madeProgress) {
|
|
10760
10777
|
options.log.warn(
|
|
10761
|
-
"[Render] Capture attempt made no forward progress; composition is likely structurally broken
|
|
10778
|
+
"[Render] Capture attempt made no forward progress; composition is likely structurally broken, not retrying.",
|
|
10762
10779
|
{ attempt, frameCount, remainingCount, workers: currentWorkers }
|
|
10763
10780
|
);
|
|
10764
10781
|
}
|
|
@@ -10793,36 +10810,6 @@ function createRenderJob(config) {
|
|
|
10793
10810
|
warnings: []
|
|
10794
10811
|
};
|
|
10795
10812
|
}
|
|
10796
|
-
function normalizeCompositionSrcPath(srcPath) {
|
|
10797
|
-
return srcPath.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
10798
|
-
}
|
|
10799
|
-
function readSceneRootDuration(entryHtml) {
|
|
10800
|
-
if (!entryHtml) return null;
|
|
10801
|
-
const { document: document2 } = parseHTML(entryHtml);
|
|
10802
|
-
const template = document2.querySelector("template");
|
|
10803
|
-
const scope = template ? parseHTML(template.innerHTML).document : document2;
|
|
10804
|
-
const root = scope.querySelector("[data-composition-id]");
|
|
10805
|
-
return root?.getAttribute("data-duration") ?? null;
|
|
10806
|
-
}
|
|
10807
|
-
function createStandaloneEntryRenderClone(root, host, sceneDuration) {
|
|
10808
|
-
const hostClone = host.cloneNode(true);
|
|
10809
|
-
hostClone.setAttribute("data-start", "0");
|
|
10810
|
-
if (root === host) return hostClone;
|
|
10811
|
-
const rootClone = root.cloneNode(false);
|
|
10812
|
-
if (sceneDuration != null) {
|
|
10813
|
-
rootClone.setAttribute("data-duration", sceneDuration);
|
|
10814
|
-
} else {
|
|
10815
|
-
rootClone.removeAttribute("data-duration");
|
|
10816
|
-
}
|
|
10817
|
-
rootClone.appendChild(hostClone);
|
|
10818
|
-
return rootClone;
|
|
10819
|
-
}
|
|
10820
|
-
function replaceBodyWithRenderClone(body, renderClone) {
|
|
10821
|
-
while (body.firstChild) {
|
|
10822
|
-
body.removeChild(body.firstChild);
|
|
10823
|
-
}
|
|
10824
|
-
body.appendChild(renderClone);
|
|
10825
|
-
}
|
|
10826
10813
|
function explainStreamingEncodeGate(cfg, outputFormat, workerCount, durationSeconds, forceParallelStream = false) {
|
|
10827
10814
|
if (!cfg.enableStreamingEncode) return { enabled: false, reason: "disabled_by_config" };
|
|
10828
10815
|
if (outputFormat === "png-sequence" || outputFormat === "gif") {
|
|
@@ -11219,25 +11206,6 @@ function resolveCaptureForceScreenshotForPageSideCompositing(args) {
|
|
|
11219
11206
|
function shouldDiscardProbeSessionForPageSideCompositing(args) {
|
|
11220
11207
|
return args.hasProbeSession && args.usePageSideCompositing;
|
|
11221
11208
|
}
|
|
11222
|
-
function extractStandaloneEntryFromIndex(indexHtml, entryFile, entryHtml) {
|
|
11223
|
-
const normalizedEntryFile = normalizeCompositionSrcPath(entryFile);
|
|
11224
|
-
const { document: document2 } = parseHTML(indexHtml);
|
|
11225
|
-
const body = document2.querySelector("body");
|
|
11226
|
-
if (!body) return null;
|
|
11227
|
-
const hosts = Array.from(document2.querySelectorAll("[data-composition-src]"));
|
|
11228
|
-
const host = hosts.find(
|
|
11229
|
-
(candidate) => normalizeCompositionSrcPath(candidate.getAttribute("data-composition-src") || "") === normalizedEntryFile
|
|
11230
|
-
);
|
|
11231
|
-
if (!host) return null;
|
|
11232
|
-
const root = Array.from(body.children).find(
|
|
11233
|
-
(candidate) => candidate.hasAttribute("data-composition-id")
|
|
11234
|
-
) ?? null;
|
|
11235
|
-
if (!root) return null;
|
|
11236
|
-
const sceneDuration = readSceneRootDuration(entryHtml) ?? host.getAttribute("data-duration");
|
|
11237
|
-
const renderClone = createStandaloneEntryRenderClone(root, host, sceneDuration);
|
|
11238
|
-
replaceBodyWithRenderClone(body, renderClone);
|
|
11239
|
-
return document2.toString();
|
|
11240
|
-
}
|
|
11241
11209
|
function deVerifyFallbackTelemetry(err) {
|
|
11242
11210
|
const details = getDrawElementVerificationDetails(err);
|
|
11243
11211
|
return {
|
|
@@ -11270,7 +11238,7 @@ async function executeRenderJob(job, projectDir, outputPath, progressSink, abort
|
|
|
11270
11238
|
execution.defer("remove workDir", () => {
|
|
11271
11239
|
if (job.config.debug) return;
|
|
11272
11240
|
if (job.status === "complete" && process.env.KEEP_TEMP === "1") {
|
|
11273
|
-
log.info("KEEP_TEMP=1
|
|
11241
|
+
log.info("KEEP_TEMP=1, leaving workDir on disk for inspection", { workDir });
|
|
11274
11242
|
return;
|
|
11275
11243
|
}
|
|
11276
11244
|
rmSync8(workDir, { recursive: true, force: true, maxRetries: 3, retryDelay: 100 });
|
|
@@ -11422,7 +11390,7 @@ async function executeRenderPipeline(input) {
|
|
|
11422
11390
|
}
|
|
11423
11391
|
assertNotAborted();
|
|
11424
11392
|
const rawEntry = readFileSync7(htmlPath, "utf-8");
|
|
11425
|
-
if (entryFile !== "index.html" && rawEntry
|
|
11393
|
+
if (entryFile !== "index.html" && isTemplateEntry(rawEntry)) {
|
|
11426
11394
|
const wrapperPath = join25(workDir, "standalone-entry.html");
|
|
11427
11395
|
const projectIndexPath = join25(projectDir, "index.html");
|
|
11428
11396
|
if (!existsSync15(projectIndexPath)) {
|
|
@@ -11507,7 +11475,7 @@ async function executeRenderPipeline(input) {
|
|
|
11507
11475
|
captureForceScreenshot = true;
|
|
11508
11476
|
updateCaptureObservability({ forceScreenshot: captureForceScreenshot });
|
|
11509
11477
|
log.info(
|
|
11510
|
-
"[Render] Low-memory render profile active
|
|
11478
|
+
"[Render] Low-memory render profile active: screenshot capture, auto-worker calibration skipped" + (job.config.workers === void 0 ? ", pinned to 1 worker" : "") + ". Override with --no-low-memory-mode or PRODUCER_LOW_MEMORY_MODE=false.",
|
|
11511
11479
|
{ totalMemMb: getSystemTotalMb(), thresholdMb: LOW_MEMORY_TOTAL_MB_THRESHOLD }
|
|
11512
11480
|
);
|
|
11513
11481
|
}
|
|
@@ -12075,7 +12043,7 @@ async function executeRenderPipeline(input) {
|
|
|
12075
12043
|
cfg.useDrawElement = false;
|
|
12076
12044
|
deClampReason = workerCount > 1 ? "parallel" : "disk_path";
|
|
12077
12045
|
log.info(
|
|
12078
|
-
"[Render] Fast capture: default-on drawElement disabled for this render
|
|
12046
|
+
"[Render] Fast capture: default-on drawElement disabled for this render: " + (workerCount > 1 ? "parallel capture" : "the disk capture path") + " has no runtime self-verification. Set PRODUCER_EXPERIMENTAL_FAST_CAPTURE=true to override."
|
|
12079
12047
|
);
|
|
12080
12048
|
if (probeSession && probeSession.captureMode === "drawelement") {
|
|
12081
12049
|
lastBrowserConsole = probeSession.browserConsoleBuffer;
|
|
@@ -12171,7 +12139,7 @@ async function executeRenderPipeline(input) {
|
|
|
12171
12139
|
});
|
|
12172
12140
|
updateCaptureObservability({ forceScreenshot: captureForceScreenshot });
|
|
12173
12141
|
log.info(
|
|
12174
|
-
`[Render] Page-side compositing enabled
|
|
12142
|
+
`[Render] Page-side compositing enabled, bypassing Node-side layered shader-blend path. Engine will capture one ${needsAlpha ? "RGBA PNG" : "opaque RGB"} screenshot per output frame.`
|
|
12175
12143
|
);
|
|
12176
12144
|
}
|
|
12177
12145
|
const useLayeredComposite = !usePageSideCompositingForTransitions && shouldUseLayeredComposite({
|
|
@@ -12668,7 +12636,7 @@ async function executeRenderPipeline(input) {
|
|
|
12668
12636
|
cfg.useDrawElement = false;
|
|
12669
12637
|
deClampReason = deClampReason ?? "disk_path";
|
|
12670
12638
|
log.info(
|
|
12671
|
-
"[Render] Fast capture: drawElement disabled for the disk fallback
|
|
12639
|
+
"[Render] Fast capture: drawElement disabled for the disk fallback: streaming encoder spawn failed and the disk path has no runtime self-verification."
|
|
12672
12640
|
);
|
|
12673
12641
|
if (probeSession && probeSession.captureMode === "drawelement") {
|
|
12674
12642
|
lastBrowserConsole = probeSession.browserConsoleBuffer;
|
|
@@ -12840,6 +12808,7 @@ async function executeRenderPipeline(input) {
|
|
|
12840
12808
|
hasAudio,
|
|
12841
12809
|
format: outputFormat,
|
|
12842
12810
|
hlsSegmentSeconds,
|
|
12811
|
+
ffmpegProcessTimeout: cfg.ffmpegProcessTimeout,
|
|
12843
12812
|
abortSignal: executionSignal,
|
|
12844
12813
|
assertNotAborted,
|
|
12845
12814
|
onProgress
|
|
@@ -13206,10 +13175,10 @@ function validateJsonSafeValue(value, field) {
|
|
|
13206
13175
|
walkVariables(value, field, /* @__PURE__ */ new WeakSet());
|
|
13207
13176
|
}
|
|
13208
13177
|
var LEAF_REJECTIONS = {
|
|
13209
|
-
undefined: "undefined leaves are silently dropped by JSON.stringify
|
|
13178
|
+
undefined: "undefined leaves are silently dropped by JSON.stringify. Use null if you mean an absent value",
|
|
13210
13179
|
function: "functions are not JSON-serializable",
|
|
13211
13180
|
symbol: "Symbols are not JSON-serializable",
|
|
13212
|
-
bigint: "BigInt values throw at JSON.stringify
|
|
13181
|
+
bigint: "BigInt values throw at JSON.stringify. Encode as a string if you need 64-bit integers"
|
|
13213
13182
|
};
|
|
13214
13183
|
function walkVariables(value, path, seen) {
|
|
13215
13184
|
const t = typeof value;
|
|
@@ -13230,7 +13199,7 @@ function walkVariables(value, path, seen) {
|
|
|
13230
13199
|
if (seen.has(value)) {
|
|
13231
13200
|
throw new InvalidConfigError(
|
|
13232
13201
|
path,
|
|
13233
|
-
"circular reference detected
|
|
13202
|
+
"circular reference detected: JSON.stringify cannot serialize cycles"
|
|
13234
13203
|
);
|
|
13235
13204
|
}
|
|
13236
13205
|
seen.add(value);
|
|
@@ -13892,7 +13861,7 @@ function validateOutputResolutionOverride(body) {
|
|
|
13892
13861
|
return `Invalid outputResolution "${body.outputResolution}". Must be one of: landscape, portrait, landscape-4k, portrait-4k, square, square-4k (aliases: 1080p, 4k, \u2026).`;
|
|
13893
13862
|
}
|
|
13894
13863
|
if (normalized !== void 0 && (body.format === "webm" || body.format === "mov")) {
|
|
13895
|
-
return `outputResolution is not supported with format "${body.format}"
|
|
13864
|
+
return `outputResolution is not supported with format "${body.format}": the alpha (webm/mov) capture path can't supersample. Use format "mp4", or omit outputResolution to render at the composition's native dimensions.`;
|
|
13896
13865
|
}
|
|
13897
13866
|
return void 0;
|
|
13898
13867
|
}
|
|
@@ -14339,7 +14308,7 @@ function startServer(options = {}) {
|
|
|
14339
14308
|
});
|
|
14340
14309
|
async function shutdown(signal) {
|
|
14341
14310
|
log.info(`Received ${signal}, shutting down`);
|
|
14342
|
-
const { drainBrowserPool } = await import("./src-
|
|
14311
|
+
const { drainBrowserPool } = await import("./src-LIERUCFW.js");
|
|
14343
14312
|
await drainBrowserPool().catch(() => {
|
|
14344
14313
|
});
|
|
14345
14314
|
const handle = await Promise.race([
|
|
@@ -14599,7 +14568,7 @@ function collectPlanAssetShas(planDir) {
|
|
|
14599
14568
|
}
|
|
14600
14569
|
if (compositionHtml === null) {
|
|
14601
14570
|
throw new Error(
|
|
14602
|
-
`[freezePlan] compiled HTML missing at ${COMPILED_INDEX_RELATIVE_PATH}
|
|
14571
|
+
`[freezePlan] compiled HTML missing at ${COMPILED_INDEX_RELATIVE_PATH} (upstream compile stage did not materialize the expected file).`
|
|
14603
14572
|
);
|
|
14604
14573
|
}
|
|
14605
14574
|
return { compositionHtml, assets };
|
|
@@ -15178,7 +15147,7 @@ var PlanTooLargeError = class extends Error {
|
|
|
15178
15147
|
const breakdownSuffix = breakdown ? ` Breakdown: video-frames=${formatBytes(breakdown.videoFramesBytes)}, compiled=${formatBytes(breakdown.compiledBytes)} (source-media=${formatBytes(breakdown.sourceMediaBytes)}), audio=${formatBytes(breakdown.audioBytes)}, metadata=${formatBytes(breakdown.metadataBytes)}, other=${formatBytes(breakdown.otherBytes)}, files=${breakdown.fileCount}.` : "";
|
|
15179
15148
|
const observationSuffix = observedAt ? ` Observed at ${observedAt}.` : "";
|
|
15180
15149
|
super(
|
|
15181
|
-
`[plan] planDir size ${formatBytes(sizeBytes)} exceeds the configured ceiling ${formatBytes(limitBytes)} (PLAN_TOO_LARGE). The default 2 GB cap fits inside AWS Lambda's 10 GB /tmp budget alongside the chunk worker's frame buffer and ffmpeg's working set. To unblock: use the content-addressed \`planV2()\` transport, shorten the composition, lower the framerate, or use the in-process renderer (\`executeRenderJob\`)
|
|
15150
|
+
`[plan] planDir size ${formatBytes(sizeBytes)} exceeds the configured ceiling ${formatBytes(limitBytes)} (PLAN_TOO_LARGE). The default 2 GB cap fits inside AWS Lambda's 10 GB /tmp budget alongside the chunk worker's frame buffer and ffmpeg's working set. To unblock: use the content-addressed \`planV2()\` transport, shorten the composition, lower the framerate, or use the in-process renderer (\`executeRenderJob\`), which has no planDir size cap.` + observationSuffix + breakdownSuffix
|
|
15182
15151
|
);
|
|
15183
15152
|
this.name = "PlanTooLargeError";
|
|
15184
15153
|
this.sizeBytes = sizeBytes;
|
|
@@ -15195,7 +15164,7 @@ var FormatNotSupportedInDistributedError = class extends Error {
|
|
|
15195
15164
|
reason;
|
|
15196
15165
|
constructor(format, reason) {
|
|
15197
15166
|
super(
|
|
15198
|
-
`[plan] format ${JSON.stringify(format)} is not supported in distributed mode: ${reason}. Render with the in-process renderer (\`executeRenderJob\`)
|
|
15167
|
+
`[plan] format ${JSON.stringify(format)} is not supported in distributed mode: ${reason}. Render with the in-process renderer (\`executeRenderJob\`), which has full format support, or pick a distributed-supported format: mp4 SDR, mov ProRes 4444, png-sequence, or webm VP9.`
|
|
15199
15168
|
);
|
|
15200
15169
|
this.name = "FormatNotSupportedInDistributedError";
|
|
15201
15170
|
this.format = format;
|
|
@@ -15284,7 +15253,7 @@ async function readFontSnapshotSha() {
|
|
|
15284
15253
|
const data = module.EMBEDDED_FONT_DATA;
|
|
15285
15254
|
if (!data || typeof data !== "object") {
|
|
15286
15255
|
throw new Error(
|
|
15287
|
-
"[plan] EMBEDDED_FONT_DATA missing from @hyperframes/core/fonts/embedded-data
|
|
15256
|
+
"[plan] EMBEDDED_FONT_DATA missing from @hyperframes/core/fonts/embedded-data. Was `bun run build:fonts` run?"
|
|
15288
15257
|
);
|
|
15289
15258
|
}
|
|
15290
15259
|
const dataObj = data;
|
|
@@ -15334,7 +15303,7 @@ function resolveEncoderTriple(config) {
|
|
|
15334
15303
|
}
|
|
15335
15304
|
if (config.codec !== void 0) {
|
|
15336
15305
|
throw new Error(
|
|
15337
|
-
`[plan] DistributedRenderConfig.codec is only valid for format="mp4"; received codec=${JSON.stringify(config.codec)} with format=${JSON.stringify(config.format)}. Omit codec for non-mp4 formats
|
|
15306
|
+
`[plan] DistributedRenderConfig.codec is only valid for format="mp4"; received codec=${JSON.stringify(config.codec)} with format=${JSON.stringify(config.format)}. Omit codec for non-mp4 formats: mov is always ProRes 4444, webm is always libvpx-vp9, and png-sequence has no encoder.`
|
|
15338
15307
|
);
|
|
15339
15308
|
}
|
|
15340
15309
|
return resolveNonMp4EncoderTriple(config.format, config.quality ?? "standard");
|
|
@@ -15524,7 +15493,7 @@ async function buildLocalExecutionPlan(projectDir, config, executionPlanDir, opt
|
|
|
15524
15493
|
if (probeResult.fileServer) closeFileServerSafely(probeResult.fileServer, "plan", log);
|
|
15525
15494
|
if (probeResult.probeSession) {
|
|
15526
15495
|
try {
|
|
15527
|
-
const { closeCaptureSession: closeCaptureSession2 } = await import("./src-
|
|
15496
|
+
const { closeCaptureSession: closeCaptureSession2 } = await import("./src-LIERUCFW.js");
|
|
15528
15497
|
await closeCaptureSession2(probeResult.probeSession);
|
|
15529
15498
|
} catch (err) {
|
|
15530
15499
|
log.warn("[plan] probe session close failed", {
|
|
@@ -16546,6 +16515,7 @@ async function assemble(planDir, chunkPaths, audioPath, outputPath, options) {
|
|
|
16546
16515
|
const log = options?.logger ?? defaultLogger;
|
|
16547
16516
|
const abortSignal = options?.abortSignal;
|
|
16548
16517
|
const cfr = options?.cfr === true;
|
|
16518
|
+
const { ffmpegProcessTimeout } = resolveConfig();
|
|
16549
16519
|
const planJsonPath = join36(planDir, "plan.json");
|
|
16550
16520
|
const chunksJsonPath = join36(planDir, "meta", "chunks.json");
|
|
16551
16521
|
if (!existsSync24(planJsonPath)) {
|
|
@@ -16585,10 +16555,13 @@ async function assemble(planDir, chunkPaths, audioPath, outputPath, options) {
|
|
|
16585
16555
|
const remuxArgs = ["-i", chunkPaths[0], "-c", "copy", "-r", fpsArg];
|
|
16586
16556
|
appendRenderProvenanceArgs(remuxArgs, concatOutputPath);
|
|
16587
16557
|
remuxArgs.push("-y", concatOutputPath);
|
|
16588
|
-
const remuxResult = await runFfmpeg(remuxArgs, {
|
|
16558
|
+
const remuxResult = await runFfmpeg(remuxArgs, {
|
|
16559
|
+
signal: abortSignal,
|
|
16560
|
+
timeout: ffmpegProcessTimeout
|
|
16561
|
+
});
|
|
16589
16562
|
if (!remuxResult.success) {
|
|
16590
16563
|
throw encoderFailureError("[assemble] ffmpeg single-chunk remux failed", {
|
|
16591
|
-
error:
|
|
16564
|
+
error: describeFfmpegFailure(remuxResult, ffmpegProcessTimeout),
|
|
16592
16565
|
failureReason: remuxResult.failureReason
|
|
16593
16566
|
});
|
|
16594
16567
|
}
|
|
@@ -16611,10 +16584,13 @@ async function assemble(planDir, chunkPaths, audioPath, outputPath, options) {
|
|
|
16611
16584
|
];
|
|
16612
16585
|
appendRenderProvenanceArgs(concatArgs, concatOutputPath);
|
|
16613
16586
|
concatArgs.push("-y", concatOutputPath);
|
|
16614
|
-
const concatResult = await runFfmpeg(concatArgs, {
|
|
16587
|
+
const concatResult = await runFfmpeg(concatArgs, {
|
|
16588
|
+
signal: abortSignal,
|
|
16589
|
+
timeout: ffmpegProcessTimeout
|
|
16590
|
+
});
|
|
16615
16591
|
if (!concatResult.success) {
|
|
16616
16592
|
throw encoderFailureError("[assemble] ffmpeg concat-copy failed", {
|
|
16617
|
-
error:
|
|
16593
|
+
error: describeFfmpegFailure(concatResult, ffmpegProcessTimeout),
|
|
16618
16594
|
failureReason: concatResult.failureReason
|
|
16619
16595
|
});
|
|
16620
16596
|
}
|
|
@@ -16655,10 +16631,13 @@ async function assemble(planDir, chunkPaths, audioPath, outputPath, options) {
|
|
|
16655
16631
|
];
|
|
16656
16632
|
appendRenderProvenanceArgs(cfrArgs, cfrOutputPath);
|
|
16657
16633
|
cfrArgs.push("-y", cfrOutputPath);
|
|
16658
|
-
const cfrResult = await runFfmpeg(cfrArgs, {
|
|
16634
|
+
const cfrResult = await runFfmpeg(cfrArgs, {
|
|
16635
|
+
signal: abortSignal,
|
|
16636
|
+
timeout: ffmpegProcessTimeout
|
|
16637
|
+
});
|
|
16659
16638
|
if (!cfrResult.success) {
|
|
16660
16639
|
throw encoderFailureError("[assemble] ffmpeg cfr re-encode failed", {
|
|
16661
|
-
error:
|
|
16640
|
+
error: describeFfmpegFailure(cfrResult, ffmpegProcessTimeout),
|
|
16662
16641
|
failureReason: cfrResult.failureReason
|
|
16663
16642
|
});
|
|
16664
16643
|
}
|
|
@@ -16676,7 +16655,8 @@ async function assemble(planDir, chunkPaths, audioPath, outputPath, options) {
|
|
|
16676
16655
|
videoPath: postConcatPath,
|
|
16677
16656
|
audioPath,
|
|
16678
16657
|
outputPath: paddedAudioPath,
|
|
16679
|
-
signal: abortSignal
|
|
16658
|
+
signal: abortSignal,
|
|
16659
|
+
timeoutMs: ffmpegProcessTimeout
|
|
16680
16660
|
});
|
|
16681
16661
|
if (!padTrimResult.success) {
|
|
16682
16662
|
throw encoderFailureError("[assemble] audio pad/trim failed", padTrimResult);
|
|
@@ -16695,9 +16675,7 @@ async function assemble(planDir, chunkPaths, audioPath, outputPath, options) {
|
|
|
16695
16675
|
normalizedAudioPath,
|
|
16696
16676
|
muxOutputPath,
|
|
16697
16677
|
abortSignal,
|
|
16698
|
-
{
|
|
16699
|
-
audioCodec: "aac"
|
|
16700
|
-
},
|
|
16678
|
+
{ audioCodec: "aac", ffmpegProcessTimeout },
|
|
16701
16679
|
{ num: plan2.dimensions.fpsNum, den: plan2.dimensions.fpsDen }
|
|
16702
16680
|
);
|
|
16703
16681
|
if (!muxResult.success) {
|
|
@@ -16708,7 +16686,7 @@ async function assemble(planDir, chunkPaths, audioPath, outputPath, options) {
|
|
|
16708
16686
|
muxOutputPath,
|
|
16709
16687
|
outputPath,
|
|
16710
16688
|
abortSignal,
|
|
16711
|
-
|
|
16689
|
+
{ ffmpegProcessTimeout },
|
|
16712
16690
|
{
|
|
16713
16691
|
num: plan2.dimensions.fpsNum,
|
|
16714
16692
|
den: plan2.dimensions.fpsDen
|