hyperframes 0.8.192 → 0.8.194
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/dist/{add-TZU2UW7A.js → add-47UAIWY4.js} +12 -12
- package/dist/{animatedGifPrep-NLAXC3VV.js → animatedGifPrep-TFSQZWK6.js} +8 -7
- package/dist/api.js +18 -17
- package/dist/{asset-JAJXA6LB.js → asset-AU7PZHXA.js} +2 -2
- package/dist/{assetCataloger-4WTX3J4I.js → assetCataloger-HC5N6WPT.js} +8 -7
- package/dist/{audio-XLWC7JKS.js → audio-7AWMZWBM.js} +14 -13
- package/dist/{auth-5K6X3NPJ.js → auth-GXH3QNDJ.js} +1 -1
- package/dist/{autoUpdate-RNV7SKGB.js → autoUpdate-GVGP5O2I.js} +3 -3
- package/dist/{backgroundChecks-QXLVZVGX.js → backgroundChecks-IUJM2Q35.js} +3 -3
- package/dist/backgroundChecksWorker.js +3 -3
- package/dist/{batchRender-THKSPDZR.js → batchRender-3XS2Y2Y4.js} +4 -4
- package/dist/{beats-K7CGCFVL.js → beats-U64B4S7Z.js} +9 -9
- package/dist/{benchmark-PHRDIXNL.js → benchmark-2YUPAI76.js} +9 -9
- package/dist/{browser-GN6R5ZSK.js → browser-DBFH7KXM.js} +5 -5
- package/dist/{bundleWithLocalizedFonts-C325UNR4.js → bundleWithLocalizedFonts-XWL7KSQJ.js} +2 -2
- package/dist/{capture-BZ7APOGQ.js → capture-E4VW75NM.js} +2 -2
- package/dist/{capture-6UBQFHZQ.js → capture-YWH7BPBI.js} +13 -12
- package/dist/{captureCompositionFrame-VORSCTWC.js → captureCompositionFrame-IG6S2OHG.js} +13 -12
- package/dist/{catalog-PHU2RUZ3.js → catalog-LZIZLZ34.js} +12 -12
- package/dist/{catch-up-HCNRM46J.js → catch-up-ZVNPIACY.js} +4 -4
- package/dist/{check-TJ5ZLB4I.js → check-EKEOD4UM.js} +38 -37
- package/dist/{checkBrowser-DWP7ZXJ7.js → checkBrowser-MYH6HPHH.js} +33 -32
- package/dist/{chunk-XF77MK3J.js → chunk-2AJU7PZ6.js} +1 -1
- package/dist/chunk-2D5WP2NI.js +3901 -0
- package/dist/{chunk-FBVUAH7N.js → chunk-2OYYNKJ4.js} +1 -1
- package/dist/{chunk-R2U2G4OS.js → chunk-37IHQVNQ.js} +1 -1
- package/dist/{chunk-IMSI7IFW.js → chunk-3OSBSUN3.js} +18 -18
- package/dist/{chunk-RHYOWDI6.js → chunk-3S3CXF4W.js} +2 -2
- package/dist/{chunk-YMQQXPD5.js → chunk-452UK7E7.js} +5 -12
- package/dist/{chunk-L2YGSAOL.js → chunk-4FVNEXSV.js} +3 -3
- package/dist/{chunk-7UZC4N62.js → chunk-4GMDL4N5.js} +1 -1
- package/dist/{chunk-YWRQHRDY.js → chunk-4PIPQPCW.js} +7 -7
- package/dist/{chunk-J2ASTCU6.js → chunk-4VSV56F2.js} +2 -2
- package/dist/{chunk-NXMYHJAL.js → chunk-4VYPICIA.js} +29 -1
- package/dist/{chunk-QX4TB4NH.js → chunk-52YJKWV3.js} +379 -127
- package/dist/{chunk-GANST5K3.js → chunk-54PZ2EQZ.js} +1 -1
- package/dist/{chunk-5IPKQHOL.js → chunk-B3GG3HJB.js} +1 -1
- package/dist/{chunk-2MCXIY4B.js → chunk-B7RJV74O.js} +28 -11
- package/dist/{chunk-VOM2HLUI.js → chunk-BK5YCT54.js} +3 -3
- package/dist/{chunk-RWGASWT7.js → chunk-BL4U6U52.js} +1 -0
- package/dist/{chunk-T6O5OLN2.js → chunk-BYADARIC.js} +2 -2
- package/dist/{chunk-VNPADTDD.js → chunk-CEUBYYVJ.js} +2 -2
- package/dist/{chunk-JCDYDF54.js → chunk-CEZH4AQT.js} +12 -2
- package/dist/{chunk-BY6OQ6XP.js → chunk-CZNSLFYD.js} +3 -1
- package/dist/{chunk-SBBQFPCJ.js → chunk-DT3JESJ6.js} +1 -1
- package/dist/{chunk-3CXIX6XS.js → chunk-DVQDBWQG.js} +4 -4
- package/dist/{chunk-K2AKVYNR.js → chunk-EB3XXHNO.js} +2 -2
- package/dist/{chunk-3FV5BVWS.js → chunk-EY7GKVPS.js} +2 -2
- package/dist/{chunk-W24SZ5FL.js → chunk-F2ASNL2K.js} +6 -9
- package/dist/{chunk-ODBYZIOH.js → chunk-F3B7CE3Q.js} +14 -14
- package/dist/{chunk-E3P3LJG6.js → chunk-FLREUEHW.js} +28 -11
- package/dist/{chunk-6XVKMBUA.js → chunk-FUA22HO4.js} +1 -1
- package/dist/{chunk-AEXVVABM.js → chunk-GAFEU6AB.js} +13 -10
- package/dist/{chunk-DIKAPMMF.js → chunk-GQVTTWZF.js} +144 -39
- package/dist/{chunk-7LLRMYP6.js → chunk-HCLBM2LQ.js} +2 -2
- package/dist/{chunk-AMZJFCOX.js → chunk-HG5ECUOR.js} +5 -5
- package/dist/{chunk-KZOZN4PI.js → chunk-HPGQPRHY.js} +3 -3
- package/dist/{chunk-BPKLUHFT.js → chunk-HQD7ODQB.js} +5 -5
- package/dist/{chunk-SK7TR7BL.js → chunk-JU4T4VAA.js} +4 -4
- package/dist/{chunk-MGBUWPXX.js → chunk-JVTWX5G3.js} +33 -8
- package/dist/{chunk-2J3NA3OB.js → chunk-JXTPNUSO.js} +83 -51
- package/dist/{chunk-2VXY3PEF.js → chunk-K2VXPQKC.js} +107 -94
- package/dist/chunk-K4MJX7SR.js +17 -0
- package/dist/{chunk-XX2PA4L3.js → chunk-KDEV5RIE.js} +7 -3
- package/dist/{chunk-MVIJTXN5.js → chunk-LMIDZIW2.js} +12 -12
- package/dist/{chunk-6WNLQI63.js → chunk-LOGKDQ3G.js} +3 -3
- package/dist/{chunk-IW5G323T.js → chunk-LTGTN2TH.js} +8 -9
- package/dist/{chunk-MEE4NTPZ.js → chunk-LZ4WPR3B.js} +2 -2
- package/dist/{chunk-32NB4VMH.js → chunk-M2VXARYK.js} +3 -2
- package/dist/{chunk-7RSY7SZN.js → chunk-MCFPMUMT.js} +2 -2
- package/dist/{chunk-BEOK6F26.js → chunk-MGSNFWGR.js} +2 -2
- package/dist/{chunk-ZEMDV6W2.js → chunk-MO6RTNYD.js} +1 -1
- package/dist/{chunk-7JJMT6LN.js → chunk-N33FO44R.js} +1 -1
- package/dist/{chunk-A4OI5ZNX.js → chunk-N3M3IU6S.js} +1 -1
- package/dist/{chunk-CXRZBWSH.js → chunk-NVVIFW3C.js} +10 -10
- package/dist/{chunk-E5V6WEMK.js → chunk-O2ILONGK.js} +10 -10
- package/dist/{chunk-4HCJOFMB.js → chunk-OJNNKHAZ.js} +94 -22
- package/dist/{chunk-QWLES6YV.js → chunk-PEHST4UY.js} +3 -3
- package/dist/{chunk-BV6YE455.js → chunk-POFJH2IS.js} +1 -1
- package/dist/{chunk-AR46ND2Q.js → chunk-PXK3ICU6.js} +1 -1
- package/dist/{chunk-LOKCBZYF.js → chunk-Q4HKC3O7.js} +3 -3
- package/dist/{chunk-J2BSUF6X.js → chunk-QJQTWTM7.js} +8 -3
- package/dist/{chunk-QFPBRZJD.js → chunk-ROEW726S.js} +1 -1
- package/dist/{chunk-OQL4AJ4X.js → chunk-RUPGFW5B.js} +6 -6
- package/dist/{chunk-5TRFLZ5Z.js → chunk-RZWJJCI7.js} +2 -2
- package/dist/{chunk-2HP5GIQ3.js → chunk-SNECH6QA.js} +1 -1
- package/dist/{chunk-REUL2KH2.js → chunk-ST35C4K6.js} +1 -1
- package/dist/{chunk-4E75LHAL.js → chunk-ST4SHO3S.js} +1 -1
- package/dist/{chunk-ULTKB5FC.js → chunk-TDYKVJTU.js} +548 -429
- package/dist/{chunk-WOKVXK4J.js → chunk-VHIBBDEI.js} +1 -1
- package/dist/{chunk-EKGGSAWR.js → chunk-VPON6DF2.js} +5 -5
- package/dist/{chunk-VRAXIQ6I.js → chunk-XYGULBFV.js} +2 -2
- package/dist/{chunk-PFRG5P32.js → chunk-Y3BT27Y7.js} +1 -1
- package/dist/{clean-2RNCTDBT.js → clean-NS2SDRK7.js} +21 -20
- package/dist/cli.js +54 -54
- package/dist/{cloud-NFIKESNZ.js → cloud-K4XQPWTY.js} +4 -4
- package/dist/{cloudrun-7224BCX3.js → cloudrun-BKOKXTXV.js} +6 -6
- package/dist/{compare-HL44MXVX.js → compare-ZAV773OL.js} +31 -30
- package/dist/{compiler-WF5QTXV7.js → compiler-CWHFCE3H.js} +5 -5
- package/dist/{component-ZBZXSJBR.js → component-OXA2ZWX3.js} +3 -3
- package/dist/{compositions-76P7LDDX.js → compositions-NKRVWCPE.js} +12 -11
- package/dist/{contactSheet-43ISAESM.js → contactSheet-5APX35L3.js} +1 -1
- package/dist/{delete-4YZBYOHJ.js → delete-HZ2LBCLC.js} +2 -2
- package/dist/{deploy-UGUUGYLF.js → deploy-FNDTZFF7.js} +1 -1
- package/dist/{deterministicFonts-RO2TCMLZ.js → deterministicFonts-RADD3BSX.js} +2 -2
- package/dist/{dist-5KKCRFPT.js → dist-2YTN2UGY.js} +3 -3
- package/dist/{dist-QQ26RUDV.js → dist-7OCZHNLY.js} +1 -1
- package/dist/{doctor-GGVUK4NB.js → doctor-6QWJGO5P.js} +14 -13
- package/dist/{events-V2VU4J3B.js → events-HTHOBIUN.js} +3 -3
- package/dist/{events-OXPTHVDB.js → events-MBKHVGXX.js} +2 -2
- package/dist/{feedback-HFZ5SCUK.js → feedback-X5QWTLEX.js} +8 -8
- package/dist/{ffmpeg-3VHY7GO3.js → ffmpeg-7GESJCCT.js} +9 -8
- package/dist/{figma-7SEZTLBJ.js → figma-SXOHFVJI.js} +3 -3
- package/dist/fontLocalizeCli.js +11 -10
- package/dist/{get-Y2S2PXCM.js → get-T2HI5FCK.js} +2 -2
- package/dist/{gpuPolicy-UHPOWRV5.js → gpuPolicy-5FABKW5G.js} +8 -7
- package/dist/{grade-compare-4VTXSQM5.js → grade-compare-JATGHA6Q.js} +37 -35
- package/dist/{gsapParser-UP3PNPC2.js → gsapParser-IEUSLYDJ.js} +11 -11
- package/dist/{gsapParserAcorn-OOTY2MVN.js → gsapParserAcorn-LZJKCFQI.js} +1 -1
- package/dist/{help-HXNOACHI.js → help-G6CIKCGS.js} +1 -1
- package/dist/{history-XDJUI4LC.js → history-CSJUHYTD.js} +9 -8
- package/dist/hyperframe.manifest.json +1 -1
- package/dist/hyperframe.runtime.iife.js +71 -65
- package/dist/hyperframes-player.global.js +3 -3
- package/dist/hyperframes-slideshow.global.js +1 -1
- package/dist/{info-KYRI3EZV.js → info-MTTUMW2C.js} +8 -8
- package/dist/{init-IL7EWMT5.js → init-LJYNI5EK.js} +30 -29
- package/dist/{inspect-TBNH23UC.js → inspect-HGDM2VJE.js} +31 -30
- package/dist/{installer-O2YMFSI4.js → installer-3XHURUDG.js} +5 -5
- package/dist/{keyframes-4GF62KAJ.js → keyframes-MSU7N53X.js} +59 -33
- package/dist/{lambda-JFL6M4XZ.js → lambda-2I2TIUSD.js} +8 -8
- package/dist/{layout-7MAEFR65.js → layout-KWOXZMN7.js} +31 -30
- package/dist/{lint-4AYHKYAM.js → lint-N53TLHFG.js} +7 -7
- package/dist/{lintProject-52SLJPRC.js → lintProject-EOUZA4EG.js} +1 -1
- package/dist/{list-3DP3D3MW.js → list-SHYPQC7U.js} +2 -2
- package/dist/{login-T54WQYRQ.js → login-TEB6PA3Y.js} +4 -4
- package/dist/{manager-MZIJY73J.js → manager-COSJVRAE.js} +2 -2
- package/dist/{manager-QROK2IH3.js → manager-PLRSZH5G.js} +10 -9
- package/dist/{media-treatment-4CXF7MSG.js → media-treatment-XTUKMIGE.js} +15 -14
- package/dist/{models-IS3I6JKU.js → models-4WKAPP2L.js} +14 -13
- package/dist/{motionShot-DVYJZOTQ.js → motionShot-PTKB4ILH.js} +17 -16
- package/dist/{normalize-audio-4527JIK4.js → normalize-audio-3NG326I2.js} +6 -6
- package/dist/{open-5JE46SAX.js → open-6S2LMF7R.js} +12 -12
- package/dist/{parakeetRunner-7JIJGJJ7.js → parakeetRunner-OEI35DVO.js} +15 -14
- package/dist/{pipeline-YEN3WFD2.js → pipeline-543FUKH4.js} +10 -9
- package/dist/{play-WFX67I7M.js → play-ETEGHP3B.js} +21 -21
- package/dist/{preflight-D377HVUZ.js → preflight-Y5IYUF2T.js} +11 -10
- package/dist/{present-XTSEKAC7.js → present-ZRSLMJ6J.js} +17 -17
- package/dist/{preview-5XH7EK6O.js → preview-CEJ3SVTY.js} +100 -65
- package/dist/{producer-TFFYF4ZM.js → producer-JFVFIV26.js} +1 -1
- package/dist/{projectConfig-6YUJHMCL.js → projectConfig-7EK3BS72.js} +7 -7
- package/dist/{publication-JK33Y55E.js → publication-Y54GYFMV.js} +3 -3
- package/dist/{publish-JHDGXWXU.js → publish-S3UJTPCV.js} +10 -10
- package/dist/{remove-background-P44MYAPJ.js → remove-background-YTATNQSI.js} +11 -10
- package/dist/{render-RBINWWP5.js → render-IIPXMSBO.js} +35 -34
- package/dist/{render-RJ3I4E3A.js → render-RN3W6YL4.js} +17 -16
- package/dist/{render-HJ34EGMN.js → render-WNIG4B3J.js} +6 -6
- package/dist/{render-batch-3D6XQYUC.js → render-batch-OYS3UQDB.js} +6 -6
- package/dist/renderSetupWorker.js +42 -4
- package/dist/{resolver-HCLTFZUW.js → resolver-OVCXVEDX.js} +5 -5
- package/dist/{sherpa-IPOUJM6Q.js → sherpa-NCSFD7S3.js} +14 -13
- package/dist/skills/hyperframes/references/format.md +1 -0
- package/dist/skills/media-use/scripts/lib/duck.mjs +18 -2
- package/dist/skills/media-use/scripts/lib/duck.test.mjs +79 -0
- package/dist/{skills-P67QEERC.js → skills-IUV3K3X7.js} +5 -5
- package/dist/{skillsUpdateCheck-IFMLRVIF.js → skillsUpdateCheck-NACBXMWW.js} +3 -3
- package/dist/{snapshot-4YM4NNWJ.js → snapshot-7S5USJ2I.js} +52 -46
- package/dist/{src-DCD3YMXX.js → src-CAR6PHI4.js} +10 -9
- package/dist/{src-SSV66L3F.js → src-HITT6NWG.js} +19 -6
- package/dist/{staticProjectServer-C7PPGLEQ.js → staticProjectServer-QR6VZBPT.js} +18 -18
- package/dist/studio/assets/{hyperframes-player-ChN3cOr0.js → hyperframes-player-DLOUZUct.js} +1 -1
- package/dist/studio/assets/{index-CHu83hHM.js → index-CAQ7OcNJ.js} +163 -163
- package/dist/studio/assets/{index-BYbFcRR0.js → index-D9kA6JUX.js} +1 -1
- package/dist/studio/index.html +1 -1
- package/dist/{studio-api-6YZ7PIQR.js → studio-api-HVNOJILH.js} +13 -11
- package/dist/{studioServer-EWHSE4GC.js → studioServer-3BG5FRJL.js} +53 -52
- package/dist/{telemetry-GGLBHZRZ.js → telemetry-PET2GFQG.js} +3 -3
- package/dist/{timeline-NKHQJXJ2.js → timeline-PVIC2Z5K.js} +20 -19
- package/dist/{tokens-FWNNDJ6R.js → tokens-4N46PWSF.js} +2 -2
- package/dist/{transcribe-TRPKXZ7L.js → transcribe-2DVBS7MH.js} +19 -18
- package/dist/{transcribe-VD2TMMC2.js → transcribe-IDC7JTM4.js} +13 -12
- package/dist/{updateCheck-CUPS6LU3.js → updateCheck-QRDVXU7I.js} +2 -2
- package/dist/{upgrade-23XO6MEX.js → upgrade-5CNE3TBH.js} +2 -2
- package/dist/{urlDownloader-YOAOONCK.js → urlDownloader-P2I25DFC.js} +7 -6
- package/dist/{validate-BWIW24G5.js → validate-CLR5PEOV.js} +25 -24
- package/dist/{video-XRXJS4GC.js → video-3CKZZBOB.js} +8 -7
- package/dist/warmCheck.js +38 -37
- package/package.json +1 -1
- package/dist/chunk-B2XLXD7V.js +0 -3897
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
EncoderInterruptedError,
|
|
9
9
|
encoderFailureError,
|
|
10
10
|
prepareAnimatedGifInputs
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-452UK7E7.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-
|
|
19
|
+
} from "./chunk-ROEW726S.js";
|
|
20
20
|
import {
|
|
21
21
|
parseEncoderOptions
|
|
22
22
|
} from "./chunk-KLIKCX6Q.js";
|
|
@@ -74,6 +74,7 @@ import {
|
|
|
74
74
|
createFrameReorderBuffer,
|
|
75
75
|
createVideoFrameInjector,
|
|
76
76
|
declareContentAddressedUrl,
|
|
77
|
+
declareProbeFactsUrl,
|
|
77
78
|
decodePng,
|
|
78
79
|
decodePngToRgb48le,
|
|
79
80
|
deriveBeginFrameProbeTimeTicks,
|
|
@@ -137,6 +138,7 @@ import {
|
|
|
137
138
|
readWebGlVendorInfoFromCanvas,
|
|
138
139
|
recaptureDrawElementFrameForVerify,
|
|
139
140
|
removeDomLayerMask,
|
|
141
|
+
renameWithRetry,
|
|
140
142
|
resampleRgb48leObjectFit,
|
|
141
143
|
resolveBrowserGpuMode,
|
|
142
144
|
resolveConfig,
|
|
@@ -156,8 +158,9 @@ import {
|
|
|
156
158
|
trackChildProcess,
|
|
157
159
|
validateEngineConfigSnapshot,
|
|
158
160
|
verifyDiskDrawElementSamples,
|
|
161
|
+
videoAudioId,
|
|
159
162
|
writeCapturedFrame
|
|
160
|
-
} from "./chunk-
|
|
163
|
+
} from "./chunk-52YJKWV3.js";
|
|
161
164
|
import {
|
|
162
165
|
DISTRIBUTED_FPS,
|
|
163
166
|
HF_VFX_ATTR,
|
|
@@ -172,7 +175,7 @@ import {
|
|
|
172
175
|
parseVfxChain,
|
|
173
176
|
resolveAuthoredTimingWindow,
|
|
174
177
|
toFps
|
|
175
|
-
} from "./chunk-
|
|
178
|
+
} from "./chunk-JVTWX5G3.js";
|
|
176
179
|
import {
|
|
177
180
|
assignBundledRuntimeCompositionIds,
|
|
178
181
|
buildVariablesByCompScript,
|
|
@@ -182,10 +185,9 @@ import {
|
|
|
182
185
|
ensureExternalScriptTag,
|
|
183
186
|
extractStandaloneEntryFromIndex,
|
|
184
187
|
inlineSubCompositions,
|
|
185
|
-
isTemplateEntry,
|
|
186
188
|
parsesAsScript,
|
|
187
189
|
prepareFlattenedInnerRoot
|
|
188
|
-
} from "./chunk-
|
|
190
|
+
} from "./chunk-GAFEU6AB.js";
|
|
189
191
|
import {
|
|
190
192
|
COMPOSITION_SOURCE_URL,
|
|
191
193
|
HF_COLOR_GRADING_ATTR,
|
|
@@ -203,17 +205,20 @@ import {
|
|
|
203
205
|
insertBeforeCloseTag,
|
|
204
206
|
isJavaScriptType,
|
|
205
207
|
isRuntimeFileUrl,
|
|
208
|
+
isTemplateEntry,
|
|
206
209
|
normalizeRateSpec,
|
|
207
210
|
parseHostVariableValues,
|
|
208
211
|
parseStrictFiniteTimingNumber,
|
|
209
212
|
readDeclaredDefaults,
|
|
210
213
|
readMediaStart,
|
|
211
214
|
resolveNaturalMediaTimelineDurationFromValues,
|
|
215
|
+
resolveRateSpec,
|
|
212
216
|
shiftRateLane,
|
|
213
217
|
shouldClampResolvedMediaDuration,
|
|
214
218
|
sourceTimeAt,
|
|
215
|
-
styleElementsFor
|
|
216
|
-
|
|
219
|
+
styleElementsFor,
|
|
220
|
+
timeAtSourceTime
|
|
221
|
+
} from "./chunk-2D5WP2NI.js";
|
|
217
222
|
import {
|
|
218
223
|
MAX_AUDIO_GAIN
|
|
219
224
|
} from "./chunk-X7HBSTCZ.js";
|
|
@@ -227,7 +232,7 @@ import {
|
|
|
227
232
|
isAspectAgnosticResolutionAlias,
|
|
228
233
|
normalizeResolutionFlag,
|
|
229
234
|
suggestMatchingPreset
|
|
230
|
-
} from "./chunk-
|
|
235
|
+
} from "./chunk-B7RJV74O.js";
|
|
231
236
|
import {
|
|
232
237
|
TRANSITIONS,
|
|
233
238
|
convertTransfer,
|
|
@@ -243,7 +248,7 @@ import {
|
|
|
243
248
|
import {
|
|
244
249
|
lintHyperframeHtml,
|
|
245
250
|
resolveReferencedStart
|
|
246
|
-
} from "./chunk-
|
|
251
|
+
} from "./chunk-K2VXPQKC.js";
|
|
247
252
|
import {
|
|
248
253
|
isUnresolvedAssetPlaceholder,
|
|
249
254
|
readProjectFile,
|
|
@@ -262,6 +267,7 @@ import {
|
|
|
262
267
|
CSS_URL_RE,
|
|
263
268
|
decodedUrlPath,
|
|
264
269
|
isNonRelativeUrl,
|
|
270
|
+
readPlaybackRate,
|
|
265
271
|
rewriteAssetPaths,
|
|
266
272
|
rewriteCssAssetUrls,
|
|
267
273
|
rewriteInlineStyleAssetUrls
|
|
@@ -1570,16 +1576,7 @@ var RenderExecutionContext = class {
|
|
|
1570
1576
|
};
|
|
1571
1577
|
|
|
1572
1578
|
// ../producer/src/services/render/artifactTransaction.ts
|
|
1573
|
-
import {
|
|
1574
|
-
closeSync as closeSync2,
|
|
1575
|
-
existsSync as existsSync5,
|
|
1576
|
-
fstatSync as fstatSync2,
|
|
1577
|
-
openSync as openSync2,
|
|
1578
|
-
readSync,
|
|
1579
|
-
readdirSync as readdirSync2,
|
|
1580
|
-
renameSync,
|
|
1581
|
-
rmSync as rmSync3
|
|
1582
|
-
} from "fs";
|
|
1579
|
+
import { closeSync as closeSync2, existsSync as existsSync5, fstatSync as fstatSync2, openSync as openSync2, readSync, readdirSync as readdirSync2, rmSync as rmSync3 } from "fs";
|
|
1583
1580
|
import { basename as basename3, dirname as dirname4, extname as extname2, join as join5, resolve as resolve4 } from "path";
|
|
1584
1581
|
|
|
1585
1582
|
// ../producer/src/services/render/renderDirOwner.ts
|
|
@@ -1692,7 +1689,7 @@ function createRenderWorkDir(prefix, outputDir) {
|
|
|
1692
1689
|
// ../producer/src/services/render/artifactTransaction.ts
|
|
1693
1690
|
var defaultFileSystem = {
|
|
1694
1691
|
existsSync: existsSync5,
|
|
1695
|
-
renameSync,
|
|
1692
|
+
renameSync: (source, destination) => renameWithRetry(source, destination),
|
|
1696
1693
|
rmSync: rmSync3
|
|
1697
1694
|
};
|
|
1698
1695
|
async function defaultArtifactDurationProbe(path) {
|
|
@@ -1770,8 +1767,11 @@ function assertDurationWithinTolerance(expectedSeconds, probedSeconds, tolerance
|
|
|
1770
1767
|
`Render artifact is truncated: expected ${expectedSeconds.toFixed(3)}s, probed ${probedSeconds.toFixed(3)}s (deficit ${deficit.toFixed(3)}s exceeds tolerance ${toleranceSeconds.toFixed(3)}s). Artifact: ${stagingPath}`
|
|
1771
1768
|
);
|
|
1772
1769
|
}
|
|
1770
|
+
function hasUsableFrameCount(frames) {
|
|
1771
|
+
return frames !== void 0 && Number.isFinite(frames) && frames > 0;
|
|
1772
|
+
}
|
|
1773
1773
|
function assertFrameCountWithinTolerance(expectedFrames, probedFrames, stagingPath, toleranceFrames = 1) {
|
|
1774
|
-
if (
|
|
1774
|
+
if (!hasUsableFrameCount(probedFrames)) {
|
|
1775
1775
|
return;
|
|
1776
1776
|
}
|
|
1777
1777
|
const shortfall = expectedFrames - probedFrames;
|
|
@@ -1791,9 +1791,10 @@ function assertSizeMatches(expected, probed, stagingPath) {
|
|
|
1791
1791
|
);
|
|
1792
1792
|
}
|
|
1793
1793
|
var ArtifactTransaction = class {
|
|
1794
|
-
constructor(destinationPath, kind, fileSystem = defaultFileSystem, durationProbe = defaultArtifactDurationProbe) {
|
|
1794
|
+
constructor(destinationPath, kind, fileSystem = defaultFileSystem, durationProbe = defaultArtifactDurationProbe, logger = defaultLogger) {
|
|
1795
1795
|
this.kind = kind;
|
|
1796
1796
|
this.fileSystem = fileSystem;
|
|
1797
|
+
this.logger = logger;
|
|
1797
1798
|
this.destinationPath = resolve4(destinationPath);
|
|
1798
1799
|
this.transactionDirectory = createSiblingTransactionDirectory(this.destinationPath);
|
|
1799
1800
|
this.stagingPath = join5(this.transactionDirectory, basename3(this.destinationPath));
|
|
@@ -1802,6 +1803,7 @@ var ArtifactTransaction = class {
|
|
|
1802
1803
|
}
|
|
1803
1804
|
kind;
|
|
1804
1805
|
fileSystem;
|
|
1806
|
+
logger;
|
|
1805
1807
|
destinationPath;
|
|
1806
1808
|
stagingPath;
|
|
1807
1809
|
transactionDirectory;
|
|
@@ -1878,6 +1880,19 @@ var ArtifactTransaction = class {
|
|
|
1878
1880
|
probePath
|
|
1879
1881
|
);
|
|
1880
1882
|
if (expected.expectedFrames !== void 0) {
|
|
1883
|
+
if (!hasUsableFrameCount(probed.frames)) {
|
|
1884
|
+
try {
|
|
1885
|
+
this.logger.debug(
|
|
1886
|
+
"[Render] Frame-count validation skipped: no usable frame count was reported.",
|
|
1887
|
+
{
|
|
1888
|
+
event: "artifact_frame_count_unavailable",
|
|
1889
|
+
artifact: this.destinationPath,
|
|
1890
|
+
expectedFrames: expected.expectedFrames
|
|
1891
|
+
}
|
|
1892
|
+
);
|
|
1893
|
+
} catch {
|
|
1894
|
+
}
|
|
1895
|
+
}
|
|
1881
1896
|
assertFrameCountWithinTolerance(expected.expectedFrames, probed.frames, probePath);
|
|
1882
1897
|
}
|
|
1883
1898
|
assertSizeMatches(expected, probed, probePath);
|
|
@@ -2079,36 +2094,8 @@ function replanAfterFailure(plan2, failure) {
|
|
|
2079
2094
|
import { existsSync as existsSync6, mkdirSync as mkdirSync3, rmSync as rmSync5, statSync as statSync2 } from "fs";
|
|
2080
2095
|
import { join as join9 } from "path";
|
|
2081
2096
|
|
|
2082
|
-
// ../producer/src/services/render/
|
|
2083
|
-
|
|
2084
|
-
browserConsole;
|
|
2085
|
-
constructor(input) {
|
|
2086
|
-
const classified = classifyCaptureFailure(input.cause);
|
|
2087
|
-
super({
|
|
2088
|
-
kind: classified.kind,
|
|
2089
|
-
message: normalizeErrorMessage(input.cause),
|
|
2090
|
-
cause: input.cause,
|
|
2091
|
-
workerDiagnostics: classified.workerDiagnostics
|
|
2092
|
-
});
|
|
2093
|
-
this.name = "CaptureStageError";
|
|
2094
|
-
this.browserConsole = input.browserConsole.slice();
|
|
2095
|
-
if (input.cause instanceof Error && input.cause.stack) {
|
|
2096
|
-
this.stack = input.cause.stack;
|
|
2097
|
-
}
|
|
2098
|
-
}
|
|
2099
|
-
};
|
|
2100
|
-
function wrapCaptureStageError(error, browserConsole) {
|
|
2101
|
-
if (error instanceof CaptureStageError || error instanceof EncoderInterruptedError) return error;
|
|
2102
|
-
return new CaptureStageError({ cause: error, browserConsole });
|
|
2103
|
-
}
|
|
2104
|
-
function getCaptureStageBrowserConsole(error) {
|
|
2105
|
-
if (error instanceof CaptureStageError) return error.browserConsole;
|
|
2106
|
-
return [];
|
|
2107
|
-
}
|
|
2108
|
-
|
|
2109
|
-
// ../producer/src/services/hdrCompositor.ts
|
|
2110
|
-
import { readSync as readSync2, closeSync as closeSync3 } from "fs";
|
|
2111
|
-
import { join as join6 } from "path";
|
|
2097
|
+
// ../producer/src/services/render/perfSummary.ts
|
|
2098
|
+
import { arch, cpus, platform, totalmem } from "os";
|
|
2112
2099
|
|
|
2113
2100
|
// ../producer/src/services/render/hdrPerf.ts
|
|
2114
2101
|
function createHdrPerfCollector() {
|
|
@@ -2214,7 +2201,257 @@ function finalizeHdrPerf(perf) {
|
|
|
2214
2201
|
};
|
|
2215
2202
|
}
|
|
2216
2203
|
|
|
2204
|
+
// ../producer/src/services/render/perfSummary.ts
|
|
2205
|
+
function worstSubTimelineWaitOutcome(perfs) {
|
|
2206
|
+
const outcomes = perfs.map((p) => p.subTimelineWaitOutcome).filter((o) => !!o);
|
|
2207
|
+
if (outcomes.length === 0) return void 0;
|
|
2208
|
+
if (outcomes.includes("script_failure")) return "script_failure";
|
|
2209
|
+
if (outcomes.includes("timeout")) return "timeout";
|
|
2210
|
+
return "ready";
|
|
2211
|
+
}
|
|
2212
|
+
function pushWorkerDedupPerfs(results, sink) {
|
|
2213
|
+
for (const r of results) {
|
|
2214
|
+
if (r.perf) sink.push(r.perf);
|
|
2215
|
+
}
|
|
2216
|
+
}
|
|
2217
|
+
function pushWorkerPageErrors(results, sink) {
|
|
2218
|
+
for (const result of results) {
|
|
2219
|
+
for (const line of result.pageErrorLines ?? []) if (!sink.includes(line)) sink.push(line);
|
|
2220
|
+
}
|
|
2221
|
+
}
|
|
2222
|
+
function withWorkerPageErrors(consoleLines, workerLines) {
|
|
2223
|
+
return [...consoleLines, ...workerLines.filter((line) => !consoleLines.includes(line))];
|
|
2224
|
+
}
|
|
2225
|
+
function roundDb(value) {
|
|
2226
|
+
return value === void 0 ? void 0 : Math.round(Math.min(value, 999) * 10) / 10;
|
|
2227
|
+
}
|
|
2228
|
+
function aggregateDrawElement(perfs, de) {
|
|
2229
|
+
if (perfs.length === 0) return void 0;
|
|
2230
|
+
const modes = [...new Set(perfs.map((p) => p.captureMode).filter(Boolean))].sort();
|
|
2231
|
+
const gateReasons = [
|
|
2232
|
+
...new Set(
|
|
2233
|
+
[de.probeGateReason, ...perfs.map((p) => p.deGateReason)].filter((r) => !!r)
|
|
2234
|
+
)
|
|
2235
|
+
].sort();
|
|
2236
|
+
const gpuRenderers = [
|
|
2237
|
+
...new Set(perfs.map((p) => p.gpuRenderer).filter((r) => !!r))
|
|
2238
|
+
].sort();
|
|
2239
|
+
const drain = de.drainStats;
|
|
2240
|
+
return {
|
|
2241
|
+
mode: modes.join("|") || "unknown",
|
|
2242
|
+
compileGate: de.compileGate,
|
|
2243
|
+
clampReason: de.clampReason,
|
|
2244
|
+
workerInversion: de.workerInversion ?? "none",
|
|
2245
|
+
preInversionWorkers: de.preInversionWorkers,
|
|
2246
|
+
compositionElementCount: de.compositionElementCount,
|
|
2247
|
+
compositionElementCountSource: de.compositionElementCountSource,
|
|
2248
|
+
compositionElementTags: de.compositionElementTags,
|
|
2249
|
+
arollVideoCount: de.arollVideoCount,
|
|
2250
|
+
heygenVideoCount: de.heygenVideoCount,
|
|
2251
|
+
adaptersUsed: de.adaptersUsed,
|
|
2252
|
+
audioCount: de.audioCount,
|
|
2253
|
+
imageCount: de.imageCount,
|
|
2254
|
+
subCompositionCount: de.subCompositionCount,
|
|
2255
|
+
audioGroupCount: de.audioGroupCount,
|
|
2256
|
+
colorGradingCount: de.colorGradingCount,
|
|
2257
|
+
hasLut: de.hasLut,
|
|
2258
|
+
rootBodyMismatch: de.rootBodyMismatch,
|
|
2259
|
+
rootBodyDeltaPxBucket: de.rootBodyDeltaPxBucket,
|
|
2260
|
+
vfxHostCount: de.vfxHostCount,
|
|
2261
|
+
vfxCapture: de.vfxCapture,
|
|
2262
|
+
vfxTypes: de.vfxTypes,
|
|
2263
|
+
shortBand: de.shortBand,
|
|
2264
|
+
parallelRouter: de.parallelRouter ?? "none",
|
|
2265
|
+
preRouterWorkers: de.preRouterWorkers,
|
|
2266
|
+
gateReason: gateReasons.length > 0 ? gateReasons.join("|") : void 0,
|
|
2267
|
+
gpuRenderer: gpuRenderers.length > 0 ? gpuRenderers.join("|") : void 0,
|
|
2268
|
+
workerEncode: perfs.some((p) => p.deWorkerEncode),
|
|
2269
|
+
verifyArmed: perfs.reduce((sum2, p) => sum2 + (p.deVerifyArmed ?? 0), 0),
|
|
2270
|
+
verifyChecked: drain?.verifyChecked ?? 0,
|
|
2271
|
+
verifyMinDb: roundDb(drain?.verifyMinDb),
|
|
2272
|
+
verifyInitMs: perfs.reduce((sum2, p) => sum2 + (p.deVerifyInitMs ?? 0), 0),
|
|
2273
|
+
selfVerifyFallback: de.selfVerifyFallback,
|
|
2274
|
+
fallbackReason: de.fallbackReason,
|
|
2275
|
+
fallbackFailedDb: roundDb(de.fallbackFailedDb),
|
|
2276
|
+
fallbackFrameIndex: de.fallbackFrameIndex,
|
|
2277
|
+
fallbackThresholdDb: roundDb(de.fallbackThresholdDb),
|
|
2278
|
+
blankSuspects: drain?.blankSuspects ?? 0,
|
|
2279
|
+
blankDeterministicAccepts: drain?.blankDeterministicAccepts ?? 0,
|
|
2280
|
+
blankRecaptures: drain?.blankRecaptures ?? 0,
|
|
2281
|
+
boundaryFrames: perfs.reduce((sum2, p) => sum2 + (p.deBoundaryFrames ?? 0), 0),
|
|
2282
|
+
ncprFallbacks: perfs.reduce((sum2, p) => sum2 + (p.deNcprFallbacks ?? 0), 0),
|
|
2283
|
+
frameTimeouts: perfs.reduce((sum2, p) => sum2 + (p.deFrameTimeouts ?? 0), 0)
|
|
2284
|
+
};
|
|
2285
|
+
}
|
|
2286
|
+
function maxDefined(values) {
|
|
2287
|
+
const present = values.filter((v) => typeof v === "number");
|
|
2288
|
+
return present.length > 0 ? Math.max(...present) : void 0;
|
|
2289
|
+
}
|
|
2290
|
+
function aggregateChromeMemory(perfs) {
|
|
2291
|
+
const sampled = perfs.filter((p) => (p.chromeMemorySamples ?? 0) > 0);
|
|
2292
|
+
if (sampled.length === 0) return void 0;
|
|
2293
|
+
return {
|
|
2294
|
+
browserRssPeakMb: maxDefined(sampled.map((p) => p.chromeBrowserRssPeakMb)),
|
|
2295
|
+
rendererRssPeakMb: maxDefined(sampled.map((p) => p.chromeRendererRssPeakMb)),
|
|
2296
|
+
// Last samples are per session; summing approximates the whole fleet's
|
|
2297
|
+
// footprint at the end of capture (workers run concurrently).
|
|
2298
|
+
rssLastMb: sampled.reduce((sum2, p) => sum2 + (p.chromeRssLastMb ?? 0), 0),
|
|
2299
|
+
gpuProcessSeenLastSample: sampled.some((p) => p.chromeGpuProcessSeenLastSample === true),
|
|
2300
|
+
samples: sampled.reduce((sum2, p) => sum2 + (p.chromeMemorySamples ?? 0), 0)
|
|
2301
|
+
};
|
|
2302
|
+
}
|
|
2303
|
+
function aggregateDedup(perfs) {
|
|
2304
|
+
if (perfs.length === 0) return void 0;
|
|
2305
|
+
const armed = perfs.some((p) => p.staticDedupArmed);
|
|
2306
|
+
const skipReasons = armed ? [] : [
|
|
2307
|
+
...new Set(perfs.map((p) => p.staticDedupSkipReason).filter((r) => !!r))
|
|
2308
|
+
].sort();
|
|
2309
|
+
const verificationPerfs = perfs.filter((perf) => perf.staticDedupVerificationOutcome);
|
|
2310
|
+
const verificationOutcomes = [
|
|
2311
|
+
...new Set(
|
|
2312
|
+
verificationPerfs.map((perf) => perf.staticDedupVerificationOutcome).filter((outcome) => outcome != null)
|
|
2313
|
+
)
|
|
2314
|
+
].sort();
|
|
2315
|
+
return {
|
|
2316
|
+
enabled: perfs.some((p) => p.staticDedupEnabled),
|
|
2317
|
+
armed,
|
|
2318
|
+
predictedFrames: perfs.reduce((sum2, p) => sum2 + (p.staticDedupPredicted ?? 0), 0),
|
|
2319
|
+
reusedFrames: perfs.reduce((sum2, p) => sum2 + (p.staticDedupReused ?? 0), 0),
|
|
2320
|
+
skipReason: skipReasons.length > 0 ? skipReasons.join("|") : void 0,
|
|
2321
|
+
...verificationPerfs.length === 0 ? {} : {
|
|
2322
|
+
verifiedFrames: verificationPerfs.reduce(
|
|
2323
|
+
(sum2, perf) => sum2 + (perf.staticDedupVerified ?? 0),
|
|
2324
|
+
0
|
|
2325
|
+
),
|
|
2326
|
+
verificationOutcomes,
|
|
2327
|
+
plannedRuns: verificationPerfs.reduce(
|
|
2328
|
+
(sum2, perf) => sum2 + (perf.staticDedupVerificationPlannedRuns ?? 0),
|
|
2329
|
+
0
|
|
2330
|
+
),
|
|
2331
|
+
completedRuns: verificationPerfs.reduce(
|
|
2332
|
+
(sum2, perf) => sum2 + (perf.staticDedupVerificationCompletedRuns ?? 0),
|
|
2333
|
+
0
|
|
2334
|
+
),
|
|
2335
|
+
screenshots: verificationPerfs.reduce(
|
|
2336
|
+
(sum2, perf) => sum2 + (perf.staticDedupVerificationScreenshots ?? 0),
|
|
2337
|
+
0
|
|
2338
|
+
),
|
|
2339
|
+
seeks: verificationPerfs.reduce(
|
|
2340
|
+
(sum2, perf) => sum2 + (perf.staticDedupVerificationSeeks ?? 0),
|
|
2341
|
+
0
|
|
2342
|
+
),
|
|
2343
|
+
comparisons: verificationPerfs.reduce(
|
|
2344
|
+
(sum2, perf) => sum2 + (perf.staticDedupVerificationComparisons ?? 0),
|
|
2345
|
+
0
|
|
2346
|
+
),
|
|
2347
|
+
verificationElapsedMs: verificationPerfs.reduce(
|
|
2348
|
+
(sum2, perf) => sum2 + (perf.staticDedupVerificationElapsedMs ?? 0),
|
|
2349
|
+
0
|
|
2350
|
+
)
|
|
2351
|
+
}
|
|
2352
|
+
};
|
|
2353
|
+
}
|
|
2354
|
+
function aggregateBeginFrameReuse(perfs) {
|
|
2355
|
+
const noDamageFrames = perfs.reduce((sum2, p) => sum2 + (p.beginFrameNoDamage ?? 0), 0);
|
|
2356
|
+
const hasDamageFrames = perfs.reduce((sum2, p) => sum2 + (p.beginFrameHasDamage ?? 0), 0);
|
|
2357
|
+
if (noDamageFrames + hasDamageFrames === 0) return void 0;
|
|
2358
|
+
return { noDamageFrames, hasDamageFrames };
|
|
2359
|
+
}
|
|
2360
|
+
function buildRenderPerfSummary(input) {
|
|
2361
|
+
return {
|
|
2362
|
+
renderId: input.job.id,
|
|
2363
|
+
totalElapsedMs: input.totalElapsedMs,
|
|
2364
|
+
// RenderPerfSummary surfaces fps as a decimal because it lands in JSON
|
|
2365
|
+
// payloads (CLI telemetry, regression-harness reports) where a single
|
|
2366
|
+
// number is friendlier than `{num,den}`. Callers needing the rational
|
|
2367
|
+
// back can read `job.config.fps`.
|
|
2368
|
+
fps: fpsToNumber(input.job.config.fps),
|
|
2369
|
+
quality: input.job.config.quality,
|
|
2370
|
+
workers: input.workerCount,
|
|
2371
|
+
workerSizing: input.workerSizing,
|
|
2372
|
+
chunkedEncode: input.enableChunkedEncode,
|
|
2373
|
+
chunkSizeFrames: input.enableChunkedEncode ? input.chunkedEncodeSize : null,
|
|
2374
|
+
compositionDurationSeconds: input.compositionDurationSeconds,
|
|
2375
|
+
totalFrames: input.totalFrames,
|
|
2376
|
+
resolution: { width: input.outputWidth, height: input.outputHeight },
|
|
2377
|
+
videoCount: input.videoCount,
|
|
2378
|
+
audioCount: input.audioCount,
|
|
2379
|
+
stages: input.perfStages,
|
|
2380
|
+
videoExtractBreakdown: input.videoExtractBreakdown,
|
|
2381
|
+
tmpPeakBytes: input.tmpPeakBytes,
|
|
2382
|
+
captureCalibration: input.captureCalibration ? {
|
|
2383
|
+
sampledFrames: input.captureCalibration.samples.map((sample) => sample.frameIndex),
|
|
2384
|
+
p95Ms: input.captureCalibration.estimate.p95Ms,
|
|
2385
|
+
multiplier: input.captureCalibration.estimate.multiplier,
|
|
2386
|
+
reasons: input.captureCalibration.estimate.reasons
|
|
2387
|
+
} : void 0,
|
|
2388
|
+
captureAttempts: input.captureAttempts.length > 0 ? input.captureAttempts : void 0,
|
|
2389
|
+
hdrDiagnostics: input.hdrDiagnostics.videoExtractionFailures > 0 || input.hdrDiagnostics.imageDecodeFailures > 0 ? { ...input.hdrDiagnostics } : void 0,
|
|
2390
|
+
hdrPerf: input.hdrPerf ? finalizeHdrPerf(input.hdrPerf) : void 0,
|
|
2391
|
+
observability: input.observability,
|
|
2392
|
+
captureAvgMs: input.totalFrames > 0 ? Math.round(
|
|
2393
|
+
(input.perfStages.captureFrameMs ?? input.perfStages.captureMs ?? 0) / input.totalFrames
|
|
2394
|
+
) : void 0,
|
|
2395
|
+
subTimelineWait: worstSubTimelineWaitOutcome(input.dedupPerfs),
|
|
2396
|
+
captureP50Ms: (() => {
|
|
2397
|
+
const withSamples = input.dedupPerfs.filter((p) => (p.p50TotalMs ?? 0) > 0);
|
|
2398
|
+
if (withSamples.length === 0) return void 0;
|
|
2399
|
+
return withSamples.reduce((a, b) => b.frames > a.frames ? b : a).p50TotalMs;
|
|
2400
|
+
})(),
|
|
2401
|
+
peakRssMb: Math.round(input.peakRssBytes / (1024 * 1024)),
|
|
2402
|
+
peakHeapUsedMb: Math.round(input.peakHeapUsedBytes / (1024 * 1024)),
|
|
2403
|
+
staticDedup: aggregateDedup(input.dedupPerfs),
|
|
2404
|
+
chromeMemory: aggregateChromeMemory(input.dedupPerfs),
|
|
2405
|
+
beginFrameReuse: aggregateBeginFrameReuse(input.dedupPerfs),
|
|
2406
|
+
drawElement: aggregateDrawElement(
|
|
2407
|
+
input.dedupPerfs,
|
|
2408
|
+
input.drawElement ?? { selfVerifyFallback: false }
|
|
2409
|
+
),
|
|
2410
|
+
host: {
|
|
2411
|
+
platform: platform(),
|
|
2412
|
+
arch: arch(),
|
|
2413
|
+
cpuCount: cpus().length,
|
|
2414
|
+
totalMemMb: Math.round(totalmem() / (1024 * 1024)),
|
|
2415
|
+
nodeVersion: process.version,
|
|
2416
|
+
gpuDisabled: input.gpuDisabled
|
|
2417
|
+
}
|
|
2418
|
+
};
|
|
2419
|
+
}
|
|
2420
|
+
|
|
2421
|
+
// ../producer/src/services/render/captureStageError.ts
|
|
2422
|
+
var CaptureStageError = class extends CaptureFailure {
|
|
2423
|
+
browserConsole;
|
|
2424
|
+
constructor(input) {
|
|
2425
|
+
const classified = classifyCaptureFailure(input.cause);
|
|
2426
|
+
super({
|
|
2427
|
+
kind: classified.kind,
|
|
2428
|
+
message: normalizeErrorMessage(input.cause),
|
|
2429
|
+
cause: input.cause,
|
|
2430
|
+
workerDiagnostics: classified.workerDiagnostics,
|
|
2431
|
+
pageErrorLines: classified.pageErrorLines
|
|
2432
|
+
});
|
|
2433
|
+
this.name = "CaptureStageError";
|
|
2434
|
+
this.browserConsole = withWorkerPageErrors(input.browserConsole, [
|
|
2435
|
+
...classified.pageErrorLines
|
|
2436
|
+
]);
|
|
2437
|
+
if (input.cause instanceof Error && input.cause.stack) {
|
|
2438
|
+
this.stack = input.cause.stack;
|
|
2439
|
+
}
|
|
2440
|
+
}
|
|
2441
|
+
};
|
|
2442
|
+
function wrapCaptureStageError(error, browserConsole) {
|
|
2443
|
+
if (error instanceof CaptureStageError || error instanceof EncoderInterruptedError) return error;
|
|
2444
|
+
return new CaptureStageError({ cause: error, browserConsole });
|
|
2445
|
+
}
|
|
2446
|
+
function getCaptureStageBrowserConsole(error) {
|
|
2447
|
+
if (error instanceof CaptureStageError) return error.browserConsole;
|
|
2448
|
+
if (error instanceof CaptureFailure) return [...error.pageErrorLines];
|
|
2449
|
+
return [];
|
|
2450
|
+
}
|
|
2451
|
+
|
|
2217
2452
|
// ../producer/src/services/hdrCompositor.ts
|
|
2453
|
+
import { readSync as readSync2, closeSync as closeSync3 } from "fs";
|
|
2454
|
+
import { join as join6 } from "path";
|
|
2218
2455
|
function countNonZeroAlpha(rgba) {
|
|
2219
2456
|
let n = 0;
|
|
2220
2457
|
for (let p = 3; p < rgba.length; p += 4) {
|
|
@@ -3274,284 +3511,75 @@ function cleanupEndedHdrVideos(args) {
|
|
|
3274
3511
|
if (frameSource) {
|
|
3275
3512
|
cleanupHdrVideoFrameSource(frameSource, log);
|
|
3276
3513
|
hdrVideoFrameSources.delete(videoId);
|
|
3277
|
-
}
|
|
3278
|
-
cleanedUpVideos.add(videoId);
|
|
3279
|
-
}
|
|
3280
|
-
}
|
|
3281
|
-
}
|
|
3282
|
-
}
|
|
3283
|
-
|
|
3284
|
-
// ../producer/src/services/render/segmentPlan.ts
|
|
3285
|
-
var DEFAULT_SEGMENT_FRAMES = 3e3;
|
|
3286
|
-
var MIN_SEGMENT_FRAMES = 30;
|
|
3287
|
-
function assertPositiveInteger(name, value) {
|
|
3288
|
-
if (!Number.isInteger(value) || value <= 0) {
|
|
3289
|
-
throw new Error(`[segmentPlan] ${name} must be a positive integer (got ${String(value)})`);
|
|
3290
|
-
}
|
|
3291
|
-
}
|
|
3292
|
-
function planSegments(totalFrames, segmentFrames) {
|
|
3293
|
-
assertPositiveInteger("totalFrames", totalFrames);
|
|
3294
|
-
assertPositiveInteger("segmentFrames", segmentFrames);
|
|
3295
|
-
const slices = [];
|
|
3296
|
-
for (let start = 0, index = 0; start < totalFrames; start += segmentFrames, index += 1) {
|
|
3297
|
-
slices.push({
|
|
3298
|
-
index,
|
|
3299
|
-
startFrame: start,
|
|
3300
|
-
endFrame: Math.min(totalFrames, start + segmentFrames)
|
|
3301
|
-
});
|
|
3302
|
-
}
|
|
3303
|
-
return slices;
|
|
3304
|
-
}
|
|
3305
|
-
function resolveSegmentFrames(env) {
|
|
3306
|
-
const raw = env.HF_SEGMENT_FRAMES;
|
|
3307
|
-
if (raw === void 0 || raw.trim() === "") return DEFAULT_SEGMENT_FRAMES;
|
|
3308
|
-
const parsed = Number(raw);
|
|
3309
|
-
if (!Number.isInteger(parsed)) return DEFAULT_SEGMENT_FRAMES;
|
|
3310
|
-
return Math.max(MIN_SEGMENT_FRAMES, parsed);
|
|
3311
|
-
}
|
|
3312
|
-
|
|
3313
|
-
// ../producer/src/services/render/segmentQueue.ts
|
|
3314
|
-
function createSegmentQueue(slices) {
|
|
3315
|
-
let cursor = 0;
|
|
3316
|
-
return {
|
|
3317
|
-
next: () => slices[cursor++],
|
|
3318
|
-
remaining: () => Math.max(0, slices.length - cursor)
|
|
3319
|
-
};
|
|
3320
|
-
}
|
|
3321
|
-
|
|
3322
|
-
// ../producer/src/services/render/segmentRecycle.ts
|
|
3323
|
-
var DEFAULT_SEGMENT_BROWSER_RECYCLE = 3;
|
|
3324
|
-
function resolveSegmentBrowserRecycle(env) {
|
|
3325
|
-
const raw = env.HF_SEGMENT_BROWSER_RECYCLE;
|
|
3326
|
-
if (raw === void 0 || raw.trim() === "") return DEFAULT_SEGMENT_BROWSER_RECYCLE;
|
|
3327
|
-
const parsed = Number(raw);
|
|
3328
|
-
return Number.isInteger(parsed) && parsed >= 0 ? parsed : DEFAULT_SEGMENT_BROWSER_RECYCLE;
|
|
3329
|
-
}
|
|
3330
|
-
var TARGET_LOSS_PATTERNS = [/target closed/i, /detached frame/i, /session closed/i];
|
|
3331
|
-
function isTargetLossError(error) {
|
|
3332
|
-
if (!(error instanceof Error)) return false;
|
|
3333
|
-
return TARGET_LOSS_PATTERNS.some((re) => re.test(error.message));
|
|
3334
|
-
}
|
|
3335
|
-
|
|
3336
|
-
// ../producer/src/services/render/stages/captureStreamingStage.ts
|
|
3337
|
-
import { mkdtemp, writeFile } from "fs/promises";
|
|
3338
|
-
import { tmpdir } from "os";
|
|
3339
|
-
import { join as join8 } from "path";
|
|
3340
|
-
|
|
3341
|
-
// ../producer/src/services/render/perfSummary.ts
|
|
3342
|
-
import { arch, cpus, platform, totalmem } from "os";
|
|
3343
|
-
function worstSubTimelineWaitOutcome(perfs) {
|
|
3344
|
-
const outcomes = perfs.map((p) => p.subTimelineWaitOutcome).filter((o) => !!o);
|
|
3345
|
-
if (outcomes.length === 0) return void 0;
|
|
3346
|
-
if (outcomes.includes("script_failure")) return "script_failure";
|
|
3347
|
-
if (outcomes.includes("timeout")) return "timeout";
|
|
3348
|
-
return "ready";
|
|
3349
|
-
}
|
|
3350
|
-
function pushWorkerDedupPerfs(results, sink) {
|
|
3351
|
-
for (const r of results) {
|
|
3352
|
-
if (r.perf) sink.push(r.perf);
|
|
3353
|
-
}
|
|
3354
|
-
}
|
|
3355
|
-
function roundDb(value) {
|
|
3356
|
-
return value === void 0 ? void 0 : Math.round(Math.min(value, 999) * 10) / 10;
|
|
3357
|
-
}
|
|
3358
|
-
function aggregateDrawElement(perfs, de) {
|
|
3359
|
-
if (perfs.length === 0) return void 0;
|
|
3360
|
-
const modes = [...new Set(perfs.map((p) => p.captureMode).filter(Boolean))].sort();
|
|
3361
|
-
const gateReasons = [
|
|
3362
|
-
...new Set(
|
|
3363
|
-
[de.probeGateReason, ...perfs.map((p) => p.deGateReason)].filter((r) => !!r)
|
|
3364
|
-
)
|
|
3365
|
-
].sort();
|
|
3366
|
-
const gpuRenderers = [
|
|
3367
|
-
...new Set(perfs.map((p) => p.gpuRenderer).filter((r) => !!r))
|
|
3368
|
-
].sort();
|
|
3369
|
-
const drain = de.drainStats;
|
|
3370
|
-
return {
|
|
3371
|
-
mode: modes.join("|") || "unknown",
|
|
3372
|
-
compileGate: de.compileGate,
|
|
3373
|
-
clampReason: de.clampReason,
|
|
3374
|
-
workerInversion: de.workerInversion ?? "none",
|
|
3375
|
-
preInversionWorkers: de.preInversionWorkers,
|
|
3376
|
-
compositionElementCount: de.compositionElementCount,
|
|
3377
|
-
compositionElementCountSource: de.compositionElementCountSource,
|
|
3378
|
-
compositionElementTags: de.compositionElementTags,
|
|
3379
|
-
arollVideoCount: de.arollVideoCount,
|
|
3380
|
-
heygenVideoCount: de.heygenVideoCount,
|
|
3381
|
-
adaptersUsed: de.adaptersUsed,
|
|
3382
|
-
audioCount: de.audioCount,
|
|
3383
|
-
imageCount: de.imageCount,
|
|
3384
|
-
subCompositionCount: de.subCompositionCount,
|
|
3385
|
-
audioGroupCount: de.audioGroupCount,
|
|
3386
|
-
colorGradingCount: de.colorGradingCount,
|
|
3387
|
-
hasLut: de.hasLut,
|
|
3388
|
-
rootBodyMismatch: de.rootBodyMismatch,
|
|
3389
|
-
rootBodyDeltaPxBucket: de.rootBodyDeltaPxBucket,
|
|
3390
|
-
vfxHostCount: de.vfxHostCount,
|
|
3391
|
-
vfxCapture: de.vfxCapture,
|
|
3392
|
-
vfxTypes: de.vfxTypes,
|
|
3393
|
-
shortBand: de.shortBand,
|
|
3394
|
-
parallelRouter: de.parallelRouter ?? "none",
|
|
3395
|
-
preRouterWorkers: de.preRouterWorkers,
|
|
3396
|
-
gateReason: gateReasons.length > 0 ? gateReasons.join("|") : void 0,
|
|
3397
|
-
gpuRenderer: gpuRenderers.length > 0 ? gpuRenderers.join("|") : void 0,
|
|
3398
|
-
workerEncode: perfs.some((p) => p.deWorkerEncode),
|
|
3399
|
-
verifyArmed: perfs.reduce((sum2, p) => sum2 + (p.deVerifyArmed ?? 0), 0),
|
|
3400
|
-
verifyChecked: drain?.verifyChecked ?? 0,
|
|
3401
|
-
verifyMinDb: roundDb(drain?.verifyMinDb),
|
|
3402
|
-
verifyInitMs: perfs.reduce((sum2, p) => sum2 + (p.deVerifyInitMs ?? 0), 0),
|
|
3403
|
-
selfVerifyFallback: de.selfVerifyFallback,
|
|
3404
|
-
fallbackReason: de.fallbackReason,
|
|
3405
|
-
fallbackFailedDb: roundDb(de.fallbackFailedDb),
|
|
3406
|
-
fallbackFrameIndex: de.fallbackFrameIndex,
|
|
3407
|
-
fallbackThresholdDb: roundDb(de.fallbackThresholdDb),
|
|
3408
|
-
blankSuspects: drain?.blankSuspects ?? 0,
|
|
3409
|
-
blankDeterministicAccepts: drain?.blankDeterministicAccepts ?? 0,
|
|
3410
|
-
blankRecaptures: drain?.blankRecaptures ?? 0,
|
|
3411
|
-
boundaryFrames: perfs.reduce((sum2, p) => sum2 + (p.deBoundaryFrames ?? 0), 0),
|
|
3412
|
-
ncprFallbacks: perfs.reduce((sum2, p) => sum2 + (p.deNcprFallbacks ?? 0), 0),
|
|
3413
|
-
frameTimeouts: perfs.reduce((sum2, p) => sum2 + (p.deFrameTimeouts ?? 0), 0)
|
|
3414
|
-
};
|
|
3415
|
-
}
|
|
3416
|
-
function maxDefined(values) {
|
|
3417
|
-
const present = values.filter((v) => typeof v === "number");
|
|
3418
|
-
return present.length > 0 ? Math.max(...present) : void 0;
|
|
3419
|
-
}
|
|
3420
|
-
function aggregateChromeMemory(perfs) {
|
|
3421
|
-
const sampled = perfs.filter((p) => (p.chromeMemorySamples ?? 0) > 0);
|
|
3422
|
-
if (sampled.length === 0) return void 0;
|
|
3423
|
-
return {
|
|
3424
|
-
browserRssPeakMb: maxDefined(sampled.map((p) => p.chromeBrowserRssPeakMb)),
|
|
3425
|
-
rendererRssPeakMb: maxDefined(sampled.map((p) => p.chromeRendererRssPeakMb)),
|
|
3426
|
-
// Last samples are per session; summing approximates the whole fleet's
|
|
3427
|
-
// footprint at the end of capture (workers run concurrently).
|
|
3428
|
-
rssLastMb: sampled.reduce((sum2, p) => sum2 + (p.chromeRssLastMb ?? 0), 0),
|
|
3429
|
-
gpuProcessSeenLastSample: sampled.some((p) => p.chromeGpuProcessSeenLastSample === true),
|
|
3430
|
-
samples: sampled.reduce((sum2, p) => sum2 + (p.chromeMemorySamples ?? 0), 0)
|
|
3431
|
-
};
|
|
3432
|
-
}
|
|
3433
|
-
function aggregateDedup(perfs) {
|
|
3434
|
-
if (perfs.length === 0) return void 0;
|
|
3435
|
-
const armed = perfs.some((p) => p.staticDedupArmed);
|
|
3436
|
-
const skipReasons = armed ? [] : [
|
|
3437
|
-
...new Set(perfs.map((p) => p.staticDedupSkipReason).filter((r) => !!r))
|
|
3438
|
-
].sort();
|
|
3439
|
-
const verificationPerfs = perfs.filter((perf) => perf.staticDedupVerificationOutcome);
|
|
3440
|
-
const verificationOutcomes = [
|
|
3441
|
-
...new Set(
|
|
3442
|
-
verificationPerfs.map((perf) => perf.staticDedupVerificationOutcome).filter((outcome) => outcome != null)
|
|
3443
|
-
)
|
|
3444
|
-
].sort();
|
|
3445
|
-
return {
|
|
3446
|
-
enabled: perfs.some((p) => p.staticDedupEnabled),
|
|
3447
|
-
armed,
|
|
3448
|
-
predictedFrames: perfs.reduce((sum2, p) => sum2 + (p.staticDedupPredicted ?? 0), 0),
|
|
3449
|
-
reusedFrames: perfs.reduce((sum2, p) => sum2 + (p.staticDedupReused ?? 0), 0),
|
|
3450
|
-
skipReason: skipReasons.length > 0 ? skipReasons.join("|") : void 0,
|
|
3451
|
-
...verificationPerfs.length === 0 ? {} : {
|
|
3452
|
-
verifiedFrames: verificationPerfs.reduce(
|
|
3453
|
-
(sum2, perf) => sum2 + (perf.staticDedupVerified ?? 0),
|
|
3454
|
-
0
|
|
3455
|
-
),
|
|
3456
|
-
verificationOutcomes,
|
|
3457
|
-
plannedRuns: verificationPerfs.reduce(
|
|
3458
|
-
(sum2, perf) => sum2 + (perf.staticDedupVerificationPlannedRuns ?? 0),
|
|
3459
|
-
0
|
|
3460
|
-
),
|
|
3461
|
-
completedRuns: verificationPerfs.reduce(
|
|
3462
|
-
(sum2, perf) => sum2 + (perf.staticDedupVerificationCompletedRuns ?? 0),
|
|
3463
|
-
0
|
|
3464
|
-
),
|
|
3465
|
-
screenshots: verificationPerfs.reduce(
|
|
3466
|
-
(sum2, perf) => sum2 + (perf.staticDedupVerificationScreenshots ?? 0),
|
|
3467
|
-
0
|
|
3468
|
-
),
|
|
3469
|
-
seeks: verificationPerfs.reduce(
|
|
3470
|
-
(sum2, perf) => sum2 + (perf.staticDedupVerificationSeeks ?? 0),
|
|
3471
|
-
0
|
|
3472
|
-
),
|
|
3473
|
-
comparisons: verificationPerfs.reduce(
|
|
3474
|
-
(sum2, perf) => sum2 + (perf.staticDedupVerificationComparisons ?? 0),
|
|
3475
|
-
0
|
|
3476
|
-
),
|
|
3477
|
-
verificationElapsedMs: verificationPerfs.reduce(
|
|
3478
|
-
(sum2, perf) => sum2 + (perf.staticDedupVerificationElapsedMs ?? 0),
|
|
3479
|
-
0
|
|
3480
|
-
)
|
|
3514
|
+
}
|
|
3515
|
+
cleanedUpVideos.add(videoId);
|
|
3516
|
+
}
|
|
3481
3517
|
}
|
|
3482
|
-
}
|
|
3518
|
+
}
|
|
3483
3519
|
}
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3520
|
+
|
|
3521
|
+
// ../producer/src/services/render/segmentPlan.ts
|
|
3522
|
+
var DEFAULT_SEGMENT_FRAMES = 3e3;
|
|
3523
|
+
var MIN_SEGMENT_FRAMES = 30;
|
|
3524
|
+
function assertPositiveInteger(name, value) {
|
|
3525
|
+
if (!Number.isInteger(value) || value <= 0) {
|
|
3526
|
+
throw new Error(`[segmentPlan] ${name} must be a positive integer (got ${String(value)})`);
|
|
3527
|
+
}
|
|
3489
3528
|
}
|
|
3490
|
-
function
|
|
3529
|
+
function planSegments(totalFrames, segmentFrames) {
|
|
3530
|
+
assertPositiveInteger("totalFrames", totalFrames);
|
|
3531
|
+
assertPositiveInteger("segmentFrames", segmentFrames);
|
|
3532
|
+
const slices = [];
|
|
3533
|
+
for (let start = 0, index = 0; start < totalFrames; start += segmentFrames, index += 1) {
|
|
3534
|
+
slices.push({
|
|
3535
|
+
index,
|
|
3536
|
+
startFrame: start,
|
|
3537
|
+
endFrame: Math.min(totalFrames, start + segmentFrames)
|
|
3538
|
+
});
|
|
3539
|
+
}
|
|
3540
|
+
return slices;
|
|
3541
|
+
}
|
|
3542
|
+
function resolveSegmentFrames(env) {
|
|
3543
|
+
const raw = env.HF_SEGMENT_FRAMES;
|
|
3544
|
+
if (raw === void 0 || raw.trim() === "") return DEFAULT_SEGMENT_FRAMES;
|
|
3545
|
+
const parsed = Number(raw);
|
|
3546
|
+
if (!Number.isInteger(parsed)) return DEFAULT_SEGMENT_FRAMES;
|
|
3547
|
+
return Math.max(MIN_SEGMENT_FRAMES, parsed);
|
|
3548
|
+
}
|
|
3549
|
+
|
|
3550
|
+
// ../producer/src/services/render/segmentQueue.ts
|
|
3551
|
+
function createSegmentQueue(slices) {
|
|
3552
|
+
let cursor = 0;
|
|
3491
3553
|
return {
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
// RenderPerfSummary surfaces fps as a decimal because it lands in JSON
|
|
3495
|
-
// payloads (CLI telemetry, regression-harness reports) where a single
|
|
3496
|
-
// number is friendlier than `{num,den}`. Callers needing the rational
|
|
3497
|
-
// back can read `job.config.fps`.
|
|
3498
|
-
fps: fpsToNumber(input.job.config.fps),
|
|
3499
|
-
quality: input.job.config.quality,
|
|
3500
|
-
workers: input.workerCount,
|
|
3501
|
-
workerSizing: input.workerSizing,
|
|
3502
|
-
chunkedEncode: input.enableChunkedEncode,
|
|
3503
|
-
chunkSizeFrames: input.enableChunkedEncode ? input.chunkedEncodeSize : null,
|
|
3504
|
-
compositionDurationSeconds: input.compositionDurationSeconds,
|
|
3505
|
-
totalFrames: input.totalFrames,
|
|
3506
|
-
resolution: { width: input.outputWidth, height: input.outputHeight },
|
|
3507
|
-
videoCount: input.videoCount,
|
|
3508
|
-
audioCount: input.audioCount,
|
|
3509
|
-
stages: input.perfStages,
|
|
3510
|
-
videoExtractBreakdown: input.videoExtractBreakdown,
|
|
3511
|
-
tmpPeakBytes: input.tmpPeakBytes,
|
|
3512
|
-
captureCalibration: input.captureCalibration ? {
|
|
3513
|
-
sampledFrames: input.captureCalibration.samples.map((sample) => sample.frameIndex),
|
|
3514
|
-
p95Ms: input.captureCalibration.estimate.p95Ms,
|
|
3515
|
-
multiplier: input.captureCalibration.estimate.multiplier,
|
|
3516
|
-
reasons: input.captureCalibration.estimate.reasons
|
|
3517
|
-
} : void 0,
|
|
3518
|
-
captureAttempts: input.captureAttempts.length > 0 ? input.captureAttempts : void 0,
|
|
3519
|
-
hdrDiagnostics: input.hdrDiagnostics.videoExtractionFailures > 0 || input.hdrDiagnostics.imageDecodeFailures > 0 ? { ...input.hdrDiagnostics } : void 0,
|
|
3520
|
-
hdrPerf: input.hdrPerf ? finalizeHdrPerf(input.hdrPerf) : void 0,
|
|
3521
|
-
observability: input.observability,
|
|
3522
|
-
captureAvgMs: input.totalFrames > 0 ? Math.round(
|
|
3523
|
-
(input.perfStages.captureFrameMs ?? input.perfStages.captureMs ?? 0) / input.totalFrames
|
|
3524
|
-
) : void 0,
|
|
3525
|
-
subTimelineWait: worstSubTimelineWaitOutcome(input.dedupPerfs),
|
|
3526
|
-
captureP50Ms: (() => {
|
|
3527
|
-
const withSamples = input.dedupPerfs.filter((p) => (p.p50TotalMs ?? 0) > 0);
|
|
3528
|
-
if (withSamples.length === 0) return void 0;
|
|
3529
|
-
return withSamples.reduce((a, b) => b.frames > a.frames ? b : a).p50TotalMs;
|
|
3530
|
-
})(),
|
|
3531
|
-
peakRssMb: Math.round(input.peakRssBytes / (1024 * 1024)),
|
|
3532
|
-
peakHeapUsedMb: Math.round(input.peakHeapUsedBytes / (1024 * 1024)),
|
|
3533
|
-
staticDedup: aggregateDedup(input.dedupPerfs),
|
|
3534
|
-
chromeMemory: aggregateChromeMemory(input.dedupPerfs),
|
|
3535
|
-
beginFrameReuse: aggregateBeginFrameReuse(input.dedupPerfs),
|
|
3536
|
-
drawElement: aggregateDrawElement(
|
|
3537
|
-
input.dedupPerfs,
|
|
3538
|
-
input.drawElement ?? { selfVerifyFallback: false }
|
|
3539
|
-
),
|
|
3540
|
-
host: {
|
|
3541
|
-
platform: platform(),
|
|
3542
|
-
arch: arch(),
|
|
3543
|
-
cpuCount: cpus().length,
|
|
3544
|
-
totalMemMb: Math.round(totalmem() / (1024 * 1024)),
|
|
3545
|
-
nodeVersion: process.version,
|
|
3546
|
-
gpuDisabled: input.gpuDisabled
|
|
3547
|
-
}
|
|
3554
|
+
next: () => slices[cursor++],
|
|
3555
|
+
remaining: () => Math.max(0, slices.length - cursor)
|
|
3548
3556
|
};
|
|
3549
3557
|
}
|
|
3550
3558
|
|
|
3559
|
+
// ../producer/src/services/render/segmentRecycle.ts
|
|
3560
|
+
var DEFAULT_SEGMENT_BROWSER_RECYCLE = 3;
|
|
3561
|
+
function resolveSegmentBrowserRecycle(env) {
|
|
3562
|
+
const raw = env.HF_SEGMENT_BROWSER_RECYCLE;
|
|
3563
|
+
if (raw === void 0 || raw.trim() === "") return DEFAULT_SEGMENT_BROWSER_RECYCLE;
|
|
3564
|
+
const parsed = Number(raw);
|
|
3565
|
+
return Number.isInteger(parsed) && parsed >= 0 ? parsed : DEFAULT_SEGMENT_BROWSER_RECYCLE;
|
|
3566
|
+
}
|
|
3567
|
+
var TARGET_LOSS_PATTERNS = [/target closed/i, /detached frame/i, /session closed/i];
|
|
3568
|
+
function isTargetLossError(error) {
|
|
3569
|
+
if (!(error instanceof Error)) return false;
|
|
3570
|
+
return TARGET_LOSS_PATTERNS.some((re) => re.test(error.message));
|
|
3571
|
+
}
|
|
3572
|
+
|
|
3551
3573
|
// ../producer/src/services/render/stages/captureStreamingStage.ts
|
|
3574
|
+
import { mkdtemp, writeFile } from "fs/promises";
|
|
3575
|
+
import { tmpdir } from "os";
|
|
3576
|
+
import { join as join8 } from "path";
|
|
3552
3577
|
var DEFAULT_CAPTURE_STALL_MS = 6e4;
|
|
3553
3578
|
var DE_STALL_POLL_MS = 5e3;
|
|
3554
3579
|
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.";
|
|
3580
|
+
function poolFailure(error, probeSession) {
|
|
3581
|
+
return wrapCaptureStageError(error, probeSession?.browserConsoleBuffer ?? []);
|
|
3582
|
+
}
|
|
3555
3583
|
var ParallelCaptureStallError = class extends Error {
|
|
3556
3584
|
variant;
|
|
3557
3585
|
constructor(args) {
|
|
@@ -3998,7 +4026,7 @@ async function runCaptureStreamingStage(input) {
|
|
|
3998
4026
|
}
|
|
3999
4027
|
);
|
|
4000
4028
|
} catch (err) {
|
|
4001
|
-
if (parallelDrainError) throw parallelDrainError;
|
|
4029
|
+
if (parallelDrainError) throw poolFailure(parallelDrainError, probeSession);
|
|
4002
4030
|
if (stalled && abortSignal?.aborted !== true) {
|
|
4003
4031
|
throw new ParallelCaptureStallError({
|
|
4004
4032
|
variant: "pool",
|
|
@@ -4009,13 +4037,15 @@ async function runCaptureStreamingStage(input) {
|
|
|
4009
4037
|
phaseSummary: phaseSummary()
|
|
4010
4038
|
});
|
|
4011
4039
|
}
|
|
4012
|
-
throw err;
|
|
4040
|
+
throw poolFailure(err, probeSession);
|
|
4013
4041
|
} finally {
|
|
4014
4042
|
clearInterval(stallTimer);
|
|
4015
4043
|
abortSignal?.removeEventListener("abort", forwardParentAbort);
|
|
4016
4044
|
}
|
|
4017
|
-
if (parallelDrainError) throw parallelDrainError;
|
|
4045
|
+
if (parallelDrainError) throw poolFailure(parallelDrainError, probeSession);
|
|
4018
4046
|
pushWorkerDedupPerfs(workerResults, dedupPerfs);
|
|
4047
|
+
const workerPageErrors = [];
|
|
4048
|
+
pushWorkerPageErrors(workerResults, workerPageErrors);
|
|
4019
4049
|
if (parallelGuardRan) {
|
|
4020
4050
|
deDrainStats = parallelStats;
|
|
4021
4051
|
}
|
|
@@ -4025,6 +4055,7 @@ async function runCaptureStreamingStage(input) {
|
|
|
4025
4055
|
await closeCaptureSession(probeSession);
|
|
4026
4056
|
probeSession = null;
|
|
4027
4057
|
}
|
|
4058
|
+
lastBrowserConsole = withWorkerPageErrors(lastBrowserConsole, workerPageErrors);
|
|
4028
4059
|
} else {
|
|
4029
4060
|
const videoInjector = createRenderVideoFrameInjector();
|
|
4030
4061
|
const session = probeSession ?? await createCaptureSession(
|
|
@@ -4471,7 +4502,7 @@ async function runCaptureSegmentedStage(input) {
|
|
|
4471
4502
|
|
|
4472
4503
|
// ../producer/src/services/render/segmentManifest.ts
|
|
4473
4504
|
import { createHash as createHash2 } from "crypto";
|
|
4474
|
-
import { existsSync as existsSync7, mkdirSync as mkdirSync4, readFileSync as readFileSync4,
|
|
4505
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync4, readFileSync as readFileSync4, statSync as statSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
4475
4506
|
import { join as join10 } from "path";
|
|
4476
4507
|
var MANIFEST_FILENAME = "segments.json";
|
|
4477
4508
|
function computeSegmentPlanHash(input) {
|
|
@@ -4528,7 +4559,7 @@ function writeSegmentManifest(segmentDir, manifest) {
|
|
|
4528
4559
|
mkdirSync4(segmentDir, { recursive: true });
|
|
4529
4560
|
const tmp = join10(segmentDir, `${MANIFEST_FILENAME}.${process.pid}.tmp`);
|
|
4530
4561
|
writeFileSync3(tmp, JSON.stringify(manifest, null, 2), "utf-8");
|
|
4531
|
-
|
|
4562
|
+
renameWithRetry(tmp, join10(segmentDir, MANIFEST_FILENAME));
|
|
4532
4563
|
}
|
|
4533
4564
|
async function probeSegmentFrameCount(path, probe) {
|
|
4534
4565
|
try {
|
|
@@ -6642,7 +6673,7 @@ async function readLocalFont(absPath) {
|
|
|
6642
6673
|
return { kind: "inline", buffer: Buffer.concat(chunks, totalBytes) };
|
|
6643
6674
|
}
|
|
6644
6675
|
async function embedLocalFontFaces(html, projectDir) {
|
|
6645
|
-
const { fontToDataUri: toDataUri } = await import("./deterministicFonts-
|
|
6676
|
+
const { fontToDataUri: toDataUri } = await import("./deterministicFonts-RADD3BSX.js");
|
|
6646
6677
|
const styleBlockRe = /<style\b[^>]*>([\s\S]*?)<\/style>/gi;
|
|
6647
6678
|
const fontFaceRe = /@font-face\s*\{([^}]*)\}/gi;
|
|
6648
6679
|
let result = html;
|
|
@@ -6923,6 +6954,9 @@ async function discoverMediaFromBrowser(page) {
|
|
|
6923
6954
|
const intrinsicDuration = isImage ? 0 : htmlEl.duration;
|
|
6924
6955
|
const playbackStartRaw = htmlEl.getAttribute("data-playback-start");
|
|
6925
6956
|
const mediaStartRaw = htmlEl.getAttribute("data-media-start");
|
|
6957
|
+
const playbackRateRaw = htmlEl.getAttribute("data-playback-rate");
|
|
6958
|
+
const automationRaw = htmlEl.getAttribute("data-automation");
|
|
6959
|
+
const defaultPlaybackRate = isImage ? 1 : htmlEl.defaultPlaybackRate;
|
|
6926
6960
|
const loop = htmlEl.hasAttribute("loop");
|
|
6927
6961
|
const hasAudio = htmlEl.getAttribute("data-has-audio") === "true";
|
|
6928
6962
|
const volume = parseFloat(htmlEl.getAttribute("data-volume") || "1");
|
|
@@ -6938,6 +6972,9 @@ async function discoverMediaFromBrowser(page) {
|
|
|
6938
6972
|
durationInferred,
|
|
6939
6973
|
playbackStartRaw,
|
|
6940
6974
|
mediaStartRaw,
|
|
6975
|
+
playbackRateRaw,
|
|
6976
|
+
automationRaw,
|
|
6977
|
+
defaultPlaybackRate,
|
|
6941
6978
|
loop,
|
|
6942
6979
|
hasAudio,
|
|
6943
6980
|
volume,
|
|
@@ -6947,7 +6984,17 @@ async function discoverMediaFromBrowser(page) {
|
|
|
6947
6984
|
return results;
|
|
6948
6985
|
});
|
|
6949
6986
|
return elements.map(
|
|
6950
|
-
({
|
|
6987
|
+
({
|
|
6988
|
+
endRaw,
|
|
6989
|
+
durationRaw,
|
|
6990
|
+
intrinsicDuration,
|
|
6991
|
+
playbackStartRaw,
|
|
6992
|
+
mediaStartRaw,
|
|
6993
|
+
playbackRateRaw,
|
|
6994
|
+
automationRaw,
|
|
6995
|
+
defaultPlaybackRate,
|
|
6996
|
+
...element
|
|
6997
|
+
}) => ({
|
|
6951
6998
|
...element,
|
|
6952
6999
|
end: parseStrictFiniteTimingNumber(endRaw) ?? 0,
|
|
6953
7000
|
duration: element.durationInferred && Number.isFinite(intrinsicDuration) && intrinsicDuration > 0 ? intrinsicDuration : parseStrictFiniteTimingNumber(durationRaw) ?? 0,
|
|
@@ -6957,7 +7004,14 @@ async function discoverMediaFromBrowser(page) {
|
|
|
6957
7004
|
if (name === "data-media-start") return mediaStartRaw;
|
|
6958
7005
|
return null;
|
|
6959
7006
|
}
|
|
6960
|
-
})
|
|
7007
|
+
}),
|
|
7008
|
+
playbackRate: resolveRateSpec(
|
|
7009
|
+
automationRaw,
|
|
7010
|
+
readPlaybackRate(
|
|
7011
|
+
(name) => name === "data-playback-rate" ? playbackRateRaw : null,
|
|
7012
|
+
defaultPlaybackRate
|
|
7013
|
+
)
|
|
7014
|
+
)
|
|
6961
7015
|
})
|
|
6962
7016
|
);
|
|
6963
7017
|
}
|
|
@@ -7425,16 +7479,28 @@ function authoredMediaStarts(html) {
|
|
|
7425
7479
|
}
|
|
7426
7480
|
return starts;
|
|
7427
7481
|
}
|
|
7428
|
-
function
|
|
7482
|
+
function isVideoAudio(audio, videoId) {
|
|
7483
|
+
return audio.type === "video" && audio.id === videoAudioId(videoId);
|
|
7484
|
+
}
|
|
7485
|
+
function adoptRuntimeMediaTiming(composition, el, authored) {
|
|
7429
7486
|
const shift = el.mediaStart - authored;
|
|
7430
|
-
if (el.mediaStart <= 0 || Math.abs(shift) <= BROWSER_MEDIA_EPSILON) return;
|
|
7431
7487
|
const entries = el.tagName === "video" ? [
|
|
7432
7488
|
...composition.videos.filter((video) => video.id === el.id),
|
|
7433
|
-
...composition.audios.filter(
|
|
7434
|
-
(audio) => audio.type === "video" && audio.id === `${el.id}-audio`
|
|
7435
|
-
)
|
|
7489
|
+
...composition.audios.filter((audio) => isVideoAudio(audio, el.id))
|
|
7436
7490
|
] : composition.audios.filter((audio) => audio.type !== "video" && audio.id === el.id);
|
|
7437
|
-
for (const entry of entries)
|
|
7491
|
+
for (const entry of entries) {
|
|
7492
|
+
if (typeof entry.playbackRate !== "object") {
|
|
7493
|
+
if (typeof el.playbackRate === "object") {
|
|
7494
|
+
const consumed = Math.max(0, entry.mediaStart - authored);
|
|
7495
|
+
const head = timeAtSourceTime(normalizeRateSpec(entry.playbackRate), consumed);
|
|
7496
|
+
entry.mediaStart += sourceTimeAt(el.playbackRate, head) - consumed;
|
|
7497
|
+
entry.playbackRate = shiftRateLane(el.playbackRate, head);
|
|
7498
|
+
} else {
|
|
7499
|
+
entry.playbackRate = el.playbackRate;
|
|
7500
|
+
}
|
|
7501
|
+
}
|
|
7502
|
+
if (el.mediaStart > 0 && Math.abs(shift) > BROWSER_MEDIA_EPSILON) entry.mediaStart += shift;
|
|
7503
|
+
}
|
|
7438
7504
|
}
|
|
7439
7505
|
function reconcileBrowserMediaEnd(existingEnd, projectedEnd, sourceChanged, durationInferred) {
|
|
7440
7506
|
if (projectedEnd <= 0) return existingEnd;
|
|
@@ -7718,7 +7784,7 @@ async function runProbeStage(input) {
|
|
|
7718
7784
|
sourceChanged,
|
|
7719
7785
|
el.durationInferred
|
|
7720
7786
|
);
|
|
7721
|
-
|
|
7787
|
+
adoptRuntimeMediaTiming(
|
|
7722
7788
|
composition,
|
|
7723
7789
|
el,
|
|
7724
7790
|
authoredStarts.get(el.id) ?? existing.mediaStart
|
|
@@ -7741,6 +7807,7 @@ async function runProbeStage(input) {
|
|
|
7741
7807
|
start: el.start,
|
|
7742
7808
|
end: resolveBrowserMediaEnd(el.start, el.end, el.duration),
|
|
7743
7809
|
mediaStart: el.mediaStart,
|
|
7810
|
+
playbackRate: el.playbackRate,
|
|
7744
7811
|
loop: el.loop,
|
|
7745
7812
|
hasAudio: el.hasAudio && !el.muted
|
|
7746
7813
|
});
|
|
@@ -7765,7 +7832,7 @@ async function runProbeStage(input) {
|
|
|
7765
7832
|
sourceChanged,
|
|
7766
7833
|
el.durationInferred
|
|
7767
7834
|
);
|
|
7768
|
-
|
|
7835
|
+
adoptRuntimeMediaTiming(
|
|
7769
7836
|
composition,
|
|
7770
7837
|
el,
|
|
7771
7838
|
authoredStarts.get(el.id) ?? existing.mediaStart
|
|
@@ -7783,6 +7850,7 @@ async function runProbeStage(input) {
|
|
|
7783
7850
|
end: resolveBrowserMediaEnd(el.start, el.end, el.duration),
|
|
7784
7851
|
mediaStart: el.mediaStart,
|
|
7785
7852
|
loop: el.loop,
|
|
7853
|
+
playbackRate: el.playbackRate,
|
|
7786
7854
|
layer: 0,
|
|
7787
7855
|
volume: el.volume,
|
|
7788
7856
|
type: "audio"
|
|
@@ -8380,7 +8448,7 @@ function appendAutoDetectedVideoAudio(composition, extracted) {
|
|
|
8380
8448
|
const video = composition.videos.find((v) => v.id === ext.videoId);
|
|
8381
8449
|
if (!video || !video.hasAudio || video.hidden || existingAudioSrcs.has(video.src)) continue;
|
|
8382
8450
|
composition.audios.push({
|
|
8383
|
-
id:
|
|
8451
|
+
id: videoAudioId(video.id),
|
|
8384
8452
|
src: video.src,
|
|
8385
8453
|
start: video.start,
|
|
8386
8454
|
end: video.end,
|
|
@@ -8401,7 +8469,7 @@ import { rmSync as rmSync7 } from "fs";
|
|
|
8401
8469
|
|
|
8402
8470
|
// ../producer/src/services/render/audioPadTrim.ts
|
|
8403
8471
|
import { spawn } from "child_process";
|
|
8404
|
-
import { mkdtempSync as mkdtempSync3,
|
|
8472
|
+
import { mkdtempSync as mkdtempSync3, rmSync as rmSync6 } from "fs";
|
|
8405
8473
|
import { dirname as dirname6, join as join16 } from "path";
|
|
8406
8474
|
|
|
8407
8475
|
// ../producer/src/services/render/audioTruePeak.ts
|
|
@@ -8648,7 +8716,7 @@ async function enforceAacTruePeak(input) {
|
|
|
8648
8716
|
}
|
|
8649
8717
|
if (truePeakDbfs <= AAC_DELIVERY_TRUE_PEAK_DBFS) {
|
|
8650
8718
|
if (measuredPath !== correctedPath) return { success: true };
|
|
8651
|
-
|
|
8719
|
+
renameWithRetry(correctedPath, input.audioPath);
|
|
8652
8720
|
return { success: true, loweredDb: Number((-attenuationDb).toFixed(2)) };
|
|
8653
8721
|
}
|
|
8654
8722
|
if (pass === MAX_TRUE_PEAK_CORRECTION_PASSES) break;
|
|
@@ -8838,6 +8906,7 @@ async function runAudioStage(input) {
|
|
|
8838
8906
|
const result = await mixAudioForDelivery(input, duration, pcmSourcePath);
|
|
8839
8907
|
let audioLoweredDb;
|
|
8840
8908
|
if (result.hasAudio) {
|
|
8909
|
+
const guardStart = Date.now();
|
|
8841
8910
|
const peak = await constrainAacTruePeak({
|
|
8842
8911
|
audioPath: result.audioOutputPath,
|
|
8843
8912
|
sourcePath: pcmSourcePath,
|
|
@@ -8847,6 +8916,7 @@ async function runAudioStage(input) {
|
|
|
8847
8916
|
});
|
|
8848
8917
|
if (!peak.success) throw encoderFailureError("Audio true-peak check failed", peak);
|
|
8849
8918
|
audioLoweredDb = peak.loweredDb;
|
|
8919
|
+
input.log?.info("[audio] phases", { ...result.audioPhaseMs, guard: Date.now() - guardStart });
|
|
8850
8920
|
}
|
|
8851
8921
|
return { ...result, audioLoweredDb, audioProcessMs: Date.now() - stageStart };
|
|
8852
8922
|
} finally {
|
|
@@ -8872,6 +8942,7 @@ async function mixAudioForDelivery(input, duration, pcmSourcePath) {
|
|
|
8872
8942
|
let hasAudio = false;
|
|
8873
8943
|
let audioError;
|
|
8874
8944
|
let audioFailures;
|
|
8945
|
+
let audioPhaseMs;
|
|
8875
8946
|
if (audios.length > 0) {
|
|
8876
8947
|
let audioResult;
|
|
8877
8948
|
try {
|
|
@@ -8921,6 +8992,7 @@ async function mixAudioForDelivery(input, duration, pcmSourcePath) {
|
|
|
8921
8992
|
assertAudioNotInterrupted(audioResult.failures);
|
|
8922
8993
|
hasAudio = audioResult.success;
|
|
8923
8994
|
audioFailures = audioResult.failures;
|
|
8995
|
+
audioPhaseMs = audioResult.phaseMs;
|
|
8924
8996
|
if (!hasAudio) {
|
|
8925
8997
|
audioError = audioResult.error ?? "audio mix failed for an unknown reason";
|
|
8926
8998
|
for (const failure of audioResult.failures ?? []) {
|
|
@@ -8939,7 +9011,8 @@ async function mixAudioForDelivery(input, duration, pcmSourcePath) {
|
|
|
8939
9011
|
audioOutputPath,
|
|
8940
9012
|
hasAudio,
|
|
8941
9013
|
audioError,
|
|
8942
|
-
audioFailures
|
|
9014
|
+
audioFailures,
|
|
9015
|
+
audioPhaseMs
|
|
8943
9016
|
};
|
|
8944
9017
|
}
|
|
8945
9018
|
|
|
@@ -9054,6 +9127,7 @@ async function runCaptureStage(input) {
|
|
|
9054
9127
|
let { workerCount } = plan2;
|
|
9055
9128
|
const { forceScreenshot } = plan2;
|
|
9056
9129
|
let lastBrowserConsole = [];
|
|
9130
|
+
const workerPageErrors = [];
|
|
9057
9131
|
let captureBeyondViewport = probeSession?.options.captureBeyondViewport;
|
|
9058
9132
|
const captureCfg = cfg.forceScreenshot === forceScreenshot ? cfg : { ...cfg, forceScreenshot };
|
|
9059
9133
|
if (frameRange !== void 0) {
|
|
@@ -9091,6 +9165,7 @@ async function runCaptureStage(input) {
|
|
|
9091
9165
|
abortSignal,
|
|
9092
9166
|
frameRangeStart: frameRange?.startFrame,
|
|
9093
9167
|
dedupPerfs,
|
|
9168
|
+
pageErrorLines: workerPageErrors,
|
|
9094
9169
|
onProgress: (progress) => {
|
|
9095
9170
|
if (progress.latestWorkerPhase) {
|
|
9096
9171
|
if (progress.capturedFrames === 0) reportWorkerStartup(job, progress, onProgress);
|
|
@@ -9111,6 +9186,11 @@ async function runCaptureStage(input) {
|
|
|
9111
9186
|
},
|
|
9112
9187
|
cfg: captureCfg,
|
|
9113
9188
|
log
|
|
9189
|
+
}).catch((error) => {
|
|
9190
|
+
throw wrapCaptureStageError(
|
|
9191
|
+
error,
|
|
9192
|
+
withWorkerPageErrors(probeSession?.browserConsoleBuffer ?? [], workerPageErrors)
|
|
9193
|
+
);
|
|
9114
9194
|
});
|
|
9115
9195
|
captureAttempts.push(...attempts);
|
|
9116
9196
|
const lastAttempt = attempts[attempts.length - 1];
|
|
@@ -9123,6 +9203,7 @@ async function runCaptureStage(input) {
|
|
|
9123
9203
|
await closeCaptureSession(probeSession);
|
|
9124
9204
|
probeSession = null;
|
|
9125
9205
|
}
|
|
9206
|
+
lastBrowserConsole = withWorkerPageErrors(lastBrowserConsole, workerPageErrors);
|
|
9126
9207
|
} else {
|
|
9127
9208
|
const sequential = await runSequentialDiskCapture(
|
|
9128
9209
|
input,
|
|
@@ -10400,7 +10481,7 @@ function videoEncoderOptions(input, engineCfg) {
|
|
|
10400
10481
|
};
|
|
10401
10482
|
}
|
|
10402
10483
|
function canEncodeWhileCapturing(input, workerCount, cpuCount) {
|
|
10403
|
-
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"
|
|
10484
|
+
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";
|
|
10404
10485
|
}
|
|
10405
10486
|
async function readLandedFrame(workerPath, mergedPath) {
|
|
10406
10487
|
if (workerPath !== void 0) {
|
|
@@ -11055,6 +11136,7 @@ async function executeDiskCaptureWithAdaptiveRetry(options) {
|
|
|
11055
11136
|
options.cfg
|
|
11056
11137
|
);
|
|
11057
11138
|
pushWorkerDedupPerfs(workerResults, options.dedupPerfs);
|
|
11139
|
+
if (options.pageErrorLines) pushWorkerPageErrors(workerResults, options.pageErrorLines);
|
|
11058
11140
|
} finally {
|
|
11059
11141
|
await mergeWorkerFrames(attemptWorkDir, tasks, options.framesDir);
|
|
11060
11142
|
}
|
|
@@ -11317,13 +11399,36 @@ function colorGradingValueHasLut(rawAttributeValue) {
|
|
|
11317
11399
|
return false;
|
|
11318
11400
|
}
|
|
11319
11401
|
}
|
|
11320
|
-
|
|
11402
|
+
var PROBE_READ_TIMEOUT_MS = 5e3;
|
|
11403
|
+
async function evaluateWithinBound(page, fn, what, log) {
|
|
11404
|
+
let timer;
|
|
11405
|
+
const timedOut = new Promise((_, reject) => {
|
|
11406
|
+
timer = setTimeout(
|
|
11407
|
+
() => reject(new Error(`no answer within ${PROBE_READ_TIMEOUT_MS} ms (page busy)`)),
|
|
11408
|
+
PROBE_READ_TIMEOUT_MS
|
|
11409
|
+
);
|
|
11410
|
+
});
|
|
11411
|
+
try {
|
|
11412
|
+
return await Promise.race([page.evaluate(fn), timedOut]);
|
|
11413
|
+
} catch (err) {
|
|
11414
|
+
log.warn(`[Render] live ${what} read skipped; using the static answer`, {
|
|
11415
|
+
error: err instanceof Error ? err.message : String(err)
|
|
11416
|
+
});
|
|
11417
|
+
throw err;
|
|
11418
|
+
} finally {
|
|
11419
|
+
clearTimeout(timer);
|
|
11420
|
+
}
|
|
11421
|
+
}
|
|
11422
|
+
async function resolveCompositionElementCount(probeSession, html, log = defaultLogger) {
|
|
11321
11423
|
if (probeSession?.isInitialized) {
|
|
11322
11424
|
try {
|
|
11323
|
-
const liveCount = await
|
|
11425
|
+
const liveCount = await evaluateWithinBound(
|
|
11426
|
+
probeSession.page,
|
|
11324
11427
|
// Live HTMLCollection length — avoids materializing a static NodeList
|
|
11325
11428
|
// on the large-DOM comps this gate exists to catch (review nit).
|
|
11326
|
-
() => document.getElementsByTagName("*").length
|
|
11429
|
+
() => document.getElementsByTagName("*").length,
|
|
11430
|
+
"element count",
|
|
11431
|
+
log
|
|
11327
11432
|
);
|
|
11328
11433
|
if (typeof liveCount === "number" && Number.isFinite(liveCount)) {
|
|
11329
11434
|
return { count: liveCount, source: "live" };
|
|
@@ -11411,11 +11516,11 @@ function probeAdaptersUsed() {
|
|
|
11411
11516
|
}
|
|
11412
11517
|
return used;
|
|
11413
11518
|
}
|
|
11414
|
-
async function resolveAdaptersUsed(probeSession, html) {
|
|
11519
|
+
async function resolveAdaptersUsed(probeSession, html, log = defaultLogger) {
|
|
11415
11520
|
const staticAdapters = detectAdaptersStatic(html);
|
|
11416
11521
|
if (!probeSession?.isInitialized) return staticAdapters;
|
|
11417
11522
|
try {
|
|
11418
|
-
const live = await probeSession.page
|
|
11523
|
+
const live = await evaluateWithinBound(probeSession.page, probeAdaptersUsed, "adapters", log);
|
|
11419
11524
|
if (!Array.isArray(live)) return staticAdapters;
|
|
11420
11525
|
const detected = /* @__PURE__ */ new Set([...staticAdapters, ...live]);
|
|
11421
11526
|
return KNOWN_RUNTIME_ADAPTERS.filter((name) => detected.has(name));
|
|
@@ -11673,7 +11778,10 @@ async function executeRenderPipeline(input) {
|
|
|
11673
11778
|
);
|
|
11674
11779
|
const artifactTransaction = new ArtifactTransaction(
|
|
11675
11780
|
outputPath,
|
|
11676
|
-
isPngSequence || isHls ? "directory" : "file"
|
|
11781
|
+
isPngSequence || isHls ? "directory" : "file",
|
|
11782
|
+
void 0,
|
|
11783
|
+
void 0,
|
|
11784
|
+
log
|
|
11677
11785
|
);
|
|
11678
11786
|
const stagedOutputPath = artifactTransaction.stagingPath;
|
|
11679
11787
|
const needsAlpha = outputNeedsAlpha(outputFormat);
|
|
@@ -12172,8 +12280,8 @@ async function executeRenderPipeline(input) {
|
|
|
12172
12280
|
vfxHostCount,
|
|
12173
12281
|
vfxCapture,
|
|
12174
12282
|
vfxTypes
|
|
12175
|
-
} = await resolveCompositionElementCount(probeSession, compiled.html);
|
|
12176
|
-
const adaptersUsed = await resolveAdaptersUsed(probeSession, compiled.html);
|
|
12283
|
+
} = await resolveCompositionElementCount(probeSession, compiled.html, log);
|
|
12284
|
+
const adaptersUsed = await resolveAdaptersUsed(probeSession, compiled.html, log);
|
|
12177
12285
|
const deShortBandEnabled = deShortBandMaxElements > 0;
|
|
12178
12286
|
const deShortBandOpen = deShortBandEnabled && deShortBandMinFrames > 0 && compositionElementCountSource === "live" && compositionElementCount <= deShortBandMaxElements;
|
|
12179
12287
|
const deShortBandRoute = process.env.HF_DE_SHORT_BAND_ROUTE === "true";
|
|
@@ -13433,7 +13541,6 @@ import {
|
|
|
13433
13541
|
existsSync as existsSync20,
|
|
13434
13542
|
linkSync,
|
|
13435
13543
|
mkdirSync as mkdirSync12,
|
|
13436
|
-
renameSync as renameSync5,
|
|
13437
13544
|
rmSync as rmSync11,
|
|
13438
13545
|
writeFileSync as writeFileSync8
|
|
13439
13546
|
} from "fs";
|
|
@@ -14360,14 +14467,7 @@ import { writeFileSync as writeFileSync7, writeSync } from "fs";
|
|
|
14360
14467
|
import { join as join30 } from "path";
|
|
14361
14468
|
|
|
14362
14469
|
// ../producer/src/services/distributed/mp4Stitch.ts
|
|
14363
|
-
import {
|
|
14364
|
-
createReadStream as createReadStream4,
|
|
14365
|
-
createWriteStream,
|
|
14366
|
-
mkdirSync as mkdirSync10,
|
|
14367
|
-
mkdtempSync as mkdtempSync4,
|
|
14368
|
-
renameSync as renameSync4,
|
|
14369
|
-
rmSync as rmSync10
|
|
14370
|
-
} from "fs";
|
|
14470
|
+
import { createReadStream as createReadStream4, createWriteStream, mkdirSync as mkdirSync10, mkdtempSync as mkdtempSync4, rmSync as rmSync10 } from "fs";
|
|
14371
14471
|
import { open } from "fs/promises";
|
|
14372
14472
|
import { dirname as dirname11, join as join29 } from "path";
|
|
14373
14473
|
import { finished, pipeline } from "stream/promises";
|
|
@@ -14741,7 +14841,7 @@ async function writeStitchedMp4(chunkPaths, outputPath, audioPath) {
|
|
|
14741
14841
|
for (const [i, path] of sourcePaths.entries()) await copyPayload(path, layouts[i], i, out);
|
|
14742
14842
|
out.end();
|
|
14743
14843
|
await finished(out);
|
|
14744
|
-
|
|
14844
|
+
renameWithRetry(join29(workDir, "out.mp4"), outputPath);
|
|
14745
14845
|
} finally {
|
|
14746
14846
|
out.destroy();
|
|
14747
14847
|
rmSync10(workDir, { recursive: true, force: true });
|
|
@@ -15467,7 +15567,10 @@ async function compilePlanComposition(projectDir, config, planDir, options) {
|
|
|
15467
15567
|
const needsAlpha = outputNeedsAlpha(config.format);
|
|
15468
15568
|
const remoteFiles = Object.entries(options.remoteFiles ?? {});
|
|
15469
15569
|
const remoteLocalPath = (rel) => join32(projectDir, ...rel.split("/"));
|
|
15470
|
-
for (const [, file] of remoteFiles)
|
|
15570
|
+
for (const [, file] of remoteFiles) {
|
|
15571
|
+
declareContentAddressedUrl(file.url, file.sha256);
|
|
15572
|
+
if (file.probeFactsUrl) declareProbeFactsUrl(file.url, file.probeFactsUrl);
|
|
15573
|
+
}
|
|
15471
15574
|
const urlByAbsentLocalPath = new Map(
|
|
15472
15575
|
remoteFiles.map(([rel, file]) => [remoteLocalPath(rel), file.url])
|
|
15473
15576
|
);
|
|
@@ -15542,7 +15645,7 @@ async function compilePlanComposition(projectDir, config, planDir, options) {
|
|
|
15542
15645
|
if (probeResult.fileServer) closeFileServerSafely(probeResult.fileServer, "plan", log);
|
|
15543
15646
|
if (probeResult.probeSession) {
|
|
15544
15647
|
try {
|
|
15545
|
-
const { closeCaptureSession: closeCaptureSession2 } = await import("./src-
|
|
15648
|
+
const { closeCaptureSession: closeCaptureSession2 } = await import("./src-HITT6NWG.js");
|
|
15546
15649
|
await closeCaptureSession2(probeResult.probeSession);
|
|
15547
15650
|
} catch (err) {
|
|
15548
15651
|
log.warn("[plan] probe session close failed", {
|
|
@@ -15589,7 +15692,8 @@ function mixPlanAudio(c, compiledDir) {
|
|
|
15589
15692
|
audios: c.composition.audios,
|
|
15590
15693
|
masterFxChain: c.composition.masterFxChain,
|
|
15591
15694
|
abortSignal: c.abortSignal,
|
|
15592
|
-
assertNotAborted: c.assertNotAborted
|
|
15695
|
+
assertNotAborted: c.assertNotAborted,
|
|
15696
|
+
log: c.log
|
|
15593
15697
|
});
|
|
15594
15698
|
}
|
|
15595
15699
|
async function extractPlanVideos(c, deferRangeExtraction) {
|
|
@@ -15608,6 +15712,7 @@ async function extractPlanVideos(c, deferRangeExtraction) {
|
|
|
15608
15712
|
if (extractResult.failureToEnforce) throw extractResult.failureToEnforce;
|
|
15609
15713
|
if (extractResult.extractionResult) {
|
|
15610
15714
|
assertVideoExtractionSucceeded(extractResult.extractionResult);
|
|
15715
|
+
c.log.info("[plan] extract phases", { ...extractResult.extractionResult.phaseBreakdown });
|
|
15611
15716
|
}
|
|
15612
15717
|
return extractResult;
|
|
15613
15718
|
}
|
|
@@ -15653,12 +15758,12 @@ async function buildLocalExecutionPlan(projectDir, config, executionPlanDir, opt
|
|
|
15653
15758
|
const videoSourcesDir = join32(planDir, "video-sources");
|
|
15654
15759
|
rmSync11(videoSourcesDir, { recursive: true, force: true });
|
|
15655
15760
|
if (existsSync20(stagedVideoFrames)) {
|
|
15656
|
-
|
|
15761
|
+
renameWithRetry(stagedVideoFrames, videoFramesDst);
|
|
15657
15762
|
} else {
|
|
15658
15763
|
mkdirSync12(videoFramesDst, { recursive: true });
|
|
15659
15764
|
}
|
|
15660
15765
|
if (existsSync20(finalCompiledDir)) rmSync11(finalCompiledDir, { recursive: true, force: true });
|
|
15661
|
-
|
|
15766
|
+
renameWithRetry(compiledDir, finalCompiledDir);
|
|
15662
15767
|
const shipVideoSource = createVideoSourceShipper({
|
|
15663
15768
|
planDir,
|
|
15664
15769
|
projectDir,
|
|
@@ -15761,7 +15866,7 @@ async function buildLocalExecutionPlan(projectDir, config, executionPlanDir, opt
|
|
|
15761
15866
|
}
|
|
15762
15867
|
const planAudioPath = join32(planDir, PLAN_AUDIO_RELATIVE_PATH);
|
|
15763
15868
|
if (audioResult?.hasAudio && existsSync20(audioResult.audioOutputPath)) {
|
|
15764
|
-
|
|
15869
|
+
renameWithRetry(audioResult.audioOutputPath, planAudioPath);
|
|
15765
15870
|
}
|
|
15766
15871
|
if (chunksCarryAudio && existsSync20(planAudioPath)) {
|
|
15767
15872
|
if (options.sliceChunkAudio) {
|
|
@@ -17193,7 +17298,7 @@ function startServer(options = {}) {
|
|
|
17193
17298
|
});
|
|
17194
17299
|
async function shutdown(signal) {
|
|
17195
17300
|
log.info(`Received ${signal}, shutting down`);
|
|
17196
|
-
const { drainBrowserPool } = await import("./src-
|
|
17301
|
+
const { drainBrowserPool } = await import("./src-HITT6NWG.js");
|
|
17197
17302
|
await drainBrowserPool().catch(() => {
|
|
17198
17303
|
});
|
|
17199
17304
|
const handle = await Promise.race([
|
|
@@ -17237,7 +17342,6 @@ import {
|
|
|
17237
17342
|
mkdtempSync as mkdtempSync7,
|
|
17238
17343
|
readFileSync as readFileSync12,
|
|
17239
17344
|
readdirSync as readdirSync9,
|
|
17240
|
-
renameSync as renameSync7,
|
|
17241
17345
|
rmSync as rmSync14,
|
|
17242
17346
|
statSync as statSync9,
|
|
17243
17347
|
writeFileSync as writeFileSync11
|
|
@@ -17252,7 +17356,6 @@ import {
|
|
|
17252
17356
|
linkSync as linkSync2,
|
|
17253
17357
|
mkdirSync as mkdirSync14,
|
|
17254
17358
|
mkdtempSync as mkdtempSync6,
|
|
17255
|
-
renameSync as renameSync6,
|
|
17256
17359
|
rmSync as rmSync13,
|
|
17257
17360
|
statSync as statSync8,
|
|
17258
17361
|
writeFileSync as writeFileSync10
|
|
@@ -17345,7 +17448,7 @@ var LocalPlanV2ArtifactPublisher = class {
|
|
|
17345
17448
|
if (!canFallbackToCopy(error)) throw error;
|
|
17346
17449
|
copyFileSync5(blob.sourcePath, temporaryPath);
|
|
17347
17450
|
}
|
|
17348
|
-
|
|
17451
|
+
renameWithRetry(temporaryPath, destinationPath);
|
|
17349
17452
|
} finally {
|
|
17350
17453
|
rmSync13(stagingDir, { recursive: true, force: true });
|
|
17351
17454
|
}
|
|
@@ -17359,7 +17462,7 @@ var LocalPlanV2ArtifactPublisher = class {
|
|
|
17359
17462
|
}
|
|
17360
17463
|
}
|
|
17361
17464
|
writeFileSync10(join37(this.temporaryDir, "plan.json"), manifestBytes, "utf-8");
|
|
17362
|
-
|
|
17465
|
+
renameWithRetry(this.temporaryDir, this.destinationDir);
|
|
17363
17466
|
this.#committed = true;
|
|
17364
17467
|
}
|
|
17365
17468
|
async abort() {
|
|
@@ -17626,7 +17729,7 @@ function writeBlob(sourcePath, destinationPath) {
|
|
|
17626
17729
|
const temporaryPath = join38(temporaryDir, "blob");
|
|
17627
17730
|
try {
|
|
17628
17731
|
copyFileSync6(sourcePath, temporaryPath);
|
|
17629
|
-
|
|
17732
|
+
renameWithRetry(temporaryPath, destinationPath);
|
|
17630
17733
|
} finally {
|
|
17631
17734
|
rmSync14(temporaryDir, { recursive: true, force: true });
|
|
17632
17735
|
}
|
|
@@ -17758,7 +17861,7 @@ function createPlanV2FromExecutionPlan(executionPlanDir, planV2Dir) {
|
|
|
17758
17861
|
canonicalJsonStringify(publication.manifest),
|
|
17759
17862
|
"utf-8"
|
|
17760
17863
|
);
|
|
17761
|
-
|
|
17864
|
+
renameWithRetry(tempDir, planV2Dir);
|
|
17762
17865
|
return resultFromManifest(planV2Dir, publication.manifest);
|
|
17763
17866
|
} catch (error) {
|
|
17764
17867
|
rmSync14(tempDir, { recursive: true, force: true });
|
|
@@ -18043,7 +18146,7 @@ function materializePlanV2Target(planV2Dir, target, destinationDir, options = {}
|
|
|
18043
18146
|
}),
|
|
18044
18147
|
"utf-8"
|
|
18045
18148
|
);
|
|
18046
|
-
|
|
18149
|
+
renameWithRetry(tempDir, destinationDir);
|
|
18047
18150
|
} catch (error) {
|
|
18048
18151
|
rmSync14(tempDir, { recursive: true, force: true });
|
|
18049
18152
|
throw error;
|
|
@@ -18121,7 +18224,6 @@ import {
|
|
|
18121
18224
|
mkdtempSync as mkdtempSync8,
|
|
18122
18225
|
readFileSync as readFileSync13,
|
|
18123
18226
|
readdirSync as readdirSync10,
|
|
18124
|
-
renameSync as renameSync8,
|
|
18125
18227
|
rmSync as rmSync15,
|
|
18126
18228
|
statSync as statSync10,
|
|
18127
18229
|
writeFileSync as writeFileSync12
|
|
@@ -18181,7 +18283,7 @@ async function assemble(planDir, chunkOutputs, audioPath, outputPath, options) {
|
|
|
18181
18283
|
const finalPath = join39(workDir, `output.${format}`);
|
|
18182
18284
|
const audio = audioPath !== null && existsSync26(audioPath) ? audioPath : null;
|
|
18183
18285
|
await writeJoined(ctx, videoSources, audio, finalPath);
|
|
18184
|
-
|
|
18286
|
+
renameWithRetry(finalPath, outputPath);
|
|
18185
18287
|
log.info("[assemble] stage timings", {
|
|
18186
18288
|
...stageMs,
|
|
18187
18289
|
chunks: chunkPaths.length,
|
|
@@ -18433,6 +18535,7 @@ function mergePngFrameDirs(chunkPaths, outputPath, totalFrames, audioPath, start
|
|
|
18433
18535
|
// ../producer/src/services/distributed/renderChunk.ts
|
|
18434
18536
|
import { randomBytes } from "crypto";
|
|
18435
18537
|
import { existsSync as existsSync27, mkdirSync as mkdirSync17, readFileSync as readFileSync14, readdirSync as readdirSync11, rmSync as rmSync16, writeFileSync as writeFileSync13 } from "fs";
|
|
18538
|
+
import { cpus as cpus3 } from "os";
|
|
18436
18539
|
import { join as join40 } from "path";
|
|
18437
18540
|
var LEGACY_DISTRIBUTED_VP9_CPU_USED = 2;
|
|
18438
18541
|
function validatePlanVideosForChunk(value) {
|
|
@@ -18721,6 +18824,7 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath, options) {
|
|
|
18721
18824
|
let forceScreenshotForChunk = encoder.forceScreenshot;
|
|
18722
18825
|
let shownBoxes;
|
|
18723
18826
|
let extraction;
|
|
18827
|
+
const overlap = { current: null };
|
|
18724
18828
|
try {
|
|
18725
18829
|
if (chunkWorkerCount === 1 || !forceScreenshotForChunk) {
|
|
18726
18830
|
const bootStarted = Date.now();
|
|
@@ -18808,6 +18912,59 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath, options) {
|
|
|
18808
18912
|
videoFrameLookup,
|
|
18809
18913
|
frameCacheOptions(cfg, chunkWorkerCount)
|
|
18810
18914
|
);
|
|
18915
|
+
const isPngSequence = plan2.dimensions.format === "png-sequence";
|
|
18916
|
+
outputKind = isPngSequence ? "frame-dir" : "file";
|
|
18917
|
+
const presetFormat = isPngSequence ? "mp4" : plan2.dimensions.format;
|
|
18918
|
+
const basePreset = getEncoderPreset(job.config.quality, presetFormat, void 0);
|
|
18919
|
+
const preset = resolvePresetForLockedEncoder(basePreset, encoder.encoder);
|
|
18920
|
+
const effectiveQuality = encoder.crf ?? preset.quality;
|
|
18921
|
+
const effectiveBitrate = encoder.crf != null ? void 0 : encoder.bitrate;
|
|
18922
|
+
const videoOnlyPath = encoder.chunksCarryAudio ? `${outputChunkPath}.video.mp4` : outputChunkPath;
|
|
18923
|
+
if (isPngSequence) {
|
|
18924
|
+
if (!existsSync27(outputChunkPath)) mkdirSync17(outputChunkPath, { recursive: true });
|
|
18925
|
+
} else {
|
|
18926
|
+
const outDir = join40(outputChunkPath, "..");
|
|
18927
|
+
if (!existsSync27(outDir)) mkdirSync17(outDir, { recursive: true });
|
|
18928
|
+
}
|
|
18929
|
+
const encodeInput = {
|
|
18930
|
+
job,
|
|
18931
|
+
log,
|
|
18932
|
+
outputPath: videoOnlyPath,
|
|
18933
|
+
framesDir,
|
|
18934
|
+
videoOnlyPath,
|
|
18935
|
+
width: Math.round(plan2.dimensions.width * encoder.deviceScaleFactor),
|
|
18936
|
+
height: Math.round(plan2.dimensions.height * encoder.deviceScaleFactor),
|
|
18937
|
+
needsAlpha: plan2.dimensions.format !== "mp4",
|
|
18938
|
+
captureImageFormat: captureOptions.format ?? "jpeg",
|
|
18939
|
+
// The encoder writes video only; audio joins at assemble time or in the
|
|
18940
|
+
// chunk that carries audio. Suppressing `hasAudio` skips the png-sequence audio
|
|
18941
|
+
// sidecar AND the mp4 audio mux.
|
|
18942
|
+
hasAudio: false,
|
|
18943
|
+
isPngSequence,
|
|
18944
|
+
// `DistributedFormat` has no "gif" member — distributed chunks are
|
|
18945
|
+
// always video segments (gif renders in-process only).
|
|
18946
|
+
isGif: false,
|
|
18947
|
+
preset,
|
|
18948
|
+
effectiveQuality,
|
|
18949
|
+
effectiveBitrate,
|
|
18950
|
+
engineConfig: {
|
|
18951
|
+
ffmpegEncodeTimeout: cfg.ffmpegEncodeTimeout,
|
|
18952
|
+
vp9CpuUsed: resolveLockedVp9CpuUsed(encoder) ?? cfg.vp9CpuUsed
|
|
18953
|
+
},
|
|
18954
|
+
// Distributed chunks emit a single ffmpeg call per chunk; the
|
|
18955
|
+
// in-process per-chunk-within-chunk path would re-split our
|
|
18956
|
+
// already-chunked work.
|
|
18957
|
+
enableChunkedEncode: false,
|
|
18958
|
+
chunkedEncodeSize: framesInChunk,
|
|
18959
|
+
abortSignal: void 0,
|
|
18960
|
+
assertNotAborted: () => {
|
|
18961
|
+
},
|
|
18962
|
+
// GOP === framesInChunk + force-keyframe at frame 0 → the chunk's
|
|
18963
|
+
// first frame is an IDR keyframe and concat-copy at assemble time
|
|
18964
|
+
// round-trips losslessly.
|
|
18965
|
+
lockGopForChunkConcat: !isPngSequence,
|
|
18966
|
+
gopSize: framesInChunk
|
|
18967
|
+
};
|
|
18811
18968
|
const captureStarted = Date.now();
|
|
18812
18969
|
captureMode = await runCaptureWithScreenshotFallback({
|
|
18813
18970
|
forceScreenshot: forceScreenshotForChunk,
|
|
@@ -18840,6 +18997,7 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath, options) {
|
|
|
18840
18997
|
}
|
|
18841
18998
|
const captureSession = session;
|
|
18842
18999
|
session = null;
|
|
19000
|
+
overlap.current = canEncodeWhileCapturing(encodeInput, chunkWorkerCount, cpus3().length) ? encodeWhileCapturing(encodeInput, framesInChunk) : null;
|
|
18843
19001
|
await runCaptureStage({
|
|
18844
19002
|
fileServer,
|
|
18845
19003
|
workDir,
|
|
@@ -18859,7 +19017,12 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath, options) {
|
|
|
18859
19017
|
abortSignal: void 0,
|
|
18860
19018
|
assertNotAborted: () => {
|
|
18861
19019
|
},
|
|
18862
|
-
frameRange: range
|
|
19020
|
+
frameRange: range,
|
|
19021
|
+
onFrameLanded: (frame) => overlap.current?.onFrameLanded(frame)
|
|
19022
|
+
}).catch(async (captureError) => {
|
|
19023
|
+
await overlap.current?.abort();
|
|
19024
|
+
overlap.current = null;
|
|
19025
|
+
throw captureError;
|
|
18863
19026
|
});
|
|
18864
19027
|
return observedChunkCaptureMode(capturePerfs);
|
|
18865
19028
|
},
|
|
@@ -18891,60 +19054,10 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath, options) {
|
|
|
18891
19054
|
log
|
|
18892
19055
|
);
|
|
18893
19056
|
framesEncoded = framesInChunk;
|
|
18894
|
-
const isPngSequence = plan2.dimensions.format === "png-sequence";
|
|
18895
|
-
outputKind = isPngSequence ? "frame-dir" : "file";
|
|
18896
|
-
const presetFormat = isPngSequence ? "mp4" : plan2.dimensions.format;
|
|
18897
|
-
const basePreset = getEncoderPreset(job.config.quality, presetFormat, void 0);
|
|
18898
|
-
const preset = resolvePresetForLockedEncoder(basePreset, encoder.encoder);
|
|
18899
|
-
const effectiveQuality = encoder.crf ?? preset.quality;
|
|
18900
|
-
const effectiveBitrate = encoder.crf != null ? void 0 : encoder.bitrate;
|
|
18901
|
-
const videoOnlyPath = encoder.chunksCarryAudio ? `${outputChunkPath}.video.mp4` : outputChunkPath;
|
|
18902
|
-
if (isPngSequence) {
|
|
18903
|
-
if (!existsSync27(outputChunkPath)) mkdirSync17(outputChunkPath, { recursive: true });
|
|
18904
|
-
} else {
|
|
18905
|
-
const outDir = join40(outputChunkPath, "..");
|
|
18906
|
-
if (!existsSync27(outDir)) mkdirSync17(outDir, { recursive: true });
|
|
18907
|
-
}
|
|
18908
19057
|
const encodeStarted = Date.now();
|
|
18909
|
-
|
|
18910
|
-
|
|
18911
|
-
|
|
18912
|
-
outputPath: videoOnlyPath,
|
|
18913
|
-
framesDir,
|
|
18914
|
-
videoOnlyPath,
|
|
18915
|
-
width: Math.round(plan2.dimensions.width * encoder.deviceScaleFactor),
|
|
18916
|
-
height: Math.round(plan2.dimensions.height * encoder.deviceScaleFactor),
|
|
18917
|
-
needsAlpha: plan2.dimensions.format !== "mp4",
|
|
18918
|
-
captureImageFormat: captureOptions.format ?? "jpeg",
|
|
18919
|
-
// The encoder writes video only; audio joins at assemble time or in the
|
|
18920
|
-
// chunk that carries audio. Suppressing `hasAudio` skips the png-sequence audio
|
|
18921
|
-
// sidecar AND the mp4 audio mux.
|
|
18922
|
-
hasAudio: false,
|
|
18923
|
-
isPngSequence,
|
|
18924
|
-
// `DistributedFormat` has no "gif" member — distributed chunks are
|
|
18925
|
-
// always video segments (gif renders in-process only).
|
|
18926
|
-
isGif: false,
|
|
18927
|
-
preset,
|
|
18928
|
-
effectiveQuality,
|
|
18929
|
-
effectiveBitrate,
|
|
18930
|
-
engineConfig: {
|
|
18931
|
-
ffmpegEncodeTimeout: cfg.ffmpegEncodeTimeout,
|
|
18932
|
-
vp9CpuUsed: resolveLockedVp9CpuUsed(encoder) ?? cfg.vp9CpuUsed
|
|
18933
|
-
},
|
|
18934
|
-
// Distributed chunks emit a single ffmpeg call per chunk; the
|
|
18935
|
-
// in-process per-chunk-within-chunk path would re-split our
|
|
18936
|
-
// already-chunked work.
|
|
18937
|
-
enableChunkedEncode: false,
|
|
18938
|
-
chunkedEncodeSize: framesInChunk,
|
|
18939
|
-
abortSignal: void 0,
|
|
18940
|
-
assertNotAborted: () => {
|
|
18941
|
-
},
|
|
18942
|
-
// GOP === framesInChunk + force-keyframe at frame 0 → the chunk's
|
|
18943
|
-
// first frame is an IDR keyframe and concat-copy at assemble time
|
|
18944
|
-
// round-trips losslessly.
|
|
18945
|
-
lockGopForChunkConcat: !isPngSequence,
|
|
18946
|
-
gopSize: framesInChunk
|
|
18947
|
-
});
|
|
19058
|
+
const overlapped = overlap.current;
|
|
19059
|
+
overlap.current = null;
|
|
19060
|
+
await (overlapped ? overlapped.finish() : runEncodeStage(encodeInput));
|
|
18948
19061
|
if (encoder.chunksCarryAudio) {
|
|
18949
19062
|
const audioScratchPath = `${outputChunkPath}.audio.m4a`;
|
|
18950
19063
|
const audioChunks = options?.frameRange ? chunksWithSubRange(chunks, chunkIndex, range) : { chunks, index: chunkIndex };
|
|
@@ -18962,6 +19075,8 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath, options) {
|
|
|
18962
19075
|
}
|
|
18963
19076
|
encodeStageMs = Date.now() - encodeStarted;
|
|
18964
19077
|
} finally {
|
|
19078
|
+
await overlap.current?.abort().catch(() => {
|
|
19079
|
+
});
|
|
18965
19080
|
await extraction?.catch(() => {
|
|
18966
19081
|
});
|
|
18967
19082
|
if (session) {
|
|
@@ -19074,6 +19189,10 @@ var READ_CHUNK_BYTES = 256 * 1024;
|
|
|
19074
19189
|
import { extname as extname7 } from "path";
|
|
19075
19190
|
var AUDIO_SIDECAR_MIN_BYTES = 32 * 1024 * 1024;
|
|
19076
19191
|
|
|
19192
|
+
// ../producer/src/services/distributed/probeFacts.ts
|
|
19193
|
+
import { writeFileSync as writeFileSync14 } from "fs";
|
|
19194
|
+
import { extname as extname8 } from "path";
|
|
19195
|
+
|
|
19077
19196
|
export {
|
|
19078
19197
|
createConsoleLogger,
|
|
19079
19198
|
defaultLogger,
|