hyperframes 0.8.173 → 0.8.174
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-V7VBTFNG.js → add-XANMFNIP.js} +14 -15
- package/dist/{animatedGifPrep-62S72ZY6.js → animatedGifPrep-OUQ4M2T3.js} +9 -11
- package/dist/api.js +19 -21
- package/dist/{asset-Z4JI2F6V.js → asset-SVONSQ67.js} +2 -2
- package/dist/{assetCataloger-Q7LE7BCC.js → assetCataloger-AG77T6SF.js} +9 -11
- package/dist/{audio-HIHNLQJ7.js → audio-DMQOTXKL.js} +16 -18
- package/dist/{auth-4K6DSZCD.js → auth-ED7SPBS6.js} +2 -2
- package/dist/{autoUpdate-DXZDD5VT.js → autoUpdate-4QQYZOVT.js} +2 -2
- package/dist/{backgroundChecks-ODMKKJ4S.js → backgroundChecks-2VT46P5S.js} +3 -3
- package/dist/backgroundChecksWorker.js +3 -3
- package/dist/{batchRender-I4BFJGPA.js → batchRender-KIYAPCTG.js} +4 -4
- package/dist/{beats-7QCA6GDR.js → beats-OE7M5BEE.js} +6 -7
- package/dist/{benchmark-IT4WTSMZ.js → benchmark-2ZQP2RNF.js} +11 -12
- package/dist/{browser-5VHM72PM.js → browser-CSSJ3VWW.js} +5 -6
- package/dist/{bundleWithLocalizedFonts-MKTQCB2Y.js → bundleWithLocalizedFonts-ZUC4MLSO.js} +2 -2
- package/dist/{capture-CMNNIMIL.js → capture-3NXAHID3.js} +2 -2
- package/dist/{capture-B5Y45EWD.js → capture-APNSW4ZT.js} +22 -18
- package/dist/{catalog-AKPJ65GY.js → catalog-CFDBIVSC.js} +15 -16
- package/dist/{catch-up-2SVYRMD3.js → catch-up-OUK522JT.js} +6 -7
- package/dist/{check-Q7AX6K7O.js → check-PUDEOXGP.js} +37 -39
- package/dist/{checkBrowser-CPXD5BZY.js → checkBrowser-PMRJSTFJ.js} +34 -36
- package/dist/chunk-2CDBTQKS.js +113 -0
- package/dist/{chunk-KR5ZHRF2.js → chunk-2XSAYE7U.js} +2 -2
- package/dist/{chunk-QVPOR7WE.js → chunk-32GKETR7.js} +22 -1
- package/dist/{chunk-BTPZ74Z3.js → chunk-3MDO2Q4F.js} +1 -1
- package/dist/{chunk-3O45NOL7.js → chunk-4PX47Z65.js} +1 -1
- package/dist/{chunk-IK3SOMZ4.js → chunk-4VTUDCHM.js} +19 -22
- package/dist/{chunk-NOMPG5HQ.js → chunk-4WQUBVDO.js} +3 -3
- package/dist/{chunk-HCOL75LA.js → chunk-55LJK3H2.js} +3 -3
- package/dist/{chunk-H5C375DW.js → chunk-6HF2WFPV.js} +5 -5
- package/dist/{chunk-BCPJSBCS.js → chunk-ALCCEHX2.js} +7 -3
- package/dist/{chunk-XDPXSQJO.js → chunk-APMA7XXB.js} +1 -1
- package/dist/{chunk-L4SFGSSQ.js → chunk-AR2SEGPZ.js} +1 -1
- package/dist/{chunk-ETPPGNJB.js → chunk-B23GBPCW.js} +2 -2
- package/dist/{chunk-4RDDUBOC.js → chunk-CI7ZHFSV.js} +11 -11
- package/dist/chunk-CIWX5UKC.js +16 -0
- package/dist/{chunk-4D2T6Y5Y.js → chunk-CSMKMVGG.js} +6 -6
- package/dist/{chunk-BYRHCRU3.js → chunk-D2YN4FNH.js} +2 -2
- package/dist/{chunk-PBVUVNWP.js → chunk-DRR3UMIY.js} +1 -1
- package/dist/{chunk-TNHRCZT3.js → chunk-EAR5LFOH.js} +42 -2
- package/dist/{chunk-5JTRGGTX.js → chunk-EJZJ5AY7.js} +1 -1
- package/dist/{chunk-ODR7V2JL.js → chunk-G4UUEQDT.js} +1 -1
- package/dist/{chunk-2TNPXPI5.js → chunk-GK2FIKIQ.js} +10 -8
- package/dist/{chunk-CBOYQOLY.js → chunk-GXWV4FNV.js} +1 -1
- package/dist/{chunk-QURKHVV5.js → chunk-H2BPHBDY.js} +1 -1
- package/dist/{chunk-X3SCQP2A.js → chunk-HB2UP4V7.js} +1 -1
- package/dist/chunk-HIP62XAW.js +36 -0
- package/dist/{chunk-6JQDH4O6.js → chunk-HIYAJFRH.js} +1 -1
- package/dist/{chunk-45IAFBUP.js → chunk-HZZYJV7K.js} +14 -14
- package/dist/{chunk-A2DMF2Q6.js → chunk-HZZZ6C6Z.js} +2 -2
- package/dist/{chunk-XZNKIYIG.js → chunk-JKPI7VLI.js} +1 -1
- package/dist/{chunk-TWZRU64W.js → chunk-JL76Y45C.js} +7 -7
- package/dist/{chunk-KRWEUM4R.js → chunk-LR72ON5B.js} +1 -1
- package/dist/{chunk-C4QGOXO2.js → chunk-LUKY7253.js} +491 -133
- package/dist/{chunk-2QJDC4NT.js → chunk-MXNPYP5F.js} +1 -1
- package/dist/{chunk-VFCKXTBB.js → chunk-NL5F3AD4.js} +27 -38
- package/dist/{chunk-WIAO42MD.js → chunk-ONXTLGJB.js} +5 -5
- package/dist/{chunk-N7RTLKMM.js → chunk-PLYTTPVE.js} +2 -2
- package/dist/{chunk-PCLYCYBK.js → chunk-QJCVK7CI.js} +4 -4
- package/dist/{chunk-6HKO6VWS.js → chunk-QRO2UBWS.js} +1 -1
- package/dist/{chunk-ROQBQHBK.js → chunk-QUK2IZKI.js} +1 -1
- package/dist/{chunk-2DWYRHJS.js → chunk-RLBLLBLL.js} +2 -2
- package/dist/{chunk-U7EGMXQR.js → chunk-RMKL5FVH.js} +4 -17
- package/dist/{chunk-2BL7BJ22.js → chunk-RNKNDYBN.js} +1 -1
- package/dist/{chunk-SOAXQ7Q7.js → chunk-RYR3LTZR.js} +2 -2
- package/dist/{chunk-5E43335V.js → chunk-RZ2FMZ5U.js} +1 -1
- package/dist/{chunk-L3RCYYON.js → chunk-S5D4Q74P.js} +2 -2
- package/dist/{chunk-V2D4QZBC.js → chunk-SEHRMJTO.js} +3 -3
- package/dist/{chunk-X2ALZSKK.js → chunk-SEXAKOK3.js} +3 -3
- package/dist/{chunk-6RIH2NDU.js → chunk-SH43VDEF.js} +9 -9
- package/dist/{chunk-YOOW26KG.js → chunk-SI76MFBF.js} +2 -2
- package/dist/{chunk-QWQ6GQTI.js → chunk-T6AGUTZJ.js} +2 -4
- package/dist/{chunk-LN4SZS7W.js → chunk-TI3HKGQC.js} +3 -3
- package/dist/{chunk-CHALU2TF.js → chunk-UDJHYQSZ.js} +1 -1
- package/dist/{chunk-MWNSVO4P.js → chunk-UKAOWORD.js} +8 -8
- package/dist/chunk-UKJECUDK.js +3805 -0
- package/dist/{chunk-OFFNB2SU.js → chunk-UQLXFITA.js} +241 -6
- package/dist/{chunk-JYVGYKXG.js → chunk-W2LGJSEN.js} +73 -1
- package/dist/{chunk-BYVBP3U5.js → chunk-W3YVQ6VI.js} +9 -9
- package/dist/{chunk-FDWTZVA6.js → chunk-W4AECR7V.js} +1 -1
- package/dist/{chunk-2YTOJ447.js → chunk-X3BE2HX4.js} +3 -3
- package/dist/{chunk-TDPVEMBS.js → chunk-XFCLWWL3.js} +1 -1
- package/dist/{chunk-O433SZAJ.js → chunk-XVIFWEPR.js} +35 -16
- package/dist/{clean-SBFI3ZKR.js → clean-6SVCU47L.js} +18 -20
- package/dist/cli.js +53 -53
- package/dist/{cloud-IRE4HLEK.js → cloud-TIISRMZV.js} +4 -4
- package/dist/{cloudrun-GIHWEBGM.js → cloudrun-4TMBWELQ.js} +5 -5
- package/dist/{compare-S6NM2FSV.js → compare-YV2XTKYX.js} +28 -30
- package/dist/{compiler-WCWRB2LZ.js → compiler-O5R3ZZDV.js} +5 -6
- package/dist/{component-WDFZQ2HN.js → component-7LWSMRKZ.js} +3 -3
- package/dist/{compositions-RMUBDPD4.js → compositions-5VTSC4M3.js} +14 -16
- package/dist/{delete-SDNARGJ4.js → delete-AV2SKLZW.js} +4 -4
- package/dist/{deploy-4MK3Y67M.js → deploy-NKWMPAMH.js} +19 -5
- package/dist/{destroy-GFQLTIY3.js → destroy-UKP522AE.js} +4 -2
- package/dist/{dist-FAN2FFAV.js → dist-2FMTAVGL.js} +3 -3
- package/dist/{dist-65ELHZOF.js → dist-4FY5EEH5.js} +3 -3
- package/dist/{doctor-YPCZILXV.js → doctor-XOCYSEAZ.js} +14 -16
- package/dist/{events-INXDJ44V.js → events-6QPRKX45.js} +4 -5
- package/dist/{events-Q2K7SNEZ.js → events-MAZUZI43.js} +5 -6
- package/dist/{feedback-FRGRCTIX.js → feedback-MGRILBMP.js} +10 -11
- package/dist/{ffmpeg-7BYARPLM.js → ffmpeg-YCULCUB2.js} +24 -4
- package/dist/{figma-C262EFOC.js → figma-UMBACTCG.js} +3 -3
- package/dist/fontLocalizeCli.js +11 -13
- package/dist/{get-ZIUUGSVI.js → get-LWEOLWYN.js} +4 -4
- package/dist/{gpuPolicy-FRLW63IY.js → gpuPolicy-MCIQK5Z7.js} +9 -11
- package/dist/{grade-compare-DN342HJC.js → grade-compare-MZQOTX3F.js} +29 -31
- package/dist/{help-XQPBPSBP.js → help-THPG2NRP.js} +1 -1
- package/dist/{history-PF5FUC6M.js → history-2IQYTDU5.js} +8 -9
- package/dist/hyperframe-runtime.js +55 -55
- package/dist/hyperframe.manifest.json +1 -1
- package/dist/hyperframe.runtime.iife.js +55 -55
- package/dist/hyperframes-player.global.js +3 -3
- package/dist/{info-PC7IKGVB.js → info-CXMADV6K.js} +10 -11
- package/dist/{init-ORZX3PSQ.js → init-Y5GU454D.js} +34 -34
- package/dist/{inspect-L5GRL6SP.js → inspect-S7JDKEMJ.js} +29 -31
- package/dist/{installer-KXS557O7.js → installer-AY23RPEZ.js} +5 -5
- package/dist/{keyframes-EIZDSXUH.js → keyframes-FKYT6QAJ.js} +8 -9
- package/dist/{lambda-U3N7MRD7.js → lambda-7WMZGRH5.js} +16 -12
- package/dist/{layout-WHAVE2H5.js → layout-LL4GOS6G.js} +29 -31
- package/dist/{lint-I7PYIW56.js → lint-2M7FY4ZT.js} +11 -12
- package/dist/{lintProject-7IEOAXJY.js → lintProject-ARKJXDQF.js} +3 -3
- package/dist/{list-XXQM3WDO.js → list-SZBMUHBW.js} +4 -4
- package/dist/{login-64NUUDYU.js → login-QRACITGK.js} +4 -4
- package/dist/{manager-B6MVBM2E.js → manager-W2BTPAVT.js} +25 -3
- package/dist/{media-treatment-5XIM4A3F.js → media-treatment-E4VJETTT.js} +23 -18
- package/dist/{models-WRB3S67Z.js → models-AHO3MYE7.js} +13 -15
- package/dist/{motionShot-BOFBL73C.js → motionShot-LMMYPGPT.js} +19 -21
- package/dist/{normalize-audio-PP4BSZSU.js → normalize-audio-RDWIWZOO.js} +6 -7
- package/dist/{open-F4CUWMZF.js → open-WOKRHFDH.js} +14 -15
- package/dist/{parakeetRunner-O7QYJ7V7.js → parakeetRunner-RY2KIE63.js} +16 -18
- package/dist/{pipeline-BCHSFFT3.js → pipeline-LEA32KLW.js} +11 -13
- package/dist/{play-PPBR2GJK.js → play-3S46XG66.js} +21 -23
- package/dist/{policies-DCSIM4AB.js → policies-5NTZOHJA.js} +2 -0
- package/dist/preflight-MCOFNWFQ.js +52 -0
- package/dist/{present-Y7VTCZRZ.js → present-GR7F4CTI.js} +17 -19
- package/dist/{preview-53AD4OME.js → preview-TKEAF3KR.js} +34 -25
- package/dist/{producer-WBJDNLBF.js → producer-BJ5SUPVD.js} +1 -1
- package/dist/{progress-5AM2MZ7V.js → progress-I37JB7R4.js} +1 -0
- package/dist/{projectConfig-4KUGQ4P6.js → projectConfig-YJBYWSNK.js} +7 -7
- package/dist/{publication-OFDIFS4R.js → publication-2HXIW4LS.js} +3 -3
- package/dist/{publish-RWWTY743.js → publish-LHJFEKEI.js} +11 -11
- package/dist/{remove-background-G7VK3VKP.js → remove-background-AQUUVAPD.js} +12 -14
- package/dist/{render-7PPMS4P6.js → render-AOHXNGIM.js} +40 -38
- package/dist/{render-6CXZNXXZ.js → render-AXTGGHVZ.js} +9 -4
- package/dist/{render-52W63I3Y.js → render-B5S7FLLS.js} +14 -15
- package/dist/{render-batch-2EJVUVVN.js → render-batch-DMQG3QWK.js} +4 -4
- package/dist/renderSetupWorker.js +3 -3
- package/dist/{resolver-FF5GV6IA.js → resolver-FV54X3T2.js} +5 -5
- package/dist/sam-IKPEJRRO.js +21 -0
- package/dist/{screenshotCapture-XAYELJK7.js → screenshotCapture-HXEZ3TNJ.js} +20 -3
- package/dist/{sherpa-QJPI6B5S.js → sherpa-RKURBTUM.js} +15 -17
- package/dist/skills/hyperframes/SKILL.md +42 -0
- package/dist/skills/hyperframes-cli/references/cloud.md +1 -1
- package/dist/skills/media-use/scripts/lib/recipe-store.mjs +5 -2
- package/dist/{skills-H6ZJNOLH.js → skills-YUXI4IRF.js} +11 -10
- package/dist/{skillsUpdateCheck-4EBGMO2A.js → skillsUpdateCheck-HK3GDYD6.js} +3 -3
- package/dist/{snapshot-DZRUBWRH.js → snapshot-D6Q52Z4X.js} +32 -34
- package/dist/{src-ZL7ACIZ3.js → src-DPR7JBU3.js} +10 -12
- package/dist/{src-WD5GOYON.js → src-MRYINZ62.js} +8 -10
- package/dist/{staticProjectServer-72JF5PPO.js → staticProjectServer-RT7JATD2.js} +15 -16
- package/dist/{status-RGHSK3DJ.js → status-BV7QAUQD.js} +2 -3
- package/dist/studio/assets/{hyperframes-player-B-wEZiX3.js → hyperframes-player-B4KfQdfl.js} +1 -1
- package/dist/studio/assets/{index-DPugLDRK.js → index-Bsc8xBh9.js} +1 -1
- package/dist/studio/assets/{index-Bvkb0Zxy.js → index-DGl_Zvb3.js} +97 -97
- package/dist/studio/index.html +1 -1
- package/dist/{studio-api-BL6CLOA6.js → studio-api-NL2RMVB5.js} +9 -10
- package/dist/{studioServer-TRWCZZXP.js → studioServer-VL2GUVCR.js} +47 -49
- package/dist/{system-VRXC6S4A.js → system-7F3UEHQT.js} +2 -3
- package/dist/{telemetry-FDSW3ZOZ.js → telemetry-5PJWDFSZ.js} +5 -6
- package/dist/{timeline-ZRN336EA.js → timeline-OH35TN25.js} +124 -51
- package/dist/{tokens-RMLNQHIB.js → tokens-YISVK7W2.js} +2 -2
- package/dist/{transcribe-SOODKU6H.js → transcribe-6KBSE76Q.js} +12 -14
- package/dist/{transcribe-AEHHCYAL.js → transcribe-KRPN2FWA.js} +22 -24
- package/dist/{updateCheck-OSPEYRBY.js → updateCheck-QCZTFFSQ.js} +2 -2
- package/dist/{upgrade-AK4S7DMX.js → upgrade-DRFQISI6.js} +2 -2
- package/dist/{urlDownloader-FSCMLFG7.js → urlDownloader-CJDXTKMC.js} +8 -10
- package/dist/{validate-JJTCKZIV.js → validate-BKY3FIJC.js} +23 -25
- package/dist/{video-ZDM5CFI2.js → video-3UEJ57Q7.js} +9 -11
- package/package.json +1 -1
- package/dist/chunk-7JDEZNBY.js +0 -3805
- package/dist/chunk-7KDQAD2W.js +0 -81
- package/dist/chunk-BXCMXMJQ.js +0 -73
- package/dist/chunk-KCF6GHJP.js +0 -250
- package/dist/preflight-G5KP7ZKA.js +0 -32
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
EncoderInterruptedError,
|
|
23
23
|
encoderFailureError,
|
|
24
24
|
prepareAnimatedGifInputs
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-RYR3LTZR.js";
|
|
26
26
|
import {
|
|
27
27
|
BROWSER_GPU_NOT_SOFTWARE,
|
|
28
28
|
CaptureFailure,
|
|
@@ -151,7 +151,7 @@ import {
|
|
|
151
151
|
validateEngineConfigSnapshot,
|
|
152
152
|
verifyDiskDrawElementSamples,
|
|
153
153
|
writeCapturedFrame
|
|
154
|
-
} from "./chunk-
|
|
154
|
+
} from "./chunk-XVIFWEPR.js";
|
|
155
155
|
import {
|
|
156
156
|
assignBundledRuntimeCompositionIds,
|
|
157
157
|
buildVariablesByCompScript,
|
|
@@ -164,12 +164,12 @@ import {
|
|
|
164
164
|
isTemplateEntry,
|
|
165
165
|
parsesAsScript,
|
|
166
166
|
prepareFlattenedInnerRoot
|
|
167
|
-
} from "./chunk-
|
|
167
|
+
} from "./chunk-UQLXFITA.js";
|
|
168
168
|
import {
|
|
169
169
|
LOW_MEMORY_TOTAL_MB_THRESHOLD,
|
|
170
170
|
getCgroupMemoryLimitMb,
|
|
171
171
|
getSystemTotalMb
|
|
172
|
-
} from "./chunk-
|
|
172
|
+
} from "./chunk-W2LGJSEN.js";
|
|
173
173
|
import {
|
|
174
174
|
DISTRIBUTED_FPS,
|
|
175
175
|
HF_VFX_ATTR,
|
|
@@ -190,7 +190,7 @@ import {
|
|
|
190
190
|
resolveAbsoluteMediaStartSeconds,
|
|
191
191
|
resolveAuthoredTimingWindow,
|
|
192
192
|
toFps
|
|
193
|
-
} from "./chunk-
|
|
193
|
+
} from "./chunk-RMKL5FVH.js";
|
|
194
194
|
import {
|
|
195
195
|
COMPOSITION_SOURCE_URL,
|
|
196
196
|
HF_COLOR_GRADING_ATTR,
|
|
@@ -218,7 +218,7 @@ import {
|
|
|
218
218
|
shouldClampResolvedMediaDuration,
|
|
219
219
|
sourceTimeAt,
|
|
220
220
|
styleElementsFor
|
|
221
|
-
} from "./chunk-
|
|
221
|
+
} from "./chunk-UKJECUDK.js";
|
|
222
222
|
import {
|
|
223
223
|
MAX_AUDIO_GAIN
|
|
224
224
|
} from "./chunk-UJKQWGFF.js";
|
|
@@ -242,7 +242,7 @@ import {
|
|
|
242
242
|
} from "./chunk-TWWSYAKJ.js";
|
|
243
243
|
import {
|
|
244
244
|
lintHyperframeHtml
|
|
245
|
-
} from "./chunk-
|
|
245
|
+
} from "./chunk-GK2FIKIQ.js";
|
|
246
246
|
import {
|
|
247
247
|
isUnresolvedAssetPlaceholder,
|
|
248
248
|
readProjectFile,
|
|
@@ -250,7 +250,7 @@ import {
|
|
|
250
250
|
} from "./chunk-6BNTGNGD.js";
|
|
251
251
|
import {
|
|
252
252
|
checkSubCompositionUsability
|
|
253
|
-
} from "./chunk-
|
|
253
|
+
} from "./chunk-32GKETR7.js";
|
|
254
254
|
import {
|
|
255
255
|
CSS_URL_RE,
|
|
256
256
|
decodedUrlPath,
|
|
@@ -419,11 +419,11 @@ var defaultLogger = createConsoleLogger("info");
|
|
|
419
419
|
|
|
420
420
|
// ../producer/src/services/fileServer.ts
|
|
421
421
|
var readFileAsync = promisify(readFile);
|
|
422
|
-
function isPathInside(
|
|
422
|
+
function isPathInside(child2, parent, options = {}) {
|
|
423
423
|
const { resolveSymlinks = false, pathModule } = options;
|
|
424
424
|
const resolveFn = pathModule?.resolve ?? resolve2;
|
|
425
425
|
const separator = pathModule?.sep ?? sep;
|
|
426
|
-
const resolvedChild = resolveFn(
|
|
426
|
+
const resolvedChild = resolveFn(child2);
|
|
427
427
|
const resolvedParent = resolveFn(parent);
|
|
428
428
|
const normalizedChild = resolveSymlinks && existsSync2(resolvedChild) ? realpathSync.native(resolvedChild) : resolvedChild;
|
|
429
429
|
const normalizedParent = resolveSymlinks && existsSync2(resolvedParent) ? realpathSync.native(resolvedParent) : resolvedParent;
|
|
@@ -3342,10 +3342,10 @@ function aggregateDrawElement(perfs, de) {
|
|
|
3342
3342
|
gateReason: gateReasons.length > 0 ? gateReasons.join("|") : void 0,
|
|
3343
3343
|
gpuRenderer: gpuRenderers.length > 0 ? gpuRenderers.join("|") : void 0,
|
|
3344
3344
|
workerEncode: perfs.some((p) => p.deWorkerEncode),
|
|
3345
|
-
verifyArmed: perfs.reduce((
|
|
3345
|
+
verifyArmed: perfs.reduce((sum2, p) => sum2 + (p.deVerifyArmed ?? 0), 0),
|
|
3346
3346
|
verifyChecked: drain?.verifyChecked ?? 0,
|
|
3347
3347
|
verifyMinDb: roundDb(drain?.verifyMinDb),
|
|
3348
|
-
verifyInitMs: perfs.reduce((
|
|
3348
|
+
verifyInitMs: perfs.reduce((sum2, p) => sum2 + (p.deVerifyInitMs ?? 0), 0),
|
|
3349
3349
|
selfVerifyFallback: de.selfVerifyFallback,
|
|
3350
3350
|
fallbackReason: de.fallbackReason,
|
|
3351
3351
|
fallbackFailedDb: roundDb(de.fallbackFailedDb),
|
|
@@ -3354,9 +3354,9 @@ function aggregateDrawElement(perfs, de) {
|
|
|
3354
3354
|
blankSuspects: drain?.blankSuspects ?? 0,
|
|
3355
3355
|
blankDeterministicAccepts: drain?.blankDeterministicAccepts ?? 0,
|
|
3356
3356
|
blankRecaptures: drain?.blankRecaptures ?? 0,
|
|
3357
|
-
boundaryFrames: perfs.reduce((
|
|
3358
|
-
ncprFallbacks: perfs.reduce((
|
|
3359
|
-
frameTimeouts: perfs.reduce((
|
|
3357
|
+
boundaryFrames: perfs.reduce((sum2, p) => sum2 + (p.deBoundaryFrames ?? 0), 0),
|
|
3358
|
+
ncprFallbacks: perfs.reduce((sum2, p) => sum2 + (p.deNcprFallbacks ?? 0), 0),
|
|
3359
|
+
frameTimeouts: perfs.reduce((sum2, p) => sum2 + (p.deFrameTimeouts ?? 0), 0)
|
|
3360
3360
|
};
|
|
3361
3361
|
}
|
|
3362
3362
|
function maxDefined(values) {
|
|
@@ -3371,9 +3371,9 @@ function aggregateChromeMemory(perfs) {
|
|
|
3371
3371
|
rendererRssPeakMb: maxDefined(sampled.map((p) => p.chromeRendererRssPeakMb)),
|
|
3372
3372
|
// Last samples are per session; summing approximates the whole fleet's
|
|
3373
3373
|
// footprint at the end of capture (workers run concurrently).
|
|
3374
|
-
rssLastMb: sampled.reduce((
|
|
3374
|
+
rssLastMb: sampled.reduce((sum2, p) => sum2 + (p.chromeRssLastMb ?? 0), 0),
|
|
3375
3375
|
gpuProcessSeenLastSample: sampled.some((p) => p.chromeGpuProcessSeenLastSample === true),
|
|
3376
|
-
samples: sampled.reduce((
|
|
3376
|
+
samples: sampled.reduce((sum2, p) => sum2 + (p.chromeMemorySamples ?? 0), 0)
|
|
3377
3377
|
};
|
|
3378
3378
|
}
|
|
3379
3379
|
function aggregateDedup(perfs) {
|
|
@@ -3391,45 +3391,45 @@ function aggregateDedup(perfs) {
|
|
|
3391
3391
|
return {
|
|
3392
3392
|
enabled: perfs.some((p) => p.staticDedupEnabled),
|
|
3393
3393
|
armed,
|
|
3394
|
-
predictedFrames: perfs.reduce((
|
|
3395
|
-
reusedFrames: perfs.reduce((
|
|
3394
|
+
predictedFrames: perfs.reduce((sum2, p) => sum2 + (p.staticDedupPredicted ?? 0), 0),
|
|
3395
|
+
reusedFrames: perfs.reduce((sum2, p) => sum2 + (p.staticDedupReused ?? 0), 0),
|
|
3396
3396
|
skipReason: skipReasons.length > 0 ? skipReasons.join("|") : void 0,
|
|
3397
3397
|
...verificationPerfs.length === 0 ? {} : {
|
|
3398
3398
|
verifiedFrames: verificationPerfs.reduce(
|
|
3399
|
-
(
|
|
3399
|
+
(sum2, perf) => sum2 + (perf.staticDedupVerified ?? 0),
|
|
3400
3400
|
0
|
|
3401
3401
|
),
|
|
3402
3402
|
verificationOutcomes,
|
|
3403
3403
|
plannedRuns: verificationPerfs.reduce(
|
|
3404
|
-
(
|
|
3404
|
+
(sum2, perf) => sum2 + (perf.staticDedupVerificationPlannedRuns ?? 0),
|
|
3405
3405
|
0
|
|
3406
3406
|
),
|
|
3407
3407
|
completedRuns: verificationPerfs.reduce(
|
|
3408
|
-
(
|
|
3408
|
+
(sum2, perf) => sum2 + (perf.staticDedupVerificationCompletedRuns ?? 0),
|
|
3409
3409
|
0
|
|
3410
3410
|
),
|
|
3411
3411
|
screenshots: verificationPerfs.reduce(
|
|
3412
|
-
(
|
|
3412
|
+
(sum2, perf) => sum2 + (perf.staticDedupVerificationScreenshots ?? 0),
|
|
3413
3413
|
0
|
|
3414
3414
|
),
|
|
3415
3415
|
seeks: verificationPerfs.reduce(
|
|
3416
|
-
(
|
|
3416
|
+
(sum2, perf) => sum2 + (perf.staticDedupVerificationSeeks ?? 0),
|
|
3417
3417
|
0
|
|
3418
3418
|
),
|
|
3419
3419
|
comparisons: verificationPerfs.reduce(
|
|
3420
|
-
(
|
|
3420
|
+
(sum2, perf) => sum2 + (perf.staticDedupVerificationComparisons ?? 0),
|
|
3421
3421
|
0
|
|
3422
3422
|
),
|
|
3423
3423
|
verificationElapsedMs: verificationPerfs.reduce(
|
|
3424
|
-
(
|
|
3424
|
+
(sum2, perf) => sum2 + (perf.staticDedupVerificationElapsedMs ?? 0),
|
|
3425
3425
|
0
|
|
3426
3426
|
)
|
|
3427
3427
|
}
|
|
3428
3428
|
};
|
|
3429
3429
|
}
|
|
3430
3430
|
function aggregateBeginFrameReuse(perfs) {
|
|
3431
|
-
const noDamageFrames = perfs.reduce((
|
|
3432
|
-
const hasDamageFrames = perfs.reduce((
|
|
3431
|
+
const noDamageFrames = perfs.reduce((sum2, p) => sum2 + (p.beginFrameNoDamage ?? 0), 0);
|
|
3432
|
+
const hasDamageFrames = perfs.reduce((sum2, p) => sum2 + (p.beginFrameHasDamage ?? 0), 0);
|
|
3433
3433
|
if (noDamageFrames + hasDamageFrames === 0) return void 0;
|
|
3434
3434
|
return { noDamageFrames, hasDamageFrames };
|
|
3435
3435
|
}
|
|
@@ -8021,7 +8021,7 @@ var VideoExtractionStageError = class extends Error {
|
|
|
8021
8021
|
affectedElementCount: failure.count
|
|
8022
8022
|
}))
|
|
8023
8023
|
)) {
|
|
8024
|
-
const total = failures.reduce((
|
|
8024
|
+
const total = failures.reduce((sum2, failure) => sum2 + failure.count, 0);
|
|
8025
8025
|
const breakdown = failures.map((failure) => `${failure.kind}=${failure.count}`).join(",");
|
|
8026
8026
|
super(`Video extraction failed for ${total} source(s) [${code}; ${breakdown}]`);
|
|
8027
8027
|
this.code = code;
|
|
@@ -10160,6 +10160,16 @@ async function padOrTrimAudioToVideoFrameCount(input) {
|
|
|
10160
10160
|
...loweredDb > 0 ? { audioLoweredDb: loweredDb } : {}
|
|
10161
10161
|
};
|
|
10162
10162
|
}
|
|
10163
|
+
async function constrainAacTruePeak(input) {
|
|
10164
|
+
const timeoutMs = input.timeoutMs ?? DEFAULT_CONFIG.ffmpegProcessTimeout;
|
|
10165
|
+
return enforceAacTruePeak({
|
|
10166
|
+
audioPath: input.audioPath,
|
|
10167
|
+
targetDurationSeconds: input.targetDurationSeconds,
|
|
10168
|
+
signal: input.signal,
|
|
10169
|
+
probeTruePeak: (audioPath, signal) => defaultProbeAudioTruePeakDbfs(audioPath, timeoutMs, signal),
|
|
10170
|
+
runner: (args) => defaultRunFfmpeg(args, timeoutMs, input.signal)
|
|
10171
|
+
});
|
|
10172
|
+
}
|
|
10163
10173
|
async function enforceAacTruePeak(input) {
|
|
10164
10174
|
let scratchDir;
|
|
10165
10175
|
try {
|
|
@@ -10755,7 +10765,7 @@ function countCapturedFrames(totalFrames, framesDir, frameExt) {
|
|
|
10755
10765
|
return captured;
|
|
10756
10766
|
}
|
|
10757
10767
|
function countFrameRanges(ranges) {
|
|
10758
|
-
return ranges.reduce((
|
|
10768
|
+
return ranges.reduce((sum2, range) => sum2 + (range.endFrame - range.startFrame), 0);
|
|
10759
10769
|
}
|
|
10760
10770
|
async function executeDiskCaptureWithAdaptiveRetry(options) {
|
|
10761
10771
|
const attempts = [];
|
|
@@ -11006,7 +11016,7 @@ function scanElementTags(html) {
|
|
|
11006
11016
|
const byTag = Object.fromEntries(
|
|
11007
11017
|
ranked.slice(0, MAX_REPORTED_ELEMENT_TAGS)
|
|
11008
11018
|
);
|
|
11009
|
-
const otherCount = ranked.slice(MAX_REPORTED_ELEMENT_TAGS).reduce((
|
|
11019
|
+
const otherCount = ranked.slice(MAX_REPORTED_ELEMENT_TAGS).reduce((sum2, [, count]) => sum2 + count, 0);
|
|
11010
11020
|
if (otherCount > 0) byTag.other = (byTag.other ?? 0) + otherCount;
|
|
11011
11021
|
const arollVideoCount = markup.match(/<video\b[^>]*\bdata-aroll=["']true["'][^>]*>/gi)?.length ?? 0;
|
|
11012
11022
|
const heygenVideoCount = markup.match(/<video\b[^>]*\bdata-media-source=["']heygen["'][^>]*>/gi)?.length ?? 0;
|
|
@@ -14002,15 +14012,15 @@ var ChunkExceedsWorkerTimeoutError = class extends Error {
|
|
|
14002
14012
|
function resolveMaxParallelChunks(config, totalFrames, megapixels, log = defaultLogger) {
|
|
14003
14013
|
if (config.maxParallelChunks !== void 0) return config.maxParallelChunks;
|
|
14004
14014
|
const { workerTimeoutSeconds, workerConcurrency } = config;
|
|
14005
|
-
const pinsChunking = config.chunkSize !== void 0 || config.targetChunkFrames !== void 0;
|
|
14006
|
-
if (pinsChunking || workerTimeoutSeconds === void 0 && workerConcurrency === void 0) {
|
|
14007
|
-
return DEFAULT_MAX_PARALLEL_CHUNKS;
|
|
14008
|
-
}
|
|
14009
|
-
const secondsPerFrame = ESTIMATED_SECONDS_PER_MEGAPIXEL_FRAME * megapixels;
|
|
14010
14015
|
const wave = Math.min(
|
|
14011
14016
|
workerConcurrency ?? DEFAULT_MAX_PARALLEL_CHUNKS,
|
|
14012
14017
|
MAX_PARALLEL_CHUNKS_CEILING
|
|
14013
14018
|
);
|
|
14019
|
+
const pinsChunking = config.chunkSize !== void 0 || config.targetChunkFrames !== void 0;
|
|
14020
|
+
if (pinsChunking || workerTimeoutSeconds === void 0 && workerConcurrency === void 0) {
|
|
14021
|
+
return wave;
|
|
14022
|
+
}
|
|
14023
|
+
const secondsPerFrame = ESTIMATED_SECONDS_PER_MEGAPIXEL_FRAME * megapixels;
|
|
14014
14024
|
const minFramesPerChunk = Math.ceil(ESTIMATED_CHUNK_OVERHEAD_SECONDS / secondsPerFrame);
|
|
14015
14025
|
const wide = Math.max(1, Math.min(wave, Math.floor(totalFrames / minFramesPerChunk)));
|
|
14016
14026
|
if (workerTimeoutSeconds === void 0) return wide;
|
|
@@ -14027,7 +14037,7 @@ function resolveMaxParallelChunks(config, totalFrames, megapixels, log = default
|
|
|
14027
14037
|
}
|
|
14028
14038
|
if (needed > wave) {
|
|
14029
14039
|
log.warn(
|
|
14030
|
-
`[plan] ${needed} chunks are needed to keep each under the ${workerTimeoutSeconds} s worker time limit, but the plan assumes ${wave} workers at once, so the render runs in ${Math.ceil(needed / wave)} waves. Raise --concurrency to ${needed} to render in one wave (Lambda: hyperframes lambda deploy --concurrency ${needed}).`,
|
|
14040
|
+
`[plan] ${needed} chunks are needed to keep each under the ${workerTimeoutSeconds} s worker time limit, but the plan assumes ${wave} workers at once, so the render runs in ${Math.ceil(needed / wave)} waves. Raise --concurrency to ${needed} to render in one wave (Lambda: hyperframes lambda deploy --concurrency ${needed}, or a higher account concurrency quota).`,
|
|
14031
14041
|
{ needed, workerConcurrency: wave, workerTimeoutSeconds }
|
|
14032
14042
|
);
|
|
14033
14043
|
}
|
|
@@ -14199,21 +14209,6 @@ function buildLockedRenderConfig(input) {
|
|
|
14199
14209
|
function carriesChunkAudio(config, options) {
|
|
14200
14210
|
return options.chunksCarryAudio === true && config.format === "mp4" && config.cfr !== true;
|
|
14201
14211
|
}
|
|
14202
|
-
async function fitPlanAudioToFrames(audioPath, workDir, totalFrames, fps, run) {
|
|
14203
|
-
const fittedPath = join29(workDir, "audio-fitted.m4a");
|
|
14204
|
-
const result = await padOrTrimAudioToVideoFrameCount({
|
|
14205
|
-
videoPath: audioPath,
|
|
14206
|
-
probeVideoFrameInfo: async () => ({ frameCount: totalFrames, fpsNum: fps, fpsDen: 1 }),
|
|
14207
|
-
audioPath,
|
|
14208
|
-
outputPath: fittedPath,
|
|
14209
|
-
signal: run.signal,
|
|
14210
|
-
timeoutMs: run.timeoutMs
|
|
14211
|
-
});
|
|
14212
|
-
if (!result.success) {
|
|
14213
|
-
throw encoderFailureError("[plan] audio pad/trim failed", result);
|
|
14214
|
-
}
|
|
14215
|
-
renameSync4(fittedPath, audioPath);
|
|
14216
|
-
}
|
|
14217
14212
|
function resolveEncoderTriple(config) {
|
|
14218
14213
|
if (config.format === "mp4") {
|
|
14219
14214
|
return resolveMp4EncoderTriple(config.codec);
|
|
@@ -14423,7 +14418,7 @@ async function buildLocalExecutionPlan(projectDir, config, executionPlanDir, opt
|
|
|
14423
14418
|
if (probeResult.fileServer) closeFileServerSafely(probeResult.fileServer, "plan", log);
|
|
14424
14419
|
if (probeResult.probeSession) {
|
|
14425
14420
|
try {
|
|
14426
|
-
const { closeCaptureSession: closeCaptureSession2 } = await import("./src-
|
|
14421
|
+
const { closeCaptureSession: closeCaptureSession2 } = await import("./src-MRYINZ62.js");
|
|
14427
14422
|
await closeCaptureSession2(probeResult.probeSession);
|
|
14428
14423
|
} catch (err) {
|
|
14429
14424
|
log.warn("[plan] probe session close failed", {
|
|
@@ -14511,13 +14506,15 @@ async function buildLocalExecutionPlan(projectDir, config, executionPlanDir, opt
|
|
|
14511
14506
|
"utf-8"
|
|
14512
14507
|
);
|
|
14513
14508
|
const digests = options.digests ?? /* @__PURE__ */ new Map();
|
|
14509
|
+
const chunksCarryAudio2 = carriesChunkAudio(config, options);
|
|
14510
|
+
const audioSeconds = chunksCarryAudio2 ? totalFrames / config.fps : probeResult.duration;
|
|
14514
14511
|
stageStarted = Date.now();
|
|
14515
14512
|
const [audioOutcome, overlapOutcome] = await Promise.allSettled([
|
|
14516
14513
|
runAudioStage({
|
|
14517
14514
|
projectDir,
|
|
14518
14515
|
workDir,
|
|
14519
14516
|
compiledDir: finalCompiledDir,
|
|
14520
|
-
duration:
|
|
14517
|
+
duration: audioSeconds,
|
|
14521
14518
|
ffmpegProcessTimeout: cfg.ffmpegProcessTimeout,
|
|
14522
14519
|
audioGain: cfg.audioGain,
|
|
14523
14520
|
audios: composition.audios,
|
|
@@ -14547,12 +14544,16 @@ async function buildLocalExecutionPlan(projectDir, config, executionPlanDir, opt
|
|
|
14547
14544
|
if (audioResult.hasAudio && existsSync18(audioResult.audioOutputPath)) {
|
|
14548
14545
|
renameSync4(audioResult.audioOutputPath, planAudioPath);
|
|
14549
14546
|
}
|
|
14550
|
-
const chunksCarryAudio2 = carriesChunkAudio(config, options);
|
|
14551
14547
|
if (chunksCarryAudio2 && existsSync18(planAudioPath)) {
|
|
14552
|
-
|
|
14548
|
+
stageStarted = Date.now();
|
|
14549
|
+
const peak = await constrainAacTruePeak({
|
|
14550
|
+
audioPath: planAudioPath,
|
|
14551
|
+
targetDurationSeconds: audioSeconds,
|
|
14553
14552
|
signal: abortSignal,
|
|
14554
14553
|
timeoutMs: cfg.ffmpegProcessTimeout
|
|
14555
14554
|
});
|
|
14555
|
+
if (!peak.success) throw encoderFailureError("[plan] audio true-peak check failed", peak);
|
|
14556
|
+
logPlanStage(log, "audio-peak", stageStarted);
|
|
14556
14557
|
}
|
|
14557
14558
|
const ffmpegVersion = await readFfmpegVersion();
|
|
14558
14559
|
const producerVersion = readProducerVersion();
|
|
@@ -14637,8 +14638,8 @@ async function buildLocalExecutionPlan(projectDir, config, executionPlanDir, opt
|
|
|
14637
14638
|
producerVersion
|
|
14638
14639
|
};
|
|
14639
14640
|
}
|
|
14640
|
-
async function plan(projectDir, config, planDir) {
|
|
14641
|
-
const executionPlan = await buildLocalExecutionPlan(projectDir, config, planDir);
|
|
14641
|
+
async function plan(projectDir, config, planDir, options = {}) {
|
|
14642
|
+
const executionPlan = await buildLocalExecutionPlan(projectDir, config, planDir, options);
|
|
14642
14643
|
return {
|
|
14643
14644
|
planDir: executionPlan.executionPlanDir,
|
|
14644
14645
|
planProtocol: PLAN_PROTOCOL_V1,
|
|
@@ -15963,7 +15964,7 @@ function startServer(options = {}) {
|
|
|
15963
15964
|
});
|
|
15964
15965
|
async function shutdown(signal) {
|
|
15965
15966
|
log.info(`Received ${signal}, shutting down`);
|
|
15966
|
-
const { drainBrowserPool } = await import("./src-
|
|
15967
|
+
const { drainBrowserPool } = await import("./src-MRYINZ62.js");
|
|
15967
15968
|
await drainBrowserPool().catch(() => {
|
|
15968
15969
|
});
|
|
15969
15970
|
const handle = await Promise.race([
|
|
@@ -16225,7 +16226,7 @@ function resolveExtractedVideoOutputDir(planDir, videoId) {
|
|
|
16225
16226
|
}
|
|
16226
16227
|
function artifactTargets(path, videoDependencies, chunksCarryAudio2) {
|
|
16227
16228
|
if (isPlanAudioArtifactPath(path)) {
|
|
16228
|
-
return { chunks:
|
|
16229
|
+
return chunksCarryAudio2 ? { chunks: "all", assembler: false } : { chunks: [], assembler: true };
|
|
16229
16230
|
}
|
|
16230
16231
|
if (path === "plan.json" || path === "meta/chunks.json" || path === "meta/encoder.json") {
|
|
16231
16232
|
return { chunks: "all", assembler: true };
|
|
@@ -16786,7 +16787,7 @@ function materializePlanV2Target(planV2Dir, target, destinationDir) {
|
|
|
16786
16787
|
planHash: manifest.planHash,
|
|
16787
16788
|
sourcePlanV1Hash: getPlanV2ExecutionPlanHash(manifest),
|
|
16788
16789
|
artifactCount: artifacts.length,
|
|
16789
|
-
sizeBytes: artifacts.reduce((
|
|
16790
|
+
sizeBytes: artifacts.reduce((sum2, artifact) => sum2 + artifact.sizeBytes, 0),
|
|
16790
16791
|
// Join the artifact's OWN name, not the current constant: a plan written
|
|
16791
16792
|
// before the container change carries the legacy name, and materializing it
|
|
16792
16793
|
// under the new one would point at a file that was never written.
|
|
@@ -16823,24 +16824,371 @@ function validatePlanV2MaterializedTarget(planDir, expectedTarget) {
|
|
|
16823
16824
|
}
|
|
16824
16825
|
|
|
16825
16826
|
// ../producer/src/services/distributed/planV2Execution.ts
|
|
16826
|
-
import { mkdtempSync as
|
|
16827
|
+
import { mkdtempSync as mkdtempSync9, rmSync as rmSync16 } from "fs";
|
|
16827
16828
|
import { tmpdir as tmpdir5 } from "os";
|
|
16828
|
-
import { join as
|
|
16829
|
+
import { join as join39 } from "path";
|
|
16829
16830
|
|
|
16830
16831
|
// ../producer/src/services/distributed/assemble.ts
|
|
16831
16832
|
import {
|
|
16832
16833
|
cpSync as cpSync3,
|
|
16833
16834
|
existsSync as existsSync24,
|
|
16834
|
-
mkdirSync as
|
|
16835
|
-
mkdtempSync as
|
|
16835
|
+
mkdirSync as mkdirSync15,
|
|
16836
|
+
mkdtempSync as mkdtempSync8,
|
|
16836
16837
|
readFileSync as readFileSync12,
|
|
16837
16838
|
readdirSync as readdirSync9,
|
|
16838
|
-
renameSync as
|
|
16839
|
-
rmSync as
|
|
16839
|
+
renameSync as renameSync8,
|
|
16840
|
+
rmSync as rmSync14,
|
|
16840
16841
|
statSync as statSync10,
|
|
16841
16842
|
writeFileSync as writeFileSync11
|
|
16842
16843
|
} from "fs";
|
|
16844
|
+
import { dirname as dirname16, join as join37 } from "path";
|
|
16845
|
+
|
|
16846
|
+
// ../producer/src/services/distributed/mp4Stitch.ts
|
|
16847
|
+
import {
|
|
16848
|
+
createReadStream as createReadStream5,
|
|
16849
|
+
createWriteStream,
|
|
16850
|
+
mkdirSync as mkdirSync14,
|
|
16851
|
+
mkdtempSync as mkdtempSync7,
|
|
16852
|
+
renameSync as renameSync7,
|
|
16853
|
+
rmSync as rmSync13
|
|
16854
|
+
} from "fs";
|
|
16855
|
+
import { open } from "fs/promises";
|
|
16843
16856
|
import { dirname as dirname15, join as join36 } from "path";
|
|
16857
|
+
import { finished, pipeline } from "stream/promises";
|
|
16858
|
+
function boxAt(src, off, at, limit) {
|
|
16859
|
+
let size = src.readUInt32BE(off);
|
|
16860
|
+
let bodyStart = at + 8;
|
|
16861
|
+
if (size === 1) {
|
|
16862
|
+
size = Number(src.readBigUInt64BE(off + 8));
|
|
16863
|
+
bodyStart = at + 16;
|
|
16864
|
+
}
|
|
16865
|
+
if (size < 8 || at + size > limit) throw new Error(`[mp4Stitch] malformed box at ${at}`);
|
|
16866
|
+
return { type: src.toString("latin1", off + 4, off + 8), start: at, bodyStart, end: at + size };
|
|
16867
|
+
}
|
|
16868
|
+
function childBoxes(buf, parent) {
|
|
16869
|
+
const boxes = [];
|
|
16870
|
+
for (let at = parent.bodyStart; at < parent.end; at = boxes.at(-1).end) {
|
|
16871
|
+
boxes.push(boxAt(buf, at, at, parent.end));
|
|
16872
|
+
}
|
|
16873
|
+
return boxes;
|
|
16874
|
+
}
|
|
16875
|
+
function findChild(buf, parent, type) {
|
|
16876
|
+
return childBoxes(buf, parent).find((box2) => box2.type === type);
|
|
16877
|
+
}
|
|
16878
|
+
function child(buf, parent, type) {
|
|
16879
|
+
const found = findChild(buf, parent, type);
|
|
16880
|
+
if (!found) throw new Error(`[mp4Stitch] ${parent.type} has no ${type}`);
|
|
16881
|
+
return found;
|
|
16882
|
+
}
|
|
16883
|
+
var SCAN_BYTES = 64 * 1024;
|
|
16884
|
+
async function readMp4Layout(read) {
|
|
16885
|
+
const found = /* @__PURE__ */ new Map();
|
|
16886
|
+
let payload;
|
|
16887
|
+
let buf = Buffer.alloc(0);
|
|
16888
|
+
let bufAt = 0;
|
|
16889
|
+
const load = async (start, end) => {
|
|
16890
|
+
if (start >= bufAt && end <= bufAt + buf.length) return;
|
|
16891
|
+
buf = await read(start, Math.max(end, start + SCAN_BYTES));
|
|
16892
|
+
bufAt = start;
|
|
16893
|
+
};
|
|
16894
|
+
for (let at = 0; !(found.has("ftyp") && found.has("moov") && payload); ) {
|
|
16895
|
+
await load(at, at + 16);
|
|
16896
|
+
if (at + 8 > bufAt + buf.length) {
|
|
16897
|
+
throw new Error(`[mp4Stitch] chunk needs ftyp, moov and mdat; found ${[...found.keys()]}`);
|
|
16898
|
+
}
|
|
16899
|
+
const box2 = boxAt(buf, at - bufAt, at, Number.MAX_SAFE_INTEGER);
|
|
16900
|
+
if (box2.type === "mdat") payload ??= box2;
|
|
16901
|
+
if (box2.type === "ftyp" || box2.type === "moov") {
|
|
16902
|
+
await load(at, box2.end);
|
|
16903
|
+
found.set(box2.type, buf.subarray(at - bufAt, box2.end - bufAt));
|
|
16904
|
+
}
|
|
16905
|
+
at = box2.end;
|
|
16906
|
+
}
|
|
16907
|
+
const [ftyp, moov] = [found.get("ftyp"), found.get("moov")];
|
|
16908
|
+
if (moov.length !== moovSize(moov)) throw new Error("[mp4Stitch] moov is cut off");
|
|
16909
|
+
return { ftyp, moov, payloadStart: payload.bodyStart, payloadEnd: payload.end };
|
|
16910
|
+
}
|
|
16911
|
+
var moovSize = (moov) => boxAt(moov, 0, 0, Number.MAX_SAFE_INTEGER).end;
|
|
16912
|
+
function readTracks(moov) {
|
|
16913
|
+
const root = boxAt(moov, 0, 0, moov.length);
|
|
16914
|
+
return childBoxes(moov, root).filter((box2) => box2.type === "trak").map((trak) => readTrack(moov, trak));
|
|
16915
|
+
}
|
|
16916
|
+
function rows(buf, table, columns, countAt = 4) {
|
|
16917
|
+
const count = buf.readUInt32BE(table.bodyStart + countAt);
|
|
16918
|
+
const first = table.bodyStart + countAt + 4;
|
|
16919
|
+
return Array.from(
|
|
16920
|
+
{ length: count },
|
|
16921
|
+
(_, row) => Array.from(
|
|
16922
|
+
{ length: columns },
|
|
16923
|
+
(_2, col) => buf.readUInt32BE(first + (row * columns + col) * 4)
|
|
16924
|
+
)
|
|
16925
|
+
);
|
|
16926
|
+
}
|
|
16927
|
+
function readMediaTime(moov, trak) {
|
|
16928
|
+
const edts = findChild(moov, trak, "edts");
|
|
16929
|
+
if (!edts) return 0;
|
|
16930
|
+
const elst = child(moov, edts, "elst");
|
|
16931
|
+
const wide = moov[elst.bodyStart] === 1;
|
|
16932
|
+
const entries = moov.readUInt32BE(elst.bodyStart + 4);
|
|
16933
|
+
for (let i = 0, at = elst.bodyStart + 8; i < entries; i++, at += wide ? 20 : 12) {
|
|
16934
|
+
const offset = at + (wide ? 8 : 4);
|
|
16935
|
+
const mediaTime = wide ? Number(moov.readBigInt64BE(offset)) : moov.readInt32BE(offset);
|
|
16936
|
+
if (mediaTime !== -1) return mediaTime;
|
|
16937
|
+
}
|
|
16938
|
+
return 0;
|
|
16939
|
+
}
|
|
16940
|
+
function readSizes(moov, stsz) {
|
|
16941
|
+
const fixedSize = moov.readUInt32BE(stsz.bodyStart + 4);
|
|
16942
|
+
if (!fixedSize) return rows(moov, stsz, 1, 8).map(([size]) => size);
|
|
16943
|
+
return Array(moov.readUInt32BE(stsz.bodyStart + 8)).fill(fixedSize);
|
|
16944
|
+
}
|
|
16945
|
+
function readSync4(moov, stbl, sampleCount) {
|
|
16946
|
+
const stss = findChild(moov, stbl, "stss");
|
|
16947
|
+
if (!stss) return null;
|
|
16948
|
+
const sync = Array(sampleCount).fill(false);
|
|
16949
|
+
for (const [n] of rows(moov, stss, 1)) sync[n - 1] = true;
|
|
16950
|
+
return sync;
|
|
16951
|
+
}
|
|
16952
|
+
function readChunkOffsets(moov, stbl) {
|
|
16953
|
+
const stco = findChild(moov, stbl, "stco");
|
|
16954
|
+
if (stco) return rows(moov, stco, 1).map(([offset]) => offset);
|
|
16955
|
+
return rows(moov, child(moov, stbl, "co64"), 2).map(([hi, lo]) => hi * 2 ** 32 + lo);
|
|
16956
|
+
}
|
|
16957
|
+
function readSamplesPerChunk(moov, stbl, chunkCount) {
|
|
16958
|
+
const stsc = rows(moov, child(moov, stbl, "stsc"), 3);
|
|
16959
|
+
return stsc.flatMap(([firstChunk, perChunk, description], i) => {
|
|
16960
|
+
if (description !== 1) throw new Error("[mp4Stitch] chunk uses more than one sample entry");
|
|
16961
|
+
const nextFirst = stsc[i + 1]?.[0] ?? chunkCount + 1;
|
|
16962
|
+
return Array(nextFirst - firstChunk).fill(perChunk);
|
|
16963
|
+
});
|
|
16964
|
+
}
|
|
16965
|
+
function readTrack(moov, trak) {
|
|
16966
|
+
const mdia = child(moov, trak, "mdia");
|
|
16967
|
+
const hdlr = child(moov, mdia, "hdlr");
|
|
16968
|
+
const stbl = child(moov, child(moov, mdia, "minf"), "stbl");
|
|
16969
|
+
if (findChild(moov, stbl, "ctts")) throw new Error("[mp4Stitch] chunk has ctts (B-frames)");
|
|
16970
|
+
const stts = rows(moov, child(moov, stbl, "stts"), 2);
|
|
16971
|
+
const durations = stts.flatMap(([n, delta]) => Array(n).fill(delta));
|
|
16972
|
+
const sizes = readSizes(moov, child(moov, stbl, "stsz"));
|
|
16973
|
+
const chunkOffsets = readChunkOffsets(moov, stbl);
|
|
16974
|
+
const samplesPerChunk = readSamplesPerChunk(moov, stbl, chunkOffsets.length);
|
|
16975
|
+
if (durations.length !== sizes.length || sum(samplesPerChunk) !== sizes.length) {
|
|
16976
|
+
throw new Error("[mp4Stitch] sample tables disagree on the sample count");
|
|
16977
|
+
}
|
|
16978
|
+
const stsd = child(moov, stbl, "stsd");
|
|
16979
|
+
return {
|
|
16980
|
+
trak,
|
|
16981
|
+
handler: moov.toString("latin1", hdlr.bodyStart + 8, hdlr.bodyStart + 12),
|
|
16982
|
+
timescale: timescaleOf(moov, child(moov, mdia, "mdhd")),
|
|
16983
|
+
mediaTime: readMediaTime(moov, trak),
|
|
16984
|
+
stsd: moov.subarray(stsd.start, stsd.end),
|
|
16985
|
+
durations,
|
|
16986
|
+
sizes,
|
|
16987
|
+
sync: readSync4(moov, stbl, sizes.length),
|
|
16988
|
+
samplesPerChunk,
|
|
16989
|
+
chunkOffsets
|
|
16990
|
+
};
|
|
16991
|
+
}
|
|
16992
|
+
function sum(values) {
|
|
16993
|
+
return values.reduce((total, value) => total + value, 0);
|
|
16994
|
+
}
|
|
16995
|
+
function box(type, ...body) {
|
|
16996
|
+
const header = Buffer.alloc(8);
|
|
16997
|
+
header.writeUInt32BE(8 + sum(body.map((part) => part.length)));
|
|
16998
|
+
header.write(type, 4, "latin1");
|
|
16999
|
+
return Buffer.concat([header, ...body]);
|
|
17000
|
+
}
|
|
17001
|
+
function fullBox(type, version, body) {
|
|
17002
|
+
return box(type, Buffer.from([version, 0, 0, 0]), body);
|
|
17003
|
+
}
|
|
17004
|
+
function u32s(values) {
|
|
17005
|
+
const buf = Buffer.alloc(values.length * 4);
|
|
17006
|
+
values.forEach((value, i) => buf.writeUInt32BE(value, i * 4));
|
|
17007
|
+
return buf;
|
|
17008
|
+
}
|
|
17009
|
+
function runs(values) {
|
|
17010
|
+
const out = [];
|
|
17011
|
+
for (const value of values) {
|
|
17012
|
+
const last = out.at(-1);
|
|
17013
|
+
if (last && last[1] === value) last[0]++;
|
|
17014
|
+
else out.push([1, value]);
|
|
17015
|
+
}
|
|
17016
|
+
return out;
|
|
17017
|
+
}
|
|
17018
|
+
function rebuild(buf, parent, replace) {
|
|
17019
|
+
const parts = childBoxes(buf, parent).map(
|
|
17020
|
+
(box2) => replace[box2.type]?.(box2) ?? buf.subarray(box2.start, box2.end)
|
|
17021
|
+
);
|
|
17022
|
+
return box(parent.type, ...parts);
|
|
17023
|
+
}
|
|
17024
|
+
var DURATION_AT = {
|
|
17025
|
+
mvhd: [16, 24],
|
|
17026
|
+
mdhd: [16, 24],
|
|
17027
|
+
tkhd: [20, 28]
|
|
17028
|
+
};
|
|
17029
|
+
function withDuration(buf, target, duration) {
|
|
17030
|
+
const copy = Buffer.from(buf.subarray(target.start, target.end));
|
|
17031
|
+
const body = target.bodyStart - target.start;
|
|
17032
|
+
const wide = copy[body] === 1;
|
|
17033
|
+
const at = body + DURATION_AT[target.type][wide ? 1 : 0];
|
|
17034
|
+
if (wide) copy.writeBigUInt64BE(BigInt(duration), at);
|
|
17035
|
+
else if (duration <= 4294967295) copy.writeUInt32BE(duration, at);
|
|
17036
|
+
else throw new Error(`[mp4Stitch] ${target.type} duration ${duration} needs a version 1 box`);
|
|
17037
|
+
return copy;
|
|
17038
|
+
}
|
|
17039
|
+
function timescaleOf(buf, header) {
|
|
17040
|
+
return buf.readUInt32BE(header.bodyStart + (buf[header.bodyStart] === 1 ? 20 : 12));
|
|
17041
|
+
}
|
|
17042
|
+
function buildStbl(stsd, track) {
|
|
17043
|
+
const stts = runs(track.durations);
|
|
17044
|
+
const stsc = [];
|
|
17045
|
+
let firstChunk = 1;
|
|
17046
|
+
for (const [count, perChunk] of runs(track.samplesPerChunk)) {
|
|
17047
|
+
stsc.push([firstChunk, perChunk, 1]);
|
|
17048
|
+
firstChunk += count;
|
|
17049
|
+
}
|
|
17050
|
+
const co64 = Buffer.alloc(4 + track.chunkOffsets.length * 8);
|
|
17051
|
+
co64.writeUInt32BE(track.chunkOffsets.length);
|
|
17052
|
+
track.chunkOffsets.forEach((offset, i) => co64.writeBigUInt64BE(BigInt(offset), 4 + i * 8));
|
|
17053
|
+
const syncSamples = track.sync?.flatMap((isSync, i) => isSync ? [i + 1] : []) ?? null;
|
|
17054
|
+
return box(
|
|
17055
|
+
"stbl",
|
|
17056
|
+
stsd,
|
|
17057
|
+
fullBox("stts", 0, u32s([stts.length, ...stts.flat()])),
|
|
17058
|
+
...syncSamples ? [fullBox("stss", 0, u32s([syncSamples.length, ...syncSamples]))] : [],
|
|
17059
|
+
fullBox("stsc", 0, u32s([stsc.length, ...stsc.flat()])),
|
|
17060
|
+
fullBox("stsz", 0, u32s([0, track.sizes.length, ...track.sizes])),
|
|
17061
|
+
fullBox("co64", 0, co64)
|
|
17062
|
+
);
|
|
17063
|
+
}
|
|
17064
|
+
var codecOf = (track) => track.stsd.toString("latin1", 20, 24);
|
|
17065
|
+
var sameTrack = (track, plan2) => track.handler === plan2.handler && track.timescale === plan2.timescale && codecOf(track) === codecOf(plan2);
|
|
17066
|
+
function planTracksOf(tracks, plan2, index) {
|
|
17067
|
+
let next = 0;
|
|
17068
|
+
const matched = plan2.map((planTrack) => {
|
|
17069
|
+
const track = tracks[next];
|
|
17070
|
+
if (track && sameTrack(track, planTrack)) return tracks[next++];
|
|
17071
|
+
if (planTrack.handler === "soun") return null;
|
|
17072
|
+
throw new Error(`[mp4Stitch] chunk ${index} tracks differ from chunk 0`);
|
|
17073
|
+
});
|
|
17074
|
+
if (next !== tracks.length)
|
|
17075
|
+
throw new Error(`[mp4Stitch] chunk ${index} tracks differ from chunk 0`);
|
|
17076
|
+
for (const track of tracks) {
|
|
17077
|
+
if (track.handler === "vide" && track.mediaTime !== 0) {
|
|
17078
|
+
throw new Error(`[mp4Stitch] chunk ${index} video starts at media time ${track.mediaTime}`);
|
|
17079
|
+
}
|
|
17080
|
+
}
|
|
17081
|
+
return matched;
|
|
17082
|
+
}
|
|
17083
|
+
function buildStitchedHeader(layouts) {
|
|
17084
|
+
const plan2 = readTracks(layouts[0].moov);
|
|
17085
|
+
const chunks = layouts.map((layout, i) => planTracksOf(readTracks(layout.moov), plan2, i));
|
|
17086
|
+
const payloadBases = [];
|
|
17087
|
+
let payloadBytes = 0;
|
|
17088
|
+
for (const layout of layouts) {
|
|
17089
|
+
payloadBases.push(payloadBytes);
|
|
17090
|
+
payloadBytes += layout.payloadEnd - layout.payloadStart;
|
|
17091
|
+
}
|
|
17092
|
+
const template = layouts[0].moov;
|
|
17093
|
+
const root = boxAt(template, 0, 0, template.length);
|
|
17094
|
+
const movieTimescale = timescaleOf(template, child(template, root, "mvhd"));
|
|
17095
|
+
const buildMoov = (dataStart2) => {
|
|
17096
|
+
const traks = plan2.map((track, t) => {
|
|
17097
|
+
const parts = chunks.flatMap((tracks, chunk) => {
|
|
17098
|
+
const part = tracks[t];
|
|
17099
|
+
return part ? [{ ...part, chunk }] : [];
|
|
17100
|
+
});
|
|
17101
|
+
const merged = {
|
|
17102
|
+
durations: parts.flatMap((part) => part.durations),
|
|
17103
|
+
sizes: parts.flatMap((part) => part.sizes),
|
|
17104
|
+
sync: parts.every((part) => !part.sync) ? null : parts.flatMap((part) => part.sync ?? part.sizes.map(() => true)),
|
|
17105
|
+
samplesPerChunk: parts.flatMap((part) => part.samplesPerChunk),
|
|
17106
|
+
chunkOffsets: parts.flatMap(
|
|
17107
|
+
(part) => part.chunkOffsets.map((offset) => {
|
|
17108
|
+
const i = part.chunk;
|
|
17109
|
+
const { payloadStart, payloadEnd } = layouts[i];
|
|
17110
|
+
if (offset < payloadStart || offset >= payloadEnd) {
|
|
17111
|
+
throw new Error(`[mp4Stitch] chunk ${i} has samples outside its mdat`);
|
|
17112
|
+
}
|
|
17113
|
+
return offset - payloadStart + payloadBases[i] + dataStart2;
|
|
17114
|
+
})
|
|
17115
|
+
)
|
|
17116
|
+
};
|
|
17117
|
+
const mediaDuration = sum(merged.durations);
|
|
17118
|
+
const shown = Math.round(
|
|
17119
|
+
(mediaDuration - track.mediaTime) * movieTimescale / track.timescale
|
|
17120
|
+
);
|
|
17121
|
+
const elst = Buffer.alloc(24);
|
|
17122
|
+
elst.writeUInt32BE(1);
|
|
17123
|
+
elst.writeBigUInt64BE(BigInt(shown), 4);
|
|
17124
|
+
elst.writeBigInt64BE(BigInt(track.mediaTime), 12);
|
|
17125
|
+
elst.writeUInt32BE(65536, 20);
|
|
17126
|
+
const edts = track.mediaTime ? box("edts", fullBox("elst", 1, elst)) : Buffer.alloc(0);
|
|
17127
|
+
const trak = rebuild(template, track.trak, {
|
|
17128
|
+
tkhd: (tkhd) => Buffer.concat([withDuration(template, tkhd, shown), edts]),
|
|
17129
|
+
edts: () => Buffer.alloc(0),
|
|
17130
|
+
mdia: (mdia) => rebuild(template, mdia, {
|
|
17131
|
+
mdhd: (mdhd) => withDuration(template, mdhd, mediaDuration),
|
|
17132
|
+
minf: (minf) => rebuild(template, minf, { stbl: () => buildStbl(track.stsd, merged) })
|
|
17133
|
+
})
|
|
17134
|
+
});
|
|
17135
|
+
return { trak, shown };
|
|
17136
|
+
});
|
|
17137
|
+
let next = 0;
|
|
17138
|
+
return rebuild(template, root, {
|
|
17139
|
+
mvhd: (mvhd) => withDuration(template, mvhd, Math.max(...traks.map((t) => t.shown))),
|
|
17140
|
+
trak: () => traks[next++].trak
|
|
17141
|
+
});
|
|
17142
|
+
};
|
|
17143
|
+
const ftyp = layouts[0].ftyp;
|
|
17144
|
+
const dataStart = ftyp.length + buildMoov(0).length + 16;
|
|
17145
|
+
const mdat = Buffer.alloc(16);
|
|
17146
|
+
mdat.writeUInt32BE(1);
|
|
17147
|
+
mdat.write("mdat", 4, "latin1");
|
|
17148
|
+
mdat.writeBigUInt64BE(BigInt(16 + payloadBytes), 8);
|
|
17149
|
+
return Buffer.concat([ftyp, buildMoov(dataStart), mdat]);
|
|
17150
|
+
}
|
|
17151
|
+
function fileRange(path) {
|
|
17152
|
+
return async (start, end) => {
|
|
17153
|
+
const file = await open(path, "r", 384);
|
|
17154
|
+
try {
|
|
17155
|
+
const buf = Buffer.alloc(end - start);
|
|
17156
|
+
const { bytesRead } = await file.read(buf, 0, buf.length, start);
|
|
17157
|
+
return buf.subarray(0, bytesRead);
|
|
17158
|
+
} finally {
|
|
17159
|
+
await file.close();
|
|
17160
|
+
}
|
|
17161
|
+
};
|
|
17162
|
+
}
|
|
17163
|
+
async function copyPayload(path, layout, index, out) {
|
|
17164
|
+
const { payloadStart, payloadEnd } = layout;
|
|
17165
|
+
const payload = createReadStream5(path, { start: payloadStart, end: payloadEnd - 1 });
|
|
17166
|
+
await pipeline(payload, out, { end: false });
|
|
17167
|
+
if (payload.bytesRead !== payloadEnd - payloadStart) {
|
|
17168
|
+
throw new Error(
|
|
17169
|
+
`[mp4Stitch] chunk ${index} mdat holds ${payload.bytesRead} of ${payloadEnd - payloadStart} payload bytes`
|
|
17170
|
+
);
|
|
17171
|
+
}
|
|
17172
|
+
}
|
|
17173
|
+
async function writeStitchedMp4(chunkPaths, outputPath) {
|
|
17174
|
+
const layouts = await Promise.all(chunkPaths.map((path) => readMp4Layout(fileRange(path))));
|
|
17175
|
+
const header = buildStitchedHeader(layouts);
|
|
17176
|
+
mkdirSync14(dirname15(outputPath), { recursive: true });
|
|
17177
|
+
const workDir = mkdtempSync7(`${outputPath}.stitch-`);
|
|
17178
|
+
const out = createWriteStream(join36(workDir, "out.mp4"));
|
|
17179
|
+
try {
|
|
17180
|
+
out.write(header);
|
|
17181
|
+
for (const [i, path] of chunkPaths.entries()) await copyPayload(path, layouts[i], i, out);
|
|
17182
|
+
out.end();
|
|
17183
|
+
await finished(out);
|
|
17184
|
+
renameSync7(join36(workDir, "out.mp4"), outputPath);
|
|
17185
|
+
} finally {
|
|
17186
|
+
out.destroy();
|
|
17187
|
+
rmSync13(workDir, { recursive: true, force: true });
|
|
17188
|
+
}
|
|
17189
|
+
}
|
|
17190
|
+
|
|
17191
|
+
// ../producer/src/services/distributed/assemble.ts
|
|
16844
17192
|
function cfrRateControlArgs(locked) {
|
|
16845
17193
|
const preset = getEncoderPreset(locked.quality ?? "standard", "mp4");
|
|
16846
17194
|
if (locked.crf == null && locked.bitrate) {
|
|
@@ -16856,12 +17204,21 @@ async function assemble(planDir, chunkPaths, audioPath, outputPath, options) {
|
|
|
16856
17204
|
if (plan2.dimensions.format === "png-sequence") {
|
|
16857
17205
|
return mergePngFrameDirs(chunkPaths, outputPath, plan2.totalFrames, audioPath, start);
|
|
16858
17206
|
}
|
|
17207
|
+
if (chunksAreStitchedMp4(planDir, cfr)) {
|
|
17208
|
+
await writeStitchedMp4(chunkPaths, outputPath);
|
|
17209
|
+
return {
|
|
17210
|
+
outputPath,
|
|
17211
|
+
durationMs: Date.now() - start,
|
|
17212
|
+
framesEncoded: plan2.totalFrames,
|
|
17213
|
+
fileSize: statSync10(outputPath).size
|
|
17214
|
+
};
|
|
17215
|
+
}
|
|
16859
17216
|
const format = plan2.dimensions.format;
|
|
16860
17217
|
const cfrEncoder = cfr ? readCfrEncoder(planDir, format) : null;
|
|
16861
|
-
if (!existsSync24(
|
|
16862
|
-
|
|
17218
|
+
if (!existsSync24(dirname16(outputPath))) {
|
|
17219
|
+
mkdirSync15(dirname16(outputPath), { recursive: true });
|
|
16863
17220
|
}
|
|
16864
|
-
const workDir =
|
|
17221
|
+
const workDir = mkdtempSync8(`${outputPath}.assemble-work-`);
|
|
16865
17222
|
const fps = { num: plan2.dimensions.fpsNum, den: plan2.dimensions.fpsDen };
|
|
16866
17223
|
const stageMs = {};
|
|
16867
17224
|
const ctx = {
|
|
@@ -16869,7 +17226,6 @@ async function assemble(planDir, chunkPaths, audioPath, outputPath, options) {
|
|
|
16869
17226
|
format,
|
|
16870
17227
|
fps,
|
|
16871
17228
|
fpsArg: fpsToFfmpegArg(fps),
|
|
16872
|
-
chunkSeconds: chunksCarryAudio(planDir) ? plan2.chunks.map((chunk) => (chunk.endFrame - chunk.startFrame) * fps.den / fps.num) : null,
|
|
16873
17229
|
signal: options?.abortSignal,
|
|
16874
17230
|
timeout: resolveConfig().ffmpegProcessTimeout,
|
|
16875
17231
|
log,
|
|
@@ -16882,10 +17238,10 @@ async function assemble(planDir, chunkPaths, audioPath, outputPath, options) {
|
|
|
16882
17238
|
};
|
|
16883
17239
|
try {
|
|
16884
17240
|
const videoSources = cfrEncoder ? [await reencodeCfr(ctx, chunkPaths, cfrEncoder)] : chunkPaths;
|
|
16885
|
-
const finalPath =
|
|
17241
|
+
const finalPath = join37(workDir, `output.${format}`);
|
|
16886
17242
|
const audio = audioPath !== null && existsSync24(audioPath) ? audioPath : null;
|
|
16887
17243
|
await writeJoined(ctx, videoSources, audio, finalPath);
|
|
16888
|
-
|
|
17244
|
+
renameSync8(finalPath, outputPath);
|
|
16889
17245
|
log.info("[assemble] stage timings", {
|
|
16890
17246
|
...stageMs,
|
|
16891
17247
|
chunks: chunkPaths.length,
|
|
@@ -16893,7 +17249,7 @@ async function assemble(planDir, chunkPaths, audioPath, outputPath, options) {
|
|
|
16893
17249
|
});
|
|
16894
17250
|
} finally {
|
|
16895
17251
|
try {
|
|
16896
|
-
|
|
17252
|
+
rmSync14(workDir, { recursive: true, force: true });
|
|
16897
17253
|
} catch (err) {
|
|
16898
17254
|
log.warn("[assemble] failed to remove work dir", {
|
|
16899
17255
|
workDir,
|
|
@@ -16910,8 +17266,8 @@ async function assemble(planDir, chunkPaths, audioPath, outputPath, options) {
|
|
|
16910
17266
|
};
|
|
16911
17267
|
}
|
|
16912
17268
|
function readAssemblePlan(planDir, chunkPaths) {
|
|
16913
|
-
const planJsonPath =
|
|
16914
|
-
const chunksJsonPath =
|
|
17269
|
+
const planJsonPath = join37(planDir, "plan.json");
|
|
17270
|
+
const chunksJsonPath = join37(planDir, "meta", "chunks.json");
|
|
16915
17271
|
if (!existsSync24(planJsonPath)) {
|
|
16916
17272
|
throw new Error(`[assemble] planDir missing plan.json: ${planJsonPath}`);
|
|
16917
17273
|
}
|
|
@@ -16932,13 +17288,13 @@ function readAssemblePlan(planDir, chunkPaths) {
|
|
|
16932
17288
|
throw new Error(`[assemble] chunk path does not exist: ${path}`);
|
|
16933
17289
|
}
|
|
16934
17290
|
}
|
|
16935
|
-
return
|
|
17291
|
+
return plan2;
|
|
16936
17292
|
}
|
|
16937
17293
|
function videoInputArgs(ctx, videoSources) {
|
|
16938
|
-
return videoSources.length === 1 ? ["-i", videoSources[0]] : concatDemuxerInput(videoSources, ctx.workDir, ctx.fpsArg
|
|
17294
|
+
return videoSources.length === 1 ? ["-i", videoSources[0]] : concatDemuxerInput(videoSources, ctx.workDir, ctx.fpsArg);
|
|
16939
17295
|
}
|
|
16940
17296
|
async function reencodeCfr(ctx, chunkPaths, encoder) {
|
|
16941
|
-
const cfrOutputPath =
|
|
17297
|
+
const cfrOutputPath = join37(ctx.workDir, `cfr.${ctx.format}`);
|
|
16942
17298
|
const cfrArgs = [
|
|
16943
17299
|
...videoInputArgs(ctx, chunkPaths),
|
|
16944
17300
|
"-c:v",
|
|
@@ -16976,7 +17332,7 @@ async function writeJoined(ctx, videoSources, audioPath, finalPath) {
|
|
|
16976
17332
|
);
|
|
16977
17333
|
return;
|
|
16978
17334
|
}
|
|
16979
|
-
const paddedAudioPath =
|
|
17335
|
+
const paddedAudioPath = join37(ctx.workDir, "audio-padded.m4a");
|
|
16980
17336
|
const padTrimResult = await ctx.timed(
|
|
16981
17337
|
"audioMs",
|
|
16982
17338
|
() => padOrTrimAudioToVideoFrameCount({
|
|
@@ -17015,15 +17371,10 @@ async function writeJoined(ctx, videoSources, audioPath, finalPath) {
|
|
|
17015
17371
|
throw encoderFailureError("[assemble] audio mux failed", muxResult);
|
|
17016
17372
|
}
|
|
17017
17373
|
}
|
|
17018
|
-
function concatDemuxerInput(chunkPaths, workDir, fpsArg
|
|
17019
|
-
const listPath =
|
|
17020
|
-
const
|
|
17021
|
-
|
|
17022
|
-
const line = `file '${path.replace(/'/g, "'\\''")}'`;
|
|
17023
|
-
return chunkSeconds ? `${line}
|
|
17024
|
-
duration ${chunkSeconds[i].toFixed(6)}` : line;
|
|
17025
|
-
});
|
|
17026
|
-
writeFileSync11(listPath, `${[...head, ...body].join("\n")}
|
|
17374
|
+
function concatDemuxerInput(chunkPaths, workDir, fpsArg) {
|
|
17375
|
+
const listPath = join37(workDir, "concat-list.txt");
|
|
17376
|
+
const body = chunkPaths.map((path) => `file '${path.replace(/'/g, "'\\''")}'`).join("\n");
|
|
17377
|
+
writeFileSync11(listPath, `${body}
|
|
17027
17378
|
`, "utf-8");
|
|
17028
17379
|
return ["-r", fpsArg, "-f", "concat", "-safe", "0", "-i", listPath];
|
|
17029
17380
|
}
|
|
@@ -17032,7 +17383,7 @@ async function probeJoinedFrameInfo(videoPaths, fps, signal) {
|
|
|
17032
17383
|
videoPaths.map((path) => defaultProbeVideoFrameInfo(path, signal))
|
|
17033
17384
|
);
|
|
17034
17385
|
return {
|
|
17035
|
-
frameCount: infos.reduce((
|
|
17386
|
+
frameCount: infos.reduce((sum2, info) => sum2 + info.frameCount, 0),
|
|
17036
17387
|
fpsNum: fps.num,
|
|
17037
17388
|
fpsDen: fps.den
|
|
17038
17389
|
};
|
|
@@ -17046,8 +17397,15 @@ async function runAssembleFfmpeg(args, step, signal, timeout) {
|
|
|
17046
17397
|
});
|
|
17047
17398
|
}
|
|
17048
17399
|
}
|
|
17400
|
+
function chunksAreStitchedMp4(planDir, cfr) {
|
|
17401
|
+
if (!chunksCarryAudio(planDir)) return false;
|
|
17402
|
+
if (cfr) {
|
|
17403
|
+
throw new Error("[assemble] cfr=true cannot re-encode a plan whose mp4 chunks carry audio");
|
|
17404
|
+
}
|
|
17405
|
+
return true;
|
|
17406
|
+
}
|
|
17049
17407
|
function chunksCarryAudio(planDir) {
|
|
17050
|
-
const encoderJsonPath =
|
|
17408
|
+
const encoderJsonPath = join37(planDir, "meta", "encoder.json");
|
|
17051
17409
|
if (!existsSync24(encoderJsonPath)) return false;
|
|
17052
17410
|
return JSON.parse(readFileSync12(encoderJsonPath, "utf-8")).chunksCarryAudio === true;
|
|
17053
17411
|
}
|
|
@@ -17057,7 +17415,7 @@ function readCfrEncoder(planDir, format) {
|
|
|
17057
17415
|
`[assemble] cfr=true is only supported for format="mp4" (got "${format}"). Stream-copy paths for webm and mov already produce exact avg_frame_rate; cfr re-encode is not needed.`
|
|
17058
17416
|
);
|
|
17059
17417
|
}
|
|
17060
|
-
const encoderJsonPath =
|
|
17418
|
+
const encoderJsonPath = join37(planDir, "meta", "encoder.json");
|
|
17061
17419
|
if (!existsSync24(encoderJsonPath)) {
|
|
17062
17420
|
throw new Error(`[assemble] planDir missing meta/encoder.json: ${encoderJsonPath}`);
|
|
17063
17421
|
}
|
|
@@ -17070,8 +17428,8 @@ function readCfrEncoder(planDir, format) {
|
|
|
17070
17428
|
return encoderJson;
|
|
17071
17429
|
}
|
|
17072
17430
|
function mergePngFrameDirs(chunkPaths, outputPath, totalFrames, audioPath, startTimeMs) {
|
|
17073
|
-
if (existsSync24(outputPath))
|
|
17074
|
-
|
|
17431
|
+
if (existsSync24(outputPath)) rmSync14(outputPath, { recursive: true, force: true });
|
|
17432
|
+
mkdirSync15(outputPath, { recursive: true });
|
|
17075
17433
|
let globalIdx = 0;
|
|
17076
17434
|
for (const chunkDir of chunkPaths) {
|
|
17077
17435
|
if (!statSync10(chunkDir).isDirectory()) {
|
|
@@ -17084,8 +17442,8 @@ function mergePngFrameDirs(chunkPaths, outputPath, totalFrames, audioPath, start
|
|
|
17084
17442
|
throw new Error(`[assemble] png-sequence chunk has no frames: ${chunkDir}`);
|
|
17085
17443
|
}
|
|
17086
17444
|
for (const frame of frames) {
|
|
17087
|
-
const dst =
|
|
17088
|
-
cpSync3(
|
|
17445
|
+
const dst = join37(outputPath, formatExportFrameName(globalIdx, "png"));
|
|
17446
|
+
cpSync3(join37(chunkDir, frame), dst);
|
|
17089
17447
|
globalIdx += 1;
|
|
17090
17448
|
}
|
|
17091
17449
|
}
|
|
@@ -17095,13 +17453,13 @@ function mergePngFrameDirs(chunkPaths, outputPath, totalFrames, audioPath, start
|
|
|
17095
17453
|
);
|
|
17096
17454
|
}
|
|
17097
17455
|
if (audioPath !== null && existsSync24(audioPath)) {
|
|
17098
|
-
const sidecar =
|
|
17456
|
+
const sidecar = join37(outputPath, MIXED_AUDIO_FILENAME);
|
|
17099
17457
|
cpSync3(audioPath, sidecar);
|
|
17100
17458
|
}
|
|
17101
17459
|
let fileSize = 0;
|
|
17102
17460
|
for (const name of readdirSync9(outputPath)) {
|
|
17103
17461
|
try {
|
|
17104
|
-
fileSize += statSync10(
|
|
17462
|
+
fileSize += statSync10(join37(outputPath, name)).size;
|
|
17105
17463
|
} catch {
|
|
17106
17464
|
}
|
|
17107
17465
|
}
|
|
@@ -17115,8 +17473,8 @@ function mergePngFrameDirs(chunkPaths, outputPath, totalFrames, audioPath, start
|
|
|
17115
17473
|
|
|
17116
17474
|
// ../producer/src/services/distributed/renderChunk.ts
|
|
17117
17475
|
import { randomBytes } from "crypto";
|
|
17118
|
-
import { existsSync as existsSync25, mkdirSync as
|
|
17119
|
-
import { extname as extname6, join as
|
|
17476
|
+
import { existsSync as existsSync25, mkdirSync as mkdirSync16, readFileSync as readFileSync13, readdirSync as readdirSync10, rmSync as rmSync15, writeFileSync as writeFileSync12 } from "fs";
|
|
17477
|
+
import { extname as extname6, join as join38 } from "path";
|
|
17120
17478
|
|
|
17121
17479
|
// ../producer/src/services/distributed/chunkAudio.ts
|
|
17122
17480
|
function audioCutForChunk(grid, chunks, index, fps) {
|
|
@@ -17302,7 +17660,7 @@ function frameNumberFromFileName(name) {
|
|
|
17302
17660
|
function rebuildExtractedFramesFromPlanDir(planDir, videos, indexMode = "dense-v1") {
|
|
17303
17661
|
const result = [];
|
|
17304
17662
|
for (const v of videos) {
|
|
17305
|
-
const outputDir =
|
|
17663
|
+
const outputDir = join38(planDir, "video-frames", v.videoId);
|
|
17306
17664
|
if (!existsSync25(outputDir)) {
|
|
17307
17665
|
throw new Error(
|
|
17308
17666
|
`[renderChunk] planDir missing extracted video frames for ${JSON.stringify(v.videoId)}: ${outputDir} not present. plan() should have written frames here; the planDir is malformed.`
|
|
@@ -17321,7 +17679,7 @@ function rebuildExtractedFramesFromPlanDir(planDir, videos, indexMode = "dense-v
|
|
|
17321
17679
|
if (!frameName) continue;
|
|
17322
17680
|
const frameNumber = indexMode === "sparse-v2" ? frameNumberFromFileName(frameName) : null;
|
|
17323
17681
|
const frameIndex = frameNumber === null ? i : frameNumber - 1;
|
|
17324
|
-
framePaths.set(frameIndex,
|
|
17682
|
+
framePaths.set(frameIndex, join38(outputDir, frameName));
|
|
17325
17683
|
}
|
|
17326
17684
|
result.push({
|
|
17327
17685
|
videoId: v.videoId,
|
|
@@ -17343,13 +17701,13 @@ function rebuildExtractedFramesFromPlanDir(planDir, videos, indexMode = "dense-v
|
|
|
17343
17701
|
return result;
|
|
17344
17702
|
}
|
|
17345
17703
|
function contiguousRuns(sortedIndexes) {
|
|
17346
|
-
const
|
|
17704
|
+
const runs2 = [];
|
|
17347
17705
|
for (const index of sortedIndexes) {
|
|
17348
|
-
const last =
|
|
17706
|
+
const last = runs2[runs2.length - 1];
|
|
17349
17707
|
if (last && last.firstFrame + last.frames === index) last.frames++;
|
|
17350
|
-
else
|
|
17708
|
+
else runs2.push({ firstFrame: index, frames: 1 });
|
|
17351
17709
|
}
|
|
17352
|
-
return
|
|
17710
|
+
return runs2;
|
|
17353
17711
|
}
|
|
17354
17712
|
async function extractDeferredVideoFramesForChunk(input) {
|
|
17355
17713
|
const deferred = input.planVideos.extracted.filter((video) => video.deferredRange);
|
|
@@ -17374,13 +17732,13 @@ async function extractDeferredVideoFramesForChunk(input) {
|
|
|
17374
17732
|
}
|
|
17375
17733
|
return Promise.all(
|
|
17376
17734
|
deferred.map(async (video) => {
|
|
17377
|
-
const outputDir =
|
|
17735
|
+
const outputDir = join38(input.outputRoot, video.videoId);
|
|
17378
17736
|
const indexes = [...shown.get(video.videoId) ?? []].sort((a, b) => a - b);
|
|
17379
17737
|
if (indexes.length === 0) {
|
|
17380
17738
|
return { ...video, outputDir, framePaths: /* @__PURE__ */ new Map(), ownedByLookup: false };
|
|
17381
17739
|
}
|
|
17382
17740
|
const range = video.deferredRange;
|
|
17383
|
-
const sourcePath =
|
|
17741
|
+
const sourcePath = join38(input.planDir, ...range.sourcePath.split("/"));
|
|
17384
17742
|
if (!existsSync25(sourcePath)) {
|
|
17385
17743
|
throw new RenderChunkValidationError(
|
|
17386
17744
|
MISSING_PLAN_ARTIFACT,
|
|
@@ -17416,7 +17774,7 @@ function hashChunkOutput(outputPath, kind) {
|
|
|
17416
17774
|
if (kind === "file") return sha256Hex(readFileSync13(outputPath));
|
|
17417
17775
|
const entries = readdirSync10(outputPath).filter((name) => /\.(png|jpg|jpeg)$/i.test(name)).sort();
|
|
17418
17776
|
const lines = entries.map(
|
|
17419
|
-
(name) => `${name}\0${sha256Hex(readFileSync13(
|
|
17777
|
+
(name) => `${name}\0${sha256Hex(readFileSync13(join38(outputPath, name)))}`
|
|
17420
17778
|
);
|
|
17421
17779
|
return sha256Hex(lines.join("\0"));
|
|
17422
17780
|
}
|
|
@@ -17433,9 +17791,9 @@ function resolveLockedVp9CpuUsed(lockedEncoder) {
|
|
|
17433
17791
|
async function renderChunk(planDir, chunkIndex, outputChunkPath) {
|
|
17434
17792
|
const start = Date.now();
|
|
17435
17793
|
const log = defaultLogger;
|
|
17436
|
-
const planJsonPath =
|
|
17437
|
-
const encoderJsonPath =
|
|
17438
|
-
const chunksJsonPath =
|
|
17794
|
+
const planJsonPath = join38(planDir, "plan.json");
|
|
17795
|
+
const encoderJsonPath = join38(planDir, "meta", "encoder.json");
|
|
17796
|
+
const chunksJsonPath = join38(planDir, "meta", "chunks.json");
|
|
17439
17797
|
if (!existsSync25(planJsonPath)) {
|
|
17440
17798
|
throw new RenderChunkValidationError(
|
|
17441
17799
|
MISSING_PLAN_ARTIFACT,
|
|
@@ -17459,7 +17817,7 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath) {
|
|
|
17459
17817
|
}
|
|
17460
17818
|
const encoder = JSON.parse(readFileSync13(encoderJsonPath, "utf-8"));
|
|
17461
17819
|
const chunks = JSON.parse(readFileSync13(chunksJsonPath, "utf-8"));
|
|
17462
|
-
const videosJsonPath =
|
|
17820
|
+
const videosJsonPath = join38(planDir, PLAN_VIDEOS_META_RELATIVE_PATH);
|
|
17463
17821
|
let planVideos = null;
|
|
17464
17822
|
if (existsSync25(videosJsonPath)) {
|
|
17465
17823
|
try {
|
|
@@ -17489,7 +17847,7 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath) {
|
|
|
17489
17847
|
`[renderChunk] chunk ${chunkIndex} has non-positive frame count: ${framesInChunk}`
|
|
17490
17848
|
);
|
|
17491
17849
|
}
|
|
17492
|
-
const compiledDir =
|
|
17850
|
+
const compiledDir = join38(planDir, "compiled");
|
|
17493
17851
|
if (!existsSync25(compiledDir)) {
|
|
17494
17852
|
throw new RenderChunkValidationError(
|
|
17495
17853
|
MISSING_PLAN_ARTIFACT,
|
|
@@ -17546,9 +17904,9 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath) {
|
|
|
17546
17904
|
forceScreenshotExplicitlyOptedOut: !encoder.forceScreenshot
|
|
17547
17905
|
};
|
|
17548
17906
|
const workDir = `${outputChunkPath}.work.${process.pid}.${randomBytes(4).toString("hex")}`;
|
|
17549
|
-
|
|
17550
|
-
const framesDir =
|
|
17551
|
-
|
|
17907
|
+
mkdirSync16(workDir, { recursive: true });
|
|
17908
|
+
const framesDir = join38(workDir, "captured-frames");
|
|
17909
|
+
mkdirSync16(framesDir, { recursive: true });
|
|
17552
17910
|
const videoFramesDir = `${workDir}.video-frames`;
|
|
17553
17911
|
const videoFrameLookup = planVideos && planVideos.extracted.length > 0 ? createFrameLookupTable(
|
|
17554
17912
|
planVideos.videos,
|
|
@@ -17601,7 +17959,7 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath) {
|
|
|
17601
17959
|
// `beginFrameTimeTicks` is host-independent. Only chunks ever set this.
|
|
17602
17960
|
lockWarmupTicks: true,
|
|
17603
17961
|
requiresWebGpu: compositionRequiresWebGpu(
|
|
17604
|
-
readFileSync13(
|
|
17962
|
+
readFileSync13(join38(compiledDir, "index.html"), "utf-8")
|
|
17605
17963
|
)
|
|
17606
17964
|
};
|
|
17607
17965
|
const chunkWorkerCount = calculateOptimalWorkers(framesInChunk, void 0, cfg);
|
|
@@ -17732,8 +18090,8 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath) {
|
|
|
17732
18090
|
return observedMode;
|
|
17733
18091
|
},
|
|
17734
18092
|
resetForScreenshotRetry: () => {
|
|
17735
|
-
|
|
17736
|
-
|
|
18093
|
+
rmSync15(workDir, { recursive: true, force: true, maxRetries: 3, retryDelay: 100 });
|
|
18094
|
+
mkdirSync16(framesDir, { recursive: true });
|
|
17737
18095
|
capturePerfs.length = 0;
|
|
17738
18096
|
captureAttempts.length = 0;
|
|
17739
18097
|
job.framesRendered = 0;
|
|
@@ -17764,10 +18122,10 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath) {
|
|
|
17764
18122
|
const effectiveBitrate = encoder.crf != null ? void 0 : encoder.bitrate;
|
|
17765
18123
|
const videoOnlyPath = encoder.chunksCarryAudio ? `${outputChunkPath}.video.mp4` : outputChunkPath;
|
|
17766
18124
|
if (isPngSequence) {
|
|
17767
|
-
if (!existsSync25(outputChunkPath))
|
|
18125
|
+
if (!existsSync25(outputChunkPath)) mkdirSync16(outputChunkPath, { recursive: true });
|
|
17768
18126
|
} else {
|
|
17769
|
-
const outDir =
|
|
17770
|
-
if (!existsSync25(outDir))
|
|
18127
|
+
const outDir = join38(outputChunkPath, "..");
|
|
18128
|
+
if (!existsSync25(outDir)) mkdirSync16(outDir, { recursive: true });
|
|
17771
18129
|
}
|
|
17772
18130
|
const encodeStarted = Date.now();
|
|
17773
18131
|
await runEncodeStage({
|
|
@@ -17819,7 +18177,7 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath) {
|
|
|
17819
18177
|
fps: { num: plan2.dimensions.fpsNum, den: plan2.dimensions.fpsDen },
|
|
17820
18178
|
timeoutMs: cfg.ffmpegProcessTimeout
|
|
17821
18179
|
});
|
|
17822
|
-
|
|
18180
|
+
rmSync15(videoOnlyPath, { force: true });
|
|
17823
18181
|
}
|
|
17824
18182
|
encodeStageMs = Date.now() - encodeStarted;
|
|
17825
18183
|
} finally {
|
|
@@ -17861,8 +18219,8 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath) {
|
|
|
17861
18219
|
writeFileSync12(perfPath, `${JSON.stringify(perfPayload, null, 2)}
|
|
17862
18220
|
`, "utf-8");
|
|
17863
18221
|
try {
|
|
17864
|
-
|
|
17865
|
-
|
|
18222
|
+
rmSync15(workDir, { recursive: true, force: true, maxRetries: 3, retryDelay: 100 });
|
|
18223
|
+
rmSync15(videoFramesDir, { recursive: true, force: true, maxRetries: 3, retryDelay: 100 });
|
|
17866
18224
|
} catch (err) {
|
|
17867
18225
|
log.warn("[renderChunk] failed to remove work dir", {
|
|
17868
18226
|
workDir,
|
|
@@ -17890,18 +18248,18 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath) {
|
|
|
17890
18248
|
|
|
17891
18249
|
// ../producer/src/services/distributed/planV2Execution.ts
|
|
17892
18250
|
async function renderChunkV2(planV2Dir, chunkIndex, outputChunkPath) {
|
|
17893
|
-
const workRoot =
|
|
17894
|
-
const materializedPlanDir =
|
|
18251
|
+
const workRoot = mkdtempSync9(join39(tmpdir5(), "hf-plan-v2-chunk-"));
|
|
18252
|
+
const materializedPlanDir = join39(workRoot, "plan");
|
|
17895
18253
|
try {
|
|
17896
18254
|
materializePlanV2Target(planV2Dir, { role: "chunk", chunkIndex }, materializedPlanDir);
|
|
17897
18255
|
return await renderChunk(materializedPlanDir, chunkIndex, outputChunkPath);
|
|
17898
18256
|
} finally {
|
|
17899
|
-
|
|
18257
|
+
rmSync16(workRoot, { recursive: true, force: true });
|
|
17900
18258
|
}
|
|
17901
18259
|
}
|
|
17902
18260
|
async function assembleV2(planV2Dir, chunkPaths, outputPath, options) {
|
|
17903
|
-
const workRoot =
|
|
17904
|
-
const materializedPlanDir =
|
|
18261
|
+
const workRoot = mkdtempSync9(join39(tmpdir5(), "hf-plan-v2-assembler-"));
|
|
18262
|
+
const materializedPlanDir = join39(workRoot, "plan");
|
|
17905
18263
|
try {
|
|
17906
18264
|
const materialized = materializePlanV2Target(
|
|
17907
18265
|
planV2Dir,
|
|
@@ -17916,14 +18274,14 @@ async function assembleV2(planV2Dir, chunkPaths, outputPath, options) {
|
|
|
17916
18274
|
options
|
|
17917
18275
|
);
|
|
17918
18276
|
} finally {
|
|
17919
|
-
|
|
18277
|
+
rmSync16(workRoot, { recursive: true, force: true });
|
|
17920
18278
|
}
|
|
17921
18279
|
}
|
|
17922
18280
|
|
|
17923
18281
|
// ../producer/src/services/distributed/projectHash.ts
|
|
17924
18282
|
import { readdirSync as readdirSync11, readFileSync as readFileSync14 } from "fs";
|
|
17925
18283
|
import { createHash as createHash7 } from "crypto";
|
|
17926
|
-
import { join as
|
|
18284
|
+
import { join as join40, relative as relative8 } from "path";
|
|
17927
18285
|
|
|
17928
18286
|
export {
|
|
17929
18287
|
createConsoleLogger,
|