@hyperframes/producer 0.4.4 → 0.4.5
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/index.js +79 -62
- package/dist/index.js.map +4 -4
- package/dist/public-server.js +79 -62
- package/dist/public-server.js.map +4 -4
- package/dist/services/htmlCompiler.d.ts.map +1 -1
- package/dist/services/renderOrchestrator.d.ts +5 -0
- package/dist/services/renderOrchestrator.d.ts.map +1 -1
- package/dist/utils/paths.d.ts +35 -0
- package/dist/utils/paths.d.ts.map +1 -1
- package/package.json +3 -3
package/dist/public-server.js
CHANGED
|
@@ -57866,7 +57866,7 @@ var require_util2 = __commonJS({
|
|
|
57866
57866
|
}
|
|
57867
57867
|
path12 = url.path;
|
|
57868
57868
|
}
|
|
57869
|
-
var
|
|
57869
|
+
var isAbsolute3 = exports.isAbsolute(path12);
|
|
57870
57870
|
var parts = path12.split(/\/+/);
|
|
57871
57871
|
for (var part, up = 0, i = parts.length - 1; i >= 0; i--) {
|
|
57872
57872
|
part = parts[i];
|
|
@@ -57886,7 +57886,7 @@ var require_util2 = __commonJS({
|
|
|
57886
57886
|
}
|
|
57887
57887
|
path12 = parts.join("/");
|
|
57888
57888
|
if (path12 === "") {
|
|
57889
|
-
path12 =
|
|
57889
|
+
path12 = isAbsolute3 ? "/" : ".";
|
|
57890
57890
|
}
|
|
57891
57891
|
if (url) {
|
|
57892
57892
|
url.path = path12;
|
|
@@ -57931,7 +57931,7 @@ var require_util2 = __commonJS({
|
|
|
57931
57931
|
exports.isAbsolute = function(aPath) {
|
|
57932
57932
|
return aPath.charAt(0) === "/" || urlRegexp.test(aPath);
|
|
57933
57933
|
};
|
|
57934
|
-
function
|
|
57934
|
+
function relative3(aRoot, aPath) {
|
|
57935
57935
|
if (aRoot === "") {
|
|
57936
57936
|
aRoot = ".";
|
|
57937
57937
|
}
|
|
@@ -57950,7 +57950,7 @@ var require_util2 = __commonJS({
|
|
|
57950
57950
|
}
|
|
57951
57951
|
return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1);
|
|
57952
57952
|
}
|
|
57953
|
-
exports.relative =
|
|
57953
|
+
exports.relative = relative3;
|
|
57954
57954
|
var supportsNullProto = (function() {
|
|
57955
57955
|
var obj = /* @__PURE__ */ Object.create(null);
|
|
57956
57956
|
return !("__proto__" in obj);
|
|
@@ -95503,10 +95503,10 @@ function compareDocumentPosition(nodeA, nodeB) {
|
|
|
95503
95503
|
function uniqueSort(nodes) {
|
|
95504
95504
|
nodes = nodes.filter((node, i, arr) => !arr.includes(node, i + 1));
|
|
95505
95505
|
nodes.sort((a, b) => {
|
|
95506
|
-
const
|
|
95507
|
-
if (
|
|
95506
|
+
const relative3 = compareDocumentPosition(a, b);
|
|
95507
|
+
if (relative3 & DocumentPosition.PRECEDING) {
|
|
95508
95508
|
return -1;
|
|
95509
|
-
} else if (
|
|
95509
|
+
} else if (relative3 & DocumentPosition.FOLLOWING) {
|
|
95510
95510
|
return 1;
|
|
95511
95511
|
}
|
|
95512
95512
|
return 0;
|
|
@@ -105931,7 +105931,7 @@ async function mergeWorkerFrames(workDir, tasks, outputDir) {
|
|
|
105931
105931
|
}
|
|
105932
105932
|
|
|
105933
105933
|
// src/services/renderOrchestrator.ts
|
|
105934
|
-
import { join as
|
|
105934
|
+
import { join as join15, dirname as dirname10, resolve as resolve10 } from "path";
|
|
105935
105935
|
import { randomUUID } from "crypto";
|
|
105936
105936
|
import { freemem as freemem2 } from "os";
|
|
105937
105937
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
@@ -106291,13 +106291,41 @@ function createFileServer2(options) {
|
|
|
106291
106291
|
|
|
106292
106292
|
// src/services/htmlCompiler.ts
|
|
106293
106293
|
import { readFileSync as readFileSync8, existsSync as existsSync14, mkdirSync as mkdirSync9 } from "fs";
|
|
106294
|
-
import { join as
|
|
106294
|
+
import { join as join14, dirname as dirname9, resolve as resolve9 } from "path";
|
|
106295
106295
|
import postcss from "postcss";
|
|
106296
106296
|
|
|
106297
|
+
// src/utils/paths.ts
|
|
106298
|
+
import { resolve as resolve8, basename as basename2, join as join12, relative as relative2, isAbsolute as isAbsolute2 } from "node:path";
|
|
106299
|
+
var DEFAULT_RENDERS_DIR = process.env.PRODUCER_RENDERS_DIR ?? resolve8(new URL(import.meta.url).pathname, "../../..", "renders");
|
|
106300
|
+
function isPathInside(childPath, parentPath) {
|
|
106301
|
+
const absChild = resolve8(childPath);
|
|
106302
|
+
const absParent = resolve8(parentPath);
|
|
106303
|
+
if (absChild === absParent) return true;
|
|
106304
|
+
const rel = relative2(absParent, absChild);
|
|
106305
|
+
return rel !== "" && !rel.startsWith("..") && !isAbsolute2(rel);
|
|
106306
|
+
}
|
|
106307
|
+
function toExternalAssetKey(absPath) {
|
|
106308
|
+
if (absPath.startsWith("hf-ext/")) return absPath;
|
|
106309
|
+
let normalised = absPath.replace(/\\/g, "/");
|
|
106310
|
+
normalised = normalised.replace(/^\/\/\?\/UNC\//i, "//");
|
|
106311
|
+
normalised = normalised.replace(/^\/\/\?\//, "");
|
|
106312
|
+
normalised = normalised.replace(/^\/\/([^/]+)\//, "unc/$1/");
|
|
106313
|
+
normalised = normalised.replace(/^\/+/, "");
|
|
106314
|
+
normalised = normalised.replace(/^([A-Za-z]):\/?/, "$1/");
|
|
106315
|
+
return "hf-ext/" + normalised;
|
|
106316
|
+
}
|
|
106317
|
+
function resolveRenderPaths(projectDir, outputPath, rendersDir = DEFAULT_RENDERS_DIR) {
|
|
106318
|
+
const absoluteProjectDir = resolve8(projectDir);
|
|
106319
|
+
const projectName = basename2(absoluteProjectDir);
|
|
106320
|
+
const resolvedOutputPath = outputPath ?? join12(rendersDir, `${projectName}.mp4`);
|
|
106321
|
+
const absoluteOutputPath = resolve8(resolvedOutputPath);
|
|
106322
|
+
return { absoluteProjectDir, absoluteOutputPath };
|
|
106323
|
+
}
|
|
106324
|
+
|
|
106297
106325
|
// src/services/deterministicFonts.ts
|
|
106298
106326
|
import { existsSync as existsSync13, mkdirSync as mkdirSync8, readFileSync as readFileSync7, writeFileSync as writeFileSync3 } from "node:fs";
|
|
106299
106327
|
import { homedir as homedir2 } from "node:os";
|
|
106300
|
-
import { join as
|
|
106328
|
+
import { join as join13 } from "node:path";
|
|
106301
106329
|
|
|
106302
106330
|
// src/services/fontData.generated.ts
|
|
106303
106331
|
var EMBEDDED_FONT_DATA = /* @__PURE__ */ new Map([
|
|
@@ -106575,20 +106603,20 @@ function warnUnresolvedFonts(unresolved) {
|
|
|
106575
106603
|
Docs: https://hyperframes.heygen.com/docs/fonts`
|
|
106576
106604
|
);
|
|
106577
106605
|
}
|
|
106578
|
-
var GOOGLE_FONTS_CACHE_DIR =
|
|
106606
|
+
var GOOGLE_FONTS_CACHE_DIR = join13(homedir2(), ".cache", "hyperframes", "fonts");
|
|
106579
106607
|
var WOFF2_USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36";
|
|
106580
106608
|
function fontSlug(familyName) {
|
|
106581
106609
|
return familyName.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
106582
106610
|
}
|
|
106583
106611
|
function fontCacheDir(slug) {
|
|
106584
|
-
const dir =
|
|
106612
|
+
const dir = join13(GOOGLE_FONTS_CACHE_DIR, slug);
|
|
106585
106613
|
if (!existsSync13(dir)) {
|
|
106586
106614
|
mkdirSync8(dir, { recursive: true });
|
|
106587
106615
|
}
|
|
106588
106616
|
return dir;
|
|
106589
106617
|
}
|
|
106590
106618
|
function cachedWoff2Path(slug, weight, style) {
|
|
106591
|
-
return
|
|
106619
|
+
return join13(fontCacheDir(slug), `${weight}-${style}.woff2`);
|
|
106592
106620
|
}
|
|
106593
106621
|
async function fetchGoogleFont(familyName) {
|
|
106594
106622
|
const slug = fontSlug(familyName);
|
|
@@ -106690,7 +106718,7 @@ async function resolveMediaDuration(src, mediaStart, baseDir, downloadDir, tagNa
|
|
|
106690
106718
|
return { duration: 0, resolvedPath: src };
|
|
106691
106719
|
}
|
|
106692
106720
|
} else if (!filePath.startsWith("/")) {
|
|
106693
|
-
filePath =
|
|
106721
|
+
filePath = join14(baseDir, filePath);
|
|
106694
106722
|
}
|
|
106695
106723
|
if (!existsSync14(filePath)) {
|
|
106696
106724
|
return { duration: 0, resolvedPath: filePath };
|
|
@@ -106756,7 +106784,7 @@ async function parseSubCompositions(html, projectDir, downloadDir, parentOffset
|
|
|
106756
106784
|
const elEnd = elEndRaw ? parseFloat(elEndRaw) : Infinity;
|
|
106757
106785
|
const absoluteStart = parentOffset + elStart;
|
|
106758
106786
|
const absoluteEnd = Math.min(parentEnd, isFinite(elEnd) ? parentOffset + elEnd : Infinity);
|
|
106759
|
-
const filePath =
|
|
106787
|
+
const filePath = resolve9(projectDir, srcPath);
|
|
106760
106788
|
if (visited.has(filePath)) {
|
|
106761
106789
|
continue;
|
|
106762
106790
|
}
|
|
@@ -106956,7 +106984,7 @@ function inlineSubCompositions(html, subCompositions, projectDir) {
|
|
|
106956
106984
|
if (!srcPath) continue;
|
|
106957
106985
|
let compHtml = subCompositions.get(srcPath) || null;
|
|
106958
106986
|
if (!compHtml) {
|
|
106959
|
-
const filePath =
|
|
106987
|
+
const filePath = resolve9(projectDir, srcPath);
|
|
106960
106988
|
if (existsSync14(filePath)) {
|
|
106961
106989
|
compHtml = readFileSync8(filePath, "utf-8");
|
|
106962
106990
|
}
|
|
@@ -107169,7 +107197,7 @@ ${safeText}
|
|
|
107169
107197
|
return result;
|
|
107170
107198
|
}
|
|
107171
107199
|
function collectExternalAssets(html, projectDir) {
|
|
107172
|
-
const absProjectDir =
|
|
107200
|
+
const absProjectDir = resolve9(projectDir);
|
|
107173
107201
|
const externalAssets = /* @__PURE__ */ new Map();
|
|
107174
107202
|
const CSS_URL_RE2 = /\burl\(\s*(["']?)([^)"']+)\1\s*\)/g;
|
|
107175
107203
|
function processPath(rawPath) {
|
|
@@ -107177,12 +107205,12 @@ function collectExternalAssets(html, projectDir) {
|
|
|
107177
107205
|
if (!trimmed || trimmed.startsWith("/") || trimmed.startsWith("http://") || trimmed.startsWith("https://") || trimmed.startsWith("//") || trimmed.startsWith("data:") || trimmed.startsWith("#")) {
|
|
107178
107206
|
return null;
|
|
107179
107207
|
}
|
|
107180
|
-
const absPath =
|
|
107181
|
-
if (
|
|
107208
|
+
const absPath = resolve9(absProjectDir, trimmed);
|
|
107209
|
+
if (isPathInside(absPath, absProjectDir)) {
|
|
107182
107210
|
return null;
|
|
107183
107211
|
}
|
|
107184
107212
|
if (!existsSync14(absPath)) return null;
|
|
107185
|
-
const safeKey =
|
|
107213
|
+
const safeKey = toExternalAssetKey(absPath);
|
|
107186
107214
|
externalAssets.set(safeKey, absPath);
|
|
107187
107215
|
return safeKey;
|
|
107188
107216
|
}
|
|
@@ -107254,7 +107282,7 @@ async function compileForRender(projectDir, htmlPath, downloadDir) {
|
|
|
107254
107282
|
const audios = dedupeElementsById([...mainAudios, ...subAudios]);
|
|
107255
107283
|
for (const video of videos) {
|
|
107256
107284
|
if (isHttpUrl(video.src)) continue;
|
|
107257
|
-
const videoPath =
|
|
107285
|
+
const videoPath = resolve9(projectDir, video.src);
|
|
107258
107286
|
const reencode = `ffmpeg -i "${video.src}" -c:v libx264 -r 30 -g 30 -keyint_min 30 -movflags +faststart -c:a copy output.mp4`;
|
|
107259
107287
|
Promise.all([analyzeKeyframeIntervals(videoPath), extractVideoMetadata(videoPath)]).then(([analysis, metadata]) => {
|
|
107260
107288
|
if (analysis.isProblematic) {
|
|
@@ -107481,17 +107509,17 @@ function installDebugLogger(logPath, log = defaultLogger) {
|
|
|
107481
107509
|
};
|
|
107482
107510
|
}
|
|
107483
107511
|
function writeCompiledArtifacts(compiled, workDir, includeSummary) {
|
|
107484
|
-
const compileDir =
|
|
107512
|
+
const compileDir = join15(workDir, "compiled");
|
|
107485
107513
|
mkdirSync10(compileDir, { recursive: true });
|
|
107486
|
-
writeFileSync4(
|
|
107514
|
+
writeFileSync4(join15(compileDir, "index.html"), compiled.html, "utf-8");
|
|
107487
107515
|
for (const [srcPath, html] of compiled.subCompositions) {
|
|
107488
|
-
const outPath =
|
|
107516
|
+
const outPath = join15(compileDir, srcPath);
|
|
107489
107517
|
mkdirSync10(dirname10(outPath), { recursive: true });
|
|
107490
107518
|
writeFileSync4(outPath, html, "utf-8");
|
|
107491
107519
|
}
|
|
107492
107520
|
for (const [relativePath, absolutePath] of compiled.externalAssets) {
|
|
107493
|
-
const outPath =
|
|
107494
|
-
if (!outPath
|
|
107521
|
+
const outPath = resolve10(join15(compileDir, relativePath));
|
|
107522
|
+
if (!isPathInside(outPath, compileDir)) {
|
|
107495
107523
|
console.warn(`[Render] Skipping external asset with unsafe path: ${relativePath}`);
|
|
107496
107524
|
continue;
|
|
107497
107525
|
}
|
|
@@ -107519,7 +107547,7 @@ function writeCompiledArtifacts(compiled, workDir, includeSummary) {
|
|
|
107519
107547
|
})),
|
|
107520
107548
|
subCompositions: Array.from(compiled.subCompositions.keys())
|
|
107521
107549
|
};
|
|
107522
|
-
writeFileSync4(
|
|
107550
|
+
writeFileSync4(join15(compileDir, "summary.json"), JSON.stringify(summary, null, 2), "utf-8");
|
|
107523
107551
|
}
|
|
107524
107552
|
}
|
|
107525
107553
|
function createRenderJob(config2) {
|
|
@@ -107563,9 +107591,9 @@ function extractStandaloneEntryFromIndex(indexHtml, entryFile) {
|
|
|
107563
107591
|
}
|
|
107564
107592
|
async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSignal) {
|
|
107565
107593
|
const moduleDir = dirname10(fileURLToPath3(import.meta.url));
|
|
107566
|
-
const producerRoot = process.env.PRODUCER_RENDERS_DIR ?
|
|
107567
|
-
const debugDir =
|
|
107568
|
-
const workDir = job.config.debug ?
|
|
107594
|
+
const producerRoot = process.env.PRODUCER_RENDERS_DIR ? resolve10(process.env.PRODUCER_RENDERS_DIR, "..") : resolve10(moduleDir, "../..");
|
|
107595
|
+
const debugDir = join15(producerRoot, ".debug");
|
|
107596
|
+
const workDir = job.config.debug ? join15(debugDir, job.id) : join15(dirname10(outputPath), `work-${job.id}`);
|
|
107569
107597
|
const pipelineStart = Date.now();
|
|
107570
107598
|
const log = job.config.logger ?? defaultLogger;
|
|
107571
107599
|
let fileServer = null;
|
|
@@ -107573,7 +107601,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
107573
107601
|
let lastBrowserConsole = [];
|
|
107574
107602
|
let restoreLogger = null;
|
|
107575
107603
|
const perfStages = {};
|
|
107576
|
-
const perfOutputPath =
|
|
107604
|
+
const perfOutputPath = join15(workDir, "perf-summary.json");
|
|
107577
107605
|
const cfg = { ...job.config.producerConfig ?? resolveConfig() };
|
|
107578
107606
|
const outputFormat = job.config.format ?? "mp4";
|
|
107579
107607
|
const isWebm = outputFormat === "webm";
|
|
@@ -107595,19 +107623,19 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
107595
107623
|
assertNotAborted();
|
|
107596
107624
|
if (!existsSync15(workDir)) mkdirSync10(workDir, { recursive: true });
|
|
107597
107625
|
if (job.config.debug) {
|
|
107598
|
-
const logPath =
|
|
107626
|
+
const logPath = join15(workDir, "render.log");
|
|
107599
107627
|
restoreLogger = installDebugLogger(logPath, log);
|
|
107600
107628
|
}
|
|
107601
107629
|
const entryFile = job.config.entryFile || "index.html";
|
|
107602
|
-
let htmlPath =
|
|
107630
|
+
let htmlPath = join15(projectDir, entryFile);
|
|
107603
107631
|
if (!existsSync15(htmlPath)) {
|
|
107604
107632
|
throw new Error(`Entry file not found: ${htmlPath}`);
|
|
107605
107633
|
}
|
|
107606
107634
|
assertNotAborted();
|
|
107607
107635
|
const rawEntry = readFileSync9(htmlPath, "utf-8");
|
|
107608
107636
|
if (entryFile !== "index.html" && rawEntry.trimStart().startsWith("<template")) {
|
|
107609
|
-
const wrapperPath =
|
|
107610
|
-
const projectIndexPath =
|
|
107637
|
+
const wrapperPath = join15(workDir, "standalone-entry.html");
|
|
107638
|
+
const projectIndexPath = join15(projectDir, "index.html");
|
|
107611
107639
|
if (!existsSync15(projectIndexPath)) {
|
|
107612
107640
|
throw new Error(
|
|
107613
107641
|
`Template entry file "${entryFile}" requires a project index.html to extract its render shell.`
|
|
@@ -107631,7 +107659,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
107631
107659
|
const stage1Start = Date.now();
|
|
107632
107660
|
updateJobStatus(job, "preprocessing", "Compiling composition", 5, onProgress);
|
|
107633
107661
|
const compileStart = Date.now();
|
|
107634
|
-
let compiled = await compileForRender(projectDir, htmlPath,
|
|
107662
|
+
let compiled = await compileForRender(projectDir, htmlPath, join15(workDir, "downloads"));
|
|
107635
107663
|
assertNotAborted();
|
|
107636
107664
|
perfStages.compileOnlyMs = Date.now() - compileStart;
|
|
107637
107665
|
writeCompiledArtifacts(compiled, workDir, Boolean(job.config.debug));
|
|
@@ -107660,7 +107688,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
107660
107688
|
reasons.push(`${compiled.unresolvedCompositions.length} unresolved composition(s)`);
|
|
107661
107689
|
fileServer = await createFileServer2({
|
|
107662
107690
|
projectDir,
|
|
107663
|
-
compiledDir:
|
|
107691
|
+
compiledDir: join15(workDir, "compiled"),
|
|
107664
107692
|
port: 0
|
|
107665
107693
|
});
|
|
107666
107694
|
assertNotAborted();
|
|
@@ -107673,7 +107701,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
107673
107701
|
};
|
|
107674
107702
|
probeSession = await createCaptureSession(
|
|
107675
107703
|
fileServer.url,
|
|
107676
|
-
|
|
107704
|
+
join15(workDir, "probe"),
|
|
107677
107705
|
captureOpts,
|
|
107678
107706
|
null,
|
|
107679
107707
|
cfg
|
|
@@ -107705,7 +107733,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
107705
107733
|
compiled,
|
|
107706
107734
|
resolutions,
|
|
107707
107735
|
projectDir,
|
|
107708
|
-
|
|
107736
|
+
join15(workDir, "downloads")
|
|
107709
107737
|
);
|
|
107710
107738
|
assertNotAborted();
|
|
107711
107739
|
composition.videos = compiled.videos;
|
|
@@ -107840,12 +107868,12 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
107840
107868
|
const stage2Start = Date.now();
|
|
107841
107869
|
updateJobStatus(job, "preprocessing", "Extracting video frames", 10, onProgress);
|
|
107842
107870
|
let frameLookup = null;
|
|
107843
|
-
const compiledDir =
|
|
107871
|
+
const compiledDir = join15(workDir, "compiled");
|
|
107844
107872
|
if (composition.videos.length > 0) {
|
|
107845
107873
|
const extractionResult = await extractAllVideoFrames(
|
|
107846
107874
|
composition.videos,
|
|
107847
107875
|
projectDir,
|
|
107848
|
-
{ fps: job.config.fps, outputDir:
|
|
107876
|
+
{ fps: job.config.fps, outputDir: join15(workDir, "video-frames") },
|
|
107849
107877
|
abortSignal,
|
|
107850
107878
|
void 0,
|
|
107851
107879
|
compiledDir
|
|
@@ -107879,13 +107907,13 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
107879
107907
|
}
|
|
107880
107908
|
const stage3Start = Date.now();
|
|
107881
107909
|
updateJobStatus(job, "preprocessing", "Processing audio tracks", 20, onProgress);
|
|
107882
|
-
const audioOutputPath =
|
|
107910
|
+
const audioOutputPath = join15(workDir, "audio.aac");
|
|
107883
107911
|
let hasAudio = false;
|
|
107884
107912
|
if (composition.audios.length > 0) {
|
|
107885
107913
|
const audioResult = await processCompositionAudio(
|
|
107886
107914
|
composition.audios,
|
|
107887
107915
|
projectDir,
|
|
107888
|
-
|
|
107916
|
+
join15(workDir, "audio-work"),
|
|
107889
107917
|
audioOutputPath,
|
|
107890
107918
|
job.duration,
|
|
107891
107919
|
abortSignal,
|
|
@@ -107903,12 +107931,12 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
107903
107931
|
if (!fileServer) {
|
|
107904
107932
|
fileServer = await createFileServer2({
|
|
107905
107933
|
projectDir,
|
|
107906
|
-
compiledDir:
|
|
107934
|
+
compiledDir: join15(workDir, "compiled"),
|
|
107907
107935
|
port: 0
|
|
107908
107936
|
});
|
|
107909
107937
|
assertNotAborted();
|
|
107910
107938
|
}
|
|
107911
|
-
const framesDir =
|
|
107939
|
+
const framesDir = join15(workDir, "captured-frames");
|
|
107912
107940
|
if (!existsSync15(framesDir)) mkdirSync10(framesDir, { recursive: true });
|
|
107913
107941
|
const captureOptions = {
|
|
107914
107942
|
width,
|
|
@@ -107920,7 +107948,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
107920
107948
|
const workerCount = calculateOptimalWorkers(job.totalFrames, job.config.workers, cfg);
|
|
107921
107949
|
const FORMAT_EXT = { mp4: ".mp4", webm: ".webm", mov: ".mov" };
|
|
107922
107950
|
const videoExt = FORMAT_EXT[outputFormat] ?? ".mp4";
|
|
107923
|
-
const videoOnlyPath =
|
|
107951
|
+
const videoOnlyPath = join15(workDir, `video-only${videoExt}`);
|
|
107924
107952
|
const preset = getEncoderPreset(job.config.quality, outputFormat);
|
|
107925
107953
|
const effectiveQuality = job.config.crf ?? preset.quality;
|
|
107926
107954
|
const effectiveBitrate = job.config.videoBitrate;
|
|
@@ -108196,7 +108224,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
108196
108224
|
}
|
|
108197
108225
|
if (job.config.debug) {
|
|
108198
108226
|
if (existsSync15(outputPath)) {
|
|
108199
|
-
const debugOutput =
|
|
108227
|
+
const debugOutput = join15(workDir, `output${videoExt}`);
|
|
108200
108228
|
copyFileSync2(outputPath, debugOutput);
|
|
108201
108229
|
}
|
|
108202
108230
|
} else {
|
|
@@ -108291,7 +108319,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
108291
108319
|
|
|
108292
108320
|
// src/services/hyperframeLint.ts
|
|
108293
108321
|
import { existsSync as existsSync16, readFileSync as readFileSync10, statSync as statSync6 } from "node:fs";
|
|
108294
|
-
import { resolve as
|
|
108322
|
+
import { resolve as resolve11, join as join16 } from "node:path";
|
|
108295
108323
|
function isStringRecord(value) {
|
|
108296
108324
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
108297
108325
|
return false;
|
|
@@ -108318,7 +108346,7 @@ function pickEntryFile(files, preferredEntryFile) {
|
|
|
108318
108346
|
return null;
|
|
108319
108347
|
}
|
|
108320
108348
|
function readProjectEntryFile(projectDir, preferredEntryFile) {
|
|
108321
|
-
const absProjectDir =
|
|
108349
|
+
const absProjectDir = resolve11(projectDir);
|
|
108322
108350
|
if (!existsSync16(absProjectDir) || !statSync6(absProjectDir).isDirectory()) {
|
|
108323
108351
|
return { error: `Project directory not found: ${absProjectDir}` };
|
|
108324
108352
|
}
|
|
@@ -108326,7 +108354,7 @@ function readProjectEntryFile(projectDir, preferredEntryFile) {
|
|
|
108326
108354
|
(value) => typeof value === "string" && value.trim().length > 0
|
|
108327
108355
|
);
|
|
108328
108356
|
for (const entryFile of entryCandidates) {
|
|
108329
|
-
const absoluteEntryPath =
|
|
108357
|
+
const absoluteEntryPath = resolve11(absProjectDir, entryFile);
|
|
108330
108358
|
if (!absoluteEntryPath.startsWith(absProjectDir)) {
|
|
108331
108359
|
return { error: `Entry file must stay inside project directory: ${entryFile}` };
|
|
108332
108360
|
}
|
|
@@ -108339,7 +108367,7 @@ function readProjectEntryFile(projectDir, preferredEntryFile) {
|
|
|
108339
108367
|
}
|
|
108340
108368
|
}
|
|
108341
108369
|
return {
|
|
108342
|
-
error: `No HTML entry file found in project directory: ${
|
|
108370
|
+
error: `No HTML entry file found in project directory: ${join16(absProjectDir, preferredEntryFile || "index.html")}`
|
|
108343
108371
|
};
|
|
108344
108372
|
}
|
|
108345
108373
|
function prepareHyperframeLintBody(body) {
|
|
@@ -108379,17 +108407,6 @@ function runHyperframeLint(prepared) {
|
|
|
108379
108407
|
return lintHyperframeHtml(prepared.html, { filePath: prepared.entryFile });
|
|
108380
108408
|
}
|
|
108381
108409
|
|
|
108382
|
-
// src/utils/paths.ts
|
|
108383
|
-
import { resolve as resolve11, basename as basename2, join as join16 } from "node:path";
|
|
108384
|
-
var DEFAULT_RENDERS_DIR = process.env.PRODUCER_RENDERS_DIR ?? resolve11(new URL(import.meta.url).pathname, "../../..", "renders");
|
|
108385
|
-
function resolveRenderPaths(projectDir, outputPath, rendersDir = DEFAULT_RENDERS_DIR) {
|
|
108386
|
-
const absoluteProjectDir = resolve11(projectDir);
|
|
108387
|
-
const projectName = basename2(absoluteProjectDir);
|
|
108388
|
-
const resolvedOutputPath = outputPath ?? join16(rendersDir, `${projectName}.mp4`);
|
|
108389
|
-
const absoluteOutputPath = resolve11(resolvedOutputPath);
|
|
108390
|
-
return { absoluteProjectDir, absoluteOutputPath };
|
|
108391
|
-
}
|
|
108392
|
-
|
|
108393
108410
|
// src/utils/semaphore.ts
|
|
108394
108411
|
var Semaphore = class {
|
|
108395
108412
|
constructor(maxConcurrent) {
|