hyperframes 0.8.192 → 0.8.193
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{add-TZU2UW7A.js → add-JC6DKZKC.js} +11 -11
- package/dist/{animatedGifPrep-NLAXC3VV.js → animatedGifPrep-S6KXJGEL.js} +5 -5
- package/dist/api.js +13 -13
- package/dist/{asset-JAJXA6LB.js → asset-XITFIFE6.js} +2 -2
- package/dist/{assetCataloger-4WTX3J4I.js → assetCataloger-K5FNKG35.js} +5 -5
- package/dist/{audio-XLWC7JKS.js → audio-364UHTY4.js} +11 -11
- package/dist/{auth-5K6X3NPJ.js → auth-5JEESRE6.js} +1 -1
- package/dist/{autoUpdate-RNV7SKGB.js → autoUpdate-RVVYEHAA.js} +3 -3
- package/dist/{backgroundChecks-QXLVZVGX.js → backgroundChecks-DCBIYWIQ.js} +3 -3
- package/dist/backgroundChecksWorker.js +3 -3
- package/dist/{batchRender-THKSPDZR.js → batchRender-ZZ4QMBAA.js} +3 -3
- package/dist/{beats-K7CGCFVL.js → beats-YEL65M6G.js} +7 -7
- package/dist/{benchmark-PHRDIXNL.js → benchmark-RBTRPA76.js} +8 -8
- package/dist/{browser-GN6R5ZSK.js → browser-BVAYXT4R.js} +3 -3
- package/dist/{bundleWithLocalizedFonts-C325UNR4.js → bundleWithLocalizedFonts-JLB2OYMT.js} +2 -2
- package/dist/{capture-6UBQFHZQ.js → capture-GBXTMYLZ.js} +9 -9
- package/dist/{capture-BZ7APOGQ.js → capture-NIFX6IRS.js} +2 -2
- package/dist/{captureCompositionFrame-VORSCTWC.js → captureCompositionFrame-ATNNKUL5.js} +10 -10
- package/dist/{catalog-PHU2RUZ3.js → catalog-AGIF5SM5.js} +11 -11
- package/dist/{catch-up-HCNRM46J.js → catch-up-SZ3ULDTI.js} +4 -4
- package/dist/{check-TJ5ZLB4I.js → check-YLQS3TF4.js} +33 -33
- package/dist/{checkBrowser-DWP7ZXJ7.js → checkBrowser-QH4FMCBO.js} +28 -28
- package/dist/{chunk-7LLRMYP6.js → chunk-2LSCYS2H.js} +2 -2
- package/dist/{chunk-KZOZN4PI.js → chunk-2NERNYCJ.js} +1 -1
- package/dist/{chunk-RHYOWDI6.js → chunk-2SFDWMSW.js} +2 -2
- package/dist/{chunk-AEXVVABM.js → chunk-3W4B6G7Y.js} +1 -1
- package/dist/{chunk-E5V6WEMK.js → chunk-4LXZJIVY.js} +9 -9
- package/dist/{chunk-YWRQHRDY.js → chunk-4PPWAQYV.js} +7 -7
- package/dist/{chunk-WOKVXK4J.js → chunk-4TKJWWPL.js} +1 -1
- package/dist/{chunk-NXMYHJAL.js → chunk-4VYPICIA.js} +29 -1
- package/dist/{chunk-6WNLQI63.js → chunk-5J6TWLFG.js} +3 -3
- package/dist/{chunk-ULTKB5FC.js → chunk-6DLCOQR4.js} +461 -427
- package/dist/{chunk-CXRZBWSH.js → chunk-6LWUPIKD.js} +9 -9
- package/dist/{chunk-5IPKQHOL.js → chunk-6XUJVEY2.js} +1 -1
- package/dist/{chunk-MGBUWPXX.js → chunk-7HTH5PFK.js} +1 -1
- package/dist/{chunk-32NB4VMH.js → chunk-7QNIXBQD.js} +1 -1
- package/dist/{chunk-AR46ND2Q.js → chunk-7YKJF5JV.js} +1 -1
- package/dist/{chunk-7RSY7SZN.js → chunk-7YSFE4SZ.js} +1 -1
- package/dist/{chunk-IMSI7IFW.js → chunk-AR3DQYRR.js} +17 -17
- package/dist/{chunk-XX2PA4L3.js → chunk-BJAS2JLW.js} +1 -1
- package/dist/{chunk-J2ASTCU6.js → chunk-BP4EMEGH.js} +1 -1
- package/dist/{chunk-4HCJOFMB.js → chunk-C4Y3ZREE.js} +20 -1
- package/dist/{chunk-7UZC4N62.js → chunk-CGTZOY53.js} +1 -1
- package/dist/{chunk-OQL4AJ4X.js → chunk-D625D4TV.js} +4 -4
- package/dist/{chunk-R2U2G4OS.js → chunk-DSQ72G5I.js} +1 -1
- package/dist/{chunk-VRAXIQ6I.js → chunk-DYNHVCBF.js} +1 -1
- package/dist/{chunk-SBBQFPCJ.js → chunk-E77ALFLW.js} +1 -1
- package/dist/{chunk-5TRFLZ5Z.js → chunk-EFXMETRK.js} +1 -1
- package/dist/{chunk-MEE4NTPZ.js → chunk-F5LLORBP.js} +2 -2
- package/dist/{chunk-A4OI5ZNX.js → chunk-GKHMSSGY.js} +1 -1
- package/dist/{chunk-AMZJFCOX.js → chunk-GR5DQKDR.js} +5 -5
- package/dist/{chunk-W24SZ5FL.js → chunk-KU3UFQN7.js} +5 -8
- package/dist/{chunk-QX4TB4NH.js → chunk-L4JB7LI4.js} +320 -75
- package/dist/{chunk-K2AKVYNR.js → chunk-L5YLA54L.js} +2 -2
- package/dist/{chunk-3FV5BVWS.js → chunk-LFUVTS6V.js} +2 -2
- package/dist/{chunk-4E75LHAL.js → chunk-LMNZLZMJ.js} +1 -1
- package/dist/{chunk-LOKCBZYF.js → chunk-M3KZBDPB.js} +3 -3
- package/dist/{chunk-VOM2HLUI.js → chunk-MFUNDJEV.js} +3 -3
- package/dist/{chunk-7JJMT6LN.js → chunk-OFV3WSOE.js} +1 -1
- package/dist/{chunk-L2YGSAOL.js → chunk-OFYW4J7Y.js} +2 -2
- package/dist/{chunk-T6O5OLN2.js → chunk-QKX7ITER.js} +2 -2
- package/dist/{chunk-BV6YE455.js → chunk-RTLPWOO6.js} +1 -1
- package/dist/{chunk-BPKLUHFT.js → chunk-SOY2FPOR.js} +5 -5
- package/dist/{chunk-YMQQXPD5.js → chunk-TY3LDJA3.js} +5 -12
- package/dist/{chunk-2HP5GIQ3.js → chunk-TZEKVLPV.js} +1 -1
- package/dist/{chunk-QWLES6YV.js → chunk-UB7BIDBS.js} +3 -3
- package/dist/{chunk-JCDYDF54.js → chunk-UIC7B5KW.js} +1 -1
- package/dist/{chunk-2J3NA3OB.js → chunk-UNATIAOT.js} +7 -7
- package/dist/chunk-USWPZXEA.js +3897 -0
- package/dist/{chunk-ZEMDV6W2.js → chunk-V7ZA2BNW.js} +1 -1
- package/dist/{chunk-PFRG5P32.js → chunk-VLLFORE2.js} +1 -1
- package/dist/{chunk-EKGGSAWR.js → chunk-VPC4XIVI.js} +5 -5
- package/dist/{chunk-6XVKMBUA.js → chunk-VW63MHQU.js} +1 -1
- package/dist/{chunk-MVIJTXN5.js → chunk-WFS6S65A.js} +12 -12
- package/dist/{chunk-VNPADTDD.js → chunk-WIVOXGEP.js} +2 -2
- package/dist/{chunk-J2BSUF6X.js → chunk-X5CECNCK.js} +1 -1
- package/dist/{chunk-SK7TR7BL.js → chunk-XQPA4W3M.js} +2 -2
- package/dist/{chunk-BEOK6F26.js → chunk-YS4JUGNI.js} +2 -2
- package/dist/{chunk-ODBYZIOH.js → chunk-ZH7J2ZUL.js} +12 -12
- package/dist/{chunk-XF77MK3J.js → chunk-ZT45TCY3.js} +1 -1
- package/dist/{chunk-3CXIX6XS.js → chunk-ZTKFRXJB.js} +3 -3
- package/dist/{chunk-GANST5K3.js → chunk-ZZPBXRYQ.js} +1 -1
- package/dist/{clean-2RNCTDBT.js → clean-5HGESK5A.js} +14 -14
- package/dist/cli.js +54 -54
- package/dist/{cloud-NFIKESNZ.js → cloud-746PHS32.js} +4 -4
- package/dist/{cloudrun-7224BCX3.js → cloudrun-DO7WFLSM.js} +4 -4
- package/dist/{compare-HL44MXVX.js → compare-66YPRNG2.js} +26 -26
- package/dist/{compiler-WF5QTXV7.js → compiler-R4UYDWXO.js} +2 -2
- package/dist/{component-ZBZXSJBR.js → component-EQ3H6RFP.js} +3 -3
- package/dist/{compositions-76P7LDDX.js → compositions-ZZ7P5HT2.js} +9 -9
- package/dist/{contactSheet-43ISAESM.js → contactSheet-SZBJDOMT.js} +1 -1
- package/dist/{delete-4YZBYOHJ.js → delete-Z5MSLJSR.js} +2 -2
- package/dist/{deploy-UGUUGYLF.js → deploy-RGSAC2K5.js} +1 -1
- package/dist/{dist-5KKCRFPT.js → dist-RKK4YLAD.js} +2 -2
- package/dist/{doctor-GGVUK4NB.js → doctor-W4ZZDRTU.js} +9 -9
- package/dist/{events-OXPTHVDB.js → events-BSSL4A4W.js} +2 -2
- package/dist/{events-V2VU4J3B.js → events-UACT7PX3.js} +3 -3
- package/dist/{feedback-HFZ5SCUK.js → feedback-47ILDLQG.js} +6 -6
- package/dist/{ffmpeg-3VHY7GO3.js → ffmpeg-IEHSUNUT.js} +5 -5
- package/dist/{figma-7SEZTLBJ.js → figma-PLFIIYRU.js} +3 -3
- package/dist/fontLocalizeCli.js +7 -7
- package/dist/{get-Y2S2PXCM.js → get-PDWGJYNL.js} +2 -2
- package/dist/{gpuPolicy-UHPOWRV5.js → gpuPolicy-6UBXO6ME.js} +5 -5
- package/dist/{grade-compare-4VTXSQM5.js → grade-compare-5VWLQGM7.js} +26 -26
- package/dist/{help-HXNOACHI.js → help-DS3KMWYO.js} +1 -1
- package/dist/{history-XDJUI4LC.js → history-OC326NVZ.js} +9 -8
- package/dist/hyperframe.manifest.json +1 -1
- package/dist/hyperframe.runtime.iife.js +51 -51
- package/dist/hyperframes-player.global.js +1 -1
- package/dist/{info-KYRI3EZV.js → info-AUIFV6MX.js} +7 -7
- package/dist/{init-IL7EWMT5.js → init-MRTWWDFW.js} +25 -25
- package/dist/{inspect-TBNH23UC.js → inspect-55NOAXI2.js} +26 -26
- package/dist/{installer-O2YMFSI4.js → installer-YSFFGBBV.js} +4 -4
- package/dist/{keyframes-4GF62KAJ.js → keyframes-OO2BX2IB.js} +6 -6
- package/dist/{lambda-JFL6M4XZ.js → lambda-CXXY6QT3.js} +6 -6
- package/dist/{layout-7MAEFR65.js → layout-57GJXKDK.js} +26 -26
- package/dist/{lint-4AYHKYAM.js → lint-J4FK3Z6G.js} +6 -6
- package/dist/{list-3DP3D3MW.js → list-VDQUJ76B.js} +2 -2
- package/dist/{login-T54WQYRQ.js → login-TJSEALWW.js} +4 -4
- package/dist/{manager-QROK2IH3.js → manager-4PLYEEWP.js} +6 -6
- package/dist/{media-treatment-4CXF7MSG.js → media-treatment-GXP4PMJH.js} +11 -11
- package/dist/{models-IS3I6JKU.js → models-HQQQKEEP.js} +9 -9
- package/dist/{motionShot-DVYJZOTQ.js → motionShot-2BT5D7DC.js} +13 -13
- package/dist/{normalize-audio-4527JIK4.js → normalize-audio-SOLFMHNP.js} +4 -4
- package/dist/{open-5JE46SAX.js → open-KHEUODFQ.js} +11 -11
- package/dist/{parakeetRunner-7JIJGJJ7.js → parakeetRunner-BHU5NCAX.js} +10 -10
- package/dist/{pipeline-YEN3WFD2.js → pipeline-WFV5HDTD.js} +6 -6
- package/dist/{play-WFX67I7M.js → play-GB34CANJ.js} +17 -17
- package/dist/{preflight-D377HVUZ.js → preflight-REF3VSJ7.js} +6 -6
- package/dist/{present-XTSEKAC7.js → present-SIUTA7TD.js} +13 -13
- package/dist/{preview-5XH7EK6O.js → preview-T2GE7Z4A.js} +16 -16
- package/dist/{producer-TFFYF4ZM.js → producer-23KVQZAB.js} +1 -1
- package/dist/{projectConfig-6YUJHMCL.js → projectConfig-DBSNBPNP.js} +6 -6
- package/dist/{publication-JK33Y55E.js → publication-IXPUKYWJ.js} +2 -2
- package/dist/{publish-JHDGXWXU.js → publish-3BA5VHXJ.js} +7 -7
- package/dist/{remove-background-P44MYAPJ.js → remove-background-RMSCJVVQ.js} +7 -7
- package/dist/{render-RJ3I4E3A.js → render-6RNE2MLU.js} +12 -12
- package/dist/{render-RBINWWP5.js → render-XGOZMMWX.js} +27 -27
- package/dist/{render-HJ34EGMN.js → render-Y6CTQ3YW.js} +5 -5
- package/dist/{render-batch-3D6XQYUC.js → render-batch-VUR6N6EY.js} +5 -5
- package/dist/{resolver-HCLTFZUW.js → resolver-GJCUH57W.js} +4 -4
- package/dist/{sherpa-IPOUJM6Q.js → sherpa-VVAKRCPL.js} +9 -9
- package/dist/skills/hyperframes/references/format.md +1 -0
- package/dist/{skills-P67QEERC.js → skills-ZHBURVQG.js} +5 -5
- package/dist/{skillsUpdateCheck-IFMLRVIF.js → skillsUpdateCheck-VMDAL2O2.js} +3 -3
- package/dist/{snapshot-4YM4NNWJ.js → snapshot-KEOG56SL.js} +46 -41
- package/dist/{src-SSV66L3F.js → src-BH5NICGQ.js} +14 -4
- package/dist/{src-DCD3YMXX.js → src-TZLGFRRX.js} +6 -6
- package/dist/{staticProjectServer-C7PPGLEQ.js → staticProjectServer-BKXL5CXB.js} +14 -14
- package/dist/studio/assets/{hyperframes-player-ChN3cOr0.js → hyperframes-player-BMcUdmDb.js} +1 -1
- package/dist/studio/assets/{index-CHu83hHM.js → index-Ca-mgTnS.js} +4 -4
- package/dist/studio/assets/{index-BYbFcRR0.js → index-Ci6GuloR.js} +1 -1
- package/dist/studio/index.html +1 -1
- package/dist/{studio-api-6YZ7PIQR.js → studio-api-A5U6QAMC.js} +9 -7
- package/dist/{studioServer-EWHSE4GC.js → studioServer-5EC5CP4W.js} +43 -43
- package/dist/{telemetry-GGLBHZRZ.js → telemetry-BCKJXDSW.js} +3 -3
- package/dist/{timeline-NKHQJXJ2.js → timeline-AZWAXTAY.js} +15 -15
- package/dist/{tokens-FWNNDJ6R.js → tokens-X7NC3V7C.js} +2 -2
- package/dist/{transcribe-VD2TMMC2.js → transcribe-7NCY7QZ2.js} +8 -8
- package/dist/{transcribe-TRPKXZ7L.js → transcribe-SH26H755.js} +14 -14
- package/dist/{updateCheck-CUPS6LU3.js → updateCheck-Y7FUWQM4.js} +2 -2
- package/dist/{upgrade-23XO6MEX.js → upgrade-ZHGEVL65.js} +2 -2
- package/dist/{urlDownloader-YOAOONCK.js → urlDownloader-FPILIT7M.js} +4 -4
- package/dist/{validate-BWIW24G5.js → validate-KQOZR4F6.js} +20 -20
- package/dist/{video-XRXJS4GC.js → video-N2QAETFB.js} +5 -5
- package/dist/warmCheck.js +33 -33
- 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-TY3LDJA3.js";
|
|
12
12
|
import {
|
|
13
13
|
GENERIC_FAMILIES,
|
|
14
14
|
collectFontFamilyCustomProperties,
|
|
@@ -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,
|
|
@@ -157,7 +159,7 @@ import {
|
|
|
157
159
|
validateEngineConfigSnapshot,
|
|
158
160
|
verifyDiskDrawElementSamples,
|
|
159
161
|
writeCapturedFrame
|
|
160
|
-
} from "./chunk-
|
|
162
|
+
} from "./chunk-L4JB7LI4.js";
|
|
161
163
|
import {
|
|
162
164
|
DISTRIBUTED_FPS,
|
|
163
165
|
HF_VFX_ATTR,
|
|
@@ -172,7 +174,7 @@ import {
|
|
|
172
174
|
parseVfxChain,
|
|
173
175
|
resolveAuthoredTimingWindow,
|
|
174
176
|
toFps
|
|
175
|
-
} from "./chunk-
|
|
177
|
+
} from "./chunk-7HTH5PFK.js";
|
|
176
178
|
import {
|
|
177
179
|
assignBundledRuntimeCompositionIds,
|
|
178
180
|
buildVariablesByCompScript,
|
|
@@ -185,7 +187,7 @@ import {
|
|
|
185
187
|
isTemplateEntry,
|
|
186
188
|
parsesAsScript,
|
|
187
189
|
prepareFlattenedInnerRoot
|
|
188
|
-
} from "./chunk-
|
|
190
|
+
} from "./chunk-3W4B6G7Y.js";
|
|
189
191
|
import {
|
|
190
192
|
COMPOSITION_SOURCE_URL,
|
|
191
193
|
HF_COLOR_GRADING_ATTR,
|
|
@@ -213,7 +215,7 @@ import {
|
|
|
213
215
|
shouldClampResolvedMediaDuration,
|
|
214
216
|
sourceTimeAt,
|
|
215
217
|
styleElementsFor
|
|
216
|
-
} from "./chunk-
|
|
218
|
+
} from "./chunk-USWPZXEA.js";
|
|
217
219
|
import {
|
|
218
220
|
MAX_AUDIO_GAIN
|
|
219
221
|
} from "./chunk-X7HBSTCZ.js";
|
|
@@ -1570,16 +1572,7 @@ var RenderExecutionContext = class {
|
|
|
1570
1572
|
};
|
|
1571
1573
|
|
|
1572
1574
|
// ../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";
|
|
1575
|
+
import { closeSync as closeSync2, existsSync as existsSync5, fstatSync as fstatSync2, openSync as openSync2, readSync, readdirSync as readdirSync2, rmSync as rmSync3 } from "fs";
|
|
1583
1576
|
import { basename as basename3, dirname as dirname4, extname as extname2, join as join5, resolve as resolve4 } from "path";
|
|
1584
1577
|
|
|
1585
1578
|
// ../producer/src/services/render/renderDirOwner.ts
|
|
@@ -1692,7 +1685,7 @@ function createRenderWorkDir(prefix, outputDir) {
|
|
|
1692
1685
|
// ../producer/src/services/render/artifactTransaction.ts
|
|
1693
1686
|
var defaultFileSystem = {
|
|
1694
1687
|
existsSync: existsSync5,
|
|
1695
|
-
renameSync,
|
|
1688
|
+
renameSync: (source, destination) => renameWithRetry(source, destination),
|
|
1696
1689
|
rmSync: rmSync3
|
|
1697
1690
|
};
|
|
1698
1691
|
async function defaultArtifactDurationProbe(path) {
|
|
@@ -2079,36 +2072,8 @@ function replanAfterFailure(plan2, failure) {
|
|
|
2079
2072
|
import { existsSync as existsSync6, mkdirSync as mkdirSync3, rmSync as rmSync5, statSync as statSync2 } from "fs";
|
|
2080
2073
|
import { join as join9 } from "path";
|
|
2081
2074
|
|
|
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";
|
|
2075
|
+
// ../producer/src/services/render/perfSummary.ts
|
|
2076
|
+
import { arch, cpus, platform, totalmem } from "os";
|
|
2112
2077
|
|
|
2113
2078
|
// ../producer/src/services/render/hdrPerf.ts
|
|
2114
2079
|
function createHdrPerfCollector() {
|
|
@@ -2214,7 +2179,257 @@ function finalizeHdrPerf(perf) {
|
|
|
2214
2179
|
};
|
|
2215
2180
|
}
|
|
2216
2181
|
|
|
2182
|
+
// ../producer/src/services/render/perfSummary.ts
|
|
2183
|
+
function worstSubTimelineWaitOutcome(perfs) {
|
|
2184
|
+
const outcomes = perfs.map((p) => p.subTimelineWaitOutcome).filter((o) => !!o);
|
|
2185
|
+
if (outcomes.length === 0) return void 0;
|
|
2186
|
+
if (outcomes.includes("script_failure")) return "script_failure";
|
|
2187
|
+
if (outcomes.includes("timeout")) return "timeout";
|
|
2188
|
+
return "ready";
|
|
2189
|
+
}
|
|
2190
|
+
function pushWorkerDedupPerfs(results, sink) {
|
|
2191
|
+
for (const r of results) {
|
|
2192
|
+
if (r.perf) sink.push(r.perf);
|
|
2193
|
+
}
|
|
2194
|
+
}
|
|
2195
|
+
function pushWorkerPageErrors(results, sink) {
|
|
2196
|
+
for (const result of results) {
|
|
2197
|
+
for (const line of result.pageErrorLines ?? []) if (!sink.includes(line)) sink.push(line);
|
|
2198
|
+
}
|
|
2199
|
+
}
|
|
2200
|
+
function withWorkerPageErrors(consoleLines, workerLines) {
|
|
2201
|
+
return [...consoleLines, ...workerLines.filter((line) => !consoleLines.includes(line))];
|
|
2202
|
+
}
|
|
2203
|
+
function roundDb(value) {
|
|
2204
|
+
return value === void 0 ? void 0 : Math.round(Math.min(value, 999) * 10) / 10;
|
|
2205
|
+
}
|
|
2206
|
+
function aggregateDrawElement(perfs, de) {
|
|
2207
|
+
if (perfs.length === 0) return void 0;
|
|
2208
|
+
const modes = [...new Set(perfs.map((p) => p.captureMode).filter(Boolean))].sort();
|
|
2209
|
+
const gateReasons = [
|
|
2210
|
+
...new Set(
|
|
2211
|
+
[de.probeGateReason, ...perfs.map((p) => p.deGateReason)].filter((r) => !!r)
|
|
2212
|
+
)
|
|
2213
|
+
].sort();
|
|
2214
|
+
const gpuRenderers = [
|
|
2215
|
+
...new Set(perfs.map((p) => p.gpuRenderer).filter((r) => !!r))
|
|
2216
|
+
].sort();
|
|
2217
|
+
const drain = de.drainStats;
|
|
2218
|
+
return {
|
|
2219
|
+
mode: modes.join("|") || "unknown",
|
|
2220
|
+
compileGate: de.compileGate,
|
|
2221
|
+
clampReason: de.clampReason,
|
|
2222
|
+
workerInversion: de.workerInversion ?? "none",
|
|
2223
|
+
preInversionWorkers: de.preInversionWorkers,
|
|
2224
|
+
compositionElementCount: de.compositionElementCount,
|
|
2225
|
+
compositionElementCountSource: de.compositionElementCountSource,
|
|
2226
|
+
compositionElementTags: de.compositionElementTags,
|
|
2227
|
+
arollVideoCount: de.arollVideoCount,
|
|
2228
|
+
heygenVideoCount: de.heygenVideoCount,
|
|
2229
|
+
adaptersUsed: de.adaptersUsed,
|
|
2230
|
+
audioCount: de.audioCount,
|
|
2231
|
+
imageCount: de.imageCount,
|
|
2232
|
+
subCompositionCount: de.subCompositionCount,
|
|
2233
|
+
audioGroupCount: de.audioGroupCount,
|
|
2234
|
+
colorGradingCount: de.colorGradingCount,
|
|
2235
|
+
hasLut: de.hasLut,
|
|
2236
|
+
rootBodyMismatch: de.rootBodyMismatch,
|
|
2237
|
+
rootBodyDeltaPxBucket: de.rootBodyDeltaPxBucket,
|
|
2238
|
+
vfxHostCount: de.vfxHostCount,
|
|
2239
|
+
vfxCapture: de.vfxCapture,
|
|
2240
|
+
vfxTypes: de.vfxTypes,
|
|
2241
|
+
shortBand: de.shortBand,
|
|
2242
|
+
parallelRouter: de.parallelRouter ?? "none",
|
|
2243
|
+
preRouterWorkers: de.preRouterWorkers,
|
|
2244
|
+
gateReason: gateReasons.length > 0 ? gateReasons.join("|") : void 0,
|
|
2245
|
+
gpuRenderer: gpuRenderers.length > 0 ? gpuRenderers.join("|") : void 0,
|
|
2246
|
+
workerEncode: perfs.some((p) => p.deWorkerEncode),
|
|
2247
|
+
verifyArmed: perfs.reduce((sum2, p) => sum2 + (p.deVerifyArmed ?? 0), 0),
|
|
2248
|
+
verifyChecked: drain?.verifyChecked ?? 0,
|
|
2249
|
+
verifyMinDb: roundDb(drain?.verifyMinDb),
|
|
2250
|
+
verifyInitMs: perfs.reduce((sum2, p) => sum2 + (p.deVerifyInitMs ?? 0), 0),
|
|
2251
|
+
selfVerifyFallback: de.selfVerifyFallback,
|
|
2252
|
+
fallbackReason: de.fallbackReason,
|
|
2253
|
+
fallbackFailedDb: roundDb(de.fallbackFailedDb),
|
|
2254
|
+
fallbackFrameIndex: de.fallbackFrameIndex,
|
|
2255
|
+
fallbackThresholdDb: roundDb(de.fallbackThresholdDb),
|
|
2256
|
+
blankSuspects: drain?.blankSuspects ?? 0,
|
|
2257
|
+
blankDeterministicAccepts: drain?.blankDeterministicAccepts ?? 0,
|
|
2258
|
+
blankRecaptures: drain?.blankRecaptures ?? 0,
|
|
2259
|
+
boundaryFrames: perfs.reduce((sum2, p) => sum2 + (p.deBoundaryFrames ?? 0), 0),
|
|
2260
|
+
ncprFallbacks: perfs.reduce((sum2, p) => sum2 + (p.deNcprFallbacks ?? 0), 0),
|
|
2261
|
+
frameTimeouts: perfs.reduce((sum2, p) => sum2 + (p.deFrameTimeouts ?? 0), 0)
|
|
2262
|
+
};
|
|
2263
|
+
}
|
|
2264
|
+
function maxDefined(values) {
|
|
2265
|
+
const present = values.filter((v) => typeof v === "number");
|
|
2266
|
+
return present.length > 0 ? Math.max(...present) : void 0;
|
|
2267
|
+
}
|
|
2268
|
+
function aggregateChromeMemory(perfs) {
|
|
2269
|
+
const sampled = perfs.filter((p) => (p.chromeMemorySamples ?? 0) > 0);
|
|
2270
|
+
if (sampled.length === 0) return void 0;
|
|
2271
|
+
return {
|
|
2272
|
+
browserRssPeakMb: maxDefined(sampled.map((p) => p.chromeBrowserRssPeakMb)),
|
|
2273
|
+
rendererRssPeakMb: maxDefined(sampled.map((p) => p.chromeRendererRssPeakMb)),
|
|
2274
|
+
// Last samples are per session; summing approximates the whole fleet's
|
|
2275
|
+
// footprint at the end of capture (workers run concurrently).
|
|
2276
|
+
rssLastMb: sampled.reduce((sum2, p) => sum2 + (p.chromeRssLastMb ?? 0), 0),
|
|
2277
|
+
gpuProcessSeenLastSample: sampled.some((p) => p.chromeGpuProcessSeenLastSample === true),
|
|
2278
|
+
samples: sampled.reduce((sum2, p) => sum2 + (p.chromeMemorySamples ?? 0), 0)
|
|
2279
|
+
};
|
|
2280
|
+
}
|
|
2281
|
+
function aggregateDedup(perfs) {
|
|
2282
|
+
if (perfs.length === 0) return void 0;
|
|
2283
|
+
const armed = perfs.some((p) => p.staticDedupArmed);
|
|
2284
|
+
const skipReasons = armed ? [] : [
|
|
2285
|
+
...new Set(perfs.map((p) => p.staticDedupSkipReason).filter((r) => !!r))
|
|
2286
|
+
].sort();
|
|
2287
|
+
const verificationPerfs = perfs.filter((perf) => perf.staticDedupVerificationOutcome);
|
|
2288
|
+
const verificationOutcomes = [
|
|
2289
|
+
...new Set(
|
|
2290
|
+
verificationPerfs.map((perf) => perf.staticDedupVerificationOutcome).filter((outcome) => outcome != null)
|
|
2291
|
+
)
|
|
2292
|
+
].sort();
|
|
2293
|
+
return {
|
|
2294
|
+
enabled: perfs.some((p) => p.staticDedupEnabled),
|
|
2295
|
+
armed,
|
|
2296
|
+
predictedFrames: perfs.reduce((sum2, p) => sum2 + (p.staticDedupPredicted ?? 0), 0),
|
|
2297
|
+
reusedFrames: perfs.reduce((sum2, p) => sum2 + (p.staticDedupReused ?? 0), 0),
|
|
2298
|
+
skipReason: skipReasons.length > 0 ? skipReasons.join("|") : void 0,
|
|
2299
|
+
...verificationPerfs.length === 0 ? {} : {
|
|
2300
|
+
verifiedFrames: verificationPerfs.reduce(
|
|
2301
|
+
(sum2, perf) => sum2 + (perf.staticDedupVerified ?? 0),
|
|
2302
|
+
0
|
|
2303
|
+
),
|
|
2304
|
+
verificationOutcomes,
|
|
2305
|
+
plannedRuns: verificationPerfs.reduce(
|
|
2306
|
+
(sum2, perf) => sum2 + (perf.staticDedupVerificationPlannedRuns ?? 0),
|
|
2307
|
+
0
|
|
2308
|
+
),
|
|
2309
|
+
completedRuns: verificationPerfs.reduce(
|
|
2310
|
+
(sum2, perf) => sum2 + (perf.staticDedupVerificationCompletedRuns ?? 0),
|
|
2311
|
+
0
|
|
2312
|
+
),
|
|
2313
|
+
screenshots: verificationPerfs.reduce(
|
|
2314
|
+
(sum2, perf) => sum2 + (perf.staticDedupVerificationScreenshots ?? 0),
|
|
2315
|
+
0
|
|
2316
|
+
),
|
|
2317
|
+
seeks: verificationPerfs.reduce(
|
|
2318
|
+
(sum2, perf) => sum2 + (perf.staticDedupVerificationSeeks ?? 0),
|
|
2319
|
+
0
|
|
2320
|
+
),
|
|
2321
|
+
comparisons: verificationPerfs.reduce(
|
|
2322
|
+
(sum2, perf) => sum2 + (perf.staticDedupVerificationComparisons ?? 0),
|
|
2323
|
+
0
|
|
2324
|
+
),
|
|
2325
|
+
verificationElapsedMs: verificationPerfs.reduce(
|
|
2326
|
+
(sum2, perf) => sum2 + (perf.staticDedupVerificationElapsedMs ?? 0),
|
|
2327
|
+
0
|
|
2328
|
+
)
|
|
2329
|
+
}
|
|
2330
|
+
};
|
|
2331
|
+
}
|
|
2332
|
+
function aggregateBeginFrameReuse(perfs) {
|
|
2333
|
+
const noDamageFrames = perfs.reduce((sum2, p) => sum2 + (p.beginFrameNoDamage ?? 0), 0);
|
|
2334
|
+
const hasDamageFrames = perfs.reduce((sum2, p) => sum2 + (p.beginFrameHasDamage ?? 0), 0);
|
|
2335
|
+
if (noDamageFrames + hasDamageFrames === 0) return void 0;
|
|
2336
|
+
return { noDamageFrames, hasDamageFrames };
|
|
2337
|
+
}
|
|
2338
|
+
function buildRenderPerfSummary(input) {
|
|
2339
|
+
return {
|
|
2340
|
+
renderId: input.job.id,
|
|
2341
|
+
totalElapsedMs: input.totalElapsedMs,
|
|
2342
|
+
// RenderPerfSummary surfaces fps as a decimal because it lands in JSON
|
|
2343
|
+
// payloads (CLI telemetry, regression-harness reports) where a single
|
|
2344
|
+
// number is friendlier than `{num,den}`. Callers needing the rational
|
|
2345
|
+
// back can read `job.config.fps`.
|
|
2346
|
+
fps: fpsToNumber(input.job.config.fps),
|
|
2347
|
+
quality: input.job.config.quality,
|
|
2348
|
+
workers: input.workerCount,
|
|
2349
|
+
workerSizing: input.workerSizing,
|
|
2350
|
+
chunkedEncode: input.enableChunkedEncode,
|
|
2351
|
+
chunkSizeFrames: input.enableChunkedEncode ? input.chunkedEncodeSize : null,
|
|
2352
|
+
compositionDurationSeconds: input.compositionDurationSeconds,
|
|
2353
|
+
totalFrames: input.totalFrames,
|
|
2354
|
+
resolution: { width: input.outputWidth, height: input.outputHeight },
|
|
2355
|
+
videoCount: input.videoCount,
|
|
2356
|
+
audioCount: input.audioCount,
|
|
2357
|
+
stages: input.perfStages,
|
|
2358
|
+
videoExtractBreakdown: input.videoExtractBreakdown,
|
|
2359
|
+
tmpPeakBytes: input.tmpPeakBytes,
|
|
2360
|
+
captureCalibration: input.captureCalibration ? {
|
|
2361
|
+
sampledFrames: input.captureCalibration.samples.map((sample) => sample.frameIndex),
|
|
2362
|
+
p95Ms: input.captureCalibration.estimate.p95Ms,
|
|
2363
|
+
multiplier: input.captureCalibration.estimate.multiplier,
|
|
2364
|
+
reasons: input.captureCalibration.estimate.reasons
|
|
2365
|
+
} : void 0,
|
|
2366
|
+
captureAttempts: input.captureAttempts.length > 0 ? input.captureAttempts : void 0,
|
|
2367
|
+
hdrDiagnostics: input.hdrDiagnostics.videoExtractionFailures > 0 || input.hdrDiagnostics.imageDecodeFailures > 0 ? { ...input.hdrDiagnostics } : void 0,
|
|
2368
|
+
hdrPerf: input.hdrPerf ? finalizeHdrPerf(input.hdrPerf) : void 0,
|
|
2369
|
+
observability: input.observability,
|
|
2370
|
+
captureAvgMs: input.totalFrames > 0 ? Math.round(
|
|
2371
|
+
(input.perfStages.captureFrameMs ?? input.perfStages.captureMs ?? 0) / input.totalFrames
|
|
2372
|
+
) : void 0,
|
|
2373
|
+
subTimelineWait: worstSubTimelineWaitOutcome(input.dedupPerfs),
|
|
2374
|
+
captureP50Ms: (() => {
|
|
2375
|
+
const withSamples = input.dedupPerfs.filter((p) => (p.p50TotalMs ?? 0) > 0);
|
|
2376
|
+
if (withSamples.length === 0) return void 0;
|
|
2377
|
+
return withSamples.reduce((a, b) => b.frames > a.frames ? b : a).p50TotalMs;
|
|
2378
|
+
})(),
|
|
2379
|
+
peakRssMb: Math.round(input.peakRssBytes / (1024 * 1024)),
|
|
2380
|
+
peakHeapUsedMb: Math.round(input.peakHeapUsedBytes / (1024 * 1024)),
|
|
2381
|
+
staticDedup: aggregateDedup(input.dedupPerfs),
|
|
2382
|
+
chromeMemory: aggregateChromeMemory(input.dedupPerfs),
|
|
2383
|
+
beginFrameReuse: aggregateBeginFrameReuse(input.dedupPerfs),
|
|
2384
|
+
drawElement: aggregateDrawElement(
|
|
2385
|
+
input.dedupPerfs,
|
|
2386
|
+
input.drawElement ?? { selfVerifyFallback: false }
|
|
2387
|
+
),
|
|
2388
|
+
host: {
|
|
2389
|
+
platform: platform(),
|
|
2390
|
+
arch: arch(),
|
|
2391
|
+
cpuCount: cpus().length,
|
|
2392
|
+
totalMemMb: Math.round(totalmem() / (1024 * 1024)),
|
|
2393
|
+
nodeVersion: process.version,
|
|
2394
|
+
gpuDisabled: input.gpuDisabled
|
|
2395
|
+
}
|
|
2396
|
+
};
|
|
2397
|
+
}
|
|
2398
|
+
|
|
2399
|
+
// ../producer/src/services/render/captureStageError.ts
|
|
2400
|
+
var CaptureStageError = class extends CaptureFailure {
|
|
2401
|
+
browserConsole;
|
|
2402
|
+
constructor(input) {
|
|
2403
|
+
const classified = classifyCaptureFailure(input.cause);
|
|
2404
|
+
super({
|
|
2405
|
+
kind: classified.kind,
|
|
2406
|
+
message: normalizeErrorMessage(input.cause),
|
|
2407
|
+
cause: input.cause,
|
|
2408
|
+
workerDiagnostics: classified.workerDiagnostics,
|
|
2409
|
+
pageErrorLines: classified.pageErrorLines
|
|
2410
|
+
});
|
|
2411
|
+
this.name = "CaptureStageError";
|
|
2412
|
+
this.browserConsole = withWorkerPageErrors(input.browserConsole, [
|
|
2413
|
+
...classified.pageErrorLines
|
|
2414
|
+
]);
|
|
2415
|
+
if (input.cause instanceof Error && input.cause.stack) {
|
|
2416
|
+
this.stack = input.cause.stack;
|
|
2417
|
+
}
|
|
2418
|
+
}
|
|
2419
|
+
};
|
|
2420
|
+
function wrapCaptureStageError(error, browserConsole) {
|
|
2421
|
+
if (error instanceof CaptureStageError || error instanceof EncoderInterruptedError) return error;
|
|
2422
|
+
return new CaptureStageError({ cause: error, browserConsole });
|
|
2423
|
+
}
|
|
2424
|
+
function getCaptureStageBrowserConsole(error) {
|
|
2425
|
+
if (error instanceof CaptureStageError) return error.browserConsole;
|
|
2426
|
+
if (error instanceof CaptureFailure) return [...error.pageErrorLines];
|
|
2427
|
+
return [];
|
|
2428
|
+
}
|
|
2429
|
+
|
|
2217
2430
|
// ../producer/src/services/hdrCompositor.ts
|
|
2431
|
+
import { readSync as readSync2, closeSync as closeSync3 } from "fs";
|
|
2432
|
+
import { join as join6 } from "path";
|
|
2218
2433
|
function countNonZeroAlpha(rgba) {
|
|
2219
2434
|
let n = 0;
|
|
2220
2435
|
for (let p = 3; p < rgba.length; p += 4) {
|
|
@@ -3249,309 +3464,100 @@ async function captureTransitionFrameOnWorker(a) {
|
|
|
3249
3464
|
function ensureFrameWritten(frameWritten, frameIndex, encoder) {
|
|
3250
3465
|
if (frameWritten) return;
|
|
3251
3466
|
const reason = encoder?.getExitError();
|
|
3252
|
-
const base = `Streaming encoder exited before frame ${frameIndex} was written`;
|
|
3253
|
-
throw encoderFailureError(base, {
|
|
3254
|
-
error: reason,
|
|
3255
|
-
failureReason: encoder?.getExitFailureReason?.()
|
|
3256
|
-
});
|
|
3257
|
-
}
|
|
3258
|
-
function cleanupEndedHdrVideos(args) {
|
|
3259
|
-
if (process.env.KEEP_TEMP === "1") return;
|
|
3260
|
-
const {
|
|
3261
|
-
time,
|
|
3262
|
-
activeTransition,
|
|
3263
|
-
hdrVideoEndTimes,
|
|
3264
|
-
cleanedUpVideos,
|
|
3265
|
-
hdrVideoFrameSources,
|
|
3266
|
-
sceneElements,
|
|
3267
|
-
log
|
|
3268
|
-
} = args;
|
|
3269
|
-
for (const [videoId, endTime] of hdrVideoEndTimes) {
|
|
3270
|
-
if (time > endTime && !cleanedUpVideos.has(videoId)) {
|
|
3271
|
-
const stillNeeded = activeTransition && (sceneElements[activeTransition.fromScene]?.includes(videoId) || sceneElements[activeTransition.toScene]?.includes(videoId));
|
|
3272
|
-
if (!stillNeeded) {
|
|
3273
|
-
const frameSource = hdrVideoFrameSources.get(videoId);
|
|
3274
|
-
if (frameSource) {
|
|
3275
|
-
cleanupHdrVideoFrameSource(frameSource, log);
|
|
3276
|
-
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
|
-
)
|
|
3467
|
+
const base = `Streaming encoder exited before frame ${frameIndex} was written`;
|
|
3468
|
+
throw encoderFailureError(base, {
|
|
3469
|
+
error: reason,
|
|
3470
|
+
failureReason: encoder?.getExitFailureReason?.()
|
|
3471
|
+
});
|
|
3472
|
+
}
|
|
3473
|
+
function cleanupEndedHdrVideos(args) {
|
|
3474
|
+
if (process.env.KEEP_TEMP === "1") return;
|
|
3475
|
+
const {
|
|
3476
|
+
time,
|
|
3477
|
+
activeTransition,
|
|
3478
|
+
hdrVideoEndTimes,
|
|
3479
|
+
cleanedUpVideos,
|
|
3480
|
+
hdrVideoFrameSources,
|
|
3481
|
+
sceneElements,
|
|
3482
|
+
log
|
|
3483
|
+
} = args;
|
|
3484
|
+
for (const [videoId, endTime] of hdrVideoEndTimes) {
|
|
3485
|
+
if (time > endTime && !cleanedUpVideos.has(videoId)) {
|
|
3486
|
+
const stillNeeded = activeTransition && (sceneElements[activeTransition.fromScene]?.includes(videoId) || sceneElements[activeTransition.toScene]?.includes(videoId));
|
|
3487
|
+
if (!stillNeeded) {
|
|
3488
|
+
const frameSource = hdrVideoFrameSources.get(videoId);
|
|
3489
|
+
if (frameSource) {
|
|
3490
|
+
cleanupHdrVideoFrameSource(frameSource, log);
|
|
3491
|
+
hdrVideoFrameSources.delete(videoId);
|
|
3492
|
+
}
|
|
3493
|
+
cleanedUpVideos.add(videoId);
|
|
3494
|
+
}
|
|
3481
3495
|
}
|
|
3482
|
-
}
|
|
3496
|
+
}
|
|
3483
3497
|
}
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3498
|
+
|
|
3499
|
+
// ../producer/src/services/render/segmentPlan.ts
|
|
3500
|
+
var DEFAULT_SEGMENT_FRAMES = 3e3;
|
|
3501
|
+
var MIN_SEGMENT_FRAMES = 30;
|
|
3502
|
+
function assertPositiveInteger(name, value) {
|
|
3503
|
+
if (!Number.isInteger(value) || value <= 0) {
|
|
3504
|
+
throw new Error(`[segmentPlan] ${name} must be a positive integer (got ${String(value)})`);
|
|
3505
|
+
}
|
|
3489
3506
|
}
|
|
3490
|
-
function
|
|
3507
|
+
function planSegments(totalFrames, segmentFrames) {
|
|
3508
|
+
assertPositiveInteger("totalFrames", totalFrames);
|
|
3509
|
+
assertPositiveInteger("segmentFrames", segmentFrames);
|
|
3510
|
+
const slices = [];
|
|
3511
|
+
for (let start = 0, index = 0; start < totalFrames; start += segmentFrames, index += 1) {
|
|
3512
|
+
slices.push({
|
|
3513
|
+
index,
|
|
3514
|
+
startFrame: start,
|
|
3515
|
+
endFrame: Math.min(totalFrames, start + segmentFrames)
|
|
3516
|
+
});
|
|
3517
|
+
}
|
|
3518
|
+
return slices;
|
|
3519
|
+
}
|
|
3520
|
+
function resolveSegmentFrames(env) {
|
|
3521
|
+
const raw = env.HF_SEGMENT_FRAMES;
|
|
3522
|
+
if (raw === void 0 || raw.trim() === "") return DEFAULT_SEGMENT_FRAMES;
|
|
3523
|
+
const parsed = Number(raw);
|
|
3524
|
+
if (!Number.isInteger(parsed)) return DEFAULT_SEGMENT_FRAMES;
|
|
3525
|
+
return Math.max(MIN_SEGMENT_FRAMES, parsed);
|
|
3526
|
+
}
|
|
3527
|
+
|
|
3528
|
+
// ../producer/src/services/render/segmentQueue.ts
|
|
3529
|
+
function createSegmentQueue(slices) {
|
|
3530
|
+
let cursor = 0;
|
|
3491
3531
|
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
|
-
}
|
|
3532
|
+
next: () => slices[cursor++],
|
|
3533
|
+
remaining: () => Math.max(0, slices.length - cursor)
|
|
3548
3534
|
};
|
|
3549
3535
|
}
|
|
3550
3536
|
|
|
3537
|
+
// ../producer/src/services/render/segmentRecycle.ts
|
|
3538
|
+
var DEFAULT_SEGMENT_BROWSER_RECYCLE = 3;
|
|
3539
|
+
function resolveSegmentBrowserRecycle(env) {
|
|
3540
|
+
const raw = env.HF_SEGMENT_BROWSER_RECYCLE;
|
|
3541
|
+
if (raw === void 0 || raw.trim() === "") return DEFAULT_SEGMENT_BROWSER_RECYCLE;
|
|
3542
|
+
const parsed = Number(raw);
|
|
3543
|
+
return Number.isInteger(parsed) && parsed >= 0 ? parsed : DEFAULT_SEGMENT_BROWSER_RECYCLE;
|
|
3544
|
+
}
|
|
3545
|
+
var TARGET_LOSS_PATTERNS = [/target closed/i, /detached frame/i, /session closed/i];
|
|
3546
|
+
function isTargetLossError(error) {
|
|
3547
|
+
if (!(error instanceof Error)) return false;
|
|
3548
|
+
return TARGET_LOSS_PATTERNS.some((re) => re.test(error.message));
|
|
3549
|
+
}
|
|
3550
|
+
|
|
3551
3551
|
// ../producer/src/services/render/stages/captureStreamingStage.ts
|
|
3552
|
+
import { mkdtemp, writeFile } from "fs/promises";
|
|
3553
|
+
import { tmpdir } from "os";
|
|
3554
|
+
import { join as join8 } from "path";
|
|
3552
3555
|
var DEFAULT_CAPTURE_STALL_MS = 6e4;
|
|
3553
3556
|
var DE_STALL_POLL_MS = 5e3;
|
|
3554
3557
|
var STALL_ADVICE = "Chrome stopped answering. If another app is keeping the GPU or CPU busy (a 3D render, a game, another export), let it finish or render one job at a time, then retry.";
|
|
3558
|
+
function poolFailure(error, probeSession) {
|
|
3559
|
+
return wrapCaptureStageError(error, probeSession?.browserConsoleBuffer ?? []);
|
|
3560
|
+
}
|
|
3555
3561
|
var ParallelCaptureStallError = class extends Error {
|
|
3556
3562
|
variant;
|
|
3557
3563
|
constructor(args) {
|
|
@@ -3998,7 +4004,7 @@ async function runCaptureStreamingStage(input) {
|
|
|
3998
4004
|
}
|
|
3999
4005
|
);
|
|
4000
4006
|
} catch (err) {
|
|
4001
|
-
if (parallelDrainError) throw parallelDrainError;
|
|
4007
|
+
if (parallelDrainError) throw poolFailure(parallelDrainError, probeSession);
|
|
4002
4008
|
if (stalled && abortSignal?.aborted !== true) {
|
|
4003
4009
|
throw new ParallelCaptureStallError({
|
|
4004
4010
|
variant: "pool",
|
|
@@ -4009,13 +4015,15 @@ async function runCaptureStreamingStage(input) {
|
|
|
4009
4015
|
phaseSummary: phaseSummary()
|
|
4010
4016
|
});
|
|
4011
4017
|
}
|
|
4012
|
-
throw err;
|
|
4018
|
+
throw poolFailure(err, probeSession);
|
|
4013
4019
|
} finally {
|
|
4014
4020
|
clearInterval(stallTimer);
|
|
4015
4021
|
abortSignal?.removeEventListener("abort", forwardParentAbort);
|
|
4016
4022
|
}
|
|
4017
|
-
if (parallelDrainError) throw parallelDrainError;
|
|
4023
|
+
if (parallelDrainError) throw poolFailure(parallelDrainError, probeSession);
|
|
4018
4024
|
pushWorkerDedupPerfs(workerResults, dedupPerfs);
|
|
4025
|
+
const workerPageErrors = [];
|
|
4026
|
+
pushWorkerPageErrors(workerResults, workerPageErrors);
|
|
4019
4027
|
if (parallelGuardRan) {
|
|
4020
4028
|
deDrainStats = parallelStats;
|
|
4021
4029
|
}
|
|
@@ -4025,6 +4033,7 @@ async function runCaptureStreamingStage(input) {
|
|
|
4025
4033
|
await closeCaptureSession(probeSession);
|
|
4026
4034
|
probeSession = null;
|
|
4027
4035
|
}
|
|
4036
|
+
lastBrowserConsole = withWorkerPageErrors(lastBrowserConsole, workerPageErrors);
|
|
4028
4037
|
} else {
|
|
4029
4038
|
const videoInjector = createRenderVideoFrameInjector();
|
|
4030
4039
|
const session = probeSession ?? await createCaptureSession(
|
|
@@ -4471,7 +4480,7 @@ async function runCaptureSegmentedStage(input) {
|
|
|
4471
4480
|
|
|
4472
4481
|
// ../producer/src/services/render/segmentManifest.ts
|
|
4473
4482
|
import { createHash as createHash2 } from "crypto";
|
|
4474
|
-
import { existsSync as existsSync7, mkdirSync as mkdirSync4, readFileSync as readFileSync4,
|
|
4483
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync4, readFileSync as readFileSync4, statSync as statSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
4475
4484
|
import { join as join10 } from "path";
|
|
4476
4485
|
var MANIFEST_FILENAME = "segments.json";
|
|
4477
4486
|
function computeSegmentPlanHash(input) {
|
|
@@ -4528,7 +4537,7 @@ function writeSegmentManifest(segmentDir, manifest) {
|
|
|
4528
4537
|
mkdirSync4(segmentDir, { recursive: true });
|
|
4529
4538
|
const tmp = join10(segmentDir, `${MANIFEST_FILENAME}.${process.pid}.tmp`);
|
|
4530
4539
|
writeFileSync3(tmp, JSON.stringify(manifest, null, 2), "utf-8");
|
|
4531
|
-
|
|
4540
|
+
renameWithRetry(tmp, join10(segmentDir, MANIFEST_FILENAME));
|
|
4532
4541
|
}
|
|
4533
4542
|
async function probeSegmentFrameCount(path, probe) {
|
|
4534
4543
|
try {
|
|
@@ -8401,7 +8410,7 @@ import { rmSync as rmSync7 } from "fs";
|
|
|
8401
8410
|
|
|
8402
8411
|
// ../producer/src/services/render/audioPadTrim.ts
|
|
8403
8412
|
import { spawn } from "child_process";
|
|
8404
|
-
import { mkdtempSync as mkdtempSync3,
|
|
8413
|
+
import { mkdtempSync as mkdtempSync3, rmSync as rmSync6 } from "fs";
|
|
8405
8414
|
import { dirname as dirname6, join as join16 } from "path";
|
|
8406
8415
|
|
|
8407
8416
|
// ../producer/src/services/render/audioTruePeak.ts
|
|
@@ -8648,7 +8657,7 @@ async function enforceAacTruePeak(input) {
|
|
|
8648
8657
|
}
|
|
8649
8658
|
if (truePeakDbfs <= AAC_DELIVERY_TRUE_PEAK_DBFS) {
|
|
8650
8659
|
if (measuredPath !== correctedPath) return { success: true };
|
|
8651
|
-
|
|
8660
|
+
renameWithRetry(correctedPath, input.audioPath);
|
|
8652
8661
|
return { success: true, loweredDb: Number((-attenuationDb).toFixed(2)) };
|
|
8653
8662
|
}
|
|
8654
8663
|
if (pass === MAX_TRUE_PEAK_CORRECTION_PASSES) break;
|
|
@@ -8838,6 +8847,7 @@ async function runAudioStage(input) {
|
|
|
8838
8847
|
const result = await mixAudioForDelivery(input, duration, pcmSourcePath);
|
|
8839
8848
|
let audioLoweredDb;
|
|
8840
8849
|
if (result.hasAudio) {
|
|
8850
|
+
const guardStart = Date.now();
|
|
8841
8851
|
const peak = await constrainAacTruePeak({
|
|
8842
8852
|
audioPath: result.audioOutputPath,
|
|
8843
8853
|
sourcePath: pcmSourcePath,
|
|
@@ -8847,6 +8857,7 @@ async function runAudioStage(input) {
|
|
|
8847
8857
|
});
|
|
8848
8858
|
if (!peak.success) throw encoderFailureError("Audio true-peak check failed", peak);
|
|
8849
8859
|
audioLoweredDb = peak.loweredDb;
|
|
8860
|
+
input.log?.info("[audio] phases", { ...result.audioPhaseMs, guard: Date.now() - guardStart });
|
|
8850
8861
|
}
|
|
8851
8862
|
return { ...result, audioLoweredDb, audioProcessMs: Date.now() - stageStart };
|
|
8852
8863
|
} finally {
|
|
@@ -8872,6 +8883,7 @@ async function mixAudioForDelivery(input, duration, pcmSourcePath) {
|
|
|
8872
8883
|
let hasAudio = false;
|
|
8873
8884
|
let audioError;
|
|
8874
8885
|
let audioFailures;
|
|
8886
|
+
let audioPhaseMs;
|
|
8875
8887
|
if (audios.length > 0) {
|
|
8876
8888
|
let audioResult;
|
|
8877
8889
|
try {
|
|
@@ -8921,6 +8933,7 @@ async function mixAudioForDelivery(input, duration, pcmSourcePath) {
|
|
|
8921
8933
|
assertAudioNotInterrupted(audioResult.failures);
|
|
8922
8934
|
hasAudio = audioResult.success;
|
|
8923
8935
|
audioFailures = audioResult.failures;
|
|
8936
|
+
audioPhaseMs = audioResult.phaseMs;
|
|
8924
8937
|
if (!hasAudio) {
|
|
8925
8938
|
audioError = audioResult.error ?? "audio mix failed for an unknown reason";
|
|
8926
8939
|
for (const failure of audioResult.failures ?? []) {
|
|
@@ -8939,7 +8952,8 @@ async function mixAudioForDelivery(input, duration, pcmSourcePath) {
|
|
|
8939
8952
|
audioOutputPath,
|
|
8940
8953
|
hasAudio,
|
|
8941
8954
|
audioError,
|
|
8942
|
-
audioFailures
|
|
8955
|
+
audioFailures,
|
|
8956
|
+
audioPhaseMs
|
|
8943
8957
|
};
|
|
8944
8958
|
}
|
|
8945
8959
|
|
|
@@ -9054,6 +9068,7 @@ async function runCaptureStage(input) {
|
|
|
9054
9068
|
let { workerCount } = plan2;
|
|
9055
9069
|
const { forceScreenshot } = plan2;
|
|
9056
9070
|
let lastBrowserConsole = [];
|
|
9071
|
+
const workerPageErrors = [];
|
|
9057
9072
|
let captureBeyondViewport = probeSession?.options.captureBeyondViewport;
|
|
9058
9073
|
const captureCfg = cfg.forceScreenshot === forceScreenshot ? cfg : { ...cfg, forceScreenshot };
|
|
9059
9074
|
if (frameRange !== void 0) {
|
|
@@ -9091,6 +9106,7 @@ async function runCaptureStage(input) {
|
|
|
9091
9106
|
abortSignal,
|
|
9092
9107
|
frameRangeStart: frameRange?.startFrame,
|
|
9093
9108
|
dedupPerfs,
|
|
9109
|
+
pageErrorLines: workerPageErrors,
|
|
9094
9110
|
onProgress: (progress) => {
|
|
9095
9111
|
if (progress.latestWorkerPhase) {
|
|
9096
9112
|
if (progress.capturedFrames === 0) reportWorkerStartup(job, progress, onProgress);
|
|
@@ -9111,6 +9127,11 @@ async function runCaptureStage(input) {
|
|
|
9111
9127
|
},
|
|
9112
9128
|
cfg: captureCfg,
|
|
9113
9129
|
log
|
|
9130
|
+
}).catch((error) => {
|
|
9131
|
+
throw wrapCaptureStageError(
|
|
9132
|
+
error,
|
|
9133
|
+
withWorkerPageErrors(probeSession?.browserConsoleBuffer ?? [], workerPageErrors)
|
|
9134
|
+
);
|
|
9114
9135
|
});
|
|
9115
9136
|
captureAttempts.push(...attempts);
|
|
9116
9137
|
const lastAttempt = attempts[attempts.length - 1];
|
|
@@ -9123,6 +9144,7 @@ async function runCaptureStage(input) {
|
|
|
9123
9144
|
await closeCaptureSession(probeSession);
|
|
9124
9145
|
probeSession = null;
|
|
9125
9146
|
}
|
|
9147
|
+
lastBrowserConsole = withWorkerPageErrors(lastBrowserConsole, workerPageErrors);
|
|
9126
9148
|
} else {
|
|
9127
9149
|
const sequential = await runSequentialDiskCapture(
|
|
9128
9150
|
input,
|
|
@@ -10400,7 +10422,7 @@ function videoEncoderOptions(input, engineCfg) {
|
|
|
10400
10422
|
};
|
|
10401
10423
|
}
|
|
10402
10424
|
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"
|
|
10425
|
+
return workerCount > 1 && workerCount < cpuCount && !input.isPngSequence && !input.isGif && !input.enableChunkedEncode && input.preset.codec === "h264" && !input.preset.hdr && input.job.config.useGpu !== true && input.captureImageFormat === "jpeg";
|
|
10404
10426
|
}
|
|
10405
10427
|
async function readLandedFrame(workerPath, mergedPath) {
|
|
10406
10428
|
if (workerPath !== void 0) {
|
|
@@ -11055,6 +11077,7 @@ async function executeDiskCaptureWithAdaptiveRetry(options) {
|
|
|
11055
11077
|
options.cfg
|
|
11056
11078
|
);
|
|
11057
11079
|
pushWorkerDedupPerfs(workerResults, options.dedupPerfs);
|
|
11080
|
+
if (options.pageErrorLines) pushWorkerPageErrors(workerResults, options.pageErrorLines);
|
|
11058
11081
|
} finally {
|
|
11059
11082
|
await mergeWorkerFrames(attemptWorkDir, tasks, options.framesDir);
|
|
11060
11083
|
}
|
|
@@ -13433,7 +13456,6 @@ import {
|
|
|
13433
13456
|
existsSync as existsSync20,
|
|
13434
13457
|
linkSync,
|
|
13435
13458
|
mkdirSync as mkdirSync12,
|
|
13436
|
-
renameSync as renameSync5,
|
|
13437
13459
|
rmSync as rmSync11,
|
|
13438
13460
|
writeFileSync as writeFileSync8
|
|
13439
13461
|
} from "fs";
|
|
@@ -14360,14 +14382,7 @@ import { writeFileSync as writeFileSync7, writeSync } from "fs";
|
|
|
14360
14382
|
import { join as join30 } from "path";
|
|
14361
14383
|
|
|
14362
14384
|
// ../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";
|
|
14385
|
+
import { createReadStream as createReadStream4, createWriteStream, mkdirSync as mkdirSync10, mkdtempSync as mkdtempSync4, rmSync as rmSync10 } from "fs";
|
|
14371
14386
|
import { open } from "fs/promises";
|
|
14372
14387
|
import { dirname as dirname11, join as join29 } from "path";
|
|
14373
14388
|
import { finished, pipeline } from "stream/promises";
|
|
@@ -14741,7 +14756,7 @@ async function writeStitchedMp4(chunkPaths, outputPath, audioPath) {
|
|
|
14741
14756
|
for (const [i, path] of sourcePaths.entries()) await copyPayload(path, layouts[i], i, out);
|
|
14742
14757
|
out.end();
|
|
14743
14758
|
await finished(out);
|
|
14744
|
-
|
|
14759
|
+
renameWithRetry(join29(workDir, "out.mp4"), outputPath);
|
|
14745
14760
|
} finally {
|
|
14746
14761
|
out.destroy();
|
|
14747
14762
|
rmSync10(workDir, { recursive: true, force: true });
|
|
@@ -15467,7 +15482,10 @@ async function compilePlanComposition(projectDir, config, planDir, options) {
|
|
|
15467
15482
|
const needsAlpha = outputNeedsAlpha(config.format);
|
|
15468
15483
|
const remoteFiles = Object.entries(options.remoteFiles ?? {});
|
|
15469
15484
|
const remoteLocalPath = (rel) => join32(projectDir, ...rel.split("/"));
|
|
15470
|
-
for (const [, file] of remoteFiles)
|
|
15485
|
+
for (const [, file] of remoteFiles) {
|
|
15486
|
+
declareContentAddressedUrl(file.url, file.sha256);
|
|
15487
|
+
if (file.probeFactsUrl) declareProbeFactsUrl(file.url, file.probeFactsUrl);
|
|
15488
|
+
}
|
|
15471
15489
|
const urlByAbsentLocalPath = new Map(
|
|
15472
15490
|
remoteFiles.map(([rel, file]) => [remoteLocalPath(rel), file.url])
|
|
15473
15491
|
);
|
|
@@ -15542,7 +15560,7 @@ async function compilePlanComposition(projectDir, config, planDir, options) {
|
|
|
15542
15560
|
if (probeResult.fileServer) closeFileServerSafely(probeResult.fileServer, "plan", log);
|
|
15543
15561
|
if (probeResult.probeSession) {
|
|
15544
15562
|
try {
|
|
15545
|
-
const { closeCaptureSession: closeCaptureSession2 } = await import("./src-
|
|
15563
|
+
const { closeCaptureSession: closeCaptureSession2 } = await import("./src-BH5NICGQ.js");
|
|
15546
15564
|
await closeCaptureSession2(probeResult.probeSession);
|
|
15547
15565
|
} catch (err) {
|
|
15548
15566
|
log.warn("[plan] probe session close failed", {
|
|
@@ -15589,7 +15607,8 @@ function mixPlanAudio(c, compiledDir) {
|
|
|
15589
15607
|
audios: c.composition.audios,
|
|
15590
15608
|
masterFxChain: c.composition.masterFxChain,
|
|
15591
15609
|
abortSignal: c.abortSignal,
|
|
15592
|
-
assertNotAborted: c.assertNotAborted
|
|
15610
|
+
assertNotAborted: c.assertNotAborted,
|
|
15611
|
+
log: c.log
|
|
15593
15612
|
});
|
|
15594
15613
|
}
|
|
15595
15614
|
async function extractPlanVideos(c, deferRangeExtraction) {
|
|
@@ -15608,6 +15627,7 @@ async function extractPlanVideos(c, deferRangeExtraction) {
|
|
|
15608
15627
|
if (extractResult.failureToEnforce) throw extractResult.failureToEnforce;
|
|
15609
15628
|
if (extractResult.extractionResult) {
|
|
15610
15629
|
assertVideoExtractionSucceeded(extractResult.extractionResult);
|
|
15630
|
+
c.log.info("[plan] extract phases", { ...extractResult.extractionResult.phaseBreakdown });
|
|
15611
15631
|
}
|
|
15612
15632
|
return extractResult;
|
|
15613
15633
|
}
|
|
@@ -15653,12 +15673,12 @@ async function buildLocalExecutionPlan(projectDir, config, executionPlanDir, opt
|
|
|
15653
15673
|
const videoSourcesDir = join32(planDir, "video-sources");
|
|
15654
15674
|
rmSync11(videoSourcesDir, { recursive: true, force: true });
|
|
15655
15675
|
if (existsSync20(stagedVideoFrames)) {
|
|
15656
|
-
|
|
15676
|
+
renameWithRetry(stagedVideoFrames, videoFramesDst);
|
|
15657
15677
|
} else {
|
|
15658
15678
|
mkdirSync12(videoFramesDst, { recursive: true });
|
|
15659
15679
|
}
|
|
15660
15680
|
if (existsSync20(finalCompiledDir)) rmSync11(finalCompiledDir, { recursive: true, force: true });
|
|
15661
|
-
|
|
15681
|
+
renameWithRetry(compiledDir, finalCompiledDir);
|
|
15662
15682
|
const shipVideoSource = createVideoSourceShipper({
|
|
15663
15683
|
planDir,
|
|
15664
15684
|
projectDir,
|
|
@@ -15761,7 +15781,7 @@ async function buildLocalExecutionPlan(projectDir, config, executionPlanDir, opt
|
|
|
15761
15781
|
}
|
|
15762
15782
|
const planAudioPath = join32(planDir, PLAN_AUDIO_RELATIVE_PATH);
|
|
15763
15783
|
if (audioResult?.hasAudio && existsSync20(audioResult.audioOutputPath)) {
|
|
15764
|
-
|
|
15784
|
+
renameWithRetry(audioResult.audioOutputPath, planAudioPath);
|
|
15765
15785
|
}
|
|
15766
15786
|
if (chunksCarryAudio && existsSync20(planAudioPath)) {
|
|
15767
15787
|
if (options.sliceChunkAudio) {
|
|
@@ -17193,7 +17213,7 @@ function startServer(options = {}) {
|
|
|
17193
17213
|
});
|
|
17194
17214
|
async function shutdown(signal) {
|
|
17195
17215
|
log.info(`Received ${signal}, shutting down`);
|
|
17196
|
-
const { drainBrowserPool } = await import("./src-
|
|
17216
|
+
const { drainBrowserPool } = await import("./src-BH5NICGQ.js");
|
|
17197
17217
|
await drainBrowserPool().catch(() => {
|
|
17198
17218
|
});
|
|
17199
17219
|
const handle = await Promise.race([
|
|
@@ -17237,7 +17257,6 @@ import {
|
|
|
17237
17257
|
mkdtempSync as mkdtempSync7,
|
|
17238
17258
|
readFileSync as readFileSync12,
|
|
17239
17259
|
readdirSync as readdirSync9,
|
|
17240
|
-
renameSync as renameSync7,
|
|
17241
17260
|
rmSync as rmSync14,
|
|
17242
17261
|
statSync as statSync9,
|
|
17243
17262
|
writeFileSync as writeFileSync11
|
|
@@ -17252,7 +17271,6 @@ import {
|
|
|
17252
17271
|
linkSync as linkSync2,
|
|
17253
17272
|
mkdirSync as mkdirSync14,
|
|
17254
17273
|
mkdtempSync as mkdtempSync6,
|
|
17255
|
-
renameSync as renameSync6,
|
|
17256
17274
|
rmSync as rmSync13,
|
|
17257
17275
|
statSync as statSync8,
|
|
17258
17276
|
writeFileSync as writeFileSync10
|
|
@@ -17345,7 +17363,7 @@ var LocalPlanV2ArtifactPublisher = class {
|
|
|
17345
17363
|
if (!canFallbackToCopy(error)) throw error;
|
|
17346
17364
|
copyFileSync5(blob.sourcePath, temporaryPath);
|
|
17347
17365
|
}
|
|
17348
|
-
|
|
17366
|
+
renameWithRetry(temporaryPath, destinationPath);
|
|
17349
17367
|
} finally {
|
|
17350
17368
|
rmSync13(stagingDir, { recursive: true, force: true });
|
|
17351
17369
|
}
|
|
@@ -17359,7 +17377,7 @@ var LocalPlanV2ArtifactPublisher = class {
|
|
|
17359
17377
|
}
|
|
17360
17378
|
}
|
|
17361
17379
|
writeFileSync10(join37(this.temporaryDir, "plan.json"), manifestBytes, "utf-8");
|
|
17362
|
-
|
|
17380
|
+
renameWithRetry(this.temporaryDir, this.destinationDir);
|
|
17363
17381
|
this.#committed = true;
|
|
17364
17382
|
}
|
|
17365
17383
|
async abort() {
|
|
@@ -17626,7 +17644,7 @@ function writeBlob(sourcePath, destinationPath) {
|
|
|
17626
17644
|
const temporaryPath = join38(temporaryDir, "blob");
|
|
17627
17645
|
try {
|
|
17628
17646
|
copyFileSync6(sourcePath, temporaryPath);
|
|
17629
|
-
|
|
17647
|
+
renameWithRetry(temporaryPath, destinationPath);
|
|
17630
17648
|
} finally {
|
|
17631
17649
|
rmSync14(temporaryDir, { recursive: true, force: true });
|
|
17632
17650
|
}
|
|
@@ -17758,7 +17776,7 @@ function createPlanV2FromExecutionPlan(executionPlanDir, planV2Dir) {
|
|
|
17758
17776
|
canonicalJsonStringify(publication.manifest),
|
|
17759
17777
|
"utf-8"
|
|
17760
17778
|
);
|
|
17761
|
-
|
|
17779
|
+
renameWithRetry(tempDir, planV2Dir);
|
|
17762
17780
|
return resultFromManifest(planV2Dir, publication.manifest);
|
|
17763
17781
|
} catch (error) {
|
|
17764
17782
|
rmSync14(tempDir, { recursive: true, force: true });
|
|
@@ -18043,7 +18061,7 @@ function materializePlanV2Target(planV2Dir, target, destinationDir, options = {}
|
|
|
18043
18061
|
}),
|
|
18044
18062
|
"utf-8"
|
|
18045
18063
|
);
|
|
18046
|
-
|
|
18064
|
+
renameWithRetry(tempDir, destinationDir);
|
|
18047
18065
|
} catch (error) {
|
|
18048
18066
|
rmSync14(tempDir, { recursive: true, force: true });
|
|
18049
18067
|
throw error;
|
|
@@ -18121,7 +18139,6 @@ import {
|
|
|
18121
18139
|
mkdtempSync as mkdtempSync8,
|
|
18122
18140
|
readFileSync as readFileSync13,
|
|
18123
18141
|
readdirSync as readdirSync10,
|
|
18124
|
-
renameSync as renameSync8,
|
|
18125
18142
|
rmSync as rmSync15,
|
|
18126
18143
|
statSync as statSync10,
|
|
18127
18144
|
writeFileSync as writeFileSync12
|
|
@@ -18181,7 +18198,7 @@ async function assemble(planDir, chunkOutputs, audioPath, outputPath, options) {
|
|
|
18181
18198
|
const finalPath = join39(workDir, `output.${format}`);
|
|
18182
18199
|
const audio = audioPath !== null && existsSync26(audioPath) ? audioPath : null;
|
|
18183
18200
|
await writeJoined(ctx, videoSources, audio, finalPath);
|
|
18184
|
-
|
|
18201
|
+
renameWithRetry(finalPath, outputPath);
|
|
18185
18202
|
log.info("[assemble] stage timings", {
|
|
18186
18203
|
...stageMs,
|
|
18187
18204
|
chunks: chunkPaths.length,
|
|
@@ -18433,6 +18450,7 @@ function mergePngFrameDirs(chunkPaths, outputPath, totalFrames, audioPath, start
|
|
|
18433
18450
|
// ../producer/src/services/distributed/renderChunk.ts
|
|
18434
18451
|
import { randomBytes } from "crypto";
|
|
18435
18452
|
import { existsSync as existsSync27, mkdirSync as mkdirSync17, readFileSync as readFileSync14, readdirSync as readdirSync11, rmSync as rmSync16, writeFileSync as writeFileSync13 } from "fs";
|
|
18453
|
+
import { cpus as cpus3 } from "os";
|
|
18436
18454
|
import { join as join40 } from "path";
|
|
18437
18455
|
var LEGACY_DISTRIBUTED_VP9_CPU_USED = 2;
|
|
18438
18456
|
function validatePlanVideosForChunk(value) {
|
|
@@ -18721,6 +18739,7 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath, options) {
|
|
|
18721
18739
|
let forceScreenshotForChunk = encoder.forceScreenshot;
|
|
18722
18740
|
let shownBoxes;
|
|
18723
18741
|
let extraction;
|
|
18742
|
+
const overlap = { current: null };
|
|
18724
18743
|
try {
|
|
18725
18744
|
if (chunkWorkerCount === 1 || !forceScreenshotForChunk) {
|
|
18726
18745
|
const bootStarted = Date.now();
|
|
@@ -18808,6 +18827,59 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath, options) {
|
|
|
18808
18827
|
videoFrameLookup,
|
|
18809
18828
|
frameCacheOptions(cfg, chunkWorkerCount)
|
|
18810
18829
|
);
|
|
18830
|
+
const isPngSequence = plan2.dimensions.format === "png-sequence";
|
|
18831
|
+
outputKind = isPngSequence ? "frame-dir" : "file";
|
|
18832
|
+
const presetFormat = isPngSequence ? "mp4" : plan2.dimensions.format;
|
|
18833
|
+
const basePreset = getEncoderPreset(job.config.quality, presetFormat, void 0);
|
|
18834
|
+
const preset = resolvePresetForLockedEncoder(basePreset, encoder.encoder);
|
|
18835
|
+
const effectiveQuality = encoder.crf ?? preset.quality;
|
|
18836
|
+
const effectiveBitrate = encoder.crf != null ? void 0 : encoder.bitrate;
|
|
18837
|
+
const videoOnlyPath = encoder.chunksCarryAudio ? `${outputChunkPath}.video.mp4` : outputChunkPath;
|
|
18838
|
+
if (isPngSequence) {
|
|
18839
|
+
if (!existsSync27(outputChunkPath)) mkdirSync17(outputChunkPath, { recursive: true });
|
|
18840
|
+
} else {
|
|
18841
|
+
const outDir = join40(outputChunkPath, "..");
|
|
18842
|
+
if (!existsSync27(outDir)) mkdirSync17(outDir, { recursive: true });
|
|
18843
|
+
}
|
|
18844
|
+
const encodeInput = {
|
|
18845
|
+
job,
|
|
18846
|
+
log,
|
|
18847
|
+
outputPath: videoOnlyPath,
|
|
18848
|
+
framesDir,
|
|
18849
|
+
videoOnlyPath,
|
|
18850
|
+
width: Math.round(plan2.dimensions.width * encoder.deviceScaleFactor),
|
|
18851
|
+
height: Math.round(plan2.dimensions.height * encoder.deviceScaleFactor),
|
|
18852
|
+
needsAlpha: plan2.dimensions.format !== "mp4",
|
|
18853
|
+
captureImageFormat: captureOptions.format ?? "jpeg",
|
|
18854
|
+
// The encoder writes video only; audio joins at assemble time or in the
|
|
18855
|
+
// chunk that carries audio. Suppressing `hasAudio` skips the png-sequence audio
|
|
18856
|
+
// sidecar AND the mp4 audio mux.
|
|
18857
|
+
hasAudio: false,
|
|
18858
|
+
isPngSequence,
|
|
18859
|
+
// `DistributedFormat` has no "gif" member — distributed chunks are
|
|
18860
|
+
// always video segments (gif renders in-process only).
|
|
18861
|
+
isGif: false,
|
|
18862
|
+
preset,
|
|
18863
|
+
effectiveQuality,
|
|
18864
|
+
effectiveBitrate,
|
|
18865
|
+
engineConfig: {
|
|
18866
|
+
ffmpegEncodeTimeout: cfg.ffmpegEncodeTimeout,
|
|
18867
|
+
vp9CpuUsed: resolveLockedVp9CpuUsed(encoder) ?? cfg.vp9CpuUsed
|
|
18868
|
+
},
|
|
18869
|
+
// Distributed chunks emit a single ffmpeg call per chunk; the
|
|
18870
|
+
// in-process per-chunk-within-chunk path would re-split our
|
|
18871
|
+
// already-chunked work.
|
|
18872
|
+
enableChunkedEncode: false,
|
|
18873
|
+
chunkedEncodeSize: framesInChunk,
|
|
18874
|
+
abortSignal: void 0,
|
|
18875
|
+
assertNotAborted: () => {
|
|
18876
|
+
},
|
|
18877
|
+
// GOP === framesInChunk + force-keyframe at frame 0 → the chunk's
|
|
18878
|
+
// first frame is an IDR keyframe and concat-copy at assemble time
|
|
18879
|
+
// round-trips losslessly.
|
|
18880
|
+
lockGopForChunkConcat: !isPngSequence,
|
|
18881
|
+
gopSize: framesInChunk
|
|
18882
|
+
};
|
|
18811
18883
|
const captureStarted = Date.now();
|
|
18812
18884
|
captureMode = await runCaptureWithScreenshotFallback({
|
|
18813
18885
|
forceScreenshot: forceScreenshotForChunk,
|
|
@@ -18840,6 +18912,7 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath, options) {
|
|
|
18840
18912
|
}
|
|
18841
18913
|
const captureSession = session;
|
|
18842
18914
|
session = null;
|
|
18915
|
+
overlap.current = canEncodeWhileCapturing(encodeInput, chunkWorkerCount, cpus3().length) ? encodeWhileCapturing(encodeInput, framesInChunk) : null;
|
|
18843
18916
|
await runCaptureStage({
|
|
18844
18917
|
fileServer,
|
|
18845
18918
|
workDir,
|
|
@@ -18859,7 +18932,12 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath, options) {
|
|
|
18859
18932
|
abortSignal: void 0,
|
|
18860
18933
|
assertNotAborted: () => {
|
|
18861
18934
|
},
|
|
18862
|
-
frameRange: range
|
|
18935
|
+
frameRange: range,
|
|
18936
|
+
onFrameLanded: (frame) => overlap.current?.onFrameLanded(frame)
|
|
18937
|
+
}).catch(async (captureError) => {
|
|
18938
|
+
await overlap.current?.abort();
|
|
18939
|
+
overlap.current = null;
|
|
18940
|
+
throw captureError;
|
|
18863
18941
|
});
|
|
18864
18942
|
return observedChunkCaptureMode(capturePerfs);
|
|
18865
18943
|
},
|
|
@@ -18891,60 +18969,10 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath, options) {
|
|
|
18891
18969
|
log
|
|
18892
18970
|
);
|
|
18893
18971
|
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
18972
|
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
|
-
});
|
|
18973
|
+
const overlapped = overlap.current;
|
|
18974
|
+
overlap.current = null;
|
|
18975
|
+
await (overlapped ? overlapped.finish() : runEncodeStage(encodeInput));
|
|
18948
18976
|
if (encoder.chunksCarryAudio) {
|
|
18949
18977
|
const audioScratchPath = `${outputChunkPath}.audio.m4a`;
|
|
18950
18978
|
const audioChunks = options?.frameRange ? chunksWithSubRange(chunks, chunkIndex, range) : { chunks, index: chunkIndex };
|
|
@@ -18962,6 +18990,8 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath, options) {
|
|
|
18962
18990
|
}
|
|
18963
18991
|
encodeStageMs = Date.now() - encodeStarted;
|
|
18964
18992
|
} finally {
|
|
18993
|
+
await overlap.current?.abort().catch(() => {
|
|
18994
|
+
});
|
|
18965
18995
|
await extraction?.catch(() => {
|
|
18966
18996
|
});
|
|
18967
18997
|
if (session) {
|
|
@@ -19074,6 +19104,10 @@ var READ_CHUNK_BYTES = 256 * 1024;
|
|
|
19074
19104
|
import { extname as extname7 } from "path";
|
|
19075
19105
|
var AUDIO_SIDECAR_MIN_BYTES = 32 * 1024 * 1024;
|
|
19076
19106
|
|
|
19107
|
+
// ../producer/src/services/distributed/probeFacts.ts
|
|
19108
|
+
import { writeFileSync as writeFileSync14 } from "fs";
|
|
19109
|
+
import { extname as extname8 } from "path";
|
|
19110
|
+
|
|
19077
19111
|
export {
|
|
19078
19112
|
createConsoleLogger,
|
|
19079
19113
|
defaultLogger,
|