@hyperframes/producer 0.4.15-alpha.1 → 0.4.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1229 -985
- package/dist/index.js.map +4 -4
- package/dist/public-server.js +1229 -985
- package/dist/public-server.js.map +4 -4
- package/dist/services/fileServer.d.ts +26 -0
- package/dist/services/fileServer.d.ts.map +1 -1
- package/dist/services/renderOrchestrator.d.ts.map +1 -1
- package/dist/utils/ffprobe.d.ts +1 -1
- package/dist/utils/ffprobe.d.ts.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1356,12 +1356,12 @@ var require_CSSValueExpression = __commonJS({
|
|
|
1356
1356
|
return false;
|
|
1357
1357
|
}
|
|
1358
1358
|
};
|
|
1359
|
-
CSSOM.CSSValueExpression.prototype._parseJSString = function(token, idx,
|
|
1360
|
-
var endIdx = this._findMatchedIdx(token, idx,
|
|
1359
|
+
CSSOM.CSSValueExpression.prototype._parseJSString = function(token, idx, sep2) {
|
|
1360
|
+
var endIdx = this._findMatchedIdx(token, idx, sep2), text;
|
|
1361
1361
|
if (endIdx === -1) {
|
|
1362
1362
|
return false;
|
|
1363
1363
|
} else {
|
|
1364
|
-
text = token.substring(idx, endIdx +
|
|
1364
|
+
text = token.substring(idx, endIdx + sep2.length);
|
|
1365
1365
|
return {
|
|
1366
1366
|
idx: endIdx,
|
|
1367
1367
|
text
|
|
@@ -1401,15 +1401,15 @@ var require_CSSValueExpression = __commonJS({
|
|
|
1401
1401
|
if (!isLegal) {
|
|
1402
1402
|
return false;
|
|
1403
1403
|
} else {
|
|
1404
|
-
var
|
|
1405
|
-
return this._parseJSString(token, idx,
|
|
1404
|
+
var sep2 = "/";
|
|
1405
|
+
return this._parseJSString(token, idx, sep2);
|
|
1406
1406
|
}
|
|
1407
1407
|
};
|
|
1408
|
-
CSSOM.CSSValueExpression.prototype._findMatchedIdx = function(token, idx,
|
|
1408
|
+
CSSOM.CSSValueExpression.prototype._findMatchedIdx = function(token, idx, sep2) {
|
|
1409
1409
|
var startIdx = idx, endIdx;
|
|
1410
1410
|
var NOT_FOUND = -1;
|
|
1411
1411
|
while (true) {
|
|
1412
|
-
endIdx = token.indexOf(
|
|
1412
|
+
endIdx = token.indexOf(sep2, startIdx + 1);
|
|
1413
1413
|
if (endIdx === -1) {
|
|
1414
1414
|
endIdx = NOT_FOUND;
|
|
1415
1415
|
break;
|
|
@@ -2148,11 +2148,11 @@ function __extends(d, b) {
|
|
|
2148
2148
|
}
|
|
2149
2149
|
function __awaiter(thisArg, _arguments, P, generator) {
|
|
2150
2150
|
function adopt(value) {
|
|
2151
|
-
return value instanceof P ? value : new P(function(
|
|
2152
|
-
|
|
2151
|
+
return value instanceof P ? value : new P(function(resolve14) {
|
|
2152
|
+
resolve14(value);
|
|
2153
2153
|
});
|
|
2154
2154
|
}
|
|
2155
|
-
return new (P || (P = Promise))(function(
|
|
2155
|
+
return new (P || (P = Promise))(function(resolve14, reject) {
|
|
2156
2156
|
function fulfilled(value) {
|
|
2157
2157
|
try {
|
|
2158
2158
|
step(generator.next(value));
|
|
@@ -2168,7 +2168,7 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
2168
2168
|
}
|
|
2169
2169
|
}
|
|
2170
2170
|
function step(result) {
|
|
2171
|
-
result.done ?
|
|
2171
|
+
result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
2172
2172
|
}
|
|
2173
2173
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
2174
2174
|
});
|
|
@@ -2331,14 +2331,14 @@ function __asyncValues(o) {
|
|
|
2331
2331
|
}, i);
|
|
2332
2332
|
function verb(n) {
|
|
2333
2333
|
i[n] = o[n] && function(v) {
|
|
2334
|
-
return new Promise(function(
|
|
2335
|
-
v = o[n](v), settle(
|
|
2334
|
+
return new Promise(function(resolve14, reject) {
|
|
2335
|
+
v = o[n](v), settle(resolve14, reject, v.done, v.value);
|
|
2336
2336
|
});
|
|
2337
2337
|
};
|
|
2338
2338
|
}
|
|
2339
|
-
function settle(
|
|
2339
|
+
function settle(resolve14, reject, d, v) {
|
|
2340
2340
|
Promise.resolve(v).then(function(v2) {
|
|
2341
|
-
|
|
2341
|
+
resolve14({ value: v2, done: d });
|
|
2342
2342
|
}, reject);
|
|
2343
2343
|
}
|
|
2344
2344
|
}
|
|
@@ -2863,7 +2863,7 @@ function of() {
|
|
|
2863
2863
|
}
|
|
2864
2864
|
function lastValueFrom(source2, config2) {
|
|
2865
2865
|
var hasConfig = typeof config2 === "object";
|
|
2866
|
-
return new Promise(function(
|
|
2866
|
+
return new Promise(function(resolve14, reject) {
|
|
2867
2867
|
var _hasValue = false;
|
|
2868
2868
|
var _value;
|
|
2869
2869
|
source2.subscribe({
|
|
@@ -2874,9 +2874,9 @@ function lastValueFrom(source2, config2) {
|
|
|
2874
2874
|
error: reject,
|
|
2875
2875
|
complete: function() {
|
|
2876
2876
|
if (_hasValue) {
|
|
2877
|
-
|
|
2877
|
+
resolve14(_value);
|
|
2878
2878
|
} else if (hasConfig) {
|
|
2879
|
-
|
|
2879
|
+
resolve14(config2.defaultValue);
|
|
2880
2880
|
} else {
|
|
2881
2881
|
reject(new EmptyError());
|
|
2882
2882
|
}
|
|
@@ -2886,16 +2886,16 @@ function lastValueFrom(source2, config2) {
|
|
|
2886
2886
|
}
|
|
2887
2887
|
function firstValueFrom(source2, config2) {
|
|
2888
2888
|
var hasConfig = typeof config2 === "object";
|
|
2889
|
-
return new Promise(function(
|
|
2889
|
+
return new Promise(function(resolve14, reject) {
|
|
2890
2890
|
var subscriber = new SafeSubscriber({
|
|
2891
2891
|
next: function(value) {
|
|
2892
|
-
|
|
2892
|
+
resolve14(value);
|
|
2893
2893
|
subscriber.unsubscribe();
|
|
2894
2894
|
},
|
|
2895
2895
|
error: reject,
|
|
2896
2896
|
complete: function() {
|
|
2897
2897
|
if (hasConfig) {
|
|
2898
|
-
|
|
2898
|
+
resolve14(config2.defaultValue);
|
|
2899
2899
|
} else {
|
|
2900
2900
|
reject(new EmptyError());
|
|
2901
2901
|
}
|
|
@@ -3934,7 +3934,7 @@ var init_rxjs = __esm({
|
|
|
3934
3934
|
Observable2.prototype.forEach = function(next, promiseCtor) {
|
|
3935
3935
|
var _this = this;
|
|
3936
3936
|
promiseCtor = getPromiseCtor(promiseCtor);
|
|
3937
|
-
return new promiseCtor(function(
|
|
3937
|
+
return new promiseCtor(function(resolve14, reject) {
|
|
3938
3938
|
var subscriber = new SafeSubscriber({
|
|
3939
3939
|
next: function(value) {
|
|
3940
3940
|
try {
|
|
@@ -3945,7 +3945,7 @@ var init_rxjs = __esm({
|
|
|
3945
3945
|
}
|
|
3946
3946
|
},
|
|
3947
3947
|
error: reject,
|
|
3948
|
-
complete:
|
|
3948
|
+
complete: resolve14
|
|
3949
3949
|
});
|
|
3950
3950
|
_this.subscribe(subscriber);
|
|
3951
3951
|
});
|
|
@@ -3967,14 +3967,14 @@ var init_rxjs = __esm({
|
|
|
3967
3967
|
Observable2.prototype.toPromise = function(promiseCtor) {
|
|
3968
3968
|
var _this = this;
|
|
3969
3969
|
promiseCtor = getPromiseCtor(promiseCtor);
|
|
3970
|
-
return new promiseCtor(function(
|
|
3970
|
+
return new promiseCtor(function(resolve14, reject) {
|
|
3971
3971
|
var value;
|
|
3972
3972
|
_this.subscribe(function(x) {
|
|
3973
3973
|
return value = x;
|
|
3974
3974
|
}, function(err) {
|
|
3975
3975
|
return reject(err);
|
|
3976
3976
|
}, function() {
|
|
3977
|
-
return
|
|
3977
|
+
return resolve14(value);
|
|
3978
3978
|
});
|
|
3979
3979
|
});
|
|
3980
3980
|
};
|
|
@@ -6404,8 +6404,8 @@ var init_Deferred = __esm({
|
|
|
6404
6404
|
// SAFETY: This is ensured by #taskPromise.
|
|
6405
6405
|
#resolve;
|
|
6406
6406
|
// TODO: Switch to Promise.withResolvers with Node 22
|
|
6407
|
-
#taskPromise = new Promise((
|
|
6408
|
-
this.#resolve =
|
|
6407
|
+
#taskPromise = new Promise((resolve14) => {
|
|
6408
|
+
this.#resolve = resolve14;
|
|
6409
6409
|
});
|
|
6410
6410
|
#timeoutId;
|
|
6411
6411
|
#timeoutError;
|
|
@@ -6495,12 +6495,12 @@ var init_Mutex = __esm({
|
|
|
6495
6495
|
return new _Mutex.Guard(this, onRelease);
|
|
6496
6496
|
}
|
|
6497
6497
|
release() {
|
|
6498
|
-
const
|
|
6499
|
-
if (!
|
|
6498
|
+
const resolve14 = this.#acquirers.shift();
|
|
6499
|
+
if (!resolve14) {
|
|
6500
6500
|
this.#locked = false;
|
|
6501
6501
|
return;
|
|
6502
6502
|
}
|
|
6503
|
-
|
|
6503
|
+
resolve14();
|
|
6504
6504
|
}
|
|
6505
6505
|
};
|
|
6506
6506
|
}
|
|
@@ -8515,12 +8515,12 @@ var init_locators = __esm({
|
|
|
8515
8515
|
}
|
|
8516
8516
|
return defer(() => {
|
|
8517
8517
|
return from(handle.evaluate((element) => {
|
|
8518
|
-
return new Promise((
|
|
8518
|
+
return new Promise((resolve14) => {
|
|
8519
8519
|
window.requestAnimationFrame(() => {
|
|
8520
8520
|
const rect1 = element.getBoundingClientRect();
|
|
8521
8521
|
window.requestAnimationFrame(() => {
|
|
8522
8522
|
const rect2 = element.getBoundingClientRect();
|
|
8523
|
-
|
|
8523
|
+
resolve14([
|
|
8524
8524
|
{
|
|
8525
8525
|
x: rect1.x,
|
|
8526
8526
|
y: rect1.y,
|
|
@@ -10259,9 +10259,9 @@ var init_ElementHandle = __esm({
|
|
|
10259
10259
|
const handle = await this.#asSVGElementHandle();
|
|
10260
10260
|
const target = __addDisposableResource6(env_5, handle && await handle.#getOwnerSVGElement(), false);
|
|
10261
10261
|
return await (target ?? this).evaluate(async (element, threshold) => {
|
|
10262
|
-
const visibleRatio = await new Promise((
|
|
10262
|
+
const visibleRatio = await new Promise((resolve14) => {
|
|
10263
10263
|
const observer = new IntersectionObserver((entries2) => {
|
|
10264
|
-
|
|
10264
|
+
resolve14(entries2[0].intersectionRatio);
|
|
10265
10265
|
observer.disconnect();
|
|
10266
10266
|
});
|
|
10267
10267
|
observer.observe(element);
|
|
@@ -10907,7 +10907,7 @@ var init_Frame = __esm({
|
|
|
10907
10907
|
}
|
|
10908
10908
|
type = type ?? "text/javascript";
|
|
10909
10909
|
return await this.mainRealm().transferHandle(await this.isolatedRealm().evaluateHandle(async ({ url, id, type: type2, content: content2 }) => {
|
|
10910
|
-
return await new Promise((
|
|
10910
|
+
return await new Promise((resolve14, reject) => {
|
|
10911
10911
|
const script = document.createElement("script");
|
|
10912
10912
|
script.type = type2;
|
|
10913
10913
|
script.text = content2;
|
|
@@ -10920,12 +10920,12 @@ var init_Frame = __esm({
|
|
|
10920
10920
|
if (url) {
|
|
10921
10921
|
script.src = url;
|
|
10922
10922
|
script.addEventListener("load", () => {
|
|
10923
|
-
|
|
10923
|
+
resolve14(script);
|
|
10924
10924
|
}, { once: true });
|
|
10925
10925
|
document.head.appendChild(script);
|
|
10926
10926
|
} else {
|
|
10927
10927
|
document.head.appendChild(script);
|
|
10928
|
-
|
|
10928
|
+
resolve14(script);
|
|
10929
10929
|
}
|
|
10930
10930
|
});
|
|
10931
10931
|
}, { ...options, type, content }));
|
|
@@ -10945,7 +10945,7 @@ var init_Frame = __esm({
|
|
|
10945
10945
|
options.content = content;
|
|
10946
10946
|
}
|
|
10947
10947
|
return await this.mainRealm().transferHandle(await this.isolatedRealm().evaluateHandle(async ({ url, content: content2 }) => {
|
|
10948
|
-
return await new Promise((
|
|
10948
|
+
return await new Promise((resolve14, reject) => {
|
|
10949
10949
|
let element;
|
|
10950
10950
|
if (!url) {
|
|
10951
10951
|
element = document.createElement("style");
|
|
@@ -10957,7 +10957,7 @@ var init_Frame = __esm({
|
|
|
10957
10957
|
element = link;
|
|
10958
10958
|
}
|
|
10959
10959
|
element.addEventListener("load", () => {
|
|
10960
|
-
|
|
10960
|
+
resolve14(element);
|
|
10961
10961
|
}, { once: true });
|
|
10962
10962
|
element.addEventListener("error", (event) => {
|
|
10963
10963
|
reject(new Error(event.message ?? "Could not load style"));
|
|
@@ -12696,9 +12696,9 @@ var init_Page = __esm({
|
|
|
12696
12696
|
++this.#screencastSessionCount;
|
|
12697
12697
|
if (!this.#startScreencastPromise) {
|
|
12698
12698
|
this.#startScreencastPromise = this.mainFrame().client.send("Page.startScreencast", { format: "png" }).then(() => {
|
|
12699
|
-
return new Promise((
|
|
12699
|
+
return new Promise((resolve14) => {
|
|
12700
12700
|
return this.mainFrame().client.once("Page.screencastFrame", () => {
|
|
12701
|
-
return
|
|
12701
|
+
return resolve14();
|
|
12702
12702
|
});
|
|
12703
12703
|
});
|
|
12704
12704
|
});
|
|
@@ -16016,11 +16016,11 @@ function addPageBinding(type, name, prefix) {
|
|
|
16016
16016
|
return value instanceof Node;
|
|
16017
16017
|
})
|
|
16018
16018
|
}));
|
|
16019
|
-
return new Promise((
|
|
16019
|
+
return new Promise((resolve14, reject) => {
|
|
16020
16020
|
callPuppeteer.callbacks.set(seq, {
|
|
16021
16021
|
resolve(value) {
|
|
16022
16022
|
callPuppeteer.args.delete(seq);
|
|
16023
|
-
|
|
16023
|
+
resolve14(value);
|
|
16024
16024
|
},
|
|
16025
16025
|
reject(value) {
|
|
16026
16026
|
callPuppeteer.args.delete(seq);
|
|
@@ -19683,8 +19683,8 @@ var init_Input2 = __esm({
|
|
|
19683
19683
|
if (typeof delay === "number") {
|
|
19684
19684
|
await Promise.all(actions);
|
|
19685
19685
|
actions.length = 0;
|
|
19686
|
-
await new Promise((
|
|
19687
|
-
setTimeout(
|
|
19686
|
+
await new Promise((resolve14) => {
|
|
19687
|
+
setTimeout(resolve14, delay);
|
|
19688
19688
|
});
|
|
19689
19689
|
}
|
|
19690
19690
|
actions.push(this.up({ ...options, clickCount }));
|
|
@@ -19704,9 +19704,9 @@ var init_Input2 = __esm({
|
|
|
19704
19704
|
});
|
|
19705
19705
|
}
|
|
19706
19706
|
async drag(start, target) {
|
|
19707
|
-
const promise = new Promise((
|
|
19707
|
+
const promise = new Promise((resolve14) => {
|
|
19708
19708
|
this.#client.once("Input.dragIntercepted", (event) => {
|
|
19709
|
-
return
|
|
19709
|
+
return resolve14(event.data);
|
|
19710
19710
|
});
|
|
19711
19711
|
});
|
|
19712
19712
|
await this.move(start.x, start.y);
|
|
@@ -19747,8 +19747,8 @@ var init_Input2 = __esm({
|
|
|
19747
19747
|
await this.dragEnter(target, data);
|
|
19748
19748
|
await this.dragOver(target, data);
|
|
19749
19749
|
if (delay) {
|
|
19750
|
-
await new Promise((
|
|
19751
|
-
return setTimeout(
|
|
19750
|
+
await new Promise((resolve14) => {
|
|
19751
|
+
return setTimeout(resolve14, delay);
|
|
19752
19752
|
});
|
|
19753
19753
|
}
|
|
19754
19754
|
await this.drop(target, data);
|
|
@@ -20632,9 +20632,9 @@ var init_Page2 = __esm({
|
|
|
20632
20632
|
async captureHeapSnapshot(options) {
|
|
20633
20633
|
const { createWriteStream: createWriteStream3 } = environment.value.fs;
|
|
20634
20634
|
const stream2 = createWriteStream3(options.path);
|
|
20635
|
-
const streamPromise = new Promise((
|
|
20635
|
+
const streamPromise = new Promise((resolve14, reject) => {
|
|
20636
20636
|
stream2.on("error", reject);
|
|
20637
|
-
stream2.on("finish",
|
|
20637
|
+
stream2.on("finish", resolve14);
|
|
20638
20638
|
});
|
|
20639
20639
|
const client = this.#primaryTargetClient;
|
|
20640
20640
|
await client.send("HeapProfiler.enable");
|
|
@@ -22276,10 +22276,10 @@ var init_BrowserWebSocketTransport = __esm({
|
|
|
22276
22276
|
"../../node_modules/.bun/puppeteer-core@24.40.0/node_modules/puppeteer-core/lib/esm/puppeteer/common/BrowserWebSocketTransport.js"() {
|
|
22277
22277
|
BrowserWebSocketTransport = class _BrowserWebSocketTransport {
|
|
22278
22278
|
static create(url) {
|
|
22279
|
-
return new Promise((
|
|
22279
|
+
return new Promise((resolve14, reject) => {
|
|
22280
22280
|
const ws = new WebSocket(url);
|
|
22281
22281
|
ws.addEventListener("open", () => {
|
|
22282
|
-
return
|
|
22282
|
+
return resolve14(new _BrowserWebSocketTransport(ws));
|
|
22283
22283
|
});
|
|
22284
22284
|
ws.addEventListener("error", reject);
|
|
22285
22285
|
});
|
|
@@ -25201,11 +25201,11 @@ var require_BrowsingContextProcessor = __commonJS({
|
|
|
25201
25201
|
}
|
|
25202
25202
|
const parentCdpClient = context2.cdpTarget.parentCdpClient;
|
|
25203
25203
|
try {
|
|
25204
|
-
const detachedFromTargetPromise = new Promise((
|
|
25204
|
+
const detachedFromTargetPromise = new Promise((resolve14) => {
|
|
25205
25205
|
const onContextDestroyed = (event) => {
|
|
25206
25206
|
if (event.targetId === params.context) {
|
|
25207
25207
|
parentCdpClient.off("Target.detachedFromTarget", onContextDestroyed);
|
|
25208
|
-
|
|
25208
|
+
resolve14();
|
|
25209
25209
|
}
|
|
25210
25210
|
};
|
|
25211
25211
|
parentCdpClient.on("Target.detachedFromTarget", onContextDestroyed);
|
|
@@ -26568,7 +26568,7 @@ var require_ActionDispatcher = __commonJS({
|
|
|
26568
26568
|
}
|
|
26569
26569
|
}
|
|
26570
26570
|
const promises = [
|
|
26571
|
-
new Promise((
|
|
26571
|
+
new Promise((resolve14) => setTimeout(resolve14, this.#tickDuration))
|
|
26572
26572
|
];
|
|
26573
26573
|
for (const option of options) {
|
|
26574
26574
|
promises.push(this.#dispatchAction(option));
|
|
@@ -27169,8 +27169,8 @@ var require_Mutex = __commonJS({
|
|
|
27169
27169
|
acquire() {
|
|
27170
27170
|
const state = { resolved: false };
|
|
27171
27171
|
if (this.#locked) {
|
|
27172
|
-
return new Promise((
|
|
27173
|
-
this.#acquirers.push(() =>
|
|
27172
|
+
return new Promise((resolve14) => {
|
|
27173
|
+
this.#acquirers.push(() => resolve14(this.#release.bind(this, state)));
|
|
27174
27174
|
});
|
|
27175
27175
|
}
|
|
27176
27176
|
this.#locked = true;
|
|
@@ -27181,12 +27181,12 @@ var require_Mutex = __commonJS({
|
|
|
27181
27181
|
throw new Error("Cannot release more than once.");
|
|
27182
27182
|
}
|
|
27183
27183
|
state.resolved = true;
|
|
27184
|
-
const
|
|
27185
|
-
if (!
|
|
27184
|
+
const resolve14 = this.#acquirers.shift();
|
|
27185
|
+
if (!resolve14) {
|
|
27186
27186
|
this.#locked = false;
|
|
27187
27187
|
return;
|
|
27188
27188
|
}
|
|
27189
|
-
|
|
27189
|
+
resolve14();
|
|
27190
27190
|
}
|
|
27191
27191
|
async run(action) {
|
|
27192
27192
|
const release = await this.acquire();
|
|
@@ -28368,8 +28368,8 @@ var require_ChannelProxy = __commonJS({
|
|
|
28368
28368
|
* in the queue.
|
|
28369
28369
|
*/
|
|
28370
28370
|
async getMessage() {
|
|
28371
|
-
const onMessage = queue.length > 0 ? Promise.resolve() : new Promise((
|
|
28372
|
-
queueNonEmptyResolver =
|
|
28371
|
+
const onMessage = queue.length > 0 ? Promise.resolve() : new Promise((resolve14) => {
|
|
28372
|
+
queueNonEmptyResolver = resolve14;
|
|
28373
28373
|
});
|
|
28374
28374
|
await onMessage;
|
|
28375
28375
|
return queue.shift();
|
|
@@ -28474,7 +28474,7 @@ var require_ChannelProxy = __commonJS({
|
|
|
28474
28474
|
functionDeclaration: String((id) => {
|
|
28475
28475
|
const w = window;
|
|
28476
28476
|
if (w[id] === void 0) {
|
|
28477
|
-
return new Promise((
|
|
28477
|
+
return new Promise((resolve14) => w[id] = resolve14);
|
|
28478
28478
|
}
|
|
28479
28479
|
const channelProxy = w[id];
|
|
28480
28480
|
delete w[id];
|
|
@@ -29975,8 +29975,8 @@ var require_Deferred = __commonJS({
|
|
|
29975
29975
|
return this.#result;
|
|
29976
29976
|
}
|
|
29977
29977
|
constructor() {
|
|
29978
|
-
this.#promise = new Promise((
|
|
29979
|
-
this.#resolve =
|
|
29978
|
+
this.#promise = new Promise((resolve14, reject) => {
|
|
29979
|
+
this.#resolve = resolve14;
|
|
29980
29980
|
this.#reject = reject;
|
|
29981
29981
|
});
|
|
29982
29982
|
this.#promise.catch((_error) => {
|
|
@@ -34820,11 +34820,11 @@ var require_BrowsingContextStorage = __commonJS({
|
|
|
34820
34820
|
if (this.#contexts.has(browsingContextId)) {
|
|
34821
34821
|
return Promise.resolve(this.getContext(browsingContextId));
|
|
34822
34822
|
}
|
|
34823
|
-
return new Promise((
|
|
34823
|
+
return new Promise((resolve14) => {
|
|
34824
34824
|
const listener = (event) => {
|
|
34825
34825
|
if (event.browsingContext.id === browsingContextId) {
|
|
34826
34826
|
this.#eventEmitter.off("added", listener);
|
|
34827
|
-
|
|
34827
|
+
resolve14(event.browsingContext);
|
|
34828
34828
|
}
|
|
34829
34829
|
};
|
|
34830
34830
|
this.#eventEmitter.on("added", listener);
|
|
@@ -38406,8 +38406,8 @@ var init_ExposedFunction = __esm({
|
|
|
38406
38406
|
const functionDeclaration = stringifyFunction(interpolateFunction((callback) => {
|
|
38407
38407
|
Object.assign(globalThis, {
|
|
38408
38408
|
[PLACEHOLDER("name")]: function(...args) {
|
|
38409
|
-
return new Promise((
|
|
38410
|
-
callback([
|
|
38409
|
+
return new Promise((resolve14, reject) => {
|
|
38410
|
+
callback([resolve14, reject, args]);
|
|
38411
38411
|
});
|
|
38412
38412
|
}
|
|
38413
38413
|
});
|
|
@@ -38495,8 +38495,8 @@ var init_ExposedFunction = __esm({
|
|
|
38495
38495
|
return;
|
|
38496
38496
|
}
|
|
38497
38497
|
try {
|
|
38498
|
-
await dataHandle.evaluate(([
|
|
38499
|
-
|
|
38498
|
+
await dataHandle.evaluate(([resolve14], result2) => {
|
|
38499
|
+
resolve14(result2);
|
|
38500
38500
|
}, result);
|
|
38501
38501
|
} catch (error) {
|
|
38502
38502
|
debugError(error);
|
|
@@ -46577,7 +46577,7 @@ var init_NodeWebSocketTransport = __esm({
|
|
|
46577
46577
|
init_version();
|
|
46578
46578
|
NodeWebSocketTransport = class _NodeWebSocketTransport {
|
|
46579
46579
|
static create(url, headers) {
|
|
46580
|
-
return new Promise((
|
|
46580
|
+
return new Promise((resolve14, reject) => {
|
|
46581
46581
|
const ws = new wrapper_default(url, [], {
|
|
46582
46582
|
followRedirects: true,
|
|
46583
46583
|
perMessageDeflate: false,
|
|
@@ -46590,7 +46590,7 @@ var init_NodeWebSocketTransport = __esm({
|
|
|
46590
46590
|
}
|
|
46591
46591
|
});
|
|
46592
46592
|
ws.addEventListener("open", () => {
|
|
46593
|
-
return
|
|
46593
|
+
return resolve14(new _NodeWebSocketTransport(ws));
|
|
46594
46594
|
});
|
|
46595
46595
|
ws.addEventListener("error", reject);
|
|
46596
46596
|
});
|
|
@@ -49651,8 +49651,8 @@ var require_helpers = __commonJS({
|
|
|
49651
49651
|
function req(url, opts = {}) {
|
|
49652
49652
|
const href = typeof url === "string" ? url : url.href;
|
|
49653
49653
|
const req2 = (href.startsWith("https:") ? https2 : http2).request(url, opts);
|
|
49654
|
-
const promise = new Promise((
|
|
49655
|
-
req2.once("response",
|
|
49654
|
+
const promise = new Promise((resolve14, reject) => {
|
|
49655
|
+
req2.once("response", resolve14).once("error", reject).end();
|
|
49656
49656
|
});
|
|
49657
49657
|
req2.then = promise.then.bind(promise);
|
|
49658
49658
|
return req2;
|
|
@@ -50029,7 +50029,7 @@ var require_parse_proxy_response = __commonJS({
|
|
|
50029
50029
|
var debug_1 = __importDefault2(require_src());
|
|
50030
50030
|
var debug6 = (0, debug_1.default)("https-proxy-agent:parse-proxy-response");
|
|
50031
50031
|
function parseProxyResponse(socket) {
|
|
50032
|
-
return new Promise((
|
|
50032
|
+
return new Promise((resolve14, reject) => {
|
|
50033
50033
|
let buffersLength = 0;
|
|
50034
50034
|
const buffers = [];
|
|
50035
50035
|
function read() {
|
|
@@ -50095,7 +50095,7 @@ var require_parse_proxy_response = __commonJS({
|
|
|
50095
50095
|
}
|
|
50096
50096
|
debug6("got proxy server response: %o %o", firstLine, headers);
|
|
50097
50097
|
cleanup();
|
|
50098
|
-
|
|
50098
|
+
resolve14({
|
|
50099
50099
|
connect: {
|
|
50100
50100
|
statusCode,
|
|
50101
50101
|
statusText,
|
|
@@ -53353,11 +53353,11 @@ var require_socksclient = __commonJS({
|
|
|
53353
53353
|
"use strict";
|
|
53354
53354
|
var __awaiter3 = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
53355
53355
|
function adopt(value) {
|
|
53356
|
-
return value instanceof P ? value : new P(function(
|
|
53357
|
-
|
|
53356
|
+
return value instanceof P ? value : new P(function(resolve14) {
|
|
53357
|
+
resolve14(value);
|
|
53358
53358
|
});
|
|
53359
53359
|
}
|
|
53360
|
-
return new (P || (P = Promise))(function(
|
|
53360
|
+
return new (P || (P = Promise))(function(resolve14, reject) {
|
|
53361
53361
|
function fulfilled(value) {
|
|
53362
53362
|
try {
|
|
53363
53363
|
step(generator.next(value));
|
|
@@ -53373,7 +53373,7 @@ var require_socksclient = __commonJS({
|
|
|
53373
53373
|
}
|
|
53374
53374
|
}
|
|
53375
53375
|
function step(result) {
|
|
53376
|
-
result.done ?
|
|
53376
|
+
result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
53377
53377
|
}
|
|
53378
53378
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
53379
53379
|
});
|
|
@@ -53407,13 +53407,13 @@ var require_socksclient = __commonJS({
|
|
|
53407
53407
|
* @returns { Promise }
|
|
53408
53408
|
*/
|
|
53409
53409
|
static createConnection(options, callback) {
|
|
53410
|
-
return new Promise((
|
|
53410
|
+
return new Promise((resolve14, reject) => {
|
|
53411
53411
|
try {
|
|
53412
53412
|
(0, helpers_1.validateSocksClientOptions)(options, ["connect"]);
|
|
53413
53413
|
} catch (err) {
|
|
53414
53414
|
if (typeof callback === "function") {
|
|
53415
53415
|
callback(err);
|
|
53416
|
-
return
|
|
53416
|
+
return resolve14(err);
|
|
53417
53417
|
} else {
|
|
53418
53418
|
return reject(err);
|
|
53419
53419
|
}
|
|
@@ -53424,16 +53424,16 @@ var require_socksclient = __commonJS({
|
|
|
53424
53424
|
client.removeAllListeners();
|
|
53425
53425
|
if (typeof callback === "function") {
|
|
53426
53426
|
callback(null, info);
|
|
53427
|
-
|
|
53427
|
+
resolve14(info);
|
|
53428
53428
|
} else {
|
|
53429
|
-
|
|
53429
|
+
resolve14(info);
|
|
53430
53430
|
}
|
|
53431
53431
|
});
|
|
53432
53432
|
client.once("error", (err) => {
|
|
53433
53433
|
client.removeAllListeners();
|
|
53434
53434
|
if (typeof callback === "function") {
|
|
53435
53435
|
callback(err);
|
|
53436
|
-
|
|
53436
|
+
resolve14(err);
|
|
53437
53437
|
} else {
|
|
53438
53438
|
reject(err);
|
|
53439
53439
|
}
|
|
@@ -53450,13 +53450,13 @@ var require_socksclient = __commonJS({
|
|
|
53450
53450
|
* @returns { Promise }
|
|
53451
53451
|
*/
|
|
53452
53452
|
static createConnectionChain(options, callback) {
|
|
53453
|
-
return new Promise((
|
|
53453
|
+
return new Promise((resolve14, reject) => __awaiter3(this, void 0, void 0, function* () {
|
|
53454
53454
|
try {
|
|
53455
53455
|
(0, helpers_1.validateSocksClientChainOptions)(options);
|
|
53456
53456
|
} catch (err) {
|
|
53457
53457
|
if (typeof callback === "function") {
|
|
53458
53458
|
callback(err);
|
|
53459
|
-
return
|
|
53459
|
+
return resolve14(err);
|
|
53460
53460
|
} else {
|
|
53461
53461
|
return reject(err);
|
|
53462
53462
|
}
|
|
@@ -53482,14 +53482,14 @@ var require_socksclient = __commonJS({
|
|
|
53482
53482
|
}
|
|
53483
53483
|
if (typeof callback === "function") {
|
|
53484
53484
|
callback(null, { socket: sock });
|
|
53485
|
-
|
|
53485
|
+
resolve14({ socket: sock });
|
|
53486
53486
|
} else {
|
|
53487
|
-
|
|
53487
|
+
resolve14({ socket: sock });
|
|
53488
53488
|
}
|
|
53489
53489
|
} catch (err) {
|
|
53490
53490
|
if (typeof callback === "function") {
|
|
53491
53491
|
callback(err);
|
|
53492
|
-
|
|
53492
|
+
resolve14(err);
|
|
53493
53493
|
} else {
|
|
53494
53494
|
reject(err);
|
|
53495
53495
|
}
|
|
@@ -54173,12 +54173,12 @@ var require_dist4 = __commonJS({
|
|
|
54173
54173
|
let { host } = opts;
|
|
54174
54174
|
const { port, lookup: lookupFn = dns.lookup } = opts;
|
|
54175
54175
|
if (shouldLookup) {
|
|
54176
|
-
host = await new Promise((
|
|
54176
|
+
host = await new Promise((resolve14, reject) => {
|
|
54177
54177
|
lookupFn(host, {}, (err, res) => {
|
|
54178
54178
|
if (err) {
|
|
54179
54179
|
reject(err);
|
|
54180
54180
|
} else {
|
|
54181
|
-
|
|
54181
|
+
resolve14(res);
|
|
54182
54182
|
}
|
|
54183
54183
|
});
|
|
54184
54184
|
});
|
|
@@ -55363,7 +55363,7 @@ var require_netUtils = __commonJS({
|
|
|
55363
55363
|
return `${socket.remoteAddress}:${socket.remotePort}`;
|
|
55364
55364
|
}
|
|
55365
55365
|
function upgradeSocket(socket, options) {
|
|
55366
|
-
return new Promise((
|
|
55366
|
+
return new Promise((resolve14, reject) => {
|
|
55367
55367
|
const tlsOptions = Object.assign({}, options, {
|
|
55368
55368
|
socket
|
|
55369
55369
|
});
|
|
@@ -55373,7 +55373,7 @@ var require_netUtils = __commonJS({
|
|
|
55373
55373
|
reject(tlsSocket.authorizationError);
|
|
55374
55374
|
} else {
|
|
55375
55375
|
tlsSocket.removeAllListeners("error");
|
|
55376
|
-
|
|
55376
|
+
resolve14(tlsSocket);
|
|
55377
55377
|
}
|
|
55378
55378
|
}).once("error", (error) => {
|
|
55379
55379
|
reject(error);
|
|
@@ -55468,7 +55468,7 @@ var require_transfer = __commonJS({
|
|
|
55468
55468
|
};
|
|
55469
55469
|
}
|
|
55470
55470
|
function connectForPassiveTransfer(host, port, ftp) {
|
|
55471
|
-
return new Promise((
|
|
55471
|
+
return new Promise((resolve14, reject) => {
|
|
55472
55472
|
let socket = ftp._newSocket();
|
|
55473
55473
|
const handleConnErr = function(err) {
|
|
55474
55474
|
err.message = "Can't open data connection in passive mode: " + err.message;
|
|
@@ -55496,7 +55496,7 @@ var require_transfer = __commonJS({
|
|
|
55496
55496
|
socket.removeListener("error", handleConnErr);
|
|
55497
55497
|
socket.removeListener("timeout", handleTimeout);
|
|
55498
55498
|
ftp.dataSocket = socket;
|
|
55499
|
-
|
|
55499
|
+
resolve14();
|
|
55500
55500
|
});
|
|
55501
55501
|
});
|
|
55502
55502
|
}
|
|
@@ -57865,7 +57865,7 @@ var require_util2 = __commonJS({
|
|
|
57865
57865
|
}
|
|
57866
57866
|
path12 = url.path;
|
|
57867
57867
|
}
|
|
57868
|
-
var
|
|
57868
|
+
var isAbsolute5 = exports.isAbsolute(path12);
|
|
57869
57869
|
var parts = path12.split(/\/+/);
|
|
57870
57870
|
for (var part, up = 0, i = parts.length - 1; i >= 0; i--) {
|
|
57871
57871
|
part = parts[i];
|
|
@@ -57885,7 +57885,7 @@ var require_util2 = __commonJS({
|
|
|
57885
57885
|
}
|
|
57886
57886
|
path12 = parts.join("/");
|
|
57887
57887
|
if (path12 === "") {
|
|
57888
|
-
path12 =
|
|
57888
|
+
path12 = isAbsolute5 ? "/" : ".";
|
|
57889
57889
|
}
|
|
57890
57890
|
if (url) {
|
|
57891
57891
|
url.path = path12;
|
|
@@ -67965,11 +67965,11 @@ function __metadata(metadataKey, metadataValue) {
|
|
|
67965
67965
|
}
|
|
67966
67966
|
function __awaiter2(thisArg, _arguments, P, generator) {
|
|
67967
67967
|
function adopt(value) {
|
|
67968
|
-
return value instanceof P ? value : new P(function(
|
|
67969
|
-
|
|
67968
|
+
return value instanceof P ? value : new P(function(resolve14) {
|
|
67969
|
+
resolve14(value);
|
|
67970
67970
|
});
|
|
67971
67971
|
}
|
|
67972
|
-
return new (P || (P = Promise))(function(
|
|
67972
|
+
return new (P || (P = Promise))(function(resolve14, reject) {
|
|
67973
67973
|
function fulfilled(value) {
|
|
67974
67974
|
try {
|
|
67975
67975
|
step(generator.next(value));
|
|
@@ -67985,7 +67985,7 @@ function __awaiter2(thisArg, _arguments, P, generator) {
|
|
|
67985
67985
|
}
|
|
67986
67986
|
}
|
|
67987
67987
|
function step(result) {
|
|
67988
|
-
result.done ?
|
|
67988
|
+
result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
67989
67989
|
}
|
|
67990
67990
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
67991
67991
|
});
|
|
@@ -68176,14 +68176,14 @@ function __asyncValues2(o) {
|
|
|
68176
68176
|
}, i);
|
|
68177
68177
|
function verb(n) {
|
|
68178
68178
|
i[n] = o[n] && function(v) {
|
|
68179
|
-
return new Promise(function(
|
|
68180
|
-
v = o[n](v), settle(
|
|
68179
|
+
return new Promise(function(resolve14, reject) {
|
|
68180
|
+
v = o[n](v), settle(resolve14, reject, v.done, v.value);
|
|
68181
68181
|
});
|
|
68182
68182
|
};
|
|
68183
68183
|
}
|
|
68184
|
-
function settle(
|
|
68184
|
+
function settle(resolve14, reject, d, v) {
|
|
68185
68185
|
Promise.resolve(v).then(function(v2) {
|
|
68186
|
-
|
|
68186
|
+
resolve14({ value: v2, done: d });
|
|
68187
68187
|
}, reject);
|
|
68188
68188
|
}
|
|
68189
68189
|
}
|
|
@@ -71736,12 +71736,12 @@ var require_util3 = __commonJS({
|
|
|
71736
71736
|
exports.isGMT = exports.dnsLookup = void 0;
|
|
71737
71737
|
var dns_1 = __require("dns");
|
|
71738
71738
|
function dnsLookup(host, opts) {
|
|
71739
|
-
return new Promise((
|
|
71739
|
+
return new Promise((resolve14, reject) => {
|
|
71740
71740
|
(0, dns_1.lookup)(host, opts, (err, res) => {
|
|
71741
71741
|
if (err) {
|
|
71742
71742
|
reject(err);
|
|
71743
71743
|
} else {
|
|
71744
|
-
|
|
71744
|
+
resolve14(res);
|
|
71745
71745
|
}
|
|
71746
71746
|
});
|
|
71747
71747
|
});
|
|
@@ -72106,10 +72106,10 @@ var require_myIpAddress = __commonJS({
|
|
|
72106
72106
|
var ip_1 = require_ip();
|
|
72107
72107
|
var net_1 = __importDefault2(__require("net"));
|
|
72108
72108
|
async function myIpAddress() {
|
|
72109
|
-
return new Promise((
|
|
72109
|
+
return new Promise((resolve14, reject) => {
|
|
72110
72110
|
const socket = net_1.default.connect({ host: "8.8.8.8", port: 53 });
|
|
72111
72111
|
const onError = () => {
|
|
72112
|
-
|
|
72112
|
+
resolve14(ip_1.ip.address());
|
|
72113
72113
|
};
|
|
72114
72114
|
socket.once("error", onError);
|
|
72115
72115
|
socket.once("connect", () => {
|
|
@@ -72117,9 +72117,9 @@ var require_myIpAddress = __commonJS({
|
|
|
72117
72117
|
const addr = socket.address();
|
|
72118
72118
|
socket.destroy();
|
|
72119
72119
|
if (typeof addr === "string") {
|
|
72120
|
-
|
|
72120
|
+
resolve14(addr);
|
|
72121
72121
|
} else if (addr.address) {
|
|
72122
|
-
|
|
72122
|
+
resolve14(addr.address);
|
|
72123
72123
|
} else {
|
|
72124
72124
|
reject(new Error("Expected a `string`"));
|
|
72125
72125
|
}
|
|
@@ -72697,8 +72697,8 @@ var require_deferred_promise = __commonJS({
|
|
|
72697
72697
|
this.context = args.context;
|
|
72698
72698
|
this.owner = args.context.runtime;
|
|
72699
72699
|
this.handle = args.promiseHandle;
|
|
72700
|
-
this.settled = new Promise((
|
|
72701
|
-
this.onSettled =
|
|
72700
|
+
this.settled = new Promise((resolve14) => {
|
|
72701
|
+
this.onSettled = resolve14;
|
|
72702
72702
|
});
|
|
72703
72703
|
this.resolveHandle = args.resolveHandle;
|
|
72704
72704
|
this.rejectHandle = args.rejectHandle;
|
|
@@ -73219,13 +73219,13 @@ var require_context = __commonJS({
|
|
|
73219
73219
|
if (vmResolveResult.error) {
|
|
73220
73220
|
return Promise.resolve(vmResolveResult);
|
|
73221
73221
|
}
|
|
73222
|
-
return new Promise((
|
|
73222
|
+
return new Promise((resolve14) => {
|
|
73223
73223
|
lifetime_1.Scope.withScope((scope) => {
|
|
73224
73224
|
const resolveHandle = scope.manage(this.newFunction("resolve", (value) => {
|
|
73225
|
-
|
|
73225
|
+
resolve14({ value: value && value.dup() });
|
|
73226
73226
|
}));
|
|
73227
73227
|
const rejectHandle = scope.manage(this.newFunction("reject", (error) => {
|
|
73228
|
-
|
|
73228
|
+
resolve14({ error: error && error.dup() });
|
|
73229
73229
|
}));
|
|
73230
73230
|
const promiseHandle = scope.manage(vmResolveResult.value);
|
|
73231
73231
|
const promiseThenHandle = scope.manage(this.getProp(promiseHandle, "then"));
|
|
@@ -75600,13 +75600,13 @@ import * as http from "node:http";
|
|
|
75600
75600
|
import * as https from "node:https";
|
|
75601
75601
|
import { URL as URL2, urlToHttpOptions } from "node:url";
|
|
75602
75602
|
function headHttpRequest(url) {
|
|
75603
|
-
return new Promise((
|
|
75603
|
+
return new Promise((resolve14) => {
|
|
75604
75604
|
const request3 = httpRequest(url, "HEAD", (response) => {
|
|
75605
75605
|
response.resume();
|
|
75606
|
-
|
|
75606
|
+
resolve14(response.statusCode === 200);
|
|
75607
75607
|
}, false);
|
|
75608
75608
|
request3.on("error", () => {
|
|
75609
|
-
|
|
75609
|
+
resolve14(false);
|
|
75610
75610
|
});
|
|
75611
75611
|
});
|
|
75612
75612
|
}
|
|
@@ -75634,7 +75634,7 @@ function httpRequest(url, method, response, keepAlive = true) {
|
|
|
75634
75634
|
return request3;
|
|
75635
75635
|
}
|
|
75636
75636
|
function downloadFile(url, destinationPath, progressCallback) {
|
|
75637
|
-
return new Promise((
|
|
75637
|
+
return new Promise((resolve14, reject) => {
|
|
75638
75638
|
let downloadedBytes = 0;
|
|
75639
75639
|
let totalBytes = 0;
|
|
75640
75640
|
function onData(chunk) {
|
|
@@ -75650,7 +75650,7 @@ function downloadFile(url, destinationPath, progressCallback) {
|
|
|
75650
75650
|
}
|
|
75651
75651
|
const file = createWriteStream(destinationPath);
|
|
75652
75652
|
file.on("close", () => {
|
|
75653
|
-
return
|
|
75653
|
+
return resolve14();
|
|
75654
75654
|
});
|
|
75655
75655
|
file.on("error", (error) => {
|
|
75656
75656
|
return reject(error);
|
|
@@ -75675,7 +75675,7 @@ async function getJSON(url) {
|
|
|
75675
75675
|
}
|
|
75676
75676
|
}
|
|
75677
75677
|
function getText3(url) {
|
|
75678
|
-
return new Promise((
|
|
75678
|
+
return new Promise((resolve14, reject) => {
|
|
75679
75679
|
const request3 = httpRequest(url, "GET", (response) => {
|
|
75680
75680
|
let data = "";
|
|
75681
75681
|
if (response.statusCode && response.statusCode >= 400) {
|
|
@@ -75686,7 +75686,7 @@ function getText3(url) {
|
|
|
75686
75686
|
});
|
|
75687
75687
|
response.on("end", () => {
|
|
75688
75688
|
try {
|
|
75689
|
-
return
|
|
75689
|
+
return resolve14(String(data));
|
|
75690
75690
|
} catch {
|
|
75691
75691
|
return reject(new Error(`Failed to read text response from ${url}`));
|
|
75692
75692
|
}
|
|
@@ -77078,7 +77078,7 @@ var init_launch = __esm({
|
|
|
77078
77078
|
if (opts.onExit) {
|
|
77079
77079
|
this.#onExitHook = opts.onExit;
|
|
77080
77080
|
}
|
|
77081
|
-
this.#browserProcessExiting = new Promise((
|
|
77081
|
+
this.#browserProcessExiting = new Promise((resolve14, reject) => {
|
|
77082
77082
|
this.#browserProcess.once("exit", async () => {
|
|
77083
77083
|
debugLaunch(`Browser process ${this.#browserProcess.pid} onExit`);
|
|
77084
77084
|
this.#clearListeners();
|
|
@@ -77089,7 +77089,7 @@ var init_launch = __esm({
|
|
|
77089
77089
|
reject(err);
|
|
77090
77090
|
return;
|
|
77091
77091
|
}
|
|
77092
|
-
|
|
77092
|
+
resolve14();
|
|
77093
77093
|
});
|
|
77094
77094
|
});
|
|
77095
77095
|
}
|
|
@@ -77205,7 +77205,7 @@ Error cause: ${isErrorLike2(error) ? error.stack : error}`);
|
|
|
77205
77205
|
return [...this.#logs];
|
|
77206
77206
|
}
|
|
77207
77207
|
waitForLineOutput(regex, timeout2 = 0) {
|
|
77208
|
-
return new Promise((
|
|
77208
|
+
return new Promise((resolve14, reject) => {
|
|
77209
77209
|
const onClose = (errorOrCode) => {
|
|
77210
77210
|
cleanup();
|
|
77211
77211
|
reject(new Error([
|
|
@@ -77241,7 +77241,7 @@ Error cause: ${isErrorLike2(error) ? error.stack : error}`);
|
|
|
77241
77241
|
return;
|
|
77242
77242
|
}
|
|
77243
77243
|
cleanup();
|
|
77244
|
-
|
|
77244
|
+
resolve14(match2[1]);
|
|
77245
77245
|
}
|
|
77246
77246
|
});
|
|
77247
77247
|
}
|
|
@@ -77710,7 +77710,7 @@ var require_get_stream = __commonJS({
|
|
|
77710
77710
|
};
|
|
77711
77711
|
const { maxBuffer } = options;
|
|
77712
77712
|
let stream2;
|
|
77713
|
-
await new Promise((
|
|
77713
|
+
await new Promise((resolve14, reject) => {
|
|
77714
77714
|
const rejectPromise = (error) => {
|
|
77715
77715
|
if (error && stream2.getBufferedLength() <= BufferConstants.MAX_LENGTH) {
|
|
77716
77716
|
error.bufferedData = stream2.getBufferedValue();
|
|
@@ -77722,7 +77722,7 @@ var require_get_stream = __commonJS({
|
|
|
77722
77722
|
rejectPromise(error);
|
|
77723
77723
|
return;
|
|
77724
77724
|
}
|
|
77725
|
-
|
|
77725
|
+
resolve14();
|
|
77726
77726
|
});
|
|
77727
77727
|
stream2.on("data", () => {
|
|
77728
77728
|
if (stream2.getBufferedLength() > maxBuffer) {
|
|
@@ -79011,7 +79011,7 @@ var require_extract_zip = __commonJS({
|
|
|
79011
79011
|
debug6("opening", this.zipPath, "with opts", this.opts);
|
|
79012
79012
|
this.zipfile = await openZip(this.zipPath, { lazyEntries: true });
|
|
79013
79013
|
this.canceled = false;
|
|
79014
|
-
return new Promise((
|
|
79014
|
+
return new Promise((resolve14, reject) => {
|
|
79015
79015
|
this.zipfile.on("error", (err) => {
|
|
79016
79016
|
this.canceled = true;
|
|
79017
79017
|
reject(err);
|
|
@@ -79020,7 +79020,7 @@ var require_extract_zip = __commonJS({
|
|
|
79020
79020
|
this.zipfile.on("close", () => {
|
|
79021
79021
|
if (!this.canceled) {
|
|
79022
79022
|
debug6("zip extraction complete");
|
|
79023
|
-
|
|
79023
|
+
resolve14();
|
|
79024
79024
|
}
|
|
79025
79025
|
});
|
|
79026
79026
|
this.zipfile.on("entry", async (entry) => {
|
|
@@ -80277,8 +80277,8 @@ var require_streamx = __commonJS({
|
|
|
80277
80277
|
return this;
|
|
80278
80278
|
},
|
|
80279
80279
|
next() {
|
|
80280
|
-
return new Promise(function(
|
|
80281
|
-
promiseResolve =
|
|
80280
|
+
return new Promise(function(resolve14, reject) {
|
|
80281
|
+
promiseResolve = resolve14;
|
|
80282
80282
|
promiseReject = reject;
|
|
80283
80283
|
const data = stream2.read();
|
|
80284
80284
|
if (data !== null) ondata(data);
|
|
@@ -80308,11 +80308,11 @@ var require_streamx = __commonJS({
|
|
|
80308
80308
|
}
|
|
80309
80309
|
function destroy(err) {
|
|
80310
80310
|
stream2.destroy(err);
|
|
80311
|
-
return new Promise((
|
|
80312
|
-
if (stream2._duplexState & DESTROYED) return
|
|
80311
|
+
return new Promise((resolve14, reject) => {
|
|
80312
|
+
if (stream2._duplexState & DESTROYED) return resolve14({ value: void 0, done: true });
|
|
80313
80313
|
stream2.once("close", function() {
|
|
80314
80314
|
if (err) reject(err);
|
|
80315
|
-
else
|
|
80315
|
+
else resolve14({ value: void 0, done: true });
|
|
80316
80316
|
});
|
|
80317
80317
|
});
|
|
80318
80318
|
}
|
|
@@ -80356,8 +80356,8 @@ var require_streamx = __commonJS({
|
|
|
80356
80356
|
const writes = pending + (ws._duplexState & WRITE_WRITING ? 1 : 0);
|
|
80357
80357
|
if (writes === 0) return Promise.resolve(true);
|
|
80358
80358
|
if (state.drains === null) state.drains = [];
|
|
80359
|
-
return new Promise((
|
|
80360
|
-
state.drains.push({ writes, resolve:
|
|
80359
|
+
return new Promise((resolve14) => {
|
|
80360
|
+
state.drains.push({ writes, resolve: resolve14 });
|
|
80361
80361
|
});
|
|
80362
80362
|
}
|
|
80363
80363
|
write(data) {
|
|
@@ -80462,10 +80462,10 @@ var require_streamx = __commonJS({
|
|
|
80462
80462
|
cb(null);
|
|
80463
80463
|
}
|
|
80464
80464
|
function pipelinePromise(...streams) {
|
|
80465
|
-
return new Promise((
|
|
80465
|
+
return new Promise((resolve14, reject) => {
|
|
80466
80466
|
return pipeline(...streams, (err) => {
|
|
80467
80467
|
if (err) return reject(err);
|
|
80468
|
-
|
|
80468
|
+
resolve14();
|
|
80469
80469
|
});
|
|
80470
80470
|
});
|
|
80471
80471
|
}
|
|
@@ -81120,16 +81120,16 @@ var require_extract = __commonJS({
|
|
|
81120
81120
|
entryCallback = null;
|
|
81121
81121
|
cb(err);
|
|
81122
81122
|
}
|
|
81123
|
-
function onnext(
|
|
81123
|
+
function onnext(resolve14, reject) {
|
|
81124
81124
|
if (error) {
|
|
81125
81125
|
return reject(error);
|
|
81126
81126
|
}
|
|
81127
81127
|
if (entryStream) {
|
|
81128
|
-
|
|
81128
|
+
resolve14({ value: entryStream, done: false });
|
|
81129
81129
|
entryStream = null;
|
|
81130
81130
|
return;
|
|
81131
81131
|
}
|
|
81132
|
-
promiseResolve =
|
|
81132
|
+
promiseResolve = resolve14;
|
|
81133
81133
|
promiseReject = reject;
|
|
81134
81134
|
consumeCallback(null);
|
|
81135
81135
|
if (extract._finished && promiseResolve) {
|
|
@@ -81157,11 +81157,11 @@ var require_extract = __commonJS({
|
|
|
81157
81157
|
function destroy(err) {
|
|
81158
81158
|
extract.destroy(err);
|
|
81159
81159
|
consumeCallback(err);
|
|
81160
|
-
return new Promise((
|
|
81161
|
-
if (extract.destroyed) return
|
|
81160
|
+
return new Promise((resolve14, reject) => {
|
|
81161
|
+
if (extract.destroyed) return resolve14({ value: void 0, done: true });
|
|
81162
81162
|
extract.once("close", function() {
|
|
81163
81163
|
if (err) reject(err);
|
|
81164
|
-
else
|
|
81164
|
+
else resolve14({ value: void 0, done: true });
|
|
81165
81165
|
});
|
|
81166
81166
|
});
|
|
81167
81167
|
}
|
|
@@ -84930,13 +84930,13 @@ function usage(yargs, shim3) {
|
|
|
84930
84930
|
};
|
|
84931
84931
|
self2.stringifiedValues = function stringifiedValues(values, separator) {
|
|
84932
84932
|
let string = "";
|
|
84933
|
-
const
|
|
84933
|
+
const sep2 = separator || ", ";
|
|
84934
84934
|
const array = [].concat(values);
|
|
84935
84935
|
if (!values || !array.length)
|
|
84936
84936
|
return string;
|
|
84937
84937
|
array.forEach((value) => {
|
|
84938
84938
|
if (string.length)
|
|
84939
|
-
string +=
|
|
84939
|
+
string += sep2;
|
|
84940
84940
|
string += JSON.stringify(value);
|
|
84941
84941
|
});
|
|
84942
84942
|
return string;
|
|
@@ -86137,12 +86137,12 @@ var init_yargs_factory = __esm({
|
|
|
86137
86137
|
async getCompletion(args, done) {
|
|
86138
86138
|
argsert("<array> [function]", [args, done], arguments.length);
|
|
86139
86139
|
if (!done) {
|
|
86140
|
-
return new Promise((
|
|
86140
|
+
return new Promise((resolve14, reject) => {
|
|
86141
86141
|
__classPrivateFieldGet2(this, _YargsInstance_completion, "f").getCompletion(args, (err, completions) => {
|
|
86142
86142
|
if (err)
|
|
86143
86143
|
reject(err);
|
|
86144
86144
|
else
|
|
86145
|
-
|
|
86145
|
+
resolve14(completions);
|
|
86146
86146
|
});
|
|
86147
86147
|
});
|
|
86148
86148
|
} else {
|
|
@@ -88943,8 +88943,8 @@ var init_ScreenRecorder = __esm({
|
|
|
88943
88943
|
static {
|
|
88944
88944
|
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
88945
88945
|
__esDecorate23(this, _private_writeFrame_descriptor = { value: __setFunctionName6(async function(buffer) {
|
|
88946
|
-
const error = await new Promise((
|
|
88947
|
-
this.#process.stdin.write(buffer,
|
|
88946
|
+
const error = await new Promise((resolve14) => {
|
|
88947
|
+
this.#process.stdin.write(buffer, resolve14);
|
|
88948
88948
|
});
|
|
88949
88949
|
if (error) {
|
|
88950
88950
|
console.log(`ffmpeg failed to write: ${error.message}.`);
|
|
@@ -89134,8 +89134,8 @@ var init_ScreenRecorder = __esm({
|
|
|
89134
89134
|
const [buffer, timestamp] = await this.#lastFrame;
|
|
89135
89135
|
await Promise.all(Array(Math.max(1, Math.round(this.#fps * (performance.now() - timestamp) / 1e3))).fill(buffer).map(this.#writeFrame.bind(this)));
|
|
89136
89136
|
this.#process.stdin.end();
|
|
89137
|
-
await new Promise((
|
|
89138
|
-
this.#process.once("close",
|
|
89137
|
+
await new Promise((resolve14) => {
|
|
89138
|
+
this.#process.once("close", resolve14);
|
|
89139
89139
|
});
|
|
89140
89140
|
}
|
|
89141
89141
|
/**
|
|
@@ -93033,8 +93033,8 @@ var CustomElementRegistry = class {
|
|
|
93033
93033
|
} : (element) => element.localName === localName;
|
|
93034
93034
|
registry.set(localName, { Class, check });
|
|
93035
93035
|
if (waiting.has(localName)) {
|
|
93036
|
-
for (const
|
|
93037
|
-
|
|
93036
|
+
for (const resolve14 of waiting.get(localName))
|
|
93037
|
+
resolve14(Class);
|
|
93038
93038
|
waiting.delete(localName);
|
|
93039
93039
|
}
|
|
93040
93040
|
ownerDocument.querySelectorAll(
|
|
@@ -93074,13 +93074,13 @@ var CustomElementRegistry = class {
|
|
|
93074
93074
|
*/
|
|
93075
93075
|
whenDefined(localName) {
|
|
93076
93076
|
const { registry, waiting } = this;
|
|
93077
|
-
return new Promise((
|
|
93077
|
+
return new Promise((resolve14) => {
|
|
93078
93078
|
if (registry.has(localName))
|
|
93079
|
-
|
|
93079
|
+
resolve14(registry.get(localName).Class);
|
|
93080
93080
|
else {
|
|
93081
93081
|
if (!waiting.has(localName))
|
|
93082
93082
|
waiting.set(localName, []);
|
|
93083
|
-
waiting.get(localName).push(
|
|
93083
|
+
waiting.get(localName).push(resolve14);
|
|
93084
93084
|
}
|
|
93085
93085
|
});
|
|
93086
93086
|
}
|
|
@@ -98730,7 +98730,7 @@ function resolveConfig(overrides) {
|
|
|
98730
98730
|
hdr: (() => {
|
|
98731
98731
|
const raw2 = env2("PRODUCER_HDR_TRANSFER");
|
|
98732
98732
|
if (raw2 === "hlg" || raw2 === "pq") return { transfer: raw2 };
|
|
98733
|
-
return
|
|
98733
|
+
return false;
|
|
98734
98734
|
})(),
|
|
98735
98735
|
hdrAutoDetect: envBool("PRODUCER_HDR_AUTO_DETECT", DEFAULT_CONFIG.hdrAutoDetect),
|
|
98736
98736
|
audioGain: envNum("PRODUCER_AUDIO_GAIN", DEFAULT_CONFIG.audioGain),
|
|
@@ -101132,7 +101132,8 @@ async function injectVideoFramesBatch(page, updates) {
|
|
|
101132
101132
|
let img = video.nextElementSibling;
|
|
101133
101133
|
const isNewImage = !img || !img.classList.contains("__render_frame__");
|
|
101134
101134
|
const computedStyle = window.getComputedStyle(video);
|
|
101135
|
-
const
|
|
101135
|
+
const opacityParsed = parseFloat(computedStyle.opacity);
|
|
101136
|
+
const computedOpacity = Number.isNaN(opacityParsed) ? 1 : opacityParsed;
|
|
101136
101137
|
const sourceIsStatic = !computedStyle.position || computedStyle.position === "static";
|
|
101137
101138
|
if (isNewImage) {
|
|
101138
101139
|
img = document.createElement("img");
|
|
@@ -101178,7 +101179,6 @@ async function injectVideoFramesBatch(page, updates) {
|
|
|
101178
101179
|
img.style.opacity = String(computedOpacity);
|
|
101179
101180
|
img.style.visibility = "visible";
|
|
101180
101181
|
video.style.setProperty("visibility", "hidden", "important");
|
|
101181
|
-
video.style.setProperty("opacity", "0", "important");
|
|
101182
101182
|
video.style.setProperty("pointer-events", "none", "important");
|
|
101183
101183
|
}
|
|
101184
101184
|
if (pendingDecodes.length > 0) {
|
|
@@ -101205,7 +101205,6 @@ async function syncVideoFrameVisibility(page, activeVideoIds) {
|
|
|
101205
101205
|
} else {
|
|
101206
101206
|
video.style.removeProperty("display");
|
|
101207
101207
|
video.style.setProperty("visibility", "hidden", "important");
|
|
101208
|
-
video.style.setProperty("opacity", "0", "important");
|
|
101209
101208
|
video.style.setProperty("pointer-events", "none", "important");
|
|
101210
101209
|
if (hasImg) {
|
|
101211
101210
|
img.style.visibility = "hidden";
|
|
@@ -101296,7 +101295,7 @@ async function pollPageExpression(page, expression, timeoutMs, intervalMs = 100)
|
|
|
101296
101295
|
while (Date.now() < deadline) {
|
|
101297
101296
|
const ready = Boolean(await page.evaluate(expression));
|
|
101298
101297
|
if (ready) return true;
|
|
101299
|
-
await new Promise((
|
|
101298
|
+
await new Promise((resolve14) => setTimeout(resolve14, intervalMs));
|
|
101300
101299
|
}
|
|
101301
101300
|
return Boolean(await page.evaluate(expression));
|
|
101302
101301
|
}
|
|
@@ -101527,9 +101526,15 @@ async function captureFrameToBuffer(session, frameIndex, time) {
|
|
|
101527
101526
|
return { buffer, captureTimeMs };
|
|
101528
101527
|
}
|
|
101529
101528
|
async function closeCaptureSession(session) {
|
|
101530
|
-
if (session.
|
|
101531
|
-
|
|
101532
|
-
|
|
101529
|
+
if (!session.pageReleased && session.page) {
|
|
101530
|
+
await session.page.close().catch(() => {
|
|
101531
|
+
});
|
|
101532
|
+
session.pageReleased = true;
|
|
101533
|
+
}
|
|
101534
|
+
if (!session.browserReleased && session.browser) {
|
|
101535
|
+
await releaseBrowser(session.browser, session.config);
|
|
101536
|
+
session.browserReleased = true;
|
|
101537
|
+
}
|
|
101533
101538
|
session.isInitialized = false;
|
|
101534
101539
|
}
|
|
101535
101540
|
function prepareCaptureSessionForReuse(session, outputDir, onBeforeCapture) {
|
|
@@ -101573,7 +101578,7 @@ import { join as join6, dirname as dirname5 } from "path";
|
|
|
101573
101578
|
// ../engine/src/utils/gpuEncoder.ts
|
|
101574
101579
|
import { spawn as spawn3 } from "child_process";
|
|
101575
101580
|
async function detectGpuEncoder() {
|
|
101576
|
-
return new Promise((
|
|
101581
|
+
return new Promise((resolve14) => {
|
|
101577
101582
|
const ffmpeg = spawn3("ffmpeg", ["-encoders"], {
|
|
101578
101583
|
stdio: ["pipe", "pipe", "pipe"]
|
|
101579
101584
|
});
|
|
@@ -101582,13 +101587,13 @@ async function detectGpuEncoder() {
|
|
|
101582
101587
|
stdout += data.toString();
|
|
101583
101588
|
});
|
|
101584
101589
|
ffmpeg.on("close", () => {
|
|
101585
|
-
if (stdout.includes("h264_nvenc"))
|
|
101586
|
-
else if (stdout.includes("h264_videotoolbox"))
|
|
101587
|
-
else if (stdout.includes("h264_vaapi"))
|
|
101588
|
-
else if (stdout.includes("h264_qsv"))
|
|
101589
|
-
else
|
|
101590
|
+
if (stdout.includes("h264_nvenc")) resolve14("nvenc");
|
|
101591
|
+
else if (stdout.includes("h264_videotoolbox")) resolve14("videotoolbox");
|
|
101592
|
+
else if (stdout.includes("h264_vaapi")) resolve14("vaapi");
|
|
101593
|
+
else if (stdout.includes("h264_qsv")) resolve14("qsv");
|
|
101594
|
+
else resolve14(null);
|
|
101590
101595
|
});
|
|
101591
|
-
ffmpeg.on("error", () =>
|
|
101596
|
+
ffmpeg.on("error", () => resolve14(null));
|
|
101592
101597
|
});
|
|
101593
101598
|
}
|
|
101594
101599
|
var cachedGpuEncoder = void 0;
|
|
@@ -101613,16 +101618,93 @@ function getGpuEncoderName(encoder, codec) {
|
|
|
101613
101618
|
return codec === "h264" ? "libx264" : "libx265";
|
|
101614
101619
|
}
|
|
101615
101620
|
}
|
|
101621
|
+
var NVENC_PRESET_MAP = {
|
|
101622
|
+
ultrafast: "p1",
|
|
101623
|
+
superfast: "p1",
|
|
101624
|
+
veryfast: "p2",
|
|
101625
|
+
faster: "p3",
|
|
101626
|
+
fast: "p4",
|
|
101627
|
+
medium: "p4",
|
|
101628
|
+
slow: "p5",
|
|
101629
|
+
slower: "p6",
|
|
101630
|
+
veryslow: "p7",
|
|
101631
|
+
placebo: "p7"
|
|
101632
|
+
};
|
|
101633
|
+
var QSV_PRESET_MAP = {
|
|
101634
|
+
ultrafast: "veryfast",
|
|
101635
|
+
superfast: "veryfast",
|
|
101636
|
+
placebo: "veryslow"
|
|
101637
|
+
};
|
|
101638
|
+
function mapPresetForGpuEncoder(encoder, preset) {
|
|
101639
|
+
switch (encoder) {
|
|
101640
|
+
case "nvenc":
|
|
101641
|
+
if (/^p[1-7]$/.test(preset)) return preset;
|
|
101642
|
+
return NVENC_PRESET_MAP[preset] ?? "p4";
|
|
101643
|
+
case "qsv":
|
|
101644
|
+
return QSV_PRESET_MAP[preset] ?? preset;
|
|
101645
|
+
default:
|
|
101646
|
+
return preset;
|
|
101647
|
+
}
|
|
101648
|
+
}
|
|
101649
|
+
|
|
101650
|
+
// ../engine/src/utils/hdr.ts
|
|
101651
|
+
function isHdrColorSpace(cs) {
|
|
101652
|
+
if (!cs) return false;
|
|
101653
|
+
return cs.colorPrimaries.includes("bt2020") || cs.colorSpace.includes("bt2020") || cs.colorTransfer === "smpte2084" || cs.colorTransfer === "arib-std-b67";
|
|
101654
|
+
}
|
|
101655
|
+
function detectTransfer(cs) {
|
|
101656
|
+
if (cs?.colorTransfer === "smpte2084") return "pq";
|
|
101657
|
+
return "hlg";
|
|
101658
|
+
}
|
|
101659
|
+
var DEFAULT_HDR10_MASTERING = {
|
|
101660
|
+
masterDisplay: "G(13250,34500)B(7500,3000)R(34000,16000)WP(15635,16450)L(10000000,1)",
|
|
101661
|
+
maxCll: "1000,400"
|
|
101662
|
+
};
|
|
101663
|
+
function getHdrEncoderColorParams(transfer, mastering = DEFAULT_HDR10_MASTERING) {
|
|
101664
|
+
const colorTrc = transfer === "pq" ? "smpte2084" : "arib-std-b67";
|
|
101665
|
+
const tagging = `colorprim=bt2020:transfer=${colorTrc}:colormatrix=bt2020nc`;
|
|
101666
|
+
const metadata = `master-display=${mastering.masterDisplay}:max-cll=${mastering.maxCll}`;
|
|
101667
|
+
return {
|
|
101668
|
+
colorPrimaries: "bt2020",
|
|
101669
|
+
colorTrc,
|
|
101670
|
+
colorspace: "bt2020nc",
|
|
101671
|
+
pixelFormat: "yuv420p10le",
|
|
101672
|
+
x265ColorParams: `${tagging}:${metadata}`,
|
|
101673
|
+
mastering
|
|
101674
|
+
};
|
|
101675
|
+
}
|
|
101676
|
+
function analyzeCompositionHdr(colorSpaces) {
|
|
101677
|
+
let hasPq = false;
|
|
101678
|
+
let hasHdr = false;
|
|
101679
|
+
for (const cs of colorSpaces) {
|
|
101680
|
+
if (!isHdrColorSpace(cs)) continue;
|
|
101681
|
+
hasHdr = true;
|
|
101682
|
+
if (cs?.colorTransfer === "smpte2084") hasPq = true;
|
|
101683
|
+
}
|
|
101684
|
+
if (!hasHdr) return { hasHdr: false, dominantTransfer: null };
|
|
101685
|
+
const dominantTransfer = hasPq ? "pq" : "hlg";
|
|
101686
|
+
return { hasHdr: true, dominantTransfer };
|
|
101687
|
+
}
|
|
101616
101688
|
|
|
101617
101689
|
// ../engine/src/utils/runFfmpeg.ts
|
|
101618
101690
|
import { spawn as spawn4 } from "child_process";
|
|
101619
101691
|
var DEFAULT_TIMEOUT2 = 3e5;
|
|
101692
|
+
var DEFAULT_STDERR_TAIL_LINES = 15;
|
|
101693
|
+
function formatFfmpegError(exitCode, stderr, tailLines = DEFAULT_STDERR_TAIL_LINES) {
|
|
101694
|
+
const tail = (stderr ?? "").split(/\r?\n/).filter((line) => line.length > 0).slice(-tailLines).join("\n");
|
|
101695
|
+
if (exitCode === null) {
|
|
101696
|
+
return tail ? `[FFmpeg] ${tail}` : "[FFmpeg] process error";
|
|
101697
|
+
}
|
|
101698
|
+
return tail ? `FFmpeg exited with code ${exitCode}
|
|
101699
|
+
ffmpeg stderr (tail):
|
|
101700
|
+
${tail}` : `FFmpeg exited with code ${exitCode}`;
|
|
101701
|
+
}
|
|
101620
101702
|
async function runFfmpeg(args, opts) {
|
|
101621
101703
|
const startMs = Date.now();
|
|
101622
101704
|
const signal = opts?.signal;
|
|
101623
101705
|
const timeout2 = opts?.timeout ?? DEFAULT_TIMEOUT2;
|
|
101624
101706
|
const onStderr = opts?.onStderr;
|
|
101625
|
-
return new Promise((
|
|
101707
|
+
return new Promise((resolve14) => {
|
|
101626
101708
|
const ffmpeg = spawn4("ffmpeg", args);
|
|
101627
101709
|
let stderr = "";
|
|
101628
101710
|
const onAbort = () => {
|
|
@@ -101648,7 +101730,7 @@ async function runFfmpeg(args, opts) {
|
|
|
101648
101730
|
ffmpeg.on("close", (code) => {
|
|
101649
101731
|
clearTimeout(timer2);
|
|
101650
101732
|
if (signal) signal.removeEventListener("abort", onAbort);
|
|
101651
|
-
|
|
101733
|
+
resolve14({
|
|
101652
101734
|
success: !signal?.aborted && code === 0,
|
|
101653
101735
|
exitCode: code,
|
|
101654
101736
|
stderr,
|
|
@@ -101658,7 +101740,7 @@ async function runFfmpeg(args, opts) {
|
|
|
101658
101740
|
ffmpeg.on("error", (err) => {
|
|
101659
101741
|
clearTimeout(timer2);
|
|
101660
101742
|
if (signal) signal.removeEventListener("abort", onAbort);
|
|
101661
|
-
|
|
101743
|
+
resolve14({
|
|
101662
101744
|
success: false,
|
|
101663
101745
|
exitCode: null,
|
|
101664
101746
|
stderr: err.message,
|
|
@@ -101713,6 +101795,12 @@ function buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder = null) {
|
|
|
101713
101795
|
pixelFormat = "yuv420p",
|
|
101714
101796
|
useGpu = false
|
|
101715
101797
|
} = options;
|
|
101798
|
+
if (options.hdr && codec === "h264") {
|
|
101799
|
+
console.warn(
|
|
101800
|
+
"[chunkEncoder] HDR is not supported with codec=h264 (libx264 has no HDR support). Stripping HDR metadata and tagging output as SDR/BT.709. Use codec=h265 for HDR output."
|
|
101801
|
+
);
|
|
101802
|
+
options = { ...options, hdr: void 0 };
|
|
101803
|
+
}
|
|
101716
101804
|
const args = [...inputArgs, "-r", String(fps)];
|
|
101717
101805
|
const shouldUseGpu = useGpu && gpuEncoder !== null;
|
|
101718
101806
|
if (codec === "h264" || codec === "h265") {
|
|
@@ -101721,7 +101809,7 @@ function buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder = null) {
|
|
|
101721
101809
|
args.push("-c:v", encoderName);
|
|
101722
101810
|
switch (gpuEncoder) {
|
|
101723
101811
|
case "nvenc":
|
|
101724
|
-
args.push("-preset", preset);
|
|
101812
|
+
args.push("-preset", mapPresetForGpuEncoder("nvenc", preset));
|
|
101725
101813
|
if (bitrate) args.push("-b:v", bitrate);
|
|
101726
101814
|
else args.push("-cq", String(quality));
|
|
101727
101815
|
break;
|
|
@@ -101740,7 +101828,7 @@ function buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder = null) {
|
|
|
101740
101828
|
else args.push("-qp", String(quality));
|
|
101741
101829
|
break;
|
|
101742
101830
|
case "qsv":
|
|
101743
|
-
args.push("-preset", preset);
|
|
101831
|
+
args.push("-preset", mapPresetForGpuEncoder("qsv", preset));
|
|
101744
101832
|
if (bitrate) args.push("-b:v", bitrate);
|
|
101745
101833
|
else args.push("-global_quality", String(quality));
|
|
101746
101834
|
break;
|
|
@@ -101751,7 +101839,7 @@ function buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder = null) {
|
|
|
101751
101839
|
if (bitrate) args.push("-b:v", bitrate);
|
|
101752
101840
|
else args.push("-crf", String(quality));
|
|
101753
101841
|
const xParamsFlag = codec === "h264" ? "-x264-params" : "-x265-params";
|
|
101754
|
-
const colorParams = "colorprim=bt709:transfer=bt709:colormatrix=bt709";
|
|
101842
|
+
const colorParams = codec === "h265" && options.hdr ? getHdrEncoderColorParams(options.hdr.transfer).x265ColorParams : "colorprim=bt709:transfer=bt709:colormatrix=bt709";
|
|
101755
101843
|
if (preset === "ultrafast") {
|
|
101756
101844
|
args.push(xParamsFlag, `aq-mode=3:${colorParams}`);
|
|
101757
101845
|
} else {
|
|
@@ -101775,16 +101863,30 @@ function buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder = null) {
|
|
|
101775
101863
|
return [...args, "-y", outputPath];
|
|
101776
101864
|
}
|
|
101777
101865
|
if (codec === "h264" || codec === "h265") {
|
|
101778
|
-
|
|
101779
|
-
"
|
|
101780
|
-
|
|
101781
|
-
|
|
101782
|
-
|
|
101783
|
-
|
|
101784
|
-
|
|
101785
|
-
|
|
101786
|
-
|
|
101787
|
-
|
|
101866
|
+
if (options.hdr) {
|
|
101867
|
+
const transferTag = options.hdr.transfer === "pq" ? "smpte2084" : "arib-std-b67";
|
|
101868
|
+
args.push(
|
|
101869
|
+
"-colorspace:v",
|
|
101870
|
+
"bt2020nc",
|
|
101871
|
+
"-color_primaries:v",
|
|
101872
|
+
"bt2020",
|
|
101873
|
+
"-color_trc:v",
|
|
101874
|
+
transferTag,
|
|
101875
|
+
"-color_range",
|
|
101876
|
+
"tv"
|
|
101877
|
+
);
|
|
101878
|
+
} else {
|
|
101879
|
+
args.push(
|
|
101880
|
+
"-colorspace:v",
|
|
101881
|
+
"bt709",
|
|
101882
|
+
"-color_primaries:v",
|
|
101883
|
+
"bt709",
|
|
101884
|
+
"-color_trc:v",
|
|
101885
|
+
"bt709",
|
|
101886
|
+
"-color_range",
|
|
101887
|
+
"tv"
|
|
101888
|
+
);
|
|
101889
|
+
}
|
|
101788
101890
|
if (gpuEncoder === "vaapi") {
|
|
101789
101891
|
const vfIdx = args.indexOf("-vf");
|
|
101790
101892
|
if (vfIdx !== -1) {
|
|
@@ -101824,7 +101926,7 @@ async function encodeFramesFromDir(framesDir, framePattern, outputPath, options,
|
|
|
101824
101926
|
const inputPath = join6(framesDir, framePattern);
|
|
101825
101927
|
const inputArgs = ["-framerate", String(options.fps), "-i", inputPath];
|
|
101826
101928
|
const args = buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder);
|
|
101827
|
-
return new Promise((
|
|
101929
|
+
return new Promise((resolve14) => {
|
|
101828
101930
|
const ffmpeg = spawn5("ffmpeg", args);
|
|
101829
101931
|
let stderr = "";
|
|
101830
101932
|
const onAbort = () => {
|
|
@@ -101849,7 +101951,7 @@ async function encodeFramesFromDir(framesDir, framePattern, outputPath, options,
|
|
|
101849
101951
|
if (signal) signal.removeEventListener("abort", onAbort);
|
|
101850
101952
|
const durationMs = Date.now() - startTime;
|
|
101851
101953
|
if (signal?.aborted) {
|
|
101852
|
-
|
|
101954
|
+
resolve14({
|
|
101853
101955
|
success: false,
|
|
101854
101956
|
outputPath,
|
|
101855
101957
|
durationMs,
|
|
@@ -101860,23 +101962,23 @@ async function encodeFramesFromDir(framesDir, framePattern, outputPath, options,
|
|
|
101860
101962
|
return;
|
|
101861
101963
|
}
|
|
101862
101964
|
if (code !== 0) {
|
|
101863
|
-
|
|
101965
|
+
resolve14({
|
|
101864
101966
|
success: false,
|
|
101865
101967
|
outputPath,
|
|
101866
101968
|
durationMs,
|
|
101867
101969
|
framesEncoded: 0,
|
|
101868
101970
|
fileSize: 0,
|
|
101869
|
-
error:
|
|
101971
|
+
error: formatFfmpegError(code, stderr)
|
|
101870
101972
|
});
|
|
101871
101973
|
return;
|
|
101872
101974
|
}
|
|
101873
101975
|
const fileSize = existsSync5(outputPath) ? statSync3(outputPath).size : 0;
|
|
101874
|
-
|
|
101976
|
+
resolve14({ success: true, outputPath, durationMs, framesEncoded: frameCount, fileSize });
|
|
101875
101977
|
});
|
|
101876
101978
|
ffmpeg.on("error", (err) => {
|
|
101877
101979
|
clearTimeout(timer2);
|
|
101878
101980
|
if (signal) signal.removeEventListener("abort", onAbort);
|
|
101879
|
-
|
|
101981
|
+
resolve14({
|
|
101880
101982
|
success: false,
|
|
101881
101983
|
outputPath,
|
|
101882
101984
|
durationMs: Date.now() - startTime,
|
|
@@ -101934,18 +102036,18 @@ async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, op
|
|
|
101934
102036
|
let gpuEncoder = null;
|
|
101935
102037
|
if (options.useGpu) gpuEncoder = await getCachedGpuEncoder();
|
|
101936
102038
|
const args = buildEncoderArgs(options, inputArgs, chunkPath, gpuEncoder);
|
|
101937
|
-
const chunkResult = await new Promise((
|
|
102039
|
+
const chunkResult = await new Promise((resolve14) => {
|
|
101938
102040
|
const ffmpeg = spawn5("ffmpeg", args);
|
|
101939
102041
|
let stderr = "";
|
|
101940
102042
|
ffmpeg.stderr.on("data", (d) => {
|
|
101941
102043
|
stderr += d.toString();
|
|
101942
102044
|
});
|
|
101943
102045
|
ffmpeg.on("close", (code) => {
|
|
101944
|
-
if (code === 0)
|
|
101945
|
-
else
|
|
102046
|
+
if (code === 0) resolve14({ success: true });
|
|
102047
|
+
else resolve14({ success: false, error: `Chunk ${i} encode failed: ${stderr.slice(-400)}` });
|
|
101946
102048
|
});
|
|
101947
102049
|
ffmpeg.on("error", (err) => {
|
|
101948
|
-
|
|
102050
|
+
resolve14({ success: false, error: `Chunk ${i} encode error: ${err.message}` });
|
|
101949
102051
|
});
|
|
101950
102052
|
});
|
|
101951
102053
|
if (!chunkResult.success) {
|
|
@@ -101975,18 +102077,18 @@ async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, op
|
|
|
101975
102077
|
"-y",
|
|
101976
102078
|
outputPath
|
|
101977
102079
|
];
|
|
101978
|
-
const concatResult = await new Promise((
|
|
102080
|
+
const concatResult = await new Promise((resolve14) => {
|
|
101979
102081
|
const ffmpeg = spawn5("ffmpeg", concatArgs);
|
|
101980
102082
|
let stderr = "";
|
|
101981
102083
|
ffmpeg.stderr.on("data", (d) => {
|
|
101982
102084
|
stderr += d.toString();
|
|
101983
102085
|
});
|
|
101984
102086
|
ffmpeg.on("close", (code) => {
|
|
101985
|
-
if (code === 0)
|
|
101986
|
-
else
|
|
102087
|
+
if (code === 0) resolve14({ success: true });
|
|
102088
|
+
else resolve14({ success: false, error: `Chunk concat failed: ${stderr.slice(-400)}` });
|
|
101987
102089
|
});
|
|
101988
102090
|
ffmpeg.on("error", (err) => {
|
|
101989
|
-
|
|
102091
|
+
resolve14({ success: false, error: `Chunk concat error: ${err.message}` });
|
|
101990
102092
|
});
|
|
101991
102093
|
});
|
|
101992
102094
|
if (!concatResult.success) {
|
|
@@ -102036,7 +102138,7 @@ async function muxVideoWithAudio(videoPath, audioPath, outputPath, signal, confi
|
|
|
102036
102138
|
success: result.success,
|
|
102037
102139
|
outputPath,
|
|
102038
102140
|
durationMs: result.durationMs,
|
|
102039
|
-
error: !result.success ? result.exitCode
|
|
102141
|
+
error: !result.success ? formatFfmpegError(result.exitCode, result.stderr) : void 0
|
|
102040
102142
|
};
|
|
102041
102143
|
}
|
|
102042
102144
|
async function applyFaststart(inputPath, outputPath, signal, config2) {
|
|
@@ -102059,7 +102161,7 @@ async function applyFaststart(inputPath, outputPath, signal, config2) {
|
|
|
102059
102161
|
success: result.success,
|
|
102060
102162
|
outputPath,
|
|
102061
102163
|
durationMs: result.durationMs,
|
|
102062
|
-
error: !result.success ? result.exitCode
|
|
102164
|
+
error: !result.success ? formatFfmpegError(result.exitCode, result.stderr) : void 0
|
|
102063
102165
|
};
|
|
102064
102166
|
}
|
|
102065
102167
|
|
|
@@ -102067,81 +102169,40 @@ async function applyFaststart(inputPath, outputPath, signal, config2) {
|
|
|
102067
102169
|
import { spawn as spawn6 } from "child_process";
|
|
102068
102170
|
import { existsSync as existsSync6, mkdirSync as mkdirSync3, statSync as statSync4 } from "fs";
|
|
102069
102171
|
import { dirname as dirname6 } from "path";
|
|
102070
|
-
|
|
102071
|
-
// ../engine/src/utils/hdr.ts
|
|
102072
|
-
function isHdrColorSpace(cs) {
|
|
102073
|
-
if (!cs) return false;
|
|
102074
|
-
return cs.colorPrimaries.includes("bt2020") || cs.colorSpace.includes("bt2020") || cs.colorTransfer === "smpte2084" || cs.colorTransfer === "arib-std-b67";
|
|
102075
|
-
}
|
|
102076
|
-
function detectTransfer(cs) {
|
|
102077
|
-
if (cs?.colorTransfer === "smpte2084") return "pq";
|
|
102078
|
-
return "hlg";
|
|
102079
|
-
}
|
|
102080
|
-
var DEFAULT_HDR10_MASTERING = {
|
|
102081
|
-
masterDisplay: "G(13250,34500)B(7500,3000)R(34000,16000)WP(15635,16450)L(10000000,1)",
|
|
102082
|
-
maxCll: "1000,400"
|
|
102083
|
-
};
|
|
102084
|
-
function getHdrEncoderColorParams(transfer, mastering = DEFAULT_HDR10_MASTERING) {
|
|
102085
|
-
const colorTrc = transfer === "pq" ? "smpte2084" : "arib-std-b67";
|
|
102086
|
-
const tagging = `colorprim=bt2020:transfer=${colorTrc}:colormatrix=bt2020nc`;
|
|
102087
|
-
const metadata = `master-display=${mastering.masterDisplay}:max-cll=${mastering.maxCll}`;
|
|
102088
|
-
return {
|
|
102089
|
-
colorPrimaries: "bt2020",
|
|
102090
|
-
colorTrc,
|
|
102091
|
-
colorspace: "bt2020nc",
|
|
102092
|
-
pixelFormat: "yuv420p10le",
|
|
102093
|
-
x265ColorParams: `${tagging}:${metadata}`,
|
|
102094
|
-
mastering
|
|
102095
|
-
};
|
|
102096
|
-
}
|
|
102097
|
-
function analyzeCompositionHdr(colorSpaces) {
|
|
102098
|
-
let hasPq = false;
|
|
102099
|
-
let hasHdr = false;
|
|
102100
|
-
for (const cs of colorSpaces) {
|
|
102101
|
-
if (!isHdrColorSpace(cs)) continue;
|
|
102102
|
-
hasHdr = true;
|
|
102103
|
-
if (cs?.colorTransfer === "smpte2084") hasPq = true;
|
|
102104
|
-
}
|
|
102105
|
-
if (!hasHdr) return { hasHdr: false, dominantTransfer: null };
|
|
102106
|
-
const dominantTransfer = hasPq ? "pq" : "hlg";
|
|
102107
|
-
return { hasHdr: true, dominantTransfer };
|
|
102108
|
-
}
|
|
102109
|
-
|
|
102110
|
-
// ../engine/src/services/streamingEncoder.ts
|
|
102111
102172
|
function createFrameReorderBuffer(startFrame, endFrame) {
|
|
102112
102173
|
let cursor = startFrame;
|
|
102113
102174
|
const pending = /* @__PURE__ */ new Map();
|
|
102114
|
-
const enqueueAt = (frame,
|
|
102175
|
+
const enqueueAt = (frame, resolve14) => {
|
|
102115
102176
|
const list = pending.get(frame);
|
|
102116
102177
|
if (list === void 0) {
|
|
102117
|
-
pending.set(frame, [
|
|
102178
|
+
pending.set(frame, [resolve14]);
|
|
102118
102179
|
} else {
|
|
102119
|
-
list.push(
|
|
102180
|
+
list.push(resolve14);
|
|
102120
102181
|
}
|
|
102121
102182
|
};
|
|
102122
102183
|
const flushAt = (frame) => {
|
|
102123
102184
|
const list = pending.get(frame);
|
|
102124
102185
|
if (list === void 0) return;
|
|
102125
102186
|
pending.delete(frame);
|
|
102126
|
-
for (const
|
|
102187
|
+
for (const resolve14 of list) resolve14();
|
|
102127
102188
|
};
|
|
102128
|
-
const waitForFrame = (frame) => new Promise((
|
|
102189
|
+
const waitForFrame = (frame) => new Promise((resolve14) => {
|
|
102129
102190
|
if (frame === cursor) {
|
|
102130
|
-
|
|
102191
|
+
resolve14();
|
|
102131
102192
|
return;
|
|
102132
102193
|
}
|
|
102133
|
-
enqueueAt(frame,
|
|
102194
|
+
enqueueAt(frame, resolve14);
|
|
102134
102195
|
});
|
|
102135
102196
|
const advanceTo = (frame) => {
|
|
102136
102197
|
cursor = frame;
|
|
102137
102198
|
flushAt(frame);
|
|
102138
102199
|
};
|
|
102139
|
-
const waitForAllDone = () => new Promise((
|
|
102200
|
+
const waitForAllDone = () => new Promise((resolve14) => {
|
|
102140
102201
|
if (cursor >= endFrame) {
|
|
102141
|
-
|
|
102202
|
+
resolve14();
|
|
102142
102203
|
return;
|
|
102143
102204
|
}
|
|
102144
|
-
enqueueAt(endFrame,
|
|
102205
|
+
enqueueAt(endFrame, resolve14);
|
|
102145
102206
|
});
|
|
102146
102207
|
return { waitForFrame, advanceTo, waitForAllDone };
|
|
102147
102208
|
}
|
|
@@ -102193,7 +102254,7 @@ function buildStreamingArgs(options, outputPath, gpuEncoder = null) {
|
|
|
102193
102254
|
args.push("-c:v", encoderName);
|
|
102194
102255
|
switch (gpuEncoder) {
|
|
102195
102256
|
case "nvenc":
|
|
102196
|
-
args.push("-preset", preset);
|
|
102257
|
+
args.push("-preset", mapPresetForGpuEncoder("nvenc", preset));
|
|
102197
102258
|
if (bitrate) args.push("-b:v", bitrate);
|
|
102198
102259
|
else args.push("-cq", String(quality));
|
|
102199
102260
|
break;
|
|
@@ -102212,7 +102273,7 @@ function buildStreamingArgs(options, outputPath, gpuEncoder = null) {
|
|
|
102212
102273
|
else args.push("-qp", String(quality));
|
|
102213
102274
|
break;
|
|
102214
102275
|
case "qsv":
|
|
102215
|
-
args.push("-preset", preset);
|
|
102276
|
+
args.push("-preset", mapPresetForGpuEncoder("qsv", preset));
|
|
102216
102277
|
if (bitrate) args.push("-b:v", bitrate);
|
|
102217
102278
|
else args.push("-global_quality", String(quality));
|
|
102218
102279
|
break;
|
|
@@ -102303,7 +102364,7 @@ async function spawnStreamingEncoder(outputPath, options, signal, config2) {
|
|
|
102303
102364
|
let stderr = "";
|
|
102304
102365
|
let exitCode = null;
|
|
102305
102366
|
let exitPromiseResolve = null;
|
|
102306
|
-
const exitPromise = new Promise((
|
|
102367
|
+
const exitPromise = new Promise((resolve14) => exitPromiseResolve = resolve14);
|
|
102307
102368
|
ffmpeg.stderr?.on("data", (data) => {
|
|
102308
102369
|
stderr += data.toString();
|
|
102309
102370
|
});
|
|
@@ -102349,8 +102410,8 @@ Process error: ${err.message}`;
|
|
|
102349
102410
|
if (signal) signal.removeEventListener("abort", onAbort);
|
|
102350
102411
|
const stdin = ffmpeg.stdin;
|
|
102351
102412
|
if (stdin && !stdin.destroyed) {
|
|
102352
|
-
await new Promise((
|
|
102353
|
-
stdin.end(() =>
|
|
102413
|
+
await new Promise((resolve14) => {
|
|
102414
|
+
stdin.end(() => resolve14());
|
|
102354
102415
|
});
|
|
102355
102416
|
}
|
|
102356
102417
|
await exitPromise;
|
|
@@ -102368,7 +102429,7 @@ Process error: ${err.message}`;
|
|
|
102368
102429
|
success: false,
|
|
102369
102430
|
durationMs,
|
|
102370
102431
|
fileSize: 0,
|
|
102371
|
-
error:
|
|
102432
|
+
error: formatFfmpegError(exitCode, stderr)
|
|
102372
102433
|
};
|
|
102373
102434
|
}
|
|
102374
102435
|
const fileSize = existsSync6(outputPath) ? statSync4(outputPath).size : 0;
|
|
@@ -102382,14 +102443,14 @@ Process error: ${err.message}`;
|
|
|
102382
102443
|
// ../engine/src/services/videoFrameExtractor.ts
|
|
102383
102444
|
import { spawn as spawn8 } from "child_process";
|
|
102384
102445
|
import { existsSync as existsSync8, mkdirSync as mkdirSync5, readdirSync as readdirSync4, rmSync } from "fs";
|
|
102385
|
-
import { join as join8 } from "path";
|
|
102446
|
+
import { isAbsolute as isAbsolute2, join as join8 } from "path";
|
|
102386
102447
|
|
|
102387
102448
|
// ../engine/src/utils/ffprobe.ts
|
|
102388
102449
|
import { spawn as spawn7 } from "child_process";
|
|
102389
102450
|
import { readFileSync as readFileSync5 } from "fs";
|
|
102390
102451
|
import { extname as extname2 } from "path";
|
|
102391
102452
|
function runFfprobe(args) {
|
|
102392
|
-
return new Promise((
|
|
102453
|
+
return new Promise((resolve14, reject) => {
|
|
102393
102454
|
const proc = spawn7("ffprobe", args);
|
|
102394
102455
|
let stdout = "";
|
|
102395
102456
|
let stderr = "";
|
|
@@ -102403,7 +102464,7 @@ function runFfprobe(args) {
|
|
|
102403
102464
|
if (code !== 0) {
|
|
102404
102465
|
reject(new Error(`[FFmpeg] ffprobe exited with code ${code}: ${stderr}`));
|
|
102405
102466
|
} else {
|
|
102406
|
-
|
|
102467
|
+
resolve14(stdout);
|
|
102407
102468
|
}
|
|
102408
102469
|
});
|
|
102409
102470
|
proc.on("error", (err) => {
|
|
@@ -102497,7 +102558,7 @@ function parseFrameRate(frameRateStr) {
|
|
|
102497
102558
|
}
|
|
102498
102559
|
return parseFloat(frameRateStr) || 0;
|
|
102499
102560
|
}
|
|
102500
|
-
async function
|
|
102561
|
+
async function extractMediaMetadata(filePath) {
|
|
102501
102562
|
const cached = videoMetadataCache.get(filePath);
|
|
102502
102563
|
if (cached) return cached;
|
|
102503
102564
|
const probePromise = (async () => {
|
|
@@ -102783,7 +102844,7 @@ async function extractVideoFramesRange(videoPath, videoId, startTime, duration,
|
|
|
102783
102844
|
const { fps, outputDir, quality = 95, format: format3 = "jpg" } = options;
|
|
102784
102845
|
const videoOutputDir = join8(outputDir, videoId);
|
|
102785
102846
|
if (!existsSync8(videoOutputDir)) mkdirSync5(videoOutputDir, { recursive: true });
|
|
102786
|
-
const metadata = await
|
|
102847
|
+
const metadata = await extractMediaMetadata(videoPath);
|
|
102787
102848
|
const framePattern = `frame_%05d.${format3}`;
|
|
102788
102849
|
const outputPattern = join8(videoOutputDir, framePattern);
|
|
102789
102850
|
const isHdr = isHdrColorSpace(metadata.colorSpace);
|
|
@@ -102802,7 +102863,7 @@ async function extractVideoFramesRange(videoPath, videoId, startTime, duration,
|
|
|
102802
102863
|
args.push("-q:v", format3 === "jpg" ? String(Math.ceil((100 - quality) / 3)) : "0");
|
|
102803
102864
|
if (format3 === "png") args.push("-compression_level", "6");
|
|
102804
102865
|
args.push("-y", outputPattern);
|
|
102805
|
-
return new Promise((
|
|
102866
|
+
return new Promise((resolve14, reject) => {
|
|
102806
102867
|
const ffmpeg = spawn8("ffmpeg", args);
|
|
102807
102868
|
let stderr = "";
|
|
102808
102869
|
const onAbort = () => {
|
|
@@ -102837,7 +102898,7 @@ async function extractVideoFramesRange(videoPath, videoId, startTime, duration,
|
|
|
102837
102898
|
files.forEach((file, index) => {
|
|
102838
102899
|
framePaths.set(index, join8(videoOutputDir, file));
|
|
102839
102900
|
});
|
|
102840
|
-
|
|
102901
|
+
resolve14({
|
|
102841
102902
|
videoId,
|
|
102842
102903
|
srcPath: videoPath,
|
|
102843
102904
|
outputDir: videoOutputDir,
|
|
@@ -102859,8 +102920,9 @@ async function extractVideoFramesRange(videoPath, videoId, startTime, duration,
|
|
|
102859
102920
|
});
|
|
102860
102921
|
});
|
|
102861
102922
|
}
|
|
102862
|
-
async function convertSdrToHdr(inputPath, outputPath, signal, config2) {
|
|
102923
|
+
async function convertSdrToHdr(inputPath, outputPath, targetTransfer, signal, config2) {
|
|
102863
102924
|
const timeout2 = config2?.ffmpegProcessTimeout ?? DEFAULT_CONFIG.ffmpegProcessTimeout;
|
|
102925
|
+
const colorTrc = targetTransfer === "pq" ? "smpte2084" : "arib-std-b67";
|
|
102864
102926
|
const args = [
|
|
102865
102927
|
"-i",
|
|
102866
102928
|
inputPath,
|
|
@@ -102869,7 +102931,7 @@ async function convertSdrToHdr(inputPath, outputPath, signal, config2) {
|
|
|
102869
102931
|
"-color_primaries",
|
|
102870
102932
|
"bt2020",
|
|
102871
102933
|
"-color_trc",
|
|
102872
|
-
|
|
102934
|
+
colorTrc,
|
|
102873
102935
|
"-colorspace",
|
|
102874
102936
|
"bt2020nc",
|
|
102875
102937
|
"-c:v",
|
|
@@ -102931,7 +102993,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config2,
|
|
|
102931
102993
|
if (signal?.aborted) break;
|
|
102932
102994
|
try {
|
|
102933
102995
|
let videoPath = video.src;
|
|
102934
|
-
if (!videoPath
|
|
102996
|
+
if (!isAbsolute2(videoPath) && !isHttpUrl(videoPath)) {
|
|
102935
102997
|
const fromCompiled = compiledDir ? join8(compiledDir, videoPath) : null;
|
|
102936
102998
|
videoPath = fromCompiled && existsSync8(fromCompiled) ? fromCompiled : join8(baseDir, videoPath);
|
|
102937
102999
|
}
|
|
@@ -102951,12 +103013,13 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config2,
|
|
|
102951
103013
|
}
|
|
102952
103014
|
const videoColorSpaces = await Promise.all(
|
|
102953
103015
|
resolvedVideos.map(async ({ videoPath }) => {
|
|
102954
|
-
const metadata = await
|
|
103016
|
+
const metadata = await extractMediaMetadata(videoPath);
|
|
102955
103017
|
return metadata.colorSpace;
|
|
102956
103018
|
})
|
|
102957
103019
|
);
|
|
102958
|
-
const
|
|
102959
|
-
if (
|
|
103020
|
+
const hdrInfo = analyzeCompositionHdr(videoColorSpaces);
|
|
103021
|
+
if (hdrInfo.hasHdr && hdrInfo.dominantTransfer) {
|
|
103022
|
+
const targetTransfer = hdrInfo.dominantTransfer;
|
|
102960
103023
|
const convertDir = join8(options.outputDir, "_hdr_normalized");
|
|
102961
103024
|
mkdirSync5(convertDir, { recursive: true });
|
|
102962
103025
|
for (let i = 0; i < resolvedVideos.length; i++) {
|
|
@@ -102967,7 +103030,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config2,
|
|
|
102967
103030
|
if (!entry) continue;
|
|
102968
103031
|
const convertedPath = join8(convertDir, `${entry.video.id}_hdr.mp4`);
|
|
102969
103032
|
try {
|
|
102970
|
-
await convertSdrToHdr(entry.videoPath, convertedPath, signal, config2);
|
|
103033
|
+
await convertSdrToHdr(entry.videoPath, convertedPath, targetTransfer, signal, config2);
|
|
102971
103034
|
entry.videoPath = convertedPath;
|
|
102972
103035
|
} catch (err) {
|
|
102973
103036
|
errors.push({
|
|
@@ -102983,7 +103046,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config2,
|
|
|
102983
103046
|
if (signal?.aborted) break;
|
|
102984
103047
|
const entry = resolvedVideos[i];
|
|
102985
103048
|
if (!entry) continue;
|
|
102986
|
-
const metadata = await
|
|
103049
|
+
const metadata = await extractMediaMetadata(entry.videoPath);
|
|
102987
103050
|
if (!metadata.isVFR) continue;
|
|
102988
103051
|
let segDuration = entry.video.end - entry.video.start;
|
|
102989
103052
|
if (!Number.isFinite(segDuration) || segDuration <= 0) {
|
|
@@ -103019,7 +103082,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config2,
|
|
|
103019
103082
|
try {
|
|
103020
103083
|
let videoDuration = video.end - video.start;
|
|
103021
103084
|
if (!Number.isFinite(videoDuration) || videoDuration <= 0) {
|
|
103022
|
-
const metadata = await
|
|
103085
|
+
const metadata = await extractMediaMetadata(videoPath);
|
|
103023
103086
|
const sourceDuration = metadata.durationSeconds - video.mediaStart;
|
|
103024
103087
|
videoDuration = sourceDuration > 0 ? sourceDuration : metadata.durationSeconds;
|
|
103025
103088
|
video.end = video.start + videoDuration;
|
|
@@ -103272,12 +103335,12 @@ async function queryElementStacking(page, nativeHdrIds) {
|
|
|
103272
103335
|
function resolveRadius(value, el) {
|
|
103273
103336
|
if (value.includes("%")) {
|
|
103274
103337
|
const pct = parseFloat(value) / 100;
|
|
103275
|
-
const
|
|
103276
|
-
const
|
|
103277
|
-
const h = htmlEl.offsetHeight || 0;
|
|
103338
|
+
const w = el instanceof HTMLElement ? el.offsetWidth : 0;
|
|
103339
|
+
const h = el instanceof HTMLElement ? el.offsetHeight : 0;
|
|
103278
103340
|
return pct * Math.min(w, h);
|
|
103279
103341
|
}
|
|
103280
|
-
|
|
103342
|
+
const parsed = parseFloat(value);
|
|
103343
|
+
return Number.isNaN(parsed) ? 0 : parsed;
|
|
103281
103344
|
}
|
|
103282
103345
|
const selfCs = window.getComputedStyle(node);
|
|
103283
103346
|
const selfRadii = [
|
|
@@ -103361,8 +103424,7 @@ async function queryElementStacking(page, nativeHdrIds) {
|
|
|
103361
103424
|
const style = window.getComputedStyle(el);
|
|
103362
103425
|
const zIndex = getEffectiveZIndex(el);
|
|
103363
103426
|
const isHdrEl = hdrSet.has(id);
|
|
103364
|
-
const
|
|
103365
|
-
const opacity = opacityStartNode ? getEffectiveOpacity(opacityStartNode) : 1;
|
|
103427
|
+
const opacity = getEffectiveOpacity(el);
|
|
103366
103428
|
const visible = style.visibility !== "hidden" && style.display !== "none" && rect.width > 0 && rect.height > 0;
|
|
103367
103429
|
const htmlEl = el instanceof HTMLElement ? el : null;
|
|
103368
103430
|
results.push({
|
|
@@ -103395,7 +103457,7 @@ async function queryElementStacking(page, nativeHdrIds) {
|
|
|
103395
103457
|
|
|
103396
103458
|
// ../engine/src/services/audioMixer.ts
|
|
103397
103459
|
import { existsSync as existsSync9, mkdirSync as mkdirSync6, rmSync as rmSync2 } from "fs";
|
|
103398
|
-
import { join as join9, dirname as dirname7 } from "path";
|
|
103460
|
+
import { isAbsolute as isAbsolute3, join as join9, dirname as dirname7 } from "path";
|
|
103399
103461
|
function parseAudioElements(html) {
|
|
103400
103462
|
const elements = [];
|
|
103401
103463
|
const { document: document2 } = parseHTML(html);
|
|
@@ -103622,7 +103684,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
103622
103684
|
}
|
|
103623
103685
|
try {
|
|
103624
103686
|
let srcPath = element.src;
|
|
103625
|
-
if (!srcPath
|
|
103687
|
+
if (!isAbsolute3(srcPath) && !isHttpUrl(srcPath)) {
|
|
103626
103688
|
const fromCompiled = compiledDir ? join9(compiledDir, srcPath) : null;
|
|
103627
103689
|
srcPath = fromCompiled && existsSync9(fromCompiled) ? fromCompiled : join9(baseDir, srcPath);
|
|
103628
103690
|
}
|
|
@@ -106359,7 +106421,7 @@ var responseViaResponseObject = async (res, outgoing, options = {}) => {
|
|
|
106359
106421
|
});
|
|
106360
106422
|
if (!chunk) {
|
|
106361
106423
|
if (i === 1) {
|
|
106362
|
-
await new Promise((
|
|
106424
|
+
await new Promise((resolve14) => setTimeout(resolve14));
|
|
106363
106425
|
maxReadCount = 3;
|
|
106364
106426
|
continue;
|
|
106365
106427
|
}
|
|
@@ -106972,13 +107034,51 @@ function normalizeObjectFit(value) {
|
|
|
106972
107034
|
}
|
|
106973
107035
|
function parseTransformMatrix(css) {
|
|
106974
107036
|
if (!css || css === "none") return null;
|
|
106975
|
-
const
|
|
107037
|
+
const match2d = css.match(
|
|
106976
107038
|
/^matrix\(\s*([^,]+),\s*([^,]+),\s*([^,]+),\s*([^,]+),\s*([^,]+),\s*([^,)]+)\s*\)$/
|
|
106977
107039
|
);
|
|
106978
|
-
if (
|
|
106979
|
-
|
|
106980
|
-
|
|
106981
|
-
|
|
107040
|
+
if (match2d) {
|
|
107041
|
+
const values = match2d.slice(1, 7).map(Number);
|
|
107042
|
+
if (!values.every(Number.isFinite)) return null;
|
|
107043
|
+
return values;
|
|
107044
|
+
}
|
|
107045
|
+
const match3d = css.match(/^matrix3d\(\s*([^)]+)\)$/);
|
|
107046
|
+
if (match3d) {
|
|
107047
|
+
const raw2 = match3d[1];
|
|
107048
|
+
if (!raw2) return null;
|
|
107049
|
+
const parts = raw2.split(",").map((s) => Number(s.trim()));
|
|
107050
|
+
if (parts.length !== 16 || !parts.every(Number.isFinite)) return null;
|
|
107051
|
+
warnIfZSignificant(parts);
|
|
107052
|
+
return [
|
|
107053
|
+
parts[0],
|
|
107054
|
+
parts[1],
|
|
107055
|
+
parts[4],
|
|
107056
|
+
parts[5],
|
|
107057
|
+
parts[12],
|
|
107058
|
+
parts[13]
|
|
107059
|
+
];
|
|
107060
|
+
}
|
|
107061
|
+
return null;
|
|
107062
|
+
}
|
|
107063
|
+
var warnedZSignificant = false;
|
|
107064
|
+
var Z_EPSILON = 1e-6;
|
|
107065
|
+
function warnIfZSignificant(parts) {
|
|
107066
|
+
if (warnedZSignificant) return;
|
|
107067
|
+
const a3 = parts[8] ?? 0;
|
|
107068
|
+
const b3 = parts[9] ?? 0;
|
|
107069
|
+
const c1 = parts[2] ?? 0;
|
|
107070
|
+
const c2 = parts[6] ?? 0;
|
|
107071
|
+
const c3 = parts[10] ?? 1;
|
|
107072
|
+
const d1 = parts[3] ?? 0;
|
|
107073
|
+
const d2 = parts[7] ?? 0;
|
|
107074
|
+
const d3 = parts[11] ?? 0;
|
|
107075
|
+
const d4 = parts[15] ?? 1;
|
|
107076
|
+
if (Math.abs(a3) > Z_EPSILON || Math.abs(b3) > Z_EPSILON || Math.abs(c1) > Z_EPSILON || Math.abs(c2) > Z_EPSILON || Math.abs(c3 - 1) > Z_EPSILON || Math.abs(d1) > Z_EPSILON || Math.abs(d2) > Z_EPSILON || Math.abs(d3) > Z_EPSILON || Math.abs(d4 - 1) > Z_EPSILON) {
|
|
107077
|
+
warnedZSignificant = true;
|
|
107078
|
+
console.warn(
|
|
107079
|
+
`[alphaBlit] parseTransformMatrix received a matrix3d with non-trivial 3D components (a3=${a3}, b3=${b3}, c1=${c1}, c2=${c2}, c3=${c3}, d1=${d1}, d2=${d2}, d3=${d3}, d4=${d4}). The engine projects 3D transforms to 2D (m11, m12, m21, m22, m41, m42) and silently discards perspective and out-of-plane rotation. If your composition uses real 3D (rotateX/Y, perspective), the rendered output will not match the studio preview. Z translation (translateZ) is dropped by design and does not trigger this warning. This warning is emitted once per process.`
|
|
107080
|
+
);
|
|
107081
|
+
}
|
|
106982
107082
|
}
|
|
106983
107083
|
|
|
106984
107084
|
// ../engine/src/utils/layerCompositor.ts
|
|
@@ -107632,14 +107732,14 @@ var ridgedBurn = (from2, to, out, w, h, p) => {
|
|
|
107632
107732
|
TRANSITIONS["ridged-burn"] = ridgedBurn;
|
|
107633
107733
|
|
|
107634
107734
|
// src/services/renderOrchestrator.ts
|
|
107635
|
-
import { join as join15, dirname as dirname10, resolve as
|
|
107735
|
+
import { join as join15, dirname as dirname10, resolve as resolve11 } from "path";
|
|
107636
107736
|
import { randomUUID } from "crypto";
|
|
107637
107737
|
import { freemem as freemem2 } from "os";
|
|
107638
107738
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
107639
107739
|
|
|
107640
107740
|
// src/services/fileServer.ts
|
|
107641
|
-
import { readFileSync as readFileSync7, existsSync as existsSync12, statSync as statSync5 } from "node:fs";
|
|
107642
|
-
import { join as join11, extname as extname4 } from "node:path";
|
|
107741
|
+
import { readFileSync as readFileSync7, existsSync as existsSync12, realpathSync, statSync as statSync5 } from "node:fs";
|
|
107742
|
+
import { join as join11, extname as extname4, resolve as resolve8, sep } from "node:path";
|
|
107643
107743
|
|
|
107644
107744
|
// src/services/hyperframeRuntimeLoader.ts
|
|
107645
107745
|
import { createHash as createHash2 } from "node:crypto";
|
|
@@ -107715,6 +107815,18 @@ function resolveVerifiedHyperframeRuntime() {
|
|
|
107715
107815
|
}
|
|
107716
107816
|
|
|
107717
107817
|
// src/services/fileServer.ts
|
|
107818
|
+
function isPathInside(child, parent, options = {}) {
|
|
107819
|
+
const { resolveSymlinks = false, pathModule } = options;
|
|
107820
|
+
const resolveFn = pathModule?.resolve ?? resolve8;
|
|
107821
|
+
const separator = pathModule?.sep ?? sep;
|
|
107822
|
+
const resolvedChild = resolveFn(child);
|
|
107823
|
+
const resolvedParent = resolveFn(parent);
|
|
107824
|
+
const normalizedChild = resolveSymlinks && existsSync12(resolvedChild) ? realpathSync.native(resolvedChild) : resolvedChild;
|
|
107825
|
+
const normalizedParent = resolveSymlinks && existsSync12(resolvedParent) ? realpathSync.native(resolvedParent) : resolvedParent;
|
|
107826
|
+
if (normalizedChild === normalizedParent) return true;
|
|
107827
|
+
const parentWithSep = normalizedParent.endsWith(separator) ? normalizedParent : normalizedParent + separator;
|
|
107828
|
+
return normalizedChild.startsWith(parentWithSep);
|
|
107829
|
+
}
|
|
107718
107830
|
var MIME_TYPES = {
|
|
107719
107831
|
".html": "text/html; charset=utf-8",
|
|
107720
107832
|
".css": "text/css; charset=utf-8",
|
|
@@ -108107,12 +108219,20 @@ function createFileServer2(options) {
|
|
|
108107
108219
|
let requestPath = c.req.path;
|
|
108108
108220
|
if (requestPath === "/") requestPath = "/index.html";
|
|
108109
108221
|
const relativePath = requestPath.replace(/^\//, "");
|
|
108110
|
-
|
|
108111
|
-
|
|
108112
|
-
|
|
108113
|
-
|
|
108114
|
-
|
|
108115
|
-
|
|
108222
|
+
let filePath = null;
|
|
108223
|
+
if (compiledDir) {
|
|
108224
|
+
const candidate = join11(compiledDir, relativePath);
|
|
108225
|
+
if (existsSync12(candidate) && isPathInside(candidate, compiledDir, { resolveSymlinks: true }) && statSync5(candidate).isFile()) {
|
|
108226
|
+
filePath = candidate;
|
|
108227
|
+
}
|
|
108228
|
+
}
|
|
108229
|
+
if (!filePath) {
|
|
108230
|
+
const candidate = join11(projectDir, relativePath);
|
|
108231
|
+
if (existsSync12(candidate) && isPathInside(candidate, projectDir, { resolveSymlinks: true }) && statSync5(candidate).isFile()) {
|
|
108232
|
+
filePath = candidate;
|
|
108233
|
+
}
|
|
108234
|
+
}
|
|
108235
|
+
if (!filePath) {
|
|
108116
108236
|
if (!/favicon\.ico$/i.test(requestPath)) {
|
|
108117
108237
|
console.warn(`[FileServer] 404 Not Found: ${requestPath}`);
|
|
108118
108238
|
}
|
|
@@ -108136,10 +108256,10 @@ function createFileServer2(options) {
|
|
|
108136
108256
|
headers: { "Content-Type": contentType }
|
|
108137
108257
|
});
|
|
108138
108258
|
});
|
|
108139
|
-
return new Promise((
|
|
108259
|
+
return new Promise((resolve14) => {
|
|
108140
108260
|
const connections = /* @__PURE__ */ new Set();
|
|
108141
108261
|
const server = serve({ fetch: app.fetch, port }, (info) => {
|
|
108142
|
-
|
|
108262
|
+
resolve14({
|
|
108143
108263
|
url: `http://localhost:${info.port}`,
|
|
108144
108264
|
port: info.port,
|
|
108145
108265
|
close: () => {
|
|
@@ -108158,18 +108278,18 @@ function createFileServer2(options) {
|
|
|
108158
108278
|
|
|
108159
108279
|
// src/services/htmlCompiler.ts
|
|
108160
108280
|
import { readFileSync as readFileSync9, existsSync as existsSync14, mkdirSync as mkdirSync9 } from "fs";
|
|
108161
|
-
import { join as join14, dirname as dirname9, resolve as
|
|
108281
|
+
import { join as join14, dirname as dirname9, resolve as resolve10 } from "path";
|
|
108162
108282
|
import postcss from "postcss";
|
|
108163
108283
|
|
|
108164
108284
|
// src/utils/paths.ts
|
|
108165
|
-
import { resolve as
|
|
108166
|
-
var DEFAULT_RENDERS_DIR = process.env.PRODUCER_RENDERS_DIR ??
|
|
108167
|
-
function
|
|
108168
|
-
const absChild =
|
|
108169
|
-
const absParent =
|
|
108285
|
+
import { resolve as resolve9, basename as basename2, join as join12, relative as relative2, isAbsolute as isAbsolute4 } from "node:path";
|
|
108286
|
+
var DEFAULT_RENDERS_DIR = process.env.PRODUCER_RENDERS_DIR ?? resolve9(new URL(import.meta.url).pathname, "../../..", "renders");
|
|
108287
|
+
function isPathInside2(childPath, parentPath) {
|
|
108288
|
+
const absChild = resolve9(childPath);
|
|
108289
|
+
const absParent = resolve9(parentPath);
|
|
108170
108290
|
if (absChild === absParent) return true;
|
|
108171
108291
|
const rel = relative2(absParent, absChild);
|
|
108172
|
-
return rel !== "" && !rel.startsWith("..") && !
|
|
108292
|
+
return rel !== "" && !rel.startsWith("..") && !isAbsolute4(rel);
|
|
108173
108293
|
}
|
|
108174
108294
|
function toExternalAssetKey(absPath) {
|
|
108175
108295
|
if (absPath.startsWith("hf-ext/")) return absPath;
|
|
@@ -108182,10 +108302,10 @@ function toExternalAssetKey(absPath) {
|
|
|
108182
108302
|
return "hf-ext/" + normalised;
|
|
108183
108303
|
}
|
|
108184
108304
|
function resolveRenderPaths(projectDir, outputPath, rendersDir = DEFAULT_RENDERS_DIR) {
|
|
108185
|
-
const absoluteProjectDir =
|
|
108305
|
+
const absoluteProjectDir = resolve9(projectDir);
|
|
108186
108306
|
const projectName = basename2(absoluteProjectDir);
|
|
108187
108307
|
const resolvedOutputPath = outputPath ?? join12(rendersDir, `${projectName}.mp4`);
|
|
108188
|
-
const absoluteOutputPath =
|
|
108308
|
+
const absoluteOutputPath = resolve9(resolvedOutputPath);
|
|
108189
108309
|
return { absoluteProjectDir, absoluteOutputPath };
|
|
108190
108310
|
}
|
|
108191
108311
|
|
|
@@ -108632,7 +108752,7 @@ async function resolveMediaDuration(src, mediaStart, baseDir, downloadDir, tagNa
|
|
|
108632
108752
|
if (!existsSync14(filePath)) {
|
|
108633
108753
|
return { duration: 0, resolvedPath: filePath };
|
|
108634
108754
|
}
|
|
108635
|
-
const metadata = tagName19 === "video" ? await
|
|
108755
|
+
const metadata = tagName19 === "video" ? await extractMediaMetadata(filePath) : await extractAudioMetadata(filePath);
|
|
108636
108756
|
const fileDuration = metadata.durationSeconds;
|
|
108637
108757
|
const effectiveDuration = fileDuration - mediaStart;
|
|
108638
108758
|
const duration = effectiveDuration > 0 ? effectiveDuration : fileDuration;
|
|
@@ -108694,7 +108814,7 @@ async function parseSubCompositions(html, projectDir, downloadDir, parentOffset
|
|
|
108694
108814
|
const elEnd = elEndRaw ? parseFloat(elEndRaw) : Infinity;
|
|
108695
108815
|
const absoluteStart = parentOffset + elStart;
|
|
108696
108816
|
const absoluteEnd = Math.min(parentEnd, isFinite(elEnd) ? parentOffset + elEnd : Infinity);
|
|
108697
|
-
const filePath =
|
|
108817
|
+
const filePath = resolve10(projectDir, srcPath);
|
|
108698
108818
|
if (visited.has(filePath)) {
|
|
108699
108819
|
continue;
|
|
108700
108820
|
}
|
|
@@ -108907,7 +109027,7 @@ function inlineSubCompositions(html, subCompositions, projectDir) {
|
|
|
108907
109027
|
if (!srcPath) continue;
|
|
108908
109028
|
let compHtml = subCompositions.get(srcPath) || null;
|
|
108909
109029
|
if (!compHtml) {
|
|
108910
|
-
const filePath =
|
|
109030
|
+
const filePath = resolve10(projectDir, srcPath);
|
|
108911
109031
|
if (existsSync14(filePath)) {
|
|
108912
109032
|
compHtml = readFileSync9(filePath, "utf-8");
|
|
108913
109033
|
}
|
|
@@ -109124,7 +109244,7 @@ ${safeText}
|
|
|
109124
109244
|
return wrappedFragment ? document2.body.innerHTML || "" : document2.toString();
|
|
109125
109245
|
}
|
|
109126
109246
|
function collectExternalAssets(html, projectDir) {
|
|
109127
|
-
const absProjectDir =
|
|
109247
|
+
const absProjectDir = resolve10(projectDir);
|
|
109128
109248
|
const externalAssets = /* @__PURE__ */ new Map();
|
|
109129
109249
|
const CSS_URL_RE2 = /\burl\(\s*(["']?)([^)"']+)\1\s*\)/g;
|
|
109130
109250
|
function processPath(rawPath) {
|
|
@@ -109132,8 +109252,8 @@ function collectExternalAssets(html, projectDir) {
|
|
|
109132
109252
|
if (!trimmed || trimmed.startsWith("/") || trimmed.startsWith("http://") || trimmed.startsWith("https://") || trimmed.startsWith("//") || trimmed.startsWith("data:") || trimmed.startsWith("#")) {
|
|
109133
109253
|
return null;
|
|
109134
109254
|
}
|
|
109135
|
-
const absPath =
|
|
109136
|
-
if (
|
|
109255
|
+
const absPath = resolve10(absProjectDir, trimmed);
|
|
109256
|
+
if (isPathInside2(absPath, absProjectDir)) {
|
|
109137
109257
|
return null;
|
|
109138
109258
|
}
|
|
109139
109259
|
if (!existsSync14(absPath)) return null;
|
|
@@ -109213,9 +109333,9 @@ async function compileForRender(projectDir, htmlPath, downloadDir) {
|
|
|
109213
109333
|
const images = dedupeElementsById([...mainImages, ...subImages]);
|
|
109214
109334
|
for (const video of videos) {
|
|
109215
109335
|
if (isHttpUrl(video.src)) continue;
|
|
109216
|
-
const videoPath =
|
|
109336
|
+
const videoPath = resolve10(projectDir, video.src);
|
|
109217
109337
|
const reencode = `ffmpeg -i "${video.src}" -c:v libx264 -r 30 -g 30 -keyint_min 30 -movflags +faststart -c:a copy output.mp4`;
|
|
109218
|
-
Promise.all([analyzeKeyframeIntervals(videoPath),
|
|
109338
|
+
Promise.all([analyzeKeyframeIntervals(videoPath), extractMediaMetadata(videoPath)]).then(([analysis, metadata]) => {
|
|
109219
109339
|
if (analysis.isProblematic) {
|
|
109220
109340
|
console.warn(
|
|
109221
109341
|
`[Compiler] WARNING: Video "${video.id}" has sparse keyframes (max interval: ${analysis.maxIntervalSeconds}s). This causes seek failures and frame freezing. Re-encode with: ${reencode}`
|
|
@@ -109414,6 +109534,21 @@ function getMaxFrameIndex(frameDir) {
|
|
|
109414
109534
|
frameDirMaxIndexCache.set(frameDir, max);
|
|
109415
109535
|
return max;
|
|
109416
109536
|
}
|
|
109537
|
+
function countNonZeroAlpha(rgba) {
|
|
109538
|
+
let n = 0;
|
|
109539
|
+
for (let p = 3; p < rgba.length; p += 4) {
|
|
109540
|
+
if (rgba[p] !== 0) n++;
|
|
109541
|
+
}
|
|
109542
|
+
return n;
|
|
109543
|
+
}
|
|
109544
|
+
function countNonZeroRgb48(buf) {
|
|
109545
|
+
let n = 0;
|
|
109546
|
+
for (let p = 0; p < buf.length; p += 6) {
|
|
109547
|
+
if (buf[p] !== 0 || buf[p + 1] !== 0 || buf[p + 2] !== 0 || buf[p + 3] !== 0 || buf[p + 4] !== 0 || buf[p + 5] !== 0)
|
|
109548
|
+
n++;
|
|
109549
|
+
}
|
|
109550
|
+
return n;
|
|
109551
|
+
}
|
|
109417
109552
|
var RenderCancelledError = class extends Error {
|
|
109418
109553
|
reason;
|
|
109419
109554
|
constructor(message = "render_cancelled", reason = "aborted") {
|
|
@@ -109474,8 +109609,8 @@ function writeCompiledArtifacts(compiled, workDir, includeSummary) {
|
|
|
109474
109609
|
writeFileSync4(outPath, html, "utf-8");
|
|
109475
109610
|
}
|
|
109476
109611
|
for (const [relativePath, absolutePath] of compiled.externalAssets) {
|
|
109477
|
-
const outPath =
|
|
109478
|
-
if (!
|
|
109612
|
+
const outPath = resolve11(join15(compileDir, relativePath));
|
|
109613
|
+
if (!isPathInside2(outPath, compileDir)) {
|
|
109479
109614
|
console.warn(`[Render] Skipping external asset with unsafe path: ${relativePath}`);
|
|
109480
109615
|
continue;
|
|
109481
109616
|
}
|
|
@@ -109621,6 +109756,165 @@ function blitHdrImageLayer(canvas, el, hdrImageBuffers, width, height, log, sour
|
|
|
109621
109756
|
}
|
|
109622
109757
|
}
|
|
109623
109758
|
}
|
|
109759
|
+
async function compositeHdrFrame(ctx, canvas, time, fullStacking, elementFilter, debugFrameIndex = -1) {
|
|
109760
|
+
const {
|
|
109761
|
+
log,
|
|
109762
|
+
domSession,
|
|
109763
|
+
beforeCaptureHook,
|
|
109764
|
+
width,
|
|
109765
|
+
height,
|
|
109766
|
+
fps,
|
|
109767
|
+
effectiveHdr,
|
|
109768
|
+
nativeHdrImageIds,
|
|
109769
|
+
hdrImageBuffers,
|
|
109770
|
+
hdrFrameDirs,
|
|
109771
|
+
hdrVideoStartTimes,
|
|
109772
|
+
imageTransfers,
|
|
109773
|
+
videoTransfers,
|
|
109774
|
+
debugDumpEnabled,
|
|
109775
|
+
debugDumpDir
|
|
109776
|
+
} = ctx;
|
|
109777
|
+
const filteredStacking = elementFilter ? fullStacking.filter((e) => elementFilter.has(e.id)) : fullStacking;
|
|
109778
|
+
const layers = groupIntoLayers(filteredStacking);
|
|
109779
|
+
const shouldLog = debugDumpEnabled && debugFrameIndex >= 0;
|
|
109780
|
+
if (shouldLog) {
|
|
109781
|
+
log.info("[diag] compositeToBuffer plan", {
|
|
109782
|
+
frame: debugFrameIndex,
|
|
109783
|
+
time: time.toFixed(3),
|
|
109784
|
+
filterSize: elementFilter?.size,
|
|
109785
|
+
fullStackingCount: fullStacking.length,
|
|
109786
|
+
filteredCount: filteredStacking.length,
|
|
109787
|
+
layerCount: layers.length,
|
|
109788
|
+
layers: layers.map(
|
|
109789
|
+
(l) => l.type === "hdr" ? {
|
|
109790
|
+
type: "hdr",
|
|
109791
|
+
id: l.element.id,
|
|
109792
|
+
z: l.element.zIndex,
|
|
109793
|
+
visible: l.element.visible,
|
|
109794
|
+
opacity: l.element.opacity,
|
|
109795
|
+
bounds: `${Math.round(l.element.x)},${Math.round(l.element.y)} ${Math.round(l.element.width)}x${Math.round(l.element.height)}`
|
|
109796
|
+
} : { type: "dom", ids: l.elementIds }
|
|
109797
|
+
)
|
|
109798
|
+
});
|
|
109799
|
+
}
|
|
109800
|
+
for (const [layerIdx, layer] of layers.entries()) {
|
|
109801
|
+
if (layer.type === "hdr") {
|
|
109802
|
+
const before2 = shouldLog ? countNonZeroRgb48(canvas) : 0;
|
|
109803
|
+
const isHdrImage = nativeHdrImageIds.has(layer.element.id);
|
|
109804
|
+
if (isHdrImage) {
|
|
109805
|
+
blitHdrImageLayer(
|
|
109806
|
+
canvas,
|
|
109807
|
+
layer.element,
|
|
109808
|
+
hdrImageBuffers,
|
|
109809
|
+
width,
|
|
109810
|
+
height,
|
|
109811
|
+
log,
|
|
109812
|
+
imageTransfers.get(layer.element.id),
|
|
109813
|
+
effectiveHdr.transfer
|
|
109814
|
+
);
|
|
109815
|
+
} else {
|
|
109816
|
+
blitHdrVideoLayer(
|
|
109817
|
+
canvas,
|
|
109818
|
+
layer.element,
|
|
109819
|
+
time,
|
|
109820
|
+
fps,
|
|
109821
|
+
hdrFrameDirs,
|
|
109822
|
+
hdrVideoStartTimes,
|
|
109823
|
+
width,
|
|
109824
|
+
height,
|
|
109825
|
+
log,
|
|
109826
|
+
videoTransfers.get(layer.element.id),
|
|
109827
|
+
effectiveHdr.transfer
|
|
109828
|
+
);
|
|
109829
|
+
}
|
|
109830
|
+
if (shouldLog) {
|
|
109831
|
+
const after2 = countNonZeroRgb48(canvas);
|
|
109832
|
+
if (isHdrImage) {
|
|
109833
|
+
const buf = hdrImageBuffers.get(layer.element.id);
|
|
109834
|
+
log.info("[diag] hdr layer blit", {
|
|
109835
|
+
frame: debugFrameIndex,
|
|
109836
|
+
layerIdx,
|
|
109837
|
+
id: layer.element.id,
|
|
109838
|
+
kind: "image",
|
|
109839
|
+
pixelsAdded: after2 - before2,
|
|
109840
|
+
totalNonZero: after2,
|
|
109841
|
+
bufferDecoded: !!buf,
|
|
109842
|
+
bufferDims: buf ? `${buf.width}x${buf.height}` : null
|
|
109843
|
+
});
|
|
109844
|
+
} else {
|
|
109845
|
+
const frameDir = hdrFrameDirs.get(layer.element.id);
|
|
109846
|
+
const startTime = hdrVideoStartTimes.get(layer.element.id) ?? 0;
|
|
109847
|
+
const localTime = time - startTime;
|
|
109848
|
+
const frameNum = Math.floor(localTime * fps) + 1;
|
|
109849
|
+
const expectedFrame = frameDir ? join15(frameDir, `frame_${String(frameNum).padStart(4, "0")}.png`) : null;
|
|
109850
|
+
log.info("[diag] hdr layer blit", {
|
|
109851
|
+
frame: debugFrameIndex,
|
|
109852
|
+
layerIdx,
|
|
109853
|
+
id: layer.element.id,
|
|
109854
|
+
kind: "video",
|
|
109855
|
+
pixelsAdded: after2 - before2,
|
|
109856
|
+
totalNonZero: after2,
|
|
109857
|
+
startTime,
|
|
109858
|
+
localTime: localTime.toFixed(3),
|
|
109859
|
+
hdrFrameNum: frameNum,
|
|
109860
|
+
expectedFrame,
|
|
109861
|
+
expectedFrameExists: expectedFrame ? existsSync15(expectedFrame) : false
|
|
109862
|
+
});
|
|
109863
|
+
}
|
|
109864
|
+
}
|
|
109865
|
+
} else {
|
|
109866
|
+
const allElementIds = fullStacking.map((e) => e.id);
|
|
109867
|
+
const layerIds = new Set(layer.elementIds);
|
|
109868
|
+
const hideIds = allElementIds.filter((id) => !layerIds.has(id));
|
|
109869
|
+
await domSession.page.evaluate((t) => {
|
|
109870
|
+
if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
|
|
109871
|
+
}, time);
|
|
109872
|
+
if (beforeCaptureHook) {
|
|
109873
|
+
await beforeCaptureHook(domSession.page, time);
|
|
109874
|
+
}
|
|
109875
|
+
await applyDomLayerMask(domSession.page, layer.elementIds, hideIds);
|
|
109876
|
+
const domPng = await captureAlphaPng(domSession.page, width, height);
|
|
109877
|
+
await removeDomLayerMask(domSession.page, hideIds);
|
|
109878
|
+
try {
|
|
109879
|
+
const { data: domRgba } = decodePng(domPng);
|
|
109880
|
+
const before2 = shouldLog ? countNonZeroRgb48(canvas) : 0;
|
|
109881
|
+
const alphaPixels = shouldLog ? countNonZeroAlpha(domRgba) : 0;
|
|
109882
|
+
blitRgba8OverRgb48le(domRgba, canvas, width, height, effectiveHdr.transfer);
|
|
109883
|
+
if (shouldLog && debugDumpDir) {
|
|
109884
|
+
const after2 = countNonZeroRgb48(canvas);
|
|
109885
|
+
const dumpName = `frame_${String(debugFrameIndex).padStart(4, "0")}_layer_${String(layerIdx).padStart(2, "0")}_dom.png`;
|
|
109886
|
+
const dumpPath = join15(debugDumpDir, dumpName);
|
|
109887
|
+
writeFileSync4(dumpPath, domPng);
|
|
109888
|
+
log.info("[diag] dom layer blit", {
|
|
109889
|
+
frame: debugFrameIndex,
|
|
109890
|
+
layerIdx,
|
|
109891
|
+
layerIds: layer.elementIds,
|
|
109892
|
+
hideCount: hideIds.length,
|
|
109893
|
+
pngBytes: domPng.length,
|
|
109894
|
+
alphaPixels,
|
|
109895
|
+
pixelsAdded: after2 - before2,
|
|
109896
|
+
totalNonZero: after2,
|
|
109897
|
+
dumpPath
|
|
109898
|
+
});
|
|
109899
|
+
}
|
|
109900
|
+
} catch (err) {
|
|
109901
|
+
log.warn("DOM layer decode/blit failed; skipping overlay", {
|
|
109902
|
+
layerIds: layer.elementIds,
|
|
109903
|
+
error: err instanceof Error ? err.message : String(err)
|
|
109904
|
+
});
|
|
109905
|
+
}
|
|
109906
|
+
}
|
|
109907
|
+
}
|
|
109908
|
+
if (shouldLog && debugDumpDir) {
|
|
109909
|
+
const finalNonZero = countNonZeroRgb48(canvas);
|
|
109910
|
+
log.info("[diag] compositeToBuffer end", {
|
|
109911
|
+
frame: debugFrameIndex,
|
|
109912
|
+
finalNonZeroPixels: finalNonZero,
|
|
109913
|
+
totalPixels: width * height,
|
|
109914
|
+
coverage: (finalNonZero / (width * height) * 100).toFixed(1) + "%"
|
|
109915
|
+
});
|
|
109916
|
+
}
|
|
109917
|
+
}
|
|
109624
109918
|
function createRenderJob(config2) {
|
|
109625
109919
|
return {
|
|
109626
109920
|
id: randomUUID(),
|
|
@@ -109662,7 +109956,7 @@ function extractStandaloneEntryFromIndex(indexHtml, entryFile) {
|
|
|
109662
109956
|
}
|
|
109663
109957
|
async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSignal) {
|
|
109664
109958
|
const moduleDir = dirname10(fileURLToPath3(import.meta.url));
|
|
109665
|
-
const producerRoot = process.env.PRODUCER_RENDERS_DIR ?
|
|
109959
|
+
const producerRoot = process.env.PRODUCER_RENDERS_DIR ? resolve11(process.env.PRODUCER_RENDERS_DIR, "..") : resolve11(moduleDir, "../..");
|
|
109666
109960
|
const debugDir = join15(producerRoot, ".debug");
|
|
109667
109961
|
const workDir = job.config.debug ? join15(debugDir, job.id) : join15(dirname10(outputPath), `work-${job.id}`);
|
|
109668
109962
|
const pipelineStart = Date.now();
|
|
@@ -109965,7 +110259,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
109965
110259
|
videoPath = fromCompiled;
|
|
109966
110260
|
}
|
|
109967
110261
|
if (!existsSync15(videoPath)) return;
|
|
109968
|
-
const meta = await
|
|
110262
|
+
const meta = await extractMediaMetadata(videoPath);
|
|
109969
110263
|
if (isHdrColorSpace(meta.colorSpace)) {
|
|
109970
110264
|
nativeHdrVideoIds.add(v.id);
|
|
109971
110265
|
videoTransfers.set(v.id, detectTransfer(meta.colorSpace));
|
|
@@ -109986,7 +110280,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
109986
110280
|
imgPath = fromCompiled;
|
|
109987
110281
|
}
|
|
109988
110282
|
if (!existsSync15(imgPath)) return null;
|
|
109989
|
-
const meta = await
|
|
110283
|
+
const meta = await extractMediaMetadata(imgPath);
|
|
109990
110284
|
if (isHdrColorSpace(meta.colorSpace)) {
|
|
109991
110285
|
nativeHdrImageIds.add(img.id);
|
|
109992
110286
|
imageTransfers.set(img.id, detectTransfer(meta.colorSpace));
|
|
@@ -110098,6 +110392,10 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110098
110392
|
format: needsAlpha ? "png" : "jpeg",
|
|
110099
110393
|
quality: needsAlpha ? void 0 : job.config.quality === "draft" ? 80 : 95
|
|
110100
110394
|
};
|
|
110395
|
+
const buildHdrCaptureOptions = () => ({
|
|
110396
|
+
...captureOptions,
|
|
110397
|
+
skipReadinessVideoIds: Array.from(nativeHdrVideoIds)
|
|
110398
|
+
});
|
|
110101
110399
|
const workerCount = calculateOptimalWorkers(totalFrames, job.config.workers, cfg);
|
|
110102
110400
|
const FORMAT_EXT = { mp4: ".mp4", webm: ".webm", mov: ".mov" };
|
|
110103
110401
|
const videoExt = FORMAT_EXT[outputFormat] ?? ".mp4";
|
|
@@ -110106,6 +110404,13 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110106
110404
|
const hasHdrContent = effectiveHdr && nativeHdrIds.size > 0;
|
|
110107
110405
|
const encoderHdr = hasHdrContent ? effectiveHdr : void 0;
|
|
110108
110406
|
const preset = getEncoderPreset(job.config.quality, outputFormat, encoderHdr);
|
|
110407
|
+
if (job.config.crf != null && job.config.videoBitrate) {
|
|
110408
|
+
log.warn(
|
|
110409
|
+
`[Render] Both crf=${job.config.crf} and videoBitrate=${job.config.videoBitrate} were set. These are mutually exclusive; honoring crf and ignoring videoBitrate. Set only one to silence this warning.`
|
|
110410
|
+
);
|
|
110411
|
+
}
|
|
110412
|
+
const effectiveQuality = job.config.crf ?? preset.quality;
|
|
110413
|
+
const effectiveBitrate = job.config.crf != null ? void 0 : job.config.videoBitrate;
|
|
110109
110414
|
job.framesRendered = 0;
|
|
110110
110415
|
if (hasHdrContent) {
|
|
110111
110416
|
log.info("[Render] HDR layered composite: z-ordered DOM + native HLG video layers");
|
|
@@ -110125,516 +110430,440 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110125
110430
|
const domSession = await createCaptureSession(
|
|
110126
110431
|
fileServer.url,
|
|
110127
110432
|
framesDir,
|
|
110128
|
-
|
|
110433
|
+
buildHdrCaptureOptions(),
|
|
110129
110434
|
createVideoFrameInjector(frameLookup),
|
|
110130
110435
|
cfg
|
|
110131
110436
|
);
|
|
110132
|
-
|
|
110133
|
-
|
|
110134
|
-
|
|
110135
|
-
await initTransparentBackground(domSession.page);
|
|
110136
|
-
const transitionMeta = await domSession.page.evaluate(() => {
|
|
110137
|
-
return window.__hf?.transitions ?? [];
|
|
110138
|
-
});
|
|
110139
|
-
const sceneElements = await domSession.page.evaluate(() => {
|
|
110140
|
-
const scenes = document.querySelectorAll(".scene");
|
|
110141
|
-
const map2 = {};
|
|
110142
|
-
for (const scene of scenes) {
|
|
110143
|
-
const els = scene.querySelectorAll("[data-start]");
|
|
110144
|
-
map2[scene.id] = Array.from(els).map((e) => e.id);
|
|
110145
|
-
}
|
|
110146
|
-
return map2;
|
|
110147
|
-
});
|
|
110148
|
-
const transitionRanges = transitionMeta.map((t) => ({
|
|
110149
|
-
...t,
|
|
110150
|
-
startFrame: Math.floor(t.time * job.config.fps),
|
|
110151
|
-
endFrame: Math.ceil((t.time + t.duration) * job.config.fps)
|
|
110152
|
-
}));
|
|
110153
|
-
if (transitionRanges.length > 0) {
|
|
110154
|
-
log.info("[Render] Detected shader transitions for HDR compositing", {
|
|
110155
|
-
count: transitionRanges.length,
|
|
110156
|
-
transitions: transitionRanges.map((t) => ({
|
|
110157
|
-
shader: t.shader,
|
|
110158
|
-
from: t.fromScene,
|
|
110159
|
-
to: t.toScene,
|
|
110160
|
-
frames: `${t.startFrame}-${t.endFrame}`
|
|
110161
|
-
}))
|
|
110162
|
-
});
|
|
110163
|
-
}
|
|
110164
|
-
const hdrEncoder = await spawnStreamingEncoder(
|
|
110165
|
-
videoOnlyPath,
|
|
110166
|
-
{
|
|
110167
|
-
fps: job.config.fps,
|
|
110168
|
-
width,
|
|
110169
|
-
height,
|
|
110170
|
-
codec: preset.codec,
|
|
110171
|
-
preset: preset.preset,
|
|
110172
|
-
quality: preset.quality,
|
|
110173
|
-
pixelFormat: preset.pixelFormat,
|
|
110174
|
-
hdr: preset.hdr,
|
|
110175
|
-
rawInputFormat: "rgb48le"
|
|
110176
|
-
},
|
|
110177
|
-
abortSignal,
|
|
110178
|
-
{ ffmpegStreamingTimeout: 36e5 }
|
|
110179
|
-
);
|
|
110180
|
-
assertNotAborted();
|
|
110181
|
-
const hdrExtractionDims = /* @__PURE__ */ new Map();
|
|
110182
|
-
const hdrImageFitInfo = /* @__PURE__ */ new Map();
|
|
110183
|
-
const hdrVideoStartTimes = /* @__PURE__ */ new Map();
|
|
110184
|
-
for (const v of composition.videos) {
|
|
110185
|
-
if (hdrVideoIds.includes(v.id)) {
|
|
110186
|
-
hdrVideoStartTimes.set(v.id, v.start);
|
|
110187
|
-
}
|
|
110188
|
-
}
|
|
110189
|
-
const hdrImageStartTimes = /* @__PURE__ */ new Map();
|
|
110190
|
-
for (const img of composition.images) {
|
|
110191
|
-
if (nativeHdrImageIds.has(img.id)) {
|
|
110192
|
-
hdrImageStartTimes.set(img.id, img.start);
|
|
110193
|
-
}
|
|
110194
|
-
}
|
|
110195
|
-
const uniqueStartTimes = [
|
|
110196
|
-
.../* @__PURE__ */ new Set([...hdrVideoStartTimes.values(), ...hdrImageStartTimes.values()])
|
|
110197
|
-
].sort((a, b) => a - b);
|
|
110198
|
-
for (const seekTime of uniqueStartTimes) {
|
|
110199
|
-
await domSession.page.evaluate((t) => {
|
|
110200
|
-
if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
|
|
110201
|
-
}, seekTime);
|
|
110202
|
-
if (domSession.onBeforeCapture) {
|
|
110203
|
-
await domSession.onBeforeCapture(domSession.page, seekTime);
|
|
110204
|
-
}
|
|
110205
|
-
const stacking = await queryElementStacking(domSession.page, nativeHdrIds);
|
|
110206
|
-
for (const el of stacking) {
|
|
110207
|
-
if (el.isHdr && el.layoutWidth > 0 && el.layoutHeight > 0 && !hdrExtractionDims.has(el.id)) {
|
|
110208
|
-
hdrExtractionDims.set(el.id, { width: el.layoutWidth, height: el.layoutHeight });
|
|
110209
|
-
}
|
|
110210
|
-
if (el.isHdr && nativeHdrImageIds.has(el.id) && !hdrImageFitInfo.has(el.id)) {
|
|
110211
|
-
hdrImageFitInfo.set(el.id, {
|
|
110212
|
-
fit: el.objectFit,
|
|
110213
|
-
position: el.objectPosition
|
|
110214
|
-
});
|
|
110215
|
-
}
|
|
110216
|
-
}
|
|
110217
|
-
}
|
|
110437
|
+
let hdrEncoder = null;
|
|
110438
|
+
let hdrEncoderClosed = false;
|
|
110439
|
+
let domSessionClosed = false;
|
|
110218
110440
|
const hdrFrameDirs = /* @__PURE__ */ new Map();
|
|
110219
|
-
|
|
110220
|
-
|
|
110221
|
-
|
|
110222
|
-
|
|
110223
|
-
|
|
110224
|
-
const
|
|
110225
|
-
|
|
110226
|
-
|
|
110227
|
-
|
|
110228
|
-
|
|
110229
|
-
|
|
110230
|
-
|
|
110231
|
-
|
|
110232
|
-
|
|
110233
|
-
"-r",
|
|
110234
|
-
String(job.config.fps),
|
|
110235
|
-
"-vf",
|
|
110236
|
-
`scale=${dims.width}:${dims.height}:force_original_aspect_ratio=increase,crop=${dims.width}:${dims.height}`,
|
|
110237
|
-
"-pix_fmt",
|
|
110238
|
-
"rgb48le",
|
|
110239
|
-
"-c:v",
|
|
110240
|
-
"png",
|
|
110241
|
-
"-y",
|
|
110242
|
-
join15(frameDir, "frame_%04d.png")
|
|
110243
|
-
];
|
|
110244
|
-
const result = await runFfmpeg(ffmpegArgs, { signal: abortSignal });
|
|
110245
|
-
if (!result.success) {
|
|
110246
|
-
hdrDiagnostics.videoExtractionFailures += 1;
|
|
110247
|
-
log.error("HDR frame pre-extraction failed; aborting render", {
|
|
110248
|
-
videoId,
|
|
110249
|
-
srcPath,
|
|
110250
|
-
stderr: result.stderr.slice(-400)
|
|
110251
|
-
});
|
|
110252
|
-
throw new Error(
|
|
110253
|
-
`HDR frame extraction failed for video "${videoId}". Aborting render to avoid shipping black HDR layers.`
|
|
110254
|
-
);
|
|
110255
|
-
}
|
|
110256
|
-
hdrFrameDirs.set(videoId, frameDir);
|
|
110257
|
-
}
|
|
110258
|
-
const hdrImageBuffers = /* @__PURE__ */ new Map();
|
|
110259
|
-
for (const [imageId, srcPath] of hdrImageSrcPaths) {
|
|
110260
|
-
try {
|
|
110261
|
-
const decoded = decodePngToRgb48le(readFileSync10(srcPath));
|
|
110262
|
-
const layout2 = hdrExtractionDims.get(imageId);
|
|
110263
|
-
const fitInfo = hdrImageFitInfo.get(imageId);
|
|
110264
|
-
if (layout2 && (layout2.width !== decoded.width || layout2.height !== decoded.height)) {
|
|
110265
|
-
const fit = normalizeObjectFit(fitInfo?.fit);
|
|
110266
|
-
const resampled = resampleRgb48leObjectFit(
|
|
110267
|
-
decoded.data,
|
|
110268
|
-
decoded.width,
|
|
110269
|
-
decoded.height,
|
|
110270
|
-
layout2.width,
|
|
110271
|
-
layout2.height,
|
|
110272
|
-
fit,
|
|
110273
|
-
fitInfo?.position
|
|
110274
|
-
);
|
|
110275
|
-
hdrImageBuffers.set(imageId, {
|
|
110276
|
-
data: resampled,
|
|
110277
|
-
width: layout2.width,
|
|
110278
|
-
height: layout2.height
|
|
110279
|
-
});
|
|
110280
|
-
} else {
|
|
110281
|
-
hdrImageBuffers.set(imageId, {
|
|
110282
|
-
data: Buffer.from(decoded.data),
|
|
110283
|
-
width: decoded.width,
|
|
110284
|
-
height: decoded.height
|
|
110285
|
-
});
|
|
110441
|
+
try {
|
|
110442
|
+
await initializeSession(domSession);
|
|
110443
|
+
assertNotAborted();
|
|
110444
|
+
lastBrowserConsole = domSession.browserConsoleBuffer;
|
|
110445
|
+
await initTransparentBackground(domSession.page);
|
|
110446
|
+
const transitionMeta = await domSession.page.evaluate(() => {
|
|
110447
|
+
return window.__hf?.transitions ?? [];
|
|
110448
|
+
});
|
|
110449
|
+
const sceneElements = await domSession.page.evaluate(() => {
|
|
110450
|
+
const scenes = document.querySelectorAll(".scene");
|
|
110451
|
+
const map2 = {};
|
|
110452
|
+
for (const scene of scenes) {
|
|
110453
|
+
const els = scene.querySelectorAll("[data-start]");
|
|
110454
|
+
map2[scene.id] = Array.from(els).map((e) => e.id);
|
|
110286
110455
|
}
|
|
110287
|
-
|
|
110288
|
-
|
|
110289
|
-
|
|
110290
|
-
|
|
110291
|
-
|
|
110292
|
-
|
|
110456
|
+
return map2;
|
|
110457
|
+
});
|
|
110458
|
+
const transitionRanges = transitionMeta.map((t) => ({
|
|
110459
|
+
...t,
|
|
110460
|
+
startFrame: Math.floor(t.time * job.config.fps),
|
|
110461
|
+
endFrame: Math.ceil((t.time + t.duration) * job.config.fps)
|
|
110462
|
+
}));
|
|
110463
|
+
if (transitionRanges.length > 0) {
|
|
110464
|
+
log.info("[Render] Detected shader transitions for HDR compositing", {
|
|
110465
|
+
count: transitionRanges.length,
|
|
110466
|
+
transitions: transitionRanges.map((t) => ({
|
|
110467
|
+
shader: t.shader,
|
|
110468
|
+
from: t.fromScene,
|
|
110469
|
+
to: t.toScene,
|
|
110470
|
+
frames: `${t.startFrame}-${t.endFrame}`
|
|
110471
|
+
}))
|
|
110293
110472
|
});
|
|
110294
|
-
throw new Error(
|
|
110295
|
-
`HDR image decode failed for image "${imageId}". Aborting render to avoid shipping missing HDR image layers.`
|
|
110296
|
-
);
|
|
110297
110473
|
}
|
|
110298
|
-
|
|
110299
|
-
|
|
110300
|
-
|
|
110301
|
-
|
|
110302
|
-
|
|
110303
|
-
|
|
110304
|
-
|
|
110474
|
+
hdrEncoder = await spawnStreamingEncoder(
|
|
110475
|
+
videoOnlyPath,
|
|
110476
|
+
{
|
|
110477
|
+
fps: job.config.fps,
|
|
110478
|
+
width,
|
|
110479
|
+
height,
|
|
110480
|
+
codec: preset.codec,
|
|
110481
|
+
preset: preset.preset,
|
|
110482
|
+
quality: effectiveQuality,
|
|
110483
|
+
bitrate: effectiveBitrate,
|
|
110484
|
+
pixelFormat: preset.pixelFormat,
|
|
110485
|
+
hdr: preset.hdr,
|
|
110486
|
+
rawInputFormat: "rgb48le"
|
|
110487
|
+
},
|
|
110488
|
+
abortSignal,
|
|
110489
|
+
{ ffmpegStreamingTimeout: 36e5 }
|
|
110490
|
+
);
|
|
110491
|
+
assertNotAborted();
|
|
110492
|
+
const hdrExtractionDims = /* @__PURE__ */ new Map();
|
|
110493
|
+
const hdrImageFitInfo = /* @__PURE__ */ new Map();
|
|
110494
|
+
const hdrVideoStartTimes = /* @__PURE__ */ new Map();
|
|
110495
|
+
for (const v of composition.videos) {
|
|
110496
|
+
if (hdrVideoIds.includes(v.id)) {
|
|
110497
|
+
hdrVideoStartTimes.set(v.id, v.start);
|
|
110305
110498
|
}
|
|
110306
|
-
|
|
110307
|
-
|
|
110308
|
-
|
|
110309
|
-
|
|
110310
|
-
|
|
110499
|
+
}
|
|
110500
|
+
const hdrImageStartTimes = /* @__PURE__ */ new Map();
|
|
110501
|
+
for (const img of composition.images) {
|
|
110502
|
+
if (nativeHdrImageIds.has(img.id)) {
|
|
110503
|
+
hdrImageStartTimes.set(img.id, img.start);
|
|
110311
110504
|
}
|
|
110312
|
-
|
|
110313
|
-
|
|
110314
|
-
|
|
110315
|
-
|
|
110316
|
-
const
|
|
110317
|
-
|
|
110318
|
-
|
|
110319
|
-
|
|
110320
|
-
|
|
110321
|
-
|
|
110322
|
-
|
|
110323
|
-
|
|
110324
|
-
|
|
110325
|
-
|
|
110326
|
-
|
|
110327
|
-
|
|
110328
|
-
|
|
110329
|
-
|
|
110330
|
-
|
|
110331
|
-
|
|
110332
|
-
|
|
110333
|
-
|
|
110334
|
-
frame: debugFrameIndex,
|
|
110335
|
-
time: time.toFixed(3),
|
|
110336
|
-
filterSize: elementFilter?.size,
|
|
110337
|
-
fullStackingCount: fullStacking.length,
|
|
110338
|
-
filteredCount: filteredStacking.length,
|
|
110339
|
-
layerCount: layers.length,
|
|
110340
|
-
layers: layers.map(
|
|
110341
|
-
(l) => l.type === "hdr" ? {
|
|
110342
|
-
type: "hdr",
|
|
110343
|
-
id: l.element.id,
|
|
110344
|
-
z: l.element.zIndex,
|
|
110345
|
-
visible: l.element.visible,
|
|
110346
|
-
opacity: l.element.opacity,
|
|
110347
|
-
bounds: `${Math.round(l.element.x)},${Math.round(l.element.y)} ${Math.round(l.element.width)}x${Math.round(l.element.height)}`
|
|
110348
|
-
} : { type: "dom", ids: l.elementIds }
|
|
110349
|
-
)
|
|
110350
|
-
});
|
|
110505
|
+
}
|
|
110506
|
+
const uniqueStartTimes = [
|
|
110507
|
+
.../* @__PURE__ */ new Set([...hdrVideoStartTimes.values(), ...hdrImageStartTimes.values()])
|
|
110508
|
+
].sort((a, b) => a - b);
|
|
110509
|
+
for (const seekTime of uniqueStartTimes) {
|
|
110510
|
+
await domSession.page.evaluate((t) => {
|
|
110511
|
+
if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
|
|
110512
|
+
}, seekTime);
|
|
110513
|
+
if (domSession.onBeforeCapture) {
|
|
110514
|
+
await domSession.onBeforeCapture(domSession.page, seekTime);
|
|
110515
|
+
}
|
|
110516
|
+
const stacking = await queryElementStacking(domSession.page, nativeHdrIds);
|
|
110517
|
+
for (const el of stacking) {
|
|
110518
|
+
if (el.isHdr && el.layoutWidth > 0 && el.layoutHeight > 0 && !hdrExtractionDims.has(el.id)) {
|
|
110519
|
+
hdrExtractionDims.set(el.id, { width: el.layoutWidth, height: el.layoutHeight });
|
|
110520
|
+
}
|
|
110521
|
+
if (el.isHdr && nativeHdrImageIds.has(el.id) && !hdrImageFitInfo.has(el.id)) {
|
|
110522
|
+
hdrImageFitInfo.set(el.id, {
|
|
110523
|
+
fit: el.objectFit,
|
|
110524
|
+
position: el.objectPosition
|
|
110525
|
+
});
|
|
110526
|
+
}
|
|
110351
110527
|
}
|
|
110352
|
-
|
|
110353
|
-
|
|
110354
|
-
|
|
110355
|
-
|
|
110356
|
-
|
|
110357
|
-
|
|
110358
|
-
|
|
110359
|
-
|
|
110360
|
-
|
|
110361
|
-
|
|
110362
|
-
|
|
110363
|
-
|
|
110364
|
-
|
|
110365
|
-
|
|
110366
|
-
|
|
110367
|
-
|
|
110368
|
-
|
|
110369
|
-
|
|
110370
|
-
|
|
110371
|
-
time,
|
|
110372
|
-
job.config.fps,
|
|
110373
|
-
hdrFrameDirs,
|
|
110374
|
-
hdrVideoStartTimes,
|
|
110375
|
-
width,
|
|
110376
|
-
height,
|
|
110377
|
-
log,
|
|
110378
|
-
videoTransfers.get(layer.element.id),
|
|
110379
|
-
effectiveHdr?.transfer
|
|
110380
|
-
);
|
|
110381
|
-
}
|
|
110382
|
-
if (shouldLog) {
|
|
110383
|
-
const after2 = countNonZeroRgb482(canvas);
|
|
110384
|
-
if (isHdrImage) {
|
|
110385
|
-
const buf = hdrImageBuffers.get(layer.element.id);
|
|
110386
|
-
log.info("[diag] hdr layer blit", {
|
|
110387
|
-
frame: debugFrameIndex,
|
|
110388
|
-
layerIdx,
|
|
110389
|
-
id: layer.element.id,
|
|
110390
|
-
kind: "image",
|
|
110391
|
-
pixelsAdded: after2 - before2,
|
|
110392
|
-
totalNonZero: after2,
|
|
110393
|
-
bufferDecoded: !!buf,
|
|
110394
|
-
bufferDims: buf ? `${buf.width}x${buf.height}` : null
|
|
110395
|
-
});
|
|
110396
|
-
} else {
|
|
110397
|
-
const frameDir = hdrFrameDirs.get(layer.element.id);
|
|
110398
|
-
const startTime = hdrVideoStartTimes.get(layer.element.id) ?? 0;
|
|
110399
|
-
const localTime = time - startTime;
|
|
110400
|
-
const frameNum = Math.floor(localTime * job.config.fps) + 1;
|
|
110401
|
-
const expectedFrame = frameDir ? join15(frameDir, `frame_${String(frameNum).padStart(4, "0")}.png`) : null;
|
|
110402
|
-
log.info("[diag] hdr layer blit", {
|
|
110403
|
-
frame: debugFrameIndex,
|
|
110404
|
-
layerIdx,
|
|
110405
|
-
id: layer.element.id,
|
|
110406
|
-
kind: "video",
|
|
110407
|
-
pixelsAdded: after2 - before2,
|
|
110408
|
-
totalNonZero: after2,
|
|
110409
|
-
startTime,
|
|
110410
|
-
localTime: localTime.toFixed(3),
|
|
110411
|
-
hdrFrameNum: frameNum,
|
|
110412
|
-
expectedFrame,
|
|
110413
|
-
expectedFrameExists: expectedFrame ? existsSync15(expectedFrame) : false
|
|
110414
|
-
});
|
|
110415
|
-
}
|
|
110416
|
-
}
|
|
110417
|
-
} else {
|
|
110418
|
-
const allElementIds = fullStacking.map((e) => e.id);
|
|
110419
|
-
const layerIds = new Set(layer.elementIds);
|
|
110420
|
-
const hideIds = allElementIds.filter((id) => !layerIds.has(id));
|
|
110421
|
-
await domSession.page.evaluate((t) => {
|
|
110422
|
-
if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
|
|
110423
|
-
}, time);
|
|
110424
|
-
if (beforeCaptureHook) {
|
|
110425
|
-
await beforeCaptureHook(domSession.page, time);
|
|
110426
|
-
}
|
|
110427
|
-
await applyDomLayerMask(domSession.page, layer.elementIds, hideIds);
|
|
110428
|
-
const domPng = await captureAlphaPng(domSession.page, width, height);
|
|
110429
|
-
await removeDomLayerMask(domSession.page, hideIds);
|
|
110430
|
-
try {
|
|
110431
|
-
const { data: domRgba } = decodePng(domPng);
|
|
110432
|
-
if (!effectiveHdr) {
|
|
110433
|
-
throw new Error(
|
|
110434
|
-
"Invariant violation: effectiveHdr is undefined inside HDR layer branch"
|
|
110435
|
-
);
|
|
110436
|
-
}
|
|
110437
|
-
const before2 = shouldLog ? countNonZeroRgb482(canvas) : 0;
|
|
110438
|
-
const alphaPixels = shouldLog ? countNonZeroAlpha2(domRgba) : 0;
|
|
110439
|
-
blitRgba8OverRgb48le(domRgba, canvas, width, height, effectiveHdr.transfer);
|
|
110440
|
-
if (shouldLog && debugDumpDir) {
|
|
110441
|
-
const after2 = countNonZeroRgb482(canvas);
|
|
110442
|
-
const dumpName = `frame_${String(debugFrameIndex).padStart(4, "0")}_layer_${String(layerIdx).padStart(2, "0")}_dom.png`;
|
|
110443
|
-
const dumpPath = join15(debugDumpDir, dumpName);
|
|
110444
|
-
writeFileSync4(dumpPath, domPng);
|
|
110445
|
-
log.info("[diag] dom layer blit", {
|
|
110446
|
-
frame: debugFrameIndex,
|
|
110447
|
-
layerIdx,
|
|
110448
|
-
layerIds: layer.elementIds,
|
|
110449
|
-
hideCount: hideIds.length,
|
|
110450
|
-
pngBytes: domPng.length,
|
|
110451
|
-
alphaPixels,
|
|
110452
|
-
pixelsAdded: after2 - before2,
|
|
110453
|
-
totalNonZero: after2,
|
|
110454
|
-
dumpPath
|
|
110455
|
-
});
|
|
110456
|
-
}
|
|
110457
|
-
} catch (err) {
|
|
110458
|
-
log.warn("DOM layer decode/blit failed; skipping overlay", {
|
|
110459
|
-
layerIds: layer.elementIds,
|
|
110460
|
-
error: err instanceof Error ? err.message : String(err)
|
|
110461
|
-
});
|
|
110528
|
+
}
|
|
110529
|
+
for (const [imageId, startTime] of hdrImageStartTimes) {
|
|
110530
|
+
if (hdrExtractionDims.has(imageId)) continue;
|
|
110531
|
+
const img = composition.images.find((i) => i.id === imageId);
|
|
110532
|
+
if (!img) continue;
|
|
110533
|
+
const duration = img.end - img.start;
|
|
110534
|
+
const retryTime = startTime + Math.min(0.5, duration * 0.1);
|
|
110535
|
+
await domSession.page.evaluate((t) => {
|
|
110536
|
+
if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
|
|
110537
|
+
}, retryTime);
|
|
110538
|
+
if (domSession.onBeforeCapture) {
|
|
110539
|
+
await domSession.onBeforeCapture(domSession.page, retryTime);
|
|
110540
|
+
}
|
|
110541
|
+
const retryStacking = await queryElementStacking(domSession.page, nativeHdrIds);
|
|
110542
|
+
for (const el of retryStacking) {
|
|
110543
|
+
if (el.id === imageId && el.isHdr && el.layoutWidth > 0 && el.layoutHeight > 0) {
|
|
110544
|
+
hdrExtractionDims.set(el.id, { width: el.layoutWidth, height: el.layoutHeight });
|
|
110545
|
+
if (!hdrImageFitInfo.has(el.id)) {
|
|
110546
|
+
hdrImageFitInfo.set(el.id, { fit: el.objectFit, position: el.objectPosition });
|
|
110462
110547
|
}
|
|
110548
|
+
break;
|
|
110463
110549
|
}
|
|
110464
110550
|
}
|
|
110465
|
-
|
|
110466
|
-
|
|
110467
|
-
|
|
110468
|
-
|
|
110469
|
-
|
|
110470
|
-
|
|
110471
|
-
|
|
110551
|
+
}
|
|
110552
|
+
for (const [videoId, srcPath] of hdrVideoSrcPaths) {
|
|
110553
|
+
const video = composition.videos.find((v) => v.id === videoId);
|
|
110554
|
+
if (!video) continue;
|
|
110555
|
+
const frameDir = join15(framesDir, `hdr_${videoId}`);
|
|
110556
|
+
mkdirSync10(frameDir, { recursive: true });
|
|
110557
|
+
const duration = video.end - video.start;
|
|
110558
|
+
const dims = hdrExtractionDims.get(videoId) ?? { width, height };
|
|
110559
|
+
const ffmpegArgs = [
|
|
110560
|
+
"-ss",
|
|
110561
|
+
String(video.mediaStart),
|
|
110562
|
+
"-i",
|
|
110563
|
+
srcPath,
|
|
110564
|
+
"-t",
|
|
110565
|
+
String(duration),
|
|
110566
|
+
"-r",
|
|
110567
|
+
String(job.config.fps),
|
|
110568
|
+
"-vf",
|
|
110569
|
+
`scale=${dims.width}:${dims.height}:force_original_aspect_ratio=increase,crop=${dims.width}:${dims.height}`,
|
|
110570
|
+
"-pix_fmt",
|
|
110571
|
+
"rgb48le",
|
|
110572
|
+
"-c:v",
|
|
110573
|
+
"png",
|
|
110574
|
+
"-y",
|
|
110575
|
+
join15(frameDir, "frame_%04d.png")
|
|
110576
|
+
];
|
|
110577
|
+
const result = await runFfmpeg(ffmpegArgs, { signal: abortSignal });
|
|
110578
|
+
if (!result.success) {
|
|
110579
|
+
hdrDiagnostics.videoExtractionFailures += 1;
|
|
110580
|
+
log.error("HDR frame pre-extraction failed; aborting render", {
|
|
110581
|
+
videoId,
|
|
110582
|
+
srcPath,
|
|
110583
|
+
stderr: result.stderr.slice(-400)
|
|
110472
110584
|
});
|
|
110585
|
+
throw new Error(
|
|
110586
|
+
`HDR frame extraction failed for video "${videoId}". Aborting render to avoid shipping black HDR layers.`
|
|
110587
|
+
);
|
|
110473
110588
|
}
|
|
110589
|
+
hdrFrameDirs.set(videoId, frameDir);
|
|
110474
110590
|
}
|
|
110475
|
-
const
|
|
110476
|
-
const
|
|
110477
|
-
|
|
110478
|
-
|
|
110479
|
-
|
|
110480
|
-
|
|
110481
|
-
|
|
110482
|
-
|
|
110483
|
-
|
|
110484
|
-
|
|
110485
|
-
|
|
110486
|
-
|
|
110487
|
-
|
|
110488
|
-
|
|
110489
|
-
|
|
110490
|
-
|
|
110491
|
-
|
|
110492
|
-
|
|
110493
|
-
|
|
110494
|
-
|
|
110495
|
-
|
|
110496
|
-
|
|
110497
|
-
|
|
110498
|
-
|
|
110499
|
-
|
|
110500
|
-
|
|
110501
|
-
|
|
110591
|
+
const hdrImageBuffers = /* @__PURE__ */ new Map();
|
|
110592
|
+
for (const [imageId, srcPath] of hdrImageSrcPaths) {
|
|
110593
|
+
try {
|
|
110594
|
+
const decoded = decodePngToRgb48le(readFileSync10(srcPath));
|
|
110595
|
+
const layout2 = hdrExtractionDims.get(imageId);
|
|
110596
|
+
const fitInfo = hdrImageFitInfo.get(imageId);
|
|
110597
|
+
if (layout2 && (layout2.width !== decoded.width || layout2.height !== decoded.height)) {
|
|
110598
|
+
const fit = normalizeObjectFit(fitInfo?.fit);
|
|
110599
|
+
const resampled = resampleRgb48leObjectFit(
|
|
110600
|
+
decoded.data,
|
|
110601
|
+
decoded.width,
|
|
110602
|
+
decoded.height,
|
|
110603
|
+
layout2.width,
|
|
110604
|
+
layout2.height,
|
|
110605
|
+
fit,
|
|
110606
|
+
fitInfo?.position
|
|
110607
|
+
);
|
|
110608
|
+
hdrImageBuffers.set(imageId, {
|
|
110609
|
+
data: resampled,
|
|
110610
|
+
width: layout2.width,
|
|
110611
|
+
height: layout2.height
|
|
110612
|
+
});
|
|
110613
|
+
} else {
|
|
110614
|
+
hdrImageBuffers.set(imageId, {
|
|
110615
|
+
data: Buffer.from(decoded.data),
|
|
110616
|
+
width: decoded.width,
|
|
110617
|
+
height: decoded.height
|
|
110618
|
+
});
|
|
110619
|
+
}
|
|
110620
|
+
} catch (err) {
|
|
110621
|
+
hdrDiagnostics.imageDecodeFailures += 1;
|
|
110622
|
+
log.error("HDR image decode failed; aborting render", {
|
|
110623
|
+
imageId,
|
|
110624
|
+
srcPath,
|
|
110625
|
+
error: err instanceof Error ? err.message : String(err)
|
|
110502
110626
|
});
|
|
110627
|
+
throw new Error(
|
|
110628
|
+
`HDR image decode failed for image "${imageId}". Aborting render to avoid shipping missing HDR image layers.`
|
|
110629
|
+
);
|
|
110503
110630
|
}
|
|
110504
|
-
|
|
110505
|
-
|
|
110506
|
-
|
|
110507
|
-
|
|
110508
|
-
|
|
110509
|
-
|
|
110510
|
-
|
|
110511
|
-
|
|
110512
|
-
|
|
110513
|
-
|
|
110514
|
-
|
|
110515
|
-
|
|
110516
|
-
|
|
110517
|
-
|
|
110518
|
-
|
|
110519
|
-
|
|
110520
|
-
|
|
110521
|
-
|
|
110522
|
-
|
|
110523
|
-
|
|
110524
|
-
|
|
110525
|
-
|
|
110526
|
-
|
|
110527
|
-
|
|
110528
|
-
|
|
110529
|
-
|
|
110530
|
-
|
|
110531
|
-
|
|
110532
|
-
|
|
110533
|
-
|
|
110534
|
-
|
|
110631
|
+
}
|
|
110632
|
+
assertNotAborted();
|
|
110633
|
+
try {
|
|
110634
|
+
const beforeCaptureHook = domSession.onBeforeCapture;
|
|
110635
|
+
const cleanedUpVideos = /* @__PURE__ */ new Set();
|
|
110636
|
+
const hdrVideoEndTimes = /* @__PURE__ */ new Map();
|
|
110637
|
+
for (const v of composition.videos) {
|
|
110638
|
+
if (hdrFrameDirs.has(v.id)) {
|
|
110639
|
+
hdrVideoEndTimes.set(v.id, v.end);
|
|
110640
|
+
}
|
|
110641
|
+
}
|
|
110642
|
+
const debugDumpEnabled = process.env.KEEP_TEMP === "1";
|
|
110643
|
+
const debugDumpDir = debugDumpEnabled ? join15(framesDir, "debug-composite") : null;
|
|
110644
|
+
if (debugDumpDir && !existsSync15(debugDumpDir)) {
|
|
110645
|
+
mkdirSync10(debugDumpDir, { recursive: true });
|
|
110646
|
+
}
|
|
110647
|
+
if (!effectiveHdr) {
|
|
110648
|
+
throw new Error(
|
|
110649
|
+
"Internal: HDR render path entered without effectiveHdr \u2014 this is a bug."
|
|
110650
|
+
);
|
|
110651
|
+
}
|
|
110652
|
+
const hdrCompositeCtx = {
|
|
110653
|
+
log,
|
|
110654
|
+
domSession,
|
|
110655
|
+
beforeCaptureHook,
|
|
110656
|
+
width,
|
|
110657
|
+
height,
|
|
110658
|
+
fps: job.config.fps,
|
|
110659
|
+
effectiveHdr,
|
|
110660
|
+
nativeHdrImageIds,
|
|
110661
|
+
hdrImageBuffers,
|
|
110662
|
+
hdrFrameDirs,
|
|
110663
|
+
hdrVideoStartTimes,
|
|
110664
|
+
imageTransfers,
|
|
110665
|
+
videoTransfers,
|
|
110666
|
+
debugDumpEnabled,
|
|
110667
|
+
debugDumpDir
|
|
110668
|
+
};
|
|
110669
|
+
const bufSize = width * height * 6;
|
|
110670
|
+
const hasTransitions = transitionRanges.length > 0;
|
|
110671
|
+
const transBufferA = hasTransitions ? Buffer.alloc(bufSize) : null;
|
|
110672
|
+
const transBufferB = hasTransitions ? Buffer.alloc(bufSize) : null;
|
|
110673
|
+
const transOutput = hasTransitions ? Buffer.alloc(bufSize) : null;
|
|
110674
|
+
const normalCanvas = Buffer.alloc(bufSize);
|
|
110675
|
+
for (let i = 0; i < totalFrames; i++) {
|
|
110676
|
+
assertNotAborted();
|
|
110677
|
+
const time = i / job.config.fps;
|
|
110678
|
+
await domSession.page.evaluate((t) => {
|
|
110679
|
+
if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
|
|
110680
|
+
}, time);
|
|
110681
|
+
if (beforeCaptureHook) {
|
|
110682
|
+
await beforeCaptureHook(domSession.page, time);
|
|
110683
|
+
}
|
|
110684
|
+
const stackingInfo = await queryElementStacking(domSession.page, nativeHdrIds);
|
|
110685
|
+
const activeTransition = transitionRanges.find(
|
|
110686
|
+
(t) => i >= t.startFrame && i <= t.endFrame
|
|
110687
|
+
);
|
|
110688
|
+
if (i % 30 === 0) {
|
|
110689
|
+
const hdrEl = stackingInfo.find((e) => e.isHdr);
|
|
110690
|
+
log.debug("[Render] HDR layer composite frame", {
|
|
110691
|
+
frame: i,
|
|
110692
|
+
time: time.toFixed(2),
|
|
110693
|
+
hdrElement: hdrEl ? { z: hdrEl.zIndex, visible: hdrEl.visible, width: hdrEl.width } : null,
|
|
110694
|
+
stackingCount: stackingInfo.length,
|
|
110695
|
+
activeTransition: activeTransition?.shader
|
|
110696
|
+
});
|
|
110697
|
+
}
|
|
110698
|
+
if (activeTransition && transBufferA && transBufferB && transOutput) {
|
|
110699
|
+
const progress = activeTransition.endFrame === activeTransition.startFrame ? 1 : (i - activeTransition.startFrame) / (activeTransition.endFrame - activeTransition.startFrame);
|
|
110700
|
+
const sceneAIds = new Set(sceneElements[activeTransition.fromScene] ?? []);
|
|
110701
|
+
const sceneBIds = new Set(sceneElements[activeTransition.toScene] ?? []);
|
|
110702
|
+
transBufferA.fill(0);
|
|
110703
|
+
transBufferB.fill(0);
|
|
110704
|
+
for (const [sceneBuf, sceneIds] of [
|
|
110705
|
+
[transBufferA, sceneAIds],
|
|
110706
|
+
[transBufferB, sceneBIds]
|
|
110707
|
+
]) {
|
|
110708
|
+
assertNotAborted();
|
|
110709
|
+
await domSession.page.evaluate((t) => {
|
|
110710
|
+
if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
|
|
110711
|
+
}, time);
|
|
110712
|
+
if (beforeCaptureHook) {
|
|
110713
|
+
await beforeCaptureHook(domSession.page, time);
|
|
110714
|
+
}
|
|
110715
|
+
for (const el of stackingInfo) {
|
|
110716
|
+
if (!el.isHdr || !sceneIds.has(el.id)) continue;
|
|
110717
|
+
if (nativeHdrImageIds.has(el.id)) {
|
|
110718
|
+
blitHdrImageLayer(
|
|
110719
|
+
sceneBuf,
|
|
110720
|
+
el,
|
|
110721
|
+
hdrImageBuffers,
|
|
110722
|
+
width,
|
|
110723
|
+
height,
|
|
110724
|
+
log,
|
|
110725
|
+
imageTransfers.get(el.id),
|
|
110726
|
+
effectiveHdr?.transfer
|
|
110727
|
+
);
|
|
110728
|
+
} else {
|
|
110729
|
+
blitHdrVideoLayer(
|
|
110730
|
+
sceneBuf,
|
|
110731
|
+
el,
|
|
110732
|
+
time,
|
|
110733
|
+
job.config.fps,
|
|
110734
|
+
hdrFrameDirs,
|
|
110735
|
+
hdrVideoStartTimes,
|
|
110736
|
+
width,
|
|
110737
|
+
height,
|
|
110738
|
+
log,
|
|
110739
|
+
videoTransfers.get(el.id),
|
|
110740
|
+
effectiveHdr?.transfer
|
|
110741
|
+
);
|
|
110742
|
+
}
|
|
110743
|
+
}
|
|
110744
|
+
const showIds = Array.from(sceneIds);
|
|
110745
|
+
const hideIds = stackingInfo.map((e) => e.id).filter((id) => !sceneIds.has(id) || nativeHdrIds.has(id));
|
|
110746
|
+
await applyDomLayerMask(domSession.page, showIds, hideIds);
|
|
110747
|
+
const domPng = await captureAlphaPng(domSession.page, width, height);
|
|
110748
|
+
await removeDomLayerMask(domSession.page, hideIds);
|
|
110749
|
+
try {
|
|
110750
|
+
const { data: domRgba } = decodePng(domPng);
|
|
110751
|
+
if (!effectiveHdr) {
|
|
110752
|
+
throw new Error(
|
|
110753
|
+
"Invariant violation: effectiveHdr is undefined inside hasHdrVideo branch"
|
|
110754
|
+
);
|
|
110755
|
+
}
|
|
110756
|
+
blitRgba8OverRgb48le(
|
|
110757
|
+
domRgba,
|
|
110535
110758
|
sceneBuf,
|
|
110536
|
-
el,
|
|
110537
|
-
time,
|
|
110538
|
-
job.config.fps,
|
|
110539
|
-
hdrFrameDirs,
|
|
110540
|
-
hdrVideoStartTimes,
|
|
110541
110759
|
width,
|
|
110542
110760
|
height,
|
|
110543
|
-
|
|
110544
|
-
videoTransfers.get(el.id),
|
|
110545
|
-
effectiveHdr?.transfer
|
|
110761
|
+
effectiveHdr.transfer
|
|
110546
110762
|
);
|
|
110763
|
+
} catch (err) {
|
|
110764
|
+
log.warn("DOM layer decode/blit failed; skipping overlay for transition scene", {
|
|
110765
|
+
frameIndex: i,
|
|
110766
|
+
sceneIds: Array.from(sceneIds),
|
|
110767
|
+
error: err instanceof Error ? err.message : String(err)
|
|
110768
|
+
});
|
|
110547
110769
|
}
|
|
110548
110770
|
}
|
|
110549
|
-
const
|
|
110550
|
-
|
|
110551
|
-
|
|
110552
|
-
|
|
110553
|
-
|
|
110554
|
-
|
|
110555
|
-
|
|
110556
|
-
|
|
110557
|
-
|
|
110558
|
-
|
|
110559
|
-
|
|
110560
|
-
|
|
110561
|
-
|
|
110562
|
-
|
|
110563
|
-
|
|
110564
|
-
|
|
110565
|
-
|
|
110566
|
-
effectiveHdr.transfer
|
|
110771
|
+
const transitionFn = TRANSITIONS[activeTransition.shader] ?? crossfade;
|
|
110772
|
+
transitionFn(transBufferA, transBufferB, transOutput, width, height, progress);
|
|
110773
|
+
hdrEncoder.writeFrame(transOutput);
|
|
110774
|
+
} else {
|
|
110775
|
+
normalCanvas.fill(0);
|
|
110776
|
+
await compositeHdrFrame(
|
|
110777
|
+
hdrCompositeCtx,
|
|
110778
|
+
normalCanvas,
|
|
110779
|
+
time,
|
|
110780
|
+
stackingInfo,
|
|
110781
|
+
void 0,
|
|
110782
|
+
i
|
|
110783
|
+
);
|
|
110784
|
+
if (debugDumpEnabled && debugDumpDir && i % 30 === 0) {
|
|
110785
|
+
const previewPath = join15(
|
|
110786
|
+
debugDumpDir,
|
|
110787
|
+
`frame_${String(i).padStart(4, "0")}_final_rgb48le.bin`
|
|
110567
110788
|
);
|
|
110568
|
-
|
|
110569
|
-
log.warn("DOM layer decode/blit failed; skipping overlay for transition scene", {
|
|
110570
|
-
frameIndex: i,
|
|
110571
|
-
sceneIds: Array.from(sceneIds),
|
|
110572
|
-
error: err instanceof Error ? err.message : String(err)
|
|
110573
|
-
});
|
|
110789
|
+
writeFileSync4(previewPath, normalCanvas);
|
|
110574
110790
|
}
|
|
110575
|
-
|
|
110576
|
-
|
|
110577
|
-
|
|
110578
|
-
|
|
110579
|
-
|
|
110580
|
-
|
|
110581
|
-
|
|
110582
|
-
|
|
110583
|
-
|
|
110584
|
-
|
|
110585
|
-
|
|
110586
|
-
|
|
110587
|
-
|
|
110588
|
-
|
|
110589
|
-
|
|
110590
|
-
|
|
110591
|
-
|
|
110592
|
-
|
|
110593
|
-
|
|
110594
|
-
|
|
110595
|
-
if (!stillNeeded) {
|
|
110596
|
-
const frameDir = hdrFrameDirs.get(videoId);
|
|
110597
|
-
if (frameDir) {
|
|
110598
|
-
try {
|
|
110599
|
-
rmSync3(frameDir, { recursive: true, force: true });
|
|
110600
|
-
} catch (err) {
|
|
110601
|
-
log.warn("Failed to clean up HDR frame directory", {
|
|
110602
|
-
videoId,
|
|
110603
|
-
frameDir,
|
|
110604
|
-
error: err instanceof Error ? err.message : String(err)
|
|
110605
|
-
});
|
|
110791
|
+
hdrEncoder.writeFrame(normalCanvas);
|
|
110792
|
+
}
|
|
110793
|
+
if (process.env.KEEP_TEMP !== "1") {
|
|
110794
|
+
for (const [videoId, endTime] of hdrVideoEndTimes) {
|
|
110795
|
+
if (time > endTime && !cleanedUpVideos.has(videoId)) {
|
|
110796
|
+
const stillNeeded = activeTransition && (sceneElements[activeTransition.fromScene]?.includes(videoId) || sceneElements[activeTransition.toScene]?.includes(videoId));
|
|
110797
|
+
if (!stillNeeded) {
|
|
110798
|
+
const frameDir = hdrFrameDirs.get(videoId);
|
|
110799
|
+
if (frameDir) {
|
|
110800
|
+
try {
|
|
110801
|
+
rmSync3(frameDir, { recursive: true, force: true });
|
|
110802
|
+
} catch (err) {
|
|
110803
|
+
log.warn("Failed to clean up HDR frame directory", {
|
|
110804
|
+
videoId,
|
|
110805
|
+
frameDir,
|
|
110806
|
+
error: err instanceof Error ? err.message : String(err)
|
|
110807
|
+
});
|
|
110808
|
+
}
|
|
110809
|
+
frameDirMaxIndexCache.delete(frameDir);
|
|
110810
|
+
hdrFrameDirs.delete(videoId);
|
|
110606
110811
|
}
|
|
110812
|
+
cleanedUpVideos.add(videoId);
|
|
110607
110813
|
}
|
|
110608
|
-
cleanedUpVideos.add(videoId);
|
|
110609
110814
|
}
|
|
110610
110815
|
}
|
|
110611
110816
|
}
|
|
110817
|
+
job.framesRendered = i + 1;
|
|
110818
|
+
if ((i + 1) % 10 === 0 || i + 1 === totalFrames) {
|
|
110819
|
+
const frameProgress = (i + 1) / totalFrames;
|
|
110820
|
+
updateJobStatus(
|
|
110821
|
+
job,
|
|
110822
|
+
"rendering",
|
|
110823
|
+
`HDR composite frame ${i + 1}/${job.totalFrames}`,
|
|
110824
|
+
Math.round(25 + frameProgress * 55),
|
|
110825
|
+
onProgress
|
|
110826
|
+
);
|
|
110827
|
+
}
|
|
110612
110828
|
}
|
|
110613
|
-
|
|
110614
|
-
|
|
110615
|
-
|
|
110616
|
-
|
|
110617
|
-
job,
|
|
110618
|
-
"rendering",
|
|
110619
|
-
`HDR composite frame ${i + 1}/${job.totalFrames}`,
|
|
110620
|
-
Math.round(25 + frameProgress * 55),
|
|
110621
|
-
onProgress
|
|
110622
|
-
);
|
|
110623
|
-
}
|
|
110829
|
+
} finally {
|
|
110830
|
+
lastBrowserConsole = domSession.browserConsoleBuffer;
|
|
110831
|
+
await closeCaptureSession(domSession);
|
|
110832
|
+
domSessionClosed = true;
|
|
110624
110833
|
}
|
|
110834
|
+
const hdrEncodeResult = await hdrEncoder.close();
|
|
110835
|
+
hdrEncoderClosed = true;
|
|
110836
|
+
assertNotAborted();
|
|
110837
|
+
if (!hdrEncodeResult.success) {
|
|
110838
|
+
throw new Error(`HDR encode failed: ${hdrEncodeResult.error}`);
|
|
110839
|
+
}
|
|
110840
|
+
perfStages.captureMs = Date.now() - stage4Start;
|
|
110841
|
+
perfStages.encodeMs = hdrEncodeResult.durationMs;
|
|
110625
110842
|
} finally {
|
|
110626
|
-
|
|
110627
|
-
|
|
110628
|
-
|
|
110629
|
-
|
|
110630
|
-
|
|
110631
|
-
|
|
110632
|
-
|
|
110843
|
+
if (hdrEncoder && !hdrEncoderClosed) {
|
|
110844
|
+
try {
|
|
110845
|
+
await hdrEncoder.close();
|
|
110846
|
+
} catch (err) {
|
|
110847
|
+
log.warn("hdrEncoder defensive close failed", {
|
|
110848
|
+
err: err instanceof Error ? err.message : String(err)
|
|
110849
|
+
});
|
|
110850
|
+
}
|
|
110851
|
+
}
|
|
110852
|
+
if (!domSessionClosed) {
|
|
110853
|
+
await closeCaptureSession(domSession).catch((err) => {
|
|
110854
|
+
log.warn("closeCaptureSession defensive close failed", {
|
|
110855
|
+
err: err instanceof Error ? err.message : String(err)
|
|
110856
|
+
});
|
|
110857
|
+
});
|
|
110858
|
+
}
|
|
110859
|
+
for (const frameDir of hdrFrameDirs.values()) {
|
|
110860
|
+
frameDirMaxIndexCache.delete(frameDir);
|
|
110861
|
+
}
|
|
110862
|
+
hdrFrameDirs.clear();
|
|
110633
110863
|
}
|
|
110634
|
-
perfStages.captureMs = Date.now() - stage4Start;
|
|
110635
|
-
perfStages.encodeMs = hdrEncodeResult.durationMs;
|
|
110636
110864
|
} else {
|
|
110637
110865
|
let streamingEncoder = null;
|
|
110866
|
+
let streamingEncoderClosed = false;
|
|
110638
110867
|
if (enableStreamingEncode) {
|
|
110639
110868
|
streamingEncoder = await spawnStreamingEncoder(
|
|
110640
110869
|
videoOnlyPath,
|
|
@@ -110644,7 +110873,8 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110644
110873
|
height,
|
|
110645
110874
|
codec: preset.codec,
|
|
110646
110875
|
preset: preset.preset,
|
|
110647
|
-
quality:
|
|
110876
|
+
quality: effectiveQuality,
|
|
110877
|
+
bitrate: effectiveBitrate,
|
|
110648
110878
|
pixelFormat: preset.pixelFormat,
|
|
110649
110879
|
useGpu: job.config.useGpu,
|
|
110650
110880
|
imageFormat: captureOptions.format || "jpeg",
|
|
@@ -110654,201 +110884,215 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110654
110884
|
);
|
|
110655
110885
|
assertNotAborted();
|
|
110656
110886
|
}
|
|
110657
|
-
|
|
110658
|
-
|
|
110659
|
-
|
|
110660
|
-
|
|
110661
|
-
|
|
110662
|
-
|
|
110663
|
-
|
|
110664
|
-
|
|
110665
|
-
|
|
110666
|
-
|
|
110667
|
-
|
|
110668
|
-
|
|
110669
|
-
|
|
110670
|
-
|
|
110671
|
-
|
|
110672
|
-
|
|
110673
|
-
|
|
110674
|
-
|
|
110675
|
-
|
|
110676
|
-
|
|
110677
|
-
|
|
110678
|
-
|
|
110887
|
+
try {
|
|
110888
|
+
if (enableStreamingEncode && streamingEncoder) {
|
|
110889
|
+
const reorderBuffer = createFrameReorderBuffer(0, totalFrames);
|
|
110890
|
+
const currentEncoder = streamingEncoder;
|
|
110891
|
+
if (workerCount > 1) {
|
|
110892
|
+
const tasks = distributeFrames(job.totalFrames, workerCount, workDir);
|
|
110893
|
+
const onFrameBuffer = async (frameIndex, buffer) => {
|
|
110894
|
+
await reorderBuffer.waitForFrame(frameIndex);
|
|
110895
|
+
currentEncoder.writeFrame(buffer);
|
|
110896
|
+
reorderBuffer.advanceTo(frameIndex + 1);
|
|
110897
|
+
};
|
|
110898
|
+
await executeParallelCapture(
|
|
110899
|
+
fileServer.url,
|
|
110900
|
+
workDir,
|
|
110901
|
+
tasks,
|
|
110902
|
+
buildHdrCaptureOptions(),
|
|
110903
|
+
() => createVideoFrameInjector(frameLookup),
|
|
110904
|
+
abortSignal,
|
|
110905
|
+
(progress) => {
|
|
110906
|
+
job.framesRendered = progress.capturedFrames;
|
|
110907
|
+
const frameProgress = progress.capturedFrames / progress.totalFrames;
|
|
110908
|
+
const progressPct = 25 + frameProgress * 55;
|
|
110909
|
+
if (progress.capturedFrames % 30 === 0 || progress.capturedFrames === progress.totalFrames) {
|
|
110910
|
+
updateJobStatus(
|
|
110911
|
+
job,
|
|
110912
|
+
"rendering",
|
|
110913
|
+
`Streaming frame ${progress.capturedFrames}/${progress.totalFrames} (${workerCount} workers)`,
|
|
110914
|
+
Math.round(progressPct),
|
|
110915
|
+
onProgress
|
|
110916
|
+
);
|
|
110917
|
+
}
|
|
110918
|
+
},
|
|
110919
|
+
onFrameBuffer,
|
|
110920
|
+
cfg
|
|
110921
|
+
);
|
|
110922
|
+
if (probeSession) {
|
|
110923
|
+
lastBrowserConsole = probeSession.browserConsoleBuffer;
|
|
110924
|
+
await closeCaptureSession(probeSession);
|
|
110925
|
+
probeSession = null;
|
|
110926
|
+
}
|
|
110927
|
+
} else {
|
|
110928
|
+
const videoInjector = createVideoFrameInjector(frameLookup);
|
|
110929
|
+
const session = probeSession ?? await createCaptureSession(
|
|
110930
|
+
fileServer.url,
|
|
110931
|
+
framesDir,
|
|
110932
|
+
buildHdrCaptureOptions(),
|
|
110933
|
+
videoInjector,
|
|
110934
|
+
cfg
|
|
110935
|
+
);
|
|
110936
|
+
if (probeSession) {
|
|
110937
|
+
prepareCaptureSessionForReuse(session, framesDir, videoInjector);
|
|
110938
|
+
probeSession = null;
|
|
110939
|
+
}
|
|
110940
|
+
try {
|
|
110941
|
+
if (!session.isInitialized) {
|
|
110942
|
+
await initializeSession(session);
|
|
110943
|
+
}
|
|
110944
|
+
assertNotAborted();
|
|
110945
|
+
lastBrowserConsole = session.browserConsoleBuffer;
|
|
110946
|
+
for (let i = 0; i < totalFrames; i++) {
|
|
110947
|
+
assertNotAborted();
|
|
110948
|
+
const time = i / job.config.fps;
|
|
110949
|
+
const { buffer } = await captureFrameToBuffer(session, i, time);
|
|
110950
|
+
await reorderBuffer.waitForFrame(i);
|
|
110951
|
+
currentEncoder.writeFrame(buffer);
|
|
110952
|
+
reorderBuffer.advanceTo(i + 1);
|
|
110953
|
+
job.framesRendered = i + 1;
|
|
110954
|
+
const frameProgress = (i + 1) / totalFrames;
|
|
110955
|
+
const progress = 25 + frameProgress * 55;
|
|
110679
110956
|
updateJobStatus(
|
|
110680
110957
|
job,
|
|
110681
110958
|
"rendering",
|
|
110682
|
-
`Streaming frame ${
|
|
110683
|
-
Math.round(
|
|
110959
|
+
`Streaming frame ${i + 1}/${job.totalFrames}`,
|
|
110960
|
+
Math.round(progress),
|
|
110684
110961
|
onProgress
|
|
110685
110962
|
);
|
|
110686
110963
|
}
|
|
110687
|
-
}
|
|
110688
|
-
|
|
110689
|
-
|
|
110690
|
-
|
|
110691
|
-
if (probeSession) {
|
|
110692
|
-
lastBrowserConsole = probeSession.browserConsoleBuffer;
|
|
110693
|
-
await closeCaptureSession(probeSession);
|
|
110694
|
-
probeSession = null;
|
|
110964
|
+
} finally {
|
|
110965
|
+
lastBrowserConsole = session.browserConsoleBuffer;
|
|
110966
|
+
await closeCaptureSession(session);
|
|
110967
|
+
}
|
|
110695
110968
|
}
|
|
110696
|
-
|
|
110697
|
-
|
|
110698
|
-
|
|
110699
|
-
|
|
110700
|
-
|
|
110701
|
-
{ ...captureOptions, skipReadinessVideoIds: Array.from(nativeHdrVideoIds) },
|
|
110702
|
-
videoInjector,
|
|
110703
|
-
cfg
|
|
110704
|
-
);
|
|
110705
|
-
if (probeSession) {
|
|
110706
|
-
prepareCaptureSessionForReuse(session, framesDir, videoInjector);
|
|
110707
|
-
probeSession = null;
|
|
110969
|
+
const encodeResult = await currentEncoder.close();
|
|
110970
|
+
streamingEncoderClosed = true;
|
|
110971
|
+
assertNotAborted();
|
|
110972
|
+
if (!encodeResult.success) {
|
|
110973
|
+
throw new Error(`Streaming encode failed: ${encodeResult.error}`);
|
|
110708
110974
|
}
|
|
110709
|
-
|
|
110710
|
-
|
|
110711
|
-
|
|
110975
|
+
perfStages.captureMs = Date.now() - stage4Start;
|
|
110976
|
+
perfStages.encodeMs = encodeResult.durationMs;
|
|
110977
|
+
} else {
|
|
110978
|
+
if (workerCount > 1) {
|
|
110979
|
+
const tasks = distributeFrames(job.totalFrames, workerCount, workDir);
|
|
110980
|
+
await executeParallelCapture(
|
|
110981
|
+
fileServer.url,
|
|
110982
|
+
workDir,
|
|
110983
|
+
tasks,
|
|
110984
|
+
buildHdrCaptureOptions(),
|
|
110985
|
+
() => createVideoFrameInjector(frameLookup),
|
|
110986
|
+
abortSignal,
|
|
110987
|
+
(progress) => {
|
|
110988
|
+
job.framesRendered = progress.capturedFrames;
|
|
110989
|
+
const frameProgress = progress.capturedFrames / progress.totalFrames;
|
|
110990
|
+
const progressPct = 25 + frameProgress * 45;
|
|
110991
|
+
if (progress.capturedFrames % 30 === 0 || progress.capturedFrames === progress.totalFrames) {
|
|
110992
|
+
updateJobStatus(
|
|
110993
|
+
job,
|
|
110994
|
+
"rendering",
|
|
110995
|
+
`Capturing frame ${progress.capturedFrames}/${progress.totalFrames} (${workerCount} workers)`,
|
|
110996
|
+
Math.round(progressPct),
|
|
110997
|
+
onProgress
|
|
110998
|
+
);
|
|
110999
|
+
}
|
|
111000
|
+
},
|
|
111001
|
+
void 0,
|
|
111002
|
+
cfg
|
|
111003
|
+
);
|
|
111004
|
+
await mergeWorkerFrames(workDir, tasks, framesDir);
|
|
111005
|
+
if (probeSession) {
|
|
111006
|
+
lastBrowserConsole = probeSession.browserConsoleBuffer;
|
|
111007
|
+
await closeCaptureSession(probeSession);
|
|
111008
|
+
probeSession = null;
|
|
110712
111009
|
}
|
|
110713
|
-
|
|
110714
|
-
|
|
110715
|
-
|
|
110716
|
-
|
|
110717
|
-
|
|
110718
|
-
|
|
110719
|
-
|
|
110720
|
-
|
|
110721
|
-
|
|
110722
|
-
|
|
110723
|
-
|
|
110724
|
-
|
|
110725
|
-
updateJobStatus(
|
|
110726
|
-
job,
|
|
110727
|
-
"rendering",
|
|
110728
|
-
`Streaming frame ${i + 1}/${job.totalFrames}`,
|
|
110729
|
-
Math.round(progress),
|
|
110730
|
-
onProgress
|
|
110731
|
-
);
|
|
111010
|
+
} else {
|
|
111011
|
+
const videoInjector = createVideoFrameInjector(frameLookup);
|
|
111012
|
+
const session = probeSession ?? await createCaptureSession(
|
|
111013
|
+
fileServer.url,
|
|
111014
|
+
framesDir,
|
|
111015
|
+
buildHdrCaptureOptions(),
|
|
111016
|
+
videoInjector,
|
|
111017
|
+
cfg
|
|
111018
|
+
);
|
|
111019
|
+
if (probeSession) {
|
|
111020
|
+
prepareCaptureSessionForReuse(session, framesDir, videoInjector);
|
|
111021
|
+
probeSession = null;
|
|
110732
111022
|
}
|
|
110733
|
-
|
|
110734
|
-
|
|
110735
|
-
|
|
110736
|
-
|
|
110737
|
-
|
|
110738
|
-
|
|
110739
|
-
|
|
110740
|
-
|
|
110741
|
-
|
|
110742
|
-
|
|
110743
|
-
|
|
110744
|
-
|
|
110745
|
-
|
|
110746
|
-
if (workerCount > 1) {
|
|
110747
|
-
const tasks = distributeFrames(job.totalFrames, workerCount, workDir);
|
|
110748
|
-
await executeParallelCapture(
|
|
110749
|
-
fileServer.url,
|
|
110750
|
-
workDir,
|
|
110751
|
-
tasks,
|
|
110752
|
-
{ ...captureOptions, skipReadinessVideoIds: Array.from(nativeHdrVideoIds) },
|
|
110753
|
-
() => createVideoFrameInjector(frameLookup),
|
|
110754
|
-
abortSignal,
|
|
110755
|
-
(progress) => {
|
|
110756
|
-
job.framesRendered = progress.capturedFrames;
|
|
110757
|
-
const frameProgress = progress.capturedFrames / progress.totalFrames;
|
|
110758
|
-
const progressPct = 25 + frameProgress * 45;
|
|
110759
|
-
if (progress.capturedFrames % 30 === 0 || progress.capturedFrames === progress.totalFrames) {
|
|
111023
|
+
try {
|
|
111024
|
+
if (!session.isInitialized) {
|
|
111025
|
+
await initializeSession(session);
|
|
111026
|
+
}
|
|
111027
|
+
assertNotAborted();
|
|
111028
|
+
lastBrowserConsole = session.browserConsoleBuffer;
|
|
111029
|
+
for (let i = 0; i < job.totalFrames; i++) {
|
|
111030
|
+
assertNotAborted();
|
|
111031
|
+
const time = i / job.config.fps;
|
|
111032
|
+
await captureFrame(session, i, time);
|
|
111033
|
+
job.framesRendered = i + 1;
|
|
111034
|
+
const frameProgress = (i + 1) / job.totalFrames;
|
|
111035
|
+
const progress = 25 + frameProgress * 45;
|
|
110760
111036
|
updateJobStatus(
|
|
110761
111037
|
job,
|
|
110762
111038
|
"rendering",
|
|
110763
|
-
`Capturing frame ${
|
|
110764
|
-
Math.round(
|
|
111039
|
+
`Capturing frame ${i + 1}/${job.totalFrames}`,
|
|
111040
|
+
Math.round(progress),
|
|
110765
111041
|
onProgress
|
|
110766
111042
|
);
|
|
110767
111043
|
}
|
|
110768
|
-
}
|
|
110769
|
-
|
|
110770
|
-
|
|
110771
|
-
|
|
110772
|
-
await mergeWorkerFrames(workDir, tasks, framesDir);
|
|
110773
|
-
if (probeSession) {
|
|
110774
|
-
lastBrowserConsole = probeSession.browserConsoleBuffer;
|
|
110775
|
-
await closeCaptureSession(probeSession);
|
|
110776
|
-
probeSession = null;
|
|
111044
|
+
} finally {
|
|
111045
|
+
lastBrowserConsole = session.browserConsoleBuffer;
|
|
111046
|
+
await closeCaptureSession(session);
|
|
111047
|
+
}
|
|
110777
111048
|
}
|
|
110778
|
-
|
|
110779
|
-
const
|
|
110780
|
-
|
|
110781
|
-
|
|
111049
|
+
perfStages.captureMs = Date.now() - stage4Start;
|
|
111050
|
+
const stage5Start = Date.now();
|
|
111051
|
+
updateJobStatus(job, "encoding", "Encoding video", 75, onProgress);
|
|
111052
|
+
const frameExt = needsAlpha ? "png" : "jpg";
|
|
111053
|
+
const framePattern = `frame_%06d.${frameExt}`;
|
|
111054
|
+
const encoderOpts = {
|
|
111055
|
+
fps: job.config.fps,
|
|
111056
|
+
width,
|
|
111057
|
+
height,
|
|
111058
|
+
codec: preset.codec,
|
|
111059
|
+
preset: preset.preset,
|
|
111060
|
+
quality: effectiveQuality,
|
|
111061
|
+
bitrate: effectiveBitrate,
|
|
111062
|
+
pixelFormat: preset.pixelFormat,
|
|
111063
|
+
useGpu: job.config.useGpu,
|
|
111064
|
+
hdr: preset.hdr
|
|
111065
|
+
};
|
|
111066
|
+
const encodeResult = enableChunkedEncode ? await encodeFramesChunkedConcat(
|
|
110782
111067
|
framesDir,
|
|
110783
|
-
|
|
110784
|
-
|
|
110785
|
-
|
|
111068
|
+
framePattern,
|
|
111069
|
+
videoOnlyPath,
|
|
111070
|
+
encoderOpts,
|
|
111071
|
+
chunkedEncodeSize,
|
|
111072
|
+
abortSignal
|
|
111073
|
+
) : await encodeFramesFromDir(
|
|
111074
|
+
framesDir,
|
|
111075
|
+
framePattern,
|
|
111076
|
+
videoOnlyPath,
|
|
111077
|
+
encoderOpts,
|
|
111078
|
+
abortSignal
|
|
110786
111079
|
);
|
|
110787
|
-
|
|
110788
|
-
|
|
110789
|
-
|
|
111080
|
+
assertNotAborted();
|
|
111081
|
+
if (!encodeResult.success) {
|
|
111082
|
+
throw new Error(`Encoding failed: ${encodeResult.error}`);
|
|
110790
111083
|
}
|
|
111084
|
+
perfStages.encodeMs = Date.now() - stage5Start;
|
|
111085
|
+
}
|
|
111086
|
+
} finally {
|
|
111087
|
+
if (streamingEncoder && !streamingEncoderClosed) {
|
|
110791
111088
|
try {
|
|
110792
|
-
|
|
110793
|
-
|
|
110794
|
-
|
|
110795
|
-
|
|
110796
|
-
|
|
110797
|
-
for (let i = 0; i < job.totalFrames; i++) {
|
|
110798
|
-
assertNotAborted();
|
|
110799
|
-
const time = i / job.config.fps;
|
|
110800
|
-
await captureFrame(session, i, time);
|
|
110801
|
-
job.framesRendered = i + 1;
|
|
110802
|
-
const frameProgress = (i + 1) / job.totalFrames;
|
|
110803
|
-
const progress = 25 + frameProgress * 45;
|
|
110804
|
-
updateJobStatus(
|
|
110805
|
-
job,
|
|
110806
|
-
"rendering",
|
|
110807
|
-
`Capturing frame ${i + 1}/${job.totalFrames}`,
|
|
110808
|
-
Math.round(progress),
|
|
110809
|
-
onProgress
|
|
110810
|
-
);
|
|
110811
|
-
}
|
|
110812
|
-
} finally {
|
|
110813
|
-
lastBrowserConsole = session.browserConsoleBuffer;
|
|
110814
|
-
await closeCaptureSession(session);
|
|
111089
|
+
await streamingEncoder.close();
|
|
111090
|
+
} catch (err) {
|
|
111091
|
+
log.warn("streamingEncoder defensive close failed", {
|
|
111092
|
+
err: err instanceof Error ? err.message : String(err)
|
|
111093
|
+
});
|
|
110815
111094
|
}
|
|
110816
111095
|
}
|
|
110817
|
-
perfStages.captureMs = Date.now() - stage4Start;
|
|
110818
|
-
const stage5Start = Date.now();
|
|
110819
|
-
updateJobStatus(job, "encoding", "Encoding video", 75, onProgress);
|
|
110820
|
-
const frameExt = needsAlpha ? "png" : "jpg";
|
|
110821
|
-
const framePattern = `frame_%06d.${frameExt}`;
|
|
110822
|
-
const encoderOpts = {
|
|
110823
|
-
fps: job.config.fps,
|
|
110824
|
-
width,
|
|
110825
|
-
height,
|
|
110826
|
-
codec: preset.codec,
|
|
110827
|
-
preset: preset.preset,
|
|
110828
|
-
quality: preset.quality,
|
|
110829
|
-
pixelFormat: preset.pixelFormat,
|
|
110830
|
-
useGpu: job.config.useGpu,
|
|
110831
|
-
hdr: preset.hdr
|
|
110832
|
-
};
|
|
110833
|
-
const encodeResult = enableChunkedEncode ? await encodeFramesChunkedConcat(
|
|
110834
|
-
framesDir,
|
|
110835
|
-
framePattern,
|
|
110836
|
-
videoOnlyPath,
|
|
110837
|
-
encoderOpts,
|
|
110838
|
-
chunkedEncodeSize,
|
|
110839
|
-
abortSignal
|
|
110840
|
-
) : await encodeFramesFromDir(
|
|
110841
|
-
framesDir,
|
|
110842
|
-
framePattern,
|
|
110843
|
-
videoOnlyPath,
|
|
110844
|
-
encoderOpts,
|
|
110845
|
-
abortSignal
|
|
110846
|
-
);
|
|
110847
|
-
assertNotAborted();
|
|
110848
|
-
if (!encodeResult.success) {
|
|
110849
|
-
throw new Error(`Encoding failed: ${encodeResult.error}`);
|
|
110850
|
-
}
|
|
110851
|
-
perfStages.encodeMs = Date.now() - stage5Start;
|
|
110852
111096
|
}
|
|
110853
111097
|
}
|
|
110854
111098
|
if (probeSession !== null) {
|
|
@@ -111020,7 +111264,7 @@ import {
|
|
|
111020
111264
|
rmSync as rmSync4,
|
|
111021
111265
|
createReadStream as createReadStream2
|
|
111022
111266
|
} from "node:fs";
|
|
111023
|
-
import { resolve as
|
|
111267
|
+
import { resolve as resolve13, dirname as dirname11, join as join17 } from "node:path";
|
|
111024
111268
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
111025
111269
|
import { parseArgs } from "node:util";
|
|
111026
111270
|
import crypto2 from "node:crypto";
|
|
@@ -111176,7 +111420,7 @@ var streamSSE = (c, cb, onError) => {
|
|
|
111176
111420
|
|
|
111177
111421
|
// src/services/hyperframeLint.ts
|
|
111178
111422
|
import { existsSync as existsSync16, readFileSync as readFileSync11, statSync as statSync6 } from "node:fs";
|
|
111179
|
-
import { resolve as
|
|
111423
|
+
import { resolve as resolve12, join as join16 } from "node:path";
|
|
111180
111424
|
function isStringRecord(value) {
|
|
111181
111425
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
111182
111426
|
return false;
|
|
@@ -111203,7 +111447,7 @@ function pickEntryFile(files, preferredEntryFile) {
|
|
|
111203
111447
|
return null;
|
|
111204
111448
|
}
|
|
111205
111449
|
function readProjectEntryFile(projectDir, preferredEntryFile) {
|
|
111206
|
-
const absProjectDir =
|
|
111450
|
+
const absProjectDir = resolve12(projectDir);
|
|
111207
111451
|
if (!existsSync16(absProjectDir) || !statSync6(absProjectDir).isDirectory()) {
|
|
111208
111452
|
return { error: `Project directory not found: ${absProjectDir}` };
|
|
111209
111453
|
}
|
|
@@ -111211,7 +111455,7 @@ function readProjectEntryFile(projectDir, preferredEntryFile) {
|
|
|
111211
111455
|
(value) => typeof value === "string" && value.trim().length > 0
|
|
111212
111456
|
);
|
|
111213
111457
|
for (const entryFile of entryCandidates) {
|
|
111214
|
-
const absoluteEntryPath =
|
|
111458
|
+
const absoluteEntryPath = resolve12(absProjectDir, entryFile);
|
|
111215
111459
|
if (!absoluteEntryPath.startsWith(absProjectDir)) {
|
|
111216
111460
|
return { error: `Entry file must stay inside project directory: ${entryFile}` };
|
|
111217
111461
|
}
|
|
@@ -111276,10 +111520,10 @@ var Semaphore = class {
|
|
|
111276
111520
|
this.active++;
|
|
111277
111521
|
return () => this.release();
|
|
111278
111522
|
}
|
|
111279
|
-
return new Promise((
|
|
111523
|
+
return new Promise((resolve14) => {
|
|
111280
111524
|
this.queue.push(() => {
|
|
111281
111525
|
this.active++;
|
|
111282
|
-
|
|
111526
|
+
resolve14(() => this.release());
|
|
111283
111527
|
});
|
|
111284
111528
|
});
|
|
111285
111529
|
}
|
|
@@ -111314,12 +111558,12 @@ async function prepareRenderBody(body) {
|
|
|
111314
111558
|
const options = parseRenderOptions(body);
|
|
111315
111559
|
const projectDir = typeof body.projectDir === "string" ? body.projectDir : void 0;
|
|
111316
111560
|
if (projectDir) {
|
|
111317
|
-
const absProjectDir =
|
|
111561
|
+
const absProjectDir = resolve13(projectDir);
|
|
111318
111562
|
if (!existsSync17(absProjectDir) || !statSync7(absProjectDir).isDirectory()) {
|
|
111319
111563
|
return { error: `Project directory not found: ${absProjectDir}` };
|
|
111320
111564
|
}
|
|
111321
111565
|
const entry = options.entryFile || "index.html";
|
|
111322
|
-
if (!existsSync17(
|
|
111566
|
+
if (!existsSync17(resolve13(absProjectDir, entry))) {
|
|
111323
111567
|
return { error: `Entry file "${entry}" not found in project directory: ${absProjectDir}` };
|
|
111324
111568
|
}
|
|
111325
111569
|
return { prepared: { input: { projectDir: absProjectDir, ...options } } };
|
|
@@ -111360,7 +111604,7 @@ function resolveOutputPath(projectDir, outputCandidate, rendersDir, log) {
|
|
|
111360
111604
|
try {
|
|
111361
111605
|
return resolveRenderPaths(projectDir, outputCandidate, rendersDir).absoluteOutputPath;
|
|
111362
111606
|
} catch (error) {
|
|
111363
|
-
const fallbackPath =
|
|
111607
|
+
const fallbackPath = resolve13(rendersDir, `producer-fallback-${Date.now()}.mp4`);
|
|
111364
111608
|
log.warn("Failed to resolve output path, using fallback", {
|
|
111365
111609
|
fallback: fallbackPath,
|
|
111366
111610
|
error: error instanceof Error ? error.message : String(error)
|
|
@@ -111739,7 +111983,7 @@ function startServer(options = {}) {
|
|
|
111739
111983
|
process.on("SIGINT", () => shutdown("SIGINT"));
|
|
111740
111984
|
return server;
|
|
111741
111985
|
}
|
|
111742
|
-
var entryScript = process.argv[1] ?
|
|
111986
|
+
var entryScript = process.argv[1] ? resolve13(process.argv[1]) : "";
|
|
111743
111987
|
var isPublicServerEntry = entryScript.endsWith("/public-server.js") || entryScript.endsWith("/src/server.ts");
|
|
111744
111988
|
if (isPublicServerEntry) {
|
|
111745
111989
|
const { values } = parseArgs({
|