hyperframes 0.8.191 → 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-S2ZQYG52.js → add-JC6DKZKC.js} +17 -17
- package/dist/{animatedGifPrep-3JA2CQ3U.js → animatedGifPrep-S6KXJGEL.js} +11 -10
- package/dist/api.js +24 -23
- package/dist/{appHistory-TH3TL6N6.js → appHistory-QVCSAOI4.js} +1 -1
- package/dist/{asset-2CNTAPOC.js → asset-XITFIFE6.js} +2 -2
- package/dist/{assetCataloger-5HXLXL7C.js → assetCataloger-K5FNKG35.js} +13 -12
- package/dist/{audio-DZTSYHXS.js → audio-364UHTY4.js} +22 -21
- package/dist/{auth-GX3M6TJ4.js → auth-5JEESRE6.js} +4 -4
- package/dist/{autoUpdate-EDIWE4Z5.js → autoUpdate-RVVYEHAA.js} +5 -5
- package/dist/{backgroundChecks-VPUPJ7UI.js → backgroundChecks-DCBIYWIQ.js} +5 -5
- package/dist/backgroundChecksWorker.js +5 -5
- package/dist/{batchRender-JHIIDBJR.js → batchRender-ZZ4QMBAA.js} +14 -7
- package/dist/{beats-PZRVTRYW.js → beats-YEL65M6G.js} +53 -15
- package/dist/{benchmark-22UFDW2N.js → benchmark-RBTRPA76.js} +18 -14
- package/dist/{browser-VRDWYIUM.js → browser-BVAYXT4R.js} +7 -7
- package/dist/{bundleWithLocalizedFonts-23QDKFSN.js → bundleWithLocalizedFonts-JLB2OYMT.js} +3 -3
- package/dist/{capture-TOCLXYMJ.js → capture-GBXTMYLZ.js} +76 -68
- package/dist/{capture-NFCBXHDE.js → capture-NIFX6IRS.js} +3 -3
- package/dist/{captureCompositionFrame-BEM6MF7F.js → captureCompositionFrame-ATNNKUL5.js} +17 -16
- package/dist/{catalog-NXS35KM7.js → catalog-AGIF5SM5.js} +18 -18
- package/dist/{catch-up-6WJBUI2C.js → catch-up-SZ3ULDTI.js} +7 -7
- package/dist/{check-WVEBMWN5.js → check-YLQS3TF4.js} +43 -42
- package/dist/{checkBrowser-RT45HJ36.js → checkBrowser-QH4FMCBO.js} +38 -37
- package/dist/{chunk-JOLZ3BSL.js → chunk-2LSCYS2H.js} +2 -2
- package/dist/{chunk-B2A56S5C.js → chunk-2MCXIY4B.js} +13 -10
- package/dist/{chunk-TADJOIFW.js → chunk-2NERNYCJ.js} +4 -4
- package/dist/{chunk-KGMHMYWI.js → chunk-2SFDWMSW.js} +2 -2
- package/dist/{chunk-DCAI5DBR.js → chunk-2ST4WAFY.js} +9 -1
- package/dist/{chunk-3NRB7YXW.js → chunk-2VXY3PEF.js} +96 -67
- package/dist/{chunk-IXLUTE6N.js → chunk-3422KMTD.js} +5 -1
- package/dist/{chunk-VYQYVYQ5.js → chunk-3W4B6G7Y.js} +83 -45
- package/dist/{chunk-JYSSPQDT.js → chunk-4LXZJIVY.js} +11 -11
- package/dist/{chunk-WHAEJX26.js → chunk-4PPWAQYV.js} +17 -12
- package/dist/{chunk-COWQITWP.js → chunk-4TKJWWPL.js} +1 -1
- package/dist/{chunk-NXMYHJAL.js → chunk-4VYPICIA.js} +29 -1
- package/dist/{chunk-RE3EEBWC.js → chunk-5J6TWLFG.js} +4 -4
- package/dist/{chunk-TFMZ4RKM.js → chunk-6DLCOQR4.js} +474 -429
- package/dist/{chunk-KV72BP7O.js → chunk-6LWUPIKD.js} +11 -11
- package/dist/{chunk-HRPWRZGF.js → chunk-6N65ZMC5.js} +1 -1
- package/dist/{chunk-XUXGIA7H.js → chunk-6NLPPKBO.js} +1 -2
- package/dist/{chunk-JJJCFKMF.js → chunk-6XUJVEY2.js} +17 -6
- package/dist/{chunk-GM3WIOO6.js → chunk-7HTH5PFK.js} +2 -2
- package/dist/{chunk-LBNEH6IQ.js → chunk-7QNIXBQD.js} +1 -1
- package/dist/{chunk-OV6KHXLX.js → chunk-7YKJF5JV.js} +1 -1
- package/dist/{chunk-COETAXRN.js → chunk-7YSFE4SZ.js} +2 -2
- package/dist/{chunk-3WJT2JCX.js → chunk-AR3DQYRR.js} +52 -23
- package/dist/{chunk-HYW6HTAK.js → chunk-BJAS2JLW.js} +2 -2
- package/dist/{chunk-RWYUK7LM.js → chunk-BP4EMEGH.js} +2 -2
- package/dist/{chunk-XGHHVYC7.js → chunk-BY6OQ6XP.js} +2 -2
- package/dist/{chunk-TMBUBLZB.js → chunk-C4Y3ZREE.js} +185 -46
- package/dist/{chunk-JQYJXUJW.js → chunk-C6KE4AFW.js} +1 -1
- package/dist/{chunk-TMK4Q7JA.js → chunk-CFUCHO4T.js} +20 -5
- package/dist/{chunk-JGTRVG32.js → chunk-CGTZOY53.js} +1 -1
- package/dist/chunk-CZGHFATT.js +31 -0
- package/dist/{chunk-NJGTNWQY.js → chunk-D625D4TV.js} +6 -6
- package/dist/{chunk-CYBXXSC4.js → chunk-DIKAPMMF.js} +2 -2
- package/dist/{chunk-CXMXJEVY.js → chunk-DSQ72G5I.js} +1 -1
- package/dist/{chunk-GLG5JWLI.js → chunk-DYNHVCBF.js} +2 -2
- package/dist/{chunk-7L37AB57.js → chunk-E3P3LJG6.js} +9 -9
- package/dist/{chunk-EFCKV7MY.js → chunk-E77ALFLW.js} +1 -1
- package/dist/{chunk-WQ3X5OH4.js → chunk-EFXMETRK.js} +2 -2
- package/dist/{chunk-7KVVNF7B.js → chunk-ELP5QZWL.js} +1 -1
- package/dist/{chunk-QH3T4WI2.js → chunk-EXAX37XR.js} +8 -2
- package/dist/{chunk-7A65UCMI.js → chunk-F5LLORBP.js} +2 -2
- package/dist/{chunk-EI7FP7F3.js → chunk-FBVUAH7N.js} +12 -2
- package/dist/{chunk-XWOCXIKR.js → chunk-GKHMSSGY.js} +1 -1
- package/dist/{chunk-DOOSC34Z.js → chunk-GR5DQKDR.js} +8 -8
- package/dist/{chunk-W64L7IFS.js → chunk-IW5G323T.js} +1 -1
- package/dist/{chunk-NAUKCKCJ.js → chunk-KU3UFQN7.js} +9 -12
- package/dist/{chunk-NMDUSCCE.js → chunk-L4JB7LI4.js} +478 -129
- package/dist/{chunk-ALEF2F5N.js → chunk-L5YLA54L.js} +2 -2
- package/dist/{chunk-MSM6VRQ4.js → chunk-LFUVTS6V.js} +2 -2
- package/dist/{chunk-7ZJEQY7Q.js → chunk-LMNZLZMJ.js} +23 -3
- package/dist/{chunk-AQB5M53R.js → chunk-M3KZBDPB.js} +3 -3
- package/dist/{chunk-BFFLKQVB.js → chunk-MFUNDJEV.js} +4 -4
- package/dist/{chunk-7NKJS5KM.js → chunk-OFV3WSOE.js} +1 -1
- package/dist/{chunk-CINKQY6M.js → chunk-OFYW4J7Y.js} +3 -3
- package/dist/{chunk-5C7R55BJ.js → chunk-P2I4RLJE.js} +1 -1
- package/dist/{chunk-RUOG4VB7.js → chunk-PKZ7RK5N.js} +5 -4
- package/dist/{chunk-LLFQA7XF.js → chunk-QFPBRZJD.js} +1 -1
- package/dist/{chunk-TRZVS6TL.js → chunk-QKX7ITER.js} +3 -3
- package/dist/{chunk-46HEFGXJ.js → chunk-REUL2KH2.js} +1 -1
- package/dist/{chunk-TFGO5YMI.js → chunk-RTLPWOO6.js} +2 -2
- package/dist/{chunk-DYAPHNV6.js → chunk-RWGASWT7.js} +1 -1
- package/dist/chunk-RXATE6FZ.js +385 -0
- package/dist/{chunk-U5GTDAQL.js → chunk-SOY2FPOR.js} +7 -7
- package/dist/{chunk-KNU5COPB.js → chunk-T2EUWCJE.js} +1 -1
- package/dist/{chunk-RQBB7PYT.js → chunk-TY3LDJA3.js} +5 -12
- package/dist/{chunk-KAC2WR7P.js → chunk-TZEKVLPV.js} +3 -3
- package/dist/{chunk-TJKE4EYX.js → chunk-UB7BIDBS.js} +3 -3
- package/dist/{chunk-WY3TQ2PT.js → chunk-UIC7B5KW.js} +2 -2
- package/dist/{chunk-2WNVHZHA.js → chunk-UNATIAOT.js} +13 -13
- package/dist/chunk-USWPZXEA.js +3897 -0
- package/dist/{chunk-FBDOHH3Q.js → chunk-V7ZA2BNW.js} +29 -59
- package/dist/{chunk-7LUJE3II.js → chunk-VLLFORE2.js} +1 -1
- package/dist/{chunk-T5YF32WV.js → chunk-VPC4XIVI.js} +6 -5
- package/dist/{chunk-7FF36MAD.js → chunk-VW63MHQU.js} +9 -6
- package/dist/{chunk-ZHKUIC7X.js → chunk-WFS6S65A.js} +21 -14
- package/dist/{chunk-UNR3P7IF.js → chunk-WIVOXGEP.js} +3 -3
- package/dist/{chunk-3XI7MIZB.js → chunk-X5CECNCK.js} +1 -1
- package/dist/{chunk-KHCTBZGJ.js → chunk-XQPA4W3M.js} +4 -4
- package/dist/{chunk-XMSQRDAK.js → chunk-YS4JUGNI.js} +2 -2
- package/dist/{chunk-SMEF3TRJ.js → chunk-ZH7J2ZUL.js} +15 -15
- package/dist/{chunk-WJEVUPVD.js → chunk-ZT45TCY3.js} +1 -1
- package/dist/{chunk-JTPHFYZI.js → chunk-ZTKFRXJB.js} +68 -7
- package/dist/{chunk-W3CS2KFV.js → chunk-ZZPBXRYQ.js} +2 -2
- package/dist/{clean-3VIU2BSK.js → clean-5HGESK5A.js} +40 -27
- package/dist/cli.js +70 -68
- package/dist/{cloud-NA3J4XW2.js → cloud-746PHS32.js} +4 -4
- package/dist/{cloudrun-4MHOF7UT.js → cloudrun-DO7WFLSM.js} +9 -9
- package/dist/commands/contrast-audit.browser.js +1 -1
- package/dist/{compare-ZR7XRPPT.js → compare-66YPRNG2.js} +76 -47
- package/dist/{compiler-MA2ELZPG.js → compiler-R4UYDWXO.js} +8 -7
- package/dist/{component-ZJSOPUAM.js → component-EQ3H6RFP.js} +3 -3
- package/dist/{compositions-WA5V2SHF.js → compositions-ZZ7P5HT2.js} +19 -17
- package/dist/{contactSheet-CAGMKI3E.js → contactSheet-SZBJDOMT.js} +2 -2
- package/dist/{delete-UC427UEA.js → delete-Z5MSLJSR.js} +7 -7
- package/dist/{deploy-B5UO4UIK.js → deploy-RGSAC2K5.js} +1 -1
- package/dist/{deterministicFonts-EGAAE7QL.js → deterministicFonts-RO2TCMLZ.js} +3 -3
- package/dist/{dist-XGPSPKKP.js → dist-QQ26RUDV.js} +5 -4
- package/dist/{dist-BPK37SAB.js → dist-RKK4YLAD.js} +5 -5
- package/dist/{doctor-ZERCTKEK.js → doctor-W4ZZDRTU.js} +20 -19
- package/dist/{events-DCOZQERS.js → events-BSSL4A4W.js} +4 -4
- package/dist/{events-CNIXB2QK.js → events-UACT7PX3.js} +5 -5
- package/dist/{feedback-YBD5ITTY.js → feedback-47ILDLQG.js} +16 -16
- package/dist/{ffmpeg-V4BBFDTG.js → ffmpeg-IEHSUNUT.js} +13 -12
- package/dist/{figma-Z45ZYVGE.js → figma-PLFIIYRU.js} +3 -3
- package/dist/fontLocalizeCli.js +14 -13
- package/dist/{get-23NXQWCD.js → get-PDWGJYNL.js} +7 -7
- package/dist/{gpuPolicy-H6ABHVEB.js → gpuPolicy-6UBXO6ME.js} +11 -10
- package/dist/{grade-compare-ZPX2G3UV.js → grade-compare-5VWLQGM7.js} +38 -37
- package/dist/{gsapParserAcorn-SKODXC2N.js → gsapParserAcorn-OOTY2MVN.js} +2 -2
- package/dist/{help-EP4CDPLO.js → help-DS3KMWYO.js} +1 -1
- package/dist/{history-E5OSXO74.js → history-OC326NVZ.js} +41 -17
- 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/hyperframes-slideshow.global.js +1 -1
- package/dist/{info-2HHGSW5H.js → info-AUIFV6MX.js} +56 -22
- package/dist/{init-ENEG6RZT.js → init-MRTWWDFW.js} +38 -45
- package/dist/{inspect-PVQK4E2A.js → inspect-55NOAXI2.js} +36 -35
- package/dist/{installer-YGGLEOSF.js → installer-YSFFGBBV.js} +8 -8
- package/dist/{keyframes-UWSYS2SL.js → keyframes-OO2BX2IB.js} +13 -14
- package/dist/{lambda-L3LPXC2M.js → lambda-CXXY6QT3.js} +11 -11
- package/dist/{layout-JVL4QREC.js → layout-57GJXKDK.js} +36 -35
- package/dist/{lint-JXQ72DDB.js → lint-J4FK3Z6G.js} +23 -16
- package/dist/{lintProject-F7IC7WY4.js → lintProject-52SLJPRC.js} +5 -4
- package/dist/{list-UFMLM3VV.js → list-VDQUJ76B.js} +7 -7
- package/dist/{login-CKGMWQJN.js → login-TJSEALWW.js} +7 -7
- package/dist/{logout-DDC4QLVK.js → logout-JYFWWUGK.js} +3 -3
- package/dist/{manager-U6OP3EXB.js → manager-4PLYEEWP.js} +14 -13
- package/dist/{manager-UHWEKPXC.js → manager-MZIJY73J.js} +3 -3
- package/dist/{media-treatment-MFMEWCDY.js → media-treatment-GXP4PMJH.js} +20 -19
- package/dist/{models-QA3TJ75Y.js → models-HQQQKEEP.js} +18 -17
- package/dist/{motionShot-NV2OPJHD.js → motionShot-2BT5D7DC.js} +21 -20
- package/dist/{normalize-3AYFSN2F.js → normalize-FASIPBUM.js} +1 -1
- package/dist/{normalize-audio-JWJRUKK2.js → normalize-audio-SOLFMHNP.js} +12 -8
- package/dist/{open-PTJNDRER.js → open-KHEUODFQ.js} +18 -18
- package/dist/{parakeetRunner-B5FCWWOO.js → parakeetRunner-BHU5NCAX.js} +20 -19
- package/dist/{pipeline-N26NA6ZG.js → pipeline-WFV5HDTD.js} +15 -14
- package/dist/{play-45D6X6TV.js → play-GB34CANJ.js} +27 -26
- package/dist/{policies-MBWGLMWB.js → policies-GHVXA5PE.js} +1 -1
- package/dist/{preflight-MFOHPUOI.js → preflight-REF3VSJ7.js} +15 -14
- package/dist/{present-IFBUDI4D.js → present-SIUTA7TD.js} +24 -23
- package/dist/{preview-MQRLXQOV.js → preview-T2GE7Z4A.js} +27 -26
- package/dist/{producer-2QG7HLAW.js → producer-23KVQZAB.js} +1 -1
- package/dist/{projectConfig-I4FTZXHB.js → projectConfig-DBSNBPNP.js} +10 -10
- package/dist/{publication-3GOFXCGU.js → publication-IXPUKYWJ.js} +5 -5
- package/dist/{publish-3B2TZCFH.js → publish-3BA5VHXJ.js} +18 -17
- package/dist/{refresh-RXTOPRBB.js → refresh-USSFPJAU.js} +3 -3
- package/dist/{remove-background-RK4BJDBF.js → remove-background-RMSCJVVQ.js} +16 -15
- package/dist/{render-SJ4HFPFU.js → render-6RNE2MLU.js} +26 -25
- package/dist/{render-PW3XGS7B.js → render-XGOZMMWX.js} +42 -41
- package/dist/{render-BV6FWFX3.js → render-Y6CTQ3YW.js} +8 -8
- package/dist/{render-batch-GKX54O6N.js → render-batch-VUR6N6EY.js} +9 -9
- package/dist/renderSetupWorker.js +9 -8
- package/dist/{resolver-RQJ7CNXD.js → resolver-GJCUH57W.js} +7 -7
- package/dist/{screenshotCapture-UBY6TT75.js → screenshotCapture-I5EDCITF.js} +6 -3
- package/dist/{sherpa-XZPG7QFF.js → sherpa-VVAKRCPL.js} +19 -18
- package/dist/skills/hyperframes/references/format.md +1 -0
- package/dist/skills/hyperframes/references/skill-lifecycle.md +8 -4
- package/dist/skills/hyperframes-cli/references/init-and-scaffold.md +1 -1
- package/dist/{skills-EYLB2V6F.js → skills-ZHBURVQG.js} +13 -75
- package/dist/{skillsUpdateCheck-TE6K5ROM.js → skillsUpdateCheck-VMDAL2O2.js} +5 -5
- package/dist/{slideshow-YTWATJRT.js → slideshow-SJGK4RQS.js} +1 -1
- package/dist/{snapshot-FE4T3SCN.js → snapshot-KEOG56SL.js} +61 -53
- package/dist/{src-ZOXSEJCD.js → src-BH5NICGQ.js} +24 -9
- package/dist/{src-SEJ7LNNB.js → src-TZLGFRRX.js} +13 -12
- package/dist/{staticProjectServer-LSVIRDRO.js → staticProjectServer-BKXL5CXB.js} +22 -21
- package/dist/{status-CM7IQTU2.js → status-H5WLKQDS.js} +3 -3
- package/dist/studio/assets/{hyperframes-player-Bv9hQ3v7.js → hyperframes-player-BMcUdmDb.js} +3 -3
- package/dist/studio/assets/{index-CBO8uz7-.css → index-CYbvOVp-.css} +1 -1
- package/dist/studio/assets/{index-D_QqfWhx.js → index-Ca-mgTnS.js} +122 -122
- package/dist/studio/assets/{index-Df14bh-L.js → index-Ci6GuloR.js} +1 -1
- package/dist/studio/index.html +2 -2
- package/dist/{studio-api-SL2Z76NU.js → studio-api-A5U6QAMC.js} +19 -14
- package/dist/{studioServer-BADWVIHU.js → studioServer-5EC5CP4W.js} +60 -59
- package/dist/{telemetry-QG5AANZ4.js → telemetry-4K6CPMNT.js} +2 -2
- package/dist/{telemetry-RN6VYEID.js → telemetry-BCKJXDSW.js} +5 -5
- package/dist/{timeline-JBTCIPLU.js → timeline-AZWAXTAY.js} +65 -43
- package/dist/{tokens-A7V7UHNK.js → tokens-X7NC3V7C.js} +2 -2
- package/dist/{transcribe-E4BOSNM4.js → transcribe-7NCY7QZ2.js} +17 -16
- package/dist/{transcribe-NTUCJGFI.js → transcribe-SH26H755.js} +26 -25
- package/dist/{tts-A2WILYGN.js → tts-5I2AJNLM.js} +1 -1
- package/dist/{updateCheck-M7UAYLUR.js → updateCheck-Y7FUWQM4.js} +4 -4
- package/dist/{upgrade-A2COSIMB.js → upgrade-ZHGEVL65.js} +4 -4
- package/dist/{urlDownloader-MBSQYART.js → urlDownloader-FPILIT7M.js} +10 -9
- package/dist/{validate-NODZYBHY.js → validate-KQOZR4F6.js} +30 -29
- package/dist/{video-LBCUUYK7.js → video-N2QAETFB.js} +12 -11
- package/dist/warmCheck.js +43 -42
- package/package.json +2 -1
- package/dist/chunk-I5JRXMCV.js +0 -6077
- package/dist/chunk-LM265QNK.js +0 -3896
|
@@ -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,
|
|
@@ -83,7 +83,7 @@ import {
|
|
|
83
83
|
} from "./chunk-4UMPIPCQ.js";
|
|
84
84
|
import {
|
|
85
85
|
resolveReferencedStart
|
|
86
|
-
} from "./chunk-
|
|
86
|
+
} from "./chunk-2VXY3PEF.js";
|
|
87
87
|
import {
|
|
88
88
|
FFMPEG_PATH_ENV,
|
|
89
89
|
FFPROBE_PATH_ENV,
|
|
@@ -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) {
|
|
@@ -4778,8 +4782,11 @@ async function sampleProcessRss(pids, exec = defaultExec(), platform = process.p
|
|
|
4778
4782
|
if (platform === "win32") {
|
|
4779
4783
|
const results = [];
|
|
4780
4784
|
for (const pid of unique) {
|
|
4781
|
-
|
|
4782
|
-
|
|
4785
|
+
try {
|
|
4786
|
+
const { stdout: stdout2 } = await exec("tasklist", ["/FO", "CSV", "/NH", "/FI", `PID eq ${pid}`]);
|
|
4787
|
+
results.push(...parseTasklistCsv(pid, stdout2));
|
|
4788
|
+
} catch {
|
|
4789
|
+
}
|
|
4783
4790
|
}
|
|
4784
4791
|
return results;
|
|
4785
4792
|
}
|
|
@@ -4795,6 +4802,7 @@ var CaptureFailure = class extends Error {
|
|
|
4795
4802
|
kind;
|
|
4796
4803
|
cause;
|
|
4797
4804
|
workerDiagnostics;
|
|
4805
|
+
pageErrorLines;
|
|
4798
4806
|
constructor(input) {
|
|
4799
4807
|
super(input.message);
|
|
4800
4808
|
this.name = "CaptureFailure";
|
|
@@ -4805,6 +4813,7 @@ var CaptureFailure = class extends Error {
|
|
|
4805
4813
|
(diagnostic) => Object.freeze({ ...diagnostic, lines: Object.freeze([...diagnostic.lines]) })
|
|
4806
4814
|
)
|
|
4807
4815
|
);
|
|
4816
|
+
this.pageErrorLines = Object.freeze([...input.pageErrorLines ?? []]);
|
|
4808
4817
|
if (input.cause instanceof Error && input.cause.stack) this.stack = input.cause.stack;
|
|
4809
4818
|
}
|
|
4810
4819
|
};
|
|
@@ -4890,32 +4899,37 @@ function ioError(error, message) {
|
|
|
4890
4899
|
)
|
|
4891
4900
|
) || BROKEN_PIPE_MESSAGE.test(message) || hasIoOperationFailure(message);
|
|
4892
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
|
+
}
|
|
4893
4920
|
function classifyCaptureFailure(error, options = {}) {
|
|
4894
|
-
|
|
4895
|
-
|
|
4921
|
+
const prior = error instanceof CaptureFailure ? error : void 0;
|
|
4922
|
+
if (prior && !(options.workerDiagnostics || options.pageErrorLines || options.signal?.aborted)) {
|
|
4923
|
+
return prior;
|
|
4896
4924
|
}
|
|
4897
4925
|
const message = messageOf(error);
|
|
4898
|
-
|
|
4899
|
-
if (options.signal?.aborted || /(?:render|capture)?_?cancelled|AbortError/i.test(message)) {
|
|
4900
|
-
kind = "cancelled";
|
|
4901
|
-
} else if (BUN_MEMORY_EXHAUSTION_EXACT_MESSAGE.test(message.trim()) || BUN_MEMORY_EXHAUSTION_WRAPPED_WORKER_MESSAGE.test(message) || matchesAny(message, MEMORY_EXHAUSTION_ERROR_PATTERNS)) {
|
|
4902
|
-
kind = "memory_exhaustion";
|
|
4903
|
-
} else if (matchesAny(message, VERIFICATION_ERROR_PATTERNS)) {
|
|
4904
|
-
kind = "verification";
|
|
4905
|
-
} else if (matchesAny(message, PROTOCOL_TIMEOUT_PATTERNS)) {
|
|
4906
|
-
kind = "protocol_timeout";
|
|
4907
|
-
} else if (matchesAny(message, TRANSIENT_BROWSER_ERROR_PATTERNS)) {
|
|
4908
|
-
kind = "transient_browser";
|
|
4909
|
-
} else if (matchesAny(message, AUTHORING_ERROR_PATTERNS)) {
|
|
4910
|
-
kind = "authoring";
|
|
4911
|
-
} else {
|
|
4912
|
-
kind = ioError(error, message) ? "io" : "authoring";
|
|
4913
|
-
}
|
|
4926
|
+
const kind = classifyKind(error, message, options.signal);
|
|
4914
4927
|
return new CaptureFailure({
|
|
4915
4928
|
kind,
|
|
4916
4929
|
message,
|
|
4917
4930
|
cause: error,
|
|
4918
|
-
workerDiagnostics: options.workerDiagnostics ??
|
|
4931
|
+
workerDiagnostics: options.workerDiagnostics ?? prior?.workerDiagnostics,
|
|
4932
|
+
pageErrorLines: options.pageErrorLines ?? prior?.pageErrorLines
|
|
4919
4933
|
});
|
|
4920
4934
|
}
|
|
4921
4935
|
function isTransientBrowserError(error) {
|
|
@@ -5200,12 +5214,14 @@ async function driveWarmupTicks(options, state) {
|
|
|
5200
5214
|
} else {
|
|
5201
5215
|
if (!state.running) return;
|
|
5202
5216
|
}
|
|
5217
|
+
let ticked = false;
|
|
5203
5218
|
try {
|
|
5204
5219
|
await options.tick(state.ticks * options.intervalMs, options.intervalMs);
|
|
5205
5220
|
state.ticks += 1;
|
|
5221
|
+
ticked = true;
|
|
5206
5222
|
} catch {
|
|
5207
5223
|
}
|
|
5208
|
-
await sleep(options.intervalMs);
|
|
5224
|
+
if (!(options.lockWarmupTicks && !state.running && ticked)) await sleep(options.intervalMs);
|
|
5209
5225
|
}
|
|
5210
5226
|
}
|
|
5211
5227
|
function resolveCaptureSessionOptions(options, browserVersion, platform = process.platform) {
|
|
@@ -8544,6 +8560,7 @@ var videoMetadataCache = /* @__PURE__ */ new Map();
|
|
|
8544
8560
|
var finalVideoFrameTimestampCache = /* @__PURE__ */ new Map();
|
|
8545
8561
|
var finalVideoFrameTimestampSignalCaches = /* @__PURE__ */ new WeakMap();
|
|
8546
8562
|
var audioMetadataCache = /* @__PURE__ */ new Map();
|
|
8563
|
+
var audioMetadataSignalCaches = /* @__PURE__ */ new WeakMap();
|
|
8547
8564
|
var mediaProbeOutputCache = /* @__PURE__ */ new Map();
|
|
8548
8565
|
var mediaProbeOutputSignalCaches = /* @__PURE__ */ new WeakMap();
|
|
8549
8566
|
var MEDIA_PROBE_OUTPUT_CACHE_MAX_ENTRIES = 128;
|
|
@@ -8599,7 +8616,20 @@ function isPngImageProbe(output) {
|
|
|
8599
8616
|
(stream) => stream.codec_type === "video" && stream.codec_name?.toLowerCase() === "png"
|
|
8600
8617
|
);
|
|
8601
8618
|
}
|
|
8619
|
+
var contentAddressedUrls = /* @__PURE__ */ new Map();
|
|
8620
|
+
var withoutQuery = (url) => url.split(/[?#]/, 1)[0] ?? url;
|
|
8621
|
+
function declareContentAddressedUrl(url, sha256) {
|
|
8622
|
+
contentAddressedUrls.set(withoutQuery(url), sha256);
|
|
8623
|
+
}
|
|
8624
|
+
var probeFactsUrls = /* @__PURE__ */ new Map();
|
|
8625
|
+
function declareProbeFactsUrl(url, factsUrl) {
|
|
8626
|
+
probeFactsUrls.set(withoutQuery(url), factsUrl);
|
|
8627
|
+
}
|
|
8602
8628
|
function mediaFileIdentity(filePath) {
|
|
8629
|
+
if (/^https?:\/\//i.test(filePath)) {
|
|
8630
|
+
const sha256 = contentAddressedUrls.get(withoutQuery(filePath));
|
|
8631
|
+
return sha256 ? `sha256:${sha256}` : null;
|
|
8632
|
+
}
|
|
8603
8633
|
try {
|
|
8604
8634
|
const stat = statSync2(filePath, { bigint: true });
|
|
8605
8635
|
return [stat.dev, stat.ino, stat.size, stat.mtimeNs, stat.ctimeNs].join(":");
|
|
@@ -8623,6 +8653,75 @@ function writeMetadataCache(cache, key, identity, promise) {
|
|
|
8623
8653
|
}
|
|
8624
8654
|
);
|
|
8625
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
|
+
}
|
|
8626
8725
|
async function probeMediaOutput(filePath, signal) {
|
|
8627
8726
|
let cache = mediaProbeOutputCache;
|
|
8628
8727
|
if (signal) {
|
|
@@ -8638,11 +8737,7 @@ async function probeMediaOutput(filePath, signal) {
|
|
|
8638
8737
|
}
|
|
8639
8738
|
return cached.promise;
|
|
8640
8739
|
}
|
|
8641
|
-
const promise =
|
|
8642
|
-
filePath,
|
|
8643
|
-
["-print_format", "json", "-show_format", "-show_streams"],
|
|
8644
|
-
signal
|
|
8645
|
-
).then(parseProbeJson);
|
|
8740
|
+
const promise = readProbeJson(filePath, signal).then(parseProbeJson);
|
|
8646
8741
|
if (identity !== null) {
|
|
8647
8742
|
cache.set(filePath, { identity, promise });
|
|
8648
8743
|
if (!signal && cache.size > MEDIA_PROBE_OUTPUT_CACHE_MAX_ENTRIES) {
|
|
@@ -8898,6 +8993,43 @@ function resolveStreamWindow(filePath, metadata) {
|
|
|
8898
8993
|
const cacheKey = `${filePath}\0${String(videoStreamStartSeconds)}\0${String(videoStreamDurationSeconds)}`;
|
|
8899
8994
|
return { videoStreamStartSeconds, videoStreamDurationSeconds, cacheKey };
|
|
8900
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
|
+
}
|
|
8901
9033
|
async function extractFinalVideoFrameTimestamp(filePath, metadata, signal) {
|
|
8902
9034
|
const {
|
|
8903
9035
|
videoStreamStartSeconds,
|
|
@@ -8913,6 +9045,9 @@ async function extractFinalVideoFrameTimestamp(filePath, metadata, signal) {
|
|
|
8913
9045
|
const cached = readMetadataCache(probeCache, cacheKey, identity);
|
|
8914
9046
|
if (cached) return cached;
|
|
8915
9047
|
const probePromise = (async () => {
|
|
9048
|
+
const pendingStored = readStoredFinalFrame(filePath, metadata);
|
|
9049
|
+
const stored = pendingStored && await pendingStored;
|
|
9050
|
+
if (stored) return stored.seconds;
|
|
8916
9051
|
if (!(videoDurationSeconds > 0) || !Number.isFinite(videoDurationSeconds)) {
|
|
8917
9052
|
throw new Error(
|
|
8918
9053
|
`[FFmpeg] Cannot locate final video frame for invalid duration ${String(videoDurationSeconds)}`
|
|
@@ -8951,44 +9086,51 @@ async function extractFinalVideoFrameTimestamp(filePath, metadata, signal) {
|
|
|
8951
9086
|
var extractVideoMetadata = extractMediaMetadata;
|
|
8952
9087
|
async function extractAudioMetadata(filePath, options) {
|
|
8953
9088
|
const identity = mediaFileIdentity(filePath);
|
|
8954
|
-
const
|
|
9089
|
+
const signal = options?.signal;
|
|
9090
|
+
if (signal && identity === null) return probeAudioMetadata(filePath, signal);
|
|
9091
|
+
let cache = audioMetadataCache;
|
|
9092
|
+
if (signal) {
|
|
9093
|
+
cache = audioMetadataSignalCaches.get(signal) ?? /* @__PURE__ */ new Map();
|
|
9094
|
+
audioMetadataSignalCaches.set(signal, cache);
|
|
9095
|
+
}
|
|
9096
|
+
const cached = readMetadataCache(cache, filePath, identity);
|
|
8955
9097
|
if (cached) return cached;
|
|
8956
|
-
const probePromise = (
|
|
8957
|
-
|
|
8958
|
-
const audioStream = output.streams.find((s) => s.codec_type === "audio");
|
|
8959
|
-
if (!audioStream) throw new Error("[FFmpeg] No audio stream found");
|
|
8960
|
-
let durationSeconds = output.format.duration ? parseFloat(output.format.duration) : 0;
|
|
8961
|
-
const streamDuration = audioStream.duration ? parseFloat(audioStream.duration) : void 0;
|
|
8962
|
-
const sampleRate = audioStream.sample_rate ? parseInt(audioStream.sample_rate) : 44100;
|
|
8963
|
-
const audioCodec = audioStream.codec_name || "unknown";
|
|
8964
|
-
if (sampleRate > 0) {
|
|
8965
|
-
const decoded = await probeDecodedAudioDuration(
|
|
8966
|
-
filePath,
|
|
8967
|
-
sampleRate,
|
|
8968
|
-
audioStartSeconds(audioStream, output.format),
|
|
8969
|
-
durationSeconds,
|
|
8970
|
-
options?.signal
|
|
8971
|
-
);
|
|
8972
|
-
if (decoded !== null) {
|
|
8973
|
-
durationSeconds = reconcileAudioDuration(durationSeconds, decoded, output.format);
|
|
8974
|
-
}
|
|
8975
|
-
}
|
|
8976
|
-
return {
|
|
8977
|
-
durationSeconds,
|
|
8978
|
-
streamDurationSeconds: streamDuration && streamDuration > 0 ? streamDuration : void 0,
|
|
8979
|
-
sampleRate,
|
|
8980
|
-
channels: audioStream.channels || 2,
|
|
8981
|
-
audioCodec,
|
|
8982
|
-
bitrate: output.format.bit_rate ? parseInt(output.format.bit_rate) : void 0,
|
|
8983
|
-
latestStreamLeadSeconds: latestStreamLeadSeconds(output),
|
|
8984
|
-
audioStreamLeadSeconds: streamLeadSeconds(output, audioStream),
|
|
8985
|
-
audioStreamCount: output.streams.filter((s) => s.codec_type === "audio").length
|
|
8986
|
-
};
|
|
8987
|
-
})();
|
|
8988
|
-
if (options?.signal) return probePromise;
|
|
8989
|
-
writeMetadataCache(audioMetadataCache, filePath, identity, probePromise);
|
|
9098
|
+
const probePromise = probeAudioMetadata(filePath, signal);
|
|
9099
|
+
writeMetadataCache(cache, filePath, identity, probePromise);
|
|
8990
9100
|
return probePromise;
|
|
8991
9101
|
}
|
|
9102
|
+
async function probeAudioMetadata(filePath, signal) {
|
|
9103
|
+
const output = await probeMediaOutput(filePath, signal);
|
|
9104
|
+
const audioStream = output.streams.find((s) => s.codec_type === "audio");
|
|
9105
|
+
if (!audioStream) throw new Error("[FFmpeg] No audio stream found");
|
|
9106
|
+
let durationSeconds = output.format.duration ? parseFloat(output.format.duration) : 0;
|
|
9107
|
+
const streamDuration = audioStream.duration ? parseFloat(audioStream.duration) : void 0;
|
|
9108
|
+
const sampleRate = audioStream.sample_rate ? parseInt(audioStream.sample_rate) : 44100;
|
|
9109
|
+
const audioCodec = audioStream.codec_name || "unknown";
|
|
9110
|
+
if (sampleRate > 0) {
|
|
9111
|
+
const decoded = await probeDecodedAudioDuration(
|
|
9112
|
+
filePath,
|
|
9113
|
+
sampleRate,
|
|
9114
|
+
audioStartSeconds(audioStream, output.format),
|
|
9115
|
+
durationSeconds,
|
|
9116
|
+
signal
|
|
9117
|
+
);
|
|
9118
|
+
if (decoded !== null) {
|
|
9119
|
+
durationSeconds = reconcileAudioDuration(durationSeconds, decoded, output.format);
|
|
9120
|
+
}
|
|
9121
|
+
}
|
|
9122
|
+
return {
|
|
9123
|
+
durationSeconds,
|
|
9124
|
+
streamDurationSeconds: streamDuration && streamDuration > 0 ? streamDuration : void 0,
|
|
9125
|
+
sampleRate,
|
|
9126
|
+
channels: audioStream.channels || 2,
|
|
9127
|
+
audioCodec,
|
|
9128
|
+
bitrate: output.format.bit_rate ? parseInt(output.format.bit_rate) : void 0,
|
|
9129
|
+
latestStreamLeadSeconds: latestStreamLeadSeconds(output),
|
|
9130
|
+
audioStreamLeadSeconds: streamLeadSeconds(output, audioStream),
|
|
9131
|
+
audioStreamCount: output.streams.filter((s) => s.codec_type === "audio").length
|
|
9132
|
+
};
|
|
9133
|
+
}
|
|
8992
9134
|
function audioVideoStreamStarts(output) {
|
|
8993
9135
|
return (output?.streams ?? []).filter(
|
|
8994
9136
|
(s) => (s.codec_type === "audio" || s.codec_type === "video") && s.disposition?.attached_pic !== 1
|
|
@@ -9124,8 +9266,10 @@ async function analyzeKeyframeIntervalsUncached(filePath, videoStreamStartSecond
|
|
|
9124
9266
|
|
|
9125
9267
|
// ../engine/src/services/softwareEncoderThreads.ts
|
|
9126
9268
|
import { availableParallelism } from "os";
|
|
9127
|
-
|
|
9128
|
-
|
|
9269
|
+
var X265_MAX_THREADS = 16;
|
|
9270
|
+
function appendSoftwareEncoderThreadsArg(args, encoder, parallelism = availableParallelism()) {
|
|
9271
|
+
const cap = encoder === "libx265" ? X265_MAX_THREADS : Infinity;
|
|
9272
|
+
args.push("-threads", String(Math.min(cap, Math.max(1, Math.floor(parallelism)))));
|
|
9129
9273
|
}
|
|
9130
9274
|
|
|
9131
9275
|
// ../engine/src/utils/renderProvenance.ts
|
|
@@ -9352,7 +9496,7 @@ function buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder = null) {
|
|
|
9352
9496
|
} else {
|
|
9353
9497
|
const encoderName = codec === "h264" ? "libx264" : "libx265";
|
|
9354
9498
|
args.push("-c:v", encoderName, "-preset", preset);
|
|
9355
|
-
appendSoftwareEncoderThreadsArg(args);
|
|
9499
|
+
appendSoftwareEncoderThreadsArg(args, encoderName);
|
|
9356
9500
|
if (bitrate) args.push("-b:v", bitrate);
|
|
9357
9501
|
else args.push("-crf", String(quality));
|
|
9358
9502
|
const gop = resolveLockedGopSize(options);
|
|
@@ -10057,7 +10201,7 @@ function buildStreamingArgs(options, outputPath, gpuEncoder = null) {
|
|
|
10057
10201
|
} else {
|
|
10058
10202
|
const encoderName = codec === "h264" ? "libx264" : "libx265";
|
|
10059
10203
|
args.push("-c:v", encoderName, "-preset", preset);
|
|
10060
|
-
appendSoftwareEncoderThreadsArg(args);
|
|
10204
|
+
appendSoftwareEncoderThreadsArg(args, encoderName);
|
|
10061
10205
|
if (bitrate) args.push("-b:v", bitrate);
|
|
10062
10206
|
else args.push("-crf", String(quality));
|
|
10063
10207
|
const lockedGop = resolveLockedGopSize(options);
|
|
@@ -11481,7 +11625,7 @@ function getSingleMeaningfulChild(container) {
|
|
|
11481
11625
|
}
|
|
11482
11626
|
function unwrapTemplate(html) {
|
|
11483
11627
|
const lowered = html.toLowerCase();
|
|
11484
|
-
if (!lowered.includes("<template") ||
|
|
11628
|
+
if (!lowered.includes("<template") || !/<\/template[ \t\n\r\f]*>/.test(lowered)) {
|
|
11485
11629
|
return html;
|
|
11486
11630
|
}
|
|
11487
11631
|
const { body } = parseHTMLContent(html);
|
|
@@ -11506,12 +11650,52 @@ import {
|
|
|
11506
11650
|
lstatSync as lstatSync2,
|
|
11507
11651
|
mkdirSync as mkdirSync5,
|
|
11508
11652
|
readdirSync as readdirSync5,
|
|
11509
|
-
renameSync,
|
|
11510
11653
|
rmSync as rmSync3,
|
|
11511
11654
|
statSync as statSync6,
|
|
11512
11655
|
utimesSync,
|
|
11513
11656
|
writeFileSync as writeFileSync3
|
|
11514
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
|
|
11515
11699
|
import { join as join9 } from "path";
|
|
11516
11700
|
var COMPLETE_SENTINEL = ".hf-complete";
|
|
11517
11701
|
var GC_MARKER = ".hf-last-gc";
|
|
@@ -11575,7 +11759,7 @@ function isTargetExistsRenameError(err) {
|
|
|
11575
11759
|
return code === "EEXIST" || code === "ENOTEMPTY" || code === "EPERM";
|
|
11576
11760
|
}
|
|
11577
11761
|
function adoptPublishedWinner(entry, partialDir) {
|
|
11578
|
-
if (!existsSync8(join9(entry.dir, COMPLETE_SENTINEL))) return null;
|
|
11762
|
+
if (!existsSync8(join9(entry.dir, COMPLETE_SENTINEL)) || !hasFrameFiles(entry.dir)) return null;
|
|
11579
11763
|
removeDir(partialDir);
|
|
11580
11764
|
return { dir: entry.dir, published: true };
|
|
11581
11765
|
}
|
|
@@ -11586,7 +11770,7 @@ function publishCacheEntry(entry, partialDir) {
|
|
|
11586
11770
|
return { dir: partialDir, published: false };
|
|
11587
11771
|
}
|
|
11588
11772
|
try {
|
|
11589
|
-
|
|
11773
|
+
renameWithRetry(partialDir, entry.dir);
|
|
11590
11774
|
return { dir: entry.dir, published: true };
|
|
11591
11775
|
} catch (err) {
|
|
11592
11776
|
if (!isTargetExistsRenameError(err)) return { dir: partialDir, published: false };
|
|
@@ -11599,7 +11783,7 @@ function publishCacheEntry(entry, partialDir) {
|
|
|
11599
11783
|
return { dir: partialDir, published: false };
|
|
11600
11784
|
}
|
|
11601
11785
|
try {
|
|
11602
|
-
|
|
11786
|
+
renameWithRetry(partialDir, entry.dir);
|
|
11603
11787
|
return { dir: entry.dir, published: true };
|
|
11604
11788
|
} catch {
|
|
11605
11789
|
return adoptPublishedWinner(entry, partialDir) ?? { dir: partialDir, published: false };
|
|
@@ -11784,6 +11968,24 @@ function extractionFrameCountForDuration(durationSeconds, fps, isVFR) {
|
|
|
11784
11968
|
const frames = Number(frameCount);
|
|
11785
11969
|
return Math.max(1, Number.isSafeInteger(frames) ? frames : Number.MAX_SAFE_INTEGER);
|
|
11786
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
|
+
}
|
|
11787
11989
|
var DOWNLOAD_SUBDIR = "_downloads";
|
|
11788
11990
|
var EXTRACT_CACHE_MIN_AGE_MS = 60 * 60 * 1e3;
|
|
11789
11991
|
var GC_STALENESS_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -12158,6 +12360,8 @@ function undoTickRoundingOnTheSourceFrameGrid(seek, lead) {
|
|
|
12158
12360
|
}
|
|
12159
12361
|
var EXTRACTION_SLOTS = Math.max(1, Math.floor(cpus().length / 2));
|
|
12160
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);
|
|
12161
12365
|
function splitFrameRanges(ranges, segmentFrames) {
|
|
12162
12366
|
const segments = [];
|
|
12163
12367
|
for (const range of ranges) {
|
|
@@ -12171,7 +12375,7 @@ function splitFrameRanges(ranges, segmentFrames) {
|
|
|
12171
12375
|
return segments;
|
|
12172
12376
|
}
|
|
12173
12377
|
async function runSegmentedExtraction(job) {
|
|
12174
|
-
const { decodeArgs, filterAndEncodeArgs, videoPath, startTime, fps, segments } = job;
|
|
12378
|
+
const { decodeArgs, filterAndEncodeArgs, videoPath, startTime, fps, segments, gate } = job;
|
|
12175
12379
|
const segmentCount = segments.length;
|
|
12176
12380
|
const failed = new AbortController();
|
|
12177
12381
|
const signal = job.runOptions.signal ? AbortSignal.any([job.runOptions.signal, failed.signal]) : failed.signal;
|
|
@@ -12182,7 +12386,7 @@ async function runSegmentedExtraction(job) {
|
|
|
12182
12386
|
const index = next++;
|
|
12183
12387
|
const { firstFrame, frames } = segments[index];
|
|
12184
12388
|
const seek = startTime + firstFrame / fps;
|
|
12185
|
-
const result = await
|
|
12389
|
+
const result = await gate(
|
|
12186
12390
|
() => runFfmpeg(
|
|
12187
12391
|
[
|
|
12188
12392
|
...decodeArgs,
|
|
@@ -12333,6 +12537,7 @@ async function extractVideoFramesRangeUnredacted(videoPath, videoId, startTime,
|
|
|
12333
12537
|
videoPath,
|
|
12334
12538
|
startTime,
|
|
12335
12539
|
fps,
|
|
12540
|
+
gate: options.tailProbe ? inTailProbeSlot : inExtractionSlot,
|
|
12336
12541
|
segments: splitFrameRanges(
|
|
12337
12542
|
options.frameRanges ?? [{ firstFrame: 0, frames: totalFrames }],
|
|
12338
12543
|
segmentFrames
|
|
@@ -12433,9 +12638,6 @@ function resolveSegmentDuration(requested, mediaStart, sourceDuration) {
|
|
|
12433
12638
|
const sourceRemaining = sourceDuration - mediaStart;
|
|
12434
12639
|
return sourceRemaining > 0 ? sourceRemaining : sourceDuration;
|
|
12435
12640
|
}
|
|
12436
|
-
function resolvePlayableVideoDuration(metadata) {
|
|
12437
|
-
return Number.isFinite(metadata.videoStreamDurationSeconds) && metadata.videoStreamDurationSeconds > 0 ? (metadata.videoStreamLeadSeconds ?? 0) + metadata.videoStreamDurationSeconds : metadata.durationSeconds;
|
|
12438
|
-
}
|
|
12439
12641
|
function canHoldFinalFramePastEof(video) {
|
|
12440
12642
|
const timelineDuration = video.end - video.start;
|
|
12441
12643
|
return !video.loop && Number.isFinite(timelineDuration) && timelineDuration > 0;
|
|
@@ -13114,23 +13316,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config, c
|
|
|
13114
13316
|
);
|
|
13115
13317
|
const tailFrames = Math.min(expectedFrames, Math.ceil(fps));
|
|
13116
13318
|
if (expectedFrames <= tailFrames) return null;
|
|
13117
|
-
const
|
|
13118
|
-
try {
|
|
13119
|
-
const tail = await extractVideoFramesRange(
|
|
13120
|
-
work.videoPath,
|
|
13121
|
-
work.video.id,
|
|
13122
|
-
work.extractionMediaStart,
|
|
13123
|
-
work.videoDuration,
|
|
13124
|
-
{
|
|
13125
|
-
...scopedExtractionOptions(work),
|
|
13126
|
-
frameRanges: [{ firstFrame: expectedFrames - tailFrames, frames: tailFrames }]
|
|
13127
|
-
},
|
|
13128
|
-
signal,
|
|
13129
|
-
config,
|
|
13130
|
-
probeDir
|
|
13131
|
-
);
|
|
13132
|
-
const totalFrames = expectedFrames - tailFrames + tail.totalFrames;
|
|
13133
|
-
if (totalFrames <= expectedFrames * 0.6) return null;
|
|
13319
|
+
const deferred = (totalFrames) => {
|
|
13134
13320
|
const outputDir = join10(options.outputDir, work.video.id);
|
|
13135
13321
|
mkdirSync6(outputDir, { recursive: true });
|
|
13136
13322
|
return {
|
|
@@ -13148,6 +13334,45 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config, c
|
|
|
13148
13334
|
format: work.format
|
|
13149
13335
|
}
|
|
13150
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);
|
|
13151
13376
|
} catch {
|
|
13152
13377
|
return null;
|
|
13153
13378
|
} finally {
|
|
@@ -14026,16 +14251,7 @@ async function queryElementStacking(page, nativeHdrIds) {
|
|
|
14026
14251
|
}
|
|
14027
14252
|
|
|
14028
14253
|
// ../engine/src/services/audioMixer.ts
|
|
14029
|
-
import {
|
|
14030
|
-
closeSync as closeSync4,
|
|
14031
|
-
existsSync as existsSync11,
|
|
14032
|
-
mkdirSync as mkdirSync7,
|
|
14033
|
-
mkdtempSync as mkdtempSync7,
|
|
14034
|
-
openSync as openSync4,
|
|
14035
|
-
renameSync as renameSync3,
|
|
14036
|
-
rmSync as rmSync8,
|
|
14037
|
-
writeFileSync as writeFileSync7
|
|
14038
|
-
} 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";
|
|
14039
14255
|
import { join as join14, dirname as dirname7, isAbsolute, relative } from "path";
|
|
14040
14256
|
|
|
14041
14257
|
// ../engine/src/utils/notMediaPayload.ts
|
|
@@ -14154,6 +14370,7 @@ function clampFadesToDuration(fades, duration) {
|
|
|
14154
14370
|
import { cpus as cpus2 } from "os";
|
|
14155
14371
|
|
|
14156
14372
|
// ../engine/src/services/aacEncode.ts
|
|
14373
|
+
import { execFile as execFile3 } from "child_process";
|
|
14157
14374
|
import { mkdtempSync as mkdtempSync4, readFileSync as readFileSync5, rmSync as rmSync5, writeFileSync as writeFileSync4 } from "fs";
|
|
14158
14375
|
import { dirname as dirname5, join as join11 } from "path";
|
|
14159
14376
|
var SAMPLE_RATE = 48e3;
|
|
@@ -14189,12 +14406,35 @@ function planSegments(totalDuration, count) {
|
|
|
14189
14406
|
return { trim, keepFrom: cut - firstFrame, keepTo: next - firstFrame };
|
|
14190
14407
|
});
|
|
14191
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
|
+
}
|
|
14192
14429
|
async function encodeAac(input, outputPath, totalDuration, {
|
|
14193
14430
|
signal,
|
|
14194
14431
|
timeout,
|
|
14195
14432
|
filter,
|
|
14196
14433
|
segments: count = aacSegmentCount(totalDuration)
|
|
14197
14434
|
}) {
|
|
14435
|
+
if (!await supportsSettsDuration()) {
|
|
14436
|
+
return encodeInOnePass(input, outputPath, { signal, timeout, filter });
|
|
14437
|
+
}
|
|
14198
14438
|
const dir = mkdtempSync4(join11(dirname5(outputPath), ".aac-segments-"));
|
|
14199
14439
|
try {
|
|
14200
14440
|
const segments = planSegments(totalDuration, count).map((segment, k) => ({
|
|
@@ -14360,7 +14600,7 @@ function audioFailureDiagnostics(values) {
|
|
|
14360
14600
|
}
|
|
14361
14601
|
|
|
14362
14602
|
// ../engine/src/services/audioVolumeEnvelope.ts
|
|
14363
|
-
import { mkdtempSync as mkdtempSync5, readFileSync as readFileSync6,
|
|
14603
|
+
import { mkdtempSync as mkdtempSync5, readFileSync as readFileSync6, rmSync as rmSync6, writeFileSync as writeFileSync5 } from "fs";
|
|
14364
14604
|
import { dirname as dirname6, join as join12 } from "path";
|
|
14365
14605
|
|
|
14366
14606
|
// ../core/dist/runtime/mediaVolumeEnvelope.js
|
|
@@ -14490,7 +14730,7 @@ function applyVolumeEnvelopeToWav(wavPath, keyframes, trackStart, baseVolume) {
|
|
|
14490
14730
|
stagingDir = mkdtempSync5(join12(dirname6(wavPath), ".hf-volume-"));
|
|
14491
14731
|
const tempPath = join12(stagingDir, "audio.wav");
|
|
14492
14732
|
writeFileSync5(tempPath, buffer, { flag: "wx" });
|
|
14493
|
-
|
|
14733
|
+
renameWithRetry(tempPath, wavPath);
|
|
14494
14734
|
return true;
|
|
14495
14735
|
} catch {
|
|
14496
14736
|
return false;
|
|
@@ -15269,6 +15509,7 @@ function legacyFilterScriptOptionIsUnsupported(stderr) {
|
|
|
15269
15509
|
return /filter_complex_script/i.test(stderr) && /(?:unrecognized option|option (?:was )?not found)/i.test(stderr);
|
|
15270
15510
|
}
|
|
15271
15511
|
var inPrepareSlot = createConcurrencyLimit(Math.max(2, Math.floor(cpus2().length / 2)));
|
|
15512
|
+
var inRemotePrepareSlot = createConcurrencyLimit(16);
|
|
15272
15513
|
var MAX_VOLUME_SEGMENTS = 32;
|
|
15273
15514
|
var VOLUME_SIMPLIFY_EPSILON = 5e-3;
|
|
15274
15515
|
var STEREO_CHANNEL_FILTER = "pan=stereo|FL=FL+FC|FR=FR+FC";
|
|
@@ -15485,8 +15726,11 @@ function parseAudioElements(html) {
|
|
|
15485
15726
|
const startCache = /* @__PURE__ */ new Map();
|
|
15486
15727
|
const visiting = /* @__PURE__ */ new Set();
|
|
15487
15728
|
const resolveStart = (el) => el.getAttribute("data-start") ? resolveReferencedStart(document2, el, startCache, visiting) : 0;
|
|
15488
|
-
const
|
|
15489
|
-
|
|
15729
|
+
const resolveEnd = (el) => {
|
|
15730
|
+
const end = parseStrictFiniteTimingNumber(el.getAttribute("data-end"));
|
|
15731
|
+
if (end != null) return end;
|
|
15732
|
+
const duration = parseStrictFiniteTimingNumber(el.getAttribute("data-duration"));
|
|
15733
|
+
return duration != null && duration > 0 ? resolveStart(el) + duration : 0;
|
|
15490
15734
|
};
|
|
15491
15735
|
const isHidden = isSelfOrAncestorHidden;
|
|
15492
15736
|
const groupsById = new Map(
|
|
@@ -15505,9 +15749,10 @@ function parseAudioElements(html) {
|
|
|
15505
15749
|
id,
|
|
15506
15750
|
src,
|
|
15507
15751
|
start: resolveStart(el),
|
|
15508
|
-
end:
|
|
15752
|
+
end: resolveEnd(el),
|
|
15509
15753
|
mediaStart: readMediaStart(el),
|
|
15510
15754
|
playbackRate: readElementRateSpec(el),
|
|
15755
|
+
loop: el.getAttribute("loop") !== null,
|
|
15511
15756
|
layer: layerAttr ? parseInt(layerAttr) : 0,
|
|
15512
15757
|
volume: volumeAttr ? parseFloat(volumeAttr) : 1,
|
|
15513
15758
|
...fades.fadeIn > 0 ? { fadeIn: fades.fadeIn } : {},
|
|
@@ -15543,7 +15788,7 @@ function parseAudioElements(html) {
|
|
|
15543
15788
|
}
|
|
15544
15789
|
var FAIL_ON_READ_ERROR_INSTEAD_OF_ENDING_THERE = ["-xerror"];
|
|
15545
15790
|
var SIDECAR_WARM_UP_SECONDS = 1;
|
|
15546
|
-
async function extractAudioSegment(srcPath, outputPath, stage, mediaStart, duration, playbackRate = 1, signal, config, audioSidecarUrl) {
|
|
15791
|
+
async function extractAudioSegment(srcPath, outputPath, stage, mediaStart, duration, playbackRate = 1, signal, config, audioSidecarUrl, options) {
|
|
15547
15792
|
const ffmpegProcessTimeout = config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG.ffmpegProcessTimeout;
|
|
15548
15793
|
const outputDir = dirname7(outputPath);
|
|
15549
15794
|
if (!existsSync11(outputDir)) mkdirSync7(outputDir, { recursive: true });
|
|
@@ -15553,7 +15798,62 @@ async function extractAudioSegment(srcPath, outputPath, stage, mediaStart, durat
|
|
|
15553
15798
|
const metadata = readsUrl ? await extractAudioMetadata(srcPath, { signal }).catch((error) => {
|
|
15554
15799
|
if (signal?.aborted) throw error;
|
|
15555
15800
|
return extractAudioMetadata(srcPath, { signal });
|
|
15556
|
-
}) : await extractAudioMetadata(srcPath).catch(() =>
|
|
15801
|
+
}) : await extractAudioMetadata(srcPath).catch((error) => {
|
|
15802
|
+
if (options?.loop) throw error;
|
|
15803
|
+
return null;
|
|
15804
|
+
});
|
|
15805
|
+
const loopDuration = (metadata?.durationSeconds ?? 0) - mediaStart;
|
|
15806
|
+
if (options?.loop && loopDuration > 0 && sourceDuration > loopDuration) {
|
|
15807
|
+
const cycleDir = mkdtempSync7(join14(outputDir, ".audio-loop-"));
|
|
15808
|
+
const cyclePath = join14(cycleDir, "cycle.wav");
|
|
15809
|
+
try {
|
|
15810
|
+
const cycle = await extractAudioSegment(
|
|
15811
|
+
srcPath,
|
|
15812
|
+
cyclePath,
|
|
15813
|
+
stage,
|
|
15814
|
+
mediaStart,
|
|
15815
|
+
loopDuration,
|
|
15816
|
+
1,
|
|
15817
|
+
signal,
|
|
15818
|
+
config,
|
|
15819
|
+
audioSidecarUrl,
|
|
15820
|
+
{ padToDuration: true }
|
|
15821
|
+
);
|
|
15822
|
+
if (!cycle.success) return { ...cycle, outputPath };
|
|
15823
|
+
const outputArgs2 = preparedAudioOutputArgs(metadata, normalizedPlaybackRate, duration, null);
|
|
15824
|
+
const result2 = await runFfmpeg(
|
|
15825
|
+
[
|
|
15826
|
+
"-stream_loop",
|
|
15827
|
+
"-1",
|
|
15828
|
+
"-t",
|
|
15829
|
+
String(sourceDuration),
|
|
15830
|
+
"-i",
|
|
15831
|
+
cyclePath,
|
|
15832
|
+
"-vn",
|
|
15833
|
+
"-acodec",
|
|
15834
|
+
"pcm_s16le",
|
|
15835
|
+
"-ar",
|
|
15836
|
+
"48000",
|
|
15837
|
+
...outputArgs2,
|
|
15838
|
+
"-t",
|
|
15839
|
+
String(duration),
|
|
15840
|
+
"-y",
|
|
15841
|
+
outputPath
|
|
15842
|
+
],
|
|
15843
|
+
{ signal, timeout: ffmpegProcessTimeout }
|
|
15844
|
+
);
|
|
15845
|
+
const failure2 = result2.success ? void 0 : ffmpegFailure(stage, result2, ffmpegProcessTimeout);
|
|
15846
|
+
return {
|
|
15847
|
+
success: result2.success,
|
|
15848
|
+
outputPath,
|
|
15849
|
+
durationMs: cycle.durationMs + result2.durationMs,
|
|
15850
|
+
error: failure2?.detail,
|
|
15851
|
+
failure: failure2
|
|
15852
|
+
};
|
|
15853
|
+
} finally {
|
|
15854
|
+
rmSync8(cycleDir, { recursive: true, force: true });
|
|
15855
|
+
}
|
|
15856
|
+
}
|
|
15557
15857
|
const inputSeek = mediaStart >= (metadata?.latestStreamLeadSeconds ?? 0);
|
|
15558
15858
|
const start = formatFilterNumber(mediaStart);
|
|
15559
15859
|
const timestampTrim = inputSeek ? null : `atrim=start=${start}:end=${formatFilterNumber(mediaStart + sourceDuration)},asetpts=PTS-${start}/TB,aresample=async=1:first_pts=0`;
|
|
@@ -15563,7 +15863,10 @@ async function extractAudioSegment(srcPath, outputPath, stage, mediaStart, durat
|
|
|
15563
15863
|
metadata,
|
|
15564
15864
|
normalizedPlaybackRate,
|
|
15565
15865
|
duration,
|
|
15566
|
-
|
|
15866
|
+
[
|
|
15867
|
+
warmUp > 0 ? `atrim=start=${warmUp},asetpts=PTS-STARTPTS` : timestampTrim,
|
|
15868
|
+
...options?.padToDuration ? ["apad"] : []
|
|
15869
|
+
].filter(Boolean).join(",") || null
|
|
15567
15870
|
);
|
|
15568
15871
|
const readFrom = fromSidecar ? audioSidecarUrl : srcPath;
|
|
15569
15872
|
const args = [
|
|
@@ -15574,7 +15877,7 @@ async function extractAudioSegment(srcPath, outputPath, stage, mediaStart, durat
|
|
|
15574
15877
|
readFrom
|
|
15575
15878
|
];
|
|
15576
15879
|
args.push("-vn", "-acodec", "pcm_s16le", "-ar", "48000", ...outputArgs);
|
|
15577
|
-
if (normalizedPlaybackRate !== 1) args.push("-t", String(duration));
|
|
15880
|
+
if (normalizedPlaybackRate !== 1 || options?.padToDuration) args.push("-t", String(duration));
|
|
15578
15881
|
args.push("-y", outputPath);
|
|
15579
15882
|
const result = await runFfmpeg(args, { signal, timeout: ffmpegProcessTimeout });
|
|
15580
15883
|
if (signal?.aborted) {
|
|
@@ -15606,6 +15909,17 @@ async function extractAudioSegment(srcPath, outputPath, stage, mediaStart, durat
|
|
|
15606
15909
|
failure
|
|
15607
15910
|
};
|
|
15608
15911
|
}
|
|
15912
|
+
function isRemoteElement(element, baseDir, compiledDir, config) {
|
|
15913
|
+
if (isHttpUrl(element.src)) return true;
|
|
15914
|
+
if (!config?.urlByAbsentLocalPath?.size) return false;
|
|
15915
|
+
try {
|
|
15916
|
+
return config.urlByAbsentLocalPath.has(
|
|
15917
|
+
resolveProjectRelativeSrc(element.src, baseDir, compiledDir)
|
|
15918
|
+
);
|
|
15919
|
+
} catch {
|
|
15920
|
+
return false;
|
|
15921
|
+
}
|
|
15922
|
+
}
|
|
15609
15923
|
async function generateSilence(outputPath, duration, signal, config) {
|
|
15610
15924
|
const ffmpegProcessTimeout = config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG.ffmpegProcessTimeout;
|
|
15611
15925
|
const outputDir = dirname7(outputPath);
|
|
@@ -15914,7 +16228,7 @@ async function mixGroupMembers(memberTracks, outputPath, totalDuration, signal,
|
|
|
15914
16228
|
try {
|
|
15915
16229
|
const summed = await sumInSlices(memberTracks, scratchDir, totalDuration, signal, config);
|
|
15916
16230
|
if (!summed.success) return summed;
|
|
15917
|
-
|
|
16231
|
+
renameWithRetry(summed.track.srcPath, outputPath);
|
|
15918
16232
|
return { success: true, degradedAutomation: summed.degradedAutomation };
|
|
15919
16233
|
} finally {
|
|
15920
16234
|
rmSync8(scratchDir, { recursive: true, force: true });
|
|
@@ -15956,12 +16270,15 @@ async function mixAudioTracks(tracks, outputPath, totalDuration, signal, config)
|
|
|
15956
16270
|
}
|
|
15957
16271
|
async function mixThroughFloatSum(tracks, masterChain, outputPath, workDir, totalDuration, signal, config) {
|
|
15958
16272
|
const sumPath = join14(workDir, "master-sum.wav");
|
|
16273
|
+
const mixStart = Date.now();
|
|
15959
16274
|
const sum = await mixAudioTracks(tracks, sumPath, totalDuration, signal, config);
|
|
15960
16275
|
if (!sum.success) return { ...sum, outputPath };
|
|
16276
|
+
const masterStart = Date.now();
|
|
15961
16277
|
const encoderInput = masterChain ? (await applyAudioFxChain(sumPath, masterChain, join14(workDir, "master-fx.wav"), {
|
|
15962
16278
|
trackId: "master",
|
|
15963
16279
|
signal
|
|
15964
16280
|
})).path : sumPath;
|
|
16281
|
+
const encodeStart = Date.now();
|
|
15965
16282
|
const encoded = await encodeAac(encoderInput, outputPath, totalDuration, {
|
|
15966
16283
|
signal,
|
|
15967
16284
|
timeout: config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG.ffmpegProcessTimeout
|
|
@@ -15981,8 +16298,17 @@ async function mixThroughFloatSum(tracks, masterChain, outputPath, workDir, tota
|
|
|
15981
16298
|
failures: [failure]
|
|
15982
16299
|
};
|
|
15983
16300
|
}
|
|
15984
|
-
if (config?.keepEncoderInputAt)
|
|
15985
|
-
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
|
+
};
|
|
15986
16312
|
}
|
|
15987
16313
|
async function processCompositionAudio(elements, baseDir, workDir, outputPath, totalDuration, signal, config, compiledDir) {
|
|
15988
16314
|
const startMs = Date.now();
|
|
@@ -16000,7 +16326,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
16000
16326
|
}
|
|
16001
16327
|
await Promise.all(
|
|
16002
16328
|
elements.map(
|
|
16003
|
-
(element, index) => inPrepareSlot(async () => {
|
|
16329
|
+
(element, index) => (isRemoteElement(element, baseDir, compiledDir, config) ? inRemotePrepareSlot : inPrepareSlot)(async () => {
|
|
16004
16330
|
if (effectiveSignal.aborted) {
|
|
16005
16331
|
failures.push({
|
|
16006
16332
|
stage: "cancelled",
|
|
@@ -16069,6 +16395,9 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
16069
16395
|
return;
|
|
16070
16396
|
}
|
|
16071
16397
|
if (element.end - element.start <= 0) {
|
|
16398
|
+
console.warn(
|
|
16399
|
+
`[audioMixer] ${element.id} has no data-duration or data-end; its length is unknown, so it plays to the end of its source`
|
|
16400
|
+
);
|
|
16072
16401
|
let metadata;
|
|
16073
16402
|
try {
|
|
16074
16403
|
metadata = await extractAudioMetadata(
|
|
@@ -16099,7 +16428,8 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
16099
16428
|
element.playbackRate,
|
|
16100
16429
|
effectiveSignal,
|
|
16101
16430
|
config,
|
|
16102
|
-
audioSidecarUrl
|
|
16431
|
+
audioSidecarUrl,
|
|
16432
|
+
{ loop: element.loop }
|
|
16103
16433
|
);
|
|
16104
16434
|
if (!extractResult.success) {
|
|
16105
16435
|
failures.push(
|
|
@@ -16125,7 +16455,9 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
16125
16455
|
element.end - element.start,
|
|
16126
16456
|
element.playbackRate,
|
|
16127
16457
|
effectiveSignal,
|
|
16128
|
-
config
|
|
16458
|
+
config,
|
|
16459
|
+
void 0,
|
|
16460
|
+
{ loop: element.loop }
|
|
16129
16461
|
);
|
|
16130
16462
|
if (!prepResult.success) {
|
|
16131
16463
|
failures.push(
|
|
@@ -16261,6 +16593,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
16261
16593
|
failures
|
|
16262
16594
|
};
|
|
16263
16595
|
};
|
|
16596
|
+
const prepareMs = Date.now() - startMs;
|
|
16264
16597
|
if (failures.length > 0) return bail();
|
|
16265
16598
|
let masterChain;
|
|
16266
16599
|
const masterFxJson = config?.masterFxChain;
|
|
@@ -16371,6 +16704,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
16371
16704
|
}
|
|
16372
16705
|
}
|
|
16373
16706
|
if (failures.length > 0) return bail();
|
|
16707
|
+
const groupsMs = Date.now() - startMs - prepareMs;
|
|
16374
16708
|
let mixResult;
|
|
16375
16709
|
try {
|
|
16376
16710
|
mixResult = tracks.length > 0 ? await mixThroughFloatSum(
|
|
@@ -16389,6 +16723,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
16389
16723
|
return {
|
|
16390
16724
|
...mixResult,
|
|
16391
16725
|
durationMs: Date.now() - startMs,
|
|
16726
|
+
phaseMs: { prepare: prepareMs, groups: groupsMs, ...mixResult.phaseMs },
|
|
16392
16727
|
// Both, when both degraded. `mixResult.error ?? degradedNote` reported only
|
|
16393
16728
|
// the outer mix and dropped the one that names which GROUPS lost their
|
|
16394
16729
|
// members' automation — two different losses, and the operator needs to
|
|
@@ -16400,18 +16735,18 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
16400
16735
|
// ../engine/src/services/parallelCoordinator.ts
|
|
16401
16736
|
import { cpus as cpus3, freemem } from "os";
|
|
16402
16737
|
import { existsSync as existsSync12, mkdirSync as mkdirSync8, readdirSync as readdirSync6 } from "fs";
|
|
16403
|
-
import { copyFile, readFile as readFile2
|
|
16738
|
+
import { copyFile, readFile as readFile2 } from "fs/promises";
|
|
16404
16739
|
import { join as join16 } from "path";
|
|
16405
16740
|
import { getHeapStatistics } from "v8";
|
|
16406
16741
|
|
|
16407
16742
|
// ../engine/src/utils/psnr.ts
|
|
16408
|
-
import { execFile as
|
|
16743
|
+
import { execFile as execFile4 } from "child_process";
|
|
16409
16744
|
import { mkdtemp, rm, writeFile } from "fs/promises";
|
|
16410
16745
|
import { tmpdir as tmpdir4 } from "os";
|
|
16411
16746
|
import { join as join15 } from "path";
|
|
16412
16747
|
import { promisify as promisify3 } from "util";
|
|
16413
16748
|
async function psnrDb(a, b) {
|
|
16414
|
-
const execFileP = promisify3(
|
|
16749
|
+
const execFileP = promisify3(execFile4);
|
|
16415
16750
|
const dir = await mkdtemp(join15(tmpdir4(), "hf-de-verify-"));
|
|
16416
16751
|
try {
|
|
16417
16752
|
const pa = join15(dir, "a.jpg");
|
|
@@ -16945,7 +17280,8 @@ async function executeWorkerTask(task, serverUrl, captureOptions, createBeforeCa
|
|
|
16945
17280
|
endFrame: task.endFrame,
|
|
16946
17281
|
frameStride: task.frameStride,
|
|
16947
17282
|
durationMs: Date.now() - startTime,
|
|
16948
|
-
perf
|
|
17283
|
+
perf,
|
|
17284
|
+
pageErrorLines: pageErrorLinesOf(activeSession)
|
|
16949
17285
|
};
|
|
16950
17286
|
} catch (error) {
|
|
16951
17287
|
const diagnostics = session ? selectWorkerDiagnostics(session.browserConsoleBuffer) : [];
|
|
@@ -16958,7 +17294,8 @@ async function executeWorkerTask(task, serverUrl, captureOptions, createBeforeCa
|
|
|
16958
17294
|
};
|
|
16959
17295
|
const failure = classifyCaptureFailure(error, {
|
|
16960
17296
|
signal,
|
|
16961
|
-
workerDiagnostics: [workerDiagnostic]
|
|
17297
|
+
workerDiagnostics: [workerDiagnostic],
|
|
17298
|
+
pageErrorLines: session ? pageErrorLinesOf(session) : void 0
|
|
16962
17299
|
});
|
|
16963
17300
|
onFailure?.(failure);
|
|
16964
17301
|
return {
|
|
@@ -16971,6 +17308,7 @@ async function executeWorkerTask(task, serverUrl, captureOptions, createBeforeCa
|
|
|
16971
17308
|
perf,
|
|
16972
17309
|
error: failure.message,
|
|
16973
17310
|
diagnostics: diagnostics.length > 0 ? diagnostics : void 0,
|
|
17311
|
+
pageErrorLines: session ? pageErrorLinesOf(session) : void 0,
|
|
16974
17312
|
failure
|
|
16975
17313
|
};
|
|
16976
17314
|
} finally {
|
|
@@ -16987,6 +17325,9 @@ function isPoolFatalWorkerFailure(failure, streaming) {
|
|
|
16987
17325
|
if (streaming) return failure.kind !== "cancelled";
|
|
16988
17326
|
return isFatalCaptureFailure(failure);
|
|
16989
17327
|
}
|
|
17328
|
+
function pageErrorLinesOf(session) {
|
|
17329
|
+
return session.browserConsoleBuffer.filter((line) => line.includes("PAGEERROR"));
|
|
17330
|
+
}
|
|
16990
17331
|
function createPoolFailureHandler(args) {
|
|
16991
17332
|
let firstFatalFailure;
|
|
16992
17333
|
return {
|
|
@@ -17078,7 +17419,8 @@ async function executeParallelCapture(serverUrl, workDir, tasks, captureOptions,
|
|
|
17078
17419
|
kind: representative?.kind ?? "io",
|
|
17079
17420
|
message: `[Parallel] Capture failed: ${errorMessages}`,
|
|
17080
17421
|
cause: representative,
|
|
17081
|
-
workerDiagnostics
|
|
17422
|
+
workerDiagnostics,
|
|
17423
|
+
pageErrorLines: [...new Set(results.flatMap((result) => result.pageErrorLines ?? []))]
|
|
17082
17424
|
});
|
|
17083
17425
|
}
|
|
17084
17426
|
return results;
|
|
@@ -17096,7 +17438,7 @@ async function mergeWorkerFrames(workDir, tasks, outputDir) {
|
|
|
17096
17438
|
const sourcePath = join16(task.outputDir, file);
|
|
17097
17439
|
const targetPath = join16(outputDir, file);
|
|
17098
17440
|
try {
|
|
17099
|
-
await
|
|
17441
|
+
await renameWithRetryAsync(sourcePath, targetPath);
|
|
17100
17442
|
} catch {
|
|
17101
17443
|
await copyFile(sourcePath, targetPath);
|
|
17102
17444
|
}
|
|
@@ -17644,6 +17986,11 @@ export {
|
|
|
17644
17986
|
formatFfmpegError,
|
|
17645
17987
|
describeFfmpegFailure,
|
|
17646
17988
|
runFfmpeg,
|
|
17989
|
+
declareContentAddressedUrl,
|
|
17990
|
+
declareProbeFactsUrl,
|
|
17991
|
+
PROBE_FACTS_VERSION,
|
|
17992
|
+
buildProbeFactsText,
|
|
17993
|
+
resolvePlayableVideoDuration,
|
|
17647
17994
|
probeMediaProfile,
|
|
17648
17995
|
extractMediaMetadata,
|
|
17649
17996
|
extractFinalVideoFrameTimestamp,
|
|
@@ -17682,6 +18029,8 @@ export {
|
|
|
17682
18029
|
fetchPublicHttpsText,
|
|
17683
18030
|
downloadToTemp,
|
|
17684
18031
|
isHttpUrl,
|
|
18032
|
+
renameWithRetry,
|
|
18033
|
+
renameWithRetryAsync,
|
|
17685
18034
|
directorySizeBytes,
|
|
17686
18035
|
gcExtractionCache,
|
|
17687
18036
|
VIDEO_FRAME_FORMATS,
|
|
@@ -17696,8 +18045,8 @@ export {
|
|
|
17696
18045
|
parseVideoElements,
|
|
17697
18046
|
parseImageElements,
|
|
17698
18047
|
extractVideoFramesRange,
|
|
17699
|
-
resolvePlayableVideoDuration,
|
|
17700
18048
|
isVideoPastTimelineEnd,
|
|
18049
|
+
rebaseVideoToWindow,
|
|
17701
18050
|
resolveTimelineExtractionWindow,
|
|
17702
18051
|
resolveFinalFrameExtractionWindow,
|
|
17703
18052
|
resolveVideoExtractionWindow,
|