@hyperframes/producer 0.4.15 → 0.4.16
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 +341 -197
- package/dist/index.js.map +3 -3
- package/dist/public-server.js +341 -197
- package/dist/public-server.js.map +3 -3
- package/dist/services/renderOrchestrator.d.ts.map +1 -1
- package/dist/utils/ffprobe.d.ts +1 -1
- package/dist/utils/ffprobe.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 isAbsolute5 = 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 = isAbsolute5 ? "/" : ".";
|
|
57890
57890
|
}
|
|
57891
57891
|
if (url) {
|
|
57892
57892
|
url.path = path12;
|
|
@@ -104407,6 +104407,34 @@ function getGpuEncoderName(encoder, codec) {
|
|
|
104407
104407
|
return codec === "h264" ? "libx264" : "libx265";
|
|
104408
104408
|
}
|
|
104409
104409
|
}
|
|
104410
|
+
var NVENC_PRESET_MAP = {
|
|
104411
|
+
ultrafast: "p1",
|
|
104412
|
+
superfast: "p1",
|
|
104413
|
+
veryfast: "p2",
|
|
104414
|
+
faster: "p3",
|
|
104415
|
+
fast: "p4",
|
|
104416
|
+
medium: "p4",
|
|
104417
|
+
slow: "p5",
|
|
104418
|
+
slower: "p6",
|
|
104419
|
+
veryslow: "p7",
|
|
104420
|
+
placebo: "p7"
|
|
104421
|
+
};
|
|
104422
|
+
var QSV_PRESET_MAP = {
|
|
104423
|
+
ultrafast: "veryfast",
|
|
104424
|
+
superfast: "veryfast",
|
|
104425
|
+
placebo: "veryslow"
|
|
104426
|
+
};
|
|
104427
|
+
function mapPresetForGpuEncoder(encoder, preset) {
|
|
104428
|
+
switch (encoder) {
|
|
104429
|
+
case "nvenc":
|
|
104430
|
+
if (/^p[1-7]$/.test(preset)) return preset;
|
|
104431
|
+
return NVENC_PRESET_MAP[preset] ?? "p4";
|
|
104432
|
+
case "qsv":
|
|
104433
|
+
return QSV_PRESET_MAP[preset] ?? preset;
|
|
104434
|
+
default:
|
|
104435
|
+
return preset;
|
|
104436
|
+
}
|
|
104437
|
+
}
|
|
104410
104438
|
|
|
104411
104439
|
// ../engine/src/utils/hdr.ts
|
|
104412
104440
|
function isHdrColorSpace(cs) {
|
|
@@ -104450,6 +104478,16 @@ function analyzeCompositionHdr(colorSpaces) {
|
|
|
104450
104478
|
// ../engine/src/utils/runFfmpeg.ts
|
|
104451
104479
|
import { spawn as spawn4 } from "child_process";
|
|
104452
104480
|
var DEFAULT_TIMEOUT2 = 3e5;
|
|
104481
|
+
var DEFAULT_STDERR_TAIL_LINES = 15;
|
|
104482
|
+
function formatFfmpegError(exitCode, stderr, tailLines = DEFAULT_STDERR_TAIL_LINES) {
|
|
104483
|
+
const tail = (stderr ?? "").split(/\r?\n/).filter((line) => line.length > 0).slice(-tailLines).join("\n");
|
|
104484
|
+
if (exitCode === null) {
|
|
104485
|
+
return tail ? `[FFmpeg] ${tail}` : "[FFmpeg] process error";
|
|
104486
|
+
}
|
|
104487
|
+
return tail ? `FFmpeg exited with code ${exitCode}
|
|
104488
|
+
ffmpeg stderr (tail):
|
|
104489
|
+
${tail}` : `FFmpeg exited with code ${exitCode}`;
|
|
104490
|
+
}
|
|
104453
104491
|
async function runFfmpeg(args, opts) {
|
|
104454
104492
|
const startMs = Date.now();
|
|
104455
104493
|
const signal = opts?.signal;
|
|
@@ -104560,7 +104598,7 @@ function buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder = null) {
|
|
|
104560
104598
|
args.push("-c:v", encoderName);
|
|
104561
104599
|
switch (gpuEncoder) {
|
|
104562
104600
|
case "nvenc":
|
|
104563
|
-
args.push("-preset", preset);
|
|
104601
|
+
args.push("-preset", mapPresetForGpuEncoder("nvenc", preset));
|
|
104564
104602
|
if (bitrate) args.push("-b:v", bitrate);
|
|
104565
104603
|
else args.push("-cq", String(quality));
|
|
104566
104604
|
break;
|
|
@@ -104579,7 +104617,7 @@ function buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder = null) {
|
|
|
104579
104617
|
else args.push("-qp", String(quality));
|
|
104580
104618
|
break;
|
|
104581
104619
|
case "qsv":
|
|
104582
|
-
args.push("-preset", preset);
|
|
104620
|
+
args.push("-preset", mapPresetForGpuEncoder("qsv", preset));
|
|
104583
104621
|
if (bitrate) args.push("-b:v", bitrate);
|
|
104584
104622
|
else args.push("-global_quality", String(quality));
|
|
104585
104623
|
break;
|
|
@@ -104719,7 +104757,7 @@ async function encodeFramesFromDir(framesDir, framePattern, outputPath, options,
|
|
|
104719
104757
|
durationMs,
|
|
104720
104758
|
framesEncoded: 0,
|
|
104721
104759
|
fileSize: 0,
|
|
104722
|
-
error:
|
|
104760
|
+
error: formatFfmpegError(code, stderr)
|
|
104723
104761
|
});
|
|
104724
104762
|
return;
|
|
104725
104763
|
}
|
|
@@ -104889,7 +104927,7 @@ async function muxVideoWithAudio(videoPath, audioPath, outputPath, signal, confi
|
|
|
104889
104927
|
success: result.success,
|
|
104890
104928
|
outputPath,
|
|
104891
104929
|
durationMs: result.durationMs,
|
|
104892
|
-
error: !result.success ? result.exitCode
|
|
104930
|
+
error: !result.success ? formatFfmpegError(result.exitCode, result.stderr) : void 0
|
|
104893
104931
|
};
|
|
104894
104932
|
}
|
|
104895
104933
|
async function applyFaststart(inputPath, outputPath, signal, config2) {
|
|
@@ -104912,7 +104950,7 @@ async function applyFaststart(inputPath, outputPath, signal, config2) {
|
|
|
104912
104950
|
success: result.success,
|
|
104913
104951
|
outputPath,
|
|
104914
104952
|
durationMs: result.durationMs,
|
|
104915
|
-
error: !result.success ? result.exitCode
|
|
104953
|
+
error: !result.success ? formatFfmpegError(result.exitCode, result.stderr) : void 0
|
|
104916
104954
|
};
|
|
104917
104955
|
}
|
|
104918
104956
|
|
|
@@ -105005,7 +105043,7 @@ function buildStreamingArgs(options, outputPath, gpuEncoder = null) {
|
|
|
105005
105043
|
args.push("-c:v", encoderName);
|
|
105006
105044
|
switch (gpuEncoder) {
|
|
105007
105045
|
case "nvenc":
|
|
105008
|
-
args.push("-preset", preset);
|
|
105046
|
+
args.push("-preset", mapPresetForGpuEncoder("nvenc", preset));
|
|
105009
105047
|
if (bitrate) args.push("-b:v", bitrate);
|
|
105010
105048
|
else args.push("-cq", String(quality));
|
|
105011
105049
|
break;
|
|
@@ -105024,7 +105062,7 @@ function buildStreamingArgs(options, outputPath, gpuEncoder = null) {
|
|
|
105024
105062
|
else args.push("-qp", String(quality));
|
|
105025
105063
|
break;
|
|
105026
105064
|
case "qsv":
|
|
105027
|
-
args.push("-preset", preset);
|
|
105065
|
+
args.push("-preset", mapPresetForGpuEncoder("qsv", preset));
|
|
105028
105066
|
if (bitrate) args.push("-b:v", bitrate);
|
|
105029
105067
|
else args.push("-global_quality", String(quality));
|
|
105030
105068
|
break;
|
|
@@ -105180,7 +105218,7 @@ Process error: ${err.message}`;
|
|
|
105180
105218
|
success: false,
|
|
105181
105219
|
durationMs,
|
|
105182
105220
|
fileSize: 0,
|
|
105183
|
-
error:
|
|
105221
|
+
error: formatFfmpegError(exitCode, stderr)
|
|
105184
105222
|
};
|
|
105185
105223
|
}
|
|
105186
105224
|
const fileSize = existsSync6(outputPath) ? statSync4(outputPath).size : 0;
|
|
@@ -105194,7 +105232,7 @@ Process error: ${err.message}`;
|
|
|
105194
105232
|
// ../engine/src/services/videoFrameExtractor.ts
|
|
105195
105233
|
import { spawn as spawn8 } from "child_process";
|
|
105196
105234
|
import { existsSync as existsSync8, mkdirSync as mkdirSync5, readdirSync as readdirSync4, rmSync } from "fs";
|
|
105197
|
-
import { join as join8 } from "path";
|
|
105235
|
+
import { isAbsolute as isAbsolute2, join as join8 } from "path";
|
|
105198
105236
|
|
|
105199
105237
|
// ../engine/src/utils/ffprobe.ts
|
|
105200
105238
|
import { spawn as spawn7 } from "child_process";
|
|
@@ -105309,7 +105347,7 @@ function parseFrameRate(frameRateStr) {
|
|
|
105309
105347
|
}
|
|
105310
105348
|
return parseFloat(frameRateStr) || 0;
|
|
105311
105349
|
}
|
|
105312
|
-
async function
|
|
105350
|
+
async function extractMediaMetadata(filePath) {
|
|
105313
105351
|
const cached = videoMetadataCache.get(filePath);
|
|
105314
105352
|
if (cached) return cached;
|
|
105315
105353
|
const probePromise = (async () => {
|
|
@@ -105595,7 +105633,7 @@ async function extractVideoFramesRange(videoPath, videoId, startTime, duration,
|
|
|
105595
105633
|
const { fps, outputDir, quality = 95, format: format3 = "jpg" } = options;
|
|
105596
105634
|
const videoOutputDir = join8(outputDir, videoId);
|
|
105597
105635
|
if (!existsSync8(videoOutputDir)) mkdirSync5(videoOutputDir, { recursive: true });
|
|
105598
|
-
const metadata = await
|
|
105636
|
+
const metadata = await extractMediaMetadata(videoPath);
|
|
105599
105637
|
const framePattern = `frame_%05d.${format3}`;
|
|
105600
105638
|
const outputPattern = join8(videoOutputDir, framePattern);
|
|
105601
105639
|
const isHdr = isHdrColorSpace(metadata.colorSpace);
|
|
@@ -105744,7 +105782,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config2,
|
|
|
105744
105782
|
if (signal?.aborted) break;
|
|
105745
105783
|
try {
|
|
105746
105784
|
let videoPath = video.src;
|
|
105747
|
-
if (!videoPath
|
|
105785
|
+
if (!isAbsolute2(videoPath) && !isHttpUrl(videoPath)) {
|
|
105748
105786
|
const fromCompiled = compiledDir ? join8(compiledDir, videoPath) : null;
|
|
105749
105787
|
videoPath = fromCompiled && existsSync8(fromCompiled) ? fromCompiled : join8(baseDir, videoPath);
|
|
105750
105788
|
}
|
|
@@ -105764,7 +105802,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config2,
|
|
|
105764
105802
|
}
|
|
105765
105803
|
const videoColorSpaces = await Promise.all(
|
|
105766
105804
|
resolvedVideos.map(async ({ videoPath }) => {
|
|
105767
|
-
const metadata = await
|
|
105805
|
+
const metadata = await extractMediaMetadata(videoPath);
|
|
105768
105806
|
return metadata.colorSpace;
|
|
105769
105807
|
})
|
|
105770
105808
|
);
|
|
@@ -105797,7 +105835,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config2,
|
|
|
105797
105835
|
if (signal?.aborted) break;
|
|
105798
105836
|
const entry = resolvedVideos[i];
|
|
105799
105837
|
if (!entry) continue;
|
|
105800
|
-
const metadata = await
|
|
105838
|
+
const metadata = await extractMediaMetadata(entry.videoPath);
|
|
105801
105839
|
if (!metadata.isVFR) continue;
|
|
105802
105840
|
let segDuration = entry.video.end - entry.video.start;
|
|
105803
105841
|
if (!Number.isFinite(segDuration) || segDuration <= 0) {
|
|
@@ -105833,7 +105871,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config2,
|
|
|
105833
105871
|
try {
|
|
105834
105872
|
let videoDuration = video.end - video.start;
|
|
105835
105873
|
if (!Number.isFinite(videoDuration) || videoDuration <= 0) {
|
|
105836
|
-
const metadata = await
|
|
105874
|
+
const metadata = await extractMediaMetadata(videoPath);
|
|
105837
105875
|
const sourceDuration = metadata.durationSeconds - video.mediaStart;
|
|
105838
105876
|
videoDuration = sourceDuration > 0 ? sourceDuration : metadata.durationSeconds;
|
|
105839
105877
|
video.end = video.start + videoDuration;
|
|
@@ -106208,7 +106246,7 @@ async function queryElementStacking(page, nativeHdrIds) {
|
|
|
106208
106246
|
|
|
106209
106247
|
// ../engine/src/services/audioMixer.ts
|
|
106210
106248
|
import { existsSync as existsSync9, mkdirSync as mkdirSync6, rmSync as rmSync2 } from "fs";
|
|
106211
|
-
import { join as join9, dirname as dirname7 } from "path";
|
|
106249
|
+
import { isAbsolute as isAbsolute3, join as join9, dirname as dirname7 } from "path";
|
|
106212
106250
|
function parseAudioElements(html) {
|
|
106213
106251
|
const elements = [];
|
|
106214
106252
|
const { document: document2 } = parseHTML(html);
|
|
@@ -106435,7 +106473,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
106435
106473
|
}
|
|
106436
106474
|
try {
|
|
106437
106475
|
let srcPath = element.src;
|
|
106438
|
-
if (!srcPath
|
|
106476
|
+
if (!isAbsolute3(srcPath) && !isHttpUrl(srcPath)) {
|
|
106439
106477
|
const fromCompiled = compiledDir ? join9(compiledDir, srcPath) : null;
|
|
106440
106478
|
srcPath = fromCompiled && existsSync9(fromCompiled) ? fromCompiled : join9(baseDir, srcPath);
|
|
106441
106479
|
}
|
|
@@ -107161,13 +107199,51 @@ function normalizeObjectFit(value) {
|
|
|
107161
107199
|
}
|
|
107162
107200
|
function parseTransformMatrix(css) {
|
|
107163
107201
|
if (!css || css === "none") return null;
|
|
107164
|
-
const
|
|
107202
|
+
const match2d = css.match(
|
|
107165
107203
|
/^matrix\(\s*([^,]+),\s*([^,]+),\s*([^,]+),\s*([^,]+),\s*([^,]+),\s*([^,)]+)\s*\)$/
|
|
107166
107204
|
);
|
|
107167
|
-
if (
|
|
107168
|
-
|
|
107169
|
-
|
|
107170
|
-
|
|
107205
|
+
if (match2d) {
|
|
107206
|
+
const values = match2d.slice(1, 7).map(Number);
|
|
107207
|
+
if (!values.every(Number.isFinite)) return null;
|
|
107208
|
+
return values;
|
|
107209
|
+
}
|
|
107210
|
+
const match3d = css.match(/^matrix3d\(\s*([^)]+)\)$/);
|
|
107211
|
+
if (match3d) {
|
|
107212
|
+
const raw2 = match3d[1];
|
|
107213
|
+
if (!raw2) return null;
|
|
107214
|
+
const parts = raw2.split(",").map((s) => Number(s.trim()));
|
|
107215
|
+
if (parts.length !== 16 || !parts.every(Number.isFinite)) return null;
|
|
107216
|
+
warnIfZSignificant(parts);
|
|
107217
|
+
return [
|
|
107218
|
+
parts[0],
|
|
107219
|
+
parts[1],
|
|
107220
|
+
parts[4],
|
|
107221
|
+
parts[5],
|
|
107222
|
+
parts[12],
|
|
107223
|
+
parts[13]
|
|
107224
|
+
];
|
|
107225
|
+
}
|
|
107226
|
+
return null;
|
|
107227
|
+
}
|
|
107228
|
+
var warnedZSignificant = false;
|
|
107229
|
+
var Z_EPSILON = 1e-6;
|
|
107230
|
+
function warnIfZSignificant(parts) {
|
|
107231
|
+
if (warnedZSignificant) return;
|
|
107232
|
+
const a3 = parts[8] ?? 0;
|
|
107233
|
+
const b3 = parts[9] ?? 0;
|
|
107234
|
+
const c1 = parts[2] ?? 0;
|
|
107235
|
+
const c2 = parts[6] ?? 0;
|
|
107236
|
+
const c3 = parts[10] ?? 1;
|
|
107237
|
+
const d1 = parts[3] ?? 0;
|
|
107238
|
+
const d2 = parts[7] ?? 0;
|
|
107239
|
+
const d3 = parts[11] ?? 0;
|
|
107240
|
+
const d4 = parts[15] ?? 1;
|
|
107241
|
+
if (Math.abs(a3) > Z_EPSILON || Math.abs(b3) > Z_EPSILON || Math.abs(c1) > Z_EPSILON || Math.abs(c2) > Z_EPSILON || Math.abs(c3 - 1) > Z_EPSILON || Math.abs(d1) > Z_EPSILON || Math.abs(d2) > Z_EPSILON || Math.abs(d3) > Z_EPSILON || Math.abs(d4 - 1) > Z_EPSILON) {
|
|
107242
|
+
warnedZSignificant = true;
|
|
107243
|
+
console.warn(
|
|
107244
|
+
`[alphaBlit] parseTransformMatrix received a matrix3d with non-trivial 3D components (a3=${a3}, b3=${b3}, c1=${c1}, c2=${c2}, c3=${c3}, d1=${d1}, d2=${d2}, d3=${d3}, d4=${d4}). The engine projects 3D transforms to 2D (m11, m12, m21, m22, m41, m42) and silently discards perspective and out-of-plane rotation. If your composition uses real 3D (rotateX/Y, perspective), the rendered output will not match the studio preview. Z translation (translateZ) is dropped by design and does not trigger this warning. This warning is emitted once per process.`
|
|
107245
|
+
);
|
|
107246
|
+
}
|
|
107171
107247
|
}
|
|
107172
107248
|
|
|
107173
107249
|
// ../engine/src/utils/layerCompositor.ts
|
|
@@ -108371,14 +108447,14 @@ import { join as join14, dirname as dirname9, resolve as resolve10 } from "path"
|
|
|
108371
108447
|
import postcss from "postcss";
|
|
108372
108448
|
|
|
108373
108449
|
// src/utils/paths.ts
|
|
108374
|
-
import { resolve as resolve9, basename as basename2, join as join12, relative as relative2, isAbsolute as
|
|
108450
|
+
import { resolve as resolve9, basename as basename2, join as join12, relative as relative2, isAbsolute as isAbsolute4 } from "node:path";
|
|
108375
108451
|
var DEFAULT_RENDERS_DIR = process.env.PRODUCER_RENDERS_DIR ?? resolve9(new URL(import.meta.url).pathname, "../../..", "renders");
|
|
108376
108452
|
function isPathInside2(childPath, parentPath) {
|
|
108377
108453
|
const absChild = resolve9(childPath);
|
|
108378
108454
|
const absParent = resolve9(parentPath);
|
|
108379
108455
|
if (absChild === absParent) return true;
|
|
108380
108456
|
const rel = relative2(absParent, absChild);
|
|
108381
|
-
return rel !== "" && !rel.startsWith("..") && !
|
|
108457
|
+
return rel !== "" && !rel.startsWith("..") && !isAbsolute4(rel);
|
|
108382
108458
|
}
|
|
108383
108459
|
function toExternalAssetKey(absPath) {
|
|
108384
108460
|
if (absPath.startsWith("hf-ext/")) return absPath;
|
|
@@ -108841,7 +108917,7 @@ async function resolveMediaDuration(src, mediaStart, baseDir, downloadDir, tagNa
|
|
|
108841
108917
|
if (!existsSync14(filePath)) {
|
|
108842
108918
|
return { duration: 0, resolvedPath: filePath };
|
|
108843
108919
|
}
|
|
108844
|
-
const metadata = tagName19 === "video" ? await
|
|
108920
|
+
const metadata = tagName19 === "video" ? await extractMediaMetadata(filePath) : await extractAudioMetadata(filePath);
|
|
108845
108921
|
const fileDuration = metadata.durationSeconds;
|
|
108846
108922
|
const effectiveDuration = fileDuration - mediaStart;
|
|
108847
108923
|
const duration = effectiveDuration > 0 ? effectiveDuration : fileDuration;
|
|
@@ -109424,7 +109500,7 @@ async function compileForRender(projectDir, htmlPath, downloadDir) {
|
|
|
109424
109500
|
if (isHttpUrl(video.src)) continue;
|
|
109425
109501
|
const videoPath = resolve10(projectDir, video.src);
|
|
109426
109502
|
const reencode = `ffmpeg -i "${video.src}" -c:v libx264 -r 30 -g 30 -keyint_min 30 -movflags +faststart -c:a copy output.mp4`;
|
|
109427
|
-
Promise.all([analyzeKeyframeIntervals(videoPath),
|
|
109503
|
+
Promise.all([analyzeKeyframeIntervals(videoPath), extractMediaMetadata(videoPath)]).then(([analysis, metadata]) => {
|
|
109428
109504
|
if (analysis.isProblematic) {
|
|
109429
109505
|
console.warn(
|
|
109430
109506
|
`[Compiler] WARNING: Video "${video.id}" has sparse keyframes (max interval: ${analysis.maxIntervalSeconds}s). This causes seek failures and frame freezing. Re-encode with: ${reencode}`
|
|
@@ -109623,6 +109699,21 @@ function getMaxFrameIndex(frameDir) {
|
|
|
109623
109699
|
frameDirMaxIndexCache.set(frameDir, max);
|
|
109624
109700
|
return max;
|
|
109625
109701
|
}
|
|
109702
|
+
function countNonZeroAlpha(rgba) {
|
|
109703
|
+
let n = 0;
|
|
109704
|
+
for (let p = 3; p < rgba.length; p += 4) {
|
|
109705
|
+
if (rgba[p] !== 0) n++;
|
|
109706
|
+
}
|
|
109707
|
+
return n;
|
|
109708
|
+
}
|
|
109709
|
+
function countNonZeroRgb48(buf) {
|
|
109710
|
+
let n = 0;
|
|
109711
|
+
for (let p = 0; p < buf.length; p += 6) {
|
|
109712
|
+
if (buf[p] !== 0 || buf[p + 1] !== 0 || buf[p + 2] !== 0 || buf[p + 3] !== 0 || buf[p + 4] !== 0 || buf[p + 5] !== 0)
|
|
109713
|
+
n++;
|
|
109714
|
+
}
|
|
109715
|
+
return n;
|
|
109716
|
+
}
|
|
109626
109717
|
var RenderCancelledError = class extends Error {
|
|
109627
109718
|
reason;
|
|
109628
109719
|
constructor(message = "render_cancelled", reason = "aborted") {
|
|
@@ -109830,6 +109921,165 @@ function blitHdrImageLayer(canvas, el, hdrImageBuffers, width, height, log, sour
|
|
|
109830
109921
|
}
|
|
109831
109922
|
}
|
|
109832
109923
|
}
|
|
109924
|
+
async function compositeHdrFrame(ctx, canvas, time, fullStacking, elementFilter, debugFrameIndex = -1) {
|
|
109925
|
+
const {
|
|
109926
|
+
log,
|
|
109927
|
+
domSession,
|
|
109928
|
+
beforeCaptureHook,
|
|
109929
|
+
width,
|
|
109930
|
+
height,
|
|
109931
|
+
fps,
|
|
109932
|
+
effectiveHdr,
|
|
109933
|
+
nativeHdrImageIds,
|
|
109934
|
+
hdrImageBuffers,
|
|
109935
|
+
hdrFrameDirs,
|
|
109936
|
+
hdrVideoStartTimes,
|
|
109937
|
+
imageTransfers,
|
|
109938
|
+
videoTransfers,
|
|
109939
|
+
debugDumpEnabled,
|
|
109940
|
+
debugDumpDir
|
|
109941
|
+
} = ctx;
|
|
109942
|
+
const filteredStacking = elementFilter ? fullStacking.filter((e) => elementFilter.has(e.id)) : fullStacking;
|
|
109943
|
+
const layers = groupIntoLayers(filteredStacking);
|
|
109944
|
+
const shouldLog = debugDumpEnabled && debugFrameIndex >= 0;
|
|
109945
|
+
if (shouldLog) {
|
|
109946
|
+
log.info("[diag] compositeToBuffer plan", {
|
|
109947
|
+
frame: debugFrameIndex,
|
|
109948
|
+
time: time.toFixed(3),
|
|
109949
|
+
filterSize: elementFilter?.size,
|
|
109950
|
+
fullStackingCount: fullStacking.length,
|
|
109951
|
+
filteredCount: filteredStacking.length,
|
|
109952
|
+
layerCount: layers.length,
|
|
109953
|
+
layers: layers.map(
|
|
109954
|
+
(l) => l.type === "hdr" ? {
|
|
109955
|
+
type: "hdr",
|
|
109956
|
+
id: l.element.id,
|
|
109957
|
+
z: l.element.zIndex,
|
|
109958
|
+
visible: l.element.visible,
|
|
109959
|
+
opacity: l.element.opacity,
|
|
109960
|
+
bounds: `${Math.round(l.element.x)},${Math.round(l.element.y)} ${Math.round(l.element.width)}x${Math.round(l.element.height)}`
|
|
109961
|
+
} : { type: "dom", ids: l.elementIds }
|
|
109962
|
+
)
|
|
109963
|
+
});
|
|
109964
|
+
}
|
|
109965
|
+
for (const [layerIdx, layer] of layers.entries()) {
|
|
109966
|
+
if (layer.type === "hdr") {
|
|
109967
|
+
const before2 = shouldLog ? countNonZeroRgb48(canvas) : 0;
|
|
109968
|
+
const isHdrImage = nativeHdrImageIds.has(layer.element.id);
|
|
109969
|
+
if (isHdrImage) {
|
|
109970
|
+
blitHdrImageLayer(
|
|
109971
|
+
canvas,
|
|
109972
|
+
layer.element,
|
|
109973
|
+
hdrImageBuffers,
|
|
109974
|
+
width,
|
|
109975
|
+
height,
|
|
109976
|
+
log,
|
|
109977
|
+
imageTransfers.get(layer.element.id),
|
|
109978
|
+
effectiveHdr.transfer
|
|
109979
|
+
);
|
|
109980
|
+
} else {
|
|
109981
|
+
blitHdrVideoLayer(
|
|
109982
|
+
canvas,
|
|
109983
|
+
layer.element,
|
|
109984
|
+
time,
|
|
109985
|
+
fps,
|
|
109986
|
+
hdrFrameDirs,
|
|
109987
|
+
hdrVideoStartTimes,
|
|
109988
|
+
width,
|
|
109989
|
+
height,
|
|
109990
|
+
log,
|
|
109991
|
+
videoTransfers.get(layer.element.id),
|
|
109992
|
+
effectiveHdr.transfer
|
|
109993
|
+
);
|
|
109994
|
+
}
|
|
109995
|
+
if (shouldLog) {
|
|
109996
|
+
const after2 = countNonZeroRgb48(canvas);
|
|
109997
|
+
if (isHdrImage) {
|
|
109998
|
+
const buf = hdrImageBuffers.get(layer.element.id);
|
|
109999
|
+
log.info("[diag] hdr layer blit", {
|
|
110000
|
+
frame: debugFrameIndex,
|
|
110001
|
+
layerIdx,
|
|
110002
|
+
id: layer.element.id,
|
|
110003
|
+
kind: "image",
|
|
110004
|
+
pixelsAdded: after2 - before2,
|
|
110005
|
+
totalNonZero: after2,
|
|
110006
|
+
bufferDecoded: !!buf,
|
|
110007
|
+
bufferDims: buf ? `${buf.width}x${buf.height}` : null
|
|
110008
|
+
});
|
|
110009
|
+
} else {
|
|
110010
|
+
const frameDir = hdrFrameDirs.get(layer.element.id);
|
|
110011
|
+
const startTime = hdrVideoStartTimes.get(layer.element.id) ?? 0;
|
|
110012
|
+
const localTime = time - startTime;
|
|
110013
|
+
const frameNum = Math.floor(localTime * fps) + 1;
|
|
110014
|
+
const expectedFrame = frameDir ? join15(frameDir, `frame_${String(frameNum).padStart(4, "0")}.png`) : null;
|
|
110015
|
+
log.info("[diag] hdr layer blit", {
|
|
110016
|
+
frame: debugFrameIndex,
|
|
110017
|
+
layerIdx,
|
|
110018
|
+
id: layer.element.id,
|
|
110019
|
+
kind: "video",
|
|
110020
|
+
pixelsAdded: after2 - before2,
|
|
110021
|
+
totalNonZero: after2,
|
|
110022
|
+
startTime,
|
|
110023
|
+
localTime: localTime.toFixed(3),
|
|
110024
|
+
hdrFrameNum: frameNum,
|
|
110025
|
+
expectedFrame,
|
|
110026
|
+
expectedFrameExists: expectedFrame ? existsSync15(expectedFrame) : false
|
|
110027
|
+
});
|
|
110028
|
+
}
|
|
110029
|
+
}
|
|
110030
|
+
} else {
|
|
110031
|
+
const allElementIds = fullStacking.map((e) => e.id);
|
|
110032
|
+
const layerIds = new Set(layer.elementIds);
|
|
110033
|
+
const hideIds = allElementIds.filter((id) => !layerIds.has(id));
|
|
110034
|
+
await domSession.page.evaluate((t) => {
|
|
110035
|
+
if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
|
|
110036
|
+
}, time);
|
|
110037
|
+
if (beforeCaptureHook) {
|
|
110038
|
+
await beforeCaptureHook(domSession.page, time);
|
|
110039
|
+
}
|
|
110040
|
+
await applyDomLayerMask(domSession.page, layer.elementIds, hideIds);
|
|
110041
|
+
const domPng = await captureAlphaPng(domSession.page, width, height);
|
|
110042
|
+
await removeDomLayerMask(domSession.page, hideIds);
|
|
110043
|
+
try {
|
|
110044
|
+
const { data: domRgba } = decodePng(domPng);
|
|
110045
|
+
const before2 = shouldLog ? countNonZeroRgb48(canvas) : 0;
|
|
110046
|
+
const alphaPixels = shouldLog ? countNonZeroAlpha(domRgba) : 0;
|
|
110047
|
+
blitRgba8OverRgb48le(domRgba, canvas, width, height, effectiveHdr.transfer);
|
|
110048
|
+
if (shouldLog && debugDumpDir) {
|
|
110049
|
+
const after2 = countNonZeroRgb48(canvas);
|
|
110050
|
+
const dumpName = `frame_${String(debugFrameIndex).padStart(4, "0")}_layer_${String(layerIdx).padStart(2, "0")}_dom.png`;
|
|
110051
|
+
const dumpPath = join15(debugDumpDir, dumpName);
|
|
110052
|
+
writeFileSync4(dumpPath, domPng);
|
|
110053
|
+
log.info("[diag] dom layer blit", {
|
|
110054
|
+
frame: debugFrameIndex,
|
|
110055
|
+
layerIdx,
|
|
110056
|
+
layerIds: layer.elementIds,
|
|
110057
|
+
hideCount: hideIds.length,
|
|
110058
|
+
pngBytes: domPng.length,
|
|
110059
|
+
alphaPixels,
|
|
110060
|
+
pixelsAdded: after2 - before2,
|
|
110061
|
+
totalNonZero: after2,
|
|
110062
|
+
dumpPath
|
|
110063
|
+
});
|
|
110064
|
+
}
|
|
110065
|
+
} catch (err) {
|
|
110066
|
+
log.warn("DOM layer decode/blit failed; skipping overlay", {
|
|
110067
|
+
layerIds: layer.elementIds,
|
|
110068
|
+
error: err instanceof Error ? err.message : String(err)
|
|
110069
|
+
});
|
|
110070
|
+
}
|
|
110071
|
+
}
|
|
110072
|
+
}
|
|
110073
|
+
if (shouldLog && debugDumpDir) {
|
|
110074
|
+
const finalNonZero = countNonZeroRgb48(canvas);
|
|
110075
|
+
log.info("[diag] compositeToBuffer end", {
|
|
110076
|
+
frame: debugFrameIndex,
|
|
110077
|
+
finalNonZeroPixels: finalNonZero,
|
|
110078
|
+
totalPixels: width * height,
|
|
110079
|
+
coverage: (finalNonZero / (width * height) * 100).toFixed(1) + "%"
|
|
110080
|
+
});
|
|
110081
|
+
}
|
|
110082
|
+
}
|
|
109833
110083
|
function createRenderJob(config2) {
|
|
109834
110084
|
return {
|
|
109835
110085
|
id: randomUUID(),
|
|
@@ -110174,7 +110424,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110174
110424
|
videoPath = fromCompiled;
|
|
110175
110425
|
}
|
|
110176
110426
|
if (!existsSync15(videoPath)) return;
|
|
110177
|
-
const meta = await
|
|
110427
|
+
const meta = await extractMediaMetadata(videoPath);
|
|
110178
110428
|
if (isHdrColorSpace(meta.colorSpace)) {
|
|
110179
110429
|
nativeHdrVideoIds.add(v.id);
|
|
110180
110430
|
videoTransfers.set(v.id, detectTransfer(meta.colorSpace));
|
|
@@ -110195,7 +110445,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110195
110445
|
imgPath = fromCompiled;
|
|
110196
110446
|
}
|
|
110197
110447
|
if (!existsSync15(imgPath)) return null;
|
|
110198
|
-
const meta = await
|
|
110448
|
+
const meta = await extractMediaMetadata(imgPath);
|
|
110199
110449
|
if (isHdrColorSpace(meta.colorSpace)) {
|
|
110200
110450
|
nativeHdrImageIds.add(img.id);
|
|
110201
110451
|
imageTransfers.set(img.id, detectTransfer(meta.colorSpace));
|
|
@@ -110307,6 +110557,10 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110307
110557
|
format: needsAlpha ? "png" : "jpeg",
|
|
110308
110558
|
quality: needsAlpha ? void 0 : job.config.quality === "draft" ? 80 : 95
|
|
110309
110559
|
};
|
|
110560
|
+
const buildHdrCaptureOptions = () => ({
|
|
110561
|
+
...captureOptions,
|
|
110562
|
+
skipReadinessVideoIds: Array.from(nativeHdrVideoIds)
|
|
110563
|
+
});
|
|
110310
110564
|
const workerCount = calculateOptimalWorkers(totalFrames, job.config.workers, cfg);
|
|
110311
110565
|
const FORMAT_EXT = { mp4: ".mp4", webm: ".webm", mov: ".mov" };
|
|
110312
110566
|
const videoExt = FORMAT_EXT[outputFormat] ?? ".mp4";
|
|
@@ -110341,7 +110595,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110341
110595
|
const domSession = await createCaptureSession(
|
|
110342
110596
|
fileServer.url,
|
|
110343
110597
|
framesDir,
|
|
110344
|
-
|
|
110598
|
+
buildHdrCaptureOptions(),
|
|
110345
110599
|
createVideoFrameInjector(frameLookup),
|
|
110346
110600
|
cfg
|
|
110347
110601
|
);
|
|
@@ -110437,6 +110691,29 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110437
110691
|
}
|
|
110438
110692
|
}
|
|
110439
110693
|
}
|
|
110694
|
+
for (const [imageId, startTime] of hdrImageStartTimes) {
|
|
110695
|
+
if (hdrExtractionDims.has(imageId)) continue;
|
|
110696
|
+
const img = composition.images.find((i) => i.id === imageId);
|
|
110697
|
+
if (!img) continue;
|
|
110698
|
+
const duration = img.end - img.start;
|
|
110699
|
+
const retryTime = startTime + Math.min(0.5, duration * 0.1);
|
|
110700
|
+
await domSession.page.evaluate((t) => {
|
|
110701
|
+
if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
|
|
110702
|
+
}, retryTime);
|
|
110703
|
+
if (domSession.onBeforeCapture) {
|
|
110704
|
+
await domSession.onBeforeCapture(domSession.page, retryTime);
|
|
110705
|
+
}
|
|
110706
|
+
const retryStacking = await queryElementStacking(domSession.page, nativeHdrIds);
|
|
110707
|
+
for (const el of retryStacking) {
|
|
110708
|
+
if (el.id === imageId && el.isHdr && el.layoutWidth > 0 && el.layoutHeight > 0) {
|
|
110709
|
+
hdrExtractionDims.set(el.id, { width: el.layoutWidth, height: el.layoutHeight });
|
|
110710
|
+
if (!hdrImageFitInfo.has(el.id)) {
|
|
110711
|
+
hdrImageFitInfo.set(el.id, { fit: el.objectFit, position: el.objectPosition });
|
|
110712
|
+
}
|
|
110713
|
+
break;
|
|
110714
|
+
}
|
|
110715
|
+
}
|
|
110716
|
+
}
|
|
110440
110717
|
for (const [videoId, srcPath] of hdrVideoSrcPaths) {
|
|
110441
110718
|
const video = composition.videos.find((v) => v.id === videoId);
|
|
110442
110719
|
if (!video) continue;
|
|
@@ -110519,21 +110796,6 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110519
110796
|
}
|
|
110520
110797
|
assertNotAborted();
|
|
110521
110798
|
try {
|
|
110522
|
-
let countNonZeroAlpha2 = function(rgba) {
|
|
110523
|
-
let n = 0;
|
|
110524
|
-
for (let p = 3; p < rgba.length; p += 4) {
|
|
110525
|
-
if (rgba[p] !== 0) n++;
|
|
110526
|
-
}
|
|
110527
|
-
return n;
|
|
110528
|
-
}, countNonZeroRgb482 = function(buf) {
|
|
110529
|
-
let n = 0;
|
|
110530
|
-
for (let p = 0; p < buf.length; p += 6) {
|
|
110531
|
-
if (buf[p] !== 0 || buf[p + 1] !== 0 || buf[p + 2] !== 0 || buf[p + 3] !== 0 || buf[p + 4] !== 0 || buf[p + 5] !== 0)
|
|
110532
|
-
n++;
|
|
110533
|
-
}
|
|
110534
|
-
return n;
|
|
110535
|
-
};
|
|
110536
|
-
var countNonZeroAlpha = countNonZeroAlpha2, countNonZeroRgb48 = countNonZeroRgb482;
|
|
110537
110799
|
const beforeCaptureHook = domSession.onBeforeCapture;
|
|
110538
110800
|
const cleanedUpVideos = /* @__PURE__ */ new Set();
|
|
110539
110801
|
const hdrVideoEndTimes = /* @__PURE__ */ new Map();
|
|
@@ -110547,153 +110809,28 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110547
110809
|
if (debugDumpDir && !existsSync15(debugDumpDir)) {
|
|
110548
110810
|
mkdirSync10(debugDumpDir, { recursive: true });
|
|
110549
110811
|
}
|
|
110550
|
-
|
|
110551
|
-
|
|
110552
|
-
|
|
110553
|
-
|
|
110554
|
-
if (shouldLog) {
|
|
110555
|
-
log.info("[diag] compositeToBuffer plan", {
|
|
110556
|
-
frame: debugFrameIndex,
|
|
110557
|
-
time: time.toFixed(3),
|
|
110558
|
-
filterSize: elementFilter?.size,
|
|
110559
|
-
fullStackingCount: fullStacking.length,
|
|
110560
|
-
filteredCount: filteredStacking.length,
|
|
110561
|
-
layerCount: layers.length,
|
|
110562
|
-
layers: layers.map(
|
|
110563
|
-
(l) => l.type === "hdr" ? {
|
|
110564
|
-
type: "hdr",
|
|
110565
|
-
id: l.element.id,
|
|
110566
|
-
z: l.element.zIndex,
|
|
110567
|
-
visible: l.element.visible,
|
|
110568
|
-
opacity: l.element.opacity,
|
|
110569
|
-
bounds: `${Math.round(l.element.x)},${Math.round(l.element.y)} ${Math.round(l.element.width)}x${Math.round(l.element.height)}`
|
|
110570
|
-
} : { type: "dom", ids: l.elementIds }
|
|
110571
|
-
)
|
|
110572
|
-
});
|
|
110573
|
-
}
|
|
110574
|
-
for (const [layerIdx, layer] of layers.entries()) {
|
|
110575
|
-
if (layer.type === "hdr") {
|
|
110576
|
-
const before2 = shouldLog ? countNonZeroRgb482(canvas) : 0;
|
|
110577
|
-
const isHdrImage = nativeHdrImageIds.has(layer.element.id);
|
|
110578
|
-
if (isHdrImage) {
|
|
110579
|
-
blitHdrImageLayer(
|
|
110580
|
-
canvas,
|
|
110581
|
-
layer.element,
|
|
110582
|
-
hdrImageBuffers,
|
|
110583
|
-
width,
|
|
110584
|
-
height,
|
|
110585
|
-
log,
|
|
110586
|
-
imageTransfers.get(layer.element.id),
|
|
110587
|
-
effectiveHdr?.transfer
|
|
110588
|
-
);
|
|
110589
|
-
} else {
|
|
110590
|
-
blitHdrVideoLayer(
|
|
110591
|
-
canvas,
|
|
110592
|
-
layer.element,
|
|
110593
|
-
time,
|
|
110594
|
-
job.config.fps,
|
|
110595
|
-
hdrFrameDirs,
|
|
110596
|
-
hdrVideoStartTimes,
|
|
110597
|
-
width,
|
|
110598
|
-
height,
|
|
110599
|
-
log,
|
|
110600
|
-
videoTransfers.get(layer.element.id),
|
|
110601
|
-
effectiveHdr?.transfer
|
|
110602
|
-
);
|
|
110603
|
-
}
|
|
110604
|
-
if (shouldLog) {
|
|
110605
|
-
const after2 = countNonZeroRgb482(canvas);
|
|
110606
|
-
if (isHdrImage) {
|
|
110607
|
-
const buf = hdrImageBuffers.get(layer.element.id);
|
|
110608
|
-
log.info("[diag] hdr layer blit", {
|
|
110609
|
-
frame: debugFrameIndex,
|
|
110610
|
-
layerIdx,
|
|
110611
|
-
id: layer.element.id,
|
|
110612
|
-
kind: "image",
|
|
110613
|
-
pixelsAdded: after2 - before2,
|
|
110614
|
-
totalNonZero: after2,
|
|
110615
|
-
bufferDecoded: !!buf,
|
|
110616
|
-
bufferDims: buf ? `${buf.width}x${buf.height}` : null
|
|
110617
|
-
});
|
|
110618
|
-
} else {
|
|
110619
|
-
const frameDir = hdrFrameDirs.get(layer.element.id);
|
|
110620
|
-
const startTime = hdrVideoStartTimes.get(layer.element.id) ?? 0;
|
|
110621
|
-
const localTime = time - startTime;
|
|
110622
|
-
const frameNum = Math.floor(localTime * job.config.fps) + 1;
|
|
110623
|
-
const expectedFrame = frameDir ? join15(frameDir, `frame_${String(frameNum).padStart(4, "0")}.png`) : null;
|
|
110624
|
-
log.info("[diag] hdr layer blit", {
|
|
110625
|
-
frame: debugFrameIndex,
|
|
110626
|
-
layerIdx,
|
|
110627
|
-
id: layer.element.id,
|
|
110628
|
-
kind: "video",
|
|
110629
|
-
pixelsAdded: after2 - before2,
|
|
110630
|
-
totalNonZero: after2,
|
|
110631
|
-
startTime,
|
|
110632
|
-
localTime: localTime.toFixed(3),
|
|
110633
|
-
hdrFrameNum: frameNum,
|
|
110634
|
-
expectedFrame,
|
|
110635
|
-
expectedFrameExists: expectedFrame ? existsSync15(expectedFrame) : false
|
|
110636
|
-
});
|
|
110637
|
-
}
|
|
110638
|
-
}
|
|
110639
|
-
} else {
|
|
110640
|
-
const allElementIds = fullStacking.map((e) => e.id);
|
|
110641
|
-
const layerIds = new Set(layer.elementIds);
|
|
110642
|
-
const hideIds = allElementIds.filter((id) => !layerIds.has(id));
|
|
110643
|
-
await domSession.page.evaluate((t) => {
|
|
110644
|
-
if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
|
|
110645
|
-
}, time);
|
|
110646
|
-
if (beforeCaptureHook) {
|
|
110647
|
-
await beforeCaptureHook(domSession.page, time);
|
|
110648
|
-
}
|
|
110649
|
-
await applyDomLayerMask(domSession.page, layer.elementIds, hideIds);
|
|
110650
|
-
const domPng = await captureAlphaPng(domSession.page, width, height);
|
|
110651
|
-
await removeDomLayerMask(domSession.page, hideIds);
|
|
110652
|
-
try {
|
|
110653
|
-
const { data: domRgba } = decodePng(domPng);
|
|
110654
|
-
if (!effectiveHdr) {
|
|
110655
|
-
throw new Error(
|
|
110656
|
-
"Invariant violation: effectiveHdr is undefined inside HDR layer branch"
|
|
110657
|
-
);
|
|
110658
|
-
}
|
|
110659
|
-
const before2 = shouldLog ? countNonZeroRgb482(canvas) : 0;
|
|
110660
|
-
const alphaPixels = shouldLog ? countNonZeroAlpha2(domRgba) : 0;
|
|
110661
|
-
blitRgba8OverRgb48le(domRgba, canvas, width, height, effectiveHdr.transfer);
|
|
110662
|
-
if (shouldLog && debugDumpDir) {
|
|
110663
|
-
const after2 = countNonZeroRgb482(canvas);
|
|
110664
|
-
const dumpName = `frame_${String(debugFrameIndex).padStart(4, "0")}_layer_${String(layerIdx).padStart(2, "0")}_dom.png`;
|
|
110665
|
-
const dumpPath = join15(debugDumpDir, dumpName);
|
|
110666
|
-
writeFileSync4(dumpPath, domPng);
|
|
110667
|
-
log.info("[diag] dom layer blit", {
|
|
110668
|
-
frame: debugFrameIndex,
|
|
110669
|
-
layerIdx,
|
|
110670
|
-
layerIds: layer.elementIds,
|
|
110671
|
-
hideCount: hideIds.length,
|
|
110672
|
-
pngBytes: domPng.length,
|
|
110673
|
-
alphaPixels,
|
|
110674
|
-
pixelsAdded: after2 - before2,
|
|
110675
|
-
totalNonZero: after2,
|
|
110676
|
-
dumpPath
|
|
110677
|
-
});
|
|
110678
|
-
}
|
|
110679
|
-
} catch (err) {
|
|
110680
|
-
log.warn("DOM layer decode/blit failed; skipping overlay", {
|
|
110681
|
-
layerIds: layer.elementIds,
|
|
110682
|
-
error: err instanceof Error ? err.message : String(err)
|
|
110683
|
-
});
|
|
110684
|
-
}
|
|
110685
|
-
}
|
|
110686
|
-
}
|
|
110687
|
-
if (shouldLog && debugDumpDir) {
|
|
110688
|
-
const finalNonZero = countNonZeroRgb482(canvas);
|
|
110689
|
-
log.info("[diag] compositeToBuffer end", {
|
|
110690
|
-
frame: debugFrameIndex,
|
|
110691
|
-
finalNonZeroPixels: finalNonZero,
|
|
110692
|
-
totalPixels: width * height,
|
|
110693
|
-
coverage: (finalNonZero / (width * height) * 100).toFixed(1) + "%"
|
|
110694
|
-
});
|
|
110695
|
-
}
|
|
110812
|
+
if (!effectiveHdr) {
|
|
110813
|
+
throw new Error(
|
|
110814
|
+
"Internal: HDR render path entered without effectiveHdr \u2014 this is a bug."
|
|
110815
|
+
);
|
|
110696
110816
|
}
|
|
110817
|
+
const hdrCompositeCtx = {
|
|
110818
|
+
log,
|
|
110819
|
+
domSession,
|
|
110820
|
+
beforeCaptureHook,
|
|
110821
|
+
width,
|
|
110822
|
+
height,
|
|
110823
|
+
fps: job.config.fps,
|
|
110824
|
+
effectiveHdr,
|
|
110825
|
+
nativeHdrImageIds,
|
|
110826
|
+
hdrImageBuffers,
|
|
110827
|
+
hdrFrameDirs,
|
|
110828
|
+
hdrVideoStartTimes,
|
|
110829
|
+
imageTransfers,
|
|
110830
|
+
videoTransfers,
|
|
110831
|
+
debugDumpEnabled,
|
|
110832
|
+
debugDumpDir
|
|
110833
|
+
};
|
|
110697
110834
|
const bufSize = width * height * 6;
|
|
110698
110835
|
const hasTransitions = transitionRanges.length > 0;
|
|
110699
110836
|
const transBufferA = hasTransitions ? Buffer.alloc(bufSize) : null;
|
|
@@ -110801,7 +110938,14 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110801
110938
|
hdrEncoder.writeFrame(transOutput);
|
|
110802
110939
|
} else {
|
|
110803
110940
|
normalCanvas.fill(0);
|
|
110804
|
-
await
|
|
110941
|
+
await compositeHdrFrame(
|
|
110942
|
+
hdrCompositeCtx,
|
|
110943
|
+
normalCanvas,
|
|
110944
|
+
time,
|
|
110945
|
+
stackingInfo,
|
|
110946
|
+
void 0,
|
|
110947
|
+
i
|
|
110948
|
+
);
|
|
110805
110949
|
if (debugDumpEnabled && debugDumpDir && i % 30 === 0) {
|
|
110806
110950
|
const previewPath = join15(
|
|
110807
110951
|
debugDumpDir,
|
|
@@ -110920,7 +111064,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110920
111064
|
fileServer.url,
|
|
110921
111065
|
workDir,
|
|
110922
111066
|
tasks,
|
|
110923
|
-
|
|
111067
|
+
buildHdrCaptureOptions(),
|
|
110924
111068
|
() => createVideoFrameInjector(frameLookup),
|
|
110925
111069
|
abortSignal,
|
|
110926
111070
|
(progress) => {
|
|
@@ -110950,7 +111094,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110950
111094
|
const session = probeSession ?? await createCaptureSession(
|
|
110951
111095
|
fileServer.url,
|
|
110952
111096
|
framesDir,
|
|
110953
|
-
|
|
111097
|
+
buildHdrCaptureOptions(),
|
|
110954
111098
|
videoInjector,
|
|
110955
111099
|
cfg
|
|
110956
111100
|
);
|
|
@@ -111002,7 +111146,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
111002
111146
|
fileServer.url,
|
|
111003
111147
|
workDir,
|
|
111004
111148
|
tasks,
|
|
111005
|
-
|
|
111149
|
+
buildHdrCaptureOptions(),
|
|
111006
111150
|
() => createVideoFrameInjector(frameLookup),
|
|
111007
111151
|
abortSignal,
|
|
111008
111152
|
(progress) => {
|
|
@@ -111033,7 +111177,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
111033
111177
|
const session = probeSession ?? await createCaptureSession(
|
|
111034
111178
|
fileServer.url,
|
|
111035
111179
|
framesDir,
|
|
111036
|
-
|
|
111180
|
+
buildHdrCaptureOptions(),
|
|
111037
111181
|
videoInjector,
|
|
111038
111182
|
cfg
|
|
111039
111183
|
);
|