@hyperframes/producer 0.4.19 → 0.4.21
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 +819 -336
- package/dist/index.js.map +4 -4
- package/dist/public-server.js +819 -336
- package/dist/public-server.js.map +4 -4
- package/dist/services/hdrImageTransferCache.d.ts +17 -0
- package/dist/services/hdrImageTransferCache.d.ts.map +1 -0
- package/dist/services/htmlCompiler.d.ts.map +1 -1
- package/dist/services/renderOrchestrator.d.ts +14 -1
- package/dist/services/renderOrchestrator.d.ts.map +1 -1
- package/dist/services/videoFrameExtractor.d.ts +1 -1
- package/dist/services/videoFrameExtractor.d.ts.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -7906,7 +7906,7 @@ function inertIfDisposed(target, _) {
|
|
|
7906
7906
|
};
|
|
7907
7907
|
}
|
|
7908
7908
|
function invokeAtMostOnceForArguments(target, _) {
|
|
7909
|
-
const
|
|
7909
|
+
const cache2 = /* @__PURE__ */ new WeakMap();
|
|
7910
7910
|
let cacheDepth = -1;
|
|
7911
7911
|
return function(...args) {
|
|
7912
7912
|
if (cacheDepth === -1) {
|
|
@@ -7916,7 +7916,7 @@ function invokeAtMostOnceForArguments(target, _) {
|
|
|
7916
7916
|
throw new Error("Memoized method was called with the wrong number of arguments");
|
|
7917
7917
|
}
|
|
7918
7918
|
let freshArguments = false;
|
|
7919
|
-
let cacheIterator =
|
|
7919
|
+
let cacheIterator = cache2;
|
|
7920
7920
|
for (const arg of args) {
|
|
7921
7921
|
if (cacheIterator.has(arg)) {
|
|
7922
7922
|
cacheIterator = cacheIterator.get(arg);
|
|
@@ -45139,7 +45139,7 @@ var require_websocket = __commonJS({
|
|
|
45139
45139
|
var http2 = __require("http");
|
|
45140
45140
|
var net = __require("net");
|
|
45141
45141
|
var tls = __require("tls");
|
|
45142
|
-
var { randomBytes, createHash:
|
|
45142
|
+
var { randomBytes, createHash: createHash4 } = __require("crypto");
|
|
45143
45143
|
var { Duplex, Readable: Readable3 } = __require("stream");
|
|
45144
45144
|
var { URL: URL3 } = __require("url");
|
|
45145
45145
|
var PerMessageDeflate = require_permessage_deflate();
|
|
@@ -45799,7 +45799,7 @@ var require_websocket = __commonJS({
|
|
|
45799
45799
|
abortHandshake(websocket, socket, "Invalid Upgrade header");
|
|
45800
45800
|
return;
|
|
45801
45801
|
}
|
|
45802
|
-
const digest =
|
|
45802
|
+
const digest = createHash4("sha1").update(key2 + GUID).digest("base64");
|
|
45803
45803
|
if (res.headers["sec-websocket-accept"] !== digest) {
|
|
45804
45804
|
abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
|
|
45805
45805
|
return;
|
|
@@ -46166,7 +46166,7 @@ var require_websocket_server = __commonJS({
|
|
|
46166
46166
|
var EventEmitter4 = __require("events");
|
|
46167
46167
|
var http2 = __require("http");
|
|
46168
46168
|
var { Duplex } = __require("stream");
|
|
46169
|
-
var { createHash:
|
|
46169
|
+
var { createHash: createHash4 } = __require("crypto");
|
|
46170
46170
|
var extension = require_extension();
|
|
46171
46171
|
var PerMessageDeflate = require_permessage_deflate();
|
|
46172
46172
|
var subprotocol = require_subprotocol();
|
|
@@ -46467,7 +46467,7 @@ var require_websocket_server = __commonJS({
|
|
|
46467
46467
|
);
|
|
46468
46468
|
}
|
|
46469
46469
|
if (this._state > RUNNING) return abortHandshake(socket, 503);
|
|
46470
|
-
const digest =
|
|
46470
|
+
const digest = createHash4("sha1").update(key2 + GUID).digest("base64");
|
|
46471
46471
|
const headers = [
|
|
46472
46472
|
"HTTP/1.1 101 Switching Protocols",
|
|
46473
46473
|
"Upgrade: websocket",
|
|
@@ -47603,7 +47603,7 @@ var require_range = __commonJS({
|
|
|
47603
47603
|
parseRange(range) {
|
|
47604
47604
|
const memoOpts = (this.options.includePrerelease && FLAG_INCLUDE_PRERELEASE) | (this.options.loose && FLAG_LOOSE);
|
|
47605
47605
|
const memoKey = memoOpts + ":" + range;
|
|
47606
|
-
const cached =
|
|
47606
|
+
const cached = cache2.get(memoKey);
|
|
47607
47607
|
if (cached) {
|
|
47608
47608
|
return cached;
|
|
47609
47609
|
}
|
|
@@ -47637,7 +47637,7 @@ var require_range = __commonJS({
|
|
|
47637
47637
|
rangeMap.delete("");
|
|
47638
47638
|
}
|
|
47639
47639
|
const result = [...rangeMap.values()];
|
|
47640
|
-
|
|
47640
|
+
cache2.set(memoKey, result);
|
|
47641
47641
|
return result;
|
|
47642
47642
|
}
|
|
47643
47643
|
intersects(range, options) {
|
|
@@ -47676,7 +47676,7 @@ var require_range = __commonJS({
|
|
|
47676
47676
|
};
|
|
47677
47677
|
module.exports = Range2;
|
|
47678
47678
|
var LRU = require_lrucache();
|
|
47679
|
-
var
|
|
47679
|
+
var cache2 = new LRU();
|
|
47680
47680
|
var parseOptions = require_parse_options();
|
|
47681
47681
|
var Comparator = require_comparator();
|
|
47682
47682
|
var debug6 = require_debug();
|
|
@@ -54356,12 +54356,12 @@ var require_data = __commonJS({
|
|
|
54356
54356
|
this.hash = hash2;
|
|
54357
54357
|
}
|
|
54358
54358
|
};
|
|
54359
|
-
var data = async ({ href: uri }, { cache } = {}) => {
|
|
54359
|
+
var data = async ({ href: uri }, { cache: cache2 } = {}) => {
|
|
54360
54360
|
const shasum = (0, crypto_1.createHash)("sha1");
|
|
54361
54361
|
shasum.update(uri);
|
|
54362
54362
|
const hash2 = shasum.digest("hex");
|
|
54363
54363
|
debug6('generated SHA1 hash for "data:" URI: %o', hash2);
|
|
54364
|
-
if (
|
|
54364
|
+
if (cache2?.hash === hash2) {
|
|
54365
54365
|
debug6("got matching cache SHA1 hash: %o", hash2);
|
|
54366
54366
|
throw new notmodified_1.default();
|
|
54367
54367
|
} else {
|
|
@@ -54406,7 +54406,7 @@ var require_file = __commonJS({
|
|
|
54406
54406
|
var debug6 = (0, debug_1.default)("get-uri:file");
|
|
54407
54407
|
var file = async ({ href: uri }, opts = {}) => {
|
|
54408
54408
|
const {
|
|
54409
|
-
cache,
|
|
54409
|
+
cache: cache2,
|
|
54410
54410
|
flags = "r",
|
|
54411
54411
|
mode = 438
|
|
54412
54412
|
// =0666
|
|
@@ -54417,7 +54417,7 @@ var require_file = __commonJS({
|
|
|
54417
54417
|
const fdHandle = await fs_1.promises.open(filepath, flags, mode);
|
|
54418
54418
|
const fd = fdHandle.fd;
|
|
54419
54419
|
const stat = await fdHandle.stat();
|
|
54420
|
-
if (
|
|
54420
|
+
if (cache2 && cache2.stat && stat && isNotModified(cache2.stat, stat)) {
|
|
54421
54421
|
await fdHandle.close();
|
|
54422
54422
|
throw new notmodified_1.default();
|
|
54423
54423
|
}
|
|
@@ -56437,7 +56437,7 @@ var require_ftp = __commonJS({
|
|
|
56437
56437
|
var notmodified_1 = __importDefault2(require_notmodified());
|
|
56438
56438
|
var debug6 = (0, debug_1.default)("get-uri:ftp");
|
|
56439
56439
|
var ftp = async (url, opts = {}) => {
|
|
56440
|
-
const { cache } = opts;
|
|
56440
|
+
const { cache: cache2 } = opts;
|
|
56441
56441
|
const filepath = decodeURIComponent(url.pathname);
|
|
56442
56442
|
let lastModified;
|
|
56443
56443
|
if (!filepath) {
|
|
@@ -56491,8 +56491,8 @@ var require_ftp = __commonJS({
|
|
|
56491
56491
|
throw err;
|
|
56492
56492
|
}
|
|
56493
56493
|
function isNotModified() {
|
|
56494
|
-
if (
|
|
56495
|
-
return +
|
|
56494
|
+
if (cache2?.lastModified && lastModified) {
|
|
56495
|
+
return +cache2.lastModified === +lastModified;
|
|
56496
56496
|
}
|
|
56497
56497
|
return false;
|
|
56498
56498
|
}
|
|
@@ -56537,10 +56537,10 @@ var require_http = __commonJS({
|
|
|
56537
56537
|
var debug6 = (0, debug_1.default)("get-uri:http");
|
|
56538
56538
|
var http2 = async (url, opts = {}) => {
|
|
56539
56539
|
debug6("GET %o", url.href);
|
|
56540
|
-
const
|
|
56541
|
-
if (
|
|
56542
|
-
const type2 =
|
|
56543
|
-
if (type2 === 3 &&
|
|
56540
|
+
const cache2 = getCache(url, opts.cache);
|
|
56541
|
+
if (cache2 && isFresh(cache2) && typeof cache2.statusCode === "number") {
|
|
56542
|
+
const type2 = cache2.statusCode / 100 | 0;
|
|
56543
|
+
if (type2 === 3 && cache2.headers.location) {
|
|
56544
56544
|
debug6("cached redirect");
|
|
56545
56545
|
throw new Error("TODO: implement cached redirects!");
|
|
56546
56546
|
}
|
|
@@ -56557,16 +56557,16 @@ var require_http = __commonJS({
|
|
|
56557
56557
|
debug6("using `http` core module");
|
|
56558
56558
|
}
|
|
56559
56559
|
const options = { ...opts };
|
|
56560
|
-
if (
|
|
56560
|
+
if (cache2) {
|
|
56561
56561
|
if (!options.headers) {
|
|
56562
56562
|
options.headers = {};
|
|
56563
56563
|
}
|
|
56564
|
-
const lastModified =
|
|
56564
|
+
const lastModified = cache2.headers["last-modified"];
|
|
56565
56565
|
if (lastModified) {
|
|
56566
56566
|
options.headers["If-Modified-Since"] = lastModified;
|
|
56567
56567
|
debug6('added "If-Modified-Since" request header: %o', lastModified);
|
|
56568
56568
|
}
|
|
56569
|
-
const etag =
|
|
56569
|
+
const etag = cache2.headers.etag;
|
|
56570
56570
|
if (etag) {
|
|
56571
56571
|
options.headers["If-None-Match"] = etag;
|
|
56572
56572
|
debug6('added "If-None-Match" request header: %o', etag);
|
|
@@ -56613,10 +56613,10 @@ var require_http = __commonJS({
|
|
|
56613
56613
|
return res;
|
|
56614
56614
|
};
|
|
56615
56615
|
exports.http = http2;
|
|
56616
|
-
function isFresh(
|
|
56616
|
+
function isFresh(cache2) {
|
|
56617
56617
|
let fresh = false;
|
|
56618
|
-
let expires = parseInt(
|
|
56619
|
-
const cacheControl =
|
|
56618
|
+
let expires = parseInt(cache2.headers.expires || "", 10);
|
|
56619
|
+
const cacheControl = cache2.headers["cache-control"];
|
|
56620
56620
|
if (cacheControl) {
|
|
56621
56621
|
debug6("Cache-Control: %o", cacheControl);
|
|
56622
56622
|
const parts = cacheControl.split(/,\s*?\b/);
|
|
@@ -56626,7 +56626,7 @@ var require_http = __commonJS({
|
|
|
56626
56626
|
const name = subparts[0];
|
|
56627
56627
|
switch (name) {
|
|
56628
56628
|
case "max-age":
|
|
56629
|
-
expires = (
|
|
56629
|
+
expires = (cache2.date || 0) + parseInt(subparts[1], 10) * 1e3;
|
|
56630
56630
|
fresh = Date.now() < expires;
|
|
56631
56631
|
if (fresh) {
|
|
56632
56632
|
debug6('cache is "fresh" due to previous %o Cache-Control param', part);
|
|
@@ -56652,14 +56652,14 @@ var require_http = __commonJS({
|
|
|
56652
56652
|
}
|
|
56653
56653
|
return false;
|
|
56654
56654
|
}
|
|
56655
|
-
function getCache(url,
|
|
56656
|
-
if (
|
|
56657
|
-
if (
|
|
56658
|
-
return
|
|
56655
|
+
function getCache(url, cache2) {
|
|
56656
|
+
if (cache2) {
|
|
56657
|
+
if (cache2.parsed && cache2.parsed.href === url.href) {
|
|
56658
|
+
return cache2;
|
|
56659
56659
|
}
|
|
56660
|
-
if (
|
|
56661
|
-
for (let i = 0; i <
|
|
56662
|
-
const c = getCache(url,
|
|
56660
|
+
if (cache2.redirects) {
|
|
56661
|
+
for (let i = 0; i < cache2.redirects.length; i++) {
|
|
56662
|
+
const c = getCache(url, cache2.redirects[i]);
|
|
56663
56663
|
if (c) {
|
|
56664
56664
|
return c;
|
|
56665
56665
|
}
|
|
@@ -57894,7 +57894,7 @@ var require_util2 = __commonJS({
|
|
|
57894
57894
|
return path12;
|
|
57895
57895
|
}
|
|
57896
57896
|
exports.normalize = normalize2;
|
|
57897
|
-
function
|
|
57897
|
+
function join19(aRoot, aPath) {
|
|
57898
57898
|
if (aRoot === "") {
|
|
57899
57899
|
aRoot = ".";
|
|
57900
57900
|
}
|
|
@@ -57926,7 +57926,7 @@ var require_util2 = __commonJS({
|
|
|
57926
57926
|
}
|
|
57927
57927
|
return joined;
|
|
57928
57928
|
}
|
|
57929
|
-
exports.join =
|
|
57929
|
+
exports.join = join19;
|
|
57930
57930
|
exports.isAbsolute = function(aPath) {
|
|
57931
57931
|
return aPath.charAt(0) === "/" || urlRegexp.test(aPath);
|
|
57932
57932
|
};
|
|
@@ -58099,7 +58099,7 @@ var require_util2 = __commonJS({
|
|
|
58099
58099
|
parsed.path = parsed.path.substring(0, index + 1);
|
|
58100
58100
|
}
|
|
58101
58101
|
}
|
|
58102
|
-
sourceURL =
|
|
58102
|
+
sourceURL = join19(urlGenerate(parsed), sourceURL);
|
|
58103
58103
|
}
|
|
58104
58104
|
return normalize2(sourceURL);
|
|
58105
58105
|
}
|
|
@@ -59901,7 +59901,7 @@ var require_escodegen = __commonJS({
|
|
|
59901
59901
|
function noEmptySpace() {
|
|
59902
59902
|
return space ? space : " ";
|
|
59903
59903
|
}
|
|
59904
|
-
function
|
|
59904
|
+
function join19(left2, right2) {
|
|
59905
59905
|
var leftSource, rightSource, leftCharCode, rightCharCode;
|
|
59906
59906
|
leftSource = toSourceNodeWhenNeeded(left2).toString();
|
|
59907
59907
|
if (leftSource.length === 0) {
|
|
@@ -60232,8 +60232,8 @@ var require_escodegen = __commonJS({
|
|
|
60232
60232
|
} else {
|
|
60233
60233
|
result.push(that.generateExpression(stmt.left, Precedence.Call, E_TTT));
|
|
60234
60234
|
}
|
|
60235
|
-
result =
|
|
60236
|
-
result = [
|
|
60235
|
+
result = join19(result, operator);
|
|
60236
|
+
result = [join19(
|
|
60237
60237
|
result,
|
|
60238
60238
|
that.generateExpression(stmt.right, Precedence.Assignment, E_TTT)
|
|
60239
60239
|
), ")"];
|
|
@@ -60376,11 +60376,11 @@ var require_escodegen = __commonJS({
|
|
|
60376
60376
|
var result, fragment;
|
|
60377
60377
|
result = ["class"];
|
|
60378
60378
|
if (stmt.id) {
|
|
60379
|
-
result =
|
|
60379
|
+
result = join19(result, this.generateExpression(stmt.id, Precedence.Sequence, E_TTT));
|
|
60380
60380
|
}
|
|
60381
60381
|
if (stmt.superClass) {
|
|
60382
|
-
fragment =
|
|
60383
|
-
result =
|
|
60382
|
+
fragment = join19("extends", this.generateExpression(stmt.superClass, Precedence.Unary, E_TTT));
|
|
60383
|
+
result = join19(result, fragment);
|
|
60384
60384
|
}
|
|
60385
60385
|
result.push(space);
|
|
60386
60386
|
result.push(this.generateStatement(stmt.body, S_TFFT));
|
|
@@ -60393,9 +60393,9 @@ var require_escodegen = __commonJS({
|
|
|
60393
60393
|
return escapeDirective(stmt.directive) + this.semicolon(flags);
|
|
60394
60394
|
},
|
|
60395
60395
|
DoWhileStatement: function(stmt, flags) {
|
|
60396
|
-
var result =
|
|
60396
|
+
var result = join19("do", this.maybeBlock(stmt.body, S_TFFF));
|
|
60397
60397
|
result = this.maybeBlockSuffix(stmt.body, result);
|
|
60398
|
-
return
|
|
60398
|
+
return join19(result, [
|
|
60399
60399
|
"while" + space + "(",
|
|
60400
60400
|
this.generateExpression(stmt.test, Precedence.Sequence, E_TTT),
|
|
60401
60401
|
")" + this.semicolon(flags)
|
|
@@ -60431,11 +60431,11 @@ var require_escodegen = __commonJS({
|
|
|
60431
60431
|
ExportDefaultDeclaration: function(stmt, flags) {
|
|
60432
60432
|
var result = ["export"], bodyFlags;
|
|
60433
60433
|
bodyFlags = flags & F_SEMICOLON_OPT ? S_TFFT : S_TFFF;
|
|
60434
|
-
result =
|
|
60434
|
+
result = join19(result, "default");
|
|
60435
60435
|
if (isStatement(stmt.declaration)) {
|
|
60436
|
-
result =
|
|
60436
|
+
result = join19(result, this.generateStatement(stmt.declaration, bodyFlags));
|
|
60437
60437
|
} else {
|
|
60438
|
-
result =
|
|
60438
|
+
result = join19(result, this.generateExpression(stmt.declaration, Precedence.Assignment, E_TTT) + this.semicolon(flags));
|
|
60439
60439
|
}
|
|
60440
60440
|
return result;
|
|
60441
60441
|
},
|
|
@@ -60443,15 +60443,15 @@ var require_escodegen = __commonJS({
|
|
|
60443
60443
|
var result = ["export"], bodyFlags, that = this;
|
|
60444
60444
|
bodyFlags = flags & F_SEMICOLON_OPT ? S_TFFT : S_TFFF;
|
|
60445
60445
|
if (stmt.declaration) {
|
|
60446
|
-
return
|
|
60446
|
+
return join19(result, this.generateStatement(stmt.declaration, bodyFlags));
|
|
60447
60447
|
}
|
|
60448
60448
|
if (stmt.specifiers) {
|
|
60449
60449
|
if (stmt.specifiers.length === 0) {
|
|
60450
|
-
result =
|
|
60450
|
+
result = join19(result, "{" + space + "}");
|
|
60451
60451
|
} else if (stmt.specifiers[0].type === Syntax.ExportBatchSpecifier) {
|
|
60452
|
-
result =
|
|
60452
|
+
result = join19(result, this.generateExpression(stmt.specifiers[0], Precedence.Sequence, E_TTT));
|
|
60453
60453
|
} else {
|
|
60454
|
-
result =
|
|
60454
|
+
result = join19(result, "{");
|
|
60455
60455
|
withIndent(function(indent2) {
|
|
60456
60456
|
var i, iz;
|
|
60457
60457
|
result.push(newline);
|
|
@@ -60469,7 +60469,7 @@ var require_escodegen = __commonJS({
|
|
|
60469
60469
|
result.push(base + "}");
|
|
60470
60470
|
}
|
|
60471
60471
|
if (stmt.source) {
|
|
60472
|
-
result =
|
|
60472
|
+
result = join19(result, [
|
|
60473
60473
|
"from" + space,
|
|
60474
60474
|
// ModuleSpecifier
|
|
60475
60475
|
this.generateExpression(stmt.source, Precedence.Sequence, E_TTT),
|
|
@@ -60557,7 +60557,7 @@ var require_escodegen = __commonJS({
|
|
|
60557
60557
|
];
|
|
60558
60558
|
cursor = 0;
|
|
60559
60559
|
if (stmt.specifiers[cursor].type === Syntax.ImportDefaultSpecifier) {
|
|
60560
|
-
result =
|
|
60560
|
+
result = join19(result, [
|
|
60561
60561
|
this.generateExpression(stmt.specifiers[cursor], Precedence.Sequence, E_TTT)
|
|
60562
60562
|
]);
|
|
60563
60563
|
++cursor;
|
|
@@ -60567,7 +60567,7 @@ var require_escodegen = __commonJS({
|
|
|
60567
60567
|
result.push(",");
|
|
60568
60568
|
}
|
|
60569
60569
|
if (stmt.specifiers[cursor].type === Syntax.ImportNamespaceSpecifier) {
|
|
60570
|
-
result =
|
|
60570
|
+
result = join19(result, [
|
|
60571
60571
|
space,
|
|
60572
60572
|
this.generateExpression(stmt.specifiers[cursor], Precedence.Sequence, E_TTT)
|
|
60573
60573
|
]);
|
|
@@ -60596,7 +60596,7 @@ var require_escodegen = __commonJS({
|
|
|
60596
60596
|
}
|
|
60597
60597
|
}
|
|
60598
60598
|
}
|
|
60599
|
-
result =
|
|
60599
|
+
result = join19(result, [
|
|
60600
60600
|
"from" + space,
|
|
60601
60601
|
// ModuleSpecifier
|
|
60602
60602
|
this.generateExpression(stmt.source, Precedence.Sequence, E_TTT),
|
|
@@ -60650,7 +60650,7 @@ var require_escodegen = __commonJS({
|
|
|
60650
60650
|
return result;
|
|
60651
60651
|
},
|
|
60652
60652
|
ThrowStatement: function(stmt, flags) {
|
|
60653
|
-
return [
|
|
60653
|
+
return [join19(
|
|
60654
60654
|
"throw",
|
|
60655
60655
|
this.generateExpression(stmt.argument, Precedence.Sequence, E_TTT)
|
|
60656
60656
|
), this.semicolon(flags)];
|
|
@@ -60661,7 +60661,7 @@ var require_escodegen = __commonJS({
|
|
|
60661
60661
|
result = this.maybeBlockSuffix(stmt.block, result);
|
|
60662
60662
|
if (stmt.handlers) {
|
|
60663
60663
|
for (i = 0, iz = stmt.handlers.length; i < iz; ++i) {
|
|
60664
|
-
result =
|
|
60664
|
+
result = join19(result, this.generateStatement(stmt.handlers[i], S_TFFF));
|
|
60665
60665
|
if (stmt.finalizer || i + 1 !== iz) {
|
|
60666
60666
|
result = this.maybeBlockSuffix(stmt.handlers[i].body, result);
|
|
60667
60667
|
}
|
|
@@ -60669,7 +60669,7 @@ var require_escodegen = __commonJS({
|
|
|
60669
60669
|
} else {
|
|
60670
60670
|
guardedHandlers = stmt.guardedHandlers || [];
|
|
60671
60671
|
for (i = 0, iz = guardedHandlers.length; i < iz; ++i) {
|
|
60672
|
-
result =
|
|
60672
|
+
result = join19(result, this.generateStatement(guardedHandlers[i], S_TFFF));
|
|
60673
60673
|
if (stmt.finalizer || i + 1 !== iz) {
|
|
60674
60674
|
result = this.maybeBlockSuffix(guardedHandlers[i].body, result);
|
|
60675
60675
|
}
|
|
@@ -60677,13 +60677,13 @@ var require_escodegen = __commonJS({
|
|
|
60677
60677
|
if (stmt.handler) {
|
|
60678
60678
|
if (Array.isArray(stmt.handler)) {
|
|
60679
60679
|
for (i = 0, iz = stmt.handler.length; i < iz; ++i) {
|
|
60680
|
-
result =
|
|
60680
|
+
result = join19(result, this.generateStatement(stmt.handler[i], S_TFFF));
|
|
60681
60681
|
if (stmt.finalizer || i + 1 !== iz) {
|
|
60682
60682
|
result = this.maybeBlockSuffix(stmt.handler[i].body, result);
|
|
60683
60683
|
}
|
|
60684
60684
|
}
|
|
60685
60685
|
} else {
|
|
60686
|
-
result =
|
|
60686
|
+
result = join19(result, this.generateStatement(stmt.handler, S_TFFF));
|
|
60687
60687
|
if (stmt.finalizer) {
|
|
60688
60688
|
result = this.maybeBlockSuffix(stmt.handler.body, result);
|
|
60689
60689
|
}
|
|
@@ -60691,7 +60691,7 @@ var require_escodegen = __commonJS({
|
|
|
60691
60691
|
}
|
|
60692
60692
|
}
|
|
60693
60693
|
if (stmt.finalizer) {
|
|
60694
|
-
result =
|
|
60694
|
+
result = join19(result, ["finally", this.maybeBlock(stmt.finalizer, S_TFFF)]);
|
|
60695
60695
|
}
|
|
60696
60696
|
return result;
|
|
60697
60697
|
},
|
|
@@ -60725,7 +60725,7 @@ var require_escodegen = __commonJS({
|
|
|
60725
60725
|
withIndent(function() {
|
|
60726
60726
|
if (stmt.test) {
|
|
60727
60727
|
result = [
|
|
60728
|
-
|
|
60728
|
+
join19("case", that.generateExpression(stmt.test, Precedence.Sequence, E_TTT)),
|
|
60729
60729
|
":"
|
|
60730
60730
|
];
|
|
60731
60731
|
} else {
|
|
@@ -60773,9 +60773,9 @@ var require_escodegen = __commonJS({
|
|
|
60773
60773
|
result.push(this.maybeBlock(stmt.consequent, S_TFFF));
|
|
60774
60774
|
result = this.maybeBlockSuffix(stmt.consequent, result);
|
|
60775
60775
|
if (stmt.alternate.type === Syntax.IfStatement) {
|
|
60776
|
-
result =
|
|
60776
|
+
result = join19(result, ["else ", this.generateStatement(stmt.alternate, bodyFlags)]);
|
|
60777
60777
|
} else {
|
|
60778
|
-
result =
|
|
60778
|
+
result = join19(result, join19("else", this.maybeBlock(stmt.alternate, bodyFlags)));
|
|
60779
60779
|
}
|
|
60780
60780
|
} else {
|
|
60781
60781
|
result.push(this.maybeBlock(stmt.consequent, bodyFlags));
|
|
@@ -60876,7 +60876,7 @@ var require_escodegen = __commonJS({
|
|
|
60876
60876
|
},
|
|
60877
60877
|
ReturnStatement: function(stmt, flags) {
|
|
60878
60878
|
if (stmt.argument) {
|
|
60879
|
-
return [
|
|
60879
|
+
return [join19(
|
|
60880
60880
|
"return",
|
|
60881
60881
|
this.generateExpression(stmt.argument, Precedence.Sequence, E_TTT)
|
|
60882
60882
|
), this.semicolon(flags)];
|
|
@@ -60965,14 +60965,14 @@ var require_escodegen = __commonJS({
|
|
|
60965
60965
|
if (leftSource.charCodeAt(leftSource.length - 1) === 47 && esutils.code.isIdentifierPartES5(expr.operator.charCodeAt(0))) {
|
|
60966
60966
|
result = [fragment, noEmptySpace(), expr.operator];
|
|
60967
60967
|
} else {
|
|
60968
|
-
result =
|
|
60968
|
+
result = join19(fragment, expr.operator);
|
|
60969
60969
|
}
|
|
60970
60970
|
fragment = this.generateExpression(expr.right, rightPrecedence, flags);
|
|
60971
60971
|
if (expr.operator === "/" && fragment.toString().charAt(0) === "/" || expr.operator.slice(-1) === "<" && fragment.toString().slice(0, 3) === "!--") {
|
|
60972
60972
|
result.push(noEmptySpace());
|
|
60973
60973
|
result.push(fragment);
|
|
60974
60974
|
} else {
|
|
60975
|
-
result =
|
|
60975
|
+
result = join19(result, fragment);
|
|
60976
60976
|
}
|
|
60977
60977
|
if (expr.operator === "in" && !(flags & F_ALLOW_IN)) {
|
|
60978
60978
|
return ["(", result, ")"];
|
|
@@ -61012,7 +61012,7 @@ var require_escodegen = __commonJS({
|
|
|
61012
61012
|
var result, length, i, iz, itemFlags;
|
|
61013
61013
|
length = expr["arguments"].length;
|
|
61014
61014
|
itemFlags = flags & F_ALLOW_UNPARATH_NEW && !parentheses && length === 0 ? E_TFT : E_TFF;
|
|
61015
|
-
result =
|
|
61015
|
+
result = join19(
|
|
61016
61016
|
"new",
|
|
61017
61017
|
this.generateExpression(expr.callee, Precedence.New, itemFlags)
|
|
61018
61018
|
);
|
|
@@ -61062,11 +61062,11 @@ var require_escodegen = __commonJS({
|
|
|
61062
61062
|
var result, fragment, rightCharCode, leftSource, leftCharCode;
|
|
61063
61063
|
fragment = this.generateExpression(expr.argument, Precedence.Unary, E_TTT);
|
|
61064
61064
|
if (space === "") {
|
|
61065
|
-
result =
|
|
61065
|
+
result = join19(expr.operator, fragment);
|
|
61066
61066
|
} else {
|
|
61067
61067
|
result = [expr.operator];
|
|
61068
61068
|
if (expr.operator.length > 2) {
|
|
61069
|
-
result =
|
|
61069
|
+
result = join19(result, fragment);
|
|
61070
61070
|
} else {
|
|
61071
61071
|
leftSource = toSourceNodeWhenNeeded(result).toString();
|
|
61072
61072
|
leftCharCode = leftSource.charCodeAt(leftSource.length - 1);
|
|
@@ -61089,7 +61089,7 @@ var require_escodegen = __commonJS({
|
|
|
61089
61089
|
result = "yield";
|
|
61090
61090
|
}
|
|
61091
61091
|
if (expr.argument) {
|
|
61092
|
-
result =
|
|
61092
|
+
result = join19(
|
|
61093
61093
|
result,
|
|
61094
61094
|
this.generateExpression(expr.argument, Precedence.Yield, E_TTT)
|
|
61095
61095
|
);
|
|
@@ -61097,7 +61097,7 @@ var require_escodegen = __commonJS({
|
|
|
61097
61097
|
return parenthesize(result, Precedence.Yield, precedence);
|
|
61098
61098
|
},
|
|
61099
61099
|
AwaitExpression: function(expr, precedence, flags) {
|
|
61100
|
-
var result =
|
|
61100
|
+
var result = join19(
|
|
61101
61101
|
expr.all ? "await*" : "await",
|
|
61102
61102
|
this.generateExpression(expr.argument, Precedence.Await, E_TTT)
|
|
61103
61103
|
);
|
|
@@ -61180,11 +61180,11 @@ var require_escodegen = __commonJS({
|
|
|
61180
61180
|
var result, fragment;
|
|
61181
61181
|
result = ["class"];
|
|
61182
61182
|
if (expr.id) {
|
|
61183
|
-
result =
|
|
61183
|
+
result = join19(result, this.generateExpression(expr.id, Precedence.Sequence, E_TTT));
|
|
61184
61184
|
}
|
|
61185
61185
|
if (expr.superClass) {
|
|
61186
|
-
fragment =
|
|
61187
|
-
result =
|
|
61186
|
+
fragment = join19("extends", this.generateExpression(expr.superClass, Precedence.Unary, E_TTT));
|
|
61187
|
+
result = join19(result, fragment);
|
|
61188
61188
|
}
|
|
61189
61189
|
result.push(space);
|
|
61190
61190
|
result.push(this.generateStatement(expr.body, S_TFFT));
|
|
@@ -61199,7 +61199,7 @@ var require_escodegen = __commonJS({
|
|
|
61199
61199
|
}
|
|
61200
61200
|
if (expr.kind === "get" || expr.kind === "set") {
|
|
61201
61201
|
fragment = [
|
|
61202
|
-
|
|
61202
|
+
join19(expr.kind, this.generatePropertyKey(expr.key, expr.computed)),
|
|
61203
61203
|
this.generateFunctionBody(expr.value)
|
|
61204
61204
|
];
|
|
61205
61205
|
} else {
|
|
@@ -61209,7 +61209,7 @@ var require_escodegen = __commonJS({
|
|
|
61209
61209
|
this.generateFunctionBody(expr.value)
|
|
61210
61210
|
];
|
|
61211
61211
|
}
|
|
61212
|
-
return
|
|
61212
|
+
return join19(result, fragment);
|
|
61213
61213
|
},
|
|
61214
61214
|
Property: function(expr, precedence, flags) {
|
|
61215
61215
|
if (expr.kind === "get" || expr.kind === "set") {
|
|
@@ -61404,7 +61404,7 @@ var require_escodegen = __commonJS({
|
|
|
61404
61404
|
for (i = 0, iz = expr.blocks.length; i < iz; ++i) {
|
|
61405
61405
|
fragment = that.generateExpression(expr.blocks[i], Precedence.Sequence, E_TTT);
|
|
61406
61406
|
if (i > 0 || extra.moz.comprehensionExpressionStartsWithAssignment) {
|
|
61407
|
-
result =
|
|
61407
|
+
result = join19(result, fragment);
|
|
61408
61408
|
} else {
|
|
61409
61409
|
result.push(fragment);
|
|
61410
61410
|
}
|
|
@@ -61412,13 +61412,13 @@ var require_escodegen = __commonJS({
|
|
|
61412
61412
|
});
|
|
61413
61413
|
}
|
|
61414
61414
|
if (expr.filter) {
|
|
61415
|
-
result =
|
|
61415
|
+
result = join19(result, "if" + space);
|
|
61416
61416
|
fragment = this.generateExpression(expr.filter, Precedence.Sequence, E_TTT);
|
|
61417
|
-
result =
|
|
61417
|
+
result = join19(result, ["(", fragment, ")"]);
|
|
61418
61418
|
}
|
|
61419
61419
|
if (!extra.moz.comprehensionExpressionStartsWithAssignment) {
|
|
61420
61420
|
fragment = this.generateExpression(expr.body, Precedence.Assignment, E_TTT);
|
|
61421
|
-
result =
|
|
61421
|
+
result = join19(result, fragment);
|
|
61422
61422
|
}
|
|
61423
61423
|
result.push(expr.type === Syntax.GeneratorExpression ? ")" : "]");
|
|
61424
61424
|
return result;
|
|
@@ -61434,8 +61434,8 @@ var require_escodegen = __commonJS({
|
|
|
61434
61434
|
} else {
|
|
61435
61435
|
fragment = this.generateExpression(expr.left, Precedence.Call, E_TTT);
|
|
61436
61436
|
}
|
|
61437
|
-
fragment =
|
|
61438
|
-
fragment =
|
|
61437
|
+
fragment = join19(fragment, expr.of ? "of" : "in");
|
|
61438
|
+
fragment = join19(fragment, this.generateExpression(expr.right, Precedence.Sequence, E_TTT));
|
|
61439
61439
|
return ["for" + space + "(", fragment, ")"];
|
|
61440
61440
|
},
|
|
61441
61441
|
SpreadElement: function(expr, precedence, flags) {
|
|
@@ -69092,12 +69092,12 @@ var require_path = __commonJS({
|
|
|
69092
69092
|
return path12.__childCache || (path12.__childCache = /* @__PURE__ */ Object.create(null));
|
|
69093
69093
|
}
|
|
69094
69094
|
function getChildPath(path12, name) {
|
|
69095
|
-
var
|
|
69095
|
+
var cache2 = getChildCache(path12);
|
|
69096
69096
|
var actualChildValue = path12.getValueProperty(name);
|
|
69097
|
-
var childPath =
|
|
69098
|
-
if (!hasOwn.call(
|
|
69097
|
+
var childPath = cache2[name];
|
|
69098
|
+
if (!hasOwn.call(cache2, name) || // Ensure consistency between cache and reality.
|
|
69099
69099
|
childPath.value !== actualChildValue) {
|
|
69100
|
-
childPath =
|
|
69100
|
+
childPath = cache2[name] = new path12.constructor(actualChildValue, path12, name);
|
|
69101
69101
|
}
|
|
69102
69102
|
return childPath;
|
|
69103
69103
|
}
|
|
@@ -69173,7 +69173,7 @@ var require_path = __commonJS({
|
|
|
69173
69173
|
isNumber4.assert(start);
|
|
69174
69174
|
isNumber4.assert(end);
|
|
69175
69175
|
var moves = /* @__PURE__ */ Object.create(null);
|
|
69176
|
-
var
|
|
69176
|
+
var cache2 = getChildCache(path12);
|
|
69177
69177
|
for (var i = start; i < end; ++i) {
|
|
69178
69178
|
if (hasOwn.call(path12.value, i)) {
|
|
69179
69179
|
var childPath = path12.get(i);
|
|
@@ -69183,17 +69183,17 @@ var require_path = __commonJS({
|
|
|
69183
69183
|
var newIndex = i + offset;
|
|
69184
69184
|
childPath.name = newIndex;
|
|
69185
69185
|
moves[newIndex] = childPath;
|
|
69186
|
-
delete
|
|
69186
|
+
delete cache2[i];
|
|
69187
69187
|
}
|
|
69188
69188
|
}
|
|
69189
|
-
delete
|
|
69189
|
+
delete cache2.length;
|
|
69190
69190
|
return function() {
|
|
69191
69191
|
for (var newIndex2 in moves) {
|
|
69192
69192
|
var childPath2 = moves[newIndex2];
|
|
69193
69193
|
if (childPath2.name !== +newIndex2) {
|
|
69194
69194
|
throw new Error("");
|
|
69195
69195
|
}
|
|
69196
|
-
|
|
69196
|
+
cache2[newIndex2] = childPath2;
|
|
69197
69197
|
path12.value[newIndex2] = childPath2.value;
|
|
69198
69198
|
}
|
|
69199
69199
|
};
|
|
@@ -69225,9 +69225,9 @@ var require_path = __commonJS({
|
|
|
69225
69225
|
};
|
|
69226
69226
|
Pp.pop = function pop() {
|
|
69227
69227
|
isArray4.assert(this.value);
|
|
69228
|
-
var
|
|
69229
|
-
delete
|
|
69230
|
-
delete
|
|
69228
|
+
var cache2 = getChildCache(this);
|
|
69229
|
+
delete cache2[this.value.length - 1];
|
|
69230
|
+
delete cache2.length;
|
|
69231
69231
|
return this.value.pop();
|
|
69232
69232
|
};
|
|
69233
69233
|
Pp.insertAt = function insertAt(index) {
|
|
@@ -76739,12 +76739,12 @@ var init_Cache = __esm({
|
|
|
76739
76739
|
/**
|
|
76740
76740
|
* @internal
|
|
76741
76741
|
*/
|
|
76742
|
-
constructor(
|
|
76743
|
-
this.#cache =
|
|
76742
|
+
constructor(cache2, browser, buildId, platform) {
|
|
76743
|
+
this.#cache = cache2;
|
|
76744
76744
|
this.browser = browser;
|
|
76745
76745
|
this.buildId = buildId;
|
|
76746
76746
|
this.platform = platform;
|
|
76747
|
-
this.executablePath =
|
|
76747
|
+
this.executablePath = cache2.computeExecutablePath({
|
|
76748
76748
|
browser,
|
|
76749
76749
|
buildId,
|
|
76750
76750
|
platform
|
|
@@ -81914,8 +81914,8 @@ async function installWithProviders(options) {
|
|
|
81914
81914
|
if (!options.platform) {
|
|
81915
81915
|
throw new Error("Platform must be defined");
|
|
81916
81916
|
}
|
|
81917
|
-
const
|
|
81918
|
-
const browserRoot =
|
|
81917
|
+
const cache2 = new Cache(options.cacheDir);
|
|
81918
|
+
const browserRoot = cache2.browserRoot(options.browser);
|
|
81919
81919
|
const providers = [...options.providers || []];
|
|
81920
81920
|
if (options.baseUrl) {
|
|
81921
81921
|
providers.push(new DefaultProvider(options.baseUrl));
|
|
@@ -82017,8 +82017,8 @@ async function installUrl(url, options, provider) {
|
|
|
82017
82017
|
}
|
|
82018
82018
|
const fileName = decodeURIComponent(url.toString()).split("/").pop();
|
|
82019
82019
|
assert2(fileName, `A malformed download URL was found: ${url}.`);
|
|
82020
|
-
const
|
|
82021
|
-
const browserRoot =
|
|
82020
|
+
const cache2 = new Cache(options.cacheDir);
|
|
82021
|
+
const browserRoot = cache2.browserRoot(options.browser);
|
|
82022
82022
|
const archivePath = path8.join(browserRoot, `${options.buildId}-${fileName}`);
|
|
82023
82023
|
if (!existsSync(browserRoot)) {
|
|
82024
82024
|
await mkdir2(browserRoot, { recursive: true });
|
|
@@ -82033,16 +82033,16 @@ async function installUrl(url, options, provider) {
|
|
|
82033
82033
|
debugTimeEnd("download");
|
|
82034
82034
|
return archivePath;
|
|
82035
82035
|
}
|
|
82036
|
-
const outputPath =
|
|
82036
|
+
const outputPath = cache2.installationDir(options.browser, options.platform, options.buildId);
|
|
82037
82037
|
const relativeExecutablePath6 = await provider.getExecutablePath({
|
|
82038
82038
|
browser: options.browser,
|
|
82039
82039
|
buildId: options.buildId,
|
|
82040
82040
|
platform: options.platform
|
|
82041
82041
|
});
|
|
82042
82042
|
debugInstall(`Using executable path from provider: ${relativeExecutablePath6}`);
|
|
82043
|
-
const installedBrowser = new InstalledBrowser(
|
|
82043
|
+
const installedBrowser = new InstalledBrowser(cache2, options.browser, options.buildId, options.platform);
|
|
82044
82044
|
if (!(provider instanceof DefaultProvider)) {
|
|
82045
|
-
|
|
82045
|
+
cache2.writeExecutablePath(options.browser, options.platform, options.buildId, relativeExecutablePath6);
|
|
82046
82046
|
}
|
|
82047
82047
|
try {
|
|
82048
82048
|
if (existsSync(outputPath)) {
|
|
@@ -87414,8 +87414,8 @@ var init_CLI = __esm({
|
|
|
87414
87414
|
console.log("Cancelled.");
|
|
87415
87415
|
return;
|
|
87416
87416
|
}
|
|
87417
|
-
const
|
|
87418
|
-
|
|
87417
|
+
const cache2 = new Cache(cacheDir);
|
|
87418
|
+
cache2.clear();
|
|
87419
87419
|
console.log(`${cacheDir} cleared.`);
|
|
87420
87420
|
});
|
|
87421
87421
|
}).command("list", "List all installed browsers in the cache directory", (yargs2) => {
|
|
@@ -87426,8 +87426,8 @@ var init_CLI = __esm({
|
|
|
87426
87426
|
return this.#definePathParameter(yargs2);
|
|
87427
87427
|
}, async (args) => {
|
|
87428
87428
|
const cacheDir = args.path ?? this.#cachePath;
|
|
87429
|
-
const
|
|
87430
|
-
const browsers =
|
|
87429
|
+
const cache2 = new Cache(cacheDir);
|
|
87430
|
+
const browsers = cache2.getInstalledBrowsers();
|
|
87431
87431
|
for (const browser of browsers) {
|
|
87432
87432
|
console.log(`${browser.browser}@${browser.buildId} (${browser.platform}) ${browser.executablePath}`);
|
|
87433
87433
|
}
|
|
@@ -87597,9 +87597,9 @@ async function getConnectionTransport(options) {
|
|
|
87597
87597
|
throw new Error("Could not detect required browser platform");
|
|
87598
87598
|
}
|
|
87599
87599
|
const { convertPuppeteerChannelToBrowsersChannel: convertPuppeteerChannelToBrowsersChannel2 } = await Promise.resolve().then(() => (init_LaunchOptions(), LaunchOptions_exports));
|
|
87600
|
-
const { join:
|
|
87600
|
+
const { join: join19 } = await import("node:path");
|
|
87601
87601
|
const userDataDir = resolveDefaultUserDataDir3(Browser4.CHROME, platform, convertPuppeteerChannelToBrowsersChannel2(options.channel));
|
|
87602
|
-
const portPath =
|
|
87602
|
+
const portPath = join19(userDataDir, "DevToolsActivePort");
|
|
87603
87603
|
try {
|
|
87604
87604
|
const fileContent = await environment.value.fs.promises.readFile(portPath, "ascii");
|
|
87605
87605
|
const [rawPort, rawPath] = fileContent.split("\n").map((line) => {
|
|
@@ -89417,12 +89417,13 @@ var init_puppeteer_core = __esm({
|
|
|
89417
89417
|
|
|
89418
89418
|
// src/services/renderOrchestrator.ts
|
|
89419
89419
|
import {
|
|
89420
|
-
existsSync as
|
|
89421
|
-
mkdirSync as
|
|
89420
|
+
existsSync as existsSync16,
|
|
89421
|
+
mkdirSync as mkdirSync11,
|
|
89422
89422
|
rmSync as rmSync3,
|
|
89423
89423
|
readFileSync as readFileSync10,
|
|
89424
|
-
readdirSync as
|
|
89425
|
-
|
|
89424
|
+
readdirSync as readdirSync8,
|
|
89425
|
+
statSync as statSync7,
|
|
89426
|
+
writeFileSync as writeFileSync5,
|
|
89426
89427
|
copyFileSync as copyFileSync2,
|
|
89427
89428
|
appendFileSync
|
|
89428
89429
|
} from "fs";
|
|
@@ -98747,7 +98748,8 @@ function resolveConfig(overrides) {
|
|
|
98747
98748
|
DEFAULT_CONFIG.renderReadyTimeout
|
|
98748
98749
|
),
|
|
98749
98750
|
verifyRuntime: env2("PRODUCER_VERIFY_HYPERFRAME_RUNTIME") !== "false",
|
|
98750
|
-
runtimeManifestPath: env2("PRODUCER_HYPERFRAME_MANIFEST_PATH")
|
|
98751
|
+
runtimeManifestPath: env2("PRODUCER_HYPERFRAME_MANIFEST_PATH"),
|
|
98752
|
+
extractCacheDir: env2("HYPERFRAMES_EXTRACT_CACHE_DIR")
|
|
98751
98753
|
};
|
|
98752
98754
|
const cleanEnv = Object.fromEntries(Object.entries(fromEnv).filter(([, v]) => v !== void 0));
|
|
98753
98755
|
return {
|
|
@@ -99903,6 +99905,7 @@ var mediaRules = [
|
|
|
99903
99905
|
|
|
99904
99906
|
// ../core/src/lint/rules/gsap.ts
|
|
99905
99907
|
var META_GSAP_KEYS = /* @__PURE__ */ new Set(["duration", "ease", "repeat", "yoyo", "overwrite", "delay"]);
|
|
99908
|
+
var SCENE_BOUNDARY_EPSILON_SECONDS = 0.05;
|
|
99906
99909
|
function countClassUsage(tags) {
|
|
99907
99910
|
const counts = /* @__PURE__ */ new Map();
|
|
99908
99911
|
for (const tag of tags) {
|
|
@@ -99943,6 +99946,7 @@ function extractGsapWindows(script) {
|
|
|
99943
99946
|
position: animation.position,
|
|
99944
99947
|
end: animation.position + meta.effectiveDuration,
|
|
99945
99948
|
properties: meta.properties.length > 0 ? meta.properties : Object.keys(animation.properties),
|
|
99949
|
+
propertyValues: meta.propertyValues,
|
|
99946
99950
|
overwriteAuto: meta.overwriteAuto,
|
|
99947
99951
|
method: match2[1] ?? "to",
|
|
99948
99952
|
raw: raw2
|
|
@@ -99951,8 +99955,14 @@ function extractGsapWindows(script) {
|
|
|
99951
99955
|
return windows;
|
|
99952
99956
|
}
|
|
99953
99957
|
function parseGsapWindowMeta(method, argsStr) {
|
|
99958
|
+
const emptyMeta = {
|
|
99959
|
+
effectiveDuration: 0,
|
|
99960
|
+
properties: [],
|
|
99961
|
+
propertyValues: {},
|
|
99962
|
+
overwriteAuto: false
|
|
99963
|
+
};
|
|
99954
99964
|
const selectorMatch = argsStr.match(/^\s*["']([^"']+)["']\s*,/);
|
|
99955
|
-
if (!selectorMatch) return
|
|
99965
|
+
if (!selectorMatch) return emptyMeta;
|
|
99956
99966
|
const afterSelector = argsStr.slice(selectorMatch[0].length);
|
|
99957
99967
|
let properties = {};
|
|
99958
99968
|
let fromProperties = {};
|
|
@@ -99990,6 +100000,7 @@ function parseGsapWindowMeta(method, argsStr) {
|
|
|
99990
100000
|
return {
|
|
99991
100001
|
effectiveDuration: method === "set" ? 0 : effectiveDuration,
|
|
99992
100002
|
properties: [...propertyNames],
|
|
100003
|
+
propertyValues: properties,
|
|
99993
100004
|
overwriteAuto
|
|
99994
100005
|
};
|
|
99995
100006
|
}
|
|
@@ -100037,6 +100048,94 @@ function stringValue(value) {
|
|
|
100037
100048
|
if (typeof value === "number") return String(value);
|
|
100038
100049
|
return null;
|
|
100039
100050
|
}
|
|
100051
|
+
function zeroValue(value) {
|
|
100052
|
+
if (typeof value === "number") return value === 0;
|
|
100053
|
+
if (typeof value !== "string") return false;
|
|
100054
|
+
return Number(value.trim()) === 0;
|
|
100055
|
+
}
|
|
100056
|
+
function isHiddenGsapState(values) {
|
|
100057
|
+
const visibility = stringValue(values.visibility)?.toLowerCase();
|
|
100058
|
+
const display = stringValue(values.display)?.toLowerCase();
|
|
100059
|
+
return zeroValue(values.opacity) || zeroValue(values.autoAlpha) || visibility === "hidden" || display === "none";
|
|
100060
|
+
}
|
|
100061
|
+
function isSceneBoundaryExit(win) {
|
|
100062
|
+
if (win.end <= win.position) return false;
|
|
100063
|
+
if (win.method !== "to" && win.method !== "fromTo") return false;
|
|
100064
|
+
return isHiddenGsapState(win.propertyValues);
|
|
100065
|
+
}
|
|
100066
|
+
function isHardKillSet(win, selector, boundary) {
|
|
100067
|
+
return win.method === "set" && win.targetSelector === selector && Math.abs(win.position - boundary) <= SCENE_BOUNDARY_EPSILON_SECONDS && isHiddenGsapState(win.propertyValues);
|
|
100068
|
+
}
|
|
100069
|
+
function hiddenStateLiteral(values) {
|
|
100070
|
+
if (zeroValue(values.autoAlpha)) return "{ autoAlpha: 0 }";
|
|
100071
|
+
if (zeroValue(values.opacity)) return "{ opacity: 0 }";
|
|
100072
|
+
if (stringValue(values.visibility)?.toLowerCase() === "hidden") return '{ visibility: "hidden" }';
|
|
100073
|
+
if (stringValue(values.display)?.toLowerCase() === "none") return '{ display: "none" }';
|
|
100074
|
+
return "{ opacity: 0 }";
|
|
100075
|
+
}
|
|
100076
|
+
function findTagEnd(source2, tag) {
|
|
100077
|
+
const escapedTagName = tag.name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
100078
|
+
const pattern = new RegExp(`<\\/?${escapedTagName}\\b[^>]*>`, "gi");
|
|
100079
|
+
pattern.lastIndex = tag.index;
|
|
100080
|
+
let depth = 0;
|
|
100081
|
+
let match2;
|
|
100082
|
+
while ((match2 = pattern.exec(source2)) !== null) {
|
|
100083
|
+
const raw2 = match2[0];
|
|
100084
|
+
const isClosing = /^<\s*\//.test(raw2);
|
|
100085
|
+
const isSelfClosing = /\/\s*>$/.test(raw2);
|
|
100086
|
+
if (!isClosing && !isSelfClosing) depth += 1;
|
|
100087
|
+
if (isClosing) depth -= 1;
|
|
100088
|
+
if (depth === 0) return pattern.lastIndex;
|
|
100089
|
+
}
|
|
100090
|
+
return source2.length;
|
|
100091
|
+
}
|
|
100092
|
+
function collectCompositionRanges(source2, tags) {
|
|
100093
|
+
return tags.map((tag) => {
|
|
100094
|
+
const id = readAttr(tag.raw, "data-composition-id");
|
|
100095
|
+
if (!id) return null;
|
|
100096
|
+
return {
|
|
100097
|
+
id,
|
|
100098
|
+
start: tag.index,
|
|
100099
|
+
end: findTagEnd(source2, tag)
|
|
100100
|
+
};
|
|
100101
|
+
}).filter((range) => range !== null);
|
|
100102
|
+
}
|
|
100103
|
+
function findContainingCompositionId(tag, ranges) {
|
|
100104
|
+
let match2 = null;
|
|
100105
|
+
for (const range of ranges) {
|
|
100106
|
+
if (tag.index < range.start || tag.index >= range.end) continue;
|
|
100107
|
+
if (!match2 || range.start >= match2.start) match2 = range;
|
|
100108
|
+
}
|
|
100109
|
+
return match2?.id || null;
|
|
100110
|
+
}
|
|
100111
|
+
function collectClipStartBoundariesByComposition(source2, tags) {
|
|
100112
|
+
const ranges = collectCompositionRanges(source2, tags);
|
|
100113
|
+
const boundaries = /* @__PURE__ */ new Map();
|
|
100114
|
+
for (const tag of tags) {
|
|
100115
|
+
const classAttr = readAttr(tag.raw, "class") || "";
|
|
100116
|
+
const classes = classAttr.split(/\s+/).filter(Boolean);
|
|
100117
|
+
if (!classes.includes("clip")) continue;
|
|
100118
|
+
const compositionId = findContainingCompositionId(tag, ranges);
|
|
100119
|
+
if (!compositionId) continue;
|
|
100120
|
+
const start = numberValue(readAttr(tag.raw, "data-start") ?? void 0);
|
|
100121
|
+
if (start == null || start <= 0) continue;
|
|
100122
|
+
const compositionBoundaries = boundaries.get(compositionId) ?? /* @__PURE__ */ new Set();
|
|
100123
|
+
compositionBoundaries.add(start);
|
|
100124
|
+
boundaries.set(compositionId, compositionBoundaries);
|
|
100125
|
+
}
|
|
100126
|
+
return new Map(
|
|
100127
|
+
[...boundaries.entries()].map(([compositionId, values]) => [
|
|
100128
|
+
compositionId,
|
|
100129
|
+
[...values].sort((a, b) => a - b)
|
|
100130
|
+
])
|
|
100131
|
+
);
|
|
100132
|
+
}
|
|
100133
|
+
function findMatchingSceneBoundary(time, boundaries) {
|
|
100134
|
+
for (const boundary of boundaries) {
|
|
100135
|
+
if (Math.abs(time - boundary) <= SCENE_BOUNDARY_EPSILON_SECONDS) return boundary;
|
|
100136
|
+
}
|
|
100137
|
+
return null;
|
|
100138
|
+
}
|
|
100040
100139
|
function isSuspiciousGlobalSelector(selector) {
|
|
100041
100140
|
if (!selector) return false;
|
|
100042
100141
|
if (selector.includes("[data-composition-id=")) return false;
|
|
@@ -100077,7 +100176,7 @@ function cssTransformToGsapProps(cssTransform) {
|
|
|
100077
100176
|
}
|
|
100078
100177
|
var gsapRules = [
|
|
100079
100178
|
// overlapping_gsap_tweens + gsap_animates_clip_element + unscoped_gsap_selector
|
|
100080
|
-
({ tags, scripts, rootCompositionId }) => {
|
|
100179
|
+
({ source: source2, tags, scripts, rootCompositionId }) => {
|
|
100081
100180
|
const findings = [];
|
|
100082
100181
|
const clipIds = /* @__PURE__ */ new Map();
|
|
100083
100182
|
const clipClasses = /* @__PURE__ */ new Map();
|
|
@@ -100097,9 +100196,11 @@ var gsapRules = [
|
|
|
100097
100196
|
}
|
|
100098
100197
|
}
|
|
100099
100198
|
const classUsage = countClassUsage(tags);
|
|
100199
|
+
const clipStartBoundariesByComposition = collectClipStartBoundariesByComposition(source2, tags);
|
|
100100
100200
|
for (const script of scripts) {
|
|
100101
100201
|
const localTimelineCompId = readRegisteredTimelineCompositionId(script.content);
|
|
100102
100202
|
const gsapWindows = extractGsapWindows(script.content);
|
|
100203
|
+
const clipStartBoundaries = clipStartBoundariesByComposition.get(localTimelineCompId || rootCompositionId || "") ?? [];
|
|
100103
100204
|
for (let i = 0; i < gsapWindows.length; i++) {
|
|
100104
100205
|
const left2 = gsapWindows[i];
|
|
100105
100206
|
if (!left2) continue;
|
|
@@ -100128,6 +100229,25 @@ ${right2.raw}`)
|
|
|
100128
100229
|
});
|
|
100129
100230
|
}
|
|
100130
100231
|
}
|
|
100232
|
+
if (clipStartBoundaries.length > 0) {
|
|
100233
|
+
for (const win of gsapWindows) {
|
|
100234
|
+
if (!isSceneBoundaryExit(win)) continue;
|
|
100235
|
+
const boundary = findMatchingSceneBoundary(win.end, clipStartBoundaries);
|
|
100236
|
+
if (boundary == null) continue;
|
|
100237
|
+
const hasHardKill = gsapWindows.some(
|
|
100238
|
+
(candidate) => isHardKillSet(candidate, win.targetSelector, boundary)
|
|
100239
|
+
);
|
|
100240
|
+
if (hasHardKill) continue;
|
|
100241
|
+
findings.push({
|
|
100242
|
+
code: "gsap_exit_missing_hard_kill",
|
|
100243
|
+
severity: "warning",
|
|
100244
|
+
message: `GSAP exit on "${win.targetSelector}" ends at the ${boundary.toFixed(2)}s clip start boundary without a matching tl.set hard kill. Non-linear seeking can land after the fade and leave stale visibility state.`,
|
|
100245
|
+
selector: win.targetSelector,
|
|
100246
|
+
fixHint: `Add \`tl.set("${win.targetSelector}", ${hiddenStateLiteral(win.propertyValues)}, ${boundary.toFixed(2)})\` after the exit tween.`,
|
|
100247
|
+
snippet: truncateSnippet(win.raw)
|
|
100248
|
+
});
|
|
100249
|
+
}
|
|
100250
|
+
}
|
|
100131
100251
|
for (const win of gsapWindows) {
|
|
100132
100252
|
const sel = win.targetSelector;
|
|
100133
100253
|
const clipInfo = clipIds.get(sel) || clipClasses.get(sel);
|
|
@@ -102442,8 +102562,8 @@ Process error: ${err.message}`;
|
|
|
102442
102562
|
|
|
102443
102563
|
// ../engine/src/services/videoFrameExtractor.ts
|
|
102444
102564
|
import { spawn as spawn8 } from "child_process";
|
|
102445
|
-
import { existsSync as
|
|
102446
|
-
import { isAbsolute as isAbsolute2, join as
|
|
102565
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync6, readdirSync as readdirSync5, rmSync } from "fs";
|
|
102566
|
+
import { isAbsolute as isAbsolute2, join as join9 } from "path";
|
|
102447
102567
|
|
|
102448
102568
|
// ../engine/src/utils/ffprobe.ts
|
|
102449
102569
|
import { spawn as spawn7 } from "child_process";
|
|
@@ -102773,10 +102893,115 @@ function isHttpUrl(path12) {
|
|
|
102773
102893
|
return path12.startsWith("http://") || path12.startsWith("https://");
|
|
102774
102894
|
}
|
|
102775
102895
|
|
|
102896
|
+
// ../engine/src/utils/htmlTemplate.ts
|
|
102897
|
+
function parseHTMLContent(html) {
|
|
102898
|
+
const trimmed = html.trimStart().toLowerCase();
|
|
102899
|
+
if (trimmed.startsWith("<!doctype") || trimmed.startsWith("<html")) {
|
|
102900
|
+
return parseHTML(html).document;
|
|
102901
|
+
}
|
|
102902
|
+
return parseHTML(`<!DOCTYPE html><html><head></head><body>${html}</body></html>`).document;
|
|
102903
|
+
}
|
|
102904
|
+
function getSingleMeaningfulChild(container) {
|
|
102905
|
+
let child = null;
|
|
102906
|
+
for (const node of Array.from(container.childNodes)) {
|
|
102907
|
+
if (node.nodeType === 3 && !(node.textContent || "").trim()) continue;
|
|
102908
|
+
if (node.nodeType === 8) continue;
|
|
102909
|
+
if (node.nodeType !== 1) return null;
|
|
102910
|
+
if (child) return null;
|
|
102911
|
+
child = node;
|
|
102912
|
+
}
|
|
102913
|
+
return child;
|
|
102914
|
+
}
|
|
102915
|
+
function unwrapTemplate(html) {
|
|
102916
|
+
const lowered = html.toLowerCase();
|
|
102917
|
+
if (!lowered.includes("<template") || !lowered.includes("</template>")) {
|
|
102918
|
+
return html;
|
|
102919
|
+
}
|
|
102920
|
+
const { body } = parseHTMLContent(html);
|
|
102921
|
+
if (!body) return html;
|
|
102922
|
+
let container = body;
|
|
102923
|
+
const bodyWrapper = getSingleMeaningfulChild(container);
|
|
102924
|
+
if (bodyWrapper?.tagName === "BODY") {
|
|
102925
|
+
container = bodyWrapper;
|
|
102926
|
+
}
|
|
102927
|
+
const template = getSingleMeaningfulChild(container);
|
|
102928
|
+
if (template?.tagName !== "TEMPLATE") {
|
|
102929
|
+
return html;
|
|
102930
|
+
}
|
|
102931
|
+
return template.innerHTML ?? html;
|
|
102932
|
+
}
|
|
102933
|
+
|
|
102934
|
+
// ../engine/src/services/extractionCache.ts
|
|
102935
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
102936
|
+
import { mkdirSync as mkdirSync5, readdirSync as readdirSync4, statSync as statSync5, writeFileSync as writeFileSync3 } from "node:fs";
|
|
102937
|
+
import { existsSync as existsSync8 } from "node:fs";
|
|
102938
|
+
import { join as join8 } from "node:path";
|
|
102939
|
+
var FRAME_FILENAME_PREFIX = "frame_";
|
|
102940
|
+
var COMPLETE_SENTINEL = ".hf-complete";
|
|
102941
|
+
var SCHEMA_PREFIX = "hfcache-v2-";
|
|
102942
|
+
var KEY_HEX_CHARS = 16;
|
|
102943
|
+
function readKeyStat(videoPath) {
|
|
102944
|
+
try {
|
|
102945
|
+
const stat = statSync5(videoPath);
|
|
102946
|
+
return { mtimeMs: Math.floor(stat.mtimeMs), size: stat.size };
|
|
102947
|
+
} catch {
|
|
102948
|
+
return null;
|
|
102949
|
+
}
|
|
102950
|
+
}
|
|
102951
|
+
function canonicalKeyBlob(input2) {
|
|
102952
|
+
const durationForKey = Number.isFinite(input2.duration) ? input2.duration : -1;
|
|
102953
|
+
return JSON.stringify({
|
|
102954
|
+
p: input2.videoPath,
|
|
102955
|
+
m: input2.mtimeMs,
|
|
102956
|
+
s: input2.size,
|
|
102957
|
+
ms: input2.mediaStart,
|
|
102958
|
+
d: durationForKey,
|
|
102959
|
+
f: input2.fps,
|
|
102960
|
+
fmt: input2.format
|
|
102961
|
+
});
|
|
102962
|
+
}
|
|
102963
|
+
function computeCacheKey(input2) {
|
|
102964
|
+
return createHash2("sha256").update(canonicalKeyBlob(input2)).digest("hex");
|
|
102965
|
+
}
|
|
102966
|
+
function cacheEntryDirName(keyHash) {
|
|
102967
|
+
return SCHEMA_PREFIX + keyHash.slice(0, KEY_HEX_CHARS);
|
|
102968
|
+
}
|
|
102969
|
+
function lookupCacheEntry(rootDir, input2) {
|
|
102970
|
+
const keyHash = computeCacheKey(input2);
|
|
102971
|
+
const dir = join8(rootDir, cacheEntryDirName(keyHash));
|
|
102972
|
+
const complete = existsSync8(join8(dir, COMPLETE_SENTINEL));
|
|
102973
|
+
return { entry: { dir, keyHash }, hit: complete };
|
|
102974
|
+
}
|
|
102975
|
+
function ensureCacheEntryDir(entry) {
|
|
102976
|
+
mkdirSync5(entry.dir, { recursive: true });
|
|
102977
|
+
}
|
|
102978
|
+
function markCacheEntryComplete(entry) {
|
|
102979
|
+
writeFileSync3(join8(entry.dir, COMPLETE_SENTINEL), "", "utf-8");
|
|
102980
|
+
}
|
|
102981
|
+
function rehydrateCacheEntry(entry, options) {
|
|
102982
|
+
const framePattern = `${FRAME_FILENAME_PREFIX}%05d.${options.format}`;
|
|
102983
|
+
const framePaths = /* @__PURE__ */ new Map();
|
|
102984
|
+
const suffix = `.${options.format}`;
|
|
102985
|
+
const files = readdirSync4(entry.dir).filter((f) => f.startsWith(FRAME_FILENAME_PREFIX) && f.endsWith(suffix)).sort();
|
|
102986
|
+
files.forEach((file, idx) => {
|
|
102987
|
+
framePaths.set(idx, join8(entry.dir, file));
|
|
102988
|
+
});
|
|
102989
|
+
return {
|
|
102990
|
+
videoId: options.videoId,
|
|
102991
|
+
srcPath: options.srcPath,
|
|
102992
|
+
outputDir: entry.dir,
|
|
102993
|
+
framePattern,
|
|
102994
|
+
fps: options.fps,
|
|
102995
|
+
totalFrames: framePaths.size,
|
|
102996
|
+
metadata: options.metadata,
|
|
102997
|
+
framePaths
|
|
102998
|
+
};
|
|
102999
|
+
}
|
|
103000
|
+
|
|
102776
103001
|
// ../engine/src/services/videoFrameExtractor.ts
|
|
102777
103002
|
function parseVideoElements(html) {
|
|
102778
103003
|
const videos = [];
|
|
102779
|
-
const { document: document2 } = parseHTML(html);
|
|
103004
|
+
const { document: document2 } = parseHTML(unwrapTemplate(html));
|
|
102780
103005
|
const videoEls = document2.querySelectorAll("video[src]");
|
|
102781
103006
|
let autoIdCounter = 0;
|
|
102782
103007
|
for (const el of videoEls) {
|
|
@@ -102813,7 +103038,7 @@ function parseVideoElements(html) {
|
|
|
102813
103038
|
}
|
|
102814
103039
|
function parseImageElements(html) {
|
|
102815
103040
|
const images = [];
|
|
102816
|
-
const { document: document2 } = parseHTML(html);
|
|
103041
|
+
const { document: document2 } = parseHTML(unwrapTemplate(html));
|
|
102817
103042
|
const imgEls = document2.querySelectorAll("img[src]");
|
|
102818
103043
|
let autoIdCounter = 0;
|
|
102819
103044
|
for (const el of imgEls) {
|
|
@@ -102839,14 +103064,14 @@ function parseImageElements(html) {
|
|
|
102839
103064
|
}
|
|
102840
103065
|
return images;
|
|
102841
103066
|
}
|
|
102842
|
-
async function extractVideoFramesRange(videoPath, videoId, startTime, duration, options, signal, config2) {
|
|
103067
|
+
async function extractVideoFramesRange(videoPath, videoId, startTime, duration, options, signal, config2, outputDirOverride) {
|
|
102843
103068
|
const ffmpegProcessTimeout = config2?.ffmpegProcessTimeout ?? DEFAULT_CONFIG.ffmpegProcessTimeout;
|
|
102844
103069
|
const { fps, outputDir, quality = 95, format: format3 = "jpg" } = options;
|
|
102845
|
-
const videoOutputDir =
|
|
102846
|
-
if (!
|
|
103070
|
+
const videoOutputDir = outputDirOverride ?? join9(outputDir, videoId);
|
|
103071
|
+
if (!existsSync9(videoOutputDir)) mkdirSync6(videoOutputDir, { recursive: true });
|
|
102847
103072
|
const metadata = await extractMediaMetadata(videoPath);
|
|
102848
|
-
const framePattern =
|
|
102849
|
-
const outputPattern =
|
|
103073
|
+
const framePattern = `${FRAME_FILENAME_PREFIX}%05d.${format3}`;
|
|
103074
|
+
const outputPattern = join9(videoOutputDir, framePattern);
|
|
102850
103075
|
const isHdr = isHdrColorSpace(metadata.colorSpace);
|
|
102851
103076
|
const isMacOS = process.platform === "darwin";
|
|
102852
103077
|
const args = [];
|
|
@@ -102894,9 +103119,9 @@ async function extractVideoFramesRange(videoPath, videoId, startTime, duration,
|
|
|
102894
103119
|
return;
|
|
102895
103120
|
}
|
|
102896
103121
|
const framePaths = /* @__PURE__ */ new Map();
|
|
102897
|
-
const files =
|
|
103122
|
+
const files = readdirSync5(videoOutputDir).filter((f) => f.startsWith(FRAME_FILENAME_PREFIX) && f.endsWith(`.${format3}`)).sort();
|
|
102898
103123
|
files.forEach((file, index) => {
|
|
102899
|
-
framePaths.set(index,
|
|
103124
|
+
framePaths.set(index, join9(videoOutputDir, file));
|
|
102900
103125
|
});
|
|
102901
103126
|
resolve14({
|
|
102902
103127
|
videoId,
|
|
@@ -102920,12 +103145,19 @@ async function extractVideoFramesRange(videoPath, videoId, startTime, duration,
|
|
|
102920
103145
|
});
|
|
102921
103146
|
});
|
|
102922
103147
|
}
|
|
102923
|
-
async function convertSdrToHdr(inputPath, outputPath, targetTransfer, signal, config2) {
|
|
103148
|
+
async function convertSdrToHdr(inputPath, outputPath, startTime, duration, targetTransfer, signal, config2) {
|
|
103149
|
+
if (duration <= 0) {
|
|
103150
|
+
throw new Error(`convertSdrToHdr: duration must be positive (got ${duration})`);
|
|
103151
|
+
}
|
|
102924
103152
|
const timeout2 = config2?.ffmpegProcessTimeout ?? DEFAULT_CONFIG.ffmpegProcessTimeout;
|
|
102925
103153
|
const colorTrc = targetTransfer === "pq" ? "smpte2084" : "arib-std-b67";
|
|
102926
103154
|
const args = [
|
|
103155
|
+
"-ss",
|
|
103156
|
+
String(startTime),
|
|
102927
103157
|
"-i",
|
|
102928
103158
|
inputPath,
|
|
103159
|
+
"-t",
|
|
103160
|
+
String(duration),
|
|
102929
103161
|
"-vf",
|
|
102930
103162
|
"colorspace=all=bt2020:iall=bt709:range=tv",
|
|
102931
103163
|
"-color_primaries",
|
|
@@ -102952,6 +103184,11 @@ async function convertSdrToHdr(inputPath, outputPath, targetTransfer, signal, co
|
|
|
102952
103184
|
);
|
|
102953
103185
|
}
|
|
102954
103186
|
}
|
|
103187
|
+
function resolveSegmentDuration(requested, mediaStart, metadata) {
|
|
103188
|
+
if (Number.isFinite(requested) && requested > 0) return requested;
|
|
103189
|
+
const sourceRemaining = metadata.durationSeconds - mediaStart;
|
|
103190
|
+
return sourceRemaining > 0 ? sourceRemaining : metadata.durationSeconds;
|
|
103191
|
+
}
|
|
102955
103192
|
async function convertVfrToCfr(inputPath, outputPath, targetFps, startTime, duration, signal, config2) {
|
|
102956
103193
|
const timeout2 = config2?.ffmpegProcessTimeout ?? DEFAULT_CONFIG.ffmpegProcessTimeout;
|
|
102957
103194
|
const args = [
|
|
@@ -102988,21 +103225,34 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config2,
|
|
|
102988
103225
|
const extracted = [];
|
|
102989
103226
|
const errors = [];
|
|
102990
103227
|
let totalFramesExtracted = 0;
|
|
103228
|
+
const breakdown = {
|
|
103229
|
+
resolveMs: 0,
|
|
103230
|
+
hdrProbeMs: 0,
|
|
103231
|
+
hdrPreflightMs: 0,
|
|
103232
|
+
hdrPreflightCount: 0,
|
|
103233
|
+
vfrProbeMs: 0,
|
|
103234
|
+
vfrPreflightMs: 0,
|
|
103235
|
+
vfrPreflightCount: 0,
|
|
103236
|
+
extractMs: 0,
|
|
103237
|
+
cacheHits: 0,
|
|
103238
|
+
cacheMisses: 0
|
|
103239
|
+
};
|
|
103240
|
+
const phase1Start = Date.now();
|
|
102991
103241
|
const resolvedVideos = [];
|
|
102992
103242
|
for (const video of videos) {
|
|
102993
103243
|
if (signal?.aborted) break;
|
|
102994
103244
|
try {
|
|
102995
103245
|
let videoPath = video.src;
|
|
102996
103246
|
if (!isAbsolute2(videoPath) && !isHttpUrl(videoPath)) {
|
|
102997
|
-
const fromCompiled = compiledDir ?
|
|
102998
|
-
videoPath = fromCompiled &&
|
|
103247
|
+
const fromCompiled = compiledDir ? join9(compiledDir, videoPath) : null;
|
|
103248
|
+
videoPath = fromCompiled && existsSync9(fromCompiled) ? fromCompiled : join9(baseDir, videoPath);
|
|
102999
103249
|
}
|
|
103000
103250
|
if (isHttpUrl(videoPath)) {
|
|
103001
|
-
const downloadDir =
|
|
103002
|
-
|
|
103251
|
+
const downloadDir = join9(options.outputDir, "_downloads");
|
|
103252
|
+
mkdirSync6(downloadDir, { recursive: true });
|
|
103003
103253
|
videoPath = await downloadToTemp(videoPath, downloadDir);
|
|
103004
103254
|
}
|
|
103005
|
-
if (!
|
|
103255
|
+
if (!existsSync9(videoPath)) {
|
|
103006
103256
|
errors.push({ videoId: video.id, error: `Video file not found: ${videoPath}` });
|
|
103007
103257
|
continue;
|
|
103008
103258
|
}
|
|
@@ -103011,27 +103261,66 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config2,
|
|
|
103011
103261
|
errors.push({ videoId: video.id, error: err instanceof Error ? err.message : String(err) });
|
|
103012
103262
|
}
|
|
103013
103263
|
}
|
|
103014
|
-
|
|
103015
|
-
|
|
103016
|
-
|
|
103017
|
-
|
|
103018
|
-
|
|
103264
|
+
breakdown.resolveMs = Date.now() - phase1Start;
|
|
103265
|
+
const cacheKeyInputs = resolvedVideos.map(({ video, videoPath }) => {
|
|
103266
|
+
const stat = readKeyStat(videoPath);
|
|
103267
|
+
if (!stat) return null;
|
|
103268
|
+
return {
|
|
103269
|
+
videoPath,
|
|
103270
|
+
mtimeMs: stat.mtimeMs,
|
|
103271
|
+
size: stat.size,
|
|
103272
|
+
mediaStart: video.mediaStart,
|
|
103273
|
+
start: video.start,
|
|
103274
|
+
end: video.end
|
|
103275
|
+
};
|
|
103276
|
+
});
|
|
103277
|
+
const phase2ProbeStart = Date.now();
|
|
103278
|
+
const videoMetadata = await Promise.all(
|
|
103279
|
+
resolvedVideos.map(({ videoPath }) => extractMediaMetadata(videoPath))
|
|
103019
103280
|
);
|
|
103281
|
+
const videoColorSpaces = videoMetadata.map((m) => m.colorSpace);
|
|
103282
|
+
breakdown.hdrProbeMs = Date.now() - phase2ProbeStart;
|
|
103283
|
+
const hdrPreflightStart = Date.now();
|
|
103020
103284
|
const hdrInfo = analyzeCompositionHdr(videoColorSpaces);
|
|
103285
|
+
const hdrSkippedIndices = /* @__PURE__ */ new Set();
|
|
103021
103286
|
if (hdrInfo.hasHdr && hdrInfo.dominantTransfer) {
|
|
103022
103287
|
const targetTransfer = hdrInfo.dominantTransfer;
|
|
103023
|
-
const convertDir =
|
|
103024
|
-
|
|
103288
|
+
const convertDir = join9(options.outputDir, "_hdr_normalized");
|
|
103289
|
+
mkdirSync6(convertDir, { recursive: true });
|
|
103025
103290
|
for (let i = 0; i < resolvedVideos.length; i++) {
|
|
103026
103291
|
if (signal?.aborted) break;
|
|
103027
103292
|
const cs = videoColorSpaces[i] ?? null;
|
|
103028
103293
|
if (!isHdrColorSpace(cs)) {
|
|
103029
103294
|
const entry = resolvedVideos[i];
|
|
103030
|
-
|
|
103031
|
-
|
|
103295
|
+
const metadata = videoMetadata[i];
|
|
103296
|
+
if (!entry || !metadata) continue;
|
|
103297
|
+
if (entry.video.mediaStart >= metadata.durationSeconds) {
|
|
103298
|
+
errors.push({
|
|
103299
|
+
videoId: entry.video.id,
|
|
103300
|
+
error: `SDR\u2192HDR conversion skipped: mediaStart (${entry.video.mediaStart}s) \u2265 source duration (${metadata.durationSeconds}s)`
|
|
103301
|
+
});
|
|
103302
|
+
hdrSkippedIndices.add(i);
|
|
103303
|
+
continue;
|
|
103304
|
+
}
|
|
103305
|
+
let segDuration = entry.video.end - entry.video.start;
|
|
103306
|
+
if (!Number.isFinite(segDuration) || segDuration <= 0) {
|
|
103307
|
+
const sourceRemaining = metadata.durationSeconds - entry.video.mediaStart;
|
|
103308
|
+
segDuration = sourceRemaining > 0 ? sourceRemaining : metadata.durationSeconds;
|
|
103309
|
+
}
|
|
103310
|
+
const convertedPath = join9(convertDir, `${entry.video.id}_hdr.mp4`);
|
|
103032
103311
|
try {
|
|
103033
|
-
await convertSdrToHdr(
|
|
103312
|
+
await convertSdrToHdr(
|
|
103313
|
+
entry.videoPath,
|
|
103314
|
+
convertedPath,
|
|
103315
|
+
entry.video.mediaStart,
|
|
103316
|
+
segDuration,
|
|
103317
|
+
targetTransfer,
|
|
103318
|
+
signal,
|
|
103319
|
+
config2
|
|
103320
|
+
);
|
|
103034
103321
|
entry.videoPath = convertedPath;
|
|
103322
|
+
entry.video = { ...entry.video, mediaStart: 0 };
|
|
103323
|
+
breakdown.hdrPreflightCount += 1;
|
|
103035
103324
|
} catch (err) {
|
|
103036
103325
|
errors.push({
|
|
103037
103326
|
videoId: entry.video.id,
|
|
@@ -103041,20 +103330,34 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config2,
|
|
|
103041
103330
|
}
|
|
103042
103331
|
}
|
|
103043
103332
|
}
|
|
103044
|
-
|
|
103333
|
+
breakdown.hdrPreflightMs = Date.now() - hdrPreflightStart;
|
|
103334
|
+
if (hdrSkippedIndices.size > 0) {
|
|
103335
|
+
for (let i = resolvedVideos.length - 1; i >= 0; i--) {
|
|
103336
|
+
if (hdrSkippedIndices.has(i)) {
|
|
103337
|
+
resolvedVideos.splice(i, 1);
|
|
103338
|
+
videoMetadata.splice(i, 1);
|
|
103339
|
+
videoColorSpaces.splice(i, 1);
|
|
103340
|
+
cacheKeyInputs.splice(i, 1);
|
|
103341
|
+
}
|
|
103342
|
+
}
|
|
103343
|
+
}
|
|
103344
|
+
const vfrPreflightStart = Date.now();
|
|
103345
|
+
const vfrNormDir = join9(options.outputDir, "_vfr_normalized");
|
|
103045
103346
|
for (let i = 0; i < resolvedVideos.length; i++) {
|
|
103046
103347
|
if (signal?.aborted) break;
|
|
103047
103348
|
const entry = resolvedVideos[i];
|
|
103048
103349
|
if (!entry) continue;
|
|
103350
|
+
const vfrProbeStart = Date.now();
|
|
103049
103351
|
const metadata = await extractMediaMetadata(entry.videoPath);
|
|
103352
|
+
breakdown.vfrProbeMs += Date.now() - vfrProbeStart;
|
|
103050
103353
|
if (!metadata.isVFR) continue;
|
|
103051
103354
|
let segDuration = entry.video.end - entry.video.start;
|
|
103052
103355
|
if (!Number.isFinite(segDuration) || segDuration <= 0) {
|
|
103053
103356
|
const sourceRemaining = metadata.durationSeconds - entry.video.mediaStart;
|
|
103054
103357
|
segDuration = sourceRemaining > 0 ? sourceRemaining : metadata.durationSeconds;
|
|
103055
103358
|
}
|
|
103056
|
-
|
|
103057
|
-
const normalizedPath =
|
|
103359
|
+
mkdirSync6(vfrNormDir, { recursive: true });
|
|
103360
|
+
const normalizedPath = join9(vfrNormDir, `${entry.video.id}_cfr.mp4`);
|
|
103058
103361
|
try {
|
|
103059
103362
|
await convertVfrToCfr(
|
|
103060
103363
|
entry.videoPath,
|
|
@@ -103067,6 +103370,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config2,
|
|
|
103067
103370
|
);
|
|
103068
103371
|
entry.videoPath = normalizedPath;
|
|
103069
103372
|
entry.video = { ...entry.video, mediaStart: 0 };
|
|
103373
|
+
breakdown.vfrPreflightCount += 1;
|
|
103070
103374
|
} catch (err) {
|
|
103071
103375
|
errors.push({
|
|
103072
103376
|
videoId: entry.video.id,
|
|
@@ -103074,19 +103378,72 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config2,
|
|
|
103074
103378
|
});
|
|
103075
103379
|
}
|
|
103076
103380
|
}
|
|
103381
|
+
breakdown.vfrPreflightMs = Date.now() - vfrPreflightStart;
|
|
103382
|
+
const phase3Start = Date.now();
|
|
103383
|
+
const cacheRootDir = config2?.extractCacheDir;
|
|
103384
|
+
const cacheFormat = options.format ?? "jpg";
|
|
103385
|
+
async function tryCachedExtract(video, videoPath, videoDuration, i) {
|
|
103386
|
+
if (!cacheRootDir) return null;
|
|
103387
|
+
const keyInput = cacheKeyInputs[i];
|
|
103388
|
+
const probedMeta = videoMetadata[i];
|
|
103389
|
+
if (!keyInput || !probedMeta) return null;
|
|
103390
|
+
const keyDuration = resolveSegmentDuration(
|
|
103391
|
+
keyInput.end - keyInput.start,
|
|
103392
|
+
keyInput.mediaStart,
|
|
103393
|
+
probedMeta
|
|
103394
|
+
);
|
|
103395
|
+
const lookup = lookupCacheEntry(cacheRootDir, {
|
|
103396
|
+
videoPath: keyInput.videoPath,
|
|
103397
|
+
mtimeMs: keyInput.mtimeMs,
|
|
103398
|
+
size: keyInput.size,
|
|
103399
|
+
mediaStart: keyInput.mediaStart,
|
|
103400
|
+
duration: keyDuration,
|
|
103401
|
+
fps: options.fps,
|
|
103402
|
+
format: cacheFormat
|
|
103403
|
+
});
|
|
103404
|
+
if (lookup.hit) {
|
|
103405
|
+
breakdown.cacheHits += 1;
|
|
103406
|
+
const rehydrated = rehydrateCacheEntry(lookup.entry, {
|
|
103407
|
+
videoId: video.id,
|
|
103408
|
+
srcPath: keyInput.videoPath,
|
|
103409
|
+
fps: options.fps,
|
|
103410
|
+
format: cacheFormat,
|
|
103411
|
+
metadata: probedMeta
|
|
103412
|
+
});
|
|
103413
|
+
return { ...rehydrated, ownedByLookup: true };
|
|
103414
|
+
}
|
|
103415
|
+
breakdown.cacheMisses += 1;
|
|
103416
|
+
ensureCacheEntryDir(lookup.entry);
|
|
103417
|
+
const result = await extractVideoFramesRange(
|
|
103418
|
+
videoPath,
|
|
103419
|
+
video.id,
|
|
103420
|
+
video.mediaStart,
|
|
103421
|
+
videoDuration,
|
|
103422
|
+
options,
|
|
103423
|
+
signal,
|
|
103424
|
+
config2,
|
|
103425
|
+
lookup.entry.dir
|
|
103426
|
+
);
|
|
103427
|
+
markCacheEntryComplete(lookup.entry);
|
|
103428
|
+
return { ...result, ownedByLookup: true };
|
|
103429
|
+
}
|
|
103077
103430
|
const results = await Promise.all(
|
|
103078
|
-
resolvedVideos.map(async ({ video, videoPath }) => {
|
|
103431
|
+
resolvedVideos.map(async ({ video, videoPath }, i) => {
|
|
103079
103432
|
if (signal?.aborted) {
|
|
103080
103433
|
throw new Error("Video frame extraction cancelled");
|
|
103081
103434
|
}
|
|
103082
103435
|
try {
|
|
103083
|
-
|
|
103084
|
-
|
|
103085
|
-
|
|
103086
|
-
|
|
103087
|
-
|
|
103436
|
+
const probedMeta = videoMetadata[i] ?? await extractMediaMetadata(videoPath);
|
|
103437
|
+
const videoDuration = resolveSegmentDuration(
|
|
103438
|
+
video.end - video.start,
|
|
103439
|
+
video.mediaStart,
|
|
103440
|
+
probedMeta
|
|
103441
|
+
);
|
|
103442
|
+
if (video.end - video.start !== videoDuration) {
|
|
103088
103443
|
video.end = video.start + videoDuration;
|
|
103089
103444
|
}
|
|
103445
|
+
const cached = await tryCachedExtract(video, videoPath, videoDuration, i);
|
|
103446
|
+
if (cached) return { result: cached };
|
|
103090
103447
|
const result = await extractVideoFramesRange(
|
|
103091
103448
|
videoPath,
|
|
103092
103449
|
video.id,
|
|
@@ -103107,6 +103464,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config2,
|
|
|
103107
103464
|
}
|
|
103108
103465
|
})
|
|
103109
103466
|
);
|
|
103467
|
+
breakdown.extractMs = Date.now() - phase3Start;
|
|
103110
103468
|
for (const item of results) {
|
|
103111
103469
|
if ("error" in item && item.error) {
|
|
103112
103470
|
errors.push(item.error);
|
|
@@ -103120,7 +103478,8 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config2,
|
|
|
103120
103478
|
extracted,
|
|
103121
103479
|
errors,
|
|
103122
103480
|
totalFramesExtracted,
|
|
103123
|
-
durationMs: Date.now() - startTime
|
|
103481
|
+
durationMs: Date.now() - startTime,
|
|
103482
|
+
phaseBreakdown: breakdown
|
|
103124
103483
|
};
|
|
103125
103484
|
}
|
|
103126
103485
|
function getFrameAtTime(extracted, globalTime, videoStart) {
|
|
@@ -103213,7 +103572,8 @@ var FrameLookupTable = class {
|
|
|
103213
103572
|
}
|
|
103214
103573
|
cleanup() {
|
|
103215
103574
|
for (const video of this.videos.values()) {
|
|
103216
|
-
if (
|
|
103575
|
+
if (video.extracted.ownedByLookup) continue;
|
|
103576
|
+
if (existsSync9(video.extracted.outputDir)) {
|
|
103217
103577
|
rmSync(video.extracted.outputDir, { recursive: true, force: true });
|
|
103218
103578
|
}
|
|
103219
103579
|
}
|
|
@@ -103236,23 +103596,23 @@ function createFrameLookupTable(videos, extracted) {
|
|
|
103236
103596
|
// ../engine/src/services/videoFrameInjector.ts
|
|
103237
103597
|
import { promises as fs7 } from "fs";
|
|
103238
103598
|
function createFrameDataUriCache(cacheLimit) {
|
|
103239
|
-
const
|
|
103599
|
+
const cache2 = /* @__PURE__ */ new Map();
|
|
103240
103600
|
const inFlight = /* @__PURE__ */ new Map();
|
|
103241
103601
|
function remember(framePath, dataUri) {
|
|
103242
|
-
if (
|
|
103243
|
-
|
|
103602
|
+
if (cache2.has(framePath)) {
|
|
103603
|
+
cache2.delete(framePath);
|
|
103244
103604
|
}
|
|
103245
|
-
|
|
103246
|
-
if (
|
|
103247
|
-
const oldestKey =
|
|
103605
|
+
cache2.set(framePath, dataUri);
|
|
103606
|
+
if (cache2.size > cacheLimit) {
|
|
103607
|
+
const oldestKey = cache2.keys().next().value;
|
|
103248
103608
|
if (oldestKey) {
|
|
103249
|
-
|
|
103609
|
+
cache2.delete(oldestKey);
|
|
103250
103610
|
}
|
|
103251
103611
|
}
|
|
103252
103612
|
return dataUri;
|
|
103253
103613
|
}
|
|
103254
103614
|
async function get(framePath) {
|
|
103255
|
-
const cached =
|
|
103615
|
+
const cached = cache2.get(framePath);
|
|
103256
103616
|
if (cached) {
|
|
103257
103617
|
remember(framePath, cached);
|
|
103258
103618
|
return cached;
|
|
@@ -103456,11 +103816,11 @@ async function queryElementStacking(page, nativeHdrIds) {
|
|
|
103456
103816
|
}
|
|
103457
103817
|
|
|
103458
103818
|
// ../engine/src/services/audioMixer.ts
|
|
103459
|
-
import { existsSync as
|
|
103460
|
-
import { isAbsolute as isAbsolute3, join as
|
|
103819
|
+
import { existsSync as existsSync10, mkdirSync as mkdirSync7, rmSync as rmSync2 } from "fs";
|
|
103820
|
+
import { isAbsolute as isAbsolute3, join as join10, dirname as dirname7 } from "path";
|
|
103461
103821
|
function parseAudioElements(html) {
|
|
103462
103822
|
const elements = [];
|
|
103463
|
-
const { document: document2 } = parseHTML(html);
|
|
103823
|
+
const { document: document2 } = parseHTML(unwrapTemplate(html));
|
|
103464
103824
|
const audioEls = document2.querySelectorAll("audio[id][src]");
|
|
103465
103825
|
for (const el of audioEls) {
|
|
103466
103826
|
const id = el.getAttribute("id");
|
|
@@ -103508,7 +103868,7 @@ function parseAudioElements(html) {
|
|
|
103508
103868
|
async function extractAudioFromVideo(videoPath, outputPath, options, signal, config2) {
|
|
103509
103869
|
const ffmpegProcessTimeout = config2?.ffmpegProcessTimeout ?? DEFAULT_CONFIG.ffmpegProcessTimeout;
|
|
103510
103870
|
const outputDir = dirname7(outputPath);
|
|
103511
|
-
if (!
|
|
103871
|
+
if (!existsSync10(outputDir)) mkdirSync7(outputDir, { recursive: true });
|
|
103512
103872
|
const args = ["-i", videoPath];
|
|
103513
103873
|
if (options?.startTime !== void 0) args.push("-ss", String(options.startTime));
|
|
103514
103874
|
if (options?.duration !== void 0) args.push("-t", String(options.duration));
|
|
@@ -103535,7 +103895,7 @@ async function extractAudioFromVideo(videoPath, outputPath, options, signal, con
|
|
|
103535
103895
|
async function prepareAudioTrack(srcPath, outputPath, mediaStart, duration, signal, config2) {
|
|
103536
103896
|
const ffmpegProcessTimeout = config2?.ffmpegProcessTimeout ?? DEFAULT_CONFIG.ffmpegProcessTimeout;
|
|
103537
103897
|
const outputDir = dirname7(outputPath);
|
|
103538
|
-
if (!
|
|
103898
|
+
if (!existsSync10(outputDir)) mkdirSync7(outputDir, { recursive: true });
|
|
103539
103899
|
const args = [
|
|
103540
103900
|
"-ss",
|
|
103541
103901
|
String(mediaStart),
|
|
@@ -103571,7 +103931,7 @@ async function prepareAudioTrack(srcPath, outputPath, mediaStart, duration, sign
|
|
|
103571
103931
|
async function generateSilence(outputPath, duration, signal, config2) {
|
|
103572
103932
|
const ffmpegProcessTimeout = config2?.ffmpegProcessTimeout ?? DEFAULT_CONFIG.ffmpegProcessTimeout;
|
|
103573
103933
|
const outputDir = dirname7(outputPath);
|
|
103574
|
-
if (!
|
|
103934
|
+
if (!existsSync10(outputDir)) mkdirSync7(outputDir, { recursive: true });
|
|
103575
103935
|
const args = [
|
|
103576
103936
|
"-f",
|
|
103577
103937
|
"lavfi",
|
|
@@ -103614,7 +103974,7 @@ async function mixAudioTracks(tracks, outputPath, totalDuration, signal, config2
|
|
|
103614
103974
|
};
|
|
103615
103975
|
}
|
|
103616
103976
|
const outputDir = dirname7(outputPath);
|
|
103617
|
-
if (!
|
|
103977
|
+
if (!existsSync10(outputDir)) mkdirSync7(outputDir, { recursive: true });
|
|
103618
103978
|
const inputs = [];
|
|
103619
103979
|
const filterParts = [];
|
|
103620
103980
|
tracks.forEach((track, i) => {
|
|
@@ -103675,7 +104035,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
103675
104035
|
const startMs = Date.now();
|
|
103676
104036
|
const tracks = [];
|
|
103677
104037
|
const errors = [];
|
|
103678
|
-
if (!
|
|
104038
|
+
if (!existsSync10(workDir)) mkdirSync7(workDir, { recursive: true });
|
|
103679
104039
|
await Promise.all(
|
|
103680
104040
|
elements.map(async (element) => {
|
|
103681
104041
|
if (signal?.aborted) {
|
|
@@ -103685,8 +104045,8 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
103685
104045
|
try {
|
|
103686
104046
|
let srcPath = element.src;
|
|
103687
104047
|
if (!isAbsolute3(srcPath) && !isHttpUrl(srcPath)) {
|
|
103688
|
-
const fromCompiled = compiledDir ?
|
|
103689
|
-
srcPath = fromCompiled &&
|
|
104048
|
+
const fromCompiled = compiledDir ? join10(compiledDir, srcPath) : null;
|
|
104049
|
+
srcPath = fromCompiled && existsSync10(fromCompiled) ? fromCompiled : join10(baseDir, srcPath);
|
|
103690
104050
|
}
|
|
103691
104051
|
if (isHttpUrl(srcPath)) {
|
|
103692
104052
|
try {
|
|
@@ -103698,7 +104058,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
103698
104058
|
return;
|
|
103699
104059
|
}
|
|
103700
104060
|
}
|
|
103701
|
-
if (!
|
|
104061
|
+
if (!existsSync10(srcPath)) {
|
|
103702
104062
|
errors.push(`Source not found: ${element.id} (${element.src})`);
|
|
103703
104063
|
return;
|
|
103704
104064
|
}
|
|
@@ -103709,7 +104069,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
103709
104069
|
}
|
|
103710
104070
|
let audioSrcPath = srcPath;
|
|
103711
104071
|
if (element.type === "video") {
|
|
103712
|
-
const extractedPath =
|
|
104072
|
+
const extractedPath = join10(workDir, `${element.id}-extracted.wav`);
|
|
103713
104073
|
const extractResult = await extractAudioFromVideo(
|
|
103714
104074
|
srcPath,
|
|
103715
104075
|
extractedPath,
|
|
@@ -103726,7 +104086,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
103726
104086
|
}
|
|
103727
104087
|
audioSrcPath = extractedPath;
|
|
103728
104088
|
} else {
|
|
103729
|
-
const trimmedPath =
|
|
104089
|
+
const trimmedPath = join10(workDir, `${element.id}-trimmed.wav`);
|
|
103730
104090
|
const prepResult = await prepareAudioTrack(
|
|
103731
104091
|
srcPath,
|
|
103732
104092
|
trimmedPath,
|
|
@@ -103769,9 +104129,9 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
103769
104129
|
|
|
103770
104130
|
// ../engine/src/services/parallelCoordinator.ts
|
|
103771
104131
|
import { cpus, freemem, totalmem } from "os";
|
|
103772
|
-
import { existsSync as
|
|
104132
|
+
import { existsSync as existsSync11, mkdirSync as mkdirSync8, readdirSync as readdirSync6 } from "fs";
|
|
103773
104133
|
import { copyFile, rename as rename2 } from "fs/promises";
|
|
103774
|
-
import { join as
|
|
104134
|
+
import { join as join11 } from "path";
|
|
103775
104135
|
var MEMORY_PER_WORKER_MB = 256;
|
|
103776
104136
|
var MIN_WORKERS = 1;
|
|
103777
104137
|
var ABSOLUTE_MAX_WORKERS = 10;
|
|
@@ -103819,7 +104179,7 @@ function distributeFrames(totalFrames, workerCount, workDir) {
|
|
|
103819
104179
|
workerId: i,
|
|
103820
104180
|
startFrame,
|
|
103821
104181
|
endFrame,
|
|
103822
|
-
outputDir:
|
|
104182
|
+
outputDir: join11(workDir, `worker-${i}`)
|
|
103823
104183
|
});
|
|
103824
104184
|
}
|
|
103825
104185
|
return tasks;
|
|
@@ -103827,7 +104187,7 @@ function distributeFrames(totalFrames, workerCount, workDir) {
|
|
|
103827
104187
|
async function executeWorkerTask(task, serverUrl, captureOptions, createBeforeCaptureHook, signal, onFrameCaptured, onFrameBuffer, config2) {
|
|
103828
104188
|
const startTime = Date.now();
|
|
103829
104189
|
let framesCaptured = 0;
|
|
103830
|
-
if (!
|
|
104190
|
+
if (!existsSync11(task.outputDir)) mkdirSync8(task.outputDir, { recursive: true });
|
|
103831
104191
|
let session = null;
|
|
103832
104192
|
let perf;
|
|
103833
104193
|
try {
|
|
@@ -103917,17 +104277,17 @@ async function executeParallelCapture(serverUrl, workDir, tasks, captureOptions,
|
|
|
103917
104277
|
return results;
|
|
103918
104278
|
}
|
|
103919
104279
|
async function mergeWorkerFrames(workDir, tasks, outputDir) {
|
|
103920
|
-
if (!
|
|
104280
|
+
if (!existsSync11(outputDir)) mkdirSync8(outputDir, { recursive: true });
|
|
103921
104281
|
let totalFrames = 0;
|
|
103922
104282
|
const sortedTasks = [...tasks].sort((a, b) => a.startFrame - b.startFrame);
|
|
103923
104283
|
for (const task of sortedTasks) {
|
|
103924
|
-
if (!
|
|
104284
|
+
if (!existsSync11(task.outputDir)) {
|
|
103925
104285
|
continue;
|
|
103926
104286
|
}
|
|
103927
|
-
const files =
|
|
104287
|
+
const files = readdirSync6(task.outputDir).filter((f) => f.startsWith("frame_") && (f.endsWith(".jpg") || f.endsWith(".png"))).sort();
|
|
103928
104288
|
const copyTasks = files.map(async (file) => {
|
|
103929
|
-
const sourcePath =
|
|
103930
|
-
const targetPath =
|
|
104289
|
+
const sourcePath = join11(task.outputDir, file);
|
|
104290
|
+
const targetPath = join11(outputDir, file);
|
|
103931
104291
|
try {
|
|
103932
104292
|
await rename2(sourcePath, targetPath);
|
|
103933
104293
|
} catch {
|
|
@@ -106214,14 +106574,14 @@ var Response2 = class _Response {
|
|
|
106214
106574
|
}
|
|
106215
106575
|
}
|
|
106216
106576
|
get headers() {
|
|
106217
|
-
const
|
|
106218
|
-
if (
|
|
106219
|
-
if (!(
|
|
106220
|
-
|
|
106221
|
-
|
|
106577
|
+
const cache2 = this[cacheKey];
|
|
106578
|
+
if (cache2) {
|
|
106579
|
+
if (!(cache2[2] instanceof Headers)) {
|
|
106580
|
+
cache2[2] = new Headers(
|
|
106581
|
+
cache2[2] || { "content-type": "text/plain; charset=UTF-8" }
|
|
106222
106582
|
);
|
|
106223
106583
|
}
|
|
106224
|
-
return
|
|
106584
|
+
return cache2[2];
|
|
106225
106585
|
}
|
|
106226
106586
|
return this[getResponseCache]().headers;
|
|
106227
106587
|
}
|
|
@@ -107732,18 +108092,18 @@ var ridgedBurn = (from2, to, out, w, h, p) => {
|
|
|
107732
108092
|
TRANSITIONS["ridged-burn"] = ridgedBurn;
|
|
107733
108093
|
|
|
107734
108094
|
// src/services/renderOrchestrator.ts
|
|
107735
|
-
import { join as
|
|
108095
|
+
import { join as join16, dirname as dirname10, resolve as resolve11 } from "path";
|
|
107736
108096
|
import { randomUUID } from "crypto";
|
|
107737
108097
|
import { freemem as freemem2 } from "os";
|
|
107738
108098
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
107739
108099
|
|
|
107740
108100
|
// src/services/fileServer.ts
|
|
107741
|
-
import { readFileSync as readFileSync7, existsSync as
|
|
107742
|
-
import { join as
|
|
108101
|
+
import { readFileSync as readFileSync7, existsSync as existsSync13, realpathSync, statSync as statSync6 } from "node:fs";
|
|
108102
|
+
import { join as join12, extname as extname4, resolve as resolve8, sep } from "node:path";
|
|
107743
108103
|
|
|
107744
108104
|
// src/services/hyperframeRuntimeLoader.ts
|
|
107745
|
-
import { createHash as
|
|
107746
|
-
import { existsSync as
|
|
108105
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
108106
|
+
import { existsSync as existsSync12, readFileSync as readFileSync6 } from "node:fs";
|
|
107747
108107
|
import { dirname as dirname8, resolve as resolve7 } from "node:path";
|
|
107748
108108
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
107749
108109
|
var PRODUCER_DIR = dirname8(fileURLToPath2(import.meta.url));
|
|
@@ -107770,7 +108130,7 @@ function resolveHyperframeManifestPath() {
|
|
|
107770
108130
|
MODULE_RELATIVE_MANIFEST_PATH
|
|
107771
108131
|
];
|
|
107772
108132
|
for (const candidate of candidates) {
|
|
107773
|
-
if (
|
|
108133
|
+
if (existsSync12(candidate)) {
|
|
107774
108134
|
return candidate;
|
|
107775
108135
|
}
|
|
107776
108136
|
}
|
|
@@ -107781,7 +108141,7 @@ function getVerifiedHyperframeRuntimeSource() {
|
|
|
107781
108141
|
}
|
|
107782
108142
|
function resolveVerifiedHyperframeRuntime() {
|
|
107783
108143
|
const manifestPath = resolveHyperframeManifestPath();
|
|
107784
|
-
if (!
|
|
108144
|
+
if (!existsSync12(manifestPath)) {
|
|
107785
108145
|
throw new Error(
|
|
107786
108146
|
`[HyperframeRuntimeLoader] Missing manifest at ${manifestPath}. Build core runtime artifacts before rendering.`
|
|
107787
108147
|
);
|
|
@@ -107795,11 +108155,11 @@ function resolveVerifiedHyperframeRuntime() {
|
|
|
107795
108155
|
);
|
|
107796
108156
|
}
|
|
107797
108157
|
const runtimePath = resolve7(dirname8(manifestPath), runtimeFileName);
|
|
107798
|
-
if (!
|
|
108158
|
+
if (!existsSync12(runtimePath)) {
|
|
107799
108159
|
throw new Error(`[HyperframeRuntimeLoader] Missing runtime artifact at ${runtimePath}.`);
|
|
107800
108160
|
}
|
|
107801
108161
|
const runtimeSource = readFileSync6(runtimePath, "utf8");
|
|
107802
|
-
const runtimeSha =
|
|
108162
|
+
const runtimeSha = createHash3("sha256").update(runtimeSource, "utf8").digest("hex");
|
|
107803
108163
|
if (runtimeSha !== manifest.sha256) {
|
|
107804
108164
|
throw new Error(
|
|
107805
108165
|
`[HyperframeRuntimeLoader] Runtime checksum mismatch. expected=${manifest.sha256} actual=${runtimeSha}`
|
|
@@ -107821,8 +108181,8 @@ function isPathInside(child, parent, options = {}) {
|
|
|
107821
108181
|
const separator = pathModule?.sep ?? sep;
|
|
107822
108182
|
const resolvedChild = resolveFn(child);
|
|
107823
108183
|
const resolvedParent = resolveFn(parent);
|
|
107824
|
-
const normalizedChild = resolveSymlinks &&
|
|
107825
|
-
const normalizedParent = resolveSymlinks &&
|
|
108184
|
+
const normalizedChild = resolveSymlinks && existsSync13(resolvedChild) ? realpathSync.native(resolvedChild) : resolvedChild;
|
|
108185
|
+
const normalizedParent = resolveSymlinks && existsSync13(resolvedParent) ? realpathSync.native(resolvedParent) : resolvedParent;
|
|
107826
108186
|
if (normalizedChild === normalizedParent) return true;
|
|
107827
108187
|
const parentWithSep = normalizedParent.endsWith(separator) ? normalizedParent : normalizedParent + separator;
|
|
107828
108188
|
return normalizedChild.startsWith(parentWithSep);
|
|
@@ -108221,14 +108581,14 @@ function createFileServer2(options) {
|
|
|
108221
108581
|
const relativePath = requestPath.replace(/^\//, "");
|
|
108222
108582
|
let filePath = null;
|
|
108223
108583
|
if (compiledDir) {
|
|
108224
|
-
const candidate =
|
|
108225
|
-
if (
|
|
108584
|
+
const candidate = join12(compiledDir, relativePath);
|
|
108585
|
+
if (existsSync13(candidate) && isPathInside(candidate, compiledDir, { resolveSymlinks: true }) && statSync6(candidate).isFile()) {
|
|
108226
108586
|
filePath = candidate;
|
|
108227
108587
|
}
|
|
108228
108588
|
}
|
|
108229
108589
|
if (!filePath) {
|
|
108230
|
-
const candidate =
|
|
108231
|
-
if (
|
|
108590
|
+
const candidate = join12(projectDir, relativePath);
|
|
108591
|
+
if (existsSync13(candidate) && isPathInside(candidate, projectDir, { resolveSymlinks: true }) && statSync6(candidate).isFile()) {
|
|
108232
108592
|
filePath = candidate;
|
|
108233
108593
|
}
|
|
108234
108594
|
}
|
|
@@ -108277,12 +108637,12 @@ function createFileServer2(options) {
|
|
|
108277
108637
|
}
|
|
108278
108638
|
|
|
108279
108639
|
// src/services/htmlCompiler.ts
|
|
108280
|
-
import { readFileSync as readFileSync9, existsSync as
|
|
108281
|
-
import { join as
|
|
108640
|
+
import { readFileSync as readFileSync9, existsSync as existsSync15, mkdirSync as mkdirSync10 } from "fs";
|
|
108641
|
+
import { join as join15, dirname as dirname9, resolve as resolve10 } from "path";
|
|
108282
108642
|
import postcss from "postcss";
|
|
108283
108643
|
|
|
108284
108644
|
// src/utils/paths.ts
|
|
108285
|
-
import { resolve as resolve9, basename as basename2, join as
|
|
108645
|
+
import { resolve as resolve9, basename as basename2, join as join13, relative as relative2, isAbsolute as isAbsolute4 } from "node:path";
|
|
108286
108646
|
var DEFAULT_RENDERS_DIR = process.env.PRODUCER_RENDERS_DIR ?? resolve9(new URL(import.meta.url).pathname, "../../..", "renders");
|
|
108287
108647
|
function isPathInside2(childPath, parentPath) {
|
|
108288
108648
|
const absChild = resolve9(childPath);
|
|
@@ -108304,15 +108664,15 @@ function toExternalAssetKey(absPath) {
|
|
|
108304
108664
|
function resolveRenderPaths(projectDir, outputPath, rendersDir = DEFAULT_RENDERS_DIR) {
|
|
108305
108665
|
const absoluteProjectDir = resolve9(projectDir);
|
|
108306
108666
|
const projectName = basename2(absoluteProjectDir);
|
|
108307
|
-
const resolvedOutputPath = outputPath ??
|
|
108667
|
+
const resolvedOutputPath = outputPath ?? join13(rendersDir, `${projectName}.mp4`);
|
|
108308
108668
|
const absoluteOutputPath = resolve9(resolvedOutputPath);
|
|
108309
108669
|
return { absoluteProjectDir, absoluteOutputPath };
|
|
108310
108670
|
}
|
|
108311
108671
|
|
|
108312
108672
|
// src/services/deterministicFonts.ts
|
|
108313
|
-
import { existsSync as
|
|
108673
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync9, readFileSync as readFileSync8, writeFileSync as writeFileSync4 } from "node:fs";
|
|
108314
108674
|
import { homedir as homedir2 } from "node:os";
|
|
108315
|
-
import { join as
|
|
108675
|
+
import { join as join14 } from "node:path";
|
|
108316
108676
|
|
|
108317
108677
|
// src/services/fontData.generated.ts
|
|
108318
108678
|
var EMBEDDED_FONT_DATA = /* @__PURE__ */ new Map([
|
|
@@ -108590,20 +108950,20 @@ function warnUnresolvedFonts(unresolved) {
|
|
|
108590
108950
|
Docs: https://hyperframes.heygen.com/docs/fonts`
|
|
108591
108951
|
);
|
|
108592
108952
|
}
|
|
108593
|
-
var GOOGLE_FONTS_CACHE_DIR =
|
|
108953
|
+
var GOOGLE_FONTS_CACHE_DIR = join14(homedir2(), ".cache", "hyperframes", "fonts");
|
|
108594
108954
|
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";
|
|
108595
108955
|
function fontSlug(familyName) {
|
|
108596
108956
|
return familyName.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
108597
108957
|
}
|
|
108598
108958
|
function fontCacheDir(slug) {
|
|
108599
|
-
const dir =
|
|
108600
|
-
if (!
|
|
108601
|
-
|
|
108959
|
+
const dir = join14(GOOGLE_FONTS_CACHE_DIR, slug);
|
|
108960
|
+
if (!existsSync14(dir)) {
|
|
108961
|
+
mkdirSync9(dir, { recursive: true });
|
|
108602
108962
|
}
|
|
108603
108963
|
return dir;
|
|
108604
108964
|
}
|
|
108605
108965
|
function cachedWoff2Path(slug, weight, style) {
|
|
108606
|
-
return
|
|
108966
|
+
return join14(fontCacheDir(slug), `${weight}-${style}.woff2`);
|
|
108607
108967
|
}
|
|
108608
108968
|
async function fetchGoogleFont(familyName) {
|
|
108609
108969
|
const slug = fontSlug(familyName);
|
|
@@ -108629,12 +108989,12 @@ async function fetchGoogleFont(familyName) {
|
|
|
108629
108989
|
const woff2Url = match2[3] || "";
|
|
108630
108990
|
if (!woff2Url) continue;
|
|
108631
108991
|
const cachePath = cachedWoff2Path(slug, weight, style);
|
|
108632
|
-
if (!
|
|
108992
|
+
if (!existsSync14(cachePath)) {
|
|
108633
108993
|
try {
|
|
108634
108994
|
const fontRes = await fetch(woff2Url);
|
|
108635
108995
|
if (!fontRes.ok) continue;
|
|
108636
108996
|
const buffer = Buffer.from(await fontRes.arrayBuffer());
|
|
108637
|
-
|
|
108997
|
+
writeFileSync4(cachePath, buffer);
|
|
108638
108998
|
} catch {
|
|
108639
108999
|
continue;
|
|
108640
109000
|
}
|
|
@@ -108740,16 +109100,16 @@ function detectRenderModeHints(html) {
|
|
|
108740
109100
|
async function resolveMediaDuration(src, mediaStart, baseDir, downloadDir, tagName19) {
|
|
108741
109101
|
let filePath = src;
|
|
108742
109102
|
if (isHttpUrl(src)) {
|
|
108743
|
-
if (!
|
|
109103
|
+
if (!existsSync15(downloadDir)) mkdirSync10(downloadDir, { recursive: true });
|
|
108744
109104
|
try {
|
|
108745
109105
|
filePath = await downloadToTemp(src, downloadDir);
|
|
108746
109106
|
} catch {
|
|
108747
109107
|
return { duration: 0, resolvedPath: src };
|
|
108748
109108
|
}
|
|
108749
109109
|
} else if (!filePath.startsWith("/")) {
|
|
108750
|
-
filePath =
|
|
109110
|
+
filePath = join15(baseDir, filePath);
|
|
108751
109111
|
}
|
|
108752
|
-
if (!
|
|
109112
|
+
if (!existsSync15(filePath)) {
|
|
108753
109113
|
return { duration: 0, resolvedPath: filePath };
|
|
108754
109114
|
}
|
|
108755
109115
|
const metadata = tagName19 === "video" ? await extractMediaMetadata(filePath) : await extractAudioMetadata(filePath);
|
|
@@ -108818,7 +109178,7 @@ async function parseSubCompositions(html, projectDir, downloadDir, parentOffset
|
|
|
108818
109178
|
if (visited.has(filePath)) {
|
|
108819
109179
|
continue;
|
|
108820
109180
|
}
|
|
108821
|
-
if (!
|
|
109181
|
+
if (!existsSync15(filePath)) {
|
|
108822
109182
|
continue;
|
|
108823
109183
|
}
|
|
108824
109184
|
const rawSubHtml = readFileSync9(filePath, "utf-8");
|
|
@@ -109028,7 +109388,7 @@ function inlineSubCompositions(html, subCompositions, projectDir) {
|
|
|
109028
109388
|
let compHtml = subCompositions.get(srcPath) || null;
|
|
109029
109389
|
if (!compHtml) {
|
|
109030
109390
|
const filePath = resolve10(projectDir, srcPath);
|
|
109031
|
-
if (
|
|
109391
|
+
if (existsSync15(filePath)) {
|
|
109032
109392
|
compHtml = readFileSync9(filePath, "utf-8");
|
|
109033
109393
|
}
|
|
109034
109394
|
}
|
|
@@ -109256,7 +109616,7 @@ function collectExternalAssets(html, projectDir) {
|
|
|
109256
109616
|
if (isPathInside2(absPath, absProjectDir)) {
|
|
109257
109617
|
return null;
|
|
109258
109618
|
}
|
|
109259
|
-
if (!
|
|
109619
|
+
if (!existsSync15(absPath)) return null;
|
|
109260
109620
|
const safeKey = toExternalAssetKey(absPath);
|
|
109261
109621
|
externalAssets.set(safeKey, absPath);
|
|
109262
109622
|
return safeKey;
|
|
@@ -109452,9 +109812,10 @@ async function recompileWithResolutions(compiled, resolutions, projectDir, downl
|
|
|
109452
109812
|
const mainVideos = parseVideoElements(html);
|
|
109453
109813
|
const mainAudios = parseAudioElements(html);
|
|
109454
109814
|
const mainImages = parseImageElements(html);
|
|
109455
|
-
const
|
|
109456
|
-
const
|
|
109457
|
-
const
|
|
109815
|
+
const hasSubMedia = subVideos.length > 0 || subAudios.length > 0 || subImages.length > 0;
|
|
109816
|
+
const videos = hasSubMedia ? dedupeElementsById([...mainVideos, ...subVideos]) : compiled.videos;
|
|
109817
|
+
const audios = hasSubMedia ? dedupeElementsById([...mainAudios, ...subAudios]) : compiled.audios;
|
|
109818
|
+
const images = hasSubMedia ? dedupeElementsById([...mainImages, ...subImages]) : compiled.images;
|
|
109458
109819
|
const remaining = compiled.unresolvedCompositions.filter(
|
|
109459
109820
|
(c) => !resolutions.some((r) => r.id === c.id)
|
|
109460
109821
|
);
|
|
@@ -109509,24 +109870,21 @@ function createConsoleLogger(level = "info") {
|
|
|
109509
109870
|
}
|
|
109510
109871
|
var defaultLogger = createConsoleLogger("info");
|
|
109511
109872
|
|
|
109512
|
-
// src/services/
|
|
109513
|
-
|
|
109514
|
-
|
|
109515
|
-
await fn();
|
|
109516
|
-
} catch (err) {
|
|
109517
|
-
log.debug(`Cleanup failed (${label})`, {
|
|
109518
|
-
error: err instanceof Error ? err.message : String(err)
|
|
109519
|
-
});
|
|
109520
|
-
}
|
|
109521
|
-
}
|
|
109522
|
-
var frameDirMaxIndexCache = /* @__PURE__ */ new Map();
|
|
109873
|
+
// src/services/frameDirCache.ts
|
|
109874
|
+
import { readdirSync as readdirSync7 } from "fs";
|
|
109875
|
+
var cache = /* @__PURE__ */ new Map();
|
|
109523
109876
|
var FRAME_FILENAME_RE = /^frame_(\d+)\.png$/;
|
|
109877
|
+
var MAX_ENTRIES = 1e3;
|
|
109524
109878
|
function getMaxFrameIndex(frameDir) {
|
|
109525
|
-
const cached =
|
|
109526
|
-
if (cached !== void 0)
|
|
109879
|
+
const cached = cache.get(frameDir);
|
|
109880
|
+
if (cached !== void 0) {
|
|
109881
|
+
cache.delete(frameDir);
|
|
109882
|
+
cache.set(frameDir, cached);
|
|
109883
|
+
return cached;
|
|
109884
|
+
}
|
|
109527
109885
|
let max = 0;
|
|
109528
109886
|
try {
|
|
109529
|
-
for (const name of
|
|
109887
|
+
for (const name of readdirSync7(frameDir)) {
|
|
109530
109888
|
const m = FRAME_FILENAME_RE.exec(name);
|
|
109531
109889
|
if (!m) continue;
|
|
109532
109890
|
const n = Number(m[1]);
|
|
@@ -109534,9 +109892,113 @@ function getMaxFrameIndex(frameDir) {
|
|
|
109534
109892
|
}
|
|
109535
109893
|
} catch {
|
|
109536
109894
|
}
|
|
109537
|
-
|
|
109895
|
+
if (cache.size >= MAX_ENTRIES) {
|
|
109896
|
+
const oldest = cache.keys().next().value;
|
|
109897
|
+
if (oldest !== void 0) cache.delete(oldest);
|
|
109898
|
+
}
|
|
109899
|
+
cache.set(frameDir, max);
|
|
109538
109900
|
return max;
|
|
109539
109901
|
}
|
|
109902
|
+
function clearMaxFrameIndex(frameDir) {
|
|
109903
|
+
return cache.delete(frameDir);
|
|
109904
|
+
}
|
|
109905
|
+
|
|
109906
|
+
// src/services/hdrImageTransferCache.ts
|
|
109907
|
+
var DEFAULT_MAX_BYTES = 200 * 1024 * 1024;
|
|
109908
|
+
function createHdrImageTransferCache(options = {}) {
|
|
109909
|
+
const maxBytes = options.maxBytes ?? DEFAULT_MAX_BYTES;
|
|
109910
|
+
if (!Number.isInteger(maxBytes) || maxBytes < 0) {
|
|
109911
|
+
throw new Error(
|
|
109912
|
+
`createHdrImageTransferCache: maxBytes must be a non-negative integer, got ${String(maxBytes)}`
|
|
109913
|
+
);
|
|
109914
|
+
}
|
|
109915
|
+
const entries2 = /* @__PURE__ */ new Map();
|
|
109916
|
+
let totalBytes = 0;
|
|
109917
|
+
function makeKey(imageId, targetTransfer) {
|
|
109918
|
+
return `${imageId}|${targetTransfer}`;
|
|
109919
|
+
}
|
|
109920
|
+
function evictUntilRoom(needed) {
|
|
109921
|
+
while (totalBytes + needed > maxBytes && entries2.size > 0) {
|
|
109922
|
+
const lruKey = entries2.keys().next().value;
|
|
109923
|
+
if (lruKey === void 0) break;
|
|
109924
|
+
const evicted = entries2.get(lruKey);
|
|
109925
|
+
if (evicted) totalBytes -= evicted.byteLength;
|
|
109926
|
+
entries2.delete(lruKey);
|
|
109927
|
+
}
|
|
109928
|
+
}
|
|
109929
|
+
return {
|
|
109930
|
+
getConverted(imageId, sourceTransfer, targetTransfer, source2) {
|
|
109931
|
+
if (sourceTransfer === targetTransfer) {
|
|
109932
|
+
return source2;
|
|
109933
|
+
}
|
|
109934
|
+
if (maxBytes === 0) {
|
|
109935
|
+
const fresh = Buffer.from(source2);
|
|
109936
|
+
convertTransfer(fresh, sourceTransfer, targetTransfer);
|
|
109937
|
+
return fresh;
|
|
109938
|
+
}
|
|
109939
|
+
const key2 = makeKey(imageId, targetTransfer);
|
|
109940
|
+
const existing = entries2.get(key2);
|
|
109941
|
+
if (existing) {
|
|
109942
|
+
entries2.delete(key2);
|
|
109943
|
+
entries2.set(key2, existing);
|
|
109944
|
+
return existing;
|
|
109945
|
+
}
|
|
109946
|
+
const converted = Buffer.from(source2);
|
|
109947
|
+
convertTransfer(converted, sourceTransfer, targetTransfer);
|
|
109948
|
+
if (converted.byteLength > maxBytes) {
|
|
109949
|
+
return converted;
|
|
109950
|
+
}
|
|
109951
|
+
evictUntilRoom(converted.byteLength);
|
|
109952
|
+
entries2.set(key2, converted);
|
|
109953
|
+
totalBytes += converted.byteLength;
|
|
109954
|
+
return converted;
|
|
109955
|
+
},
|
|
109956
|
+
size() {
|
|
109957
|
+
return entries2.size;
|
|
109958
|
+
},
|
|
109959
|
+
bytesUsed() {
|
|
109960
|
+
return totalBytes;
|
|
109961
|
+
}
|
|
109962
|
+
};
|
|
109963
|
+
}
|
|
109964
|
+
|
|
109965
|
+
// src/services/renderOrchestrator.ts
|
|
109966
|
+
async function safeCleanup(label, fn, log = defaultLogger) {
|
|
109967
|
+
try {
|
|
109968
|
+
await fn();
|
|
109969
|
+
} catch (err) {
|
|
109970
|
+
log.debug(`Cleanup failed (${label})`, {
|
|
109971
|
+
error: err instanceof Error ? err.message : String(err)
|
|
109972
|
+
});
|
|
109973
|
+
}
|
|
109974
|
+
}
|
|
109975
|
+
function sampleDirectoryBytes(dir) {
|
|
109976
|
+
let total = 0;
|
|
109977
|
+
const stack = [dir];
|
|
109978
|
+
while (stack.length > 0) {
|
|
109979
|
+
const current = stack.pop();
|
|
109980
|
+
if (!current) continue;
|
|
109981
|
+
let entries2 = [];
|
|
109982
|
+
try {
|
|
109983
|
+
entries2 = readdirSync8(current);
|
|
109984
|
+
} catch {
|
|
109985
|
+
continue;
|
|
109986
|
+
}
|
|
109987
|
+
for (const name of entries2) {
|
|
109988
|
+
const full = join16(current, name);
|
|
109989
|
+
try {
|
|
109990
|
+
const st = statSync7(full);
|
|
109991
|
+
if (st.isDirectory()) {
|
|
109992
|
+
stack.push(full);
|
|
109993
|
+
} else if (st.isFile()) {
|
|
109994
|
+
total += st.size;
|
|
109995
|
+
}
|
|
109996
|
+
} catch {
|
|
109997
|
+
}
|
|
109998
|
+
}
|
|
109999
|
+
}
|
|
110000
|
+
return total;
|
|
110001
|
+
}
|
|
109540
110002
|
function countNonZeroAlpha(rgba) {
|
|
109541
110003
|
let n = 0;
|
|
109542
110004
|
for (let p = 3; p < rgba.length; p += 4) {
|
|
@@ -109560,6 +110022,10 @@ var RenderCancelledError = class extends Error {
|
|
|
109560
110022
|
this.reason = reason;
|
|
109561
110023
|
}
|
|
109562
110024
|
};
|
|
110025
|
+
var BROWSER_MEDIA_EPSILON = 1e-4;
|
|
110026
|
+
function projectBrowserEndToCompositionTimeline(existingStart, browserStart, browserEnd) {
|
|
110027
|
+
return browserEnd + (existingStart - browserStart);
|
|
110028
|
+
}
|
|
109563
110029
|
function updateJobStatus(job, status, stage, progress, onProgress) {
|
|
109564
110030
|
job.status = status;
|
|
109565
110031
|
job.currentStage = stage;
|
|
@@ -109603,21 +110069,21 @@ function installDebugLogger(logPath, log = defaultLogger) {
|
|
|
109603
110069
|
};
|
|
109604
110070
|
}
|
|
109605
110071
|
function writeCompiledArtifacts(compiled, workDir, includeSummary) {
|
|
109606
|
-
const compileDir =
|
|
109607
|
-
|
|
109608
|
-
|
|
110072
|
+
const compileDir = join16(workDir, "compiled");
|
|
110073
|
+
mkdirSync11(compileDir, { recursive: true });
|
|
110074
|
+
writeFileSync5(join16(compileDir, "index.html"), compiled.html, "utf-8");
|
|
109609
110075
|
for (const [srcPath, html] of compiled.subCompositions) {
|
|
109610
|
-
const outPath =
|
|
109611
|
-
|
|
109612
|
-
|
|
110076
|
+
const outPath = join16(compileDir, srcPath);
|
|
110077
|
+
mkdirSync11(dirname10(outPath), { recursive: true });
|
|
110078
|
+
writeFileSync5(outPath, html, "utf-8");
|
|
109613
110079
|
}
|
|
109614
110080
|
for (const [relativePath, absolutePath] of compiled.externalAssets) {
|
|
109615
|
-
const outPath = resolve11(
|
|
110081
|
+
const outPath = resolve11(join16(compileDir, relativePath));
|
|
109616
110082
|
if (!isPathInside2(outPath, compileDir)) {
|
|
109617
110083
|
console.warn(`[Render] Skipping external asset with unsafe path: ${relativePath}`);
|
|
109618
110084
|
continue;
|
|
109619
110085
|
}
|
|
109620
|
-
|
|
110086
|
+
mkdirSync11(dirname10(outPath), { recursive: true });
|
|
109621
110087
|
copyFileSync2(absolutePath, outPath);
|
|
109622
110088
|
}
|
|
109623
110089
|
if (includeSummary) {
|
|
@@ -109642,7 +110108,7 @@ function writeCompiledArtifacts(compiled, workDir, includeSummary) {
|
|
|
109642
110108
|
subCompositions: Array.from(compiled.subCompositions.keys()),
|
|
109643
110109
|
renderModeHints: compiled.renderModeHints
|
|
109644
110110
|
};
|
|
109645
|
-
|
|
110111
|
+
writeFileSync5(join16(compileDir, "summary.json"), JSON.stringify(summary, null, 2), "utf-8");
|
|
109646
110112
|
}
|
|
109647
110113
|
}
|
|
109648
110114
|
function applyRenderModeHints(cfg, compiled, log = defaultLogger) {
|
|
@@ -109663,8 +110129,8 @@ function blitHdrVideoLayer(canvas, el, time, fps, hdrFrameDirs, hdrStartTimes, w
|
|
|
109663
110129
|
if (videoFrameIndex < 1) return;
|
|
109664
110130
|
const maxIndex = getMaxFrameIndex(frameDir);
|
|
109665
110131
|
const effectiveIndex = maxIndex > 0 ? Math.min(videoFrameIndex, maxIndex) : videoFrameIndex;
|
|
109666
|
-
const framePath =
|
|
109667
|
-
if (!
|
|
110132
|
+
const framePath = join16(frameDir, `frame_${String(effectiveIndex).padStart(4, "0")}.png`);
|
|
110133
|
+
if (!existsSync16(framePath)) {
|
|
109668
110134
|
return;
|
|
109669
110135
|
}
|
|
109670
110136
|
try {
|
|
@@ -109710,17 +110176,13 @@ function blitHdrVideoLayer(canvas, el, time, fps, hdrFrameDirs, hdrStartTimes, w
|
|
|
109710
110176
|
}
|
|
109711
110177
|
}
|
|
109712
110178
|
}
|
|
109713
|
-
function blitHdrImageLayer(canvas, el, hdrImageBuffers, width, height, log, sourceTransfer, targetTransfer) {
|
|
110179
|
+
function blitHdrImageLayer(canvas, el, hdrImageBuffers, hdrImageTransferCache, width, height, log, sourceTransfer, targetTransfer) {
|
|
109714
110180
|
const buf = hdrImageBuffers.get(el.id);
|
|
109715
110181
|
if (!buf) {
|
|
109716
110182
|
return;
|
|
109717
110183
|
}
|
|
109718
110184
|
try {
|
|
109719
|
-
|
|
109720
|
-
if (sourceTransfer && targetTransfer && sourceTransfer !== targetTransfer) {
|
|
109721
|
-
hdrRgb = Buffer.from(buf.data);
|
|
109722
|
-
convertTransfer(hdrRgb, sourceTransfer, targetTransfer);
|
|
109723
|
-
}
|
|
110185
|
+
const hdrRgb = sourceTransfer && targetTransfer ? hdrImageTransferCache.getConverted(el.id, sourceTransfer, targetTransfer, buf.data) : buf.data;
|
|
109724
110186
|
const viewportMatrix = parseTransformMatrix(el.transform);
|
|
109725
110187
|
const br = el.borderRadius;
|
|
109726
110188
|
const hasBorderRadius = br[0] > 0 || br[1] > 0 || br[2] > 0 || br[3] > 0;
|
|
@@ -109770,6 +110232,7 @@ async function compositeHdrFrame(ctx, canvas, time, fullStacking, elementFilter,
|
|
|
109770
110232
|
effectiveHdr,
|
|
109771
110233
|
nativeHdrImageIds,
|
|
109772
110234
|
hdrImageBuffers,
|
|
110235
|
+
hdrImageTransferCache,
|
|
109773
110236
|
hdrFrameDirs,
|
|
109774
110237
|
hdrVideoStartTimes,
|
|
109775
110238
|
imageTransfers,
|
|
@@ -109809,6 +110272,7 @@ async function compositeHdrFrame(ctx, canvas, time, fullStacking, elementFilter,
|
|
|
109809
110272
|
canvas,
|
|
109810
110273
|
layer.element,
|
|
109811
110274
|
hdrImageBuffers,
|
|
110275
|
+
hdrImageTransferCache,
|
|
109812
110276
|
width,
|
|
109813
110277
|
height,
|
|
109814
110278
|
log,
|
|
@@ -109849,7 +110313,7 @@ async function compositeHdrFrame(ctx, canvas, time, fullStacking, elementFilter,
|
|
|
109849
110313
|
const startTime = hdrVideoStartTimes.get(layer.element.id) ?? 0;
|
|
109850
110314
|
const localTime = time - startTime;
|
|
109851
110315
|
const frameNum = Math.floor(localTime * fps) + 1;
|
|
109852
|
-
const expectedFrame = frameDir ?
|
|
110316
|
+
const expectedFrame = frameDir ? join16(frameDir, `frame_${String(frameNum).padStart(4, "0")}.png`) : null;
|
|
109853
110317
|
log.info("[diag] hdr layer blit", {
|
|
109854
110318
|
frame: debugFrameIndex,
|
|
109855
110319
|
layerIdx,
|
|
@@ -109861,7 +110325,7 @@ async function compositeHdrFrame(ctx, canvas, time, fullStacking, elementFilter,
|
|
|
109861
110325
|
localTime: localTime.toFixed(3),
|
|
109862
110326
|
hdrFrameNum: frameNum,
|
|
109863
110327
|
expectedFrame,
|
|
109864
|
-
expectedFrameExists: expectedFrame ?
|
|
110328
|
+
expectedFrameExists: expectedFrame ? existsSync16(expectedFrame) : false
|
|
109865
110329
|
});
|
|
109866
110330
|
}
|
|
109867
110331
|
}
|
|
@@ -109886,8 +110350,8 @@ async function compositeHdrFrame(ctx, canvas, time, fullStacking, elementFilter,
|
|
|
109886
110350
|
if (shouldLog && debugDumpDir) {
|
|
109887
110351
|
const after2 = countNonZeroRgb48(canvas);
|
|
109888
110352
|
const dumpName = `frame_${String(debugFrameIndex).padStart(4, "0")}_layer_${String(layerIdx).padStart(2, "0")}_dom.png`;
|
|
109889
|
-
const dumpPath =
|
|
109890
|
-
|
|
110353
|
+
const dumpPath = join16(debugDumpDir, dumpName);
|
|
110354
|
+
writeFileSync5(dumpPath, domPng);
|
|
109891
110355
|
log.info("[diag] dom layer blit", {
|
|
109892
110356
|
frame: debugFrameIndex,
|
|
109893
110357
|
layerIdx,
|
|
@@ -109960,8 +110424,8 @@ function extractStandaloneEntryFromIndex(indexHtml, entryFile) {
|
|
|
109960
110424
|
async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSignal) {
|
|
109961
110425
|
const moduleDir = dirname10(fileURLToPath3(import.meta.url));
|
|
109962
110426
|
const producerRoot = process.env.PRODUCER_RENDERS_DIR ? resolve11(process.env.PRODUCER_RENDERS_DIR, "..") : resolve11(moduleDir, "../..");
|
|
109963
|
-
const debugDir =
|
|
109964
|
-
const workDir = job.config.debug ?
|
|
110427
|
+
const debugDir = join16(producerRoot, ".debug");
|
|
110428
|
+
const workDir = job.config.debug ? join16(debugDir, job.id) : join16(dirname10(outputPath), `work-${job.id}`);
|
|
109965
110429
|
const pipelineStart = Date.now();
|
|
109966
110430
|
const log = job.config.logger ?? defaultLogger;
|
|
109967
110431
|
let fileServer = null;
|
|
@@ -109973,7 +110437,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
109973
110437
|
videoExtractionFailures: 0,
|
|
109974
110438
|
imageDecodeFailures: 0
|
|
109975
110439
|
};
|
|
109976
|
-
const perfOutputPath =
|
|
110440
|
+
const perfOutputPath = join16(workDir, "perf-summary.json");
|
|
109977
110441
|
const cfg = { ...job.config.producerConfig ?? resolveConfig() };
|
|
109978
110442
|
const outputFormat = job.config.format ?? "mp4";
|
|
109979
110443
|
const isWebm = outputFormat === "webm";
|
|
@@ -110006,22 +110470,22 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110006
110470
|
};
|
|
110007
110471
|
job.startedAt = /* @__PURE__ */ new Date();
|
|
110008
110472
|
assertNotAborted();
|
|
110009
|
-
if (!
|
|
110473
|
+
if (!existsSync16(workDir)) mkdirSync11(workDir, { recursive: true });
|
|
110010
110474
|
if (job.config.debug) {
|
|
110011
|
-
const logPath =
|
|
110475
|
+
const logPath = join16(workDir, "render.log");
|
|
110012
110476
|
restoreLogger = installDebugLogger(logPath, log);
|
|
110013
110477
|
}
|
|
110014
110478
|
const entryFile = job.config.entryFile || "index.html";
|
|
110015
|
-
let htmlPath =
|
|
110016
|
-
if (!
|
|
110479
|
+
let htmlPath = join16(projectDir, entryFile);
|
|
110480
|
+
if (!existsSync16(htmlPath)) {
|
|
110017
110481
|
throw new Error(`Entry file not found: ${htmlPath}`);
|
|
110018
110482
|
}
|
|
110019
110483
|
assertNotAborted();
|
|
110020
110484
|
const rawEntry = readFileSync10(htmlPath, "utf-8");
|
|
110021
110485
|
if (entryFile !== "index.html" && rawEntry.trimStart().startsWith("<template")) {
|
|
110022
|
-
const wrapperPath =
|
|
110023
|
-
const projectIndexPath =
|
|
110024
|
-
if (!
|
|
110486
|
+
const wrapperPath = join16(workDir, "standalone-entry.html");
|
|
110487
|
+
const projectIndexPath = join16(projectDir, "index.html");
|
|
110488
|
+
if (!existsSync16(projectIndexPath)) {
|
|
110025
110489
|
throw new Error(
|
|
110026
110490
|
`Template entry file "${entryFile}" requires a project index.html to extract its render shell.`
|
|
110027
110491
|
);
|
|
@@ -110035,7 +110499,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110035
110499
|
`Entry file "${entryFile}" is not mounted from index.html via data-composition-src, so it cannot be rendered independently.`
|
|
110036
110500
|
);
|
|
110037
110501
|
}
|
|
110038
|
-
|
|
110502
|
+
writeFileSync5(wrapperPath, standaloneHtml, "utf-8");
|
|
110039
110503
|
htmlPath = wrapperPath;
|
|
110040
110504
|
log.info("Extracted standalone entry from index.html host context", {
|
|
110041
110505
|
entryFile
|
|
@@ -110044,7 +110508,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110044
110508
|
const stage1Start = Date.now();
|
|
110045
110509
|
updateJobStatus(job, "preprocessing", "Compiling composition", 5, onProgress);
|
|
110046
110510
|
const compileStart = Date.now();
|
|
110047
|
-
let compiled = await compileForRender(projectDir, htmlPath,
|
|
110511
|
+
let compiled = await compileForRender(projectDir, htmlPath, join16(workDir, "downloads"));
|
|
110048
110512
|
assertNotAborted();
|
|
110049
110513
|
perfStages.compileOnlyMs = Date.now() - compileStart;
|
|
110050
110514
|
applyRenderModeHints(cfg, compiled, log);
|
|
@@ -110076,7 +110540,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110076
110540
|
reasons.push(`${compiled.unresolvedCompositions.length} unresolved composition(s)`);
|
|
110077
110541
|
fileServer = await createFileServer2({
|
|
110078
110542
|
projectDir,
|
|
110079
|
-
compiledDir:
|
|
110543
|
+
compiledDir: join16(workDir, "compiled"),
|
|
110080
110544
|
port: 0,
|
|
110081
110545
|
preHeadScripts: [VIRTUAL_TIME_SHIM]
|
|
110082
110546
|
});
|
|
@@ -110090,7 +110554,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110090
110554
|
};
|
|
110091
110555
|
probeSession = await createCaptureSession(
|
|
110092
110556
|
fileServer.url,
|
|
110093
|
-
|
|
110557
|
+
join16(workDir, "probe"),
|
|
110094
110558
|
captureOpts,
|
|
110095
110559
|
null,
|
|
110096
110560
|
cfg
|
|
@@ -110122,7 +110586,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110122
110586
|
compiled,
|
|
110123
110587
|
resolutions,
|
|
110124
110588
|
projectDir,
|
|
110125
|
-
|
|
110589
|
+
join16(workDir, "downloads")
|
|
110126
110590
|
);
|
|
110127
110591
|
assertNotAborted();
|
|
110128
110592
|
composition.videos = compiled.videos;
|
|
@@ -110149,10 +110613,15 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110149
110613
|
if (existing.src !== src) {
|
|
110150
110614
|
existing.src = src;
|
|
110151
110615
|
}
|
|
110152
|
-
|
|
110153
|
-
existing.
|
|
110616
|
+
const projectedEnd = projectBrowserEndToCompositionTimeline(
|
|
110617
|
+
existing.start,
|
|
110618
|
+
el.start,
|
|
110619
|
+
el.end
|
|
110620
|
+
);
|
|
110621
|
+
if (projectedEnd > 0 && (existing.end <= 0 || Math.abs(existing.end - projectedEnd) > BROWSER_MEDIA_EPSILON)) {
|
|
110622
|
+
existing.end = projectedEnd;
|
|
110154
110623
|
}
|
|
110155
|
-
if (el.mediaStart > 0 && (existing.mediaStart <= 0 || Math.abs(existing.mediaStart - el.mediaStart) >
|
|
110624
|
+
if (el.mediaStart > 0 && (existing.mediaStart <= 0 || Math.abs(existing.mediaStart - el.mediaStart) > BROWSER_MEDIA_EPSILON)) {
|
|
110156
110625
|
existing.mediaStart = el.mediaStart;
|
|
110157
110626
|
}
|
|
110158
110627
|
if (el.hasAudio && !existing.hasAudio) {
|
|
@@ -110177,13 +110646,18 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110177
110646
|
if (existing.src !== src) {
|
|
110178
110647
|
existing.src = src;
|
|
110179
110648
|
}
|
|
110180
|
-
|
|
110181
|
-
existing.
|
|
110649
|
+
const projectedEnd = projectBrowserEndToCompositionTimeline(
|
|
110650
|
+
existing.start,
|
|
110651
|
+
el.start,
|
|
110652
|
+
el.end
|
|
110653
|
+
);
|
|
110654
|
+
if (projectedEnd > 0 && (existing.end <= 0 || Math.abs(existing.end - projectedEnd) > BROWSER_MEDIA_EPSILON)) {
|
|
110655
|
+
existing.end = projectedEnd;
|
|
110182
110656
|
}
|
|
110183
|
-
if (el.mediaStart > 0 && (existing.mediaStart <= 0 || Math.abs(existing.mediaStart - el.mediaStart) >
|
|
110657
|
+
if (el.mediaStart > 0 && (existing.mediaStart <= 0 || Math.abs(existing.mediaStart - el.mediaStart) > BROWSER_MEDIA_EPSILON)) {
|
|
110184
110658
|
existing.mediaStart = el.mediaStart;
|
|
110185
110659
|
}
|
|
110186
|
-
if (el.volume > 0 && Math.abs((existing.volume ?? 1) - el.volume) >
|
|
110660
|
+
if (el.volume > 0 && Math.abs((existing.volume ?? 1) - el.volume) > BROWSER_MEDIA_EPSILON) {
|
|
110187
110661
|
existing.volume = el.volume;
|
|
110188
110662
|
}
|
|
110189
110663
|
}
|
|
@@ -110262,7 +110736,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110262
110736
|
const stage2Start = Date.now();
|
|
110263
110737
|
updateJobStatus(job, "preprocessing", "Extracting video frames", 10, onProgress);
|
|
110264
110738
|
let frameLookup = null;
|
|
110265
|
-
const compiledDir =
|
|
110739
|
+
const compiledDir = join16(workDir, "compiled");
|
|
110266
110740
|
let extractionResult = null;
|
|
110267
110741
|
const nativeHdrVideoIds = /* @__PURE__ */ new Set();
|
|
110268
110742
|
const videoTransfers = /* @__PURE__ */ new Map();
|
|
@@ -110271,10 +110745,10 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110271
110745
|
composition.videos.map(async (v) => {
|
|
110272
110746
|
let videoPath = v.src;
|
|
110273
110747
|
if (!videoPath.startsWith("/")) {
|
|
110274
|
-
const fromCompiled =
|
|
110748
|
+
const fromCompiled = existsSync16(join16(compiledDir, videoPath)) ? join16(compiledDir, videoPath) : join16(projectDir, videoPath);
|
|
110275
110749
|
videoPath = fromCompiled;
|
|
110276
110750
|
}
|
|
110277
|
-
if (!
|
|
110751
|
+
if (!existsSync16(videoPath)) return;
|
|
110278
110752
|
const meta = await extractMediaMetadata(videoPath);
|
|
110279
110753
|
if (isHdrColorSpace(meta.colorSpace)) {
|
|
110280
110754
|
nativeHdrVideoIds.add(v.id);
|
|
@@ -110292,10 +110766,10 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110292
110766
|
composition.images.map(async (img) => {
|
|
110293
110767
|
let imgPath = img.src;
|
|
110294
110768
|
if (!imgPath.startsWith("/")) {
|
|
110295
|
-
const fromCompiled =
|
|
110769
|
+
const fromCompiled = existsSync16(join16(compiledDir, imgPath)) ? join16(compiledDir, imgPath) : join16(projectDir, imgPath);
|
|
110296
110770
|
imgPath = fromCompiled;
|
|
110297
110771
|
}
|
|
110298
|
-
if (!
|
|
110772
|
+
if (!existsSync16(imgPath)) return null;
|
|
110299
110773
|
const meta = await extractMediaMetadata(imgPath);
|
|
110300
110774
|
if (isHdrColorSpace(meta.colorSpace)) {
|
|
110301
110775
|
nativeHdrImageIds.add(img.id);
|
|
@@ -110311,9 +110785,9 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110311
110785
|
extractionResult = await extractAllVideoFrames(
|
|
110312
110786
|
composition.videos,
|
|
110313
110787
|
projectDir,
|
|
110314
|
-
{ fps: job.config.fps, outputDir:
|
|
110788
|
+
{ fps: job.config.fps, outputDir: join16(workDir, "video-frames") },
|
|
110315
110789
|
abortSignal,
|
|
110316
|
-
|
|
110790
|
+
{ extractCacheDir: cfg.extractCacheDir },
|
|
110317
110791
|
compiledDir
|
|
110318
110792
|
);
|
|
110319
110793
|
assertNotAborted();
|
|
@@ -110369,13 +110843,13 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110369
110843
|
}
|
|
110370
110844
|
const stage3Start = Date.now();
|
|
110371
110845
|
updateJobStatus(job, "preprocessing", "Processing audio tracks", 20, onProgress);
|
|
110372
|
-
const audioOutputPath =
|
|
110846
|
+
const audioOutputPath = join16(workDir, "audio.aac");
|
|
110373
110847
|
let hasAudio = false;
|
|
110374
110848
|
if (composition.audios.length > 0) {
|
|
110375
110849
|
const audioResult = await processCompositionAudio(
|
|
110376
110850
|
composition.audios,
|
|
110377
110851
|
projectDir,
|
|
110378
|
-
|
|
110852
|
+
join16(workDir, "audio-work"),
|
|
110379
110853
|
audioOutputPath,
|
|
110380
110854
|
job.duration,
|
|
110381
110855
|
abortSignal,
|
|
@@ -110393,14 +110867,14 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110393
110867
|
if (!fileServer) {
|
|
110394
110868
|
fileServer = await createFileServer2({
|
|
110395
110869
|
projectDir,
|
|
110396
|
-
compiledDir:
|
|
110870
|
+
compiledDir: join16(workDir, "compiled"),
|
|
110397
110871
|
port: 0,
|
|
110398
110872
|
preHeadScripts: [VIRTUAL_TIME_SHIM]
|
|
110399
110873
|
});
|
|
110400
110874
|
assertNotAborted();
|
|
110401
110875
|
}
|
|
110402
|
-
const framesDir =
|
|
110403
|
-
if (!
|
|
110876
|
+
const framesDir = join16(workDir, "captured-frames");
|
|
110877
|
+
if (!existsSync16(framesDir)) mkdirSync11(framesDir, { recursive: true });
|
|
110404
110878
|
const captureOptions = {
|
|
110405
110879
|
width,
|
|
110406
110880
|
height,
|
|
@@ -110415,7 +110889,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110415
110889
|
const workerCount = calculateOptimalWorkers(totalFrames, job.config.workers, cfg);
|
|
110416
110890
|
const FORMAT_EXT = { mp4: ".mp4", webm: ".webm", mov: ".mov" };
|
|
110417
110891
|
const videoExt = FORMAT_EXT[outputFormat] ?? ".mp4";
|
|
110418
|
-
const videoOnlyPath =
|
|
110892
|
+
const videoOnlyPath = join16(workDir, `video-only${videoExt}`);
|
|
110419
110893
|
const nativeHdrIds = /* @__PURE__ */ new Set([...nativeHdrVideoIds, ...nativeHdrImageIds]);
|
|
110420
110894
|
const hasHdrContent = effectiveHdr && nativeHdrIds.size > 0;
|
|
110421
110895
|
const encoderHdr = hasHdrContent ? effectiveHdr : void 0;
|
|
@@ -110437,8 +110911,8 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110437
110911
|
if (!hdrVideoIds.includes(v.id)) continue;
|
|
110438
110912
|
let srcPath = v.src;
|
|
110439
110913
|
if (!srcPath.startsWith("/")) {
|
|
110440
|
-
const fromCompiled =
|
|
110441
|
-
srcPath =
|
|
110914
|
+
const fromCompiled = join16(compiledDir, srcPath);
|
|
110915
|
+
srcPath = existsSync16(fromCompiled) ? fromCompiled : join16(projectDir, srcPath);
|
|
110442
110916
|
}
|
|
110443
110917
|
hdrVideoSrcPaths.set(v.id, srcPath);
|
|
110444
110918
|
}
|
|
@@ -110568,8 +111042,8 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110568
111042
|
for (const [videoId, srcPath] of hdrVideoSrcPaths) {
|
|
110569
111043
|
const video = composition.videos.find((v) => v.id === videoId);
|
|
110570
111044
|
if (!video) continue;
|
|
110571
|
-
const frameDir =
|
|
110572
|
-
|
|
111045
|
+
const frameDir = join16(framesDir, `hdr_${videoId}`);
|
|
111046
|
+
mkdirSync11(frameDir, { recursive: true });
|
|
110573
111047
|
const duration = video.end - video.start;
|
|
110574
111048
|
const dims = hdrExtractionDims.get(videoId) ?? { width, height };
|
|
110575
111049
|
const ffmpegArgs = [
|
|
@@ -110588,7 +111062,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110588
111062
|
"-c:v",
|
|
110589
111063
|
"png",
|
|
110590
111064
|
"-y",
|
|
110591
|
-
|
|
111065
|
+
join16(frameDir, "frame_%04d.png")
|
|
110592
111066
|
];
|
|
110593
111067
|
const result = await runFfmpeg(ffmpegArgs, { signal: abortSignal });
|
|
110594
111068
|
if (!result.success) {
|
|
@@ -110656,15 +111130,19 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110656
111130
|
}
|
|
110657
111131
|
}
|
|
110658
111132
|
const debugDumpEnabled = process.env.KEEP_TEMP === "1";
|
|
110659
|
-
const debugDumpDir = debugDumpEnabled ?
|
|
110660
|
-
if (debugDumpDir && !
|
|
110661
|
-
|
|
111133
|
+
const debugDumpDir = debugDumpEnabled ? join16(framesDir, "debug-composite") : null;
|
|
111134
|
+
if (debugDumpDir && !existsSync16(debugDumpDir)) {
|
|
111135
|
+
mkdirSync11(debugDumpDir, { recursive: true });
|
|
110662
111136
|
}
|
|
110663
111137
|
if (!effectiveHdr) {
|
|
110664
111138
|
throw new Error(
|
|
110665
111139
|
"Internal: HDR render path entered without effectiveHdr \u2014 this is a bug."
|
|
110666
111140
|
);
|
|
110667
111141
|
}
|
|
111142
|
+
const hdrCacheMaxBytes = process.env.HDR_TRANSFER_CACHE_MAX_BYTES ? Number(process.env.HDR_TRANSFER_CACHE_MAX_BYTES) : void 0;
|
|
111143
|
+
const hdrImageTransferCache = createHdrImageTransferCache(
|
|
111144
|
+
hdrCacheMaxBytes !== void 0 ? { maxBytes: hdrCacheMaxBytes } : {}
|
|
111145
|
+
);
|
|
110668
111146
|
const hdrCompositeCtx = {
|
|
110669
111147
|
log,
|
|
110670
111148
|
domSession,
|
|
@@ -110675,6 +111153,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110675
111153
|
effectiveHdr,
|
|
110676
111154
|
nativeHdrImageIds,
|
|
110677
111155
|
hdrImageBuffers,
|
|
111156
|
+
hdrImageTransferCache,
|
|
110678
111157
|
hdrFrameDirs,
|
|
110679
111158
|
hdrVideoStartTimes,
|
|
110680
111159
|
imageTransfers,
|
|
@@ -110735,6 +111214,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110735
111214
|
sceneBuf,
|
|
110736
111215
|
el,
|
|
110737
111216
|
hdrImageBuffers,
|
|
111217
|
+
hdrImageTransferCache,
|
|
110738
111218
|
width,
|
|
110739
111219
|
height,
|
|
110740
111220
|
log,
|
|
@@ -110798,11 +111278,11 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110798
111278
|
i
|
|
110799
111279
|
);
|
|
110800
111280
|
if (debugDumpEnabled && debugDumpDir && i % 30 === 0) {
|
|
110801
|
-
const previewPath =
|
|
111281
|
+
const previewPath = join16(
|
|
110802
111282
|
debugDumpDir,
|
|
110803
111283
|
`frame_${String(i).padStart(4, "0")}_final_rgb48le.bin`
|
|
110804
111284
|
);
|
|
110805
|
-
|
|
111285
|
+
writeFileSync5(previewPath, normalCanvas);
|
|
110806
111286
|
}
|
|
110807
111287
|
hdrEncoder.writeFrame(normalCanvas);
|
|
110808
111288
|
}
|
|
@@ -110822,7 +111302,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110822
111302
|
error: err instanceof Error ? err.message : String(err)
|
|
110823
111303
|
});
|
|
110824
111304
|
}
|
|
110825
|
-
|
|
111305
|
+
clearMaxFrameIndex(frameDir);
|
|
110826
111306
|
hdrFrameDirs.delete(videoId);
|
|
110827
111307
|
}
|
|
110828
111308
|
cleanedUpVideos.add(videoId);
|
|
@@ -110873,7 +111353,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110873
111353
|
});
|
|
110874
111354
|
}
|
|
110875
111355
|
for (const frameDir of hdrFrameDirs.values()) {
|
|
110876
|
-
|
|
111356
|
+
clearMaxFrameIndex(frameDir);
|
|
110877
111357
|
}
|
|
110878
111358
|
hdrFrameDirs.clear();
|
|
110879
111359
|
}
|
|
@@ -111145,6 +111625,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
111145
111625
|
updateJobStatus(job, "complete", "Render complete", 100, onProgress);
|
|
111146
111626
|
const totalElapsed = Date.now() - pipelineStart;
|
|
111147
111627
|
sampleMemory();
|
|
111628
|
+
const tmpPeakBytes = existsSync16(workDir) ? sampleDirectoryBytes(workDir) : 0;
|
|
111148
111629
|
const perfSummary = {
|
|
111149
111630
|
renderId: job.id,
|
|
111150
111631
|
totalElapsedMs: totalElapsed,
|
|
@@ -111159,6 +111640,8 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
111159
111640
|
videoCount: composition.videos.length,
|
|
111160
111641
|
audioCount: composition.audios.length,
|
|
111161
111642
|
stages: perfStages,
|
|
111643
|
+
videoExtractBreakdown: extractionResult?.phaseBreakdown,
|
|
111644
|
+
tmpPeakBytes,
|
|
111162
111645
|
hdrDiagnostics: hdrDiagnostics.videoExtractionFailures > 0 || hdrDiagnostics.imageDecodeFailures > 0 ? { ...hdrDiagnostics } : void 0,
|
|
111163
111646
|
captureAvgMs: totalFrames > 0 ? Math.round((perfStages.captureMs ?? 0) / totalFrames) : void 0,
|
|
111164
111647
|
peakRssMb: Math.round(peakRssBytes / (1024 * 1024)),
|
|
@@ -111167,7 +111650,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
111167
111650
|
job.perfSummary = perfSummary;
|
|
111168
111651
|
if (job.config.debug) {
|
|
111169
111652
|
try {
|
|
111170
|
-
|
|
111653
|
+
writeFileSync5(perfOutputPath, JSON.stringify(perfSummary, null, 2), "utf-8");
|
|
111171
111654
|
} catch (err) {
|
|
111172
111655
|
log.debug("Failed to write perf summary", {
|
|
111173
111656
|
perfOutputPath,
|
|
@@ -111176,8 +111659,8 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
111176
111659
|
}
|
|
111177
111660
|
}
|
|
111178
111661
|
if (job.config.debug) {
|
|
111179
|
-
if (
|
|
111180
|
-
const debugOutput =
|
|
111662
|
+
if (existsSync16(outputPath)) {
|
|
111663
|
+
const debugOutput = join16(workDir, `output${videoExt}`);
|
|
111181
111664
|
copyFileSync2(outputPath, debugOutput);
|
|
111182
111665
|
}
|
|
111183
111666
|
} else if (process.env.KEEP_TEMP === "1") {
|
|
@@ -111263,7 +111746,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
111263
111746
|
await safeCleanup(
|
|
111264
111747
|
"remove workDir (error)",
|
|
111265
111748
|
() => {
|
|
111266
|
-
if (
|
|
111749
|
+
if (existsSync16(workDir)) rmSync3(workDir, { recursive: true, force: true });
|
|
111267
111750
|
},
|
|
111268
111751
|
log
|
|
111269
111752
|
);
|
|
@@ -111277,15 +111760,15 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
111277
111760
|
|
|
111278
111761
|
// src/server.ts
|
|
111279
111762
|
import {
|
|
111280
|
-
existsSync as
|
|
111281
|
-
mkdirSync as
|
|
111282
|
-
statSync as
|
|
111763
|
+
existsSync as existsSync18,
|
|
111764
|
+
mkdirSync as mkdirSync12,
|
|
111765
|
+
statSync as statSync9,
|
|
111283
111766
|
mkdtempSync,
|
|
111284
|
-
writeFileSync as
|
|
111767
|
+
writeFileSync as writeFileSync6,
|
|
111285
111768
|
rmSync as rmSync4,
|
|
111286
111769
|
createReadStream as createReadStream2
|
|
111287
111770
|
} from "node:fs";
|
|
111288
|
-
import { resolve as resolve13, dirname as dirname11, join as
|
|
111771
|
+
import { resolve as resolve13, dirname as dirname11, join as join18 } from "node:path";
|
|
111289
111772
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
111290
111773
|
import { parseArgs } from "node:util";
|
|
111291
111774
|
import crypto2 from "node:crypto";
|
|
@@ -111440,8 +111923,8 @@ var streamSSE = (c, cb, onError) => {
|
|
|
111440
111923
|
};
|
|
111441
111924
|
|
|
111442
111925
|
// src/services/hyperframeLint.ts
|
|
111443
|
-
import { existsSync as
|
|
111444
|
-
import { resolve as resolve12, join as
|
|
111926
|
+
import { existsSync as existsSync17, readFileSync as readFileSync11, statSync as statSync8 } from "node:fs";
|
|
111927
|
+
import { resolve as resolve12, join as join17 } from "node:path";
|
|
111445
111928
|
function isStringRecord(value) {
|
|
111446
111929
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
111447
111930
|
return false;
|
|
@@ -111469,7 +111952,7 @@ function pickEntryFile(files, preferredEntryFile) {
|
|
|
111469
111952
|
}
|
|
111470
111953
|
function readProjectEntryFile(projectDir, preferredEntryFile) {
|
|
111471
111954
|
const absProjectDir = resolve12(projectDir);
|
|
111472
|
-
if (!
|
|
111955
|
+
if (!existsSync17(absProjectDir) || !statSync8(absProjectDir).isDirectory()) {
|
|
111473
111956
|
return { error: `Project directory not found: ${absProjectDir}` };
|
|
111474
111957
|
}
|
|
111475
111958
|
const entryCandidates = [preferredEntryFile, "index.html", "src/index.html"].filter(
|
|
@@ -111480,7 +111963,7 @@ function readProjectEntryFile(projectDir, preferredEntryFile) {
|
|
|
111480
111963
|
if (!absoluteEntryPath.startsWith(absProjectDir)) {
|
|
111481
111964
|
return { error: `Entry file must stay inside project directory: ${entryFile}` };
|
|
111482
111965
|
}
|
|
111483
|
-
if (
|
|
111966
|
+
if (existsSync17(absoluteEntryPath) && statSync8(absoluteEntryPath).isFile()) {
|
|
111484
111967
|
return {
|
|
111485
111968
|
entryFile,
|
|
111486
111969
|
html: readFileSync11(absoluteEntryPath, "utf-8"),
|
|
@@ -111489,7 +111972,7 @@ function readProjectEntryFile(projectDir, preferredEntryFile) {
|
|
|
111489
111972
|
}
|
|
111490
111973
|
}
|
|
111491
111974
|
return {
|
|
111492
|
-
error: `No HTML entry file found in project directory: ${
|
|
111975
|
+
error: `No HTML entry file found in project directory: ${join17(absProjectDir, preferredEntryFile || "index.html")}`
|
|
111493
111976
|
};
|
|
111494
111977
|
}
|
|
111495
111978
|
function prepareHyperframeLintBody(body) {
|
|
@@ -111580,11 +112063,11 @@ async function prepareRenderBody(body) {
|
|
|
111580
112063
|
const projectDir = typeof body.projectDir === "string" ? body.projectDir : void 0;
|
|
111581
112064
|
if (projectDir) {
|
|
111582
112065
|
const absProjectDir = resolve13(projectDir);
|
|
111583
|
-
if (!
|
|
112066
|
+
if (!existsSync18(absProjectDir) || !statSync9(absProjectDir).isDirectory()) {
|
|
111584
112067
|
return { error: `Project directory not found: ${absProjectDir}` };
|
|
111585
112068
|
}
|
|
111586
112069
|
const entry = options.entryFile || "index.html";
|
|
111587
|
-
if (!
|
|
112070
|
+
if (!existsSync18(resolve13(absProjectDir, entry))) {
|
|
111588
112071
|
return { error: `Entry file "${entry}" not found in project directory: ${absProjectDir}` };
|
|
111589
112072
|
}
|
|
111590
112073
|
return { prepared: { input: { projectDir: absProjectDir, ...options } } };
|
|
@@ -111609,8 +112092,8 @@ async function prepareRenderBody(body) {
|
|
|
111609
112092
|
}
|
|
111610
112093
|
}
|
|
111611
112094
|
const tempRoot = process.env.PRODUCER_TMP_PROJECT_DIR || tmpdir2();
|
|
111612
|
-
const tempProjectDir = mkdtempSync(
|
|
111613
|
-
|
|
112095
|
+
const tempProjectDir = mkdtempSync(join18(tempRoot, "producer-project-"));
|
|
112096
|
+
writeFileSync6(join18(tempProjectDir, "index.html"), htmlContent, "utf-8");
|
|
111614
112097
|
return {
|
|
111615
112098
|
prepared: {
|
|
111616
112099
|
input: {
|
|
@@ -111733,7 +112216,7 @@ function createRenderHandlers(options = {}) {
|
|
|
111733
112216
|
log
|
|
111734
112217
|
);
|
|
111735
112218
|
const outputDir = dirname11(absoluteOutputPath);
|
|
111736
|
-
if (!
|
|
112219
|
+
if (!existsSync18(outputDir)) mkdirSync12(outputDir, { recursive: true });
|
|
111737
112220
|
const release = await renderSemaphore.acquire();
|
|
111738
112221
|
log.info("render started", {
|
|
111739
112222
|
requestId,
|
|
@@ -111760,7 +112243,7 @@ function createRenderHandlers(options = {}) {
|
|
|
111760
112243
|
log.info(`render progress ${pct}%`, { requestId, stage: j.currentStage, message });
|
|
111761
112244
|
}
|
|
111762
112245
|
});
|
|
111763
|
-
const fileSize =
|
|
112246
|
+
const fileSize = existsSync18(absoluteOutputPath) ? statSync9(absoluteOutputPath).size : 0;
|
|
111764
112247
|
const durationMs = Date.now() - t0;
|
|
111765
112248
|
const outputToken = store.register(absoluteOutputPath);
|
|
111766
112249
|
const outputUrl = `${outputUrlPrefix}/${outputToken}`;
|
|
@@ -111844,7 +112327,7 @@ function createRenderHandlers(options = {}) {
|
|
|
111844
112327
|
log
|
|
111845
112328
|
);
|
|
111846
112329
|
const outputDir = dirname11(absoluteOutputPath);
|
|
111847
|
-
if (!
|
|
112330
|
+
if (!existsSync18(outputDir)) mkdirSync12(outputDir, { recursive: true });
|
|
111848
112331
|
log.info("render-stream started", { requestId, projectDir: input2.projectDir });
|
|
111849
112332
|
const job = createRenderJob({
|
|
111850
112333
|
fps: input2.fps,
|
|
@@ -111889,7 +112372,7 @@ function createRenderHandlers(options = {}) {
|
|
|
111889
112372
|
},
|
|
111890
112373
|
abortController.signal
|
|
111891
112374
|
);
|
|
111892
|
-
const fileSize =
|
|
112375
|
+
const fileSize = existsSync18(absoluteOutputPath) ? statSync9(absoluteOutputPath).size : 0;
|
|
111893
112376
|
const outputToken = store.register(absoluteOutputPath);
|
|
111894
112377
|
const outputUrl = `${outputUrlPrefix}/${outputToken}`;
|
|
111895
112378
|
log.info("render-stream completed", { requestId, fileSize, perf: job.perfSummary ?? null });
|
|
@@ -111948,11 +112431,11 @@ function createRenderHandlers(options = {}) {
|
|
|
111948
112431
|
if (!artifact) {
|
|
111949
112432
|
return c.json({ success: false, error: "Output artifact not found or expired" }, 404);
|
|
111950
112433
|
}
|
|
111951
|
-
if (!
|
|
112434
|
+
if (!existsSync18(artifact.path)) {
|
|
111952
112435
|
store.delete(token);
|
|
111953
112436
|
return c.json({ success: false, error: "Output artifact file missing" }, 404);
|
|
111954
112437
|
}
|
|
111955
|
-
const stats =
|
|
112438
|
+
const stats = statSync9(artifact.path);
|
|
111956
112439
|
return new Response(createReadStream2(artifact.path), {
|
|
111957
112440
|
headers: {
|
|
111958
112441
|
"content-type": "video/mp4",
|