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
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
renderFrameIdForRenderId,
|
|
27
27
|
resolveAuthoredTimingWindow,
|
|
28
28
|
toFps
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-7HTH5PFK.js";
|
|
30
30
|
import {
|
|
31
31
|
AUDIO_GROUP_RENDER_ID_ATTR,
|
|
32
32
|
COLOR_GRADING_SOURCE_HIDDEN_ATTR,
|
|
@@ -63,7 +63,7 @@ import {
|
|
|
63
63
|
sourceTimeAt,
|
|
64
64
|
timeAtSourceTime,
|
|
65
65
|
volumeSegmentSampleCount
|
|
66
|
-
} from "./chunk-
|
|
66
|
+
} from "./chunk-USWPZXEA.js";
|
|
67
67
|
import {
|
|
68
68
|
clampAudioGain,
|
|
69
69
|
clipGain,
|
|
@@ -1477,6 +1477,7 @@ function getLowMemoryFlags() {
|
|
|
1477
1477
|
}
|
|
1478
1478
|
var CANVAS_DRAW_ELEMENT_FEATURE_FLAG = "--enable-features=CanvasDrawElement";
|
|
1479
1479
|
var WEBGPU_FLAG = "--enable-unsafe-webgpu";
|
|
1480
|
+
var DISABLE_DXC_FLAG = "--disable-dawn-features=use_dxc";
|
|
1480
1481
|
function usesSoftwareWebGpu(requiresWebGpu, config) {
|
|
1481
1482
|
return !!requiresWebGpu && !!config?.allowSoftwareWebGpu && !(config.disableGpu ?? DEFAULT_CONFIG.disableGpu) && (config.browserGpuMode ?? DEFAULT_CONFIG.browserGpuMode) === "software";
|
|
1482
1483
|
}
|
|
@@ -1532,6 +1533,9 @@ function buildChromeArgs(options, config) {
|
|
|
1532
1533
|
];
|
|
1533
1534
|
if (browserGpuMode !== "software" || options.requiresWebGpu) {
|
|
1534
1535
|
chromeArgs.push(WEBGPU_FLAG);
|
|
1536
|
+
if (platform === "win32") {
|
|
1537
|
+
chromeArgs.push(DISABLE_DXC_FLAG);
|
|
1538
|
+
}
|
|
1535
1539
|
}
|
|
1536
1540
|
if (softwareWebGpu) chromeArgs.push("--use-vulkan=swiftshader");
|
|
1537
1541
|
if (browserGpuMode === "software" && !softwareWebGpu) {
|
|
@@ -4798,6 +4802,7 @@ var CaptureFailure = class extends Error {
|
|
|
4798
4802
|
kind;
|
|
4799
4803
|
cause;
|
|
4800
4804
|
workerDiagnostics;
|
|
4805
|
+
pageErrorLines;
|
|
4801
4806
|
constructor(input) {
|
|
4802
4807
|
super(input.message);
|
|
4803
4808
|
this.name = "CaptureFailure";
|
|
@@ -4808,6 +4813,7 @@ var CaptureFailure = class extends Error {
|
|
|
4808
4813
|
(diagnostic) => Object.freeze({ ...diagnostic, lines: Object.freeze([...diagnostic.lines]) })
|
|
4809
4814
|
)
|
|
4810
4815
|
);
|
|
4816
|
+
this.pageErrorLines = Object.freeze([...input.pageErrorLines ?? []]);
|
|
4811
4817
|
if (input.cause instanceof Error && input.cause.stack) this.stack = input.cause.stack;
|
|
4812
4818
|
}
|
|
4813
4819
|
};
|
|
@@ -4893,32 +4899,37 @@ function ioError(error, message) {
|
|
|
4893
4899
|
)
|
|
4894
4900
|
) || BROKEN_PIPE_MESSAGE.test(message) || hasIoOperationFailure(message);
|
|
4895
4901
|
}
|
|
4902
|
+
var ORDERED_KIND_RULES = [
|
|
4903
|
+
[
|
|
4904
|
+
"memory_exhaustion",
|
|
4905
|
+
(message) => BUN_MEMORY_EXHAUSTION_EXACT_MESSAGE.test(message.trim()) || BUN_MEMORY_EXHAUSTION_WRAPPED_WORKER_MESSAGE.test(message) || matchesAny(message, MEMORY_EXHAUSTION_ERROR_PATTERNS)
|
|
4906
|
+
],
|
|
4907
|
+
["verification", (message) => matchesAny(message, VERIFICATION_ERROR_PATTERNS)],
|
|
4908
|
+
["protocol_timeout", (message) => matchesAny(message, PROTOCOL_TIMEOUT_PATTERNS)],
|
|
4909
|
+
["transient_browser", (message) => matchesAny(message, TRANSIENT_BROWSER_ERROR_PATTERNS)],
|
|
4910
|
+
["authoring", (message) => matchesAny(message, AUTHORING_ERROR_PATTERNS)]
|
|
4911
|
+
];
|
|
4912
|
+
function classifyKind(error, message, signal) {
|
|
4913
|
+
if (signal?.aborted || /(?:render|capture)?_?cancelled|AbortError/i.test(message)) {
|
|
4914
|
+
return "cancelled";
|
|
4915
|
+
}
|
|
4916
|
+
const rule = ORDERED_KIND_RULES.find(([, matches]) => matches(message));
|
|
4917
|
+
if (rule) return rule[0];
|
|
4918
|
+
return ioError(error, message) ? "io" : "authoring";
|
|
4919
|
+
}
|
|
4896
4920
|
function classifyCaptureFailure(error, options = {}) {
|
|
4897
|
-
|
|
4898
|
-
|
|
4921
|
+
const prior = error instanceof CaptureFailure ? error : void 0;
|
|
4922
|
+
if (prior && !(options.workerDiagnostics || options.pageErrorLines || options.signal?.aborted)) {
|
|
4923
|
+
return prior;
|
|
4899
4924
|
}
|
|
4900
4925
|
const message = messageOf(error);
|
|
4901
|
-
|
|
4902
|
-
if (options.signal?.aborted || /(?:render|capture)?_?cancelled|AbortError/i.test(message)) {
|
|
4903
|
-
kind = "cancelled";
|
|
4904
|
-
} else if (BUN_MEMORY_EXHAUSTION_EXACT_MESSAGE.test(message.trim()) || BUN_MEMORY_EXHAUSTION_WRAPPED_WORKER_MESSAGE.test(message) || matchesAny(message, MEMORY_EXHAUSTION_ERROR_PATTERNS)) {
|
|
4905
|
-
kind = "memory_exhaustion";
|
|
4906
|
-
} else if (matchesAny(message, VERIFICATION_ERROR_PATTERNS)) {
|
|
4907
|
-
kind = "verification";
|
|
4908
|
-
} else if (matchesAny(message, PROTOCOL_TIMEOUT_PATTERNS)) {
|
|
4909
|
-
kind = "protocol_timeout";
|
|
4910
|
-
} else if (matchesAny(message, TRANSIENT_BROWSER_ERROR_PATTERNS)) {
|
|
4911
|
-
kind = "transient_browser";
|
|
4912
|
-
} else if (matchesAny(message, AUTHORING_ERROR_PATTERNS)) {
|
|
4913
|
-
kind = "authoring";
|
|
4914
|
-
} else {
|
|
4915
|
-
kind = ioError(error, message) ? "io" : "authoring";
|
|
4916
|
-
}
|
|
4926
|
+
const kind = classifyKind(error, message, options.signal);
|
|
4917
4927
|
return new CaptureFailure({
|
|
4918
4928
|
kind,
|
|
4919
4929
|
message,
|
|
4920
4930
|
cause: error,
|
|
4921
|
-
workerDiagnostics: options.workerDiagnostics ??
|
|
4931
|
+
workerDiagnostics: options.workerDiagnostics ?? prior?.workerDiagnostics,
|
|
4932
|
+
pageErrorLines: options.pageErrorLines ?? prior?.pageErrorLines
|
|
4922
4933
|
});
|
|
4923
4934
|
}
|
|
4924
4935
|
function isTransientBrowserError(error) {
|
|
@@ -5203,12 +5214,14 @@ async function driveWarmupTicks(options, state) {
|
|
|
5203
5214
|
} else {
|
|
5204
5215
|
if (!state.running) return;
|
|
5205
5216
|
}
|
|
5217
|
+
let ticked = false;
|
|
5206
5218
|
try {
|
|
5207
5219
|
await options.tick(state.ticks * options.intervalMs, options.intervalMs);
|
|
5208
5220
|
state.ticks += 1;
|
|
5221
|
+
ticked = true;
|
|
5209
5222
|
} catch {
|
|
5210
5223
|
}
|
|
5211
|
-
await sleep(options.intervalMs);
|
|
5224
|
+
if (!(options.lockWarmupTicks && !state.running && ticked)) await sleep(options.intervalMs);
|
|
5212
5225
|
}
|
|
5213
5226
|
}
|
|
5214
5227
|
function resolveCaptureSessionOptions(options, browserVersion, platform = process.platform) {
|
|
@@ -8608,6 +8621,10 @@ var withoutQuery = (url) => url.split(/[?#]/, 1)[0] ?? url;
|
|
|
8608
8621
|
function declareContentAddressedUrl(url, sha256) {
|
|
8609
8622
|
contentAddressedUrls.set(withoutQuery(url), sha256);
|
|
8610
8623
|
}
|
|
8624
|
+
var probeFactsUrls = /* @__PURE__ */ new Map();
|
|
8625
|
+
function declareProbeFactsUrl(url, factsUrl) {
|
|
8626
|
+
probeFactsUrls.set(withoutQuery(url), factsUrl);
|
|
8627
|
+
}
|
|
8611
8628
|
function mediaFileIdentity(filePath) {
|
|
8612
8629
|
if (/^https?:\/\//i.test(filePath)) {
|
|
8613
8630
|
const sha256 = contentAddressedUrls.get(withoutQuery(filePath));
|
|
@@ -8636,6 +8653,75 @@ function writeMetadataCache(cache, key, identity, promise) {
|
|
|
8636
8653
|
}
|
|
8637
8654
|
);
|
|
8638
8655
|
}
|
|
8656
|
+
var PROBE_FACTS_VERSION = "v2";
|
|
8657
|
+
var PROBE_JSON_ARGS = ["-print_format", "json", "-show_format", "-show_streams"];
|
|
8658
|
+
var storedFacts = /* @__PURE__ */ new Map();
|
|
8659
|
+
function readStoredFacts(filePath) {
|
|
8660
|
+
if (!/^https?:\/\//i.test(filePath)) return void 0;
|
|
8661
|
+
const factsUrl = probeFactsUrls.get(withoutQuery(filePath));
|
|
8662
|
+
if (!factsUrl) return void 0;
|
|
8663
|
+
let facts = storedFacts.get(factsUrl);
|
|
8664
|
+
if (!facts) {
|
|
8665
|
+
facts = (async () => {
|
|
8666
|
+
try {
|
|
8667
|
+
const response = await fetch(factsUrl, { signal: AbortSignal.timeout(1e4) });
|
|
8668
|
+
if (!response.ok) return null;
|
|
8669
|
+
const parsed = JSON.parse(await response.text());
|
|
8670
|
+
return Array.isArray(parsed.ffprobe?.streams) ? parsed : null;
|
|
8671
|
+
} catch {
|
|
8672
|
+
return null;
|
|
8673
|
+
}
|
|
8674
|
+
})();
|
|
8675
|
+
storedFacts.set(factsUrl, facts);
|
|
8676
|
+
}
|
|
8677
|
+
return facts;
|
|
8678
|
+
}
|
|
8679
|
+
function readProbeJson(filePath, signal) {
|
|
8680
|
+
const pending = readStoredFacts(filePath);
|
|
8681
|
+
if (!pending) return runFfprobe(filePath, PROBE_JSON_ARGS, signal);
|
|
8682
|
+
return pending.then(
|
|
8683
|
+
(stored) => stored ? JSON.stringify(stored.ffprobe) : runFfprobe(filePath, PROBE_JSON_ARGS, signal)
|
|
8684
|
+
);
|
|
8685
|
+
}
|
|
8686
|
+
var runtimeFfprobeMajor;
|
|
8687
|
+
function ffprobeMajor() {
|
|
8688
|
+
runtimeFfprobeMajor ??= new Promise((resolve) => {
|
|
8689
|
+
let out = "";
|
|
8690
|
+
const binary = getFfprobeBinary();
|
|
8691
|
+
const proc = spawn3(binary, ["-version"], { stdio: ["ignore", "pipe", "ignore"] });
|
|
8692
|
+
proc.stdout.on("data", (chunk) => out += String(chunk));
|
|
8693
|
+
proc.on("error", () => resolve(void 0));
|
|
8694
|
+
proc.on("close", () => resolve(Number(/version n?(\d+)/.exec(out)?.[1]) || void 0));
|
|
8695
|
+
});
|
|
8696
|
+
return runtimeFfprobeMajor;
|
|
8697
|
+
}
|
|
8698
|
+
async function buildProbeFactsText(filePath, signal) {
|
|
8699
|
+
const facts = {
|
|
8700
|
+
ffprobe: parseProbeJson(await runFfprobe(filePath, PROBE_JSON_ARGS, signal)),
|
|
8701
|
+
ffprobeMajor: await ffprobeMajor()
|
|
8702
|
+
};
|
|
8703
|
+
try {
|
|
8704
|
+
const metadata = await extractMediaMetadata(filePath);
|
|
8705
|
+
const window2 = resolveStreamWindow(filePath, {
|
|
8706
|
+
videoStreamStartSeconds: metadata.videoStreamStartSeconds,
|
|
8707
|
+
videoStreamDurationSeconds: resolvePlayableVideoDuration(metadata) - (metadata.videoStreamLeadSeconds ?? 0)
|
|
8708
|
+
});
|
|
8709
|
+
if (window2.videoStreamDurationSeconds > 0) {
|
|
8710
|
+
facts.finalFrame = {
|
|
8711
|
+
streamStart: window2.videoStreamStartSeconds,
|
|
8712
|
+
streamDuration: window2.videoStreamDurationSeconds,
|
|
8713
|
+
seconds: await extractFinalVideoFrameTimestamp(filePath, window2, signal),
|
|
8714
|
+
lastPacketSeconds: await extractFinalPacketDuration(filePath, window2, signal)
|
|
8715
|
+
};
|
|
8716
|
+
}
|
|
8717
|
+
} catch {
|
|
8718
|
+
if (signal?.aborted) throw signal.reason;
|
|
8719
|
+
}
|
|
8720
|
+
return JSON.stringify(facts);
|
|
8721
|
+
}
|
|
8722
|
+
function resolvePlayableVideoDuration(metadata) {
|
|
8723
|
+
return Number.isFinite(metadata.videoStreamDurationSeconds) && metadata.videoStreamDurationSeconds > 0 ? (metadata.videoStreamLeadSeconds ?? 0) + metadata.videoStreamDurationSeconds : metadata.durationSeconds;
|
|
8724
|
+
}
|
|
8639
8725
|
async function probeMediaOutput(filePath, signal) {
|
|
8640
8726
|
let cache = mediaProbeOutputCache;
|
|
8641
8727
|
if (signal) {
|
|
@@ -8651,11 +8737,7 @@ async function probeMediaOutput(filePath, signal) {
|
|
|
8651
8737
|
}
|
|
8652
8738
|
return cached.promise;
|
|
8653
8739
|
}
|
|
8654
|
-
const promise =
|
|
8655
|
-
filePath,
|
|
8656
|
-
["-print_format", "json", "-show_format", "-show_streams"],
|
|
8657
|
-
signal
|
|
8658
|
-
).then(parseProbeJson);
|
|
8740
|
+
const promise = readProbeJson(filePath, signal).then(parseProbeJson);
|
|
8659
8741
|
if (identity !== null) {
|
|
8660
8742
|
cache.set(filePath, { identity, promise });
|
|
8661
8743
|
if (!signal && cache.size > MEDIA_PROBE_OUTPUT_CACHE_MAX_ENTRIES) {
|
|
@@ -8911,6 +8993,43 @@ function resolveStreamWindow(filePath, metadata) {
|
|
|
8911
8993
|
const cacheKey = `${filePath}\0${String(videoStreamStartSeconds)}\0${String(videoStreamDurationSeconds)}`;
|
|
8912
8994
|
return { videoStreamStartSeconds, videoStreamDurationSeconds, cacheKey };
|
|
8913
8995
|
}
|
|
8996
|
+
function readStoredFinalFrame(filePath, metadata) {
|
|
8997
|
+
const { videoStreamStartSeconds, videoStreamDurationSeconds } = resolveStreamWindow(
|
|
8998
|
+
filePath,
|
|
8999
|
+
metadata
|
|
9000
|
+
);
|
|
9001
|
+
return readStoredFacts(filePath)?.then(async (facts) => {
|
|
9002
|
+
const stored = facts?.finalFrame;
|
|
9003
|
+
if (facts?.ffprobeMajor !== void 0 && facts.ffprobeMajor !== await ffprobeMajor())
|
|
9004
|
+
return void 0;
|
|
9005
|
+
return stored && stored.streamStart === videoStreamStartSeconds && stored.streamDuration === videoStreamDurationSeconds ? stored : void 0;
|
|
9006
|
+
});
|
|
9007
|
+
}
|
|
9008
|
+
async function extractFinalPacketDuration(filePath, window2, signal) {
|
|
9009
|
+
const streamEnd = window2.videoStreamStartSeconds + window2.videoStreamDurationSeconds;
|
|
9010
|
+
const intervalStart = Math.max(window2.videoStreamStartSeconds, streamEnd - 1);
|
|
9011
|
+
const stdout = await runFfprobe(
|
|
9012
|
+
filePath,
|
|
9013
|
+
[
|
|
9014
|
+
"-select_streams",
|
|
9015
|
+
"v:0",
|
|
9016
|
+
"-read_intervals",
|
|
9017
|
+
`${intervalStart}%${streamEnd}`,
|
|
9018
|
+
"-show_entries",
|
|
9019
|
+
"packet=pts_time,duration_time",
|
|
9020
|
+
"-of",
|
|
9021
|
+
"csv=p=0"
|
|
9022
|
+
],
|
|
9023
|
+
signal,
|
|
9024
|
+
{ retainTail: true, maxChars: 64 * 1024 }
|
|
9025
|
+
);
|
|
9026
|
+
const packets = stdout.split("\n").map((line) => line.trim().split(",").map(Number)).filter(([pts, duration]) => Number.isFinite(pts) && Number.isFinite(duration));
|
|
9027
|
+
const last = packets.reduce(
|
|
9028
|
+
(best, packet) => !best || packet[0] > best[0] ? packet : best,
|
|
9029
|
+
void 0
|
|
9030
|
+
);
|
|
9031
|
+
return last?.[1];
|
|
9032
|
+
}
|
|
8914
9033
|
async function extractFinalVideoFrameTimestamp(filePath, metadata, signal) {
|
|
8915
9034
|
const {
|
|
8916
9035
|
videoStreamStartSeconds,
|
|
@@ -8926,6 +9045,9 @@ async function extractFinalVideoFrameTimestamp(filePath, metadata, signal) {
|
|
|
8926
9045
|
const cached = readMetadataCache(probeCache, cacheKey, identity);
|
|
8927
9046
|
if (cached) return cached;
|
|
8928
9047
|
const probePromise = (async () => {
|
|
9048
|
+
const pendingStored = readStoredFinalFrame(filePath, metadata);
|
|
9049
|
+
const stored = pendingStored && await pendingStored;
|
|
9050
|
+
if (stored) return stored.seconds;
|
|
8929
9051
|
if (!(videoDurationSeconds > 0) || !Number.isFinite(videoDurationSeconds)) {
|
|
8930
9052
|
throw new Error(
|
|
8931
9053
|
`[FFmpeg] Cannot locate final video frame for invalid duration ${String(videoDurationSeconds)}`
|
|
@@ -11528,12 +11650,52 @@ import {
|
|
|
11528
11650
|
lstatSync as lstatSync2,
|
|
11529
11651
|
mkdirSync as mkdirSync5,
|
|
11530
11652
|
readdirSync as readdirSync5,
|
|
11531
|
-
renameSync,
|
|
11532
11653
|
rmSync as rmSync3,
|
|
11533
11654
|
statSync as statSync6,
|
|
11534
11655
|
utimesSync,
|
|
11535
11656
|
writeFileSync as writeFileSync3
|
|
11536
11657
|
} from "fs";
|
|
11658
|
+
|
|
11659
|
+
// ../engine/src/utils/renameWithRetry.ts
|
|
11660
|
+
import { renameSync } from "fs";
|
|
11661
|
+
import { rename } from "fs/promises";
|
|
11662
|
+
var RETRYABLE = /* @__PURE__ */ new Set(["EPERM", "EACCES", "EBUSY"]);
|
|
11663
|
+
var BACKOFF_MS = [10, 20, 40, 80, 160, 320, 640];
|
|
11664
|
+
function isRetryable(error, platform) {
|
|
11665
|
+
if (platform !== "win32") return false;
|
|
11666
|
+
return RETRYABLE.has(error?.code ?? "");
|
|
11667
|
+
}
|
|
11668
|
+
function sleepSync(ms) {
|
|
11669
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
11670
|
+
}
|
|
11671
|
+
function renameWithRetry(from, to, options = {}) {
|
|
11672
|
+
const doRename = options.rename ?? renameSync;
|
|
11673
|
+
const platform = options.platform ?? process.platform;
|
|
11674
|
+
for (let attempt = 0; ; attempt++) {
|
|
11675
|
+
try {
|
|
11676
|
+
doRename(from, to);
|
|
11677
|
+
return;
|
|
11678
|
+
} catch (error) {
|
|
11679
|
+
if (attempt >= BACKOFF_MS.length || !isRetryable(error, platform)) throw error;
|
|
11680
|
+
sleepSync(BACKOFF_MS[attempt]);
|
|
11681
|
+
}
|
|
11682
|
+
}
|
|
11683
|
+
}
|
|
11684
|
+
async function renameWithRetryAsync(from, to, options = {}) {
|
|
11685
|
+
const doRename = options.rename ?? rename;
|
|
11686
|
+
const platform = options.platform ?? process.platform;
|
|
11687
|
+
for (let attempt = 0; ; attempt++) {
|
|
11688
|
+
try {
|
|
11689
|
+
await doRename(from, to);
|
|
11690
|
+
return;
|
|
11691
|
+
} catch (error) {
|
|
11692
|
+
if (attempt >= BACKOFF_MS.length || !isRetryable(error, platform)) throw error;
|
|
11693
|
+
await new Promise((resolve) => setTimeout(resolve, BACKOFF_MS[attempt]));
|
|
11694
|
+
}
|
|
11695
|
+
}
|
|
11696
|
+
}
|
|
11697
|
+
|
|
11698
|
+
// ../engine/src/services/extractionCache.ts
|
|
11537
11699
|
import { join as join9 } from "path";
|
|
11538
11700
|
var COMPLETE_SENTINEL = ".hf-complete";
|
|
11539
11701
|
var GC_MARKER = ".hf-last-gc";
|
|
@@ -11608,7 +11770,7 @@ function publishCacheEntry(entry, partialDir) {
|
|
|
11608
11770
|
return { dir: partialDir, published: false };
|
|
11609
11771
|
}
|
|
11610
11772
|
try {
|
|
11611
|
-
|
|
11773
|
+
renameWithRetry(partialDir, entry.dir);
|
|
11612
11774
|
return { dir: entry.dir, published: true };
|
|
11613
11775
|
} catch (err) {
|
|
11614
11776
|
if (!isTargetExistsRenameError(err)) return { dir: partialDir, published: false };
|
|
@@ -11621,7 +11783,7 @@ function publishCacheEntry(entry, partialDir) {
|
|
|
11621
11783
|
return { dir: partialDir, published: false };
|
|
11622
11784
|
}
|
|
11623
11785
|
try {
|
|
11624
|
-
|
|
11786
|
+
renameWithRetry(partialDir, entry.dir);
|
|
11625
11787
|
return { dir: entry.dir, published: true };
|
|
11626
11788
|
} catch {
|
|
11627
11789
|
return adoptPublishedWinner(entry, partialDir) ?? { dir: partialDir, published: false };
|
|
@@ -11806,6 +11968,24 @@ function extractionFrameCountForDuration(durationSeconds, fps, isVFR) {
|
|
|
11806
11968
|
const frames = Number(frameCount);
|
|
11807
11969
|
return Math.max(1, Number.isSafeInteger(frames) ? frames : Number.MAX_SAFE_INTEGER);
|
|
11808
11970
|
}
|
|
11971
|
+
function exactSourceRate(probed) {
|
|
11972
|
+
const nominal = Math.round(probed * 1.001);
|
|
11973
|
+
return [nominal, nominal * 1e3 / 1001].find((rate) => Math.abs(rate - probed) <= 5e-3 + 1e-9) ?? null;
|
|
11974
|
+
}
|
|
11975
|
+
function tailFramesFromFinalFrame(input) {
|
|
11976
|
+
const sourceRate = exactSourceRate(input.sourceFps);
|
|
11977
|
+
if (!sourceRate || !(input.outputFps > 0)) return null;
|
|
11978
|
+
const lead = input.streamLeadSeconds;
|
|
11979
|
+
if (lead !== 0 && !(Math.abs((input.lastPacketSeconds ?? NaN) - 1 / sourceRate) <= 1e-4)) {
|
|
11980
|
+
return null;
|
|
11981
|
+
}
|
|
11982
|
+
const seek = input.startTime + input.firstFrame / input.outputFps;
|
|
11983
|
+
const slots = (lead + input.finalFrameSeconds + 1 / sourceRate - seek) * input.outputFps;
|
|
11984
|
+
const distanceToSlot = Math.abs(slots - Math.round(slots));
|
|
11985
|
+
if (distanceToSlot >= 5e-5 && distanceToSlot < 5e-4) return null;
|
|
11986
|
+
const count = Math.min(input.tailFrames, Math.ceil(slots - 5e-5));
|
|
11987
|
+
return count > 0 ? count : null;
|
|
11988
|
+
}
|
|
11809
11989
|
var DOWNLOAD_SUBDIR = "_downloads";
|
|
11810
11990
|
var EXTRACT_CACHE_MIN_AGE_MS = 60 * 60 * 1e3;
|
|
11811
11991
|
var GC_STALENESS_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -12180,6 +12360,8 @@ function undoTickRoundingOnTheSourceFrameGrid(seek, lead) {
|
|
|
12180
12360
|
}
|
|
12181
12361
|
var EXTRACTION_SLOTS = Math.max(1, Math.floor(cpus().length / 2));
|
|
12182
12362
|
var inExtractionSlot = createConcurrencyLimit(EXTRACTION_SLOTS);
|
|
12363
|
+
var TAIL_PROBE_SLOTS = Math.max(1, Number(process.env.HF_TAIL_PROBE_SLOTS) || 16);
|
|
12364
|
+
var inTailProbeSlot = createConcurrencyLimit(TAIL_PROBE_SLOTS);
|
|
12183
12365
|
function splitFrameRanges(ranges, segmentFrames) {
|
|
12184
12366
|
const segments = [];
|
|
12185
12367
|
for (const range of ranges) {
|
|
@@ -12193,7 +12375,7 @@ function splitFrameRanges(ranges, segmentFrames) {
|
|
|
12193
12375
|
return segments;
|
|
12194
12376
|
}
|
|
12195
12377
|
async function runSegmentedExtraction(job) {
|
|
12196
|
-
const { decodeArgs, filterAndEncodeArgs, videoPath, startTime, fps, segments } = job;
|
|
12378
|
+
const { decodeArgs, filterAndEncodeArgs, videoPath, startTime, fps, segments, gate } = job;
|
|
12197
12379
|
const segmentCount = segments.length;
|
|
12198
12380
|
const failed = new AbortController();
|
|
12199
12381
|
const signal = job.runOptions.signal ? AbortSignal.any([job.runOptions.signal, failed.signal]) : failed.signal;
|
|
@@ -12204,7 +12386,7 @@ async function runSegmentedExtraction(job) {
|
|
|
12204
12386
|
const index = next++;
|
|
12205
12387
|
const { firstFrame, frames } = segments[index];
|
|
12206
12388
|
const seek = startTime + firstFrame / fps;
|
|
12207
|
-
const result = await
|
|
12389
|
+
const result = await gate(
|
|
12208
12390
|
() => runFfmpeg(
|
|
12209
12391
|
[
|
|
12210
12392
|
...decodeArgs,
|
|
@@ -12355,6 +12537,7 @@ async function extractVideoFramesRangeUnredacted(videoPath, videoId, startTime,
|
|
|
12355
12537
|
videoPath,
|
|
12356
12538
|
startTime,
|
|
12357
12539
|
fps,
|
|
12540
|
+
gate: options.tailProbe ? inTailProbeSlot : inExtractionSlot,
|
|
12358
12541
|
segments: splitFrameRanges(
|
|
12359
12542
|
options.frameRanges ?? [{ firstFrame: 0, frames: totalFrames }],
|
|
12360
12543
|
segmentFrames
|
|
@@ -12455,9 +12638,6 @@ function resolveSegmentDuration(requested, mediaStart, sourceDuration) {
|
|
|
12455
12638
|
const sourceRemaining = sourceDuration - mediaStart;
|
|
12456
12639
|
return sourceRemaining > 0 ? sourceRemaining : sourceDuration;
|
|
12457
12640
|
}
|
|
12458
|
-
function resolvePlayableVideoDuration(metadata) {
|
|
12459
|
-
return Number.isFinite(metadata.videoStreamDurationSeconds) && metadata.videoStreamDurationSeconds > 0 ? (metadata.videoStreamLeadSeconds ?? 0) + metadata.videoStreamDurationSeconds : metadata.durationSeconds;
|
|
12460
|
-
}
|
|
12461
12641
|
function canHoldFinalFramePastEof(video) {
|
|
12462
12642
|
const timelineDuration = video.end - video.start;
|
|
12463
12643
|
return !video.loop && Number.isFinite(timelineDuration) && timelineDuration > 0;
|
|
@@ -13136,23 +13316,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config, c
|
|
|
13136
13316
|
);
|
|
13137
13317
|
const tailFrames = Math.min(expectedFrames, Math.ceil(fps));
|
|
13138
13318
|
if (expectedFrames <= tailFrames) return null;
|
|
13139
|
-
const
|
|
13140
|
-
try {
|
|
13141
|
-
const tail = await extractVideoFramesRange(
|
|
13142
|
-
work.videoPath,
|
|
13143
|
-
work.video.id,
|
|
13144
|
-
work.extractionMediaStart,
|
|
13145
|
-
work.videoDuration,
|
|
13146
|
-
{
|
|
13147
|
-
...scopedExtractionOptions(work),
|
|
13148
|
-
frameRanges: [{ firstFrame: expectedFrames - tailFrames, frames: tailFrames }]
|
|
13149
|
-
},
|
|
13150
|
-
signal,
|
|
13151
|
-
config,
|
|
13152
|
-
probeDir
|
|
13153
|
-
);
|
|
13154
|
-
const totalFrames = expectedFrames - tailFrames + tail.totalFrames;
|
|
13155
|
-
if (totalFrames <= expectedFrames * 0.6) return null;
|
|
13319
|
+
const deferred = (totalFrames) => {
|
|
13156
13320
|
const outputDir = join10(options.outputDir, work.video.id);
|
|
13157
13321
|
mkdirSync6(outputDir, { recursive: true });
|
|
13158
13322
|
return {
|
|
@@ -13170,6 +13334,45 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config, c
|
|
|
13170
13334
|
format: work.format
|
|
13171
13335
|
}
|
|
13172
13336
|
};
|
|
13337
|
+
};
|
|
13338
|
+
if (work.extractionMediaStart + work.videoDuration + 1 <= resolvePlayableVideoDuration(work.metadata)) {
|
|
13339
|
+
return deferred(expectedFrames);
|
|
13340
|
+
}
|
|
13341
|
+
const firstTailFrame = expectedFrames - tailFrames;
|
|
13342
|
+
const storedFinalFrame = await readStoredFinalFrame(work.videoPath, work.metadata);
|
|
13343
|
+
const storedTailFrames = storedFinalFrame === void 0 ? null : tailFramesFromFinalFrame({
|
|
13344
|
+
startTime: work.extractionMediaStart,
|
|
13345
|
+
firstFrame: firstTailFrame,
|
|
13346
|
+
tailFrames,
|
|
13347
|
+
outputFps: fps,
|
|
13348
|
+
sourceFps: work.metadata.fps,
|
|
13349
|
+
finalFrameSeconds: storedFinalFrame.seconds,
|
|
13350
|
+
lastPacketSeconds: storedFinalFrame.lastPacketSeconds,
|
|
13351
|
+
streamLeadSeconds: work.metadata.videoStreamLeadSeconds ?? 0
|
|
13352
|
+
});
|
|
13353
|
+
if (storedTailFrames !== null) {
|
|
13354
|
+
const totalFrames = firstTailFrame + storedTailFrames;
|
|
13355
|
+
return totalFrames <= expectedFrames * 0.6 ? null : deferred(totalFrames);
|
|
13356
|
+
}
|
|
13357
|
+
const probeDir = join10(options.outputDir, `${work.video.id}.tail-probe`);
|
|
13358
|
+
try {
|
|
13359
|
+
const tail = await extractVideoFramesRange(
|
|
13360
|
+
work.videoPath,
|
|
13361
|
+
work.video.id,
|
|
13362
|
+
work.extractionMediaStart,
|
|
13363
|
+
work.videoDuration,
|
|
13364
|
+
{
|
|
13365
|
+
...scopedExtractionOptions(work),
|
|
13366
|
+
frameRanges: [{ firstFrame: firstTailFrame, frames: tailFrames }],
|
|
13367
|
+
tailProbe: isHttpUrl(work.videoPath)
|
|
13368
|
+
},
|
|
13369
|
+
signal,
|
|
13370
|
+
config,
|
|
13371
|
+
probeDir
|
|
13372
|
+
);
|
|
13373
|
+
const totalFrames = firstTailFrame + tail.totalFrames;
|
|
13374
|
+
if (totalFrames <= expectedFrames * 0.6) return null;
|
|
13375
|
+
return deferred(totalFrames);
|
|
13173
13376
|
} catch {
|
|
13174
13377
|
return null;
|
|
13175
13378
|
} finally {
|
|
@@ -14048,16 +14251,7 @@ async function queryElementStacking(page, nativeHdrIds) {
|
|
|
14048
14251
|
}
|
|
14049
14252
|
|
|
14050
14253
|
// ../engine/src/services/audioMixer.ts
|
|
14051
|
-
import {
|
|
14052
|
-
closeSync as closeSync4,
|
|
14053
|
-
existsSync as existsSync11,
|
|
14054
|
-
mkdirSync as mkdirSync7,
|
|
14055
|
-
mkdtempSync as mkdtempSync7,
|
|
14056
|
-
openSync as openSync4,
|
|
14057
|
-
renameSync as renameSync3,
|
|
14058
|
-
rmSync as rmSync8,
|
|
14059
|
-
writeFileSync as writeFileSync7
|
|
14060
|
-
} from "fs";
|
|
14254
|
+
import { closeSync as closeSync4, existsSync as existsSync11, mkdirSync as mkdirSync7, mkdtempSync as mkdtempSync7, openSync as openSync4, rmSync as rmSync8, writeFileSync as writeFileSync7 } from "fs";
|
|
14061
14255
|
import { join as join14, dirname as dirname7, isAbsolute, relative } from "path";
|
|
14062
14256
|
|
|
14063
14257
|
// ../engine/src/utils/notMediaPayload.ts
|
|
@@ -14176,6 +14370,7 @@ function clampFadesToDuration(fades, duration) {
|
|
|
14176
14370
|
import { cpus as cpus2 } from "os";
|
|
14177
14371
|
|
|
14178
14372
|
// ../engine/src/services/aacEncode.ts
|
|
14373
|
+
import { execFile as execFile3 } from "child_process";
|
|
14179
14374
|
import { mkdtempSync as mkdtempSync4, readFileSync as readFileSync5, rmSync as rmSync5, writeFileSync as writeFileSync4 } from "fs";
|
|
14180
14375
|
import { dirname as dirname5, join as join11 } from "path";
|
|
14181
14376
|
var SAMPLE_RATE = 48e3;
|
|
@@ -14211,12 +14406,35 @@ function planSegments(totalDuration, count) {
|
|
|
14211
14406
|
return { trim, keepFrom: cut - firstFrame, keepTo: next - firstFrame };
|
|
14212
14407
|
});
|
|
14213
14408
|
}
|
|
14409
|
+
var settsDurationSupport = /* @__PURE__ */ new Map();
|
|
14410
|
+
function supportsSettsDuration(binary = getFfmpegBinary()) {
|
|
14411
|
+
let supported = settsDurationSupport.get(binary);
|
|
14412
|
+
if (!supported) {
|
|
14413
|
+
supported = new Promise((resolve) => {
|
|
14414
|
+
execFile3(binary, ["-hide_banner", "-h", "bsf=setts"], (error, stdout) => {
|
|
14415
|
+
resolve(error !== null || stdout.includes("duration"));
|
|
14416
|
+
});
|
|
14417
|
+
});
|
|
14418
|
+
settsDurationSupport.set(binary, supported);
|
|
14419
|
+
}
|
|
14420
|
+
return supported;
|
|
14421
|
+
}
|
|
14422
|
+
function encodeInOnePass(input, outputPath, { signal, timeout, filter }) {
|
|
14423
|
+
const filters = [filter, `aresample=${SAMPLE_RATE}`].filter(Boolean).join(",");
|
|
14424
|
+
return runFfmpeg(["-i", input, "-af", filters, ...AAC_ARGS, "-y", outputPath], {
|
|
14425
|
+
signal,
|
|
14426
|
+
timeout
|
|
14427
|
+
});
|
|
14428
|
+
}
|
|
14214
14429
|
async function encodeAac(input, outputPath, totalDuration, {
|
|
14215
14430
|
signal,
|
|
14216
14431
|
timeout,
|
|
14217
14432
|
filter,
|
|
14218
14433
|
segments: count = aacSegmentCount(totalDuration)
|
|
14219
14434
|
}) {
|
|
14435
|
+
if (!await supportsSettsDuration()) {
|
|
14436
|
+
return encodeInOnePass(input, outputPath, { signal, timeout, filter });
|
|
14437
|
+
}
|
|
14220
14438
|
const dir = mkdtempSync4(join11(dirname5(outputPath), ".aac-segments-"));
|
|
14221
14439
|
try {
|
|
14222
14440
|
const segments = planSegments(totalDuration, count).map((segment, k) => ({
|
|
@@ -14382,7 +14600,7 @@ function audioFailureDiagnostics(values) {
|
|
|
14382
14600
|
}
|
|
14383
14601
|
|
|
14384
14602
|
// ../engine/src/services/audioVolumeEnvelope.ts
|
|
14385
|
-
import { mkdtempSync as mkdtempSync5, readFileSync as readFileSync6,
|
|
14603
|
+
import { mkdtempSync as mkdtempSync5, readFileSync as readFileSync6, rmSync as rmSync6, writeFileSync as writeFileSync5 } from "fs";
|
|
14386
14604
|
import { dirname as dirname6, join as join12 } from "path";
|
|
14387
14605
|
|
|
14388
14606
|
// ../core/dist/runtime/mediaVolumeEnvelope.js
|
|
@@ -14512,7 +14730,7 @@ function applyVolumeEnvelopeToWav(wavPath, keyframes, trackStart, baseVolume) {
|
|
|
14512
14730
|
stagingDir = mkdtempSync5(join12(dirname6(wavPath), ".hf-volume-"));
|
|
14513
14731
|
const tempPath = join12(stagingDir, "audio.wav");
|
|
14514
14732
|
writeFileSync5(tempPath, buffer, { flag: "wx" });
|
|
14515
|
-
|
|
14733
|
+
renameWithRetry(tempPath, wavPath);
|
|
14516
14734
|
return true;
|
|
14517
14735
|
} catch {
|
|
14518
14736
|
return false;
|
|
@@ -16010,7 +16228,7 @@ async function mixGroupMembers(memberTracks, outputPath, totalDuration, signal,
|
|
|
16010
16228
|
try {
|
|
16011
16229
|
const summed = await sumInSlices(memberTracks, scratchDir, totalDuration, signal, config);
|
|
16012
16230
|
if (!summed.success) return summed;
|
|
16013
|
-
|
|
16231
|
+
renameWithRetry(summed.track.srcPath, outputPath);
|
|
16014
16232
|
return { success: true, degradedAutomation: summed.degradedAutomation };
|
|
16015
16233
|
} finally {
|
|
16016
16234
|
rmSync8(scratchDir, { recursive: true, force: true });
|
|
@@ -16052,12 +16270,15 @@ async function mixAudioTracks(tracks, outputPath, totalDuration, signal, config)
|
|
|
16052
16270
|
}
|
|
16053
16271
|
async function mixThroughFloatSum(tracks, masterChain, outputPath, workDir, totalDuration, signal, config) {
|
|
16054
16272
|
const sumPath = join14(workDir, "master-sum.wav");
|
|
16273
|
+
const mixStart = Date.now();
|
|
16055
16274
|
const sum = await mixAudioTracks(tracks, sumPath, totalDuration, signal, config);
|
|
16056
16275
|
if (!sum.success) return { ...sum, outputPath };
|
|
16276
|
+
const masterStart = Date.now();
|
|
16057
16277
|
const encoderInput = masterChain ? (await applyAudioFxChain(sumPath, masterChain, join14(workDir, "master-fx.wav"), {
|
|
16058
16278
|
trackId: "master",
|
|
16059
16279
|
signal
|
|
16060
16280
|
})).path : sumPath;
|
|
16281
|
+
const encodeStart = Date.now();
|
|
16061
16282
|
const encoded = await encodeAac(encoderInput, outputPath, totalDuration, {
|
|
16062
16283
|
signal,
|
|
16063
16284
|
timeout: config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG.ffmpegProcessTimeout
|
|
@@ -16077,8 +16298,17 @@ async function mixThroughFloatSum(tracks, masterChain, outputPath, workDir, tota
|
|
|
16077
16298
|
failures: [failure]
|
|
16078
16299
|
};
|
|
16079
16300
|
}
|
|
16080
|
-
if (config?.keepEncoderInputAt)
|
|
16081
|
-
return {
|
|
16301
|
+
if (config?.keepEncoderInputAt) renameWithRetry(encoderInput, config.keepEncoderInputAt);
|
|
16302
|
+
return {
|
|
16303
|
+
...sum,
|
|
16304
|
+
outputPath,
|
|
16305
|
+
durationMs: sum.durationMs + encoded.durationMs,
|
|
16306
|
+
phaseMs: {
|
|
16307
|
+
mix: masterStart - mixStart,
|
|
16308
|
+
master: encodeStart - masterStart,
|
|
16309
|
+
encode: Date.now() - encodeStart
|
|
16310
|
+
}
|
|
16311
|
+
};
|
|
16082
16312
|
}
|
|
16083
16313
|
async function processCompositionAudio(elements, baseDir, workDir, outputPath, totalDuration, signal, config, compiledDir) {
|
|
16084
16314
|
const startMs = Date.now();
|
|
@@ -16363,6 +16593,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
16363
16593
|
failures
|
|
16364
16594
|
};
|
|
16365
16595
|
};
|
|
16596
|
+
const prepareMs = Date.now() - startMs;
|
|
16366
16597
|
if (failures.length > 0) return bail();
|
|
16367
16598
|
let masterChain;
|
|
16368
16599
|
const masterFxJson = config?.masterFxChain;
|
|
@@ -16473,6 +16704,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
16473
16704
|
}
|
|
16474
16705
|
}
|
|
16475
16706
|
if (failures.length > 0) return bail();
|
|
16707
|
+
const groupsMs = Date.now() - startMs - prepareMs;
|
|
16476
16708
|
let mixResult;
|
|
16477
16709
|
try {
|
|
16478
16710
|
mixResult = tracks.length > 0 ? await mixThroughFloatSum(
|
|
@@ -16491,6 +16723,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
16491
16723
|
return {
|
|
16492
16724
|
...mixResult,
|
|
16493
16725
|
durationMs: Date.now() - startMs,
|
|
16726
|
+
phaseMs: { prepare: prepareMs, groups: groupsMs, ...mixResult.phaseMs },
|
|
16494
16727
|
// Both, when both degraded. `mixResult.error ?? degradedNote` reported only
|
|
16495
16728
|
// the outer mix and dropped the one that names which GROUPS lost their
|
|
16496
16729
|
// members' automation — two different losses, and the operator needs to
|
|
@@ -16502,18 +16735,18 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
16502
16735
|
// ../engine/src/services/parallelCoordinator.ts
|
|
16503
16736
|
import { cpus as cpus3, freemem } from "os";
|
|
16504
16737
|
import { existsSync as existsSync12, mkdirSync as mkdirSync8, readdirSync as readdirSync6 } from "fs";
|
|
16505
|
-
import { copyFile, readFile as readFile2
|
|
16738
|
+
import { copyFile, readFile as readFile2 } from "fs/promises";
|
|
16506
16739
|
import { join as join16 } from "path";
|
|
16507
16740
|
import { getHeapStatistics } from "v8";
|
|
16508
16741
|
|
|
16509
16742
|
// ../engine/src/utils/psnr.ts
|
|
16510
|
-
import { execFile as
|
|
16743
|
+
import { execFile as execFile4 } from "child_process";
|
|
16511
16744
|
import { mkdtemp, rm, writeFile } from "fs/promises";
|
|
16512
16745
|
import { tmpdir as tmpdir4 } from "os";
|
|
16513
16746
|
import { join as join15 } from "path";
|
|
16514
16747
|
import { promisify as promisify3 } from "util";
|
|
16515
16748
|
async function psnrDb(a, b) {
|
|
16516
|
-
const execFileP = promisify3(
|
|
16749
|
+
const execFileP = promisify3(execFile4);
|
|
16517
16750
|
const dir = await mkdtemp(join15(tmpdir4(), "hf-de-verify-"));
|
|
16518
16751
|
try {
|
|
16519
16752
|
const pa = join15(dir, "a.jpg");
|
|
@@ -17047,7 +17280,8 @@ async function executeWorkerTask(task, serverUrl, captureOptions, createBeforeCa
|
|
|
17047
17280
|
endFrame: task.endFrame,
|
|
17048
17281
|
frameStride: task.frameStride,
|
|
17049
17282
|
durationMs: Date.now() - startTime,
|
|
17050
|
-
perf
|
|
17283
|
+
perf,
|
|
17284
|
+
pageErrorLines: pageErrorLinesOf(activeSession)
|
|
17051
17285
|
};
|
|
17052
17286
|
} catch (error) {
|
|
17053
17287
|
const diagnostics = session ? selectWorkerDiagnostics(session.browserConsoleBuffer) : [];
|
|
@@ -17060,7 +17294,8 @@ async function executeWorkerTask(task, serverUrl, captureOptions, createBeforeCa
|
|
|
17060
17294
|
};
|
|
17061
17295
|
const failure = classifyCaptureFailure(error, {
|
|
17062
17296
|
signal,
|
|
17063
|
-
workerDiagnostics: [workerDiagnostic]
|
|
17297
|
+
workerDiagnostics: [workerDiagnostic],
|
|
17298
|
+
pageErrorLines: session ? pageErrorLinesOf(session) : void 0
|
|
17064
17299
|
});
|
|
17065
17300
|
onFailure?.(failure);
|
|
17066
17301
|
return {
|
|
@@ -17073,6 +17308,7 @@ async function executeWorkerTask(task, serverUrl, captureOptions, createBeforeCa
|
|
|
17073
17308
|
perf,
|
|
17074
17309
|
error: failure.message,
|
|
17075
17310
|
diagnostics: diagnostics.length > 0 ? diagnostics : void 0,
|
|
17311
|
+
pageErrorLines: session ? pageErrorLinesOf(session) : void 0,
|
|
17076
17312
|
failure
|
|
17077
17313
|
};
|
|
17078
17314
|
} finally {
|
|
@@ -17089,6 +17325,9 @@ function isPoolFatalWorkerFailure(failure, streaming) {
|
|
|
17089
17325
|
if (streaming) return failure.kind !== "cancelled";
|
|
17090
17326
|
return isFatalCaptureFailure(failure);
|
|
17091
17327
|
}
|
|
17328
|
+
function pageErrorLinesOf(session) {
|
|
17329
|
+
return session.browserConsoleBuffer.filter((line) => line.includes("PAGEERROR"));
|
|
17330
|
+
}
|
|
17092
17331
|
function createPoolFailureHandler(args) {
|
|
17093
17332
|
let firstFatalFailure;
|
|
17094
17333
|
return {
|
|
@@ -17180,7 +17419,8 @@ async function executeParallelCapture(serverUrl, workDir, tasks, captureOptions,
|
|
|
17180
17419
|
kind: representative?.kind ?? "io",
|
|
17181
17420
|
message: `[Parallel] Capture failed: ${errorMessages}`,
|
|
17182
17421
|
cause: representative,
|
|
17183
|
-
workerDiagnostics
|
|
17422
|
+
workerDiagnostics,
|
|
17423
|
+
pageErrorLines: [...new Set(results.flatMap((result) => result.pageErrorLines ?? []))]
|
|
17184
17424
|
});
|
|
17185
17425
|
}
|
|
17186
17426
|
return results;
|
|
@@ -17198,7 +17438,7 @@ async function mergeWorkerFrames(workDir, tasks, outputDir) {
|
|
|
17198
17438
|
const sourcePath = join16(task.outputDir, file);
|
|
17199
17439
|
const targetPath = join16(outputDir, file);
|
|
17200
17440
|
try {
|
|
17201
|
-
await
|
|
17441
|
+
await renameWithRetryAsync(sourcePath, targetPath);
|
|
17202
17442
|
} catch {
|
|
17203
17443
|
await copyFile(sourcePath, targetPath);
|
|
17204
17444
|
}
|
|
@@ -17747,6 +17987,10 @@ export {
|
|
|
17747
17987
|
describeFfmpegFailure,
|
|
17748
17988
|
runFfmpeg,
|
|
17749
17989
|
declareContentAddressedUrl,
|
|
17990
|
+
declareProbeFactsUrl,
|
|
17991
|
+
PROBE_FACTS_VERSION,
|
|
17992
|
+
buildProbeFactsText,
|
|
17993
|
+
resolvePlayableVideoDuration,
|
|
17750
17994
|
probeMediaProfile,
|
|
17751
17995
|
extractMediaMetadata,
|
|
17752
17996
|
extractFinalVideoFrameTimestamp,
|
|
@@ -17785,6 +18029,8 @@ export {
|
|
|
17785
18029
|
fetchPublicHttpsText,
|
|
17786
18030
|
downloadToTemp,
|
|
17787
18031
|
isHttpUrl,
|
|
18032
|
+
renameWithRetry,
|
|
18033
|
+
renameWithRetryAsync,
|
|
17788
18034
|
directorySizeBytes,
|
|
17789
18035
|
gcExtractionCache,
|
|
17790
18036
|
VIDEO_FRAME_FORMATS,
|
|
@@ -17799,7 +18045,6 @@ export {
|
|
|
17799
18045
|
parseVideoElements,
|
|
17800
18046
|
parseImageElements,
|
|
17801
18047
|
extractVideoFramesRange,
|
|
17802
|
-
resolvePlayableVideoDuration,
|
|
17803
18048
|
isVideoPastTimelineEnd,
|
|
17804
18049
|
rebaseVideoToWindow,
|
|
17805
18050
|
resolveTimelineExtractionWindow,
|