hyperframes 0.8.188 → 0.8.190-hdr.1
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-UORF6235.js → add-42OFT2PY.js} +11 -11
- package/dist/{animatedGifPrep-23MLSEXF.js → animatedGifPrep-ADGDO7XY.js} +5 -5
- package/dist/api.js +13 -13
- package/dist/{asset-DOKDVHCW.js → asset-O67VPO3R.js} +2 -2
- package/dist/{assetCataloger-CD27MHEY.js → assetCataloger-6XITUU4Q.js} +5 -5
- package/dist/{audio-3NMZHNNU.js → audio-XKJ3ZIDS.js} +11 -11
- package/dist/{auth-AWKTSKGC.js → auth-OQPI6LUT.js} +1 -1
- package/dist/{autoUpdate-VBOI4CNU.js → autoUpdate-A2N5A6DZ.js} +2 -2
- package/dist/{backgroundChecks-S4R454YU.js → backgroundChecks-WMA3TUHP.js} +3 -3
- package/dist/backgroundChecksWorker.js +3 -3
- package/dist/{batchRender-EGPYNDHK.js → batchRender-QZKFVWEI.js} +3 -3
- package/dist/{beats-YENEQUOA.js → beats-36HTUETR.js} +4 -4
- package/dist/{benchmark-THSJIQG7.js → benchmark-PPJOA4I5.js} +8 -8
- package/dist/{browser-BDMVQ6WJ.js → browser-ZVRJHCG5.js} +3 -3
- package/dist/{bundleWithLocalizedFonts-3QG722YD.js → bundleWithLocalizedFonts-R64YXJL5.js} +2 -2
- package/dist/{capture-Z6BGCTK3.js → capture-U7E5PPGU.js} +8 -8
- package/dist/{capture-WM4XDMFX.js → capture-YFK4OMCA.js} +2 -2
- package/dist/{captureCompositionFrame-EMHSAIBZ.js → captureCompositionFrame-DSKY6NL7.js} +11 -11
- package/dist/{catalog-7TV6UNCG.js → catalog-AYZ2KQMV.js} +11 -11
- package/dist/{catch-up-63IUDZRW.js → catch-up-EXF4BC4Z.js} +4 -4
- package/dist/{check-7RHZL4DV.js → check-4CTWFC7P.js} +34 -33
- package/dist/{checkBrowser-PF56CT5X.js → checkBrowser-JCZJGHYX.js} +29 -30
- package/dist/{chunk-5OZI55AC.js → chunk-2ICQSIZZ.js} +1 -1
- package/dist/{chunk-I7C5GUEQ.js → chunk-3B35XAD2.js} +3 -3
- package/dist/{chunk-OKSYDQHY.js → chunk-3Q5WJY5E.js} +3 -3
- package/dist/{chunk-YCW345M4.js → chunk-4BINHKAB.js} +359 -211
- package/dist/{chunk-KY7375C4.js → chunk-4TFBD773.js} +1 -1
- package/dist/{chunk-YV4WT7CJ.js → chunk-56IOFIYB.js} +12 -1
- package/dist/{chunk-46VJ2UAV.js → chunk-5XD6QAMF.js} +5 -5
- package/dist/{chunk-HKUZCSNZ.js → chunk-6HYHHMX3.js} +2 -2
- package/dist/{chunk-PQLFJYGP.js → chunk-6OJBN6P4.js} +5 -5
- package/dist/{chunk-6OWNUXTU.js → chunk-6TBDO6H6.js} +1 -1
- package/dist/{chunk-FWVILDOZ.js → chunk-7DJCW4YE.js} +3 -3
- package/dist/{chunk-NMOTNNP2.js → chunk-7KTMMDHC.js} +1 -1
- package/dist/{chunk-IA2IDJAG.js → chunk-A4WDFBHY.js} +1 -1
- package/dist/{chunk-NFLZNSUZ.js → chunk-AGUVIOZR.js} +1 -1
- package/dist/{chunk-V6NM4KL3.js → chunk-AMGFHO6X.js} +2 -2
- package/dist/{chunk-JWRT2IXO.js → chunk-ATQTK7CJ.js} +1 -1
- package/dist/{chunk-HPQSUPR7.js → chunk-AYFF3GX6.js} +1 -1
- package/dist/{chunk-W2KGJHUL.js → chunk-B7JFAXDP.js} +2 -2
- package/dist/{chunk-LWYZN7HS.js → chunk-BT64TTSE.js} +219 -79
- package/dist/{chunk-ZIRIDSDB.js → chunk-BWPY64WA.js} +1 -1
- package/dist/{chunk-44QWRPGE.js → chunk-CWRAVNDW.js} +2 -2
- package/dist/chunk-DIV37NUE.js +3896 -0
- package/dist/{chunk-57XL23DE.js → chunk-E65UJDKR.js} +1 -1
- package/dist/{chunk-MTPPEEYZ.js → chunk-E6BMTU6F.js} +16 -8
- package/dist/{chunk-LWY3PFJ7.js → chunk-EPOYPP36.js} +2 -2
- package/dist/{chunk-KDBPZOXK.js → chunk-EQXUGT5K.js} +11 -11
- package/dist/{chunk-6HYPEIH7.js → chunk-EYBS6GH2.js} +2 -2
- package/dist/{chunk-T3OXKSRG.js → chunk-EZFGQAYH.js} +2 -2
- package/dist/{chunk-FSTLXRIN.js → chunk-GWE3UEGX.js} +1 -1
- package/dist/{chunk-XPVN4R66.js → chunk-HJZ5CPZA.js} +31 -7
- package/dist/{chunk-BU4HRISA.js → chunk-ID4S5OVW.js} +91 -24
- package/dist/{chunk-GYBPAKBM.js → chunk-ILIPOK4L.js} +53 -31
- package/dist/{chunk-BWEZDN6U.js → chunk-JVG4G46L.js} +1 -1
- package/dist/{chunk-MJKUCR3C.js → chunk-KVZ4ZANT.js} +2 -2
- package/dist/{chunk-6HZ7TSJJ.js → chunk-L34DPWY4.js} +15 -11
- package/dist/{chunk-KWSEIVR6.js → chunk-LJKMM3XW.js} +1 -1
- package/dist/{chunk-L243NE72.js → chunk-O6NHRPQV.js} +7 -7
- package/dist/{chunk-2DHCCBCN.js → chunk-OAZGGUCB.js} +9 -9
- package/dist/{chunk-NFHRGHCJ.js → chunk-PFMLW2WE.js} +4 -4
- package/dist/{chunk-DA4TQFSF.js → chunk-PWEK5IYU.js} +1 -1
- package/dist/{chunk-5DPV7LU3.js → chunk-RDHEG7RX.js} +2 -2
- package/dist/{chunk-DLFAVRF3.js → chunk-SUSSMCWL.js} +1 -1
- package/dist/{chunk-YZ73IPW2.js → chunk-T6MUUXE3.js} +2 -2
- package/dist/{chunk-U6RXZNZE.js → chunk-TMBUBLZB.js} +55 -23
- package/dist/{chunk-SMF6YAUL.js → chunk-TSQAPPRS.js} +1 -1
- package/dist/{chunk-OJOZXWLC.js → chunk-U4DWSOH5.js} +3 -3
- package/dist/{chunk-JYC53CW4.js → chunk-UASUPXBJ.js} +97 -30
- package/dist/{chunk-UF6RCYA5.js → chunk-UQMPHIOA.js} +1 -1
- package/dist/{chunk-PMXR3IUH.js → chunk-UWSJL63I.js} +1 -1
- package/dist/{chunk-DG4ME554.js → chunk-UZ7RJDEC.js} +1 -1
- package/dist/{chunk-X556BGL7.js → chunk-WBUO6WH6.js} +1 -1
- package/dist/{chunk-IJYR4TTA.js → chunk-XBZEQTBH.js} +1 -1
- package/dist/{chunk-B2P4JRUJ.js → chunk-XNLYMHX2.js} +1 -1
- package/dist/{chunk-FOLMMQF3.js → chunk-XRYN74FP.js} +13 -13
- package/dist/{chunk-2WUDFZCR.js → chunk-XSDZ3H5H.js} +2 -2
- package/dist/{chunk-MXXX6WVC.js → chunk-YDGW5KWX.js} +1 -1
- package/dist/{chunk-FH7WODJH.js → chunk-ZFFKWHXN.js} +8 -0
- package/dist/{chunk-6Q5CFUAP.js → chunk-ZKWXDQAE.js} +1 -1
- package/dist/{clean-43O47OTN.js → clean-2JS7FOL5.js} +14 -14
- package/dist/cli.js +53 -53
- package/dist/{cloud-ZFWKFFSU.js → cloud-HCB6VY6B.js} +4 -4
- package/dist/{cloudrun-XBBESKEU.js → cloudrun-CTNX64R6.js} +4 -4
- package/dist/{compare-OW4ELTFZ.js → compare-ISRKIX34.js} +26 -26
- package/dist/{compiler-23MT6CX6.js → compiler-EJE3HLCS.js} +2 -2
- package/dist/{component-SDV7LWH6.js → component-ZBPQXTNP.js} +3 -3
- package/dist/{compositions-DI5QZCEK.js → compositions-WOZU3EYH.js} +9 -9
- package/dist/{delete-QY2NSQ2G.js → delete-NX3DWOKP.js} +2 -2
- package/dist/{deploy-MJVC4EFY.js → deploy-RW7L3BHN.js} +1 -1
- package/dist/{dist-RFTGYT26.js → dist-NHW2JQCA.js} +4 -2
- package/dist/{doctor-7ZOECPHR.js → doctor-KFHSQJWL.js} +9 -9
- package/dist/{events-XVQQGECC.js → events-RY3Z2CFX.js} +2 -2
- package/dist/{events-WIX4JM2K.js → events-YT6WKFUT.js} +3 -3
- package/dist/{feedback-GBYBR6UO.js → feedback-GRNEVOPP.js} +6 -6
- package/dist/{ffmpeg-QGQBYMO3.js → ffmpeg-BTEY5DB5.js} +5 -5
- package/dist/{figma-2CMKUGJQ.js → figma-WN7BLU45.js} +3 -3
- package/dist/fontLocalizeCli.js +7 -7
- package/dist/{get-RWCNUOHU.js → get-DVXYGS3H.js} +2 -2
- package/dist/{gpuPolicy-UGWSN32D.js → gpuPolicy-MWZSLJFR.js} +5 -5
- package/dist/{grade-compare-J2MX7HZL.js → grade-compare-LQXE5JYS.js} +27 -27
- package/dist/{help-SH3ID7MV.js → help-22RCD5VH.js} +1 -1
- package/dist/{history-C7V5QH7J.js → history-IF553ERO.js} +7 -7
- package/dist/hyperframe.manifest.json +1 -1
- package/dist/hyperframe.runtime.iife.js +62 -62
- package/dist/hyperframes-player.global.js +3 -3
- package/dist/{info-ZN3JJ3IN.js → info-VQGFR3XN.js} +7 -7
- package/dist/{init-KRNGSRNH.js → init-UPM6HJKO.js} +25 -25
- package/dist/{inspect-AYDZXTX7.js → inspect-S2XEY7E2.js} +27 -27
- package/dist/{installer-N6AIK6XQ.js → installer-PQKH2S7C.js} +4 -4
- package/dist/{keyframes-2RFUCEDK.js → keyframes-54Q3I2A5.js} +6 -6
- package/dist/{lambda-VW3CF6EE.js → lambda-6IGRFK3D.js} +6 -6
- package/dist/{layout-OE64APE7.js → layout-ZIE7P36K.js} +27 -27
- package/dist/{lint-UXJTX5WS.js → lint-ONB3UNVL.js} +6 -6
- package/dist/{list-KOL6JPZJ.js → list-P5VNTBT4.js} +2 -2
- package/dist/{login-MAQXOPDG.js → login-7ROFE2PP.js} +4 -4
- package/dist/{manager-3LZKRK7P.js → manager-4IBU76NA.js} +6 -6
- package/dist/{media-treatment-COLSXXQJ.js → media-treatment-GUZYPOL5.js} +11 -11
- package/dist/{models-XXWMGOD7.js → models-POH5ZYWG.js} +9 -9
- package/dist/{motionShot-RECBNTBZ.js → motionShot-TXQ7EFJW.js} +16 -16
- package/dist/{normalize-audio-LKVGHZWR.js → normalize-audio-SFFU7VUW.js} +4 -4
- package/dist/{open-UEQVSRKH.js → open-2MY4ESCL.js} +11 -11
- package/dist/{parakeetRunner-QVPCZ36U.js → parakeetRunner-7UPEE7SO.js} +10 -10
- package/dist/{pipeline-5VSMQBKW.js → pipeline-VZMOR53B.js} +6 -6
- package/dist/{play-MNEABYN4.js → play-IOELJ2NM.js} +17 -17
- package/dist/{preflight-ONJ74DWQ.js → preflight-MGUBNYUV.js} +6 -6
- package/dist/{present-GQ24GTYX.js → present-7LOVKMN7.js} +13 -13
- package/dist/{preview-ALL7O4RG.js → preview-XN7YD5ZP.js} +16 -16
- package/dist/{producer-43L2UDF6.js → producer-BLRL4SQP.js} +1 -1
- package/dist/{projectConfig-VJXUXK7U.js → projectConfig-LN3NR5OM.js} +6 -6
- package/dist/{publication-L6E5NTFV.js → publication-TXMCS4KM.js} +2 -2
- package/dist/{publish-LCLBJEPR.js → publish-57VURD7Z.js} +7 -7
- package/dist/{remove-background-PDL4KPR4.js → remove-background-OOF3QB2R.js} +7 -7
- package/dist/{render-J33ZHR6I.js → render-E27W7W3K.js} +27 -27
- package/dist/{render-OPCRLZVL.js → render-IDI4KMVH.js} +12 -12
- package/dist/{render-7HVKJ7T4.js → render-SP7WAUB4.js} +5 -5
- package/dist/{render-batch-ZHHIGXU3.js → render-batch-7ULP5RIJ.js} +5 -5
- package/dist/{resolver-KNNIMMBM.js → resolver-D3XERO6U.js} +4 -4
- package/dist/{sherpa-GI62H3H5.js → sherpa-B7HLM6FV.js} +9 -9
- package/dist/skills/hyperframes/references/motion.md +1 -1
- package/dist/{skills-IUTD6VQO.js → skills-JASL5NGP.js} +5 -5
- package/dist/{skillsUpdateCheck-XZE7MJG6.js → skillsUpdateCheck-OTF363HZ.js} +3 -3
- package/dist/{snapshot-XEXTHLZP.js → snapshot-MWBENTZA.js} +31 -31
- package/dist/{src-ZPIV4PGX.js → src-65S55XOQ.js} +6 -4
- package/dist/{src-6STRGCDC.js → src-OGTPL3Q6.js} +6 -6
- package/dist/{staticProjectServer-HJLT7MHE.js → staticProjectServer-JMFGTPMX.js} +15 -13
- package/dist/studio/assets/{hyperframes-player-DwWIKKZG.js → hyperframes-player-BV6dTpsG.js} +1 -1
- package/dist/studio/assets/{index-CESvLzz0.css → index-B3vk3hfU.css} +1 -1
- package/dist/studio/assets/{index-Cjwz7_13.js → index-CPVUyhno.js} +1 -1
- package/dist/studio/assets/{index-M8lEpS0Q.js → index-Ct_WfjBH.js} +127 -127
- package/dist/studio/index.html +2 -2
- package/dist/{studio-api-OBHEB5ND.js → studio-api-SZ4OMFPN.js} +7 -7
- package/dist/{studioServer-KRIZFYML.js → studioServer-6JDUXBF7.js} +44 -44
- package/dist/{telemetry-N5OOVBCP.js → telemetry-R7QKFTNL.js} +3 -3
- package/dist/{timeline-YUFH65OG.js → timeline-GTUWGREV.js} +15 -15
- package/dist/{tokens-K4VYLSWJ.js → tokens-2JZSWS5F.js} +2 -2
- package/dist/{transcribe-CY4CVO54.js → transcribe-M7OSQ5OU.js} +14 -14
- package/dist/{transcribe-GMQXKDYN.js → transcribe-PSZC4HH6.js} +8 -8
- package/dist/{updateCheck-2625RXK4.js → updateCheck-Y4MKTYXE.js} +2 -2
- package/dist/{upgrade-6ZY5MSBQ.js → upgrade-WHEHL2KG.js} +2 -2
- package/dist/{urlDownloader-PVJWG7V3.js → urlDownloader-VN2X7CIY.js} +4 -4
- package/dist/{validate-XSRHEE7E.js → validate-TC66RN5I.js} +21 -21
- package/dist/{video-MBFHC54F.js → video-SNGPARSX.js} +5 -5
- package/dist/warmCheck.js +34 -35
- package/package.json +1 -1
- package/dist/chunk-BPX7LZG6.js +0 -3896
- package/dist/chunk-KANNRHY7.js +0 -53
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
renderFrameIdForRenderId,
|
|
27
27
|
resolveAuthoredTimingWindow,
|
|
28
28
|
toFps
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-56IOFIYB.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-DIV37NUE.js";
|
|
67
67
|
import {
|
|
68
68
|
clampAudioGain,
|
|
69
69
|
clipGain,
|
|
@@ -1090,7 +1090,6 @@ var BEGINFRAME_ONLY_FLAGS = /* @__PURE__ */ new Set([
|
|
|
1090
1090
|
function stripBeginFrameFlags(args) {
|
|
1091
1091
|
return args.filter((a) => !BEGINFRAME_ONLY_FLAGS.has(a));
|
|
1092
1092
|
}
|
|
1093
|
-
var BEGINFRAME_SCREENSHOT_PROBE_ATTEMPTS = 10;
|
|
1094
1093
|
var BEGINFRAME_PROBE_TIMEOUT_MS = 2e3;
|
|
1095
1094
|
var BEGINFRAME_PROBE_CLEANUP_TIMEOUT_MS = 250;
|
|
1096
1095
|
async function awaitBeforeDeadline(operation, deadline, label) {
|
|
@@ -1174,7 +1173,8 @@ async function probeBeginFrameSupport(browser, timeoutMs = BEGINFRAME_PROBE_TIME
|
|
|
1174
1173
|
let bytes = Buffer.alloc(0);
|
|
1175
1174
|
let isPng = false;
|
|
1176
1175
|
let attempts = 0;
|
|
1177
|
-
|
|
1176
|
+
while (!isPng && Date.now() < deadline) {
|
|
1177
|
+
attempts += 1;
|
|
1178
1178
|
const response = await awaitBeforeDeadline(
|
|
1179
1179
|
client.send("HeadlessExperimental.beginFrame", {
|
|
1180
1180
|
frameTimeTicks: 1e3 + (attempts - 1) * 33,
|
|
@@ -1187,7 +1187,7 @@ async function probeBeginFrameSupport(browser, timeoutMs = BEGINFRAME_PROBE_TIME
|
|
|
1187
1187
|
const screenshot = response.screenshotData ?? "";
|
|
1188
1188
|
bytes = screenshot ? Buffer.from(screenshot, "base64") : Buffer.alloc(0);
|
|
1189
1189
|
isPng = bytes.length >= 8 && bytes[0] === 137 && bytes[1] === 80 && bytes[2] === 78 && bytes[3] === 71;
|
|
1190
|
-
if (isPng) break;
|
|
1190
|
+
if (isPng || Date.now() + 10 >= deadline) break;
|
|
1191
1191
|
await awaitBeforeDeadline(
|
|
1192
1192
|
new Promise((resolveDelay) => setTimeout(resolveDelay, 10)),
|
|
1193
1193
|
deadline,
|
|
@@ -1196,7 +1196,7 @@ async function probeBeginFrameSupport(browser, timeoutMs = BEGINFRAME_PROBE_TIME
|
|
|
1196
1196
|
}
|
|
1197
1197
|
if (!isPng) {
|
|
1198
1198
|
throw new Error(
|
|
1199
|
-
`beginFrame screenshot returned ${bytes.length} bytes after ${
|
|
1199
|
+
`beginFrame screenshot returned ${bytes.length} bytes after ${attempts} attempts in ${Date.now() - started}ms with signature ${bytes.length >= 4 ? bytes.subarray(0, 4).toString("hex") : "<empty>"}`
|
|
1200
1200
|
);
|
|
1201
1201
|
}
|
|
1202
1202
|
await awaitBeforeDeadline(client.detach(), deadline, "CDP detach").catch(() => {
|
|
@@ -1691,6 +1691,24 @@ identically under Docker. Consider:
|
|
|
1691
1691
|
import { existsSync as existsSync3, mkdirSync, writeFileSync } from "fs";
|
|
1692
1692
|
import { join as join3 } from "path";
|
|
1693
1693
|
|
|
1694
|
+
// ../engine/src/services/renderFrameVideoHold.ts
|
|
1695
|
+
function holdRenderFrameVideos(ids, renderIdAttr) {
|
|
1696
|
+
const held = new Set(ids);
|
|
1697
|
+
window.__HF_RENDER_FRAME_VIDEO_IDS = ids;
|
|
1698
|
+
const hold = (el) => {
|
|
1699
|
+
if (el instanceof HTMLVideoElement && held.has(el.getAttribute(renderIdAttr) || el.id))
|
|
1700
|
+
el.preload = "none";
|
|
1701
|
+
};
|
|
1702
|
+
new MutationObserver((records) => {
|
|
1703
|
+
for (const record2 of records)
|
|
1704
|
+
for (const node of record2.addedNodes) {
|
|
1705
|
+
if (node.nodeType !== 1) continue;
|
|
1706
|
+
hold(node);
|
|
1707
|
+
for (const video of node.querySelectorAll("video")) hold(video);
|
|
1708
|
+
}
|
|
1709
|
+
}).observe(document, { childList: true, subtree: true });
|
|
1710
|
+
}
|
|
1711
|
+
|
|
1694
1712
|
// ../engine/src/services/drawElementCaptureError.ts
|
|
1695
1713
|
var DrawElementCaptureError = class extends Error {
|
|
1696
1714
|
frameIndex;
|
|
@@ -2548,15 +2566,17 @@ async function readPageMotionBlur(page) {
|
|
|
2548
2566
|
const report = api && typeof api === "object" ? Reflect.get(api, "report") : null;
|
|
2549
2567
|
const got = typeof report === "function" ? report() : null;
|
|
2550
2568
|
if (!got || typeof got !== "object") return null;
|
|
2569
|
+
const tier = Reflect.get(got, "tier");
|
|
2551
2570
|
return {
|
|
2552
2571
|
state: String(Reflect.get(got, "state")),
|
|
2553
2572
|
code: String(Reflect.get(got, "reasonCode")),
|
|
2554
2573
|
movers: Number(Reflect.get(got, "movers")),
|
|
2555
|
-
failedFrames: Number(Reflect.get(got, "failedFrames")) || 0
|
|
2574
|
+
failedFrames: Number(Reflect.get(got, "failedFrames")) || 0,
|
|
2575
|
+
tier: typeof tier === "string" ? tier : null
|
|
2556
2576
|
};
|
|
2557
2577
|
});
|
|
2558
2578
|
}
|
|
2559
|
-
var formatPageMotionBlur = (r) => `[motion-blur] ${r.state} reasonCode=${r.code} movers=${r.movers} failedFrames=${r.failedFrames}`;
|
|
2579
|
+
var formatPageMotionBlur = (r) => `[motion-blur] ${r.state} reasonCode=${r.code} movers=${r.movers} failedFrames=${r.failedFrames}${r.tier ? ` tier=${r.tier}` : ""}`;
|
|
2560
2580
|
async function describePageMotionBlur(page) {
|
|
2561
2581
|
const r = await readPageMotionBlur(page);
|
|
2562
2582
|
return r && formatPageMotionBlur(r);
|
|
@@ -5488,6 +5508,13 @@ async function constructCaptureSession(input) {
|
|
|
5488
5508
|
}
|
|
5489
5509
|
});
|
|
5490
5510
|
await installMediaRenderIdBridge(page);
|
|
5511
|
+
if (options.skipReadinessVideoIds?.length) {
|
|
5512
|
+
await page.evaluateOnNewDocument(
|
|
5513
|
+
holdRenderFrameVideos,
|
|
5514
|
+
options.skipReadinessVideoIds,
|
|
5515
|
+
MEDIA_RENDER_ID_ATTR
|
|
5516
|
+
);
|
|
5517
|
+
}
|
|
5491
5518
|
if (useDrawElement) {
|
|
5492
5519
|
await page.evaluateOnNewDocument(instrumentAcceleratedCanvases);
|
|
5493
5520
|
}
|
|
@@ -8993,6 +9020,14 @@ async function analyzeKeyframeIntervalsUncached(filePath, videoStreamStartSecond
|
|
|
8993
9020
|
};
|
|
8994
9021
|
}
|
|
8995
9022
|
|
|
9023
|
+
// ../engine/src/services/softwareEncoderThreads.ts
|
|
9024
|
+
import { availableParallelism } from "os";
|
|
9025
|
+
var X265_MAX_THREADS = 16;
|
|
9026
|
+
function appendSoftwareEncoderThreadsArg(args, encoder, parallelism = availableParallelism()) {
|
|
9027
|
+
const cap = encoder === "libx265" ? X265_MAX_THREADS : Infinity;
|
|
9028
|
+
args.push("-threads", String(Math.min(cap, Math.max(1, Math.floor(parallelism)))));
|
|
9029
|
+
}
|
|
9030
|
+
|
|
8996
9031
|
// ../engine/src/utils/renderProvenance.ts
|
|
8997
9032
|
import { readFileSync as readFileSync2 } from "fs";
|
|
8998
9033
|
import { dirname, join as join5 } from "path";
|
|
@@ -9217,6 +9252,7 @@ function buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder = null) {
|
|
|
9217
9252
|
} else {
|
|
9218
9253
|
const encoderName = codec === "h264" ? "libx264" : "libx265";
|
|
9219
9254
|
args.push("-c:v", encoderName, "-preset", preset);
|
|
9255
|
+
appendSoftwareEncoderThreadsArg(args, encoderName);
|
|
9220
9256
|
if (bitrate) args.push("-b:v", bitrate);
|
|
9221
9257
|
else args.push("-crf", String(quality));
|
|
9222
9258
|
const gop = resolveLockedGopSize(options);
|
|
@@ -9921,6 +9957,7 @@ function buildStreamingArgs(options, outputPath, gpuEncoder = null) {
|
|
|
9921
9957
|
} else {
|
|
9922
9958
|
const encoderName = codec === "h264" ? "libx264" : "libx265";
|
|
9923
9959
|
args.push("-c:v", encoderName, "-preset", preset);
|
|
9960
|
+
appendSoftwareEncoderThreadsArg(args, encoderName);
|
|
9924
9961
|
if (bitrate) args.push("-b:v", bitrate);
|
|
9925
9962
|
else args.push("-crf", String(quality));
|
|
9926
9963
|
const lockedGop = resolveLockedGopSize(options);
|
|
@@ -12472,6 +12509,7 @@ function resolveVideoExtractionDuration(video, metadata, timelineEnd) {
|
|
|
12472
12509
|
return resolveVideoExtractionWindow(video, metadata, timelineEnd).durationSeconds;
|
|
12473
12510
|
}
|
|
12474
12511
|
var ALPHA_CAPABLE_CODECS = /* @__PURE__ */ new Set(["vp9", "vp8", "prores"]);
|
|
12512
|
+
var SIDECAR_ALPHA_CODECS = /* @__PURE__ */ new Set(["vp9", "vp8"]);
|
|
12475
12513
|
function codecMayHaveAlpha(codec) {
|
|
12476
12514
|
return ALPHA_CAPABLE_CODECS.has((codec ?? "").toLowerCase());
|
|
12477
12515
|
}
|
|
@@ -12479,7 +12517,8 @@ function decoderForCodec(codec) {
|
|
|
12479
12517
|
return alphaDecoderFor(codec) ?? (codec ?? "").toLowerCase();
|
|
12480
12518
|
}
|
|
12481
12519
|
function resolveFrameFormat(metadata, requested) {
|
|
12482
|
-
if (metadata.hasAlpha ||
|
|
12520
|
+
if (metadata.hasAlpha || SIDECAR_ALPHA_CODECS.has((metadata.videoCodec ?? "").toLowerCase()))
|
|
12521
|
+
return "png";
|
|
12483
12522
|
if (requested === "png" || requested === "jpg") return requested;
|
|
12484
12523
|
return "jpg";
|
|
12485
12524
|
}
|
|
@@ -14011,6 +14050,9 @@ function clampFadesToDuration(fades, duration) {
|
|
|
14011
14050
|
return { fadeIn: fadeIn * scale, fadeOut: fadeOut * scale };
|
|
14012
14051
|
}
|
|
14013
14052
|
|
|
14053
|
+
// ../engine/src/services/audioMixer.ts
|
|
14054
|
+
import { cpus as cpus2 } from "os";
|
|
14055
|
+
|
|
14014
14056
|
// ../engine/src/services/aacEncode.ts
|
|
14015
14057
|
import { mkdtempSync as mkdtempSync4, readFileSync as readFileSync5, rmSync as rmSync5, writeFileSync as writeFileSync4 } from "fs";
|
|
14016
14058
|
import { dirname as dirname5, join as join11 } from "path";
|
|
@@ -15126,6 +15168,7 @@ function escapeExpressionCommas(expression) {
|
|
|
15126
15168
|
function legacyFilterScriptOptionIsUnsupported(stderr) {
|
|
15127
15169
|
return /filter_complex_script/i.test(stderr) && /(?:unrecognized option|option (?:was )?not found)/i.test(stderr);
|
|
15128
15170
|
}
|
|
15171
|
+
var inPrepareSlot = createConcurrencyLimit(Math.max(2, Math.floor(cpus2().length / 2)));
|
|
15129
15172
|
var MAX_VOLUME_SEGMENTS = 32;
|
|
15130
15173
|
var VOLUME_SIMPLIFY_EPSILON = 5e-3;
|
|
15131
15174
|
var STEREO_CHANNEL_FILTER = "pan=stereo|FL=FL+FC|FR=FR+FC";
|
|
@@ -15239,7 +15282,8 @@ function boundedDetail(message, maxLength = 2e3) {
|
|
|
15239
15282
|
/(^|[\s"'(])\/.+?(?=:\s[A-Z]|\s(?:ENOENT|EACCES|EPERM)\b|\r?$)/gm,
|
|
15240
15283
|
"$1<redacted-path>"
|
|
15241
15284
|
);
|
|
15242
|
-
|
|
15285
|
+
const head = Math.floor(maxLength / 4);
|
|
15286
|
+
return redacted.length <= maxLength ? redacted : `${redacted.slice(0, head)}\u2026${redacted.slice(-(maxLength - head - 1))}`;
|
|
15243
15287
|
}
|
|
15244
15288
|
function probeFailure(message, elementId) {
|
|
15245
15289
|
const unavailable = /(?:not found|ENOENT|spawn)/i.test(message);
|
|
@@ -15303,7 +15347,7 @@ function ffmpegFailure(stage, result, timeoutMs, elementId) {
|
|
|
15303
15347
|
elementId,
|
|
15304
15348
|
subprocess: audioSubprocessEvidence(result),
|
|
15305
15349
|
detail: boundedDetail(
|
|
15306
|
-
result.error?.message ? `${describeFfmpegFailure(result, timeoutMs)}: ${result.error.message}` : describeFfmpegFailure(result, timeoutMs)
|
|
15350
|
+
`(ran ${result.durationMs} ms, limit ${timeoutMs} ms) ` + (result.error?.message ? `${describeFfmpegFailure(result, timeoutMs)}: ${result.error.message}` : describeFfmpegFailure(result, timeoutMs))
|
|
15307
15351
|
)
|
|
15308
15352
|
};
|
|
15309
15353
|
}
|
|
@@ -15500,8 +15544,13 @@ async function generateSilence(outputPath, duration, signal, config) {
|
|
|
15500
15544
|
failure
|
|
15501
15545
|
};
|
|
15502
15546
|
}
|
|
15503
|
-
|
|
15504
|
-
|
|
15547
|
+
var MIX_TIMEOUT_MS_PER_FILM_SECOND = 100;
|
|
15548
|
+
function mixProcessTimeout(config, totalDuration) {
|
|
15549
|
+
const configured = config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG.ffmpegProcessTimeout;
|
|
15550
|
+
return Math.max(configured, Math.ceil(totalDuration * MIX_TIMEOUT_MS_PER_FILM_SECOND));
|
|
15551
|
+
}
|
|
15552
|
+
async function mixAudioTracksFlat(tracks, outputPath, totalDuration, signal, config) {
|
|
15553
|
+
const ffmpegProcessTimeout = mixProcessTimeout(config, totalDuration);
|
|
15505
15554
|
const masterOutputGain = config?.audioGain ?? DEFAULT_CONFIG.audioGain;
|
|
15506
15555
|
if (tracks.length === 0) {
|
|
15507
15556
|
const result2 = await generateSilence(outputPath, totalDuration, signal, config);
|
|
@@ -15621,8 +15670,8 @@ async function mixAudioTracks(tracks, outputPath, totalDuration, signal, config)
|
|
|
15621
15670
|
function groupNormalizeOptionUnsupported(stderr) {
|
|
15622
15671
|
return /normalize/i.test(stderr) && /(?:unrecognized option|option (?:was )?not found|no option name)/i.test(stderr);
|
|
15623
15672
|
}
|
|
15624
|
-
async function
|
|
15625
|
-
const ffmpegProcessTimeout = config
|
|
15673
|
+
async function mixGroupMembersFlat(memberTracks, outputPath, totalDuration, signal, config) {
|
|
15674
|
+
const ffmpegProcessTimeout = mixProcessTimeout(config, totalDuration);
|
|
15626
15675
|
const outputDir = dirname7(outputPath);
|
|
15627
15676
|
if (!existsSync11(outputDir)) mkdirSync7(outputDir, { recursive: true });
|
|
15628
15677
|
const buildInputFilters = (ignoreKeyframes, padMembers) => memberTracks.map((track, i) => {
|
|
@@ -15707,6 +15756,100 @@ async function mixGroupMembers(memberTracks, outputPath, totalDuration, signal,
|
|
|
15707
15756
|
}
|
|
15708
15757
|
return { success: true, degradedAutomation };
|
|
15709
15758
|
}
|
|
15759
|
+
var MAX_MIX_INPUTS = 96;
|
|
15760
|
+
async function sumInSlices(tracks, scratchDir, totalDuration, signal, config) {
|
|
15761
|
+
const wavTrack = (id, srcPath) => ({
|
|
15762
|
+
id,
|
|
15763
|
+
srcPath,
|
|
15764
|
+
start: 0,
|
|
15765
|
+
end: totalDuration,
|
|
15766
|
+
mediaStart: 0,
|
|
15767
|
+
duration: totalDuration,
|
|
15768
|
+
volume: 1
|
|
15769
|
+
});
|
|
15770
|
+
let running = null;
|
|
15771
|
+
let degradedAutomation = false;
|
|
15772
|
+
for (let at = 0; at < tracks.length; at += MAX_MIX_INPUTS) {
|
|
15773
|
+
const id = `sum-${at / MAX_MIX_INPUTS}`;
|
|
15774
|
+
const slicePath = join14(scratchDir, `${id}-slice.wav`);
|
|
15775
|
+
const slice = await mixGroupMembersFlat(
|
|
15776
|
+
tracks.slice(at, at + MAX_MIX_INPUTS),
|
|
15777
|
+
slicePath,
|
|
15778
|
+
totalDuration,
|
|
15779
|
+
signal,
|
|
15780
|
+
config
|
|
15781
|
+
);
|
|
15782
|
+
if (!slice.success) return slice;
|
|
15783
|
+
degradedAutomation ||= slice.degradedAutomation === true;
|
|
15784
|
+
if (!running) {
|
|
15785
|
+
running = wavTrack(id, slicePath);
|
|
15786
|
+
continue;
|
|
15787
|
+
}
|
|
15788
|
+
const foldedPath = join14(scratchDir, `${id}.wav`);
|
|
15789
|
+
const folded = await mixGroupMembersFlat(
|
|
15790
|
+
[running, wavTrack(`${id}-slice`, slicePath)],
|
|
15791
|
+
foldedPath,
|
|
15792
|
+
totalDuration,
|
|
15793
|
+
signal,
|
|
15794
|
+
config
|
|
15795
|
+
);
|
|
15796
|
+
rmSync8(running.srcPath, { force: true });
|
|
15797
|
+
rmSync8(slicePath, { force: true });
|
|
15798
|
+
if (!folded.success) return folded;
|
|
15799
|
+
running = wavTrack(id, foldedPath);
|
|
15800
|
+
}
|
|
15801
|
+
if (!running) throw new Error("[audioMixer] sumInSlices needs at least one track");
|
|
15802
|
+
return { success: true, track: running, degradedAutomation };
|
|
15803
|
+
}
|
|
15804
|
+
async function mixGroupMembers(memberTracks, outputPath, totalDuration, signal, config) {
|
|
15805
|
+
if (memberTracks.length <= MAX_MIX_INPUTS) {
|
|
15806
|
+
return mixGroupMembersFlat(memberTracks, outputPath, totalDuration, signal, config);
|
|
15807
|
+
}
|
|
15808
|
+
mkdirSync7(dirname7(outputPath), { recursive: true });
|
|
15809
|
+
const scratchDir = mkdtempSync7(join14(dirname7(outputPath), ".mix-batches-"));
|
|
15810
|
+
try {
|
|
15811
|
+
const summed = await sumInSlices(memberTracks, scratchDir, totalDuration, signal, config);
|
|
15812
|
+
if (!summed.success) return summed;
|
|
15813
|
+
renameSync3(summed.track.srcPath, outputPath);
|
|
15814
|
+
return { success: true, degradedAutomation: summed.degradedAutomation };
|
|
15815
|
+
} finally {
|
|
15816
|
+
rmSync8(scratchDir, { recursive: true, force: true });
|
|
15817
|
+
}
|
|
15818
|
+
}
|
|
15819
|
+
async function mixAudioTracks(tracks, outputPath, totalDuration, signal, config) {
|
|
15820
|
+
if (tracks.length <= MAX_MIX_INPUTS) {
|
|
15821
|
+
return mixAudioTracksFlat(tracks, outputPath, totalDuration, signal, config);
|
|
15822
|
+
}
|
|
15823
|
+
mkdirSync7(dirname7(outputPath), { recursive: true });
|
|
15824
|
+
const scratchDir = mkdtempSync7(join14(dirname7(outputPath), ".mix-batches-"));
|
|
15825
|
+
try {
|
|
15826
|
+
const summed = await sumInSlices(tracks, scratchDir, totalDuration, signal, config);
|
|
15827
|
+
if (!summed.success) {
|
|
15828
|
+
return {
|
|
15829
|
+
success: false,
|
|
15830
|
+
outputPath,
|
|
15831
|
+
durationMs: 0,
|
|
15832
|
+
tracksProcessed: 0,
|
|
15833
|
+
error: summed.error,
|
|
15834
|
+
failures: [summed.failure]
|
|
15835
|
+
};
|
|
15836
|
+
}
|
|
15837
|
+
const mixed = await mixAudioTracksFlat(
|
|
15838
|
+
[summed.track],
|
|
15839
|
+
outputPath,
|
|
15840
|
+
totalDuration,
|
|
15841
|
+
signal,
|
|
15842
|
+
config
|
|
15843
|
+
);
|
|
15844
|
+
return mixed.success ? {
|
|
15845
|
+
...mixed,
|
|
15846
|
+
tracksProcessed: tracks.length,
|
|
15847
|
+
error: summed.degradedAutomation ? "Volume automation exceeded this ffmpeg build's expression limits; rendered at base volume" : mixed.error
|
|
15848
|
+
} : mixed;
|
|
15849
|
+
} finally {
|
|
15850
|
+
rmSync8(scratchDir, { recursive: true, force: true });
|
|
15851
|
+
}
|
|
15852
|
+
}
|
|
15710
15853
|
async function mixThroughFloatSum(tracks, masterChain, outputPath, workDir, totalDuration, signal, config) {
|
|
15711
15854
|
const sumPath = join14(workDir, "master-sum.wav");
|
|
15712
15855
|
const sum = await mixAudioTracks(tracks, sumPath, totalDuration, signal, config);
|
|
@@ -15752,216 +15895,220 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
15752
15895
|
else signal.addEventListener("abort", () => internalController.abort(), { once: true });
|
|
15753
15896
|
}
|
|
15754
15897
|
await Promise.all(
|
|
15755
|
-
elements.map(
|
|
15756
|
-
|
|
15757
|
-
|
|
15758
|
-
stage: "cancelled",
|
|
15759
|
-
reason: "cancelled",
|
|
15760
|
-
owner: "user",
|
|
15761
|
-
retryable: false,
|
|
15762
|
-
elementId: element.id,
|
|
15763
|
-
detail: boundedDetail(`Cancelled audio element ${element.id}`)
|
|
15764
|
-
});
|
|
15765
|
-
return;
|
|
15766
|
-
}
|
|
15767
|
-
try {
|
|
15768
|
-
let srcPath = element.src;
|
|
15769
|
-
let readInPlace = false;
|
|
15770
|
-
if (!isHttpUrl(srcPath)) {
|
|
15771
|
-
srcPath = resolveProjectRelativeSrc(element.src, baseDir, compiledDir);
|
|
15772
|
-
const remoteUrl = config?.urlByAbsentLocalPath?.get(srcPath);
|
|
15773
|
-
if (remoteUrl) {
|
|
15774
|
-
srcPath = remoteUrl;
|
|
15775
|
-
readInPlace = true;
|
|
15776
|
-
}
|
|
15777
|
-
}
|
|
15778
|
-
if (isHttpUrl(srcPath) && !readInPlace) {
|
|
15779
|
-
try {
|
|
15780
|
-
srcPath = await downloadToTemp(
|
|
15781
|
-
srcPath,
|
|
15782
|
-
workDir,
|
|
15783
|
-
void 0,
|
|
15784
|
-
effectiveSignal,
|
|
15785
|
-
void 0,
|
|
15786
|
-
{
|
|
15787
|
-
onTelemetry: writeUrlDownloadTelemetry
|
|
15788
|
-
}
|
|
15789
|
-
);
|
|
15790
|
-
} catch (err) {
|
|
15791
|
-
failures.push(downloadFailure(err, element.id));
|
|
15792
|
-
return;
|
|
15793
|
-
}
|
|
15794
|
-
}
|
|
15795
|
-
if (!readInPlace && !existsSync11(srcPath)) {
|
|
15898
|
+
elements.map(
|
|
15899
|
+
(element, index) => inPrepareSlot(async () => {
|
|
15900
|
+
if (effectiveSignal.aborted) {
|
|
15796
15901
|
failures.push({
|
|
15797
|
-
stage: "
|
|
15798
|
-
reason: "
|
|
15902
|
+
stage: "cancelled",
|
|
15903
|
+
reason: "cancelled",
|
|
15799
15904
|
owner: "user",
|
|
15800
15905
|
retryable: false,
|
|
15801
15906
|
elementId: element.id,
|
|
15802
|
-
detail: boundedDetail(
|
|
15907
|
+
detail: boundedDetail(`Cancelled audio element ${element.id}`)
|
|
15803
15908
|
});
|
|
15804
15909
|
return;
|
|
15805
15910
|
}
|
|
15806
|
-
|
|
15807
|
-
|
|
15808
|
-
|
|
15809
|
-
|
|
15810
|
-
|
|
15811
|
-
|
|
15812
|
-
|
|
15813
|
-
|
|
15814
|
-
|
|
15815
|
-
|
|
15816
|
-
}
|
|
15817
|
-
|
|
15818
|
-
|
|
15819
|
-
|
|
15820
|
-
|
|
15821
|
-
|
|
15822
|
-
|
|
15911
|
+
try {
|
|
15912
|
+
let srcPath = element.src;
|
|
15913
|
+
let readInPlace = false;
|
|
15914
|
+
if (!isHttpUrl(srcPath)) {
|
|
15915
|
+
srcPath = resolveProjectRelativeSrc(element.src, baseDir, compiledDir);
|
|
15916
|
+
const remoteUrl = config?.urlByAbsentLocalPath?.get(srcPath);
|
|
15917
|
+
if (remoteUrl) {
|
|
15918
|
+
srcPath = remoteUrl;
|
|
15919
|
+
readInPlace = true;
|
|
15920
|
+
}
|
|
15921
|
+
}
|
|
15922
|
+
if (isHttpUrl(srcPath) && !readInPlace) {
|
|
15923
|
+
try {
|
|
15924
|
+
srcPath = await downloadToTemp(
|
|
15925
|
+
srcPath,
|
|
15926
|
+
workDir,
|
|
15927
|
+
void 0,
|
|
15928
|
+
effectiveSignal,
|
|
15929
|
+
void 0,
|
|
15930
|
+
{
|
|
15931
|
+
onTelemetry: writeUrlDownloadTelemetry
|
|
15932
|
+
}
|
|
15933
|
+
);
|
|
15934
|
+
} catch (err) {
|
|
15935
|
+
failures.push(downloadFailure(err, element.id));
|
|
15936
|
+
return;
|
|
15937
|
+
}
|
|
15938
|
+
}
|
|
15939
|
+
if (!readInPlace && !existsSync11(srcPath)) {
|
|
15940
|
+
failures.push({
|
|
15941
|
+
stage: "source",
|
|
15942
|
+
reason: "source_not_found",
|
|
15943
|
+
owner: "user",
|
|
15944
|
+
retryable: false,
|
|
15945
|
+
elementId: element.id,
|
|
15946
|
+
detail: boundedDetail(
|
|
15947
|
+
missingSourceMessage(element.id, element.src, baseDir, srcPath)
|
|
15948
|
+
)
|
|
15949
|
+
});
|
|
15950
|
+
return;
|
|
15951
|
+
}
|
|
15952
|
+
if (await isNotMediaPayload(srcPath)) {
|
|
15953
|
+
failures.push({
|
|
15954
|
+
stage: "source",
|
|
15955
|
+
reason: "invalid_media",
|
|
15956
|
+
owner: "user",
|
|
15957
|
+
retryable: false,
|
|
15958
|
+
elementId: element.id,
|
|
15959
|
+
detail: boundedDetail(
|
|
15960
|
+
`Audio element ${element.id} source is a text document (HTML/XML/JSON), not media`
|
|
15961
|
+
)
|
|
15962
|
+
});
|
|
15963
|
+
return;
|
|
15964
|
+
}
|
|
15965
|
+
if (element.end - element.start <= 0) {
|
|
15966
|
+
let metadata;
|
|
15967
|
+
try {
|
|
15968
|
+
metadata = await extractAudioMetadata(
|
|
15969
|
+
srcPath,
|
|
15970
|
+
readInPlace ? { signal: effectiveSignal } : void 0
|
|
15971
|
+
);
|
|
15972
|
+
} catch (err) {
|
|
15973
|
+
failures.push(
|
|
15974
|
+
probeFailure(err instanceof Error ? err.message : String(err), element.id)
|
|
15975
|
+
);
|
|
15976
|
+
return;
|
|
15977
|
+
}
|
|
15978
|
+
const effectiveDuration = timeAtSourceTime(
|
|
15979
|
+
normalizeRateSpec(element.playbackRate),
|
|
15980
|
+
metadata.durationSeconds - element.mediaStart
|
|
15981
|
+
);
|
|
15982
|
+
element.end = element.start + (effectiveDuration > 0 ? effectiveDuration : metadata.durationSeconds);
|
|
15983
|
+
}
|
|
15984
|
+
let audioSrcPath = srcPath;
|
|
15985
|
+
if (element.type === "video") {
|
|
15986
|
+
const extractedPath = join14(workDir, `${element.id}-extracted.wav`);
|
|
15987
|
+
const extractResult = await extractAudioSegment(
|
|
15823
15988
|
srcPath,
|
|
15824
|
-
|
|
15989
|
+
extractedPath,
|
|
15990
|
+
"extract",
|
|
15991
|
+
element.mediaStart,
|
|
15992
|
+
element.end - element.start,
|
|
15993
|
+
element.playbackRate,
|
|
15994
|
+
effectiveSignal,
|
|
15995
|
+
config
|
|
15825
15996
|
);
|
|
15826
|
-
|
|
15827
|
-
|
|
15828
|
-
|
|
15997
|
+
if (!extractResult.success) {
|
|
15998
|
+
failures.push(
|
|
15999
|
+
extractResult.failure ? { ...extractResult.failure, elementId: element.id } : {
|
|
16000
|
+
stage: "extract",
|
|
16001
|
+
reason: "ffmpeg_failed",
|
|
16002
|
+
owner: "system",
|
|
16003
|
+
retryable: false,
|
|
16004
|
+
elementId: element.id,
|
|
16005
|
+
detail: boundedDetail(`Audio extract failed for element ${element.id}`)
|
|
16006
|
+
}
|
|
16007
|
+
);
|
|
16008
|
+
return;
|
|
16009
|
+
}
|
|
16010
|
+
audioSrcPath = extractedPath;
|
|
16011
|
+
} else {
|
|
16012
|
+
const trimmedPath = join14(workDir, `${element.id}-trimmed.wav`);
|
|
16013
|
+
const prepResult = await extractAudioSegment(
|
|
16014
|
+
srcPath,
|
|
16015
|
+
trimmedPath,
|
|
16016
|
+
"prepare",
|
|
16017
|
+
element.mediaStart,
|
|
16018
|
+
element.end - element.start,
|
|
16019
|
+
element.playbackRate,
|
|
16020
|
+
effectiveSignal,
|
|
16021
|
+
config
|
|
15829
16022
|
);
|
|
15830
|
-
|
|
16023
|
+
if (!prepResult.success) {
|
|
16024
|
+
failures.push(
|
|
16025
|
+
prepResult.failure ? { ...prepResult.failure, elementId: element.id } : {
|
|
16026
|
+
stage: "prepare",
|
|
16027
|
+
reason: "ffmpeg_failed",
|
|
16028
|
+
owner: "system",
|
|
16029
|
+
retryable: false,
|
|
16030
|
+
elementId: element.id,
|
|
16031
|
+
detail: boundedDetail(`Audio prepare failed for element ${element.id}`)
|
|
16032
|
+
}
|
|
16033
|
+
);
|
|
16034
|
+
return;
|
|
16035
|
+
}
|
|
16036
|
+
audioSrcPath = trimmedPath;
|
|
15831
16037
|
}
|
|
15832
|
-
const
|
|
15833
|
-
|
|
15834
|
-
|
|
15835
|
-
|
|
15836
|
-
|
|
15837
|
-
|
|
15838
|
-
let audioSrcPath = srcPath;
|
|
15839
|
-
if (element.type === "video") {
|
|
15840
|
-
const extractedPath = join14(workDir, `${element.id}-extracted.wav`);
|
|
15841
|
-
const extractResult = await extractAudioSegment(
|
|
15842
|
-
srcPath,
|
|
15843
|
-
extractedPath,
|
|
15844
|
-
"extract",
|
|
15845
|
-
element.mediaStart,
|
|
16038
|
+
const chain = element.fxChain ? parseAudioFxChain(element.fxChain) : void 0;
|
|
16039
|
+
const automation = element.automation ? resolveAutomation(parseAutomation(element.automation), chain) : null;
|
|
16040
|
+
const gainBeforeFx = chain !== void 0 && enabledAudioFxNodes(chain).length > 0;
|
|
16041
|
+
const laneKeyframes = automation ? volumeLaneKeyframes(
|
|
16042
|
+
automation,
|
|
16043
|
+
element.start,
|
|
15846
16044
|
element.end - element.start,
|
|
15847
|
-
element.
|
|
15848
|
-
|
|
15849
|
-
|
|
15850
|
-
);
|
|
15851
|
-
|
|
15852
|
-
|
|
15853
|
-
|
|
15854
|
-
|
|
15855
|
-
|
|
15856
|
-
|
|
15857
|
-
|
|
15858
|
-
|
|
15859
|
-
|
|
16045
|
+
element.volume ?? 1,
|
|
16046
|
+
gainBeforeFx
|
|
16047
|
+
) : null;
|
|
16048
|
+
const tweened = !laneKeyframes && (element.volumeKeyframes?.length ?? 0) > 0;
|
|
16049
|
+
const envelopeKeyframes = laneKeyframes ?? element.volumeKeyframes;
|
|
16050
|
+
const envelope = envelopeKeyframes && envelopeKeyframes.length > 0 ? {
|
|
16051
|
+
keyframes: envelopeKeyframes,
|
|
16052
|
+
trackStart: element.start,
|
|
16053
|
+
baseVolume: element.volume ?? 1
|
|
16054
|
+
} : null;
|
|
16055
|
+
let bakedEnvelope = false;
|
|
16056
|
+
let tailSeconds = 0;
|
|
16057
|
+
if (chain) {
|
|
16058
|
+
tailSeconds = chainTailSeconds(chain, automation ?? void 0);
|
|
16059
|
+
const fxResult = await applyAudioFxChain(
|
|
16060
|
+
audioSrcPath,
|
|
16061
|
+
chain,
|
|
16062
|
+
join14(workDir, `${element.id}-fx.wav`),
|
|
16063
|
+
{
|
|
16064
|
+
trackId: element.id,
|
|
16065
|
+
signal: effectiveSignal,
|
|
16066
|
+
...automation ? { automation } : {},
|
|
16067
|
+
...envelope ? { envelope } : {},
|
|
16068
|
+
...gainBeforeFx ? { inputGain: clipGain(element.volume ?? 1, tweened) } : {}
|
|
15860
16069
|
}
|
|
15861
16070
|
);
|
|
15862
|
-
|
|
16071
|
+
audioSrcPath = fxResult.path;
|
|
16072
|
+
bakedEnvelope = fxResult.envelopeBaked;
|
|
15863
16073
|
}
|
|
15864
|
-
|
|
15865
|
-
|
|
15866
|
-
|
|
15867
|
-
|
|
15868
|
-
|
|
15869
|
-
|
|
15870
|
-
"prepare",
|
|
15871
|
-
element.mediaStart,
|
|
15872
|
-
element.end - element.start,
|
|
15873
|
-
element.playbackRate,
|
|
15874
|
-
effectiveSignal,
|
|
15875
|
-
config
|
|
15876
|
-
);
|
|
15877
|
-
if (!prepResult.success) {
|
|
15878
|
-
failures.push(
|
|
15879
|
-
prepResult.failure ? { ...prepResult.failure, elementId: element.id } : {
|
|
15880
|
-
stage: "prepare",
|
|
15881
|
-
reason: "ffmpeg_failed",
|
|
15882
|
-
owner: "system",
|
|
15883
|
-
retryable: false,
|
|
15884
|
-
elementId: element.id,
|
|
15885
|
-
detail: boundedDetail(`Audio prepare failed for element ${element.id}`)
|
|
15886
|
-
}
|
|
16074
|
+
if (envelope && !bakedEnvelope) {
|
|
16075
|
+
bakedEnvelope = applyVolumeEnvelopeToWav(
|
|
16076
|
+
audioSrcPath,
|
|
16077
|
+
envelope.keyframes,
|
|
16078
|
+
envelope.trackStart,
|
|
16079
|
+
envelope.baseVolume
|
|
15887
16080
|
);
|
|
15888
|
-
return;
|
|
15889
16081
|
}
|
|
15890
|
-
|
|
15891
|
-
|
|
15892
|
-
|
|
15893
|
-
|
|
15894
|
-
|
|
15895
|
-
|
|
15896
|
-
|
|
15897
|
-
|
|
15898
|
-
|
|
15899
|
-
|
|
15900
|
-
|
|
15901
|
-
|
|
15902
|
-
|
|
15903
|
-
|
|
15904
|
-
|
|
15905
|
-
|
|
15906
|
-
|
|
15907
|
-
|
|
15908
|
-
|
|
15909
|
-
|
|
15910
|
-
|
|
15911
|
-
|
|
15912
|
-
|
|
15913
|
-
|
|
15914
|
-
|
|
15915
|
-
|
|
15916
|
-
|
|
15917
|
-
{
|
|
15918
|
-
trackId: element.id,
|
|
15919
|
-
signal: effectiveSignal,
|
|
15920
|
-
...automation ? { automation } : {},
|
|
15921
|
-
...envelope ? { envelope } : {},
|
|
15922
|
-
...gainBeforeFx ? { inputGain: clipGain(element.volume ?? 1, tweened) } : {}
|
|
15923
|
-
}
|
|
15924
|
-
);
|
|
15925
|
-
audioSrcPath = fxResult.path;
|
|
15926
|
-
bakedEnvelope = fxResult.envelopeBaked;
|
|
15927
|
-
}
|
|
15928
|
-
if (envelope && !bakedEnvelope) {
|
|
15929
|
-
bakedEnvelope = applyVolumeEnvelopeToWav(
|
|
15930
|
-
audioSrcPath,
|
|
15931
|
-
envelope.keyframes,
|
|
15932
|
-
envelope.trackStart,
|
|
15933
|
-
envelope.baseVolume
|
|
15934
|
-
);
|
|
16082
|
+
const track = {
|
|
16083
|
+
id: element.id,
|
|
16084
|
+
srcPath: audioSrcPath,
|
|
16085
|
+
start: element.start,
|
|
16086
|
+
end: element.end,
|
|
16087
|
+
mediaStart: element.mediaStart,
|
|
16088
|
+
duration: element.end - element.start,
|
|
16089
|
+
// Gain is already in the samples when baked, so mix at unity.
|
|
16090
|
+
volume: bakedEnvelope || gainBeforeFx && !tweened ? 1 : element.volume ?? 1,
|
|
16091
|
+
volumeKeyframes: bakedEnvelope ? void 0 : envelopeKeyframes ?? void 0,
|
|
16092
|
+
...element.fadeIn ? { fadeIn: element.fadeIn } : {},
|
|
16093
|
+
...element.fadeOut ? { fadeOut: element.fadeOut } : {},
|
|
16094
|
+
...tailSeconds > 0 ? { tailSeconds } : {}
|
|
16095
|
+
};
|
|
16096
|
+
preparedTracks[index] = track;
|
|
16097
|
+
} catch (err) {
|
|
16098
|
+
if (err instanceof AudioFxRenderError) throw err;
|
|
16099
|
+
failures.push({
|
|
16100
|
+
stage: "internal",
|
|
16101
|
+
reason: "internal",
|
|
16102
|
+
owner: "system",
|
|
16103
|
+
retryable: false,
|
|
16104
|
+
elementId: element.id,
|
|
16105
|
+
detail: boundedDetail(
|
|
16106
|
+
`Audio processing failed for element ${element.id}: ${err instanceof Error ? err.message : String(err)}`
|
|
16107
|
+
)
|
|
16108
|
+
});
|
|
15935
16109
|
}
|
|
15936
|
-
|
|
15937
|
-
|
|
15938
|
-
srcPath: audioSrcPath,
|
|
15939
|
-
start: element.start,
|
|
15940
|
-
end: element.end,
|
|
15941
|
-
mediaStart: element.mediaStart,
|
|
15942
|
-
duration: element.end - element.start,
|
|
15943
|
-
// Gain is already in the samples when baked, so mix at unity.
|
|
15944
|
-
volume: bakedEnvelope || gainBeforeFx && !tweened ? 1 : element.volume ?? 1,
|
|
15945
|
-
volumeKeyframes: bakedEnvelope ? void 0 : envelopeKeyframes ?? void 0,
|
|
15946
|
-
...element.fadeIn ? { fadeIn: element.fadeIn } : {},
|
|
15947
|
-
...element.fadeOut ? { fadeOut: element.fadeOut } : {},
|
|
15948
|
-
...tailSeconds > 0 ? { tailSeconds } : {}
|
|
15949
|
-
};
|
|
15950
|
-
preparedTracks[index] = track;
|
|
15951
|
-
} catch (err) {
|
|
15952
|
-
if (err instanceof AudioFxRenderError) throw err;
|
|
15953
|
-
failures.push({
|
|
15954
|
-
stage: "internal",
|
|
15955
|
-
reason: "internal",
|
|
15956
|
-
owner: "system",
|
|
15957
|
-
retryable: false,
|
|
15958
|
-
elementId: element.id,
|
|
15959
|
-
detail: boundedDetail(
|
|
15960
|
-
`Audio processing failed for element ${element.id}: ${err instanceof Error ? err.message : String(err)}`
|
|
15961
|
-
)
|
|
15962
|
-
});
|
|
15963
|
-
}
|
|
15964
|
-
})
|
|
16110
|
+
}, effectiveSignal)
|
|
16111
|
+
)
|
|
15965
16112
|
).catch((err) => {
|
|
15966
16113
|
internalController.abort();
|
|
15967
16114
|
try {
|
|
@@ -16144,7 +16291,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
16144
16291
|
}
|
|
16145
16292
|
|
|
16146
16293
|
// ../engine/src/services/parallelCoordinator.ts
|
|
16147
|
-
import { cpus as
|
|
16294
|
+
import { cpus as cpus3, freemem } from "os";
|
|
16148
16295
|
import { existsSync as existsSync12, mkdirSync as mkdirSync8, readdirSync as readdirSync6 } from "fs";
|
|
16149
16296
|
import { copyFile, readFile as readFile2, rename } from "fs/promises";
|
|
16150
16297
|
import { join as join16 } from "path";
|
|
@@ -16259,7 +16406,7 @@ var MIN_WORKERS = 1;
|
|
|
16259
16406
|
var MAX_WORKER_DIAGNOSTIC_LINES = 8;
|
|
16260
16407
|
var ABSOLUTE_MAX_WORKERS = 24;
|
|
16261
16408
|
function defaultSafeMaxWorkers() {
|
|
16262
|
-
return Math.max(6, Math.min(16, Math.floor(
|
|
16409
|
+
return Math.max(6, Math.min(16, Math.floor(cpus3().length / 8)));
|
|
16263
16410
|
}
|
|
16264
16411
|
var MIN_FRAMES_PER_WORKER = 30;
|
|
16265
16412
|
function shouldDisableBrowserPoolForParallelWorker({
|
|
@@ -16299,7 +16446,7 @@ function formatWorkerFailure(result) {
|
|
|
16299
16446
|
return `${base}; diagnostics: ${diagnostics}`;
|
|
16300
16447
|
}
|
|
16301
16448
|
function computeWorkerSizing(totalFrames, requested, config) {
|
|
16302
|
-
const cpuCount =
|
|
16449
|
+
const cpuCount = cpus3().length;
|
|
16303
16450
|
const totalMemoryMb = getSystemTotalMb();
|
|
16304
16451
|
const heapLimitMb = Math.round(getHeapStatistics().heap_size_limit / (1024 * 1024));
|
|
16305
16452
|
const heapBasedWorkers = Math.max(
|
|
@@ -16854,7 +17001,7 @@ async function mergeWorkerFrames(workDir, tasks, outputDir) {
|
|
|
16854
17001
|
}
|
|
16855
17002
|
function getSystemResources() {
|
|
16856
17003
|
return {
|
|
16857
|
-
cpuCores:
|
|
17004
|
+
cpuCores: cpus3().length,
|
|
16858
17005
|
totalMemoryMB: getSystemTotalMb(),
|
|
16859
17006
|
freeMemoryMB: Math.round(freemem() / (1024 * 1024)),
|
|
16860
17007
|
recommendedWorkers: calculateOptimalWorkers(1e3)
|
|
@@ -17396,6 +17543,7 @@ export {
|
|
|
17396
17543
|
extractVideoMetadata,
|
|
17397
17544
|
extractAudioMetadata,
|
|
17398
17545
|
analyzeKeyframeIntervals,
|
|
17546
|
+
appendSoftwareEncoderThreadsArg,
|
|
17399
17547
|
PROVENANCE_RENDERER_TAG,
|
|
17400
17548
|
PROVENANCE_VERSION_TAG,
|
|
17401
17549
|
PROVENANCE_RENDERER_NAME,
|