@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/index.js
CHANGED
|
@@ -57865,7 +57865,7 @@ var require_util2 = __commonJS({
|
|
|
57865
57865
|
}
|
|
57866
57866
|
path12 = url.path;
|
|
57867
57867
|
}
|
|
57868
|
-
var
|
|
57868
|
+
var isAbsolute5 = exports.isAbsolute(path12);
|
|
57869
57869
|
var parts = path12.split(/\/+/);
|
|
57870
57870
|
for (var part, up = 0, i = parts.length - 1; i >= 0; i--) {
|
|
57871
57871
|
part = parts[i];
|
|
@@ -57885,7 +57885,7 @@ var require_util2 = __commonJS({
|
|
|
57885
57885
|
}
|
|
57886
57886
|
path12 = parts.join("/");
|
|
57887
57887
|
if (path12 === "") {
|
|
57888
|
-
path12 =
|
|
57888
|
+
path12 = isAbsolute5 ? "/" : ".";
|
|
57889
57889
|
}
|
|
57890
57890
|
if (url) {
|
|
57891
57891
|
url.path = path12;
|
|
@@ -101618,6 +101618,34 @@ function getGpuEncoderName(encoder, codec) {
|
|
|
101618
101618
|
return codec === "h264" ? "libx264" : "libx265";
|
|
101619
101619
|
}
|
|
101620
101620
|
}
|
|
101621
|
+
var NVENC_PRESET_MAP = {
|
|
101622
|
+
ultrafast: "p1",
|
|
101623
|
+
superfast: "p1",
|
|
101624
|
+
veryfast: "p2",
|
|
101625
|
+
faster: "p3",
|
|
101626
|
+
fast: "p4",
|
|
101627
|
+
medium: "p4",
|
|
101628
|
+
slow: "p5",
|
|
101629
|
+
slower: "p6",
|
|
101630
|
+
veryslow: "p7",
|
|
101631
|
+
placebo: "p7"
|
|
101632
|
+
};
|
|
101633
|
+
var QSV_PRESET_MAP = {
|
|
101634
|
+
ultrafast: "veryfast",
|
|
101635
|
+
superfast: "veryfast",
|
|
101636
|
+
placebo: "veryslow"
|
|
101637
|
+
};
|
|
101638
|
+
function mapPresetForGpuEncoder(encoder, preset) {
|
|
101639
|
+
switch (encoder) {
|
|
101640
|
+
case "nvenc":
|
|
101641
|
+
if (/^p[1-7]$/.test(preset)) return preset;
|
|
101642
|
+
return NVENC_PRESET_MAP[preset] ?? "p4";
|
|
101643
|
+
case "qsv":
|
|
101644
|
+
return QSV_PRESET_MAP[preset] ?? preset;
|
|
101645
|
+
default:
|
|
101646
|
+
return preset;
|
|
101647
|
+
}
|
|
101648
|
+
}
|
|
101621
101649
|
|
|
101622
101650
|
// ../engine/src/utils/hdr.ts
|
|
101623
101651
|
function isHdrColorSpace(cs) {
|
|
@@ -101661,6 +101689,16 @@ function analyzeCompositionHdr(colorSpaces) {
|
|
|
101661
101689
|
// ../engine/src/utils/runFfmpeg.ts
|
|
101662
101690
|
import { spawn as spawn4 } from "child_process";
|
|
101663
101691
|
var DEFAULT_TIMEOUT2 = 3e5;
|
|
101692
|
+
var DEFAULT_STDERR_TAIL_LINES = 15;
|
|
101693
|
+
function formatFfmpegError(exitCode, stderr, tailLines = DEFAULT_STDERR_TAIL_LINES) {
|
|
101694
|
+
const tail = (stderr ?? "").split(/\r?\n/).filter((line) => line.length > 0).slice(-tailLines).join("\n");
|
|
101695
|
+
if (exitCode === null) {
|
|
101696
|
+
return tail ? `[FFmpeg] ${tail}` : "[FFmpeg] process error";
|
|
101697
|
+
}
|
|
101698
|
+
return tail ? `FFmpeg exited with code ${exitCode}
|
|
101699
|
+
ffmpeg stderr (tail):
|
|
101700
|
+
${tail}` : `FFmpeg exited with code ${exitCode}`;
|
|
101701
|
+
}
|
|
101664
101702
|
async function runFfmpeg(args, opts) {
|
|
101665
101703
|
const startMs = Date.now();
|
|
101666
101704
|
const signal = opts?.signal;
|
|
@@ -101771,7 +101809,7 @@ function buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder = null) {
|
|
|
101771
101809
|
args.push("-c:v", encoderName);
|
|
101772
101810
|
switch (gpuEncoder) {
|
|
101773
101811
|
case "nvenc":
|
|
101774
|
-
args.push("-preset", preset);
|
|
101812
|
+
args.push("-preset", mapPresetForGpuEncoder("nvenc", preset));
|
|
101775
101813
|
if (bitrate) args.push("-b:v", bitrate);
|
|
101776
101814
|
else args.push("-cq", String(quality));
|
|
101777
101815
|
break;
|
|
@@ -101790,7 +101828,7 @@ function buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder = null) {
|
|
|
101790
101828
|
else args.push("-qp", String(quality));
|
|
101791
101829
|
break;
|
|
101792
101830
|
case "qsv":
|
|
101793
|
-
args.push("-preset", preset);
|
|
101831
|
+
args.push("-preset", mapPresetForGpuEncoder("qsv", preset));
|
|
101794
101832
|
if (bitrate) args.push("-b:v", bitrate);
|
|
101795
101833
|
else args.push("-global_quality", String(quality));
|
|
101796
101834
|
break;
|
|
@@ -101930,7 +101968,7 @@ async function encodeFramesFromDir(framesDir, framePattern, outputPath, options,
|
|
|
101930
101968
|
durationMs,
|
|
101931
101969
|
framesEncoded: 0,
|
|
101932
101970
|
fileSize: 0,
|
|
101933
|
-
error:
|
|
101971
|
+
error: formatFfmpegError(code, stderr)
|
|
101934
101972
|
});
|
|
101935
101973
|
return;
|
|
101936
101974
|
}
|
|
@@ -102100,7 +102138,7 @@ async function muxVideoWithAudio(videoPath, audioPath, outputPath, signal, confi
|
|
|
102100
102138
|
success: result.success,
|
|
102101
102139
|
outputPath,
|
|
102102
102140
|
durationMs: result.durationMs,
|
|
102103
|
-
error: !result.success ? result.exitCode
|
|
102141
|
+
error: !result.success ? formatFfmpegError(result.exitCode, result.stderr) : void 0
|
|
102104
102142
|
};
|
|
102105
102143
|
}
|
|
102106
102144
|
async function applyFaststart(inputPath, outputPath, signal, config2) {
|
|
@@ -102123,7 +102161,7 @@ async function applyFaststart(inputPath, outputPath, signal, config2) {
|
|
|
102123
102161
|
success: result.success,
|
|
102124
102162
|
outputPath,
|
|
102125
102163
|
durationMs: result.durationMs,
|
|
102126
|
-
error: !result.success ? result.exitCode
|
|
102164
|
+
error: !result.success ? formatFfmpegError(result.exitCode, result.stderr) : void 0
|
|
102127
102165
|
};
|
|
102128
102166
|
}
|
|
102129
102167
|
|
|
@@ -102216,7 +102254,7 @@ function buildStreamingArgs(options, outputPath, gpuEncoder = null) {
|
|
|
102216
102254
|
args.push("-c:v", encoderName);
|
|
102217
102255
|
switch (gpuEncoder) {
|
|
102218
102256
|
case "nvenc":
|
|
102219
|
-
args.push("-preset", preset);
|
|
102257
|
+
args.push("-preset", mapPresetForGpuEncoder("nvenc", preset));
|
|
102220
102258
|
if (bitrate) args.push("-b:v", bitrate);
|
|
102221
102259
|
else args.push("-cq", String(quality));
|
|
102222
102260
|
break;
|
|
@@ -102235,7 +102273,7 @@ function buildStreamingArgs(options, outputPath, gpuEncoder = null) {
|
|
|
102235
102273
|
else args.push("-qp", String(quality));
|
|
102236
102274
|
break;
|
|
102237
102275
|
case "qsv":
|
|
102238
|
-
args.push("-preset", preset);
|
|
102276
|
+
args.push("-preset", mapPresetForGpuEncoder("qsv", preset));
|
|
102239
102277
|
if (bitrate) args.push("-b:v", bitrate);
|
|
102240
102278
|
else args.push("-global_quality", String(quality));
|
|
102241
102279
|
break;
|
|
@@ -102391,7 +102429,7 @@ Process error: ${err.message}`;
|
|
|
102391
102429
|
success: false,
|
|
102392
102430
|
durationMs,
|
|
102393
102431
|
fileSize: 0,
|
|
102394
|
-
error:
|
|
102432
|
+
error: formatFfmpegError(exitCode, stderr)
|
|
102395
102433
|
};
|
|
102396
102434
|
}
|
|
102397
102435
|
const fileSize = existsSync6(outputPath) ? statSync4(outputPath).size : 0;
|
|
@@ -102405,7 +102443,7 @@ Process error: ${err.message}`;
|
|
|
102405
102443
|
// ../engine/src/services/videoFrameExtractor.ts
|
|
102406
102444
|
import { spawn as spawn8 } from "child_process";
|
|
102407
102445
|
import { existsSync as existsSync8, mkdirSync as mkdirSync5, readdirSync as readdirSync4, rmSync } from "fs";
|
|
102408
|
-
import { join as join8 } from "path";
|
|
102446
|
+
import { isAbsolute as isAbsolute2, join as join8 } from "path";
|
|
102409
102447
|
|
|
102410
102448
|
// ../engine/src/utils/ffprobe.ts
|
|
102411
102449
|
import { spawn as spawn7 } from "child_process";
|
|
@@ -102520,7 +102558,7 @@ function parseFrameRate(frameRateStr) {
|
|
|
102520
102558
|
}
|
|
102521
102559
|
return parseFloat(frameRateStr) || 0;
|
|
102522
102560
|
}
|
|
102523
|
-
async function
|
|
102561
|
+
async function extractMediaMetadata(filePath) {
|
|
102524
102562
|
const cached = videoMetadataCache.get(filePath);
|
|
102525
102563
|
if (cached) return cached;
|
|
102526
102564
|
const probePromise = (async () => {
|
|
@@ -102806,7 +102844,7 @@ async function extractVideoFramesRange(videoPath, videoId, startTime, duration,
|
|
|
102806
102844
|
const { fps, outputDir, quality = 95, format: format3 = "jpg" } = options;
|
|
102807
102845
|
const videoOutputDir = join8(outputDir, videoId);
|
|
102808
102846
|
if (!existsSync8(videoOutputDir)) mkdirSync5(videoOutputDir, { recursive: true });
|
|
102809
|
-
const metadata = await
|
|
102847
|
+
const metadata = await extractMediaMetadata(videoPath);
|
|
102810
102848
|
const framePattern = `frame_%05d.${format3}`;
|
|
102811
102849
|
const outputPattern = join8(videoOutputDir, framePattern);
|
|
102812
102850
|
const isHdr = isHdrColorSpace(metadata.colorSpace);
|
|
@@ -102955,7 +102993,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config2,
|
|
|
102955
102993
|
if (signal?.aborted) break;
|
|
102956
102994
|
try {
|
|
102957
102995
|
let videoPath = video.src;
|
|
102958
|
-
if (!videoPath
|
|
102996
|
+
if (!isAbsolute2(videoPath) && !isHttpUrl(videoPath)) {
|
|
102959
102997
|
const fromCompiled = compiledDir ? join8(compiledDir, videoPath) : null;
|
|
102960
102998
|
videoPath = fromCompiled && existsSync8(fromCompiled) ? fromCompiled : join8(baseDir, videoPath);
|
|
102961
102999
|
}
|
|
@@ -102975,7 +103013,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config2,
|
|
|
102975
103013
|
}
|
|
102976
103014
|
const videoColorSpaces = await Promise.all(
|
|
102977
103015
|
resolvedVideos.map(async ({ videoPath }) => {
|
|
102978
|
-
const metadata = await
|
|
103016
|
+
const metadata = await extractMediaMetadata(videoPath);
|
|
102979
103017
|
return metadata.colorSpace;
|
|
102980
103018
|
})
|
|
102981
103019
|
);
|
|
@@ -103008,7 +103046,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config2,
|
|
|
103008
103046
|
if (signal?.aborted) break;
|
|
103009
103047
|
const entry = resolvedVideos[i];
|
|
103010
103048
|
if (!entry) continue;
|
|
103011
|
-
const metadata = await
|
|
103049
|
+
const metadata = await extractMediaMetadata(entry.videoPath);
|
|
103012
103050
|
if (!metadata.isVFR) continue;
|
|
103013
103051
|
let segDuration = entry.video.end - entry.video.start;
|
|
103014
103052
|
if (!Number.isFinite(segDuration) || segDuration <= 0) {
|
|
@@ -103044,7 +103082,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config2,
|
|
|
103044
103082
|
try {
|
|
103045
103083
|
let videoDuration = video.end - video.start;
|
|
103046
103084
|
if (!Number.isFinite(videoDuration) || videoDuration <= 0) {
|
|
103047
|
-
const metadata = await
|
|
103085
|
+
const metadata = await extractMediaMetadata(videoPath);
|
|
103048
103086
|
const sourceDuration = metadata.durationSeconds - video.mediaStart;
|
|
103049
103087
|
videoDuration = sourceDuration > 0 ? sourceDuration : metadata.durationSeconds;
|
|
103050
103088
|
video.end = video.start + videoDuration;
|
|
@@ -103419,7 +103457,7 @@ async function queryElementStacking(page, nativeHdrIds) {
|
|
|
103419
103457
|
|
|
103420
103458
|
// ../engine/src/services/audioMixer.ts
|
|
103421
103459
|
import { existsSync as existsSync9, mkdirSync as mkdirSync6, rmSync as rmSync2 } from "fs";
|
|
103422
|
-
import { join as join9, dirname as dirname7 } from "path";
|
|
103460
|
+
import { isAbsolute as isAbsolute3, join as join9, dirname as dirname7 } from "path";
|
|
103423
103461
|
function parseAudioElements(html) {
|
|
103424
103462
|
const elements = [];
|
|
103425
103463
|
const { document: document2 } = parseHTML(html);
|
|
@@ -103646,7 +103684,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
103646
103684
|
}
|
|
103647
103685
|
try {
|
|
103648
103686
|
let srcPath = element.src;
|
|
103649
|
-
if (!srcPath
|
|
103687
|
+
if (!isAbsolute3(srcPath) && !isHttpUrl(srcPath)) {
|
|
103650
103688
|
const fromCompiled = compiledDir ? join9(compiledDir, srcPath) : null;
|
|
103651
103689
|
srcPath = fromCompiled && existsSync9(fromCompiled) ? fromCompiled : join9(baseDir, srcPath);
|
|
103652
103690
|
}
|
|
@@ -106996,13 +107034,51 @@ function normalizeObjectFit(value) {
|
|
|
106996
107034
|
}
|
|
106997
107035
|
function parseTransformMatrix(css) {
|
|
106998
107036
|
if (!css || css === "none") return null;
|
|
106999
|
-
const
|
|
107037
|
+
const match2d = css.match(
|
|
107000
107038
|
/^matrix\(\s*([^,]+),\s*([^,]+),\s*([^,]+),\s*([^,]+),\s*([^,]+),\s*([^,)]+)\s*\)$/
|
|
107001
107039
|
);
|
|
107002
|
-
if (
|
|
107003
|
-
|
|
107004
|
-
|
|
107005
|
-
|
|
107040
|
+
if (match2d) {
|
|
107041
|
+
const values = match2d.slice(1, 7).map(Number);
|
|
107042
|
+
if (!values.every(Number.isFinite)) return null;
|
|
107043
|
+
return values;
|
|
107044
|
+
}
|
|
107045
|
+
const match3d = css.match(/^matrix3d\(\s*([^)]+)\)$/);
|
|
107046
|
+
if (match3d) {
|
|
107047
|
+
const raw2 = match3d[1];
|
|
107048
|
+
if (!raw2) return null;
|
|
107049
|
+
const parts = raw2.split(",").map((s) => Number(s.trim()));
|
|
107050
|
+
if (parts.length !== 16 || !parts.every(Number.isFinite)) return null;
|
|
107051
|
+
warnIfZSignificant(parts);
|
|
107052
|
+
return [
|
|
107053
|
+
parts[0],
|
|
107054
|
+
parts[1],
|
|
107055
|
+
parts[4],
|
|
107056
|
+
parts[5],
|
|
107057
|
+
parts[12],
|
|
107058
|
+
parts[13]
|
|
107059
|
+
];
|
|
107060
|
+
}
|
|
107061
|
+
return null;
|
|
107062
|
+
}
|
|
107063
|
+
var warnedZSignificant = false;
|
|
107064
|
+
var Z_EPSILON = 1e-6;
|
|
107065
|
+
function warnIfZSignificant(parts) {
|
|
107066
|
+
if (warnedZSignificant) return;
|
|
107067
|
+
const a3 = parts[8] ?? 0;
|
|
107068
|
+
const b3 = parts[9] ?? 0;
|
|
107069
|
+
const c1 = parts[2] ?? 0;
|
|
107070
|
+
const c2 = parts[6] ?? 0;
|
|
107071
|
+
const c3 = parts[10] ?? 1;
|
|
107072
|
+
const d1 = parts[3] ?? 0;
|
|
107073
|
+
const d2 = parts[7] ?? 0;
|
|
107074
|
+
const d3 = parts[11] ?? 0;
|
|
107075
|
+
const d4 = parts[15] ?? 1;
|
|
107076
|
+
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) {
|
|
107077
|
+
warnedZSignificant = true;
|
|
107078
|
+
console.warn(
|
|
107079
|
+
`[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.`
|
|
107080
|
+
);
|
|
107081
|
+
}
|
|
107006
107082
|
}
|
|
107007
107083
|
|
|
107008
107084
|
// ../engine/src/utils/layerCompositor.ts
|
|
@@ -108206,14 +108282,14 @@ import { join as join14, dirname as dirname9, resolve as resolve10 } from "path"
|
|
|
108206
108282
|
import postcss from "postcss";
|
|
108207
108283
|
|
|
108208
108284
|
// src/utils/paths.ts
|
|
108209
|
-
import { resolve as resolve9, basename as basename2, join as join12, relative as relative2, isAbsolute as
|
|
108285
|
+
import { resolve as resolve9, basename as basename2, join as join12, relative as relative2, isAbsolute as isAbsolute4 } from "node:path";
|
|
108210
108286
|
var DEFAULT_RENDERS_DIR = process.env.PRODUCER_RENDERS_DIR ?? resolve9(new URL(import.meta.url).pathname, "../../..", "renders");
|
|
108211
108287
|
function isPathInside2(childPath, parentPath) {
|
|
108212
108288
|
const absChild = resolve9(childPath);
|
|
108213
108289
|
const absParent = resolve9(parentPath);
|
|
108214
108290
|
if (absChild === absParent) return true;
|
|
108215
108291
|
const rel = relative2(absParent, absChild);
|
|
108216
|
-
return rel !== "" && !rel.startsWith("..") && !
|
|
108292
|
+
return rel !== "" && !rel.startsWith("..") && !isAbsolute4(rel);
|
|
108217
108293
|
}
|
|
108218
108294
|
function toExternalAssetKey(absPath) {
|
|
108219
108295
|
if (absPath.startsWith("hf-ext/")) return absPath;
|
|
@@ -108676,7 +108752,7 @@ async function resolveMediaDuration(src, mediaStart, baseDir, downloadDir, tagNa
|
|
|
108676
108752
|
if (!existsSync14(filePath)) {
|
|
108677
108753
|
return { duration: 0, resolvedPath: filePath };
|
|
108678
108754
|
}
|
|
108679
|
-
const metadata = tagName19 === "video" ? await
|
|
108755
|
+
const metadata = tagName19 === "video" ? await extractMediaMetadata(filePath) : await extractAudioMetadata(filePath);
|
|
108680
108756
|
const fileDuration = metadata.durationSeconds;
|
|
108681
108757
|
const effectiveDuration = fileDuration - mediaStart;
|
|
108682
108758
|
const duration = effectiveDuration > 0 ? effectiveDuration : fileDuration;
|
|
@@ -109259,7 +109335,7 @@ async function compileForRender(projectDir, htmlPath, downloadDir) {
|
|
|
109259
109335
|
if (isHttpUrl(video.src)) continue;
|
|
109260
109336
|
const videoPath = resolve10(projectDir, video.src);
|
|
109261
109337
|
const reencode = `ffmpeg -i "${video.src}" -c:v libx264 -r 30 -g 30 -keyint_min 30 -movflags +faststart -c:a copy output.mp4`;
|
|
109262
|
-
Promise.all([analyzeKeyframeIntervals(videoPath),
|
|
109338
|
+
Promise.all([analyzeKeyframeIntervals(videoPath), extractMediaMetadata(videoPath)]).then(([analysis, metadata]) => {
|
|
109263
109339
|
if (analysis.isProblematic) {
|
|
109264
109340
|
console.warn(
|
|
109265
109341
|
`[Compiler] WARNING: Video "${video.id}" has sparse keyframes (max interval: ${analysis.maxIntervalSeconds}s). This causes seek failures and frame freezing. Re-encode with: ${reencode}`
|
|
@@ -109458,6 +109534,21 @@ function getMaxFrameIndex(frameDir) {
|
|
|
109458
109534
|
frameDirMaxIndexCache.set(frameDir, max);
|
|
109459
109535
|
return max;
|
|
109460
109536
|
}
|
|
109537
|
+
function countNonZeroAlpha(rgba) {
|
|
109538
|
+
let n = 0;
|
|
109539
|
+
for (let p = 3; p < rgba.length; p += 4) {
|
|
109540
|
+
if (rgba[p] !== 0) n++;
|
|
109541
|
+
}
|
|
109542
|
+
return n;
|
|
109543
|
+
}
|
|
109544
|
+
function countNonZeroRgb48(buf) {
|
|
109545
|
+
let n = 0;
|
|
109546
|
+
for (let p = 0; p < buf.length; p += 6) {
|
|
109547
|
+
if (buf[p] !== 0 || buf[p + 1] !== 0 || buf[p + 2] !== 0 || buf[p + 3] !== 0 || buf[p + 4] !== 0 || buf[p + 5] !== 0)
|
|
109548
|
+
n++;
|
|
109549
|
+
}
|
|
109550
|
+
return n;
|
|
109551
|
+
}
|
|
109461
109552
|
var RenderCancelledError = class extends Error {
|
|
109462
109553
|
reason;
|
|
109463
109554
|
constructor(message = "render_cancelled", reason = "aborted") {
|
|
@@ -109665,6 +109756,165 @@ function blitHdrImageLayer(canvas, el, hdrImageBuffers, width, height, log, sour
|
|
|
109665
109756
|
}
|
|
109666
109757
|
}
|
|
109667
109758
|
}
|
|
109759
|
+
async function compositeHdrFrame(ctx, canvas, time, fullStacking, elementFilter, debugFrameIndex = -1) {
|
|
109760
|
+
const {
|
|
109761
|
+
log,
|
|
109762
|
+
domSession,
|
|
109763
|
+
beforeCaptureHook,
|
|
109764
|
+
width,
|
|
109765
|
+
height,
|
|
109766
|
+
fps,
|
|
109767
|
+
effectiveHdr,
|
|
109768
|
+
nativeHdrImageIds,
|
|
109769
|
+
hdrImageBuffers,
|
|
109770
|
+
hdrFrameDirs,
|
|
109771
|
+
hdrVideoStartTimes,
|
|
109772
|
+
imageTransfers,
|
|
109773
|
+
videoTransfers,
|
|
109774
|
+
debugDumpEnabled,
|
|
109775
|
+
debugDumpDir
|
|
109776
|
+
} = ctx;
|
|
109777
|
+
const filteredStacking = elementFilter ? fullStacking.filter((e) => elementFilter.has(e.id)) : fullStacking;
|
|
109778
|
+
const layers = groupIntoLayers(filteredStacking);
|
|
109779
|
+
const shouldLog = debugDumpEnabled && debugFrameIndex >= 0;
|
|
109780
|
+
if (shouldLog) {
|
|
109781
|
+
log.info("[diag] compositeToBuffer plan", {
|
|
109782
|
+
frame: debugFrameIndex,
|
|
109783
|
+
time: time.toFixed(3),
|
|
109784
|
+
filterSize: elementFilter?.size,
|
|
109785
|
+
fullStackingCount: fullStacking.length,
|
|
109786
|
+
filteredCount: filteredStacking.length,
|
|
109787
|
+
layerCount: layers.length,
|
|
109788
|
+
layers: layers.map(
|
|
109789
|
+
(l) => l.type === "hdr" ? {
|
|
109790
|
+
type: "hdr",
|
|
109791
|
+
id: l.element.id,
|
|
109792
|
+
z: l.element.zIndex,
|
|
109793
|
+
visible: l.element.visible,
|
|
109794
|
+
opacity: l.element.opacity,
|
|
109795
|
+
bounds: `${Math.round(l.element.x)},${Math.round(l.element.y)} ${Math.round(l.element.width)}x${Math.round(l.element.height)}`
|
|
109796
|
+
} : { type: "dom", ids: l.elementIds }
|
|
109797
|
+
)
|
|
109798
|
+
});
|
|
109799
|
+
}
|
|
109800
|
+
for (const [layerIdx, layer] of layers.entries()) {
|
|
109801
|
+
if (layer.type === "hdr") {
|
|
109802
|
+
const before2 = shouldLog ? countNonZeroRgb48(canvas) : 0;
|
|
109803
|
+
const isHdrImage = nativeHdrImageIds.has(layer.element.id);
|
|
109804
|
+
if (isHdrImage) {
|
|
109805
|
+
blitHdrImageLayer(
|
|
109806
|
+
canvas,
|
|
109807
|
+
layer.element,
|
|
109808
|
+
hdrImageBuffers,
|
|
109809
|
+
width,
|
|
109810
|
+
height,
|
|
109811
|
+
log,
|
|
109812
|
+
imageTransfers.get(layer.element.id),
|
|
109813
|
+
effectiveHdr.transfer
|
|
109814
|
+
);
|
|
109815
|
+
} else {
|
|
109816
|
+
blitHdrVideoLayer(
|
|
109817
|
+
canvas,
|
|
109818
|
+
layer.element,
|
|
109819
|
+
time,
|
|
109820
|
+
fps,
|
|
109821
|
+
hdrFrameDirs,
|
|
109822
|
+
hdrVideoStartTimes,
|
|
109823
|
+
width,
|
|
109824
|
+
height,
|
|
109825
|
+
log,
|
|
109826
|
+
videoTransfers.get(layer.element.id),
|
|
109827
|
+
effectiveHdr.transfer
|
|
109828
|
+
);
|
|
109829
|
+
}
|
|
109830
|
+
if (shouldLog) {
|
|
109831
|
+
const after2 = countNonZeroRgb48(canvas);
|
|
109832
|
+
if (isHdrImage) {
|
|
109833
|
+
const buf = hdrImageBuffers.get(layer.element.id);
|
|
109834
|
+
log.info("[diag] hdr layer blit", {
|
|
109835
|
+
frame: debugFrameIndex,
|
|
109836
|
+
layerIdx,
|
|
109837
|
+
id: layer.element.id,
|
|
109838
|
+
kind: "image",
|
|
109839
|
+
pixelsAdded: after2 - before2,
|
|
109840
|
+
totalNonZero: after2,
|
|
109841
|
+
bufferDecoded: !!buf,
|
|
109842
|
+
bufferDims: buf ? `${buf.width}x${buf.height}` : null
|
|
109843
|
+
});
|
|
109844
|
+
} else {
|
|
109845
|
+
const frameDir = hdrFrameDirs.get(layer.element.id);
|
|
109846
|
+
const startTime = hdrVideoStartTimes.get(layer.element.id) ?? 0;
|
|
109847
|
+
const localTime = time - startTime;
|
|
109848
|
+
const frameNum = Math.floor(localTime * fps) + 1;
|
|
109849
|
+
const expectedFrame = frameDir ? join15(frameDir, `frame_${String(frameNum).padStart(4, "0")}.png`) : null;
|
|
109850
|
+
log.info("[diag] hdr layer blit", {
|
|
109851
|
+
frame: debugFrameIndex,
|
|
109852
|
+
layerIdx,
|
|
109853
|
+
id: layer.element.id,
|
|
109854
|
+
kind: "video",
|
|
109855
|
+
pixelsAdded: after2 - before2,
|
|
109856
|
+
totalNonZero: after2,
|
|
109857
|
+
startTime,
|
|
109858
|
+
localTime: localTime.toFixed(3),
|
|
109859
|
+
hdrFrameNum: frameNum,
|
|
109860
|
+
expectedFrame,
|
|
109861
|
+
expectedFrameExists: expectedFrame ? existsSync15(expectedFrame) : false
|
|
109862
|
+
});
|
|
109863
|
+
}
|
|
109864
|
+
}
|
|
109865
|
+
} else {
|
|
109866
|
+
const allElementIds = fullStacking.map((e) => e.id);
|
|
109867
|
+
const layerIds = new Set(layer.elementIds);
|
|
109868
|
+
const hideIds = allElementIds.filter((id) => !layerIds.has(id));
|
|
109869
|
+
await domSession.page.evaluate((t) => {
|
|
109870
|
+
if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
|
|
109871
|
+
}, time);
|
|
109872
|
+
if (beforeCaptureHook) {
|
|
109873
|
+
await beforeCaptureHook(domSession.page, time);
|
|
109874
|
+
}
|
|
109875
|
+
await applyDomLayerMask(domSession.page, layer.elementIds, hideIds);
|
|
109876
|
+
const domPng = await captureAlphaPng(domSession.page, width, height);
|
|
109877
|
+
await removeDomLayerMask(domSession.page, hideIds);
|
|
109878
|
+
try {
|
|
109879
|
+
const { data: domRgba } = decodePng(domPng);
|
|
109880
|
+
const before2 = shouldLog ? countNonZeroRgb48(canvas) : 0;
|
|
109881
|
+
const alphaPixels = shouldLog ? countNonZeroAlpha(domRgba) : 0;
|
|
109882
|
+
blitRgba8OverRgb48le(domRgba, canvas, width, height, effectiveHdr.transfer);
|
|
109883
|
+
if (shouldLog && debugDumpDir) {
|
|
109884
|
+
const after2 = countNonZeroRgb48(canvas);
|
|
109885
|
+
const dumpName = `frame_${String(debugFrameIndex).padStart(4, "0")}_layer_${String(layerIdx).padStart(2, "0")}_dom.png`;
|
|
109886
|
+
const dumpPath = join15(debugDumpDir, dumpName);
|
|
109887
|
+
writeFileSync4(dumpPath, domPng);
|
|
109888
|
+
log.info("[diag] dom layer blit", {
|
|
109889
|
+
frame: debugFrameIndex,
|
|
109890
|
+
layerIdx,
|
|
109891
|
+
layerIds: layer.elementIds,
|
|
109892
|
+
hideCount: hideIds.length,
|
|
109893
|
+
pngBytes: domPng.length,
|
|
109894
|
+
alphaPixels,
|
|
109895
|
+
pixelsAdded: after2 - before2,
|
|
109896
|
+
totalNonZero: after2,
|
|
109897
|
+
dumpPath
|
|
109898
|
+
});
|
|
109899
|
+
}
|
|
109900
|
+
} catch (err) {
|
|
109901
|
+
log.warn("DOM layer decode/blit failed; skipping overlay", {
|
|
109902
|
+
layerIds: layer.elementIds,
|
|
109903
|
+
error: err instanceof Error ? err.message : String(err)
|
|
109904
|
+
});
|
|
109905
|
+
}
|
|
109906
|
+
}
|
|
109907
|
+
}
|
|
109908
|
+
if (shouldLog && debugDumpDir) {
|
|
109909
|
+
const finalNonZero = countNonZeroRgb48(canvas);
|
|
109910
|
+
log.info("[diag] compositeToBuffer end", {
|
|
109911
|
+
frame: debugFrameIndex,
|
|
109912
|
+
finalNonZeroPixels: finalNonZero,
|
|
109913
|
+
totalPixels: width * height,
|
|
109914
|
+
coverage: (finalNonZero / (width * height) * 100).toFixed(1) + "%"
|
|
109915
|
+
});
|
|
109916
|
+
}
|
|
109917
|
+
}
|
|
109668
109918
|
function createRenderJob(config2) {
|
|
109669
109919
|
return {
|
|
109670
109920
|
id: randomUUID(),
|
|
@@ -110009,7 +110259,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110009
110259
|
videoPath = fromCompiled;
|
|
110010
110260
|
}
|
|
110011
110261
|
if (!existsSync15(videoPath)) return;
|
|
110012
|
-
const meta = await
|
|
110262
|
+
const meta = await extractMediaMetadata(videoPath);
|
|
110013
110263
|
if (isHdrColorSpace(meta.colorSpace)) {
|
|
110014
110264
|
nativeHdrVideoIds.add(v.id);
|
|
110015
110265
|
videoTransfers.set(v.id, detectTransfer(meta.colorSpace));
|
|
@@ -110030,7 +110280,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110030
110280
|
imgPath = fromCompiled;
|
|
110031
110281
|
}
|
|
110032
110282
|
if (!existsSync15(imgPath)) return null;
|
|
110033
|
-
const meta = await
|
|
110283
|
+
const meta = await extractMediaMetadata(imgPath);
|
|
110034
110284
|
if (isHdrColorSpace(meta.colorSpace)) {
|
|
110035
110285
|
nativeHdrImageIds.add(img.id);
|
|
110036
110286
|
imageTransfers.set(img.id, detectTransfer(meta.colorSpace));
|
|
@@ -110142,6 +110392,10 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110142
110392
|
format: needsAlpha ? "png" : "jpeg",
|
|
110143
110393
|
quality: needsAlpha ? void 0 : job.config.quality === "draft" ? 80 : 95
|
|
110144
110394
|
};
|
|
110395
|
+
const buildHdrCaptureOptions = () => ({
|
|
110396
|
+
...captureOptions,
|
|
110397
|
+
skipReadinessVideoIds: Array.from(nativeHdrVideoIds)
|
|
110398
|
+
});
|
|
110145
110399
|
const workerCount = calculateOptimalWorkers(totalFrames, job.config.workers, cfg);
|
|
110146
110400
|
const FORMAT_EXT = { mp4: ".mp4", webm: ".webm", mov: ".mov" };
|
|
110147
110401
|
const videoExt = FORMAT_EXT[outputFormat] ?? ".mp4";
|
|
@@ -110176,7 +110430,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110176
110430
|
const domSession = await createCaptureSession(
|
|
110177
110431
|
fileServer.url,
|
|
110178
110432
|
framesDir,
|
|
110179
|
-
|
|
110433
|
+
buildHdrCaptureOptions(),
|
|
110180
110434
|
createVideoFrameInjector(frameLookup),
|
|
110181
110435
|
cfg
|
|
110182
110436
|
);
|
|
@@ -110272,6 +110526,29 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110272
110526
|
}
|
|
110273
110527
|
}
|
|
110274
110528
|
}
|
|
110529
|
+
for (const [imageId, startTime] of hdrImageStartTimes) {
|
|
110530
|
+
if (hdrExtractionDims.has(imageId)) continue;
|
|
110531
|
+
const img = composition.images.find((i) => i.id === imageId);
|
|
110532
|
+
if (!img) continue;
|
|
110533
|
+
const duration = img.end - img.start;
|
|
110534
|
+
const retryTime = startTime + Math.min(0.5, duration * 0.1);
|
|
110535
|
+
await domSession.page.evaluate((t) => {
|
|
110536
|
+
if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
|
|
110537
|
+
}, retryTime);
|
|
110538
|
+
if (domSession.onBeforeCapture) {
|
|
110539
|
+
await domSession.onBeforeCapture(domSession.page, retryTime);
|
|
110540
|
+
}
|
|
110541
|
+
const retryStacking = await queryElementStacking(domSession.page, nativeHdrIds);
|
|
110542
|
+
for (const el of retryStacking) {
|
|
110543
|
+
if (el.id === imageId && el.isHdr && el.layoutWidth > 0 && el.layoutHeight > 0) {
|
|
110544
|
+
hdrExtractionDims.set(el.id, { width: el.layoutWidth, height: el.layoutHeight });
|
|
110545
|
+
if (!hdrImageFitInfo.has(el.id)) {
|
|
110546
|
+
hdrImageFitInfo.set(el.id, { fit: el.objectFit, position: el.objectPosition });
|
|
110547
|
+
}
|
|
110548
|
+
break;
|
|
110549
|
+
}
|
|
110550
|
+
}
|
|
110551
|
+
}
|
|
110275
110552
|
for (const [videoId, srcPath] of hdrVideoSrcPaths) {
|
|
110276
110553
|
const video = composition.videos.find((v) => v.id === videoId);
|
|
110277
110554
|
if (!video) continue;
|
|
@@ -110354,21 +110631,6 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110354
110631
|
}
|
|
110355
110632
|
assertNotAborted();
|
|
110356
110633
|
try {
|
|
110357
|
-
let countNonZeroAlpha2 = function(rgba) {
|
|
110358
|
-
let n = 0;
|
|
110359
|
-
for (let p = 3; p < rgba.length; p += 4) {
|
|
110360
|
-
if (rgba[p] !== 0) n++;
|
|
110361
|
-
}
|
|
110362
|
-
return n;
|
|
110363
|
-
}, countNonZeroRgb482 = function(buf) {
|
|
110364
|
-
let n = 0;
|
|
110365
|
-
for (let p = 0; p < buf.length; p += 6) {
|
|
110366
|
-
if (buf[p] !== 0 || buf[p + 1] !== 0 || buf[p + 2] !== 0 || buf[p + 3] !== 0 || buf[p + 4] !== 0 || buf[p + 5] !== 0)
|
|
110367
|
-
n++;
|
|
110368
|
-
}
|
|
110369
|
-
return n;
|
|
110370
|
-
};
|
|
110371
|
-
var countNonZeroAlpha = countNonZeroAlpha2, countNonZeroRgb48 = countNonZeroRgb482;
|
|
110372
110634
|
const beforeCaptureHook = domSession.onBeforeCapture;
|
|
110373
110635
|
const cleanedUpVideos = /* @__PURE__ */ new Set();
|
|
110374
110636
|
const hdrVideoEndTimes = /* @__PURE__ */ new Map();
|
|
@@ -110382,153 +110644,28 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110382
110644
|
if (debugDumpDir && !existsSync15(debugDumpDir)) {
|
|
110383
110645
|
mkdirSync10(debugDumpDir, { recursive: true });
|
|
110384
110646
|
}
|
|
110385
|
-
|
|
110386
|
-
|
|
110387
|
-
|
|
110388
|
-
|
|
110389
|
-
if (shouldLog) {
|
|
110390
|
-
log.info("[diag] compositeToBuffer plan", {
|
|
110391
|
-
frame: debugFrameIndex,
|
|
110392
|
-
time: time.toFixed(3),
|
|
110393
|
-
filterSize: elementFilter?.size,
|
|
110394
|
-
fullStackingCount: fullStacking.length,
|
|
110395
|
-
filteredCount: filteredStacking.length,
|
|
110396
|
-
layerCount: layers.length,
|
|
110397
|
-
layers: layers.map(
|
|
110398
|
-
(l) => l.type === "hdr" ? {
|
|
110399
|
-
type: "hdr",
|
|
110400
|
-
id: l.element.id,
|
|
110401
|
-
z: l.element.zIndex,
|
|
110402
|
-
visible: l.element.visible,
|
|
110403
|
-
opacity: l.element.opacity,
|
|
110404
|
-
bounds: `${Math.round(l.element.x)},${Math.round(l.element.y)} ${Math.round(l.element.width)}x${Math.round(l.element.height)}`
|
|
110405
|
-
} : { type: "dom", ids: l.elementIds }
|
|
110406
|
-
)
|
|
110407
|
-
});
|
|
110408
|
-
}
|
|
110409
|
-
for (const [layerIdx, layer] of layers.entries()) {
|
|
110410
|
-
if (layer.type === "hdr") {
|
|
110411
|
-
const before2 = shouldLog ? countNonZeroRgb482(canvas) : 0;
|
|
110412
|
-
const isHdrImage = nativeHdrImageIds.has(layer.element.id);
|
|
110413
|
-
if (isHdrImage) {
|
|
110414
|
-
blitHdrImageLayer(
|
|
110415
|
-
canvas,
|
|
110416
|
-
layer.element,
|
|
110417
|
-
hdrImageBuffers,
|
|
110418
|
-
width,
|
|
110419
|
-
height,
|
|
110420
|
-
log,
|
|
110421
|
-
imageTransfers.get(layer.element.id),
|
|
110422
|
-
effectiveHdr?.transfer
|
|
110423
|
-
);
|
|
110424
|
-
} else {
|
|
110425
|
-
blitHdrVideoLayer(
|
|
110426
|
-
canvas,
|
|
110427
|
-
layer.element,
|
|
110428
|
-
time,
|
|
110429
|
-
job.config.fps,
|
|
110430
|
-
hdrFrameDirs,
|
|
110431
|
-
hdrVideoStartTimes,
|
|
110432
|
-
width,
|
|
110433
|
-
height,
|
|
110434
|
-
log,
|
|
110435
|
-
videoTransfers.get(layer.element.id),
|
|
110436
|
-
effectiveHdr?.transfer
|
|
110437
|
-
);
|
|
110438
|
-
}
|
|
110439
|
-
if (shouldLog) {
|
|
110440
|
-
const after2 = countNonZeroRgb482(canvas);
|
|
110441
|
-
if (isHdrImage) {
|
|
110442
|
-
const buf = hdrImageBuffers.get(layer.element.id);
|
|
110443
|
-
log.info("[diag] hdr layer blit", {
|
|
110444
|
-
frame: debugFrameIndex,
|
|
110445
|
-
layerIdx,
|
|
110446
|
-
id: layer.element.id,
|
|
110447
|
-
kind: "image",
|
|
110448
|
-
pixelsAdded: after2 - before2,
|
|
110449
|
-
totalNonZero: after2,
|
|
110450
|
-
bufferDecoded: !!buf,
|
|
110451
|
-
bufferDims: buf ? `${buf.width}x${buf.height}` : null
|
|
110452
|
-
});
|
|
110453
|
-
} else {
|
|
110454
|
-
const frameDir = hdrFrameDirs.get(layer.element.id);
|
|
110455
|
-
const startTime = hdrVideoStartTimes.get(layer.element.id) ?? 0;
|
|
110456
|
-
const localTime = time - startTime;
|
|
110457
|
-
const frameNum = Math.floor(localTime * job.config.fps) + 1;
|
|
110458
|
-
const expectedFrame = frameDir ? join15(frameDir, `frame_${String(frameNum).padStart(4, "0")}.png`) : null;
|
|
110459
|
-
log.info("[diag] hdr layer blit", {
|
|
110460
|
-
frame: debugFrameIndex,
|
|
110461
|
-
layerIdx,
|
|
110462
|
-
id: layer.element.id,
|
|
110463
|
-
kind: "video",
|
|
110464
|
-
pixelsAdded: after2 - before2,
|
|
110465
|
-
totalNonZero: after2,
|
|
110466
|
-
startTime,
|
|
110467
|
-
localTime: localTime.toFixed(3),
|
|
110468
|
-
hdrFrameNum: frameNum,
|
|
110469
|
-
expectedFrame,
|
|
110470
|
-
expectedFrameExists: expectedFrame ? existsSync15(expectedFrame) : false
|
|
110471
|
-
});
|
|
110472
|
-
}
|
|
110473
|
-
}
|
|
110474
|
-
} else {
|
|
110475
|
-
const allElementIds = fullStacking.map((e) => e.id);
|
|
110476
|
-
const layerIds = new Set(layer.elementIds);
|
|
110477
|
-
const hideIds = allElementIds.filter((id) => !layerIds.has(id));
|
|
110478
|
-
await domSession.page.evaluate((t) => {
|
|
110479
|
-
if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
|
|
110480
|
-
}, time);
|
|
110481
|
-
if (beforeCaptureHook) {
|
|
110482
|
-
await beforeCaptureHook(domSession.page, time);
|
|
110483
|
-
}
|
|
110484
|
-
await applyDomLayerMask(domSession.page, layer.elementIds, hideIds);
|
|
110485
|
-
const domPng = await captureAlphaPng(domSession.page, width, height);
|
|
110486
|
-
await removeDomLayerMask(domSession.page, hideIds);
|
|
110487
|
-
try {
|
|
110488
|
-
const { data: domRgba } = decodePng(domPng);
|
|
110489
|
-
if (!effectiveHdr) {
|
|
110490
|
-
throw new Error(
|
|
110491
|
-
"Invariant violation: effectiveHdr is undefined inside HDR layer branch"
|
|
110492
|
-
);
|
|
110493
|
-
}
|
|
110494
|
-
const before2 = shouldLog ? countNonZeroRgb482(canvas) : 0;
|
|
110495
|
-
const alphaPixels = shouldLog ? countNonZeroAlpha2(domRgba) : 0;
|
|
110496
|
-
blitRgba8OverRgb48le(domRgba, canvas, width, height, effectiveHdr.transfer);
|
|
110497
|
-
if (shouldLog && debugDumpDir) {
|
|
110498
|
-
const after2 = countNonZeroRgb482(canvas);
|
|
110499
|
-
const dumpName = `frame_${String(debugFrameIndex).padStart(4, "0")}_layer_${String(layerIdx).padStart(2, "0")}_dom.png`;
|
|
110500
|
-
const dumpPath = join15(debugDumpDir, dumpName);
|
|
110501
|
-
writeFileSync4(dumpPath, domPng);
|
|
110502
|
-
log.info("[diag] dom layer blit", {
|
|
110503
|
-
frame: debugFrameIndex,
|
|
110504
|
-
layerIdx,
|
|
110505
|
-
layerIds: layer.elementIds,
|
|
110506
|
-
hideCount: hideIds.length,
|
|
110507
|
-
pngBytes: domPng.length,
|
|
110508
|
-
alphaPixels,
|
|
110509
|
-
pixelsAdded: after2 - before2,
|
|
110510
|
-
totalNonZero: after2,
|
|
110511
|
-
dumpPath
|
|
110512
|
-
});
|
|
110513
|
-
}
|
|
110514
|
-
} catch (err) {
|
|
110515
|
-
log.warn("DOM layer decode/blit failed; skipping overlay", {
|
|
110516
|
-
layerIds: layer.elementIds,
|
|
110517
|
-
error: err instanceof Error ? err.message : String(err)
|
|
110518
|
-
});
|
|
110519
|
-
}
|
|
110520
|
-
}
|
|
110521
|
-
}
|
|
110522
|
-
if (shouldLog && debugDumpDir) {
|
|
110523
|
-
const finalNonZero = countNonZeroRgb482(canvas);
|
|
110524
|
-
log.info("[diag] compositeToBuffer end", {
|
|
110525
|
-
frame: debugFrameIndex,
|
|
110526
|
-
finalNonZeroPixels: finalNonZero,
|
|
110527
|
-
totalPixels: width * height,
|
|
110528
|
-
coverage: (finalNonZero / (width * height) * 100).toFixed(1) + "%"
|
|
110529
|
-
});
|
|
110530
|
-
}
|
|
110647
|
+
if (!effectiveHdr) {
|
|
110648
|
+
throw new Error(
|
|
110649
|
+
"Internal: HDR render path entered without effectiveHdr \u2014 this is a bug."
|
|
110650
|
+
);
|
|
110531
110651
|
}
|
|
110652
|
+
const hdrCompositeCtx = {
|
|
110653
|
+
log,
|
|
110654
|
+
domSession,
|
|
110655
|
+
beforeCaptureHook,
|
|
110656
|
+
width,
|
|
110657
|
+
height,
|
|
110658
|
+
fps: job.config.fps,
|
|
110659
|
+
effectiveHdr,
|
|
110660
|
+
nativeHdrImageIds,
|
|
110661
|
+
hdrImageBuffers,
|
|
110662
|
+
hdrFrameDirs,
|
|
110663
|
+
hdrVideoStartTimes,
|
|
110664
|
+
imageTransfers,
|
|
110665
|
+
videoTransfers,
|
|
110666
|
+
debugDumpEnabled,
|
|
110667
|
+
debugDumpDir
|
|
110668
|
+
};
|
|
110532
110669
|
const bufSize = width * height * 6;
|
|
110533
110670
|
const hasTransitions = transitionRanges.length > 0;
|
|
110534
110671
|
const transBufferA = hasTransitions ? Buffer.alloc(bufSize) : null;
|
|
@@ -110636,7 +110773,14 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110636
110773
|
hdrEncoder.writeFrame(transOutput);
|
|
110637
110774
|
} else {
|
|
110638
110775
|
normalCanvas.fill(0);
|
|
110639
|
-
await
|
|
110776
|
+
await compositeHdrFrame(
|
|
110777
|
+
hdrCompositeCtx,
|
|
110778
|
+
normalCanvas,
|
|
110779
|
+
time,
|
|
110780
|
+
stackingInfo,
|
|
110781
|
+
void 0,
|
|
110782
|
+
i
|
|
110783
|
+
);
|
|
110640
110784
|
if (debugDumpEnabled && debugDumpDir && i % 30 === 0) {
|
|
110641
110785
|
const previewPath = join15(
|
|
110642
110786
|
debugDumpDir,
|
|
@@ -110755,7 +110899,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110755
110899
|
fileServer.url,
|
|
110756
110900
|
workDir,
|
|
110757
110901
|
tasks,
|
|
110758
|
-
|
|
110902
|
+
buildHdrCaptureOptions(),
|
|
110759
110903
|
() => createVideoFrameInjector(frameLookup),
|
|
110760
110904
|
abortSignal,
|
|
110761
110905
|
(progress) => {
|
|
@@ -110785,7 +110929,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110785
110929
|
const session = probeSession ?? await createCaptureSession(
|
|
110786
110930
|
fileServer.url,
|
|
110787
110931
|
framesDir,
|
|
110788
|
-
|
|
110932
|
+
buildHdrCaptureOptions(),
|
|
110789
110933
|
videoInjector,
|
|
110790
110934
|
cfg
|
|
110791
110935
|
);
|
|
@@ -110837,7 +110981,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110837
110981
|
fileServer.url,
|
|
110838
110982
|
workDir,
|
|
110839
110983
|
tasks,
|
|
110840
|
-
|
|
110984
|
+
buildHdrCaptureOptions(),
|
|
110841
110985
|
() => createVideoFrameInjector(frameLookup),
|
|
110842
110986
|
abortSignal,
|
|
110843
110987
|
(progress) => {
|
|
@@ -110868,7 +111012,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110868
111012
|
const session = probeSession ?? await createCaptureSession(
|
|
110869
111013
|
fileServer.url,
|
|
110870
111014
|
framesDir,
|
|
110871
|
-
|
|
111015
|
+
buildHdrCaptureOptions(),
|
|
110872
111016
|
videoInjector,
|
|
110873
111017
|
cfg
|
|
110874
111018
|
);
|