mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-08-31 02:41:44 +00:00
feat(cli): surface extract-cache dir in doctor + add --frames-cache-dir sugar
Windows users with the OS temp dir on a small system drive have hit C: exhaustion mid-render (Slack ts=1784219488 · CLI v0.7.58 · win32 15 GB / 8-core, ~5500 frames). The engine already honors HYPERFRAMES_EXTRACT_CACHE_DIR for relocation, but the knob was undocumented and invisible in diagnostics — the reporter had to piece together a 4-flag compound workaround including EXTRACT_CACHE_DIR=off. Changes: - Extract the env-var resolver into a public engine API (resolveExtractCacheDir, defaultExtractCacheDir, EXTRACT_CACHE_DIR_DISABLED_ALIASES) with a typed resolution shape distinguishing "disabled by user" vs "default" vs "env override". - Add a Frames-cache check to `hyperframes doctor` that reports the effective directory, its free space, source (env or default), and fails with a relocation hint when <2 GB free at that mount. - Add `hyperframes render --frames-cache-dir <path>` as discoverable CLI sugar for the env var, including the opt-out aliases (off/none/false/0) and CWD-safe absolute-path resolution. - Document the flag in docs/packages/cli.mdx with the field-signal citation, and add a render example row for the Windows workflow. - Cover both surfaces with unit tests (6 doctor cases + 4 engine cases including all disabled-alias variants). Refs Slack #hyperframes-cli-feedback ts=1784219488 (win32 v0.7.58). Co-authored-by: Via <via-heygen[bot]@users.noreply.github.com>
This commit is contained in:
@@ -720,6 +720,7 @@ Word-level transcripts (whisper output) are grouped into readable caption cues o
|
||||
| `--strict-variables` | — | off | Fail render if any `--variables` key is undeclared or has a wrong type vs the composition's `data-composition-variables`. Without this flag, mismatches print as warnings and the render continues. |
|
||||
| `--browser-timeout` | seconds (0.001–86400) | 60 | Puppeteer page-navigation timeout for the entry HTML. Increase when heavy compositions (many videos, fonts, or asset requests) cannot reach `domcontentloaded` within the default 60 s. The flag takes **seconds**; the env fallback `PRODUCER_PAGE_NAVIGATION_TIMEOUT_MS` takes **milliseconds**. This controls `page.goto` only — very heavy compositions may also need `PRODUCER_PUPPETEER_PROTOCOL_TIMEOUT_MS` and/or `PRODUCER_PLAYER_READY_TIMEOUT_MS` bumped (post-navigation `window.__hf` readiness has its own 45 s budget). |
|
||||
| `--protocol-timeout` | milliseconds (≥ 1000) | 300000 (5 min) | Puppeteer CDP protocol timeout — the per-call budget for `Runtime.callFunctionOn` seek/paint, `Page.captureScreenshot`, and other CDP round-trips. Raise on RAM-pressured hosts (≤ 8 GB), heavy-asset compositions (many videos + images), or when the render fails with `Runtime.callFunctionOn timed out` / `Target closed`. The default is auto-scaled per composition by output pixel area (a 4K comp bumps the ceiling proportionally, capped at 30 min); an explicit override sets the floor and disables scaling below it. Env fallback `PRODUCER_PUPPETEER_PROTOCOL_TIMEOUT_MS` (also **milliseconds**). |
|
||||
| `--frames-cache-dir` | path or `off` / `none` / `false` / `0` | `<tmpdir>/hyperframes-extract-cache-<uid>` | Directory for the content-addressed extracted-frame cache. Relocate it off the system drive when the OS temp directory lives on a small partition — long renders can accumulate multi-GB of frames, and on Windows `%TEMP%` defaults to `C:` (reporter `ts=1784219488`, CLI 0.7.58, 15 GB laptop: extract cache exhausted C: mid-render). Pass an opt-out alias (`off`, `none`, `false`, `0`) to disable caching entirely; frames then extract into the render's `workDir` and are cleaned up when the render ends. Env fallback `HYPERFRAMES_EXTRACT_CACHE_DIR`. `hyperframes doctor` reports the effective directory + free space at that location. |
|
||||
|
||||
CRF and target bitrate default to the `--quality` preset. Use `--crf` or `--video-bitrate` for fine-grained overrides; `RenderConfig.crf` and `RenderConfig.videoBitrate` accept the same overrides programmatically. Use `--video-frame-format png` when source videos are UI recordings, screen captures, or other color-sensitive clips that should avoid JPEG frame extraction.
|
||||
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
||||
import { buildDoctorReport, redactHome, parseToolVersion, type CheckOutcome } from "./doctor.js";
|
||||
import {
|
||||
buildDoctorReport,
|
||||
checkFramesCache,
|
||||
redactHome,
|
||||
parseToolVersion,
|
||||
type CheckOutcome,
|
||||
} from "./doctor.js";
|
||||
|
||||
// ── Fixtures ────────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -195,3 +201,74 @@ describe("buildDoctorReport", () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("checkFramesCache", () => {
|
||||
it("reports disabled state with the raw env value when the user opts out", () => {
|
||||
const result = checkFramesCache(
|
||||
{ HYPERFRAMES_EXTRACT_CACHE_DIR: "off" },
|
||||
() => 100_000,
|
||||
() => true,
|
||||
);
|
||||
expect(result.ok).toBe(true);
|
||||
expect(result.detail).toContain("Disabled (off)");
|
||||
expect(result.detail).toContain("per-render workDir");
|
||||
});
|
||||
|
||||
it("reports the effective directory + free space + default source when env is unset", () => {
|
||||
const result = checkFramesCache(
|
||||
{},
|
||||
() => 50_000, // ~48.8 GB
|
||||
() => true,
|
||||
);
|
||||
expect(result.ok).toBe(true);
|
||||
expect(result.detail).toContain("48.8 GB free");
|
||||
expect(result.detail).toContain("default");
|
||||
});
|
||||
|
||||
it("reports a positive env override with source: HYPERFRAMES_EXTRACT_CACHE_DIR", () => {
|
||||
const result = checkFramesCache(
|
||||
{ HYPERFRAMES_EXTRACT_CACHE_DIR: "/mnt/scratch/hf" },
|
||||
() => 10_000,
|
||||
() => true,
|
||||
);
|
||||
expect(result.ok).toBe(true);
|
||||
expect(result.detail).toContain("/mnt/scratch/hf");
|
||||
expect(result.detail).toContain("HYPERFRAMES_EXTRACT_CACHE_DIR");
|
||||
});
|
||||
|
||||
it("fails with a relocation hint when free space at the cache location is <2 GB", () => {
|
||||
const result = checkFramesCache(
|
||||
{ HYPERFRAMES_EXTRACT_CACHE_DIR: "/tmp/hf" },
|
||||
() => 512, // 0.5 GB
|
||||
() => true,
|
||||
);
|
||||
expect(result.ok).toBe(false);
|
||||
expect(result.hint).toContain("--frames-cache-dir");
|
||||
expect(result.hint).toContain("HYPERFRAMES_EXTRACT_CACHE_DIR");
|
||||
});
|
||||
|
||||
it("falls back to the first existing ancestor when the cache dir does not exist yet", () => {
|
||||
const seen: string[] = [];
|
||||
const result = checkFramesCache(
|
||||
{ HYPERFRAMES_EXTRACT_CACHE_DIR: "/mnt/scratch/newly/created/subdir" },
|
||||
(path) => {
|
||||
seen.push(path);
|
||||
return 20_000;
|
||||
},
|
||||
(path) => path === "/mnt/scratch",
|
||||
);
|
||||
expect(result.ok).toBe(true);
|
||||
// statfs was called against the walked-up ancestor, not the raw dir.
|
||||
expect(seen).toContain("/mnt/scratch");
|
||||
});
|
||||
|
||||
it("handles a null free-space reading without failing the check", () => {
|
||||
const result = checkFramesCache(
|
||||
{ HYPERFRAMES_EXTRACT_CACHE_DIR: "/mnt/scratch" },
|
||||
() => null,
|
||||
() => true,
|
||||
);
|
||||
expect(result.ok).toBe(true);
|
||||
expect(result.detail).toContain("free space unknown");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
// fallow-ignore-file complexity
|
||||
import { defineCommand } from "citty";
|
||||
import { execFileSync, execSync } from "node:child_process";
|
||||
import { existsSync } from "node:fs";
|
||||
import { platform } from "node:os";
|
||||
import { dirname } from "node:path";
|
||||
import { resolveExtractCacheDir } from "@hyperframes/engine";
|
||||
import type { Example } from "./_examples.js";
|
||||
import { c } from "../ui/colors.js";
|
||||
import { parseToolVersion, runEnvironmentChecks } from "../browser/preflight.js";
|
||||
@@ -133,6 +136,70 @@ function checkDisk(): CheckResult {
|
||||
return { ok: true, detail: `${freeGb} GB free` };
|
||||
}
|
||||
|
||||
/**
|
||||
* Report the effective extracted-frame cache directory. Long renders can
|
||||
* accumulate multi-GB of extracted video frames here; on Windows the OS
|
||||
* `%TEMP%` default lives on C:, so users with output on a data drive but the
|
||||
* OS on a small SSD have hit disk-exhaustion mid-render (field signal
|
||||
* `ts=1784219488` · CLI 0.7.58 · 15GB/8-core). Surfacing the effective path
|
||||
* + free space at that path lets `hyperframes doctor` catch the mismatch
|
||||
* before the render, and reminds users the relocation knob exists.
|
||||
*
|
||||
* `statfsSync` requires the path to exist. When the configured cache dir has
|
||||
* not been created yet, walk up to the nearest existing ancestor and report
|
||||
* the free space there (which is the same filesystem in practice — free space
|
||||
* is per-mount, not per-directory).
|
||||
*/
|
||||
export function checkFramesCache(
|
||||
env: Record<string, string | undefined> = process.env,
|
||||
freeDiskMb: (path: string) => number | null = getFreeDiskMb,
|
||||
fileExists: (path: string) => boolean = existsSync,
|
||||
): CheckResult {
|
||||
const resolution = resolveExtractCacheDir(env);
|
||||
if (resolution.disabled) {
|
||||
return {
|
||||
ok: true,
|
||||
detail: `Disabled (${resolution.rawValue}) — frames extract into per-render workDir`,
|
||||
};
|
||||
}
|
||||
const dir = resolution.dir;
|
||||
const probePath = firstExistingAncestor(dir, fileExists) ?? dir;
|
||||
const freeMb = freeDiskMb(probePath);
|
||||
if (freeMb === null) {
|
||||
return {
|
||||
ok: true,
|
||||
detail: `${dir} (free space unknown; ${sourceLabel(resolution.source)})`,
|
||||
};
|
||||
}
|
||||
const freeGb = (freeMb / 1024).toFixed(1);
|
||||
const suffix = `${freeGb} GB free at ${probePath} · ${sourceLabel(resolution.source)}`;
|
||||
if (freeMb < 2048) {
|
||||
return {
|
||||
ok: false,
|
||||
detail: `${dir} · ${suffix}`,
|
||||
hint:
|
||||
"Low free space at the extract cache location — long renders can exhaust the drive. " +
|
||||
"Relocate via HYPERFRAMES_EXTRACT_CACHE_DIR=<path> or `hyperframes render --frames-cache-dir <path>`.",
|
||||
};
|
||||
}
|
||||
return { ok: true, detail: `${dir} · ${suffix}` };
|
||||
}
|
||||
|
||||
function firstExistingAncestor(path: string, fileExists: (p: string) => boolean): string | null {
|
||||
let current = path;
|
||||
for (let i = 0; i < 64; i += 1) {
|
||||
if (fileExists(current)) return current;
|
||||
const parent = dirname(current);
|
||||
if (parent === current) return null;
|
||||
current = parent;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function sourceLabel(source: "env" | "default"): string {
|
||||
return source === "env" ? "HYPERFRAMES_EXTRACT_CACHE_DIR" : "default";
|
||||
}
|
||||
|
||||
function commandExists(command: string): boolean {
|
||||
try {
|
||||
execFileSync("which", [command], { stdio: "ignore", timeout: 5000 });
|
||||
@@ -269,6 +336,7 @@ export default defineCommand({
|
||||
{ name: "CPU", run: checkCPU },
|
||||
{ name: "Memory", run: checkMemory },
|
||||
{ name: "Disk", run: checkDisk },
|
||||
{ name: "Frames cache", run: () => checkFramesCache() },
|
||||
{ name: "Archive extractor", run: checkArchiveExtractor },
|
||||
];
|
||||
|
||||
|
||||
@@ -35,6 +35,10 @@ export const examples: Example[] = [
|
||||
["Deterministic render via Docker", "hyperframes render --docker --output deterministic.mp4"],
|
||||
["Parallel rendering with 6 workers", "hyperframes render --workers 6 --output fast.mp4"],
|
||||
["Opt out of browser GPU render", "hyperframes render --no-browser-gpu --output cpu.mp4"],
|
||||
[
|
||||
"Relocate frame cache off C: (Windows) or another small partition",
|
||||
"hyperframes render --frames-cache-dir D:/hf-cache --output out.mp4",
|
||||
],
|
||||
["HDR output (auto-detected)", "hyperframes render --output hdr-output.mp4"],
|
||||
[
|
||||
"Override composition variables (parametrized render)",
|
||||
@@ -396,6 +400,18 @@ export default defineCommand({
|
||||
// guard below leaves PRODUCER_EXPERIMENTAL_FAST_CAPTURE untouched and the
|
||||
// env fallback survives (matches the --low-memory-mode idiom).
|
||||
},
|
||||
"frames-cache-dir": {
|
||||
type: "string",
|
||||
description:
|
||||
"Directory for the content-addressed extracted-frame cache. " +
|
||||
"Use to relocate the cache off the system drive when the OS temp " +
|
||||
"directory lives on a small partition (e.g. Windows C: exhaustion " +
|
||||
'during long renders). Pass "off" / "none" / "false" / "0" to ' +
|
||||
"disable caching entirely (frames extract into the render's workDir " +
|
||||
"and are cleaned up when the render ends). Default: " +
|
||||
"<tmpdir>/hyperframes-extract-cache-<uid>. " +
|
||||
"Env: HYPERFRAMES_EXTRACT_CACHE_DIR.",
|
||||
},
|
||||
},
|
||||
// `run` is the citty handler for `hyperframes render` — sequential flag
|
||||
// validation + render dispatch. Inherited CRITICAL on main (CRAP 1290);
|
||||
@@ -579,6 +595,19 @@ export default defineCommand({
|
||||
: "false";
|
||||
}
|
||||
|
||||
// ── Override: extracted-frame cache directory ────────────────────────
|
||||
// Sugar for HYPERFRAMES_EXTRACT_CACHE_DIR. Set BEFORE resolveConfig() so
|
||||
// the env resolver picks up the CLI-supplied value. Disabling aliases
|
||||
// (off/none/false/0) pass through verbatim — the engine helper canonicalizes.
|
||||
// Positive paths are resolved to absolute so CWD changes downstream can't
|
||||
// stale them.
|
||||
if (typeof args["frames-cache-dir"] === "string" && args["frames-cache-dir"].trim() !== "") {
|
||||
const raw = args["frames-cache-dir"].trim();
|
||||
const normalized = raw.toLowerCase();
|
||||
const isDisableAlias = ["off", "none", "false", "0"].includes(normalized);
|
||||
process.env.HYPERFRAMES_EXTRACT_CACHE_DIR = isDisableAlias ? raw : resolve(raw);
|
||||
}
|
||||
|
||||
// ── Validate max-concurrent-renders ─────────────────────────────────
|
||||
if (args["max-concurrent-renders"] != null) {
|
||||
const parsed = parseInt(args["max-concurrent-renders"], 10);
|
||||
|
||||
@@ -8,6 +8,9 @@ import {
|
||||
shouldClampToScreenshotForConcreteGpu,
|
||||
applyConcreteGpuScreenshotClamp,
|
||||
shouldAutoDisableStreamingEncodeOnWin32Compound,
|
||||
resolveExtractCacheDir,
|
||||
defaultExtractCacheDir,
|
||||
EXTRACT_CACHE_DIR_DISABLED_ALIASES,
|
||||
} from "./config.js";
|
||||
import type { EngineConfig } from "./config.js";
|
||||
import { isLowMemorySystem } from "./services/systemMemory.js";
|
||||
@@ -798,3 +801,45 @@ describe("scaleProtocolTimeoutForComposition", () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("resolveExtractCacheDir", () => {
|
||||
it("returns the OS-default cache dir when the env var is unset", () => {
|
||||
const res = resolveExtractCacheDir({});
|
||||
expect(res.disabled).toBe(false);
|
||||
expect(res.source).toBe("default");
|
||||
if (!res.disabled) {
|
||||
expect(res.dir).toBe(defaultExtractCacheDir());
|
||||
}
|
||||
});
|
||||
|
||||
it("threads a positive env value through verbatim (source: env)", () => {
|
||||
const res = resolveExtractCacheDir({
|
||||
HYPERFRAMES_EXTRACT_CACHE_DIR: "D:/hf-cache",
|
||||
});
|
||||
expect(res.disabled).toBe(false);
|
||||
expect(res.source).toBe("env");
|
||||
if (!res.disabled) {
|
||||
expect(res.dir).toBe("D:/hf-cache");
|
||||
expect(res.rawValue).toBe("D:/hf-cache");
|
||||
}
|
||||
});
|
||||
|
||||
it.each(EXTRACT_CACHE_DIR_DISABLED_ALIASES.flatMap((v) => [v, v.toUpperCase(), ` ${v} `]))(
|
||||
"reports disabled for opt-out alias %s",
|
||||
(value) => {
|
||||
const res = resolveExtractCacheDir({ HYPERFRAMES_EXTRACT_CACHE_DIR: value });
|
||||
expect(res.disabled).toBe(true);
|
||||
if (res.disabled) {
|
||||
expect(res.dir).toBeUndefined();
|
||||
expect(res.rawValue).toBe(value);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
it("defaults to process.env when no env argument is passed", () => {
|
||||
// Signal-only smoke test — the previous callers rely on this default and
|
||||
// both engine.resolveConfig() and doctor's checkFramesCache() would break
|
||||
// silently if the signature drifted to require an env argument.
|
||||
expect(() => resolveExtractCacheDir()).not.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -420,6 +420,69 @@ export function shouldAutoDisableStreamingEncodeOnWin32Compound(opts: {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Result of resolving the extract cache directory from the env, decoupled from
|
||||
* the wider {@link resolveConfig} pipeline so `hyperframes doctor` (and any
|
||||
* other diagnostic surface) can report the exact same effective value the
|
||||
* renderer will use — including whether the user has explicitly disabled the
|
||||
* cache via `off`/`none`/`false`/`0`.
|
||||
*
|
||||
* - `dir: string` + `disabled: false` → renderer will use this directory.
|
||||
* `source` reports whether the value came from the env or the OS default.
|
||||
* - `dir: undefined` + `disabled: true` → user explicitly turned caching off;
|
||||
* frames extract into the per-render workDir (auto-cleaned when the render
|
||||
* ends). `rawValue` carries the exact string the user set.
|
||||
*/
|
||||
export type ExtractCacheDirResolution =
|
||||
| { dir: string; disabled: false; source: "env" | "default"; rawValue?: string }
|
||||
| { dir: undefined; disabled: true; source: "env"; rawValue: string };
|
||||
|
||||
/**
|
||||
* Env-var values that disable the extract cache entirely. Case-insensitive;
|
||||
* whitespace-trimmed. Kept as an exported constant so the CLI can echo the
|
||||
* accepted alias set in `--frames-cache-dir` help text without drift.
|
||||
*/
|
||||
export const EXTRACT_CACHE_DIR_DISABLED_ALIASES: readonly string[] = ["off", "none", "false", "0"];
|
||||
|
||||
/**
|
||||
* Compute the default extract-cache directory when the user has NOT set
|
||||
* `HYPERFRAMES_EXTRACT_CACHE_DIR`. Exported so downstream tests can reproduce
|
||||
* the exact path without duplicating the uid-suffix idiom.
|
||||
*/
|
||||
export function defaultExtractCacheDir(): string {
|
||||
return join(tmpdir(), `hyperframes-extract-cache-${process.getuid?.() ?? "u"}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the extract-cache directory from an environment (defaults to
|
||||
* `process.env`). Mirrors the internal helper used by {@link resolveConfig},
|
||||
* but returns a rich resolution object so callers can distinguish "disabled by
|
||||
* user" from "default location" without re-parsing the env value.
|
||||
*
|
||||
* See {@link ExtractCacheDirResolution} for the shape and its two states.
|
||||
*/
|
||||
export function resolveExtractCacheDir(
|
||||
env: Record<string, string | undefined> = process.env,
|
||||
): ExtractCacheDirResolution {
|
||||
const raw = env["HYPERFRAMES_EXTRACT_CACHE_DIR"];
|
||||
if (raw === undefined) {
|
||||
return { dir: defaultExtractCacheDir(), disabled: false, source: "default" };
|
||||
}
|
||||
const normalized = raw.trim().toLowerCase();
|
||||
if (EXTRACT_CACHE_DIR_DISABLED_ALIASES.includes(normalized)) {
|
||||
return { dir: undefined, disabled: true, source: "env", rawValue: raw };
|
||||
}
|
||||
return { dir: raw, disabled: false, source: "env", rawValue: raw };
|
||||
}
|
||||
|
||||
function resolveExtractCacheDirFromEnv(
|
||||
env: (key: string) => string | undefined,
|
||||
): string | undefined {
|
||||
const raw = env("HYPERFRAMES_EXTRACT_CACHE_DIR");
|
||||
return resolveExtractCacheDir(raw === undefined ? {} : { HYPERFRAMES_EXTRACT_CACHE_DIR: raw })
|
||||
.dir;
|
||||
}
|
||||
|
||||
function memoryAdaptiveCacheLimit(): number {
|
||||
const total = getSystemTotalMb();
|
||||
if (total < 4096) return 32;
|
||||
@@ -474,23 +537,6 @@ export function resolveConfig(overrides?: Partial<EngineConfig>): EngineConfig {
|
||||
const raw = env("HF_STATIC_DEDUP")?.trim().toLowerCase();
|
||||
return !(raw === "false" || raw === "off" || raw === "0");
|
||||
};
|
||||
const resolveExtractCacheDir = (): string | undefined => {
|
||||
const raw = env("HYPERFRAMES_EXTRACT_CACHE_DIR");
|
||||
if (raw === undefined) {
|
||||
return join(tmpdir(), `hyperframes-extract-cache-${process.getuid?.() ?? "u"}`);
|
||||
}
|
||||
const trimmed = raw.trim();
|
||||
const normalized = trimmed.toLowerCase();
|
||||
if (
|
||||
normalized === "off" ||
|
||||
normalized === "none" ||
|
||||
normalized === "false" ||
|
||||
normalized === "0"
|
||||
) {
|
||||
return undefined;
|
||||
}
|
||||
return raw;
|
||||
};
|
||||
|
||||
// Env-var layer (backward compat)
|
||||
const fromEnv: Partial<EngineConfig> = {
|
||||
@@ -589,7 +635,7 @@ export function resolveConfig(overrides?: Partial<EngineConfig>): EngineConfig {
|
||||
verifyRuntime: env("PRODUCER_VERIFY_HYPERFRAME_RUNTIME") !== "false",
|
||||
runtimeManifestPath: env("PRODUCER_HYPERFRAME_MANIFEST_PATH"),
|
||||
|
||||
extractCacheDir: resolveExtractCacheDir(),
|
||||
extractCacheDir: resolveExtractCacheDirFromEnv(env),
|
||||
extractCacheMaxBytes:
|
||||
envNum("HYPERFRAMES_EXTRACT_CACHE_MAX_MB", DEFAULT_CONFIG.extractCacheMaxBytes / 1024 ** 2) *
|
||||
1024 ** 2,
|
||||
|
||||
@@ -52,7 +52,11 @@ export {
|
||||
scaleProtocolTimeoutForComposition,
|
||||
shouldClampToScreenshotForConcreteGpu,
|
||||
applyConcreteGpuScreenshotClamp,
|
||||
resolveExtractCacheDir,
|
||||
defaultExtractCacheDir,
|
||||
EXTRACT_CACHE_DIR_DISABLED_ALIASES,
|
||||
type EngineConfig,
|
||||
type ExtractCacheDirResolution,
|
||||
} from "./config.js";
|
||||
export {
|
||||
DEFAULT_VP9_CPU_USED,
|
||||
|
||||
Reference in New Issue
Block a user