@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/public-server.js
CHANGED
|
@@ -1357,12 +1357,12 @@ var require_CSSValueExpression = __commonJS({
|
|
|
1357
1357
|
return false;
|
|
1358
1358
|
}
|
|
1359
1359
|
};
|
|
1360
|
-
CSSOM.CSSValueExpression.prototype._parseJSString = function(token, idx,
|
|
1361
|
-
var endIdx = this._findMatchedIdx(token, idx,
|
|
1360
|
+
CSSOM.CSSValueExpression.prototype._parseJSString = function(token, idx, sep2) {
|
|
1361
|
+
var endIdx = this._findMatchedIdx(token, idx, sep2), text;
|
|
1362
1362
|
if (endIdx === -1) {
|
|
1363
1363
|
return false;
|
|
1364
1364
|
} else {
|
|
1365
|
-
text = token.substring(idx, endIdx +
|
|
1365
|
+
text = token.substring(idx, endIdx + sep2.length);
|
|
1366
1366
|
return {
|
|
1367
1367
|
idx: endIdx,
|
|
1368
1368
|
text
|
|
@@ -1402,15 +1402,15 @@ var require_CSSValueExpression = __commonJS({
|
|
|
1402
1402
|
if (!isLegal) {
|
|
1403
1403
|
return false;
|
|
1404
1404
|
} else {
|
|
1405
|
-
var
|
|
1406
|
-
return this._parseJSString(token, idx,
|
|
1405
|
+
var sep2 = "/";
|
|
1406
|
+
return this._parseJSString(token, idx, sep2);
|
|
1407
1407
|
}
|
|
1408
1408
|
};
|
|
1409
|
-
CSSOM.CSSValueExpression.prototype._findMatchedIdx = function(token, idx,
|
|
1409
|
+
CSSOM.CSSValueExpression.prototype._findMatchedIdx = function(token, idx, sep2) {
|
|
1410
1410
|
var startIdx = idx, endIdx;
|
|
1411
1411
|
var NOT_FOUND = -1;
|
|
1412
1412
|
while (true) {
|
|
1413
|
-
endIdx = token.indexOf(
|
|
1413
|
+
endIdx = token.indexOf(sep2, startIdx + 1);
|
|
1414
1414
|
if (endIdx === -1) {
|
|
1415
1415
|
endIdx = NOT_FOUND;
|
|
1416
1416
|
break;
|
|
@@ -2149,11 +2149,11 @@ function __extends(d, b) {
|
|
|
2149
2149
|
}
|
|
2150
2150
|
function __awaiter(thisArg, _arguments, P, generator) {
|
|
2151
2151
|
function adopt(value) {
|
|
2152
|
-
return value instanceof P ? value : new P(function(
|
|
2153
|
-
|
|
2152
|
+
return value instanceof P ? value : new P(function(resolve14) {
|
|
2153
|
+
resolve14(value);
|
|
2154
2154
|
});
|
|
2155
2155
|
}
|
|
2156
|
-
return new (P || (P = Promise))(function(
|
|
2156
|
+
return new (P || (P = Promise))(function(resolve14, reject) {
|
|
2157
2157
|
function fulfilled(value) {
|
|
2158
2158
|
try {
|
|
2159
2159
|
step(generator.next(value));
|
|
@@ -2169,7 +2169,7 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
2169
2169
|
}
|
|
2170
2170
|
}
|
|
2171
2171
|
function step(result) {
|
|
2172
|
-
result.done ?
|
|
2172
|
+
result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
2173
2173
|
}
|
|
2174
2174
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
2175
2175
|
});
|
|
@@ -2332,14 +2332,14 @@ function __asyncValues(o) {
|
|
|
2332
2332
|
}, i);
|
|
2333
2333
|
function verb(n) {
|
|
2334
2334
|
i[n] = o[n] && function(v) {
|
|
2335
|
-
return new Promise(function(
|
|
2336
|
-
v = o[n](v), settle(
|
|
2335
|
+
return new Promise(function(resolve14, reject) {
|
|
2336
|
+
v = o[n](v), settle(resolve14, reject, v.done, v.value);
|
|
2337
2337
|
});
|
|
2338
2338
|
};
|
|
2339
2339
|
}
|
|
2340
|
-
function settle(
|
|
2340
|
+
function settle(resolve14, reject, d, v) {
|
|
2341
2341
|
Promise.resolve(v).then(function(v2) {
|
|
2342
|
-
|
|
2342
|
+
resolve14({ value: v2, done: d });
|
|
2343
2343
|
}, reject);
|
|
2344
2344
|
}
|
|
2345
2345
|
}
|
|
@@ -2864,7 +2864,7 @@ function of() {
|
|
|
2864
2864
|
}
|
|
2865
2865
|
function lastValueFrom(source2, config2) {
|
|
2866
2866
|
var hasConfig = typeof config2 === "object";
|
|
2867
|
-
return new Promise(function(
|
|
2867
|
+
return new Promise(function(resolve14, reject) {
|
|
2868
2868
|
var _hasValue = false;
|
|
2869
2869
|
var _value;
|
|
2870
2870
|
source2.subscribe({
|
|
@@ -2875,9 +2875,9 @@ function lastValueFrom(source2, config2) {
|
|
|
2875
2875
|
error: reject,
|
|
2876
2876
|
complete: function() {
|
|
2877
2877
|
if (_hasValue) {
|
|
2878
|
-
|
|
2878
|
+
resolve14(_value);
|
|
2879
2879
|
} else if (hasConfig) {
|
|
2880
|
-
|
|
2880
|
+
resolve14(config2.defaultValue);
|
|
2881
2881
|
} else {
|
|
2882
2882
|
reject(new EmptyError());
|
|
2883
2883
|
}
|
|
@@ -2887,16 +2887,16 @@ function lastValueFrom(source2, config2) {
|
|
|
2887
2887
|
}
|
|
2888
2888
|
function firstValueFrom(source2, config2) {
|
|
2889
2889
|
var hasConfig = typeof config2 === "object";
|
|
2890
|
-
return new Promise(function(
|
|
2890
|
+
return new Promise(function(resolve14, reject) {
|
|
2891
2891
|
var subscriber = new SafeSubscriber({
|
|
2892
2892
|
next: function(value) {
|
|
2893
|
-
|
|
2893
|
+
resolve14(value);
|
|
2894
2894
|
subscriber.unsubscribe();
|
|
2895
2895
|
},
|
|
2896
2896
|
error: reject,
|
|
2897
2897
|
complete: function() {
|
|
2898
2898
|
if (hasConfig) {
|
|
2899
|
-
|
|
2899
|
+
resolve14(config2.defaultValue);
|
|
2900
2900
|
} else {
|
|
2901
2901
|
reject(new EmptyError());
|
|
2902
2902
|
}
|
|
@@ -3935,7 +3935,7 @@ var init_rxjs = __esm({
|
|
|
3935
3935
|
Observable2.prototype.forEach = function(next, promiseCtor) {
|
|
3936
3936
|
var _this = this;
|
|
3937
3937
|
promiseCtor = getPromiseCtor(promiseCtor);
|
|
3938
|
-
return new promiseCtor(function(
|
|
3938
|
+
return new promiseCtor(function(resolve14, reject) {
|
|
3939
3939
|
var subscriber = new SafeSubscriber({
|
|
3940
3940
|
next: function(value) {
|
|
3941
3941
|
try {
|
|
@@ -3946,7 +3946,7 @@ var init_rxjs = __esm({
|
|
|
3946
3946
|
}
|
|
3947
3947
|
},
|
|
3948
3948
|
error: reject,
|
|
3949
|
-
complete:
|
|
3949
|
+
complete: resolve14
|
|
3950
3950
|
});
|
|
3951
3951
|
_this.subscribe(subscriber);
|
|
3952
3952
|
});
|
|
@@ -3968,14 +3968,14 @@ var init_rxjs = __esm({
|
|
|
3968
3968
|
Observable2.prototype.toPromise = function(promiseCtor) {
|
|
3969
3969
|
var _this = this;
|
|
3970
3970
|
promiseCtor = getPromiseCtor(promiseCtor);
|
|
3971
|
-
return new promiseCtor(function(
|
|
3971
|
+
return new promiseCtor(function(resolve14, reject) {
|
|
3972
3972
|
var value;
|
|
3973
3973
|
_this.subscribe(function(x) {
|
|
3974
3974
|
return value = x;
|
|
3975
3975
|
}, function(err) {
|
|
3976
3976
|
return reject(err);
|
|
3977
3977
|
}, function() {
|
|
3978
|
-
return
|
|
3978
|
+
return resolve14(value);
|
|
3979
3979
|
});
|
|
3980
3980
|
});
|
|
3981
3981
|
};
|
|
@@ -6405,8 +6405,8 @@ var init_Deferred = __esm({
|
|
|
6405
6405
|
// SAFETY: This is ensured by #taskPromise.
|
|
6406
6406
|
#resolve;
|
|
6407
6407
|
// TODO: Switch to Promise.withResolvers with Node 22
|
|
6408
|
-
#taskPromise = new Promise((
|
|
6409
|
-
this.#resolve =
|
|
6408
|
+
#taskPromise = new Promise((resolve14) => {
|
|
6409
|
+
this.#resolve = resolve14;
|
|
6410
6410
|
});
|
|
6411
6411
|
#timeoutId;
|
|
6412
6412
|
#timeoutError;
|
|
@@ -6496,12 +6496,12 @@ var init_Mutex = __esm({
|
|
|
6496
6496
|
return new _Mutex.Guard(this, onRelease);
|
|
6497
6497
|
}
|
|
6498
6498
|
release() {
|
|
6499
|
-
const
|
|
6500
|
-
if (!
|
|
6499
|
+
const resolve14 = this.#acquirers.shift();
|
|
6500
|
+
if (!resolve14) {
|
|
6501
6501
|
this.#locked = false;
|
|
6502
6502
|
return;
|
|
6503
6503
|
}
|
|
6504
|
-
|
|
6504
|
+
resolve14();
|
|
6505
6505
|
}
|
|
6506
6506
|
};
|
|
6507
6507
|
}
|
|
@@ -8516,12 +8516,12 @@ var init_locators = __esm({
|
|
|
8516
8516
|
}
|
|
8517
8517
|
return defer(() => {
|
|
8518
8518
|
return from(handle.evaluate((element) => {
|
|
8519
|
-
return new Promise((
|
|
8519
|
+
return new Promise((resolve14) => {
|
|
8520
8520
|
window.requestAnimationFrame(() => {
|
|
8521
8521
|
const rect1 = element.getBoundingClientRect();
|
|
8522
8522
|
window.requestAnimationFrame(() => {
|
|
8523
8523
|
const rect2 = element.getBoundingClientRect();
|
|
8524
|
-
|
|
8524
|
+
resolve14([
|
|
8525
8525
|
{
|
|
8526
8526
|
x: rect1.x,
|
|
8527
8527
|
y: rect1.y,
|
|
@@ -10260,9 +10260,9 @@ var init_ElementHandle = __esm({
|
|
|
10260
10260
|
const handle = await this.#asSVGElementHandle();
|
|
10261
10261
|
const target = __addDisposableResource6(env_5, handle && await handle.#getOwnerSVGElement(), false);
|
|
10262
10262
|
return await (target ?? this).evaluate(async (element, threshold) => {
|
|
10263
|
-
const visibleRatio = await new Promise((
|
|
10263
|
+
const visibleRatio = await new Promise((resolve14) => {
|
|
10264
10264
|
const observer = new IntersectionObserver((entries2) => {
|
|
10265
|
-
|
|
10265
|
+
resolve14(entries2[0].intersectionRatio);
|
|
10266
10266
|
observer.disconnect();
|
|
10267
10267
|
});
|
|
10268
10268
|
observer.observe(element);
|
|
@@ -10908,7 +10908,7 @@ var init_Frame = __esm({
|
|
|
10908
10908
|
}
|
|
10909
10909
|
type = type ?? "text/javascript";
|
|
10910
10910
|
return await this.mainRealm().transferHandle(await this.isolatedRealm().evaluateHandle(async ({ url, id, type: type2, content: content2 }) => {
|
|
10911
|
-
return await new Promise((
|
|
10911
|
+
return await new Promise((resolve14, reject) => {
|
|
10912
10912
|
const script = document.createElement("script");
|
|
10913
10913
|
script.type = type2;
|
|
10914
10914
|
script.text = content2;
|
|
@@ -10921,12 +10921,12 @@ var init_Frame = __esm({
|
|
|
10921
10921
|
if (url) {
|
|
10922
10922
|
script.src = url;
|
|
10923
10923
|
script.addEventListener("load", () => {
|
|
10924
|
-
|
|
10924
|
+
resolve14(script);
|
|
10925
10925
|
}, { once: true });
|
|
10926
10926
|
document.head.appendChild(script);
|
|
10927
10927
|
} else {
|
|
10928
10928
|
document.head.appendChild(script);
|
|
10929
|
-
|
|
10929
|
+
resolve14(script);
|
|
10930
10930
|
}
|
|
10931
10931
|
});
|
|
10932
10932
|
}, { ...options, type, content }));
|
|
@@ -10946,7 +10946,7 @@ var init_Frame = __esm({
|
|
|
10946
10946
|
options.content = content;
|
|
10947
10947
|
}
|
|
10948
10948
|
return await this.mainRealm().transferHandle(await this.isolatedRealm().evaluateHandle(async ({ url, content: content2 }) => {
|
|
10949
|
-
return await new Promise((
|
|
10949
|
+
return await new Promise((resolve14, reject) => {
|
|
10950
10950
|
let element;
|
|
10951
10951
|
if (!url) {
|
|
10952
10952
|
element = document.createElement("style");
|
|
@@ -10958,7 +10958,7 @@ var init_Frame = __esm({
|
|
|
10958
10958
|
element = link;
|
|
10959
10959
|
}
|
|
10960
10960
|
element.addEventListener("load", () => {
|
|
10961
|
-
|
|
10961
|
+
resolve14(element);
|
|
10962
10962
|
}, { once: true });
|
|
10963
10963
|
element.addEventListener("error", (event) => {
|
|
10964
10964
|
reject(new Error(event.message ?? "Could not load style"));
|
|
@@ -12697,9 +12697,9 @@ var init_Page = __esm({
|
|
|
12697
12697
|
++this.#screencastSessionCount;
|
|
12698
12698
|
if (!this.#startScreencastPromise) {
|
|
12699
12699
|
this.#startScreencastPromise = this.mainFrame().client.send("Page.startScreencast", { format: "png" }).then(() => {
|
|
12700
|
-
return new Promise((
|
|
12700
|
+
return new Promise((resolve14) => {
|
|
12701
12701
|
return this.mainFrame().client.once("Page.screencastFrame", () => {
|
|
12702
|
-
return
|
|
12702
|
+
return resolve14();
|
|
12703
12703
|
});
|
|
12704
12704
|
});
|
|
12705
12705
|
});
|
|
@@ -16017,11 +16017,11 @@ function addPageBinding(type, name, prefix) {
|
|
|
16017
16017
|
return value instanceof Node;
|
|
16018
16018
|
})
|
|
16019
16019
|
}));
|
|
16020
|
-
return new Promise((
|
|
16020
|
+
return new Promise((resolve14, reject) => {
|
|
16021
16021
|
callPuppeteer.callbacks.set(seq, {
|
|
16022
16022
|
resolve(value) {
|
|
16023
16023
|
callPuppeteer.args.delete(seq);
|
|
16024
|
-
|
|
16024
|
+
resolve14(value);
|
|
16025
16025
|
},
|
|
16026
16026
|
reject(value) {
|
|
16027
16027
|
callPuppeteer.args.delete(seq);
|
|
@@ -19684,8 +19684,8 @@ var init_Input2 = __esm({
|
|
|
19684
19684
|
if (typeof delay === "number") {
|
|
19685
19685
|
await Promise.all(actions);
|
|
19686
19686
|
actions.length = 0;
|
|
19687
|
-
await new Promise((
|
|
19688
|
-
setTimeout(
|
|
19687
|
+
await new Promise((resolve14) => {
|
|
19688
|
+
setTimeout(resolve14, delay);
|
|
19689
19689
|
});
|
|
19690
19690
|
}
|
|
19691
19691
|
actions.push(this.up({ ...options, clickCount }));
|
|
@@ -19705,9 +19705,9 @@ var init_Input2 = __esm({
|
|
|
19705
19705
|
});
|
|
19706
19706
|
}
|
|
19707
19707
|
async drag(start, target) {
|
|
19708
|
-
const promise = new Promise((
|
|
19708
|
+
const promise = new Promise((resolve14) => {
|
|
19709
19709
|
this.#client.once("Input.dragIntercepted", (event) => {
|
|
19710
|
-
return
|
|
19710
|
+
return resolve14(event.data);
|
|
19711
19711
|
});
|
|
19712
19712
|
});
|
|
19713
19713
|
await this.move(start.x, start.y);
|
|
@@ -19748,8 +19748,8 @@ var init_Input2 = __esm({
|
|
|
19748
19748
|
await this.dragEnter(target, data);
|
|
19749
19749
|
await this.dragOver(target, data);
|
|
19750
19750
|
if (delay) {
|
|
19751
|
-
await new Promise((
|
|
19752
|
-
return setTimeout(
|
|
19751
|
+
await new Promise((resolve14) => {
|
|
19752
|
+
return setTimeout(resolve14, delay);
|
|
19753
19753
|
});
|
|
19754
19754
|
}
|
|
19755
19755
|
await this.drop(target, data);
|
|
@@ -20633,9 +20633,9 @@ var init_Page2 = __esm({
|
|
|
20633
20633
|
async captureHeapSnapshot(options) {
|
|
20634
20634
|
const { createWriteStream: createWriteStream3 } = environment.value.fs;
|
|
20635
20635
|
const stream2 = createWriteStream3(options.path);
|
|
20636
|
-
const streamPromise = new Promise((
|
|
20636
|
+
const streamPromise = new Promise((resolve14, reject) => {
|
|
20637
20637
|
stream2.on("error", reject);
|
|
20638
|
-
stream2.on("finish",
|
|
20638
|
+
stream2.on("finish", resolve14);
|
|
20639
20639
|
});
|
|
20640
20640
|
const client = this.#primaryTargetClient;
|
|
20641
20641
|
await client.send("HeapProfiler.enable");
|
|
@@ -22277,10 +22277,10 @@ var init_BrowserWebSocketTransport = __esm({
|
|
|
22277
22277
|
"../../node_modules/.bun/puppeteer-core@24.40.0/node_modules/puppeteer-core/lib/esm/puppeteer/common/BrowserWebSocketTransport.js"() {
|
|
22278
22278
|
BrowserWebSocketTransport = class _BrowserWebSocketTransport {
|
|
22279
22279
|
static create(url) {
|
|
22280
|
-
return new Promise((
|
|
22280
|
+
return new Promise((resolve14, reject) => {
|
|
22281
22281
|
const ws = new WebSocket(url);
|
|
22282
22282
|
ws.addEventListener("open", () => {
|
|
22283
|
-
return
|
|
22283
|
+
return resolve14(new _BrowserWebSocketTransport(ws));
|
|
22284
22284
|
});
|
|
22285
22285
|
ws.addEventListener("error", reject);
|
|
22286
22286
|
});
|
|
@@ -25202,11 +25202,11 @@ var require_BrowsingContextProcessor = __commonJS({
|
|
|
25202
25202
|
}
|
|
25203
25203
|
const parentCdpClient = context2.cdpTarget.parentCdpClient;
|
|
25204
25204
|
try {
|
|
25205
|
-
const detachedFromTargetPromise = new Promise((
|
|
25205
|
+
const detachedFromTargetPromise = new Promise((resolve14) => {
|
|
25206
25206
|
const onContextDestroyed = (event) => {
|
|
25207
25207
|
if (event.targetId === params.context) {
|
|
25208
25208
|
parentCdpClient.off("Target.detachedFromTarget", onContextDestroyed);
|
|
25209
|
-
|
|
25209
|
+
resolve14();
|
|
25210
25210
|
}
|
|
25211
25211
|
};
|
|
25212
25212
|
parentCdpClient.on("Target.detachedFromTarget", onContextDestroyed);
|
|
@@ -26569,7 +26569,7 @@ var require_ActionDispatcher = __commonJS({
|
|
|
26569
26569
|
}
|
|
26570
26570
|
}
|
|
26571
26571
|
const promises = [
|
|
26572
|
-
new Promise((
|
|
26572
|
+
new Promise((resolve14) => setTimeout(resolve14, this.#tickDuration))
|
|
26573
26573
|
];
|
|
26574
26574
|
for (const option of options) {
|
|
26575
26575
|
promises.push(this.#dispatchAction(option));
|
|
@@ -27170,8 +27170,8 @@ var require_Mutex = __commonJS({
|
|
|
27170
27170
|
acquire() {
|
|
27171
27171
|
const state = { resolved: false };
|
|
27172
27172
|
if (this.#locked) {
|
|
27173
|
-
return new Promise((
|
|
27174
|
-
this.#acquirers.push(() =>
|
|
27173
|
+
return new Promise((resolve14) => {
|
|
27174
|
+
this.#acquirers.push(() => resolve14(this.#release.bind(this, state)));
|
|
27175
27175
|
});
|
|
27176
27176
|
}
|
|
27177
27177
|
this.#locked = true;
|
|
@@ -27182,12 +27182,12 @@ var require_Mutex = __commonJS({
|
|
|
27182
27182
|
throw new Error("Cannot release more than once.");
|
|
27183
27183
|
}
|
|
27184
27184
|
state.resolved = true;
|
|
27185
|
-
const
|
|
27186
|
-
if (!
|
|
27185
|
+
const resolve14 = this.#acquirers.shift();
|
|
27186
|
+
if (!resolve14) {
|
|
27187
27187
|
this.#locked = false;
|
|
27188
27188
|
return;
|
|
27189
27189
|
}
|
|
27190
|
-
|
|
27190
|
+
resolve14();
|
|
27191
27191
|
}
|
|
27192
27192
|
async run(action) {
|
|
27193
27193
|
const release = await this.acquire();
|
|
@@ -28369,8 +28369,8 @@ var require_ChannelProxy = __commonJS({
|
|
|
28369
28369
|
* in the queue.
|
|
28370
28370
|
*/
|
|
28371
28371
|
async getMessage() {
|
|
28372
|
-
const onMessage = queue.length > 0 ? Promise.resolve() : new Promise((
|
|
28373
|
-
queueNonEmptyResolver =
|
|
28372
|
+
const onMessage = queue.length > 0 ? Promise.resolve() : new Promise((resolve14) => {
|
|
28373
|
+
queueNonEmptyResolver = resolve14;
|
|
28374
28374
|
});
|
|
28375
28375
|
await onMessage;
|
|
28376
28376
|
return queue.shift();
|
|
@@ -28475,7 +28475,7 @@ var require_ChannelProxy = __commonJS({
|
|
|
28475
28475
|
functionDeclaration: String((id) => {
|
|
28476
28476
|
const w = window;
|
|
28477
28477
|
if (w[id] === void 0) {
|
|
28478
|
-
return new Promise((
|
|
28478
|
+
return new Promise((resolve14) => w[id] = resolve14);
|
|
28479
28479
|
}
|
|
28480
28480
|
const channelProxy = w[id];
|
|
28481
28481
|
delete w[id];
|
|
@@ -29976,8 +29976,8 @@ var require_Deferred = __commonJS({
|
|
|
29976
29976
|
return this.#result;
|
|
29977
29977
|
}
|
|
29978
29978
|
constructor() {
|
|
29979
|
-
this.#promise = new Promise((
|
|
29980
|
-
this.#resolve =
|
|
29979
|
+
this.#promise = new Promise((resolve14, reject) => {
|
|
29980
|
+
this.#resolve = resolve14;
|
|
29981
29981
|
this.#reject = reject;
|
|
29982
29982
|
});
|
|
29983
29983
|
this.#promise.catch((_error) => {
|
|
@@ -34821,11 +34821,11 @@ var require_BrowsingContextStorage = __commonJS({
|
|
|
34821
34821
|
if (this.#contexts.has(browsingContextId)) {
|
|
34822
34822
|
return Promise.resolve(this.getContext(browsingContextId));
|
|
34823
34823
|
}
|
|
34824
|
-
return new Promise((
|
|
34824
|
+
return new Promise((resolve14) => {
|
|
34825
34825
|
const listener = (event) => {
|
|
34826
34826
|
if (event.browsingContext.id === browsingContextId) {
|
|
34827
34827
|
this.#eventEmitter.off("added", listener);
|
|
34828
|
-
|
|
34828
|
+
resolve14(event.browsingContext);
|
|
34829
34829
|
}
|
|
34830
34830
|
};
|
|
34831
34831
|
this.#eventEmitter.on("added", listener);
|
|
@@ -38407,8 +38407,8 @@ var init_ExposedFunction = __esm({
|
|
|
38407
38407
|
const functionDeclaration = stringifyFunction(interpolateFunction((callback) => {
|
|
38408
38408
|
Object.assign(globalThis, {
|
|
38409
38409
|
[PLACEHOLDER("name")]: function(...args) {
|
|
38410
|
-
return new Promise((
|
|
38411
|
-
callback([
|
|
38410
|
+
return new Promise((resolve14, reject) => {
|
|
38411
|
+
callback([resolve14, reject, args]);
|
|
38412
38412
|
});
|
|
38413
38413
|
}
|
|
38414
38414
|
});
|
|
@@ -38496,8 +38496,8 @@ var init_ExposedFunction = __esm({
|
|
|
38496
38496
|
return;
|
|
38497
38497
|
}
|
|
38498
38498
|
try {
|
|
38499
|
-
await dataHandle.evaluate(([
|
|
38500
|
-
|
|
38499
|
+
await dataHandle.evaluate(([resolve14], result2) => {
|
|
38500
|
+
resolve14(result2);
|
|
38501
38501
|
}, result);
|
|
38502
38502
|
} catch (error) {
|
|
38503
38503
|
debugError(error);
|
|
@@ -46578,7 +46578,7 @@ var init_NodeWebSocketTransport = __esm({
|
|
|
46578
46578
|
init_version();
|
|
46579
46579
|
NodeWebSocketTransport = class _NodeWebSocketTransport {
|
|
46580
46580
|
static create(url, headers) {
|
|
46581
|
-
return new Promise((
|
|
46581
|
+
return new Promise((resolve14, reject) => {
|
|
46582
46582
|
const ws = new wrapper_default(url, [], {
|
|
46583
46583
|
followRedirects: true,
|
|
46584
46584
|
perMessageDeflate: false,
|
|
@@ -46591,7 +46591,7 @@ var init_NodeWebSocketTransport = __esm({
|
|
|
46591
46591
|
}
|
|
46592
46592
|
});
|
|
46593
46593
|
ws.addEventListener("open", () => {
|
|
46594
|
-
return
|
|
46594
|
+
return resolve14(new _NodeWebSocketTransport(ws));
|
|
46595
46595
|
});
|
|
46596
46596
|
ws.addEventListener("error", reject);
|
|
46597
46597
|
});
|
|
@@ -49652,8 +49652,8 @@ var require_helpers = __commonJS({
|
|
|
49652
49652
|
function req(url, opts = {}) {
|
|
49653
49653
|
const href = typeof url === "string" ? url : url.href;
|
|
49654
49654
|
const req2 = (href.startsWith("https:") ? https2 : http2).request(url, opts);
|
|
49655
|
-
const promise = new Promise((
|
|
49656
|
-
req2.once("response",
|
|
49655
|
+
const promise = new Promise((resolve14, reject) => {
|
|
49656
|
+
req2.once("response", resolve14).once("error", reject).end();
|
|
49657
49657
|
});
|
|
49658
49658
|
req2.then = promise.then.bind(promise);
|
|
49659
49659
|
return req2;
|
|
@@ -50030,7 +50030,7 @@ var require_parse_proxy_response = __commonJS({
|
|
|
50030
50030
|
var debug_1 = __importDefault2(require_src());
|
|
50031
50031
|
var debug6 = (0, debug_1.default)("https-proxy-agent:parse-proxy-response");
|
|
50032
50032
|
function parseProxyResponse(socket) {
|
|
50033
|
-
return new Promise((
|
|
50033
|
+
return new Promise((resolve14, reject) => {
|
|
50034
50034
|
let buffersLength = 0;
|
|
50035
50035
|
const buffers = [];
|
|
50036
50036
|
function read() {
|
|
@@ -50096,7 +50096,7 @@ var require_parse_proxy_response = __commonJS({
|
|
|
50096
50096
|
}
|
|
50097
50097
|
debug6("got proxy server response: %o %o", firstLine, headers);
|
|
50098
50098
|
cleanup();
|
|
50099
|
-
|
|
50099
|
+
resolve14({
|
|
50100
50100
|
connect: {
|
|
50101
50101
|
statusCode,
|
|
50102
50102
|
statusText,
|
|
@@ -53354,11 +53354,11 @@ var require_socksclient = __commonJS({
|
|
|
53354
53354
|
"use strict";
|
|
53355
53355
|
var __awaiter3 = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
53356
53356
|
function adopt(value) {
|
|
53357
|
-
return value instanceof P ? value : new P(function(
|
|
53358
|
-
|
|
53357
|
+
return value instanceof P ? value : new P(function(resolve14) {
|
|
53358
|
+
resolve14(value);
|
|
53359
53359
|
});
|
|
53360
53360
|
}
|
|
53361
|
-
return new (P || (P = Promise))(function(
|
|
53361
|
+
return new (P || (P = Promise))(function(resolve14, reject) {
|
|
53362
53362
|
function fulfilled(value) {
|
|
53363
53363
|
try {
|
|
53364
53364
|
step(generator.next(value));
|
|
@@ -53374,7 +53374,7 @@ var require_socksclient = __commonJS({
|
|
|
53374
53374
|
}
|
|
53375
53375
|
}
|
|
53376
53376
|
function step(result) {
|
|
53377
|
-
result.done ?
|
|
53377
|
+
result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
53378
53378
|
}
|
|
53379
53379
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
53380
53380
|
});
|
|
@@ -53408,13 +53408,13 @@ var require_socksclient = __commonJS({
|
|
|
53408
53408
|
* @returns { Promise }
|
|
53409
53409
|
*/
|
|
53410
53410
|
static createConnection(options, callback) {
|
|
53411
|
-
return new Promise((
|
|
53411
|
+
return new Promise((resolve14, reject) => {
|
|
53412
53412
|
try {
|
|
53413
53413
|
(0, helpers_1.validateSocksClientOptions)(options, ["connect"]);
|
|
53414
53414
|
} catch (err) {
|
|
53415
53415
|
if (typeof callback === "function") {
|
|
53416
53416
|
callback(err);
|
|
53417
|
-
return
|
|
53417
|
+
return resolve14(err);
|
|
53418
53418
|
} else {
|
|
53419
53419
|
return reject(err);
|
|
53420
53420
|
}
|
|
@@ -53425,16 +53425,16 @@ var require_socksclient = __commonJS({
|
|
|
53425
53425
|
client.removeAllListeners();
|
|
53426
53426
|
if (typeof callback === "function") {
|
|
53427
53427
|
callback(null, info);
|
|
53428
|
-
|
|
53428
|
+
resolve14(info);
|
|
53429
53429
|
} else {
|
|
53430
|
-
|
|
53430
|
+
resolve14(info);
|
|
53431
53431
|
}
|
|
53432
53432
|
});
|
|
53433
53433
|
client.once("error", (err) => {
|
|
53434
53434
|
client.removeAllListeners();
|
|
53435
53435
|
if (typeof callback === "function") {
|
|
53436
53436
|
callback(err);
|
|
53437
|
-
|
|
53437
|
+
resolve14(err);
|
|
53438
53438
|
} else {
|
|
53439
53439
|
reject(err);
|
|
53440
53440
|
}
|
|
@@ -53451,13 +53451,13 @@ var require_socksclient = __commonJS({
|
|
|
53451
53451
|
* @returns { Promise }
|
|
53452
53452
|
*/
|
|
53453
53453
|
static createConnectionChain(options, callback) {
|
|
53454
|
-
return new Promise((
|
|
53454
|
+
return new Promise((resolve14, reject) => __awaiter3(this, void 0, void 0, function* () {
|
|
53455
53455
|
try {
|
|
53456
53456
|
(0, helpers_1.validateSocksClientChainOptions)(options);
|
|
53457
53457
|
} catch (err) {
|
|
53458
53458
|
if (typeof callback === "function") {
|
|
53459
53459
|
callback(err);
|
|
53460
|
-
return
|
|
53460
|
+
return resolve14(err);
|
|
53461
53461
|
} else {
|
|
53462
53462
|
return reject(err);
|
|
53463
53463
|
}
|
|
@@ -53483,14 +53483,14 @@ var require_socksclient = __commonJS({
|
|
|
53483
53483
|
}
|
|
53484
53484
|
if (typeof callback === "function") {
|
|
53485
53485
|
callback(null, { socket: sock });
|
|
53486
|
-
|
|
53486
|
+
resolve14({ socket: sock });
|
|
53487
53487
|
} else {
|
|
53488
|
-
|
|
53488
|
+
resolve14({ socket: sock });
|
|
53489
53489
|
}
|
|
53490
53490
|
} catch (err) {
|
|
53491
53491
|
if (typeof callback === "function") {
|
|
53492
53492
|
callback(err);
|
|
53493
|
-
|
|
53493
|
+
resolve14(err);
|
|
53494
53494
|
} else {
|
|
53495
53495
|
reject(err);
|
|
53496
53496
|
}
|
|
@@ -54174,12 +54174,12 @@ var require_dist4 = __commonJS({
|
|
|
54174
54174
|
let { host } = opts;
|
|
54175
54175
|
const { port, lookup: lookupFn = dns.lookup } = opts;
|
|
54176
54176
|
if (shouldLookup) {
|
|
54177
|
-
host = await new Promise((
|
|
54177
|
+
host = await new Promise((resolve14, reject) => {
|
|
54178
54178
|
lookupFn(host, {}, (err, res) => {
|
|
54179
54179
|
if (err) {
|
|
54180
54180
|
reject(err);
|
|
54181
54181
|
} else {
|
|
54182
|
-
|
|
54182
|
+
resolve14(res);
|
|
54183
54183
|
}
|
|
54184
54184
|
});
|
|
54185
54185
|
});
|
|
@@ -55364,7 +55364,7 @@ var require_netUtils = __commonJS({
|
|
|
55364
55364
|
return `${socket.remoteAddress}:${socket.remotePort}`;
|
|
55365
55365
|
}
|
|
55366
55366
|
function upgradeSocket(socket, options) {
|
|
55367
|
-
return new Promise((
|
|
55367
|
+
return new Promise((resolve14, reject) => {
|
|
55368
55368
|
const tlsOptions = Object.assign({}, options, {
|
|
55369
55369
|
socket
|
|
55370
55370
|
});
|
|
@@ -55374,7 +55374,7 @@ var require_netUtils = __commonJS({
|
|
|
55374
55374
|
reject(tlsSocket.authorizationError);
|
|
55375
55375
|
} else {
|
|
55376
55376
|
tlsSocket.removeAllListeners("error");
|
|
55377
|
-
|
|
55377
|
+
resolve14(tlsSocket);
|
|
55378
55378
|
}
|
|
55379
55379
|
}).once("error", (error) => {
|
|
55380
55380
|
reject(error);
|
|
@@ -55469,7 +55469,7 @@ var require_transfer = __commonJS({
|
|
|
55469
55469
|
};
|
|
55470
55470
|
}
|
|
55471
55471
|
function connectForPassiveTransfer(host, port, ftp) {
|
|
55472
|
-
return new Promise((
|
|
55472
|
+
return new Promise((resolve14, reject) => {
|
|
55473
55473
|
let socket = ftp._newSocket();
|
|
55474
55474
|
const handleConnErr = function(err) {
|
|
55475
55475
|
err.message = "Can't open data connection in passive mode: " + err.message;
|
|
@@ -55497,7 +55497,7 @@ var require_transfer = __commonJS({
|
|
|
55497
55497
|
socket.removeListener("error", handleConnErr);
|
|
55498
55498
|
socket.removeListener("timeout", handleTimeout);
|
|
55499
55499
|
ftp.dataSocket = socket;
|
|
55500
|
-
|
|
55500
|
+
resolve14();
|
|
55501
55501
|
});
|
|
55502
55502
|
});
|
|
55503
55503
|
}
|
|
@@ -57866,7 +57866,7 @@ var require_util2 = __commonJS({
|
|
|
57866
57866
|
}
|
|
57867
57867
|
path12 = url.path;
|
|
57868
57868
|
}
|
|
57869
|
-
var
|
|
57869
|
+
var isAbsolute5 = exports.isAbsolute(path12);
|
|
57870
57870
|
var parts = path12.split(/\/+/);
|
|
57871
57871
|
for (var part, up = 0, i = parts.length - 1; i >= 0; i--) {
|
|
57872
57872
|
part = parts[i];
|
|
@@ -57886,7 +57886,7 @@ var require_util2 = __commonJS({
|
|
|
57886
57886
|
}
|
|
57887
57887
|
path12 = parts.join("/");
|
|
57888
57888
|
if (path12 === "") {
|
|
57889
|
-
path12 =
|
|
57889
|
+
path12 = isAbsolute5 ? "/" : ".";
|
|
57890
57890
|
}
|
|
57891
57891
|
if (url) {
|
|
57892
57892
|
url.path = path12;
|
|
@@ -67966,11 +67966,11 @@ function __metadata(metadataKey, metadataValue) {
|
|
|
67966
67966
|
}
|
|
67967
67967
|
function __awaiter2(thisArg, _arguments, P, generator) {
|
|
67968
67968
|
function adopt(value) {
|
|
67969
|
-
return value instanceof P ? value : new P(function(
|
|
67970
|
-
|
|
67969
|
+
return value instanceof P ? value : new P(function(resolve14) {
|
|
67970
|
+
resolve14(value);
|
|
67971
67971
|
});
|
|
67972
67972
|
}
|
|
67973
|
-
return new (P || (P = Promise))(function(
|
|
67973
|
+
return new (P || (P = Promise))(function(resolve14, reject) {
|
|
67974
67974
|
function fulfilled(value) {
|
|
67975
67975
|
try {
|
|
67976
67976
|
step(generator.next(value));
|
|
@@ -67986,7 +67986,7 @@ function __awaiter2(thisArg, _arguments, P, generator) {
|
|
|
67986
67986
|
}
|
|
67987
67987
|
}
|
|
67988
67988
|
function step(result) {
|
|
67989
|
-
result.done ?
|
|
67989
|
+
result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
67990
67990
|
}
|
|
67991
67991
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
67992
67992
|
});
|
|
@@ -68177,14 +68177,14 @@ function __asyncValues2(o) {
|
|
|
68177
68177
|
}, i);
|
|
68178
68178
|
function verb(n) {
|
|
68179
68179
|
i[n] = o[n] && function(v) {
|
|
68180
|
-
return new Promise(function(
|
|
68181
|
-
v = o[n](v), settle(
|
|
68180
|
+
return new Promise(function(resolve14, reject) {
|
|
68181
|
+
v = o[n](v), settle(resolve14, reject, v.done, v.value);
|
|
68182
68182
|
});
|
|
68183
68183
|
};
|
|
68184
68184
|
}
|
|
68185
|
-
function settle(
|
|
68185
|
+
function settle(resolve14, reject, d, v) {
|
|
68186
68186
|
Promise.resolve(v).then(function(v2) {
|
|
68187
|
-
|
|
68187
|
+
resolve14({ value: v2, done: d });
|
|
68188
68188
|
}, reject);
|
|
68189
68189
|
}
|
|
68190
68190
|
}
|
|
@@ -71737,12 +71737,12 @@ var require_util3 = __commonJS({
|
|
|
71737
71737
|
exports.isGMT = exports.dnsLookup = void 0;
|
|
71738
71738
|
var dns_1 = __require("dns");
|
|
71739
71739
|
function dnsLookup(host, opts) {
|
|
71740
|
-
return new Promise((
|
|
71740
|
+
return new Promise((resolve14, reject) => {
|
|
71741
71741
|
(0, dns_1.lookup)(host, opts, (err, res) => {
|
|
71742
71742
|
if (err) {
|
|
71743
71743
|
reject(err);
|
|
71744
71744
|
} else {
|
|
71745
|
-
|
|
71745
|
+
resolve14(res);
|
|
71746
71746
|
}
|
|
71747
71747
|
});
|
|
71748
71748
|
});
|
|
@@ -72107,10 +72107,10 @@ var require_myIpAddress = __commonJS({
|
|
|
72107
72107
|
var ip_1 = require_ip();
|
|
72108
72108
|
var net_1 = __importDefault2(__require("net"));
|
|
72109
72109
|
async function myIpAddress() {
|
|
72110
|
-
return new Promise((
|
|
72110
|
+
return new Promise((resolve14, reject) => {
|
|
72111
72111
|
const socket = net_1.default.connect({ host: "8.8.8.8", port: 53 });
|
|
72112
72112
|
const onError = () => {
|
|
72113
|
-
|
|
72113
|
+
resolve14(ip_1.ip.address());
|
|
72114
72114
|
};
|
|
72115
72115
|
socket.once("error", onError);
|
|
72116
72116
|
socket.once("connect", () => {
|
|
@@ -72118,9 +72118,9 @@ var require_myIpAddress = __commonJS({
|
|
|
72118
72118
|
const addr = socket.address();
|
|
72119
72119
|
socket.destroy();
|
|
72120
72120
|
if (typeof addr === "string") {
|
|
72121
|
-
|
|
72121
|
+
resolve14(addr);
|
|
72122
72122
|
} else if (addr.address) {
|
|
72123
|
-
|
|
72123
|
+
resolve14(addr.address);
|
|
72124
72124
|
} else {
|
|
72125
72125
|
reject(new Error("Expected a `string`"));
|
|
72126
72126
|
}
|
|
@@ -72698,8 +72698,8 @@ var require_deferred_promise = __commonJS({
|
|
|
72698
72698
|
this.context = args.context;
|
|
72699
72699
|
this.owner = args.context.runtime;
|
|
72700
72700
|
this.handle = args.promiseHandle;
|
|
72701
|
-
this.settled = new Promise((
|
|
72702
|
-
this.onSettled =
|
|
72701
|
+
this.settled = new Promise((resolve14) => {
|
|
72702
|
+
this.onSettled = resolve14;
|
|
72703
72703
|
});
|
|
72704
72704
|
this.resolveHandle = args.resolveHandle;
|
|
72705
72705
|
this.rejectHandle = args.rejectHandle;
|
|
@@ -73220,13 +73220,13 @@ var require_context = __commonJS({
|
|
|
73220
73220
|
if (vmResolveResult.error) {
|
|
73221
73221
|
return Promise.resolve(vmResolveResult);
|
|
73222
73222
|
}
|
|
73223
|
-
return new Promise((
|
|
73223
|
+
return new Promise((resolve14) => {
|
|
73224
73224
|
lifetime_1.Scope.withScope((scope) => {
|
|
73225
73225
|
const resolveHandle = scope.manage(this.newFunction("resolve", (value) => {
|
|
73226
|
-
|
|
73226
|
+
resolve14({ value: value && value.dup() });
|
|
73227
73227
|
}));
|
|
73228
73228
|
const rejectHandle = scope.manage(this.newFunction("reject", (error) => {
|
|
73229
|
-
|
|
73229
|
+
resolve14({ error: error && error.dup() });
|
|
73230
73230
|
}));
|
|
73231
73231
|
const promiseHandle = scope.manage(vmResolveResult.value);
|
|
73232
73232
|
const promiseThenHandle = scope.manage(this.getProp(promiseHandle, "then"));
|
|
@@ -75601,13 +75601,13 @@ import * as http from "node:http";
|
|
|
75601
75601
|
import * as https from "node:https";
|
|
75602
75602
|
import { URL as URL2, urlToHttpOptions } from "node:url";
|
|
75603
75603
|
function headHttpRequest(url) {
|
|
75604
|
-
return new Promise((
|
|
75604
|
+
return new Promise((resolve14) => {
|
|
75605
75605
|
const request3 = httpRequest(url, "HEAD", (response) => {
|
|
75606
75606
|
response.resume();
|
|
75607
|
-
|
|
75607
|
+
resolve14(response.statusCode === 200);
|
|
75608
75608
|
}, false);
|
|
75609
75609
|
request3.on("error", () => {
|
|
75610
|
-
|
|
75610
|
+
resolve14(false);
|
|
75611
75611
|
});
|
|
75612
75612
|
});
|
|
75613
75613
|
}
|
|
@@ -75635,7 +75635,7 @@ function httpRequest(url, method, response, keepAlive = true) {
|
|
|
75635
75635
|
return request3;
|
|
75636
75636
|
}
|
|
75637
75637
|
function downloadFile(url, destinationPath, progressCallback) {
|
|
75638
|
-
return new Promise((
|
|
75638
|
+
return new Promise((resolve14, reject) => {
|
|
75639
75639
|
let downloadedBytes = 0;
|
|
75640
75640
|
let totalBytes = 0;
|
|
75641
75641
|
function onData(chunk) {
|
|
@@ -75651,7 +75651,7 @@ function downloadFile(url, destinationPath, progressCallback) {
|
|
|
75651
75651
|
}
|
|
75652
75652
|
const file = createWriteStream(destinationPath);
|
|
75653
75653
|
file.on("close", () => {
|
|
75654
|
-
return
|
|
75654
|
+
return resolve14();
|
|
75655
75655
|
});
|
|
75656
75656
|
file.on("error", (error) => {
|
|
75657
75657
|
return reject(error);
|
|
@@ -75676,7 +75676,7 @@ async function getJSON(url) {
|
|
|
75676
75676
|
}
|
|
75677
75677
|
}
|
|
75678
75678
|
function getText3(url) {
|
|
75679
|
-
return new Promise((
|
|
75679
|
+
return new Promise((resolve14, reject) => {
|
|
75680
75680
|
const request3 = httpRequest(url, "GET", (response) => {
|
|
75681
75681
|
let data = "";
|
|
75682
75682
|
if (response.statusCode && response.statusCode >= 400) {
|
|
@@ -75687,7 +75687,7 @@ function getText3(url) {
|
|
|
75687
75687
|
});
|
|
75688
75688
|
response.on("end", () => {
|
|
75689
75689
|
try {
|
|
75690
|
-
return
|
|
75690
|
+
return resolve14(String(data));
|
|
75691
75691
|
} catch {
|
|
75692
75692
|
return reject(new Error(`Failed to read text response from ${url}`));
|
|
75693
75693
|
}
|
|
@@ -77079,7 +77079,7 @@ var init_launch = __esm({
|
|
|
77079
77079
|
if (opts.onExit) {
|
|
77080
77080
|
this.#onExitHook = opts.onExit;
|
|
77081
77081
|
}
|
|
77082
|
-
this.#browserProcessExiting = new Promise((
|
|
77082
|
+
this.#browserProcessExiting = new Promise((resolve14, reject) => {
|
|
77083
77083
|
this.#browserProcess.once("exit", async () => {
|
|
77084
77084
|
debugLaunch(`Browser process ${this.#browserProcess.pid} onExit`);
|
|
77085
77085
|
this.#clearListeners();
|
|
@@ -77090,7 +77090,7 @@ var init_launch = __esm({
|
|
|
77090
77090
|
reject(err);
|
|
77091
77091
|
return;
|
|
77092
77092
|
}
|
|
77093
|
-
|
|
77093
|
+
resolve14();
|
|
77094
77094
|
});
|
|
77095
77095
|
});
|
|
77096
77096
|
}
|
|
@@ -77206,7 +77206,7 @@ Error cause: ${isErrorLike2(error) ? error.stack : error}`);
|
|
|
77206
77206
|
return [...this.#logs];
|
|
77207
77207
|
}
|
|
77208
77208
|
waitForLineOutput(regex, timeout2 = 0) {
|
|
77209
|
-
return new Promise((
|
|
77209
|
+
return new Promise((resolve14, reject) => {
|
|
77210
77210
|
const onClose = (errorOrCode) => {
|
|
77211
77211
|
cleanup();
|
|
77212
77212
|
reject(new Error([
|
|
@@ -77242,7 +77242,7 @@ Error cause: ${isErrorLike2(error) ? error.stack : error}`);
|
|
|
77242
77242
|
return;
|
|
77243
77243
|
}
|
|
77244
77244
|
cleanup();
|
|
77245
|
-
|
|
77245
|
+
resolve14(match2[1]);
|
|
77246
77246
|
}
|
|
77247
77247
|
});
|
|
77248
77248
|
}
|
|
@@ -77711,7 +77711,7 @@ var require_get_stream = __commonJS({
|
|
|
77711
77711
|
};
|
|
77712
77712
|
const { maxBuffer } = options;
|
|
77713
77713
|
let stream2;
|
|
77714
|
-
await new Promise((
|
|
77714
|
+
await new Promise((resolve14, reject) => {
|
|
77715
77715
|
const rejectPromise = (error) => {
|
|
77716
77716
|
if (error && stream2.getBufferedLength() <= BufferConstants.MAX_LENGTH) {
|
|
77717
77717
|
error.bufferedData = stream2.getBufferedValue();
|
|
@@ -77723,7 +77723,7 @@ var require_get_stream = __commonJS({
|
|
|
77723
77723
|
rejectPromise(error);
|
|
77724
77724
|
return;
|
|
77725
77725
|
}
|
|
77726
|
-
|
|
77726
|
+
resolve14();
|
|
77727
77727
|
});
|
|
77728
77728
|
stream2.on("data", () => {
|
|
77729
77729
|
if (stream2.getBufferedLength() > maxBuffer) {
|
|
@@ -79012,7 +79012,7 @@ var require_extract_zip = __commonJS({
|
|
|
79012
79012
|
debug6("opening", this.zipPath, "with opts", this.opts);
|
|
79013
79013
|
this.zipfile = await openZip(this.zipPath, { lazyEntries: true });
|
|
79014
79014
|
this.canceled = false;
|
|
79015
|
-
return new Promise((
|
|
79015
|
+
return new Promise((resolve14, reject) => {
|
|
79016
79016
|
this.zipfile.on("error", (err) => {
|
|
79017
79017
|
this.canceled = true;
|
|
79018
79018
|
reject(err);
|
|
@@ -79021,7 +79021,7 @@ var require_extract_zip = __commonJS({
|
|
|
79021
79021
|
this.zipfile.on("close", () => {
|
|
79022
79022
|
if (!this.canceled) {
|
|
79023
79023
|
debug6("zip extraction complete");
|
|
79024
|
-
|
|
79024
|
+
resolve14();
|
|
79025
79025
|
}
|
|
79026
79026
|
});
|
|
79027
79027
|
this.zipfile.on("entry", async (entry) => {
|
|
@@ -80278,8 +80278,8 @@ var require_streamx = __commonJS({
|
|
|
80278
80278
|
return this;
|
|
80279
80279
|
},
|
|
80280
80280
|
next() {
|
|
80281
|
-
return new Promise(function(
|
|
80282
|
-
promiseResolve =
|
|
80281
|
+
return new Promise(function(resolve14, reject) {
|
|
80282
|
+
promiseResolve = resolve14;
|
|
80283
80283
|
promiseReject = reject;
|
|
80284
80284
|
const data = stream2.read();
|
|
80285
80285
|
if (data !== null) ondata(data);
|
|
@@ -80309,11 +80309,11 @@ var require_streamx = __commonJS({
|
|
|
80309
80309
|
}
|
|
80310
80310
|
function destroy(err) {
|
|
80311
80311
|
stream2.destroy(err);
|
|
80312
|
-
return new Promise((
|
|
80313
|
-
if (stream2._duplexState & DESTROYED) return
|
|
80312
|
+
return new Promise((resolve14, reject) => {
|
|
80313
|
+
if (stream2._duplexState & DESTROYED) return resolve14({ value: void 0, done: true });
|
|
80314
80314
|
stream2.once("close", function() {
|
|
80315
80315
|
if (err) reject(err);
|
|
80316
|
-
else
|
|
80316
|
+
else resolve14({ value: void 0, done: true });
|
|
80317
80317
|
});
|
|
80318
80318
|
});
|
|
80319
80319
|
}
|
|
@@ -80357,8 +80357,8 @@ var require_streamx = __commonJS({
|
|
|
80357
80357
|
const writes = pending + (ws._duplexState & WRITE_WRITING ? 1 : 0);
|
|
80358
80358
|
if (writes === 0) return Promise.resolve(true);
|
|
80359
80359
|
if (state.drains === null) state.drains = [];
|
|
80360
|
-
return new Promise((
|
|
80361
|
-
state.drains.push({ writes, resolve:
|
|
80360
|
+
return new Promise((resolve14) => {
|
|
80361
|
+
state.drains.push({ writes, resolve: resolve14 });
|
|
80362
80362
|
});
|
|
80363
80363
|
}
|
|
80364
80364
|
write(data) {
|
|
@@ -80463,10 +80463,10 @@ var require_streamx = __commonJS({
|
|
|
80463
80463
|
cb(null);
|
|
80464
80464
|
}
|
|
80465
80465
|
function pipelinePromise(...streams) {
|
|
80466
|
-
return new Promise((
|
|
80466
|
+
return new Promise((resolve14, reject) => {
|
|
80467
80467
|
return pipeline(...streams, (err) => {
|
|
80468
80468
|
if (err) return reject(err);
|
|
80469
|
-
|
|
80469
|
+
resolve14();
|
|
80470
80470
|
});
|
|
80471
80471
|
});
|
|
80472
80472
|
}
|
|
@@ -81121,16 +81121,16 @@ var require_extract = __commonJS({
|
|
|
81121
81121
|
entryCallback = null;
|
|
81122
81122
|
cb(err);
|
|
81123
81123
|
}
|
|
81124
|
-
function onnext(
|
|
81124
|
+
function onnext(resolve14, reject) {
|
|
81125
81125
|
if (error) {
|
|
81126
81126
|
return reject(error);
|
|
81127
81127
|
}
|
|
81128
81128
|
if (entryStream) {
|
|
81129
|
-
|
|
81129
|
+
resolve14({ value: entryStream, done: false });
|
|
81130
81130
|
entryStream = null;
|
|
81131
81131
|
return;
|
|
81132
81132
|
}
|
|
81133
|
-
promiseResolve =
|
|
81133
|
+
promiseResolve = resolve14;
|
|
81134
81134
|
promiseReject = reject;
|
|
81135
81135
|
consumeCallback(null);
|
|
81136
81136
|
if (extract._finished && promiseResolve) {
|
|
@@ -81158,11 +81158,11 @@ var require_extract = __commonJS({
|
|
|
81158
81158
|
function destroy(err) {
|
|
81159
81159
|
extract.destroy(err);
|
|
81160
81160
|
consumeCallback(err);
|
|
81161
|
-
return new Promise((
|
|
81162
|
-
if (extract.destroyed) return
|
|
81161
|
+
return new Promise((resolve14, reject) => {
|
|
81162
|
+
if (extract.destroyed) return resolve14({ value: void 0, done: true });
|
|
81163
81163
|
extract.once("close", function() {
|
|
81164
81164
|
if (err) reject(err);
|
|
81165
|
-
else
|
|
81165
|
+
else resolve14({ value: void 0, done: true });
|
|
81166
81166
|
});
|
|
81167
81167
|
});
|
|
81168
81168
|
}
|
|
@@ -84931,13 +84931,13 @@ function usage(yargs, shim3) {
|
|
|
84931
84931
|
};
|
|
84932
84932
|
self2.stringifiedValues = function stringifiedValues(values, separator) {
|
|
84933
84933
|
let string = "";
|
|
84934
|
-
const
|
|
84934
|
+
const sep2 = separator || ", ";
|
|
84935
84935
|
const array = [].concat(values);
|
|
84936
84936
|
if (!values || !array.length)
|
|
84937
84937
|
return string;
|
|
84938
84938
|
array.forEach((value) => {
|
|
84939
84939
|
if (string.length)
|
|
84940
|
-
string +=
|
|
84940
|
+
string += sep2;
|
|
84941
84941
|
string += JSON.stringify(value);
|
|
84942
84942
|
});
|
|
84943
84943
|
return string;
|
|
@@ -86138,12 +86138,12 @@ var init_yargs_factory = __esm({
|
|
|
86138
86138
|
async getCompletion(args, done) {
|
|
86139
86139
|
argsert("<array> [function]", [args, done], arguments.length);
|
|
86140
86140
|
if (!done) {
|
|
86141
|
-
return new Promise((
|
|
86141
|
+
return new Promise((resolve14, reject) => {
|
|
86142
86142
|
__classPrivateFieldGet2(this, _YargsInstance_completion, "f").getCompletion(args, (err, completions) => {
|
|
86143
86143
|
if (err)
|
|
86144
86144
|
reject(err);
|
|
86145
86145
|
else
|
|
86146
|
-
|
|
86146
|
+
resolve14(completions);
|
|
86147
86147
|
});
|
|
86148
86148
|
});
|
|
86149
86149
|
} else {
|
|
@@ -88944,8 +88944,8 @@ var init_ScreenRecorder = __esm({
|
|
|
88944
88944
|
static {
|
|
88945
88945
|
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
88946
88946
|
__esDecorate23(this, _private_writeFrame_descriptor = { value: __setFunctionName6(async function(buffer) {
|
|
88947
|
-
const error = await new Promise((
|
|
88948
|
-
this.#process.stdin.write(buffer,
|
|
88947
|
+
const error = await new Promise((resolve14) => {
|
|
88948
|
+
this.#process.stdin.write(buffer, resolve14);
|
|
88949
88949
|
});
|
|
88950
88950
|
if (error) {
|
|
88951
88951
|
console.log(`ffmpeg failed to write: ${error.message}.`);
|
|
@@ -89135,8 +89135,8 @@ var init_ScreenRecorder = __esm({
|
|
|
89135
89135
|
const [buffer, timestamp] = await this.#lastFrame;
|
|
89136
89136
|
await Promise.all(Array(Math.max(1, Math.round(this.#fps * (performance.now() - timestamp) / 1e3))).fill(buffer).map(this.#writeFrame.bind(this)));
|
|
89137
89137
|
this.#process.stdin.end();
|
|
89138
|
-
await new Promise((
|
|
89139
|
-
this.#process.once("close",
|
|
89138
|
+
await new Promise((resolve14) => {
|
|
89139
|
+
this.#process.once("close", resolve14);
|
|
89140
89140
|
});
|
|
89141
89141
|
}
|
|
89142
89142
|
/**
|
|
@@ -89426,7 +89426,7 @@ import {
|
|
|
89426
89426
|
rmSync as rmSync4,
|
|
89427
89427
|
createReadStream as createReadStream2
|
|
89428
89428
|
} from "node:fs";
|
|
89429
|
-
import { resolve as
|
|
89429
|
+
import { resolve as resolve13, dirname as dirname11, join as join17 } from "node:path";
|
|
89430
89430
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
89431
89431
|
import { parseArgs } from "node:util";
|
|
89432
89432
|
import crypto2 from "node:crypto";
|
|
@@ -92061,7 +92061,7 @@ var responseViaResponseObject = async (res, outgoing, options = {}) => {
|
|
|
92061
92061
|
});
|
|
92062
92062
|
if (!chunk) {
|
|
92063
92063
|
if (i === 1) {
|
|
92064
|
-
await new Promise((
|
|
92064
|
+
await new Promise((resolve14) => setTimeout(resolve14));
|
|
92065
92065
|
maxReadCount = 3;
|
|
92066
92066
|
continue;
|
|
92067
92067
|
}
|
|
@@ -95822,8 +95822,8 @@ var CustomElementRegistry = class {
|
|
|
95822
95822
|
} : (element) => element.localName === localName;
|
|
95823
95823
|
registry.set(localName, { Class, check });
|
|
95824
95824
|
if (waiting.has(localName)) {
|
|
95825
|
-
for (const
|
|
95826
|
-
|
|
95825
|
+
for (const resolve14 of waiting.get(localName))
|
|
95826
|
+
resolve14(Class);
|
|
95827
95827
|
waiting.delete(localName);
|
|
95828
95828
|
}
|
|
95829
95829
|
ownerDocument.querySelectorAll(
|
|
@@ -95863,13 +95863,13 @@ var CustomElementRegistry = class {
|
|
|
95863
95863
|
*/
|
|
95864
95864
|
whenDefined(localName) {
|
|
95865
95865
|
const { registry, waiting } = this;
|
|
95866
|
-
return new Promise((
|
|
95866
|
+
return new Promise((resolve14) => {
|
|
95867
95867
|
if (registry.has(localName))
|
|
95868
|
-
|
|
95868
|
+
resolve14(registry.get(localName).Class);
|
|
95869
95869
|
else {
|
|
95870
95870
|
if (!waiting.has(localName))
|
|
95871
95871
|
waiting.set(localName, []);
|
|
95872
|
-
waiting.get(localName).push(
|
|
95872
|
+
waiting.get(localName).push(resolve14);
|
|
95873
95873
|
}
|
|
95874
95874
|
});
|
|
95875
95875
|
}
|
|
@@ -101519,7 +101519,7 @@ function resolveConfig(overrides) {
|
|
|
101519
101519
|
hdr: (() => {
|
|
101520
101520
|
const raw2 = env2("PRODUCER_HDR_TRANSFER");
|
|
101521
101521
|
if (raw2 === "hlg" || raw2 === "pq") return { transfer: raw2 };
|
|
101522
|
-
return
|
|
101522
|
+
return false;
|
|
101523
101523
|
})(),
|
|
101524
101524
|
hdrAutoDetect: envBool("PRODUCER_HDR_AUTO_DETECT", DEFAULT_CONFIG.hdrAutoDetect),
|
|
101525
101525
|
audioGain: envNum("PRODUCER_AUDIO_GAIN", DEFAULT_CONFIG.audioGain),
|
|
@@ -103921,7 +103921,8 @@ async function injectVideoFramesBatch(page, updates) {
|
|
|
103921
103921
|
let img = video.nextElementSibling;
|
|
103922
103922
|
const isNewImage = !img || !img.classList.contains("__render_frame__");
|
|
103923
103923
|
const computedStyle = window.getComputedStyle(video);
|
|
103924
|
-
const
|
|
103924
|
+
const opacityParsed = parseFloat(computedStyle.opacity);
|
|
103925
|
+
const computedOpacity = Number.isNaN(opacityParsed) ? 1 : opacityParsed;
|
|
103925
103926
|
const sourceIsStatic = !computedStyle.position || computedStyle.position === "static";
|
|
103926
103927
|
if (isNewImage) {
|
|
103927
103928
|
img = document.createElement("img");
|
|
@@ -103967,7 +103968,6 @@ async function injectVideoFramesBatch(page, updates) {
|
|
|
103967
103968
|
img.style.opacity = String(computedOpacity);
|
|
103968
103969
|
img.style.visibility = "visible";
|
|
103969
103970
|
video.style.setProperty("visibility", "hidden", "important");
|
|
103970
|
-
video.style.setProperty("opacity", "0", "important");
|
|
103971
103971
|
video.style.setProperty("pointer-events", "none", "important");
|
|
103972
103972
|
}
|
|
103973
103973
|
if (pendingDecodes.length > 0) {
|
|
@@ -103994,7 +103994,6 @@ async function syncVideoFrameVisibility(page, activeVideoIds) {
|
|
|
103994
103994
|
} else {
|
|
103995
103995
|
video.style.removeProperty("display");
|
|
103996
103996
|
video.style.setProperty("visibility", "hidden", "important");
|
|
103997
|
-
video.style.setProperty("opacity", "0", "important");
|
|
103998
103997
|
video.style.setProperty("pointer-events", "none", "important");
|
|
103999
103998
|
if (hasImg) {
|
|
104000
103999
|
img.style.visibility = "hidden";
|
|
@@ -104085,7 +104084,7 @@ async function pollPageExpression(page, expression, timeoutMs, intervalMs = 100)
|
|
|
104085
104084
|
while (Date.now() < deadline) {
|
|
104086
104085
|
const ready = Boolean(await page.evaluate(expression));
|
|
104087
104086
|
if (ready) return true;
|
|
104088
|
-
await new Promise((
|
|
104087
|
+
await new Promise((resolve14) => setTimeout(resolve14, intervalMs));
|
|
104089
104088
|
}
|
|
104090
104089
|
return Boolean(await page.evaluate(expression));
|
|
104091
104090
|
}
|
|
@@ -104316,9 +104315,15 @@ async function captureFrameToBuffer(session, frameIndex, time) {
|
|
|
104316
104315
|
return { buffer, captureTimeMs };
|
|
104317
104316
|
}
|
|
104318
104317
|
async function closeCaptureSession(session) {
|
|
104319
|
-
if (session.
|
|
104320
|
-
|
|
104321
|
-
|
|
104318
|
+
if (!session.pageReleased && session.page) {
|
|
104319
|
+
await session.page.close().catch(() => {
|
|
104320
|
+
});
|
|
104321
|
+
session.pageReleased = true;
|
|
104322
|
+
}
|
|
104323
|
+
if (!session.browserReleased && session.browser) {
|
|
104324
|
+
await releaseBrowser(session.browser, session.config);
|
|
104325
|
+
session.browserReleased = true;
|
|
104326
|
+
}
|
|
104322
104327
|
session.isInitialized = false;
|
|
104323
104328
|
}
|
|
104324
104329
|
function prepareCaptureSessionForReuse(session, outputDir, onBeforeCapture) {
|
|
@@ -104362,7 +104367,7 @@ import { join as join6, dirname as dirname5 } from "path";
|
|
|
104362
104367
|
// ../engine/src/utils/gpuEncoder.ts
|
|
104363
104368
|
import { spawn as spawn3 } from "child_process";
|
|
104364
104369
|
async function detectGpuEncoder() {
|
|
104365
|
-
return new Promise((
|
|
104370
|
+
return new Promise((resolve14) => {
|
|
104366
104371
|
const ffmpeg = spawn3("ffmpeg", ["-encoders"], {
|
|
104367
104372
|
stdio: ["pipe", "pipe", "pipe"]
|
|
104368
104373
|
});
|
|
@@ -104371,13 +104376,13 @@ async function detectGpuEncoder() {
|
|
|
104371
104376
|
stdout += data.toString();
|
|
104372
104377
|
});
|
|
104373
104378
|
ffmpeg.on("close", () => {
|
|
104374
|
-
if (stdout.includes("h264_nvenc"))
|
|
104375
|
-
else if (stdout.includes("h264_videotoolbox"))
|
|
104376
|
-
else if (stdout.includes("h264_vaapi"))
|
|
104377
|
-
else if (stdout.includes("h264_qsv"))
|
|
104378
|
-
else
|
|
104379
|
+
if (stdout.includes("h264_nvenc")) resolve14("nvenc");
|
|
104380
|
+
else if (stdout.includes("h264_videotoolbox")) resolve14("videotoolbox");
|
|
104381
|
+
else if (stdout.includes("h264_vaapi")) resolve14("vaapi");
|
|
104382
|
+
else if (stdout.includes("h264_qsv")) resolve14("qsv");
|
|
104383
|
+
else resolve14(null);
|
|
104379
104384
|
});
|
|
104380
|
-
ffmpeg.on("error", () =>
|
|
104385
|
+
ffmpeg.on("error", () => resolve14(null));
|
|
104381
104386
|
});
|
|
104382
104387
|
}
|
|
104383
104388
|
var cachedGpuEncoder = void 0;
|
|
@@ -104402,16 +104407,93 @@ function getGpuEncoderName(encoder, codec) {
|
|
|
104402
104407
|
return codec === "h264" ? "libx264" : "libx265";
|
|
104403
104408
|
}
|
|
104404
104409
|
}
|
|
104410
|
+
var NVENC_PRESET_MAP = {
|
|
104411
|
+
ultrafast: "p1",
|
|
104412
|
+
superfast: "p1",
|
|
104413
|
+
veryfast: "p2",
|
|
104414
|
+
faster: "p3",
|
|
104415
|
+
fast: "p4",
|
|
104416
|
+
medium: "p4",
|
|
104417
|
+
slow: "p5",
|
|
104418
|
+
slower: "p6",
|
|
104419
|
+
veryslow: "p7",
|
|
104420
|
+
placebo: "p7"
|
|
104421
|
+
};
|
|
104422
|
+
var QSV_PRESET_MAP = {
|
|
104423
|
+
ultrafast: "veryfast",
|
|
104424
|
+
superfast: "veryfast",
|
|
104425
|
+
placebo: "veryslow"
|
|
104426
|
+
};
|
|
104427
|
+
function mapPresetForGpuEncoder(encoder, preset) {
|
|
104428
|
+
switch (encoder) {
|
|
104429
|
+
case "nvenc":
|
|
104430
|
+
if (/^p[1-7]$/.test(preset)) return preset;
|
|
104431
|
+
return NVENC_PRESET_MAP[preset] ?? "p4";
|
|
104432
|
+
case "qsv":
|
|
104433
|
+
return QSV_PRESET_MAP[preset] ?? preset;
|
|
104434
|
+
default:
|
|
104435
|
+
return preset;
|
|
104436
|
+
}
|
|
104437
|
+
}
|
|
104438
|
+
|
|
104439
|
+
// ../engine/src/utils/hdr.ts
|
|
104440
|
+
function isHdrColorSpace(cs) {
|
|
104441
|
+
if (!cs) return false;
|
|
104442
|
+
return cs.colorPrimaries.includes("bt2020") || cs.colorSpace.includes("bt2020") || cs.colorTransfer === "smpte2084" || cs.colorTransfer === "arib-std-b67";
|
|
104443
|
+
}
|
|
104444
|
+
function detectTransfer(cs) {
|
|
104445
|
+
if (cs?.colorTransfer === "smpte2084") return "pq";
|
|
104446
|
+
return "hlg";
|
|
104447
|
+
}
|
|
104448
|
+
var DEFAULT_HDR10_MASTERING = {
|
|
104449
|
+
masterDisplay: "G(13250,34500)B(7500,3000)R(34000,16000)WP(15635,16450)L(10000000,1)",
|
|
104450
|
+
maxCll: "1000,400"
|
|
104451
|
+
};
|
|
104452
|
+
function getHdrEncoderColorParams(transfer, mastering = DEFAULT_HDR10_MASTERING) {
|
|
104453
|
+
const colorTrc = transfer === "pq" ? "smpte2084" : "arib-std-b67";
|
|
104454
|
+
const tagging = `colorprim=bt2020:transfer=${colorTrc}:colormatrix=bt2020nc`;
|
|
104455
|
+
const metadata = `master-display=${mastering.masterDisplay}:max-cll=${mastering.maxCll}`;
|
|
104456
|
+
return {
|
|
104457
|
+
colorPrimaries: "bt2020",
|
|
104458
|
+
colorTrc,
|
|
104459
|
+
colorspace: "bt2020nc",
|
|
104460
|
+
pixelFormat: "yuv420p10le",
|
|
104461
|
+
x265ColorParams: `${tagging}:${metadata}`,
|
|
104462
|
+
mastering
|
|
104463
|
+
};
|
|
104464
|
+
}
|
|
104465
|
+
function analyzeCompositionHdr(colorSpaces) {
|
|
104466
|
+
let hasPq = false;
|
|
104467
|
+
let hasHdr = false;
|
|
104468
|
+
for (const cs of colorSpaces) {
|
|
104469
|
+
if (!isHdrColorSpace(cs)) continue;
|
|
104470
|
+
hasHdr = true;
|
|
104471
|
+
if (cs?.colorTransfer === "smpte2084") hasPq = true;
|
|
104472
|
+
}
|
|
104473
|
+
if (!hasHdr) return { hasHdr: false, dominantTransfer: null };
|
|
104474
|
+
const dominantTransfer = hasPq ? "pq" : "hlg";
|
|
104475
|
+
return { hasHdr: true, dominantTransfer };
|
|
104476
|
+
}
|
|
104405
104477
|
|
|
104406
104478
|
// ../engine/src/utils/runFfmpeg.ts
|
|
104407
104479
|
import { spawn as spawn4 } from "child_process";
|
|
104408
104480
|
var DEFAULT_TIMEOUT2 = 3e5;
|
|
104481
|
+
var DEFAULT_STDERR_TAIL_LINES = 15;
|
|
104482
|
+
function formatFfmpegError(exitCode, stderr, tailLines = DEFAULT_STDERR_TAIL_LINES) {
|
|
104483
|
+
const tail = (stderr ?? "").split(/\r?\n/).filter((line) => line.length > 0).slice(-tailLines).join("\n");
|
|
104484
|
+
if (exitCode === null) {
|
|
104485
|
+
return tail ? `[FFmpeg] ${tail}` : "[FFmpeg] process error";
|
|
104486
|
+
}
|
|
104487
|
+
return tail ? `FFmpeg exited with code ${exitCode}
|
|
104488
|
+
ffmpeg stderr (tail):
|
|
104489
|
+
${tail}` : `FFmpeg exited with code ${exitCode}`;
|
|
104490
|
+
}
|
|
104409
104491
|
async function runFfmpeg(args, opts) {
|
|
104410
104492
|
const startMs = Date.now();
|
|
104411
104493
|
const signal = opts?.signal;
|
|
104412
104494
|
const timeout2 = opts?.timeout ?? DEFAULT_TIMEOUT2;
|
|
104413
104495
|
const onStderr = opts?.onStderr;
|
|
104414
|
-
return new Promise((
|
|
104496
|
+
return new Promise((resolve14) => {
|
|
104415
104497
|
const ffmpeg = spawn4("ffmpeg", args);
|
|
104416
104498
|
let stderr = "";
|
|
104417
104499
|
const onAbort = () => {
|
|
@@ -104437,7 +104519,7 @@ async function runFfmpeg(args, opts) {
|
|
|
104437
104519
|
ffmpeg.on("close", (code) => {
|
|
104438
104520
|
clearTimeout(timer2);
|
|
104439
104521
|
if (signal) signal.removeEventListener("abort", onAbort);
|
|
104440
|
-
|
|
104522
|
+
resolve14({
|
|
104441
104523
|
success: !signal?.aborted && code === 0,
|
|
104442
104524
|
exitCode: code,
|
|
104443
104525
|
stderr,
|
|
@@ -104447,7 +104529,7 @@ async function runFfmpeg(args, opts) {
|
|
|
104447
104529
|
ffmpeg.on("error", (err) => {
|
|
104448
104530
|
clearTimeout(timer2);
|
|
104449
104531
|
if (signal) signal.removeEventListener("abort", onAbort);
|
|
104450
|
-
|
|
104532
|
+
resolve14({
|
|
104451
104533
|
success: false,
|
|
104452
104534
|
exitCode: null,
|
|
104453
104535
|
stderr: err.message,
|
|
@@ -104502,6 +104584,12 @@ function buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder = null) {
|
|
|
104502
104584
|
pixelFormat = "yuv420p",
|
|
104503
104585
|
useGpu = false
|
|
104504
104586
|
} = options;
|
|
104587
|
+
if (options.hdr && codec === "h264") {
|
|
104588
|
+
console.warn(
|
|
104589
|
+
"[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."
|
|
104590
|
+
);
|
|
104591
|
+
options = { ...options, hdr: void 0 };
|
|
104592
|
+
}
|
|
104505
104593
|
const args = [...inputArgs, "-r", String(fps)];
|
|
104506
104594
|
const shouldUseGpu = useGpu && gpuEncoder !== null;
|
|
104507
104595
|
if (codec === "h264" || codec === "h265") {
|
|
@@ -104510,7 +104598,7 @@ function buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder = null) {
|
|
|
104510
104598
|
args.push("-c:v", encoderName);
|
|
104511
104599
|
switch (gpuEncoder) {
|
|
104512
104600
|
case "nvenc":
|
|
104513
|
-
args.push("-preset", preset);
|
|
104601
|
+
args.push("-preset", mapPresetForGpuEncoder("nvenc", preset));
|
|
104514
104602
|
if (bitrate) args.push("-b:v", bitrate);
|
|
104515
104603
|
else args.push("-cq", String(quality));
|
|
104516
104604
|
break;
|
|
@@ -104529,7 +104617,7 @@ function buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder = null) {
|
|
|
104529
104617
|
else args.push("-qp", String(quality));
|
|
104530
104618
|
break;
|
|
104531
104619
|
case "qsv":
|
|
104532
|
-
args.push("-preset", preset);
|
|
104620
|
+
args.push("-preset", mapPresetForGpuEncoder("qsv", preset));
|
|
104533
104621
|
if (bitrate) args.push("-b:v", bitrate);
|
|
104534
104622
|
else args.push("-global_quality", String(quality));
|
|
104535
104623
|
break;
|
|
@@ -104540,7 +104628,7 @@ function buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder = null) {
|
|
|
104540
104628
|
if (bitrate) args.push("-b:v", bitrate);
|
|
104541
104629
|
else args.push("-crf", String(quality));
|
|
104542
104630
|
const xParamsFlag = codec === "h264" ? "-x264-params" : "-x265-params";
|
|
104543
|
-
const colorParams = "colorprim=bt709:transfer=bt709:colormatrix=bt709";
|
|
104631
|
+
const colorParams = codec === "h265" && options.hdr ? getHdrEncoderColorParams(options.hdr.transfer).x265ColorParams : "colorprim=bt709:transfer=bt709:colormatrix=bt709";
|
|
104544
104632
|
if (preset === "ultrafast") {
|
|
104545
104633
|
args.push(xParamsFlag, `aq-mode=3:${colorParams}`);
|
|
104546
104634
|
} else {
|
|
@@ -104564,16 +104652,30 @@ function buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder = null) {
|
|
|
104564
104652
|
return [...args, "-y", outputPath];
|
|
104565
104653
|
}
|
|
104566
104654
|
if (codec === "h264" || codec === "h265") {
|
|
104567
|
-
|
|
104568
|
-
"
|
|
104569
|
-
|
|
104570
|
-
|
|
104571
|
-
|
|
104572
|
-
|
|
104573
|
-
|
|
104574
|
-
|
|
104575
|
-
|
|
104576
|
-
|
|
104655
|
+
if (options.hdr) {
|
|
104656
|
+
const transferTag = options.hdr.transfer === "pq" ? "smpte2084" : "arib-std-b67";
|
|
104657
|
+
args.push(
|
|
104658
|
+
"-colorspace:v",
|
|
104659
|
+
"bt2020nc",
|
|
104660
|
+
"-color_primaries:v",
|
|
104661
|
+
"bt2020",
|
|
104662
|
+
"-color_trc:v",
|
|
104663
|
+
transferTag,
|
|
104664
|
+
"-color_range",
|
|
104665
|
+
"tv"
|
|
104666
|
+
);
|
|
104667
|
+
} else {
|
|
104668
|
+
args.push(
|
|
104669
|
+
"-colorspace:v",
|
|
104670
|
+
"bt709",
|
|
104671
|
+
"-color_primaries:v",
|
|
104672
|
+
"bt709",
|
|
104673
|
+
"-color_trc:v",
|
|
104674
|
+
"bt709",
|
|
104675
|
+
"-color_range",
|
|
104676
|
+
"tv"
|
|
104677
|
+
);
|
|
104678
|
+
}
|
|
104577
104679
|
if (gpuEncoder === "vaapi") {
|
|
104578
104680
|
const vfIdx = args.indexOf("-vf");
|
|
104579
104681
|
if (vfIdx !== -1) {
|
|
@@ -104613,7 +104715,7 @@ async function encodeFramesFromDir(framesDir, framePattern, outputPath, options,
|
|
|
104613
104715
|
const inputPath = join6(framesDir, framePattern);
|
|
104614
104716
|
const inputArgs = ["-framerate", String(options.fps), "-i", inputPath];
|
|
104615
104717
|
const args = buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder);
|
|
104616
|
-
return new Promise((
|
|
104718
|
+
return new Promise((resolve14) => {
|
|
104617
104719
|
const ffmpeg = spawn5("ffmpeg", args);
|
|
104618
104720
|
let stderr = "";
|
|
104619
104721
|
const onAbort = () => {
|
|
@@ -104638,7 +104740,7 @@ async function encodeFramesFromDir(framesDir, framePattern, outputPath, options,
|
|
|
104638
104740
|
if (signal) signal.removeEventListener("abort", onAbort);
|
|
104639
104741
|
const durationMs = Date.now() - startTime;
|
|
104640
104742
|
if (signal?.aborted) {
|
|
104641
|
-
|
|
104743
|
+
resolve14({
|
|
104642
104744
|
success: false,
|
|
104643
104745
|
outputPath,
|
|
104644
104746
|
durationMs,
|
|
@@ -104649,23 +104751,23 @@ async function encodeFramesFromDir(framesDir, framePattern, outputPath, options,
|
|
|
104649
104751
|
return;
|
|
104650
104752
|
}
|
|
104651
104753
|
if (code !== 0) {
|
|
104652
|
-
|
|
104754
|
+
resolve14({
|
|
104653
104755
|
success: false,
|
|
104654
104756
|
outputPath,
|
|
104655
104757
|
durationMs,
|
|
104656
104758
|
framesEncoded: 0,
|
|
104657
104759
|
fileSize: 0,
|
|
104658
|
-
error:
|
|
104760
|
+
error: formatFfmpegError(code, stderr)
|
|
104659
104761
|
});
|
|
104660
104762
|
return;
|
|
104661
104763
|
}
|
|
104662
104764
|
const fileSize = existsSync5(outputPath) ? statSync3(outputPath).size : 0;
|
|
104663
|
-
|
|
104765
|
+
resolve14({ success: true, outputPath, durationMs, framesEncoded: frameCount, fileSize });
|
|
104664
104766
|
});
|
|
104665
104767
|
ffmpeg.on("error", (err) => {
|
|
104666
104768
|
clearTimeout(timer2);
|
|
104667
104769
|
if (signal) signal.removeEventListener("abort", onAbort);
|
|
104668
|
-
|
|
104770
|
+
resolve14({
|
|
104669
104771
|
success: false,
|
|
104670
104772
|
outputPath,
|
|
104671
104773
|
durationMs: Date.now() - startTime,
|
|
@@ -104723,18 +104825,18 @@ async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, op
|
|
|
104723
104825
|
let gpuEncoder = null;
|
|
104724
104826
|
if (options.useGpu) gpuEncoder = await getCachedGpuEncoder();
|
|
104725
104827
|
const args = buildEncoderArgs(options, inputArgs, chunkPath, gpuEncoder);
|
|
104726
|
-
const chunkResult = await new Promise((
|
|
104828
|
+
const chunkResult = await new Promise((resolve14) => {
|
|
104727
104829
|
const ffmpeg = spawn5("ffmpeg", args);
|
|
104728
104830
|
let stderr = "";
|
|
104729
104831
|
ffmpeg.stderr.on("data", (d) => {
|
|
104730
104832
|
stderr += d.toString();
|
|
104731
104833
|
});
|
|
104732
104834
|
ffmpeg.on("close", (code) => {
|
|
104733
|
-
if (code === 0)
|
|
104734
|
-
else
|
|
104835
|
+
if (code === 0) resolve14({ success: true });
|
|
104836
|
+
else resolve14({ success: false, error: `Chunk ${i} encode failed: ${stderr.slice(-400)}` });
|
|
104735
104837
|
});
|
|
104736
104838
|
ffmpeg.on("error", (err) => {
|
|
104737
|
-
|
|
104839
|
+
resolve14({ success: false, error: `Chunk ${i} encode error: ${err.message}` });
|
|
104738
104840
|
});
|
|
104739
104841
|
});
|
|
104740
104842
|
if (!chunkResult.success) {
|
|
@@ -104764,18 +104866,18 @@ async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, op
|
|
|
104764
104866
|
"-y",
|
|
104765
104867
|
outputPath
|
|
104766
104868
|
];
|
|
104767
|
-
const concatResult = await new Promise((
|
|
104869
|
+
const concatResult = await new Promise((resolve14) => {
|
|
104768
104870
|
const ffmpeg = spawn5("ffmpeg", concatArgs);
|
|
104769
104871
|
let stderr = "";
|
|
104770
104872
|
ffmpeg.stderr.on("data", (d) => {
|
|
104771
104873
|
stderr += d.toString();
|
|
104772
104874
|
});
|
|
104773
104875
|
ffmpeg.on("close", (code) => {
|
|
104774
|
-
if (code === 0)
|
|
104775
|
-
else
|
|
104876
|
+
if (code === 0) resolve14({ success: true });
|
|
104877
|
+
else resolve14({ success: false, error: `Chunk concat failed: ${stderr.slice(-400)}` });
|
|
104776
104878
|
});
|
|
104777
104879
|
ffmpeg.on("error", (err) => {
|
|
104778
|
-
|
|
104880
|
+
resolve14({ success: false, error: `Chunk concat error: ${err.message}` });
|
|
104779
104881
|
});
|
|
104780
104882
|
});
|
|
104781
104883
|
if (!concatResult.success) {
|
|
@@ -104825,7 +104927,7 @@ async function muxVideoWithAudio(videoPath, audioPath, outputPath, signal, confi
|
|
|
104825
104927
|
success: result.success,
|
|
104826
104928
|
outputPath,
|
|
104827
104929
|
durationMs: result.durationMs,
|
|
104828
|
-
error: !result.success ? result.exitCode
|
|
104930
|
+
error: !result.success ? formatFfmpegError(result.exitCode, result.stderr) : void 0
|
|
104829
104931
|
};
|
|
104830
104932
|
}
|
|
104831
104933
|
async function applyFaststart(inputPath, outputPath, signal, config2) {
|
|
@@ -104848,7 +104950,7 @@ async function applyFaststart(inputPath, outputPath, signal, config2) {
|
|
|
104848
104950
|
success: result.success,
|
|
104849
104951
|
outputPath,
|
|
104850
104952
|
durationMs: result.durationMs,
|
|
104851
|
-
error: !result.success ? result.exitCode
|
|
104953
|
+
error: !result.success ? formatFfmpegError(result.exitCode, result.stderr) : void 0
|
|
104852
104954
|
};
|
|
104853
104955
|
}
|
|
104854
104956
|
|
|
@@ -104856,81 +104958,40 @@ async function applyFaststart(inputPath, outputPath, signal, config2) {
|
|
|
104856
104958
|
import { spawn as spawn6 } from "child_process";
|
|
104857
104959
|
import { existsSync as existsSync6, mkdirSync as mkdirSync3, statSync as statSync4 } from "fs";
|
|
104858
104960
|
import { dirname as dirname6 } from "path";
|
|
104859
|
-
|
|
104860
|
-
// ../engine/src/utils/hdr.ts
|
|
104861
|
-
function isHdrColorSpace(cs) {
|
|
104862
|
-
if (!cs) return false;
|
|
104863
|
-
return cs.colorPrimaries.includes("bt2020") || cs.colorSpace.includes("bt2020") || cs.colorTransfer === "smpte2084" || cs.colorTransfer === "arib-std-b67";
|
|
104864
|
-
}
|
|
104865
|
-
function detectTransfer(cs) {
|
|
104866
|
-
if (cs?.colorTransfer === "smpte2084") return "pq";
|
|
104867
|
-
return "hlg";
|
|
104868
|
-
}
|
|
104869
|
-
var DEFAULT_HDR10_MASTERING = {
|
|
104870
|
-
masterDisplay: "G(13250,34500)B(7500,3000)R(34000,16000)WP(15635,16450)L(10000000,1)",
|
|
104871
|
-
maxCll: "1000,400"
|
|
104872
|
-
};
|
|
104873
|
-
function getHdrEncoderColorParams(transfer, mastering = DEFAULT_HDR10_MASTERING) {
|
|
104874
|
-
const colorTrc = transfer === "pq" ? "smpte2084" : "arib-std-b67";
|
|
104875
|
-
const tagging = `colorprim=bt2020:transfer=${colorTrc}:colormatrix=bt2020nc`;
|
|
104876
|
-
const metadata = `master-display=${mastering.masterDisplay}:max-cll=${mastering.maxCll}`;
|
|
104877
|
-
return {
|
|
104878
|
-
colorPrimaries: "bt2020",
|
|
104879
|
-
colorTrc,
|
|
104880
|
-
colorspace: "bt2020nc",
|
|
104881
|
-
pixelFormat: "yuv420p10le",
|
|
104882
|
-
x265ColorParams: `${tagging}:${metadata}`,
|
|
104883
|
-
mastering
|
|
104884
|
-
};
|
|
104885
|
-
}
|
|
104886
|
-
function analyzeCompositionHdr(colorSpaces) {
|
|
104887
|
-
let hasPq = false;
|
|
104888
|
-
let hasHdr = false;
|
|
104889
|
-
for (const cs of colorSpaces) {
|
|
104890
|
-
if (!isHdrColorSpace(cs)) continue;
|
|
104891
|
-
hasHdr = true;
|
|
104892
|
-
if (cs?.colorTransfer === "smpte2084") hasPq = true;
|
|
104893
|
-
}
|
|
104894
|
-
if (!hasHdr) return { hasHdr: false, dominantTransfer: null };
|
|
104895
|
-
const dominantTransfer = hasPq ? "pq" : "hlg";
|
|
104896
|
-
return { hasHdr: true, dominantTransfer };
|
|
104897
|
-
}
|
|
104898
|
-
|
|
104899
|
-
// ../engine/src/services/streamingEncoder.ts
|
|
104900
104961
|
function createFrameReorderBuffer(startFrame, endFrame) {
|
|
104901
104962
|
let cursor = startFrame;
|
|
104902
104963
|
const pending = /* @__PURE__ */ new Map();
|
|
104903
|
-
const enqueueAt = (frame,
|
|
104964
|
+
const enqueueAt = (frame, resolve14) => {
|
|
104904
104965
|
const list = pending.get(frame);
|
|
104905
104966
|
if (list === void 0) {
|
|
104906
|
-
pending.set(frame, [
|
|
104967
|
+
pending.set(frame, [resolve14]);
|
|
104907
104968
|
} else {
|
|
104908
|
-
list.push(
|
|
104969
|
+
list.push(resolve14);
|
|
104909
104970
|
}
|
|
104910
104971
|
};
|
|
104911
104972
|
const flushAt = (frame) => {
|
|
104912
104973
|
const list = pending.get(frame);
|
|
104913
104974
|
if (list === void 0) return;
|
|
104914
104975
|
pending.delete(frame);
|
|
104915
|
-
for (const
|
|
104976
|
+
for (const resolve14 of list) resolve14();
|
|
104916
104977
|
};
|
|
104917
|
-
const waitForFrame = (frame) => new Promise((
|
|
104978
|
+
const waitForFrame = (frame) => new Promise((resolve14) => {
|
|
104918
104979
|
if (frame === cursor) {
|
|
104919
|
-
|
|
104980
|
+
resolve14();
|
|
104920
104981
|
return;
|
|
104921
104982
|
}
|
|
104922
|
-
enqueueAt(frame,
|
|
104983
|
+
enqueueAt(frame, resolve14);
|
|
104923
104984
|
});
|
|
104924
104985
|
const advanceTo = (frame) => {
|
|
104925
104986
|
cursor = frame;
|
|
104926
104987
|
flushAt(frame);
|
|
104927
104988
|
};
|
|
104928
|
-
const waitForAllDone = () => new Promise((
|
|
104989
|
+
const waitForAllDone = () => new Promise((resolve14) => {
|
|
104929
104990
|
if (cursor >= endFrame) {
|
|
104930
|
-
|
|
104991
|
+
resolve14();
|
|
104931
104992
|
return;
|
|
104932
104993
|
}
|
|
104933
|
-
enqueueAt(endFrame,
|
|
104994
|
+
enqueueAt(endFrame, resolve14);
|
|
104934
104995
|
});
|
|
104935
104996
|
return { waitForFrame, advanceTo, waitForAllDone };
|
|
104936
104997
|
}
|
|
@@ -104982,7 +105043,7 @@ function buildStreamingArgs(options, outputPath, gpuEncoder = null) {
|
|
|
104982
105043
|
args.push("-c:v", encoderName);
|
|
104983
105044
|
switch (gpuEncoder) {
|
|
104984
105045
|
case "nvenc":
|
|
104985
|
-
args.push("-preset", preset);
|
|
105046
|
+
args.push("-preset", mapPresetForGpuEncoder("nvenc", preset));
|
|
104986
105047
|
if (bitrate) args.push("-b:v", bitrate);
|
|
104987
105048
|
else args.push("-cq", String(quality));
|
|
104988
105049
|
break;
|
|
@@ -105001,7 +105062,7 @@ function buildStreamingArgs(options, outputPath, gpuEncoder = null) {
|
|
|
105001
105062
|
else args.push("-qp", String(quality));
|
|
105002
105063
|
break;
|
|
105003
105064
|
case "qsv":
|
|
105004
|
-
args.push("-preset", preset);
|
|
105065
|
+
args.push("-preset", mapPresetForGpuEncoder("qsv", preset));
|
|
105005
105066
|
if (bitrate) args.push("-b:v", bitrate);
|
|
105006
105067
|
else args.push("-global_quality", String(quality));
|
|
105007
105068
|
break;
|
|
@@ -105092,7 +105153,7 @@ async function spawnStreamingEncoder(outputPath, options, signal, config2) {
|
|
|
105092
105153
|
let stderr = "";
|
|
105093
105154
|
let exitCode = null;
|
|
105094
105155
|
let exitPromiseResolve = null;
|
|
105095
|
-
const exitPromise = new Promise((
|
|
105156
|
+
const exitPromise = new Promise((resolve14) => exitPromiseResolve = resolve14);
|
|
105096
105157
|
ffmpeg.stderr?.on("data", (data) => {
|
|
105097
105158
|
stderr += data.toString();
|
|
105098
105159
|
});
|
|
@@ -105138,8 +105199,8 @@ Process error: ${err.message}`;
|
|
|
105138
105199
|
if (signal) signal.removeEventListener("abort", onAbort);
|
|
105139
105200
|
const stdin = ffmpeg.stdin;
|
|
105140
105201
|
if (stdin && !stdin.destroyed) {
|
|
105141
|
-
await new Promise((
|
|
105142
|
-
stdin.end(() =>
|
|
105202
|
+
await new Promise((resolve14) => {
|
|
105203
|
+
stdin.end(() => resolve14());
|
|
105143
105204
|
});
|
|
105144
105205
|
}
|
|
105145
105206
|
await exitPromise;
|
|
@@ -105157,7 +105218,7 @@ Process error: ${err.message}`;
|
|
|
105157
105218
|
success: false,
|
|
105158
105219
|
durationMs,
|
|
105159
105220
|
fileSize: 0,
|
|
105160
|
-
error:
|
|
105221
|
+
error: formatFfmpegError(exitCode, stderr)
|
|
105161
105222
|
};
|
|
105162
105223
|
}
|
|
105163
105224
|
const fileSize = existsSync6(outputPath) ? statSync4(outputPath).size : 0;
|
|
@@ -105171,14 +105232,14 @@ Process error: ${err.message}`;
|
|
|
105171
105232
|
// ../engine/src/services/videoFrameExtractor.ts
|
|
105172
105233
|
import { spawn as spawn8 } from "child_process";
|
|
105173
105234
|
import { existsSync as existsSync8, mkdirSync as mkdirSync5, readdirSync as readdirSync4, rmSync } from "fs";
|
|
105174
|
-
import { join as join8 } from "path";
|
|
105235
|
+
import { isAbsolute as isAbsolute2, join as join8 } from "path";
|
|
105175
105236
|
|
|
105176
105237
|
// ../engine/src/utils/ffprobe.ts
|
|
105177
105238
|
import { spawn as spawn7 } from "child_process";
|
|
105178
105239
|
import { readFileSync as readFileSync5 } from "fs";
|
|
105179
105240
|
import { extname as extname2 } from "path";
|
|
105180
105241
|
function runFfprobe(args) {
|
|
105181
|
-
return new Promise((
|
|
105242
|
+
return new Promise((resolve14, reject) => {
|
|
105182
105243
|
const proc = spawn7("ffprobe", args);
|
|
105183
105244
|
let stdout = "";
|
|
105184
105245
|
let stderr = "";
|
|
@@ -105192,7 +105253,7 @@ function runFfprobe(args) {
|
|
|
105192
105253
|
if (code !== 0) {
|
|
105193
105254
|
reject(new Error(`[FFmpeg] ffprobe exited with code ${code}: ${stderr}`));
|
|
105194
105255
|
} else {
|
|
105195
|
-
|
|
105256
|
+
resolve14(stdout);
|
|
105196
105257
|
}
|
|
105197
105258
|
});
|
|
105198
105259
|
proc.on("error", (err) => {
|
|
@@ -105286,7 +105347,7 @@ function parseFrameRate(frameRateStr) {
|
|
|
105286
105347
|
}
|
|
105287
105348
|
return parseFloat(frameRateStr) || 0;
|
|
105288
105349
|
}
|
|
105289
|
-
async function
|
|
105350
|
+
async function extractMediaMetadata(filePath) {
|
|
105290
105351
|
const cached = videoMetadataCache.get(filePath);
|
|
105291
105352
|
if (cached) return cached;
|
|
105292
105353
|
const probePromise = (async () => {
|
|
@@ -105572,7 +105633,7 @@ async function extractVideoFramesRange(videoPath, videoId, startTime, duration,
|
|
|
105572
105633
|
const { fps, outputDir, quality = 95, format: format3 = "jpg" } = options;
|
|
105573
105634
|
const videoOutputDir = join8(outputDir, videoId);
|
|
105574
105635
|
if (!existsSync8(videoOutputDir)) mkdirSync5(videoOutputDir, { recursive: true });
|
|
105575
|
-
const metadata = await
|
|
105636
|
+
const metadata = await extractMediaMetadata(videoPath);
|
|
105576
105637
|
const framePattern = `frame_%05d.${format3}`;
|
|
105577
105638
|
const outputPattern = join8(videoOutputDir, framePattern);
|
|
105578
105639
|
const isHdr = isHdrColorSpace(metadata.colorSpace);
|
|
@@ -105591,7 +105652,7 @@ async function extractVideoFramesRange(videoPath, videoId, startTime, duration,
|
|
|
105591
105652
|
args.push("-q:v", format3 === "jpg" ? String(Math.ceil((100 - quality) / 3)) : "0");
|
|
105592
105653
|
if (format3 === "png") args.push("-compression_level", "6");
|
|
105593
105654
|
args.push("-y", outputPattern);
|
|
105594
|
-
return new Promise((
|
|
105655
|
+
return new Promise((resolve14, reject) => {
|
|
105595
105656
|
const ffmpeg = spawn8("ffmpeg", args);
|
|
105596
105657
|
let stderr = "";
|
|
105597
105658
|
const onAbort = () => {
|
|
@@ -105626,7 +105687,7 @@ async function extractVideoFramesRange(videoPath, videoId, startTime, duration,
|
|
|
105626
105687
|
files.forEach((file, index) => {
|
|
105627
105688
|
framePaths.set(index, join8(videoOutputDir, file));
|
|
105628
105689
|
});
|
|
105629
|
-
|
|
105690
|
+
resolve14({
|
|
105630
105691
|
videoId,
|
|
105631
105692
|
srcPath: videoPath,
|
|
105632
105693
|
outputDir: videoOutputDir,
|
|
@@ -105648,8 +105709,9 @@ async function extractVideoFramesRange(videoPath, videoId, startTime, duration,
|
|
|
105648
105709
|
});
|
|
105649
105710
|
});
|
|
105650
105711
|
}
|
|
105651
|
-
async function convertSdrToHdr(inputPath, outputPath, signal, config2) {
|
|
105712
|
+
async function convertSdrToHdr(inputPath, outputPath, targetTransfer, signal, config2) {
|
|
105652
105713
|
const timeout2 = config2?.ffmpegProcessTimeout ?? DEFAULT_CONFIG.ffmpegProcessTimeout;
|
|
105714
|
+
const colorTrc = targetTransfer === "pq" ? "smpte2084" : "arib-std-b67";
|
|
105653
105715
|
const args = [
|
|
105654
105716
|
"-i",
|
|
105655
105717
|
inputPath,
|
|
@@ -105658,7 +105720,7 @@ async function convertSdrToHdr(inputPath, outputPath, signal, config2) {
|
|
|
105658
105720
|
"-color_primaries",
|
|
105659
105721
|
"bt2020",
|
|
105660
105722
|
"-color_trc",
|
|
105661
|
-
|
|
105723
|
+
colorTrc,
|
|
105662
105724
|
"-colorspace",
|
|
105663
105725
|
"bt2020nc",
|
|
105664
105726
|
"-c:v",
|
|
@@ -105720,7 +105782,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config2,
|
|
|
105720
105782
|
if (signal?.aborted) break;
|
|
105721
105783
|
try {
|
|
105722
105784
|
let videoPath = video.src;
|
|
105723
|
-
if (!videoPath
|
|
105785
|
+
if (!isAbsolute2(videoPath) && !isHttpUrl(videoPath)) {
|
|
105724
105786
|
const fromCompiled = compiledDir ? join8(compiledDir, videoPath) : null;
|
|
105725
105787
|
videoPath = fromCompiled && existsSync8(fromCompiled) ? fromCompiled : join8(baseDir, videoPath);
|
|
105726
105788
|
}
|
|
@@ -105740,12 +105802,13 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config2,
|
|
|
105740
105802
|
}
|
|
105741
105803
|
const videoColorSpaces = await Promise.all(
|
|
105742
105804
|
resolvedVideos.map(async ({ videoPath }) => {
|
|
105743
|
-
const metadata = await
|
|
105805
|
+
const metadata = await extractMediaMetadata(videoPath);
|
|
105744
105806
|
return metadata.colorSpace;
|
|
105745
105807
|
})
|
|
105746
105808
|
);
|
|
105747
|
-
const
|
|
105748
|
-
if (
|
|
105809
|
+
const hdrInfo = analyzeCompositionHdr(videoColorSpaces);
|
|
105810
|
+
if (hdrInfo.hasHdr && hdrInfo.dominantTransfer) {
|
|
105811
|
+
const targetTransfer = hdrInfo.dominantTransfer;
|
|
105749
105812
|
const convertDir = join8(options.outputDir, "_hdr_normalized");
|
|
105750
105813
|
mkdirSync5(convertDir, { recursive: true });
|
|
105751
105814
|
for (let i = 0; i < resolvedVideos.length; i++) {
|
|
@@ -105756,7 +105819,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config2,
|
|
|
105756
105819
|
if (!entry) continue;
|
|
105757
105820
|
const convertedPath = join8(convertDir, `${entry.video.id}_hdr.mp4`);
|
|
105758
105821
|
try {
|
|
105759
|
-
await convertSdrToHdr(entry.videoPath, convertedPath, signal, config2);
|
|
105822
|
+
await convertSdrToHdr(entry.videoPath, convertedPath, targetTransfer, signal, config2);
|
|
105760
105823
|
entry.videoPath = convertedPath;
|
|
105761
105824
|
} catch (err) {
|
|
105762
105825
|
errors.push({
|
|
@@ -105772,7 +105835,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config2,
|
|
|
105772
105835
|
if (signal?.aborted) break;
|
|
105773
105836
|
const entry = resolvedVideos[i];
|
|
105774
105837
|
if (!entry) continue;
|
|
105775
|
-
const metadata = await
|
|
105838
|
+
const metadata = await extractMediaMetadata(entry.videoPath);
|
|
105776
105839
|
if (!metadata.isVFR) continue;
|
|
105777
105840
|
let segDuration = entry.video.end - entry.video.start;
|
|
105778
105841
|
if (!Number.isFinite(segDuration) || segDuration <= 0) {
|
|
@@ -105808,7 +105871,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config2,
|
|
|
105808
105871
|
try {
|
|
105809
105872
|
let videoDuration = video.end - video.start;
|
|
105810
105873
|
if (!Number.isFinite(videoDuration) || videoDuration <= 0) {
|
|
105811
|
-
const metadata = await
|
|
105874
|
+
const metadata = await extractMediaMetadata(videoPath);
|
|
105812
105875
|
const sourceDuration = metadata.durationSeconds - video.mediaStart;
|
|
105813
105876
|
videoDuration = sourceDuration > 0 ? sourceDuration : metadata.durationSeconds;
|
|
105814
105877
|
video.end = video.start + videoDuration;
|
|
@@ -106061,12 +106124,12 @@ async function queryElementStacking(page, nativeHdrIds) {
|
|
|
106061
106124
|
function resolveRadius(value, el) {
|
|
106062
106125
|
if (value.includes("%")) {
|
|
106063
106126
|
const pct = parseFloat(value) / 100;
|
|
106064
|
-
const
|
|
106065
|
-
const
|
|
106066
|
-
const h = htmlEl.offsetHeight || 0;
|
|
106127
|
+
const w = el instanceof HTMLElement ? el.offsetWidth : 0;
|
|
106128
|
+
const h = el instanceof HTMLElement ? el.offsetHeight : 0;
|
|
106067
106129
|
return pct * Math.min(w, h);
|
|
106068
106130
|
}
|
|
106069
|
-
|
|
106131
|
+
const parsed = parseFloat(value);
|
|
106132
|
+
return Number.isNaN(parsed) ? 0 : parsed;
|
|
106070
106133
|
}
|
|
106071
106134
|
const selfCs = window.getComputedStyle(node);
|
|
106072
106135
|
const selfRadii = [
|
|
@@ -106150,8 +106213,7 @@ async function queryElementStacking(page, nativeHdrIds) {
|
|
|
106150
106213
|
const style = window.getComputedStyle(el);
|
|
106151
106214
|
const zIndex = getEffectiveZIndex(el);
|
|
106152
106215
|
const isHdrEl = hdrSet.has(id);
|
|
106153
|
-
const
|
|
106154
|
-
const opacity = opacityStartNode ? getEffectiveOpacity(opacityStartNode) : 1;
|
|
106216
|
+
const opacity = getEffectiveOpacity(el);
|
|
106155
106217
|
const visible = style.visibility !== "hidden" && style.display !== "none" && rect.width > 0 && rect.height > 0;
|
|
106156
106218
|
const htmlEl = el instanceof HTMLElement ? el : null;
|
|
106157
106219
|
results.push({
|
|
@@ -106184,7 +106246,7 @@ async function queryElementStacking(page, nativeHdrIds) {
|
|
|
106184
106246
|
|
|
106185
106247
|
// ../engine/src/services/audioMixer.ts
|
|
106186
106248
|
import { existsSync as existsSync9, mkdirSync as mkdirSync6, rmSync as rmSync2 } from "fs";
|
|
106187
|
-
import { join as join9, dirname as dirname7 } from "path";
|
|
106249
|
+
import { isAbsolute as isAbsolute3, join as join9, dirname as dirname7 } from "path";
|
|
106188
106250
|
function parseAudioElements(html) {
|
|
106189
106251
|
const elements = [];
|
|
106190
106252
|
const { document: document2 } = parseHTML(html);
|
|
@@ -106411,7 +106473,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
106411
106473
|
}
|
|
106412
106474
|
try {
|
|
106413
106475
|
let srcPath = element.src;
|
|
106414
|
-
if (!srcPath
|
|
106476
|
+
if (!isAbsolute3(srcPath) && !isHttpUrl(srcPath)) {
|
|
106415
106477
|
const fromCompiled = compiledDir ? join9(compiledDir, srcPath) : null;
|
|
106416
106478
|
srcPath = fromCompiled && existsSync9(fromCompiled) ? fromCompiled : join9(baseDir, srcPath);
|
|
106417
106479
|
}
|
|
@@ -107137,13 +107199,51 @@ function normalizeObjectFit(value) {
|
|
|
107137
107199
|
}
|
|
107138
107200
|
function parseTransformMatrix(css) {
|
|
107139
107201
|
if (!css || css === "none") return null;
|
|
107140
|
-
const
|
|
107202
|
+
const match2d = css.match(
|
|
107141
107203
|
/^matrix\(\s*([^,]+),\s*([^,]+),\s*([^,]+),\s*([^,]+),\s*([^,]+),\s*([^,)]+)\s*\)$/
|
|
107142
107204
|
);
|
|
107143
|
-
if (
|
|
107144
|
-
|
|
107145
|
-
|
|
107146
|
-
|
|
107205
|
+
if (match2d) {
|
|
107206
|
+
const values = match2d.slice(1, 7).map(Number);
|
|
107207
|
+
if (!values.every(Number.isFinite)) return null;
|
|
107208
|
+
return values;
|
|
107209
|
+
}
|
|
107210
|
+
const match3d = css.match(/^matrix3d\(\s*([^)]+)\)$/);
|
|
107211
|
+
if (match3d) {
|
|
107212
|
+
const raw2 = match3d[1];
|
|
107213
|
+
if (!raw2) return null;
|
|
107214
|
+
const parts = raw2.split(",").map((s) => Number(s.trim()));
|
|
107215
|
+
if (parts.length !== 16 || !parts.every(Number.isFinite)) return null;
|
|
107216
|
+
warnIfZSignificant(parts);
|
|
107217
|
+
return [
|
|
107218
|
+
parts[0],
|
|
107219
|
+
parts[1],
|
|
107220
|
+
parts[4],
|
|
107221
|
+
parts[5],
|
|
107222
|
+
parts[12],
|
|
107223
|
+
parts[13]
|
|
107224
|
+
];
|
|
107225
|
+
}
|
|
107226
|
+
return null;
|
|
107227
|
+
}
|
|
107228
|
+
var warnedZSignificant = false;
|
|
107229
|
+
var Z_EPSILON = 1e-6;
|
|
107230
|
+
function warnIfZSignificant(parts) {
|
|
107231
|
+
if (warnedZSignificant) return;
|
|
107232
|
+
const a3 = parts[8] ?? 0;
|
|
107233
|
+
const b3 = parts[9] ?? 0;
|
|
107234
|
+
const c1 = parts[2] ?? 0;
|
|
107235
|
+
const c2 = parts[6] ?? 0;
|
|
107236
|
+
const c3 = parts[10] ?? 1;
|
|
107237
|
+
const d1 = parts[3] ?? 0;
|
|
107238
|
+
const d2 = parts[7] ?? 0;
|
|
107239
|
+
const d3 = parts[11] ?? 0;
|
|
107240
|
+
const d4 = parts[15] ?? 1;
|
|
107241
|
+
if (Math.abs(a3) > Z_EPSILON || Math.abs(b3) > Z_EPSILON || Math.abs(c1) > Z_EPSILON || Math.abs(c2) > Z_EPSILON || Math.abs(c3 - 1) > Z_EPSILON || Math.abs(d1) > Z_EPSILON || Math.abs(d2) > Z_EPSILON || Math.abs(d3) > Z_EPSILON || Math.abs(d4 - 1) > Z_EPSILON) {
|
|
107242
|
+
warnedZSignificant = true;
|
|
107243
|
+
console.warn(
|
|
107244
|
+
`[alphaBlit] parseTransformMatrix received a matrix3d with non-trivial 3D components (a3=${a3}, b3=${b3}, c1=${c1}, c2=${c2}, c3=${c3}, d1=${d1}, d2=${d2}, d3=${d3}, d4=${d4}). The engine projects 3D transforms to 2D (m11, m12, m21, m22, m41, m42) and silently discards perspective and out-of-plane rotation. If your composition uses real 3D (rotateX/Y, perspective), the rendered output will not match the studio preview. Z translation (translateZ) is dropped by design and does not trigger this warning. This warning is emitted once per process.`
|
|
107245
|
+
);
|
|
107246
|
+
}
|
|
107147
107247
|
}
|
|
107148
107248
|
|
|
107149
107249
|
// ../engine/src/utils/layerCompositor.ts
|
|
@@ -107797,14 +107897,14 @@ var ridgedBurn = (from2, to, out, w, h, p) => {
|
|
|
107797
107897
|
TRANSITIONS["ridged-burn"] = ridgedBurn;
|
|
107798
107898
|
|
|
107799
107899
|
// src/services/renderOrchestrator.ts
|
|
107800
|
-
import { join as join15, dirname as dirname10, resolve as
|
|
107900
|
+
import { join as join15, dirname as dirname10, resolve as resolve11 } from "path";
|
|
107801
107901
|
import { randomUUID } from "crypto";
|
|
107802
107902
|
import { freemem as freemem2 } from "os";
|
|
107803
107903
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
107804
107904
|
|
|
107805
107905
|
// src/services/fileServer.ts
|
|
107806
|
-
import { readFileSync as readFileSync7, existsSync as existsSync12, statSync as statSync5 } from "node:fs";
|
|
107807
|
-
import { join as join11, extname as extname4 } from "node:path";
|
|
107906
|
+
import { readFileSync as readFileSync7, existsSync as existsSync12, realpathSync, statSync as statSync5 } from "node:fs";
|
|
107907
|
+
import { join as join11, extname as extname4, resolve as resolve8, sep } from "node:path";
|
|
107808
107908
|
|
|
107809
107909
|
// src/services/hyperframeRuntimeLoader.ts
|
|
107810
107910
|
import { createHash as createHash2 } from "node:crypto";
|
|
@@ -107880,6 +107980,18 @@ function resolveVerifiedHyperframeRuntime() {
|
|
|
107880
107980
|
}
|
|
107881
107981
|
|
|
107882
107982
|
// src/services/fileServer.ts
|
|
107983
|
+
function isPathInside(child, parent, options = {}) {
|
|
107984
|
+
const { resolveSymlinks = false, pathModule } = options;
|
|
107985
|
+
const resolveFn = pathModule?.resolve ?? resolve8;
|
|
107986
|
+
const separator = pathModule?.sep ?? sep;
|
|
107987
|
+
const resolvedChild = resolveFn(child);
|
|
107988
|
+
const resolvedParent = resolveFn(parent);
|
|
107989
|
+
const normalizedChild = resolveSymlinks && existsSync12(resolvedChild) ? realpathSync.native(resolvedChild) : resolvedChild;
|
|
107990
|
+
const normalizedParent = resolveSymlinks && existsSync12(resolvedParent) ? realpathSync.native(resolvedParent) : resolvedParent;
|
|
107991
|
+
if (normalizedChild === normalizedParent) return true;
|
|
107992
|
+
const parentWithSep = normalizedParent.endsWith(separator) ? normalizedParent : normalizedParent + separator;
|
|
107993
|
+
return normalizedChild.startsWith(parentWithSep);
|
|
107994
|
+
}
|
|
107883
107995
|
var MIME_TYPES = {
|
|
107884
107996
|
".html": "text/html; charset=utf-8",
|
|
107885
107997
|
".css": "text/css; charset=utf-8",
|
|
@@ -108272,12 +108384,20 @@ function createFileServer2(options) {
|
|
|
108272
108384
|
let requestPath = c.req.path;
|
|
108273
108385
|
if (requestPath === "/") requestPath = "/index.html";
|
|
108274
108386
|
const relativePath = requestPath.replace(/^\//, "");
|
|
108275
|
-
|
|
108276
|
-
|
|
108277
|
-
|
|
108278
|
-
|
|
108279
|
-
|
|
108280
|
-
|
|
108387
|
+
let filePath = null;
|
|
108388
|
+
if (compiledDir) {
|
|
108389
|
+
const candidate = join11(compiledDir, relativePath);
|
|
108390
|
+
if (existsSync12(candidate) && isPathInside(candidate, compiledDir, { resolveSymlinks: true }) && statSync5(candidate).isFile()) {
|
|
108391
|
+
filePath = candidate;
|
|
108392
|
+
}
|
|
108393
|
+
}
|
|
108394
|
+
if (!filePath) {
|
|
108395
|
+
const candidate = join11(projectDir, relativePath);
|
|
108396
|
+
if (existsSync12(candidate) && isPathInside(candidate, projectDir, { resolveSymlinks: true }) && statSync5(candidate).isFile()) {
|
|
108397
|
+
filePath = candidate;
|
|
108398
|
+
}
|
|
108399
|
+
}
|
|
108400
|
+
if (!filePath) {
|
|
108281
108401
|
if (!/favicon\.ico$/i.test(requestPath)) {
|
|
108282
108402
|
console.warn(`[FileServer] 404 Not Found: ${requestPath}`);
|
|
108283
108403
|
}
|
|
@@ -108301,10 +108421,10 @@ function createFileServer2(options) {
|
|
|
108301
108421
|
headers: { "Content-Type": contentType }
|
|
108302
108422
|
});
|
|
108303
108423
|
});
|
|
108304
|
-
return new Promise((
|
|
108424
|
+
return new Promise((resolve14) => {
|
|
108305
108425
|
const connections = /* @__PURE__ */ new Set();
|
|
108306
108426
|
const server = serve({ fetch: app.fetch, port }, (info) => {
|
|
108307
|
-
|
|
108427
|
+
resolve14({
|
|
108308
108428
|
url: `http://localhost:${info.port}`,
|
|
108309
108429
|
port: info.port,
|
|
108310
108430
|
close: () => {
|
|
@@ -108323,18 +108443,18 @@ function createFileServer2(options) {
|
|
|
108323
108443
|
|
|
108324
108444
|
// src/services/htmlCompiler.ts
|
|
108325
108445
|
import { readFileSync as readFileSync9, existsSync as existsSync14, mkdirSync as mkdirSync9 } from "fs";
|
|
108326
|
-
import { join as join14, dirname as dirname9, resolve as
|
|
108446
|
+
import { join as join14, dirname as dirname9, resolve as resolve10 } from "path";
|
|
108327
108447
|
import postcss from "postcss";
|
|
108328
108448
|
|
|
108329
108449
|
// src/utils/paths.ts
|
|
108330
|
-
import { resolve as
|
|
108331
|
-
var DEFAULT_RENDERS_DIR = process.env.PRODUCER_RENDERS_DIR ??
|
|
108332
|
-
function
|
|
108333
|
-
const absChild =
|
|
108334
|
-
const absParent =
|
|
108450
|
+
import { resolve as resolve9, basename as basename2, join as join12, relative as relative2, isAbsolute as isAbsolute4 } from "node:path";
|
|
108451
|
+
var DEFAULT_RENDERS_DIR = process.env.PRODUCER_RENDERS_DIR ?? resolve9(new URL(import.meta.url).pathname, "../../..", "renders");
|
|
108452
|
+
function isPathInside2(childPath, parentPath) {
|
|
108453
|
+
const absChild = resolve9(childPath);
|
|
108454
|
+
const absParent = resolve9(parentPath);
|
|
108335
108455
|
if (absChild === absParent) return true;
|
|
108336
108456
|
const rel = relative2(absParent, absChild);
|
|
108337
|
-
return rel !== "" && !rel.startsWith("..") && !
|
|
108457
|
+
return rel !== "" && !rel.startsWith("..") && !isAbsolute4(rel);
|
|
108338
108458
|
}
|
|
108339
108459
|
function toExternalAssetKey(absPath) {
|
|
108340
108460
|
if (absPath.startsWith("hf-ext/")) return absPath;
|
|
@@ -108347,10 +108467,10 @@ function toExternalAssetKey(absPath) {
|
|
|
108347
108467
|
return "hf-ext/" + normalised;
|
|
108348
108468
|
}
|
|
108349
108469
|
function resolveRenderPaths(projectDir, outputPath, rendersDir = DEFAULT_RENDERS_DIR) {
|
|
108350
|
-
const absoluteProjectDir =
|
|
108470
|
+
const absoluteProjectDir = resolve9(projectDir);
|
|
108351
108471
|
const projectName = basename2(absoluteProjectDir);
|
|
108352
108472
|
const resolvedOutputPath = outputPath ?? join12(rendersDir, `${projectName}.mp4`);
|
|
108353
|
-
const absoluteOutputPath =
|
|
108473
|
+
const absoluteOutputPath = resolve9(resolvedOutputPath);
|
|
108354
108474
|
return { absoluteProjectDir, absoluteOutputPath };
|
|
108355
108475
|
}
|
|
108356
108476
|
|
|
@@ -108797,7 +108917,7 @@ async function resolveMediaDuration(src, mediaStart, baseDir, downloadDir, tagNa
|
|
|
108797
108917
|
if (!existsSync14(filePath)) {
|
|
108798
108918
|
return { duration: 0, resolvedPath: filePath };
|
|
108799
108919
|
}
|
|
108800
|
-
const metadata = tagName19 === "video" ? await
|
|
108920
|
+
const metadata = tagName19 === "video" ? await extractMediaMetadata(filePath) : await extractAudioMetadata(filePath);
|
|
108801
108921
|
const fileDuration = metadata.durationSeconds;
|
|
108802
108922
|
const effectiveDuration = fileDuration - mediaStart;
|
|
108803
108923
|
const duration = effectiveDuration > 0 ? effectiveDuration : fileDuration;
|
|
@@ -108859,7 +108979,7 @@ async function parseSubCompositions(html, projectDir, downloadDir, parentOffset
|
|
|
108859
108979
|
const elEnd = elEndRaw ? parseFloat(elEndRaw) : Infinity;
|
|
108860
108980
|
const absoluteStart = parentOffset + elStart;
|
|
108861
108981
|
const absoluteEnd = Math.min(parentEnd, isFinite(elEnd) ? parentOffset + elEnd : Infinity);
|
|
108862
|
-
const filePath =
|
|
108982
|
+
const filePath = resolve10(projectDir, srcPath);
|
|
108863
108983
|
if (visited.has(filePath)) {
|
|
108864
108984
|
continue;
|
|
108865
108985
|
}
|
|
@@ -109072,7 +109192,7 @@ function inlineSubCompositions(html, subCompositions, projectDir) {
|
|
|
109072
109192
|
if (!srcPath) continue;
|
|
109073
109193
|
let compHtml = subCompositions.get(srcPath) || null;
|
|
109074
109194
|
if (!compHtml) {
|
|
109075
|
-
const filePath =
|
|
109195
|
+
const filePath = resolve10(projectDir, srcPath);
|
|
109076
109196
|
if (existsSync14(filePath)) {
|
|
109077
109197
|
compHtml = readFileSync9(filePath, "utf-8");
|
|
109078
109198
|
}
|
|
@@ -109289,7 +109409,7 @@ ${safeText}
|
|
|
109289
109409
|
return wrappedFragment ? document2.body.innerHTML || "" : document2.toString();
|
|
109290
109410
|
}
|
|
109291
109411
|
function collectExternalAssets(html, projectDir) {
|
|
109292
|
-
const absProjectDir =
|
|
109412
|
+
const absProjectDir = resolve10(projectDir);
|
|
109293
109413
|
const externalAssets = /* @__PURE__ */ new Map();
|
|
109294
109414
|
const CSS_URL_RE2 = /\burl\(\s*(["']?)([^)"']+)\1\s*\)/g;
|
|
109295
109415
|
function processPath(rawPath) {
|
|
@@ -109297,8 +109417,8 @@ function collectExternalAssets(html, projectDir) {
|
|
|
109297
109417
|
if (!trimmed || trimmed.startsWith("/") || trimmed.startsWith("http://") || trimmed.startsWith("https://") || trimmed.startsWith("//") || trimmed.startsWith("data:") || trimmed.startsWith("#")) {
|
|
109298
109418
|
return null;
|
|
109299
109419
|
}
|
|
109300
|
-
const absPath =
|
|
109301
|
-
if (
|
|
109420
|
+
const absPath = resolve10(absProjectDir, trimmed);
|
|
109421
|
+
if (isPathInside2(absPath, absProjectDir)) {
|
|
109302
109422
|
return null;
|
|
109303
109423
|
}
|
|
109304
109424
|
if (!existsSync14(absPath)) return null;
|
|
@@ -109378,9 +109498,9 @@ async function compileForRender(projectDir, htmlPath, downloadDir) {
|
|
|
109378
109498
|
const images = dedupeElementsById([...mainImages, ...subImages]);
|
|
109379
109499
|
for (const video of videos) {
|
|
109380
109500
|
if (isHttpUrl(video.src)) continue;
|
|
109381
|
-
const videoPath =
|
|
109501
|
+
const videoPath = resolve10(projectDir, video.src);
|
|
109382
109502
|
const reencode = `ffmpeg -i "${video.src}" -c:v libx264 -r 30 -g 30 -keyint_min 30 -movflags +faststart -c:a copy output.mp4`;
|
|
109383
|
-
Promise.all([analyzeKeyframeIntervals(videoPath),
|
|
109503
|
+
Promise.all([analyzeKeyframeIntervals(videoPath), extractMediaMetadata(videoPath)]).then(([analysis, metadata]) => {
|
|
109384
109504
|
if (analysis.isProblematic) {
|
|
109385
109505
|
console.warn(
|
|
109386
109506
|
`[Compiler] WARNING: Video "${video.id}" has sparse keyframes (max interval: ${analysis.maxIntervalSeconds}s). This causes seek failures and frame freezing. Re-encode with: ${reencode}`
|
|
@@ -109579,6 +109699,21 @@ function getMaxFrameIndex(frameDir) {
|
|
|
109579
109699
|
frameDirMaxIndexCache.set(frameDir, max);
|
|
109580
109700
|
return max;
|
|
109581
109701
|
}
|
|
109702
|
+
function countNonZeroAlpha(rgba) {
|
|
109703
|
+
let n = 0;
|
|
109704
|
+
for (let p = 3; p < rgba.length; p += 4) {
|
|
109705
|
+
if (rgba[p] !== 0) n++;
|
|
109706
|
+
}
|
|
109707
|
+
return n;
|
|
109708
|
+
}
|
|
109709
|
+
function countNonZeroRgb48(buf) {
|
|
109710
|
+
let n = 0;
|
|
109711
|
+
for (let p = 0; p < buf.length; p += 6) {
|
|
109712
|
+
if (buf[p] !== 0 || buf[p + 1] !== 0 || buf[p + 2] !== 0 || buf[p + 3] !== 0 || buf[p + 4] !== 0 || buf[p + 5] !== 0)
|
|
109713
|
+
n++;
|
|
109714
|
+
}
|
|
109715
|
+
return n;
|
|
109716
|
+
}
|
|
109582
109717
|
var RenderCancelledError = class extends Error {
|
|
109583
109718
|
reason;
|
|
109584
109719
|
constructor(message = "render_cancelled", reason = "aborted") {
|
|
@@ -109639,8 +109774,8 @@ function writeCompiledArtifacts(compiled, workDir, includeSummary) {
|
|
|
109639
109774
|
writeFileSync4(outPath, html, "utf-8");
|
|
109640
109775
|
}
|
|
109641
109776
|
for (const [relativePath, absolutePath] of compiled.externalAssets) {
|
|
109642
|
-
const outPath =
|
|
109643
|
-
if (!
|
|
109777
|
+
const outPath = resolve11(join15(compileDir, relativePath));
|
|
109778
|
+
if (!isPathInside2(outPath, compileDir)) {
|
|
109644
109779
|
console.warn(`[Render] Skipping external asset with unsafe path: ${relativePath}`);
|
|
109645
109780
|
continue;
|
|
109646
109781
|
}
|
|
@@ -109786,6 +109921,165 @@ function blitHdrImageLayer(canvas, el, hdrImageBuffers, width, height, log, sour
|
|
|
109786
109921
|
}
|
|
109787
109922
|
}
|
|
109788
109923
|
}
|
|
109924
|
+
async function compositeHdrFrame(ctx, canvas, time, fullStacking, elementFilter, debugFrameIndex = -1) {
|
|
109925
|
+
const {
|
|
109926
|
+
log,
|
|
109927
|
+
domSession,
|
|
109928
|
+
beforeCaptureHook,
|
|
109929
|
+
width,
|
|
109930
|
+
height,
|
|
109931
|
+
fps,
|
|
109932
|
+
effectiveHdr,
|
|
109933
|
+
nativeHdrImageIds,
|
|
109934
|
+
hdrImageBuffers,
|
|
109935
|
+
hdrFrameDirs,
|
|
109936
|
+
hdrVideoStartTimes,
|
|
109937
|
+
imageTransfers,
|
|
109938
|
+
videoTransfers,
|
|
109939
|
+
debugDumpEnabled,
|
|
109940
|
+
debugDumpDir
|
|
109941
|
+
} = ctx;
|
|
109942
|
+
const filteredStacking = elementFilter ? fullStacking.filter((e) => elementFilter.has(e.id)) : fullStacking;
|
|
109943
|
+
const layers = groupIntoLayers(filteredStacking);
|
|
109944
|
+
const shouldLog = debugDumpEnabled && debugFrameIndex >= 0;
|
|
109945
|
+
if (shouldLog) {
|
|
109946
|
+
log.info("[diag] compositeToBuffer plan", {
|
|
109947
|
+
frame: debugFrameIndex,
|
|
109948
|
+
time: time.toFixed(3),
|
|
109949
|
+
filterSize: elementFilter?.size,
|
|
109950
|
+
fullStackingCount: fullStacking.length,
|
|
109951
|
+
filteredCount: filteredStacking.length,
|
|
109952
|
+
layerCount: layers.length,
|
|
109953
|
+
layers: layers.map(
|
|
109954
|
+
(l) => l.type === "hdr" ? {
|
|
109955
|
+
type: "hdr",
|
|
109956
|
+
id: l.element.id,
|
|
109957
|
+
z: l.element.zIndex,
|
|
109958
|
+
visible: l.element.visible,
|
|
109959
|
+
opacity: l.element.opacity,
|
|
109960
|
+
bounds: `${Math.round(l.element.x)},${Math.round(l.element.y)} ${Math.round(l.element.width)}x${Math.round(l.element.height)}`
|
|
109961
|
+
} : { type: "dom", ids: l.elementIds }
|
|
109962
|
+
)
|
|
109963
|
+
});
|
|
109964
|
+
}
|
|
109965
|
+
for (const [layerIdx, layer] of layers.entries()) {
|
|
109966
|
+
if (layer.type === "hdr") {
|
|
109967
|
+
const before2 = shouldLog ? countNonZeroRgb48(canvas) : 0;
|
|
109968
|
+
const isHdrImage = nativeHdrImageIds.has(layer.element.id);
|
|
109969
|
+
if (isHdrImage) {
|
|
109970
|
+
blitHdrImageLayer(
|
|
109971
|
+
canvas,
|
|
109972
|
+
layer.element,
|
|
109973
|
+
hdrImageBuffers,
|
|
109974
|
+
width,
|
|
109975
|
+
height,
|
|
109976
|
+
log,
|
|
109977
|
+
imageTransfers.get(layer.element.id),
|
|
109978
|
+
effectiveHdr.transfer
|
|
109979
|
+
);
|
|
109980
|
+
} else {
|
|
109981
|
+
blitHdrVideoLayer(
|
|
109982
|
+
canvas,
|
|
109983
|
+
layer.element,
|
|
109984
|
+
time,
|
|
109985
|
+
fps,
|
|
109986
|
+
hdrFrameDirs,
|
|
109987
|
+
hdrVideoStartTimes,
|
|
109988
|
+
width,
|
|
109989
|
+
height,
|
|
109990
|
+
log,
|
|
109991
|
+
videoTransfers.get(layer.element.id),
|
|
109992
|
+
effectiveHdr.transfer
|
|
109993
|
+
);
|
|
109994
|
+
}
|
|
109995
|
+
if (shouldLog) {
|
|
109996
|
+
const after2 = countNonZeroRgb48(canvas);
|
|
109997
|
+
if (isHdrImage) {
|
|
109998
|
+
const buf = hdrImageBuffers.get(layer.element.id);
|
|
109999
|
+
log.info("[diag] hdr layer blit", {
|
|
110000
|
+
frame: debugFrameIndex,
|
|
110001
|
+
layerIdx,
|
|
110002
|
+
id: layer.element.id,
|
|
110003
|
+
kind: "image",
|
|
110004
|
+
pixelsAdded: after2 - before2,
|
|
110005
|
+
totalNonZero: after2,
|
|
110006
|
+
bufferDecoded: !!buf,
|
|
110007
|
+
bufferDims: buf ? `${buf.width}x${buf.height}` : null
|
|
110008
|
+
});
|
|
110009
|
+
} else {
|
|
110010
|
+
const frameDir = hdrFrameDirs.get(layer.element.id);
|
|
110011
|
+
const startTime = hdrVideoStartTimes.get(layer.element.id) ?? 0;
|
|
110012
|
+
const localTime = time - startTime;
|
|
110013
|
+
const frameNum = Math.floor(localTime * fps) + 1;
|
|
110014
|
+
const expectedFrame = frameDir ? join15(frameDir, `frame_${String(frameNum).padStart(4, "0")}.png`) : null;
|
|
110015
|
+
log.info("[diag] hdr layer blit", {
|
|
110016
|
+
frame: debugFrameIndex,
|
|
110017
|
+
layerIdx,
|
|
110018
|
+
id: layer.element.id,
|
|
110019
|
+
kind: "video",
|
|
110020
|
+
pixelsAdded: after2 - before2,
|
|
110021
|
+
totalNonZero: after2,
|
|
110022
|
+
startTime,
|
|
110023
|
+
localTime: localTime.toFixed(3),
|
|
110024
|
+
hdrFrameNum: frameNum,
|
|
110025
|
+
expectedFrame,
|
|
110026
|
+
expectedFrameExists: expectedFrame ? existsSync15(expectedFrame) : false
|
|
110027
|
+
});
|
|
110028
|
+
}
|
|
110029
|
+
}
|
|
110030
|
+
} else {
|
|
110031
|
+
const allElementIds = fullStacking.map((e) => e.id);
|
|
110032
|
+
const layerIds = new Set(layer.elementIds);
|
|
110033
|
+
const hideIds = allElementIds.filter((id) => !layerIds.has(id));
|
|
110034
|
+
await domSession.page.evaluate((t) => {
|
|
110035
|
+
if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
|
|
110036
|
+
}, time);
|
|
110037
|
+
if (beforeCaptureHook) {
|
|
110038
|
+
await beforeCaptureHook(domSession.page, time);
|
|
110039
|
+
}
|
|
110040
|
+
await applyDomLayerMask(domSession.page, layer.elementIds, hideIds);
|
|
110041
|
+
const domPng = await captureAlphaPng(domSession.page, width, height);
|
|
110042
|
+
await removeDomLayerMask(domSession.page, hideIds);
|
|
110043
|
+
try {
|
|
110044
|
+
const { data: domRgba } = decodePng(domPng);
|
|
110045
|
+
const before2 = shouldLog ? countNonZeroRgb48(canvas) : 0;
|
|
110046
|
+
const alphaPixels = shouldLog ? countNonZeroAlpha(domRgba) : 0;
|
|
110047
|
+
blitRgba8OverRgb48le(domRgba, canvas, width, height, effectiveHdr.transfer);
|
|
110048
|
+
if (shouldLog && debugDumpDir) {
|
|
110049
|
+
const after2 = countNonZeroRgb48(canvas);
|
|
110050
|
+
const dumpName = `frame_${String(debugFrameIndex).padStart(4, "0")}_layer_${String(layerIdx).padStart(2, "0")}_dom.png`;
|
|
110051
|
+
const dumpPath = join15(debugDumpDir, dumpName);
|
|
110052
|
+
writeFileSync4(dumpPath, domPng);
|
|
110053
|
+
log.info("[diag] dom layer blit", {
|
|
110054
|
+
frame: debugFrameIndex,
|
|
110055
|
+
layerIdx,
|
|
110056
|
+
layerIds: layer.elementIds,
|
|
110057
|
+
hideCount: hideIds.length,
|
|
110058
|
+
pngBytes: domPng.length,
|
|
110059
|
+
alphaPixels,
|
|
110060
|
+
pixelsAdded: after2 - before2,
|
|
110061
|
+
totalNonZero: after2,
|
|
110062
|
+
dumpPath
|
|
110063
|
+
});
|
|
110064
|
+
}
|
|
110065
|
+
} catch (err) {
|
|
110066
|
+
log.warn("DOM layer decode/blit failed; skipping overlay", {
|
|
110067
|
+
layerIds: layer.elementIds,
|
|
110068
|
+
error: err instanceof Error ? err.message : String(err)
|
|
110069
|
+
});
|
|
110070
|
+
}
|
|
110071
|
+
}
|
|
110072
|
+
}
|
|
110073
|
+
if (shouldLog && debugDumpDir) {
|
|
110074
|
+
const finalNonZero = countNonZeroRgb48(canvas);
|
|
110075
|
+
log.info("[diag] compositeToBuffer end", {
|
|
110076
|
+
frame: debugFrameIndex,
|
|
110077
|
+
finalNonZeroPixels: finalNonZero,
|
|
110078
|
+
totalPixels: width * height,
|
|
110079
|
+
coverage: (finalNonZero / (width * height) * 100).toFixed(1) + "%"
|
|
110080
|
+
});
|
|
110081
|
+
}
|
|
110082
|
+
}
|
|
109789
110083
|
function createRenderJob(config2) {
|
|
109790
110084
|
return {
|
|
109791
110085
|
id: randomUUID(),
|
|
@@ -109827,7 +110121,7 @@ function extractStandaloneEntryFromIndex(indexHtml, entryFile) {
|
|
|
109827
110121
|
}
|
|
109828
110122
|
async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSignal) {
|
|
109829
110123
|
const moduleDir = dirname10(fileURLToPath3(import.meta.url));
|
|
109830
|
-
const producerRoot = process.env.PRODUCER_RENDERS_DIR ?
|
|
110124
|
+
const producerRoot = process.env.PRODUCER_RENDERS_DIR ? resolve11(process.env.PRODUCER_RENDERS_DIR, "..") : resolve11(moduleDir, "../..");
|
|
109831
110125
|
const debugDir = join15(producerRoot, ".debug");
|
|
109832
110126
|
const workDir = job.config.debug ? join15(debugDir, job.id) : join15(dirname10(outputPath), `work-${job.id}`);
|
|
109833
110127
|
const pipelineStart = Date.now();
|
|
@@ -110130,7 +110424,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110130
110424
|
videoPath = fromCompiled;
|
|
110131
110425
|
}
|
|
110132
110426
|
if (!existsSync15(videoPath)) return;
|
|
110133
|
-
const meta = await
|
|
110427
|
+
const meta = await extractMediaMetadata(videoPath);
|
|
110134
110428
|
if (isHdrColorSpace(meta.colorSpace)) {
|
|
110135
110429
|
nativeHdrVideoIds.add(v.id);
|
|
110136
110430
|
videoTransfers.set(v.id, detectTransfer(meta.colorSpace));
|
|
@@ -110151,7 +110445,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110151
110445
|
imgPath = fromCompiled;
|
|
110152
110446
|
}
|
|
110153
110447
|
if (!existsSync15(imgPath)) return null;
|
|
110154
|
-
const meta = await
|
|
110448
|
+
const meta = await extractMediaMetadata(imgPath);
|
|
110155
110449
|
if (isHdrColorSpace(meta.colorSpace)) {
|
|
110156
110450
|
nativeHdrImageIds.add(img.id);
|
|
110157
110451
|
imageTransfers.set(img.id, detectTransfer(meta.colorSpace));
|
|
@@ -110263,6 +110557,10 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110263
110557
|
format: needsAlpha ? "png" : "jpeg",
|
|
110264
110558
|
quality: needsAlpha ? void 0 : job.config.quality === "draft" ? 80 : 95
|
|
110265
110559
|
};
|
|
110560
|
+
const buildHdrCaptureOptions = () => ({
|
|
110561
|
+
...captureOptions,
|
|
110562
|
+
skipReadinessVideoIds: Array.from(nativeHdrVideoIds)
|
|
110563
|
+
});
|
|
110266
110564
|
const workerCount = calculateOptimalWorkers(totalFrames, job.config.workers, cfg);
|
|
110267
110565
|
const FORMAT_EXT = { mp4: ".mp4", webm: ".webm", mov: ".mov" };
|
|
110268
110566
|
const videoExt = FORMAT_EXT[outputFormat] ?? ".mp4";
|
|
@@ -110271,6 +110569,13 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110271
110569
|
const hasHdrContent = effectiveHdr && nativeHdrIds.size > 0;
|
|
110272
110570
|
const encoderHdr = hasHdrContent ? effectiveHdr : void 0;
|
|
110273
110571
|
const preset = getEncoderPreset(job.config.quality, outputFormat, encoderHdr);
|
|
110572
|
+
if (job.config.crf != null && job.config.videoBitrate) {
|
|
110573
|
+
log.warn(
|
|
110574
|
+
`[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.`
|
|
110575
|
+
);
|
|
110576
|
+
}
|
|
110577
|
+
const effectiveQuality = job.config.crf ?? preset.quality;
|
|
110578
|
+
const effectiveBitrate = job.config.crf != null ? void 0 : job.config.videoBitrate;
|
|
110274
110579
|
job.framesRendered = 0;
|
|
110275
110580
|
if (hasHdrContent) {
|
|
110276
110581
|
log.info("[Render] HDR layered composite: z-ordered DOM + native HLG video layers");
|
|
@@ -110290,516 +110595,440 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110290
110595
|
const domSession = await createCaptureSession(
|
|
110291
110596
|
fileServer.url,
|
|
110292
110597
|
framesDir,
|
|
110293
|
-
|
|
110598
|
+
buildHdrCaptureOptions(),
|
|
110294
110599
|
createVideoFrameInjector(frameLookup),
|
|
110295
110600
|
cfg
|
|
110296
110601
|
);
|
|
110297
|
-
|
|
110298
|
-
|
|
110299
|
-
|
|
110300
|
-
await initTransparentBackground(domSession.page);
|
|
110301
|
-
const transitionMeta = await domSession.page.evaluate(() => {
|
|
110302
|
-
return window.__hf?.transitions ?? [];
|
|
110303
|
-
});
|
|
110304
|
-
const sceneElements = await domSession.page.evaluate(() => {
|
|
110305
|
-
const scenes = document.querySelectorAll(".scene");
|
|
110306
|
-
const map2 = {};
|
|
110307
|
-
for (const scene of scenes) {
|
|
110308
|
-
const els = scene.querySelectorAll("[data-start]");
|
|
110309
|
-
map2[scene.id] = Array.from(els).map((e) => e.id);
|
|
110310
|
-
}
|
|
110311
|
-
return map2;
|
|
110312
|
-
});
|
|
110313
|
-
const transitionRanges = transitionMeta.map((t) => ({
|
|
110314
|
-
...t,
|
|
110315
|
-
startFrame: Math.floor(t.time * job.config.fps),
|
|
110316
|
-
endFrame: Math.ceil((t.time + t.duration) * job.config.fps)
|
|
110317
|
-
}));
|
|
110318
|
-
if (transitionRanges.length > 0) {
|
|
110319
|
-
log.info("[Render] Detected shader transitions for HDR compositing", {
|
|
110320
|
-
count: transitionRanges.length,
|
|
110321
|
-
transitions: transitionRanges.map((t) => ({
|
|
110322
|
-
shader: t.shader,
|
|
110323
|
-
from: t.fromScene,
|
|
110324
|
-
to: t.toScene,
|
|
110325
|
-
frames: `${t.startFrame}-${t.endFrame}`
|
|
110326
|
-
}))
|
|
110327
|
-
});
|
|
110328
|
-
}
|
|
110329
|
-
const hdrEncoder = await spawnStreamingEncoder(
|
|
110330
|
-
videoOnlyPath,
|
|
110331
|
-
{
|
|
110332
|
-
fps: job.config.fps,
|
|
110333
|
-
width,
|
|
110334
|
-
height,
|
|
110335
|
-
codec: preset.codec,
|
|
110336
|
-
preset: preset.preset,
|
|
110337
|
-
quality: preset.quality,
|
|
110338
|
-
pixelFormat: preset.pixelFormat,
|
|
110339
|
-
hdr: preset.hdr,
|
|
110340
|
-
rawInputFormat: "rgb48le"
|
|
110341
|
-
},
|
|
110342
|
-
abortSignal,
|
|
110343
|
-
{ ffmpegStreamingTimeout: 36e5 }
|
|
110344
|
-
);
|
|
110345
|
-
assertNotAborted();
|
|
110346
|
-
const hdrExtractionDims = /* @__PURE__ */ new Map();
|
|
110347
|
-
const hdrImageFitInfo = /* @__PURE__ */ new Map();
|
|
110348
|
-
const hdrVideoStartTimes = /* @__PURE__ */ new Map();
|
|
110349
|
-
for (const v of composition.videos) {
|
|
110350
|
-
if (hdrVideoIds.includes(v.id)) {
|
|
110351
|
-
hdrVideoStartTimes.set(v.id, v.start);
|
|
110352
|
-
}
|
|
110353
|
-
}
|
|
110354
|
-
const hdrImageStartTimes = /* @__PURE__ */ new Map();
|
|
110355
|
-
for (const img of composition.images) {
|
|
110356
|
-
if (nativeHdrImageIds.has(img.id)) {
|
|
110357
|
-
hdrImageStartTimes.set(img.id, img.start);
|
|
110358
|
-
}
|
|
110359
|
-
}
|
|
110360
|
-
const uniqueStartTimes = [
|
|
110361
|
-
.../* @__PURE__ */ new Set([...hdrVideoStartTimes.values(), ...hdrImageStartTimes.values()])
|
|
110362
|
-
].sort((a, b) => a - b);
|
|
110363
|
-
for (const seekTime of uniqueStartTimes) {
|
|
110364
|
-
await domSession.page.evaluate((t) => {
|
|
110365
|
-
if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
|
|
110366
|
-
}, seekTime);
|
|
110367
|
-
if (domSession.onBeforeCapture) {
|
|
110368
|
-
await domSession.onBeforeCapture(domSession.page, seekTime);
|
|
110369
|
-
}
|
|
110370
|
-
const stacking = await queryElementStacking(domSession.page, nativeHdrIds);
|
|
110371
|
-
for (const el of stacking) {
|
|
110372
|
-
if (el.isHdr && el.layoutWidth > 0 && el.layoutHeight > 0 && !hdrExtractionDims.has(el.id)) {
|
|
110373
|
-
hdrExtractionDims.set(el.id, { width: el.layoutWidth, height: el.layoutHeight });
|
|
110374
|
-
}
|
|
110375
|
-
if (el.isHdr && nativeHdrImageIds.has(el.id) && !hdrImageFitInfo.has(el.id)) {
|
|
110376
|
-
hdrImageFitInfo.set(el.id, {
|
|
110377
|
-
fit: el.objectFit,
|
|
110378
|
-
position: el.objectPosition
|
|
110379
|
-
});
|
|
110380
|
-
}
|
|
110381
|
-
}
|
|
110382
|
-
}
|
|
110602
|
+
let hdrEncoder = null;
|
|
110603
|
+
let hdrEncoderClosed = false;
|
|
110604
|
+
let domSessionClosed = false;
|
|
110383
110605
|
const hdrFrameDirs = /* @__PURE__ */ new Map();
|
|
110384
|
-
|
|
110385
|
-
|
|
110386
|
-
|
|
110387
|
-
|
|
110388
|
-
|
|
110389
|
-
const
|
|
110390
|
-
|
|
110391
|
-
|
|
110392
|
-
|
|
110393
|
-
|
|
110394
|
-
|
|
110395
|
-
|
|
110396
|
-
|
|
110397
|
-
|
|
110398
|
-
"-r",
|
|
110399
|
-
String(job.config.fps),
|
|
110400
|
-
"-vf",
|
|
110401
|
-
`scale=${dims.width}:${dims.height}:force_original_aspect_ratio=increase,crop=${dims.width}:${dims.height}`,
|
|
110402
|
-
"-pix_fmt",
|
|
110403
|
-
"rgb48le",
|
|
110404
|
-
"-c:v",
|
|
110405
|
-
"png",
|
|
110406
|
-
"-y",
|
|
110407
|
-
join15(frameDir, "frame_%04d.png")
|
|
110408
|
-
];
|
|
110409
|
-
const result = await runFfmpeg(ffmpegArgs, { signal: abortSignal });
|
|
110410
|
-
if (!result.success) {
|
|
110411
|
-
hdrDiagnostics.videoExtractionFailures += 1;
|
|
110412
|
-
log.error("HDR frame pre-extraction failed; aborting render", {
|
|
110413
|
-
videoId,
|
|
110414
|
-
srcPath,
|
|
110415
|
-
stderr: result.stderr.slice(-400)
|
|
110416
|
-
});
|
|
110417
|
-
throw new Error(
|
|
110418
|
-
`HDR frame extraction failed for video "${videoId}". Aborting render to avoid shipping black HDR layers.`
|
|
110419
|
-
);
|
|
110420
|
-
}
|
|
110421
|
-
hdrFrameDirs.set(videoId, frameDir);
|
|
110422
|
-
}
|
|
110423
|
-
const hdrImageBuffers = /* @__PURE__ */ new Map();
|
|
110424
|
-
for (const [imageId, srcPath] of hdrImageSrcPaths) {
|
|
110425
|
-
try {
|
|
110426
|
-
const decoded = decodePngToRgb48le(readFileSync10(srcPath));
|
|
110427
|
-
const layout2 = hdrExtractionDims.get(imageId);
|
|
110428
|
-
const fitInfo = hdrImageFitInfo.get(imageId);
|
|
110429
|
-
if (layout2 && (layout2.width !== decoded.width || layout2.height !== decoded.height)) {
|
|
110430
|
-
const fit = normalizeObjectFit(fitInfo?.fit);
|
|
110431
|
-
const resampled = resampleRgb48leObjectFit(
|
|
110432
|
-
decoded.data,
|
|
110433
|
-
decoded.width,
|
|
110434
|
-
decoded.height,
|
|
110435
|
-
layout2.width,
|
|
110436
|
-
layout2.height,
|
|
110437
|
-
fit,
|
|
110438
|
-
fitInfo?.position
|
|
110439
|
-
);
|
|
110440
|
-
hdrImageBuffers.set(imageId, {
|
|
110441
|
-
data: resampled,
|
|
110442
|
-
width: layout2.width,
|
|
110443
|
-
height: layout2.height
|
|
110444
|
-
});
|
|
110445
|
-
} else {
|
|
110446
|
-
hdrImageBuffers.set(imageId, {
|
|
110447
|
-
data: Buffer.from(decoded.data),
|
|
110448
|
-
width: decoded.width,
|
|
110449
|
-
height: decoded.height
|
|
110450
|
-
});
|
|
110606
|
+
try {
|
|
110607
|
+
await initializeSession(domSession);
|
|
110608
|
+
assertNotAborted();
|
|
110609
|
+
lastBrowserConsole = domSession.browserConsoleBuffer;
|
|
110610
|
+
await initTransparentBackground(domSession.page);
|
|
110611
|
+
const transitionMeta = await domSession.page.evaluate(() => {
|
|
110612
|
+
return window.__hf?.transitions ?? [];
|
|
110613
|
+
});
|
|
110614
|
+
const sceneElements = await domSession.page.evaluate(() => {
|
|
110615
|
+
const scenes = document.querySelectorAll(".scene");
|
|
110616
|
+
const map2 = {};
|
|
110617
|
+
for (const scene of scenes) {
|
|
110618
|
+
const els = scene.querySelectorAll("[data-start]");
|
|
110619
|
+
map2[scene.id] = Array.from(els).map((e) => e.id);
|
|
110451
110620
|
}
|
|
110452
|
-
|
|
110453
|
-
|
|
110454
|
-
|
|
110455
|
-
|
|
110456
|
-
|
|
110457
|
-
|
|
110621
|
+
return map2;
|
|
110622
|
+
});
|
|
110623
|
+
const transitionRanges = transitionMeta.map((t) => ({
|
|
110624
|
+
...t,
|
|
110625
|
+
startFrame: Math.floor(t.time * job.config.fps),
|
|
110626
|
+
endFrame: Math.ceil((t.time + t.duration) * job.config.fps)
|
|
110627
|
+
}));
|
|
110628
|
+
if (transitionRanges.length > 0) {
|
|
110629
|
+
log.info("[Render] Detected shader transitions for HDR compositing", {
|
|
110630
|
+
count: transitionRanges.length,
|
|
110631
|
+
transitions: transitionRanges.map((t) => ({
|
|
110632
|
+
shader: t.shader,
|
|
110633
|
+
from: t.fromScene,
|
|
110634
|
+
to: t.toScene,
|
|
110635
|
+
frames: `${t.startFrame}-${t.endFrame}`
|
|
110636
|
+
}))
|
|
110458
110637
|
});
|
|
110459
|
-
throw new Error(
|
|
110460
|
-
`HDR image decode failed for image "${imageId}". Aborting render to avoid shipping missing HDR image layers.`
|
|
110461
|
-
);
|
|
110462
110638
|
}
|
|
110463
|
-
|
|
110464
|
-
|
|
110465
|
-
|
|
110466
|
-
|
|
110467
|
-
|
|
110468
|
-
|
|
110469
|
-
|
|
110639
|
+
hdrEncoder = await spawnStreamingEncoder(
|
|
110640
|
+
videoOnlyPath,
|
|
110641
|
+
{
|
|
110642
|
+
fps: job.config.fps,
|
|
110643
|
+
width,
|
|
110644
|
+
height,
|
|
110645
|
+
codec: preset.codec,
|
|
110646
|
+
preset: preset.preset,
|
|
110647
|
+
quality: effectiveQuality,
|
|
110648
|
+
bitrate: effectiveBitrate,
|
|
110649
|
+
pixelFormat: preset.pixelFormat,
|
|
110650
|
+
hdr: preset.hdr,
|
|
110651
|
+
rawInputFormat: "rgb48le"
|
|
110652
|
+
},
|
|
110653
|
+
abortSignal,
|
|
110654
|
+
{ ffmpegStreamingTimeout: 36e5 }
|
|
110655
|
+
);
|
|
110656
|
+
assertNotAborted();
|
|
110657
|
+
const hdrExtractionDims = /* @__PURE__ */ new Map();
|
|
110658
|
+
const hdrImageFitInfo = /* @__PURE__ */ new Map();
|
|
110659
|
+
const hdrVideoStartTimes = /* @__PURE__ */ new Map();
|
|
110660
|
+
for (const v of composition.videos) {
|
|
110661
|
+
if (hdrVideoIds.includes(v.id)) {
|
|
110662
|
+
hdrVideoStartTimes.set(v.id, v.start);
|
|
110470
110663
|
}
|
|
110471
|
-
|
|
110472
|
-
|
|
110473
|
-
|
|
110474
|
-
|
|
110475
|
-
|
|
110664
|
+
}
|
|
110665
|
+
const hdrImageStartTimes = /* @__PURE__ */ new Map();
|
|
110666
|
+
for (const img of composition.images) {
|
|
110667
|
+
if (nativeHdrImageIds.has(img.id)) {
|
|
110668
|
+
hdrImageStartTimes.set(img.id, img.start);
|
|
110476
110669
|
}
|
|
110477
|
-
|
|
110478
|
-
|
|
110479
|
-
|
|
110480
|
-
|
|
110481
|
-
const
|
|
110482
|
-
|
|
110483
|
-
|
|
110484
|
-
|
|
110485
|
-
|
|
110486
|
-
|
|
110487
|
-
|
|
110488
|
-
|
|
110489
|
-
|
|
110490
|
-
|
|
110491
|
-
|
|
110492
|
-
|
|
110493
|
-
|
|
110494
|
-
|
|
110495
|
-
|
|
110496
|
-
|
|
110497
|
-
|
|
110498
|
-
|
|
110499
|
-
frame: debugFrameIndex,
|
|
110500
|
-
time: time.toFixed(3),
|
|
110501
|
-
filterSize: elementFilter?.size,
|
|
110502
|
-
fullStackingCount: fullStacking.length,
|
|
110503
|
-
filteredCount: filteredStacking.length,
|
|
110504
|
-
layerCount: layers.length,
|
|
110505
|
-
layers: layers.map(
|
|
110506
|
-
(l) => l.type === "hdr" ? {
|
|
110507
|
-
type: "hdr",
|
|
110508
|
-
id: l.element.id,
|
|
110509
|
-
z: l.element.zIndex,
|
|
110510
|
-
visible: l.element.visible,
|
|
110511
|
-
opacity: l.element.opacity,
|
|
110512
|
-
bounds: `${Math.round(l.element.x)},${Math.round(l.element.y)} ${Math.round(l.element.width)}x${Math.round(l.element.height)}`
|
|
110513
|
-
} : { type: "dom", ids: l.elementIds }
|
|
110514
|
-
)
|
|
110515
|
-
});
|
|
110670
|
+
}
|
|
110671
|
+
const uniqueStartTimes = [
|
|
110672
|
+
.../* @__PURE__ */ new Set([...hdrVideoStartTimes.values(), ...hdrImageStartTimes.values()])
|
|
110673
|
+
].sort((a, b) => a - b);
|
|
110674
|
+
for (const seekTime of uniqueStartTimes) {
|
|
110675
|
+
await domSession.page.evaluate((t) => {
|
|
110676
|
+
if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
|
|
110677
|
+
}, seekTime);
|
|
110678
|
+
if (domSession.onBeforeCapture) {
|
|
110679
|
+
await domSession.onBeforeCapture(domSession.page, seekTime);
|
|
110680
|
+
}
|
|
110681
|
+
const stacking = await queryElementStacking(domSession.page, nativeHdrIds);
|
|
110682
|
+
for (const el of stacking) {
|
|
110683
|
+
if (el.isHdr && el.layoutWidth > 0 && el.layoutHeight > 0 && !hdrExtractionDims.has(el.id)) {
|
|
110684
|
+
hdrExtractionDims.set(el.id, { width: el.layoutWidth, height: el.layoutHeight });
|
|
110685
|
+
}
|
|
110686
|
+
if (el.isHdr && nativeHdrImageIds.has(el.id) && !hdrImageFitInfo.has(el.id)) {
|
|
110687
|
+
hdrImageFitInfo.set(el.id, {
|
|
110688
|
+
fit: el.objectFit,
|
|
110689
|
+
position: el.objectPosition
|
|
110690
|
+
});
|
|
110691
|
+
}
|
|
110516
110692
|
}
|
|
110517
|
-
|
|
110518
|
-
|
|
110519
|
-
|
|
110520
|
-
|
|
110521
|
-
|
|
110522
|
-
|
|
110523
|
-
|
|
110524
|
-
|
|
110525
|
-
|
|
110526
|
-
|
|
110527
|
-
|
|
110528
|
-
|
|
110529
|
-
|
|
110530
|
-
|
|
110531
|
-
|
|
110532
|
-
|
|
110533
|
-
|
|
110534
|
-
|
|
110535
|
-
|
|
110536
|
-
time,
|
|
110537
|
-
job.config.fps,
|
|
110538
|
-
hdrFrameDirs,
|
|
110539
|
-
hdrVideoStartTimes,
|
|
110540
|
-
width,
|
|
110541
|
-
height,
|
|
110542
|
-
log,
|
|
110543
|
-
videoTransfers.get(layer.element.id),
|
|
110544
|
-
effectiveHdr?.transfer
|
|
110545
|
-
);
|
|
110546
|
-
}
|
|
110547
|
-
if (shouldLog) {
|
|
110548
|
-
const after2 = countNonZeroRgb482(canvas);
|
|
110549
|
-
if (isHdrImage) {
|
|
110550
|
-
const buf = hdrImageBuffers.get(layer.element.id);
|
|
110551
|
-
log.info("[diag] hdr layer blit", {
|
|
110552
|
-
frame: debugFrameIndex,
|
|
110553
|
-
layerIdx,
|
|
110554
|
-
id: layer.element.id,
|
|
110555
|
-
kind: "image",
|
|
110556
|
-
pixelsAdded: after2 - before2,
|
|
110557
|
-
totalNonZero: after2,
|
|
110558
|
-
bufferDecoded: !!buf,
|
|
110559
|
-
bufferDims: buf ? `${buf.width}x${buf.height}` : null
|
|
110560
|
-
});
|
|
110561
|
-
} else {
|
|
110562
|
-
const frameDir = hdrFrameDirs.get(layer.element.id);
|
|
110563
|
-
const startTime = hdrVideoStartTimes.get(layer.element.id) ?? 0;
|
|
110564
|
-
const localTime = time - startTime;
|
|
110565
|
-
const frameNum = Math.floor(localTime * job.config.fps) + 1;
|
|
110566
|
-
const expectedFrame = frameDir ? join15(frameDir, `frame_${String(frameNum).padStart(4, "0")}.png`) : null;
|
|
110567
|
-
log.info("[diag] hdr layer blit", {
|
|
110568
|
-
frame: debugFrameIndex,
|
|
110569
|
-
layerIdx,
|
|
110570
|
-
id: layer.element.id,
|
|
110571
|
-
kind: "video",
|
|
110572
|
-
pixelsAdded: after2 - before2,
|
|
110573
|
-
totalNonZero: after2,
|
|
110574
|
-
startTime,
|
|
110575
|
-
localTime: localTime.toFixed(3),
|
|
110576
|
-
hdrFrameNum: frameNum,
|
|
110577
|
-
expectedFrame,
|
|
110578
|
-
expectedFrameExists: expectedFrame ? existsSync15(expectedFrame) : false
|
|
110579
|
-
});
|
|
110580
|
-
}
|
|
110581
|
-
}
|
|
110582
|
-
} else {
|
|
110583
|
-
const allElementIds = fullStacking.map((e) => e.id);
|
|
110584
|
-
const layerIds = new Set(layer.elementIds);
|
|
110585
|
-
const hideIds = allElementIds.filter((id) => !layerIds.has(id));
|
|
110586
|
-
await domSession.page.evaluate((t) => {
|
|
110587
|
-
if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
|
|
110588
|
-
}, time);
|
|
110589
|
-
if (beforeCaptureHook) {
|
|
110590
|
-
await beforeCaptureHook(domSession.page, time);
|
|
110591
|
-
}
|
|
110592
|
-
await applyDomLayerMask(domSession.page, layer.elementIds, hideIds);
|
|
110593
|
-
const domPng = await captureAlphaPng(domSession.page, width, height);
|
|
110594
|
-
await removeDomLayerMask(domSession.page, hideIds);
|
|
110595
|
-
try {
|
|
110596
|
-
const { data: domRgba } = decodePng(domPng);
|
|
110597
|
-
if (!effectiveHdr) {
|
|
110598
|
-
throw new Error(
|
|
110599
|
-
"Invariant violation: effectiveHdr is undefined inside HDR layer branch"
|
|
110600
|
-
);
|
|
110601
|
-
}
|
|
110602
|
-
const before2 = shouldLog ? countNonZeroRgb482(canvas) : 0;
|
|
110603
|
-
const alphaPixels = shouldLog ? countNonZeroAlpha2(domRgba) : 0;
|
|
110604
|
-
blitRgba8OverRgb48le(domRgba, canvas, width, height, effectiveHdr.transfer);
|
|
110605
|
-
if (shouldLog && debugDumpDir) {
|
|
110606
|
-
const after2 = countNonZeroRgb482(canvas);
|
|
110607
|
-
const dumpName = `frame_${String(debugFrameIndex).padStart(4, "0")}_layer_${String(layerIdx).padStart(2, "0")}_dom.png`;
|
|
110608
|
-
const dumpPath = join15(debugDumpDir, dumpName);
|
|
110609
|
-
writeFileSync4(dumpPath, domPng);
|
|
110610
|
-
log.info("[diag] dom layer blit", {
|
|
110611
|
-
frame: debugFrameIndex,
|
|
110612
|
-
layerIdx,
|
|
110613
|
-
layerIds: layer.elementIds,
|
|
110614
|
-
hideCount: hideIds.length,
|
|
110615
|
-
pngBytes: domPng.length,
|
|
110616
|
-
alphaPixels,
|
|
110617
|
-
pixelsAdded: after2 - before2,
|
|
110618
|
-
totalNonZero: after2,
|
|
110619
|
-
dumpPath
|
|
110620
|
-
});
|
|
110621
|
-
}
|
|
110622
|
-
} catch (err) {
|
|
110623
|
-
log.warn("DOM layer decode/blit failed; skipping overlay", {
|
|
110624
|
-
layerIds: layer.elementIds,
|
|
110625
|
-
error: err instanceof Error ? err.message : String(err)
|
|
110626
|
-
});
|
|
110693
|
+
}
|
|
110694
|
+
for (const [imageId, startTime] of hdrImageStartTimes) {
|
|
110695
|
+
if (hdrExtractionDims.has(imageId)) continue;
|
|
110696
|
+
const img = composition.images.find((i) => i.id === imageId);
|
|
110697
|
+
if (!img) continue;
|
|
110698
|
+
const duration = img.end - img.start;
|
|
110699
|
+
const retryTime = startTime + Math.min(0.5, duration * 0.1);
|
|
110700
|
+
await domSession.page.evaluate((t) => {
|
|
110701
|
+
if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
|
|
110702
|
+
}, retryTime);
|
|
110703
|
+
if (domSession.onBeforeCapture) {
|
|
110704
|
+
await domSession.onBeforeCapture(domSession.page, retryTime);
|
|
110705
|
+
}
|
|
110706
|
+
const retryStacking = await queryElementStacking(domSession.page, nativeHdrIds);
|
|
110707
|
+
for (const el of retryStacking) {
|
|
110708
|
+
if (el.id === imageId && el.isHdr && el.layoutWidth > 0 && el.layoutHeight > 0) {
|
|
110709
|
+
hdrExtractionDims.set(el.id, { width: el.layoutWidth, height: el.layoutHeight });
|
|
110710
|
+
if (!hdrImageFitInfo.has(el.id)) {
|
|
110711
|
+
hdrImageFitInfo.set(el.id, { fit: el.objectFit, position: el.objectPosition });
|
|
110627
110712
|
}
|
|
110713
|
+
break;
|
|
110628
110714
|
}
|
|
110629
110715
|
}
|
|
110630
|
-
|
|
110631
|
-
|
|
110632
|
-
|
|
110633
|
-
|
|
110634
|
-
|
|
110635
|
-
|
|
110636
|
-
|
|
110716
|
+
}
|
|
110717
|
+
for (const [videoId, srcPath] of hdrVideoSrcPaths) {
|
|
110718
|
+
const video = composition.videos.find((v) => v.id === videoId);
|
|
110719
|
+
if (!video) continue;
|
|
110720
|
+
const frameDir = join15(framesDir, `hdr_${videoId}`);
|
|
110721
|
+
mkdirSync10(frameDir, { recursive: true });
|
|
110722
|
+
const duration = video.end - video.start;
|
|
110723
|
+
const dims = hdrExtractionDims.get(videoId) ?? { width, height };
|
|
110724
|
+
const ffmpegArgs = [
|
|
110725
|
+
"-ss",
|
|
110726
|
+
String(video.mediaStart),
|
|
110727
|
+
"-i",
|
|
110728
|
+
srcPath,
|
|
110729
|
+
"-t",
|
|
110730
|
+
String(duration),
|
|
110731
|
+
"-r",
|
|
110732
|
+
String(job.config.fps),
|
|
110733
|
+
"-vf",
|
|
110734
|
+
`scale=${dims.width}:${dims.height}:force_original_aspect_ratio=increase,crop=${dims.width}:${dims.height}`,
|
|
110735
|
+
"-pix_fmt",
|
|
110736
|
+
"rgb48le",
|
|
110737
|
+
"-c:v",
|
|
110738
|
+
"png",
|
|
110739
|
+
"-y",
|
|
110740
|
+
join15(frameDir, "frame_%04d.png")
|
|
110741
|
+
];
|
|
110742
|
+
const result = await runFfmpeg(ffmpegArgs, { signal: abortSignal });
|
|
110743
|
+
if (!result.success) {
|
|
110744
|
+
hdrDiagnostics.videoExtractionFailures += 1;
|
|
110745
|
+
log.error("HDR frame pre-extraction failed; aborting render", {
|
|
110746
|
+
videoId,
|
|
110747
|
+
srcPath,
|
|
110748
|
+
stderr: result.stderr.slice(-400)
|
|
110637
110749
|
});
|
|
110750
|
+
throw new Error(
|
|
110751
|
+
`HDR frame extraction failed for video "${videoId}". Aborting render to avoid shipping black HDR layers.`
|
|
110752
|
+
);
|
|
110638
110753
|
}
|
|
110754
|
+
hdrFrameDirs.set(videoId, frameDir);
|
|
110639
110755
|
}
|
|
110640
|
-
const
|
|
110641
|
-
const
|
|
110642
|
-
|
|
110643
|
-
|
|
110644
|
-
|
|
110645
|
-
|
|
110646
|
-
|
|
110647
|
-
|
|
110648
|
-
|
|
110649
|
-
|
|
110650
|
-
|
|
110651
|
-
|
|
110652
|
-
|
|
110653
|
-
|
|
110654
|
-
|
|
110655
|
-
|
|
110656
|
-
|
|
110657
|
-
|
|
110658
|
-
|
|
110659
|
-
|
|
110660
|
-
|
|
110661
|
-
|
|
110662
|
-
|
|
110663
|
-
|
|
110664
|
-
|
|
110665
|
-
|
|
110666
|
-
|
|
110756
|
+
const hdrImageBuffers = /* @__PURE__ */ new Map();
|
|
110757
|
+
for (const [imageId, srcPath] of hdrImageSrcPaths) {
|
|
110758
|
+
try {
|
|
110759
|
+
const decoded = decodePngToRgb48le(readFileSync10(srcPath));
|
|
110760
|
+
const layout2 = hdrExtractionDims.get(imageId);
|
|
110761
|
+
const fitInfo = hdrImageFitInfo.get(imageId);
|
|
110762
|
+
if (layout2 && (layout2.width !== decoded.width || layout2.height !== decoded.height)) {
|
|
110763
|
+
const fit = normalizeObjectFit(fitInfo?.fit);
|
|
110764
|
+
const resampled = resampleRgb48leObjectFit(
|
|
110765
|
+
decoded.data,
|
|
110766
|
+
decoded.width,
|
|
110767
|
+
decoded.height,
|
|
110768
|
+
layout2.width,
|
|
110769
|
+
layout2.height,
|
|
110770
|
+
fit,
|
|
110771
|
+
fitInfo?.position
|
|
110772
|
+
);
|
|
110773
|
+
hdrImageBuffers.set(imageId, {
|
|
110774
|
+
data: resampled,
|
|
110775
|
+
width: layout2.width,
|
|
110776
|
+
height: layout2.height
|
|
110777
|
+
});
|
|
110778
|
+
} else {
|
|
110779
|
+
hdrImageBuffers.set(imageId, {
|
|
110780
|
+
data: Buffer.from(decoded.data),
|
|
110781
|
+
width: decoded.width,
|
|
110782
|
+
height: decoded.height
|
|
110783
|
+
});
|
|
110784
|
+
}
|
|
110785
|
+
} catch (err) {
|
|
110786
|
+
hdrDiagnostics.imageDecodeFailures += 1;
|
|
110787
|
+
log.error("HDR image decode failed; aborting render", {
|
|
110788
|
+
imageId,
|
|
110789
|
+
srcPath,
|
|
110790
|
+
error: err instanceof Error ? err.message : String(err)
|
|
110667
110791
|
});
|
|
110792
|
+
throw new Error(
|
|
110793
|
+
`HDR image decode failed for image "${imageId}". Aborting render to avoid shipping missing HDR image layers.`
|
|
110794
|
+
);
|
|
110668
110795
|
}
|
|
110669
|
-
|
|
110670
|
-
|
|
110671
|
-
|
|
110672
|
-
|
|
110673
|
-
|
|
110674
|
-
|
|
110675
|
-
|
|
110676
|
-
|
|
110677
|
-
|
|
110678
|
-
|
|
110679
|
-
|
|
110680
|
-
|
|
110681
|
-
|
|
110682
|
-
|
|
110683
|
-
|
|
110684
|
-
|
|
110685
|
-
|
|
110686
|
-
|
|
110687
|
-
|
|
110688
|
-
|
|
110689
|
-
|
|
110690
|
-
|
|
110691
|
-
|
|
110692
|
-
|
|
110693
|
-
|
|
110694
|
-
|
|
110695
|
-
|
|
110696
|
-
|
|
110697
|
-
|
|
110698
|
-
|
|
110699
|
-
|
|
110796
|
+
}
|
|
110797
|
+
assertNotAborted();
|
|
110798
|
+
try {
|
|
110799
|
+
const beforeCaptureHook = domSession.onBeforeCapture;
|
|
110800
|
+
const cleanedUpVideos = /* @__PURE__ */ new Set();
|
|
110801
|
+
const hdrVideoEndTimes = /* @__PURE__ */ new Map();
|
|
110802
|
+
for (const v of composition.videos) {
|
|
110803
|
+
if (hdrFrameDirs.has(v.id)) {
|
|
110804
|
+
hdrVideoEndTimes.set(v.id, v.end);
|
|
110805
|
+
}
|
|
110806
|
+
}
|
|
110807
|
+
const debugDumpEnabled = process.env.KEEP_TEMP === "1";
|
|
110808
|
+
const debugDumpDir = debugDumpEnabled ? join15(framesDir, "debug-composite") : null;
|
|
110809
|
+
if (debugDumpDir && !existsSync15(debugDumpDir)) {
|
|
110810
|
+
mkdirSync10(debugDumpDir, { recursive: true });
|
|
110811
|
+
}
|
|
110812
|
+
if (!effectiveHdr) {
|
|
110813
|
+
throw new Error(
|
|
110814
|
+
"Internal: HDR render path entered without effectiveHdr \u2014 this is a bug."
|
|
110815
|
+
);
|
|
110816
|
+
}
|
|
110817
|
+
const hdrCompositeCtx = {
|
|
110818
|
+
log,
|
|
110819
|
+
domSession,
|
|
110820
|
+
beforeCaptureHook,
|
|
110821
|
+
width,
|
|
110822
|
+
height,
|
|
110823
|
+
fps: job.config.fps,
|
|
110824
|
+
effectiveHdr,
|
|
110825
|
+
nativeHdrImageIds,
|
|
110826
|
+
hdrImageBuffers,
|
|
110827
|
+
hdrFrameDirs,
|
|
110828
|
+
hdrVideoStartTimes,
|
|
110829
|
+
imageTransfers,
|
|
110830
|
+
videoTransfers,
|
|
110831
|
+
debugDumpEnabled,
|
|
110832
|
+
debugDumpDir
|
|
110833
|
+
};
|
|
110834
|
+
const bufSize = width * height * 6;
|
|
110835
|
+
const hasTransitions = transitionRanges.length > 0;
|
|
110836
|
+
const transBufferA = hasTransitions ? Buffer.alloc(bufSize) : null;
|
|
110837
|
+
const transBufferB = hasTransitions ? Buffer.alloc(bufSize) : null;
|
|
110838
|
+
const transOutput = hasTransitions ? Buffer.alloc(bufSize) : null;
|
|
110839
|
+
const normalCanvas = Buffer.alloc(bufSize);
|
|
110840
|
+
for (let i = 0; i < totalFrames; i++) {
|
|
110841
|
+
assertNotAborted();
|
|
110842
|
+
const time = i / job.config.fps;
|
|
110843
|
+
await domSession.page.evaluate((t) => {
|
|
110844
|
+
if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
|
|
110845
|
+
}, time);
|
|
110846
|
+
if (beforeCaptureHook) {
|
|
110847
|
+
await beforeCaptureHook(domSession.page, time);
|
|
110848
|
+
}
|
|
110849
|
+
const stackingInfo = await queryElementStacking(domSession.page, nativeHdrIds);
|
|
110850
|
+
const activeTransition = transitionRanges.find(
|
|
110851
|
+
(t) => i >= t.startFrame && i <= t.endFrame
|
|
110852
|
+
);
|
|
110853
|
+
if (i % 30 === 0) {
|
|
110854
|
+
const hdrEl = stackingInfo.find((e) => e.isHdr);
|
|
110855
|
+
log.debug("[Render] HDR layer composite frame", {
|
|
110856
|
+
frame: i,
|
|
110857
|
+
time: time.toFixed(2),
|
|
110858
|
+
hdrElement: hdrEl ? { z: hdrEl.zIndex, visible: hdrEl.visible, width: hdrEl.width } : null,
|
|
110859
|
+
stackingCount: stackingInfo.length,
|
|
110860
|
+
activeTransition: activeTransition?.shader
|
|
110861
|
+
});
|
|
110862
|
+
}
|
|
110863
|
+
if (activeTransition && transBufferA && transBufferB && transOutput) {
|
|
110864
|
+
const progress = activeTransition.endFrame === activeTransition.startFrame ? 1 : (i - activeTransition.startFrame) / (activeTransition.endFrame - activeTransition.startFrame);
|
|
110865
|
+
const sceneAIds = new Set(sceneElements[activeTransition.fromScene] ?? []);
|
|
110866
|
+
const sceneBIds = new Set(sceneElements[activeTransition.toScene] ?? []);
|
|
110867
|
+
transBufferA.fill(0);
|
|
110868
|
+
transBufferB.fill(0);
|
|
110869
|
+
for (const [sceneBuf, sceneIds] of [
|
|
110870
|
+
[transBufferA, sceneAIds],
|
|
110871
|
+
[transBufferB, sceneBIds]
|
|
110872
|
+
]) {
|
|
110873
|
+
assertNotAborted();
|
|
110874
|
+
await domSession.page.evaluate((t) => {
|
|
110875
|
+
if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
|
|
110876
|
+
}, time);
|
|
110877
|
+
if (beforeCaptureHook) {
|
|
110878
|
+
await beforeCaptureHook(domSession.page, time);
|
|
110879
|
+
}
|
|
110880
|
+
for (const el of stackingInfo) {
|
|
110881
|
+
if (!el.isHdr || !sceneIds.has(el.id)) continue;
|
|
110882
|
+
if (nativeHdrImageIds.has(el.id)) {
|
|
110883
|
+
blitHdrImageLayer(
|
|
110884
|
+
sceneBuf,
|
|
110885
|
+
el,
|
|
110886
|
+
hdrImageBuffers,
|
|
110887
|
+
width,
|
|
110888
|
+
height,
|
|
110889
|
+
log,
|
|
110890
|
+
imageTransfers.get(el.id),
|
|
110891
|
+
effectiveHdr?.transfer
|
|
110892
|
+
);
|
|
110893
|
+
} else {
|
|
110894
|
+
blitHdrVideoLayer(
|
|
110895
|
+
sceneBuf,
|
|
110896
|
+
el,
|
|
110897
|
+
time,
|
|
110898
|
+
job.config.fps,
|
|
110899
|
+
hdrFrameDirs,
|
|
110900
|
+
hdrVideoStartTimes,
|
|
110901
|
+
width,
|
|
110902
|
+
height,
|
|
110903
|
+
log,
|
|
110904
|
+
videoTransfers.get(el.id),
|
|
110905
|
+
effectiveHdr?.transfer
|
|
110906
|
+
);
|
|
110907
|
+
}
|
|
110908
|
+
}
|
|
110909
|
+
const showIds = Array.from(sceneIds);
|
|
110910
|
+
const hideIds = stackingInfo.map((e) => e.id).filter((id) => !sceneIds.has(id) || nativeHdrIds.has(id));
|
|
110911
|
+
await applyDomLayerMask(domSession.page, showIds, hideIds);
|
|
110912
|
+
const domPng = await captureAlphaPng(domSession.page, width, height);
|
|
110913
|
+
await removeDomLayerMask(domSession.page, hideIds);
|
|
110914
|
+
try {
|
|
110915
|
+
const { data: domRgba } = decodePng(domPng);
|
|
110916
|
+
if (!effectiveHdr) {
|
|
110917
|
+
throw new Error(
|
|
110918
|
+
"Invariant violation: effectiveHdr is undefined inside hasHdrVideo branch"
|
|
110919
|
+
);
|
|
110920
|
+
}
|
|
110921
|
+
blitRgba8OverRgb48le(
|
|
110922
|
+
domRgba,
|
|
110700
110923
|
sceneBuf,
|
|
110701
|
-
el,
|
|
110702
|
-
time,
|
|
110703
|
-
job.config.fps,
|
|
110704
|
-
hdrFrameDirs,
|
|
110705
|
-
hdrVideoStartTimes,
|
|
110706
110924
|
width,
|
|
110707
110925
|
height,
|
|
110708
|
-
|
|
110709
|
-
videoTransfers.get(el.id),
|
|
110710
|
-
effectiveHdr?.transfer
|
|
110926
|
+
effectiveHdr.transfer
|
|
110711
110927
|
);
|
|
110928
|
+
} catch (err) {
|
|
110929
|
+
log.warn("DOM layer decode/blit failed; skipping overlay for transition scene", {
|
|
110930
|
+
frameIndex: i,
|
|
110931
|
+
sceneIds: Array.from(sceneIds),
|
|
110932
|
+
error: err instanceof Error ? err.message : String(err)
|
|
110933
|
+
});
|
|
110712
110934
|
}
|
|
110713
110935
|
}
|
|
110714
|
-
const
|
|
110715
|
-
|
|
110716
|
-
|
|
110717
|
-
|
|
110718
|
-
|
|
110719
|
-
|
|
110720
|
-
|
|
110721
|
-
|
|
110722
|
-
|
|
110723
|
-
|
|
110724
|
-
|
|
110725
|
-
|
|
110726
|
-
|
|
110727
|
-
|
|
110728
|
-
|
|
110729
|
-
|
|
110730
|
-
|
|
110731
|
-
effectiveHdr.transfer
|
|
110936
|
+
const transitionFn = TRANSITIONS[activeTransition.shader] ?? crossfade;
|
|
110937
|
+
transitionFn(transBufferA, transBufferB, transOutput, width, height, progress);
|
|
110938
|
+
hdrEncoder.writeFrame(transOutput);
|
|
110939
|
+
} else {
|
|
110940
|
+
normalCanvas.fill(0);
|
|
110941
|
+
await compositeHdrFrame(
|
|
110942
|
+
hdrCompositeCtx,
|
|
110943
|
+
normalCanvas,
|
|
110944
|
+
time,
|
|
110945
|
+
stackingInfo,
|
|
110946
|
+
void 0,
|
|
110947
|
+
i
|
|
110948
|
+
);
|
|
110949
|
+
if (debugDumpEnabled && debugDumpDir && i % 30 === 0) {
|
|
110950
|
+
const previewPath = join15(
|
|
110951
|
+
debugDumpDir,
|
|
110952
|
+
`frame_${String(i).padStart(4, "0")}_final_rgb48le.bin`
|
|
110732
110953
|
);
|
|
110733
|
-
|
|
110734
|
-
log.warn("DOM layer decode/blit failed; skipping overlay for transition scene", {
|
|
110735
|
-
frameIndex: i,
|
|
110736
|
-
sceneIds: Array.from(sceneIds),
|
|
110737
|
-
error: err instanceof Error ? err.message : String(err)
|
|
110738
|
-
});
|
|
110954
|
+
writeFileSync4(previewPath, normalCanvas);
|
|
110739
110955
|
}
|
|
110740
|
-
|
|
110741
|
-
|
|
110742
|
-
|
|
110743
|
-
|
|
110744
|
-
|
|
110745
|
-
|
|
110746
|
-
|
|
110747
|
-
|
|
110748
|
-
|
|
110749
|
-
|
|
110750
|
-
|
|
110751
|
-
|
|
110752
|
-
|
|
110753
|
-
|
|
110754
|
-
|
|
110755
|
-
|
|
110756
|
-
|
|
110757
|
-
|
|
110758
|
-
|
|
110759
|
-
|
|
110760
|
-
if (!stillNeeded) {
|
|
110761
|
-
const frameDir = hdrFrameDirs.get(videoId);
|
|
110762
|
-
if (frameDir) {
|
|
110763
|
-
try {
|
|
110764
|
-
rmSync3(frameDir, { recursive: true, force: true });
|
|
110765
|
-
} catch (err) {
|
|
110766
|
-
log.warn("Failed to clean up HDR frame directory", {
|
|
110767
|
-
videoId,
|
|
110768
|
-
frameDir,
|
|
110769
|
-
error: err instanceof Error ? err.message : String(err)
|
|
110770
|
-
});
|
|
110956
|
+
hdrEncoder.writeFrame(normalCanvas);
|
|
110957
|
+
}
|
|
110958
|
+
if (process.env.KEEP_TEMP !== "1") {
|
|
110959
|
+
for (const [videoId, endTime] of hdrVideoEndTimes) {
|
|
110960
|
+
if (time > endTime && !cleanedUpVideos.has(videoId)) {
|
|
110961
|
+
const stillNeeded = activeTransition && (sceneElements[activeTransition.fromScene]?.includes(videoId) || sceneElements[activeTransition.toScene]?.includes(videoId));
|
|
110962
|
+
if (!stillNeeded) {
|
|
110963
|
+
const frameDir = hdrFrameDirs.get(videoId);
|
|
110964
|
+
if (frameDir) {
|
|
110965
|
+
try {
|
|
110966
|
+
rmSync3(frameDir, { recursive: true, force: true });
|
|
110967
|
+
} catch (err) {
|
|
110968
|
+
log.warn("Failed to clean up HDR frame directory", {
|
|
110969
|
+
videoId,
|
|
110970
|
+
frameDir,
|
|
110971
|
+
error: err instanceof Error ? err.message : String(err)
|
|
110972
|
+
});
|
|
110973
|
+
}
|
|
110974
|
+
frameDirMaxIndexCache.delete(frameDir);
|
|
110975
|
+
hdrFrameDirs.delete(videoId);
|
|
110771
110976
|
}
|
|
110977
|
+
cleanedUpVideos.add(videoId);
|
|
110772
110978
|
}
|
|
110773
|
-
cleanedUpVideos.add(videoId);
|
|
110774
110979
|
}
|
|
110775
110980
|
}
|
|
110776
110981
|
}
|
|
110982
|
+
job.framesRendered = i + 1;
|
|
110983
|
+
if ((i + 1) % 10 === 0 || i + 1 === totalFrames) {
|
|
110984
|
+
const frameProgress = (i + 1) / totalFrames;
|
|
110985
|
+
updateJobStatus(
|
|
110986
|
+
job,
|
|
110987
|
+
"rendering",
|
|
110988
|
+
`HDR composite frame ${i + 1}/${job.totalFrames}`,
|
|
110989
|
+
Math.round(25 + frameProgress * 55),
|
|
110990
|
+
onProgress
|
|
110991
|
+
);
|
|
110992
|
+
}
|
|
110777
110993
|
}
|
|
110778
|
-
|
|
110779
|
-
|
|
110780
|
-
|
|
110781
|
-
|
|
110782
|
-
job,
|
|
110783
|
-
"rendering",
|
|
110784
|
-
`HDR composite frame ${i + 1}/${job.totalFrames}`,
|
|
110785
|
-
Math.round(25 + frameProgress * 55),
|
|
110786
|
-
onProgress
|
|
110787
|
-
);
|
|
110788
|
-
}
|
|
110994
|
+
} finally {
|
|
110995
|
+
lastBrowserConsole = domSession.browserConsoleBuffer;
|
|
110996
|
+
await closeCaptureSession(domSession);
|
|
110997
|
+
domSessionClosed = true;
|
|
110789
110998
|
}
|
|
110999
|
+
const hdrEncodeResult = await hdrEncoder.close();
|
|
111000
|
+
hdrEncoderClosed = true;
|
|
111001
|
+
assertNotAborted();
|
|
111002
|
+
if (!hdrEncodeResult.success) {
|
|
111003
|
+
throw new Error(`HDR encode failed: ${hdrEncodeResult.error}`);
|
|
111004
|
+
}
|
|
111005
|
+
perfStages.captureMs = Date.now() - stage4Start;
|
|
111006
|
+
perfStages.encodeMs = hdrEncodeResult.durationMs;
|
|
110790
111007
|
} finally {
|
|
110791
|
-
|
|
110792
|
-
|
|
110793
|
-
|
|
110794
|
-
|
|
110795
|
-
|
|
110796
|
-
|
|
110797
|
-
|
|
111008
|
+
if (hdrEncoder && !hdrEncoderClosed) {
|
|
111009
|
+
try {
|
|
111010
|
+
await hdrEncoder.close();
|
|
111011
|
+
} catch (err) {
|
|
111012
|
+
log.warn("hdrEncoder defensive close failed", {
|
|
111013
|
+
err: err instanceof Error ? err.message : String(err)
|
|
111014
|
+
});
|
|
111015
|
+
}
|
|
111016
|
+
}
|
|
111017
|
+
if (!domSessionClosed) {
|
|
111018
|
+
await closeCaptureSession(domSession).catch((err) => {
|
|
111019
|
+
log.warn("closeCaptureSession defensive close failed", {
|
|
111020
|
+
err: err instanceof Error ? err.message : String(err)
|
|
111021
|
+
});
|
|
111022
|
+
});
|
|
111023
|
+
}
|
|
111024
|
+
for (const frameDir of hdrFrameDirs.values()) {
|
|
111025
|
+
frameDirMaxIndexCache.delete(frameDir);
|
|
111026
|
+
}
|
|
111027
|
+
hdrFrameDirs.clear();
|
|
110798
111028
|
}
|
|
110799
|
-
perfStages.captureMs = Date.now() - stage4Start;
|
|
110800
|
-
perfStages.encodeMs = hdrEncodeResult.durationMs;
|
|
110801
111029
|
} else {
|
|
110802
111030
|
let streamingEncoder = null;
|
|
111031
|
+
let streamingEncoderClosed = false;
|
|
110803
111032
|
if (enableStreamingEncode) {
|
|
110804
111033
|
streamingEncoder = await spawnStreamingEncoder(
|
|
110805
111034
|
videoOnlyPath,
|
|
@@ -110809,7 +111038,8 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110809
111038
|
height,
|
|
110810
111039
|
codec: preset.codec,
|
|
110811
111040
|
preset: preset.preset,
|
|
110812
|
-
quality:
|
|
111041
|
+
quality: effectiveQuality,
|
|
111042
|
+
bitrate: effectiveBitrate,
|
|
110813
111043
|
pixelFormat: preset.pixelFormat,
|
|
110814
111044
|
useGpu: job.config.useGpu,
|
|
110815
111045
|
imageFormat: captureOptions.format || "jpeg",
|
|
@@ -110819,201 +111049,215 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110819
111049
|
);
|
|
110820
111050
|
assertNotAborted();
|
|
110821
111051
|
}
|
|
110822
|
-
|
|
110823
|
-
|
|
110824
|
-
|
|
110825
|
-
|
|
110826
|
-
|
|
110827
|
-
|
|
110828
|
-
|
|
110829
|
-
|
|
110830
|
-
|
|
110831
|
-
|
|
110832
|
-
|
|
110833
|
-
|
|
110834
|
-
|
|
110835
|
-
|
|
110836
|
-
|
|
110837
|
-
|
|
110838
|
-
|
|
110839
|
-
|
|
110840
|
-
|
|
110841
|
-
|
|
110842
|
-
|
|
110843
|
-
|
|
111052
|
+
try {
|
|
111053
|
+
if (enableStreamingEncode && streamingEncoder) {
|
|
111054
|
+
const reorderBuffer = createFrameReorderBuffer(0, totalFrames);
|
|
111055
|
+
const currentEncoder = streamingEncoder;
|
|
111056
|
+
if (workerCount > 1) {
|
|
111057
|
+
const tasks = distributeFrames(job.totalFrames, workerCount, workDir);
|
|
111058
|
+
const onFrameBuffer = async (frameIndex, buffer) => {
|
|
111059
|
+
await reorderBuffer.waitForFrame(frameIndex);
|
|
111060
|
+
currentEncoder.writeFrame(buffer);
|
|
111061
|
+
reorderBuffer.advanceTo(frameIndex + 1);
|
|
111062
|
+
};
|
|
111063
|
+
await executeParallelCapture(
|
|
111064
|
+
fileServer.url,
|
|
111065
|
+
workDir,
|
|
111066
|
+
tasks,
|
|
111067
|
+
buildHdrCaptureOptions(),
|
|
111068
|
+
() => createVideoFrameInjector(frameLookup),
|
|
111069
|
+
abortSignal,
|
|
111070
|
+
(progress) => {
|
|
111071
|
+
job.framesRendered = progress.capturedFrames;
|
|
111072
|
+
const frameProgress = progress.capturedFrames / progress.totalFrames;
|
|
111073
|
+
const progressPct = 25 + frameProgress * 55;
|
|
111074
|
+
if (progress.capturedFrames % 30 === 0 || progress.capturedFrames === progress.totalFrames) {
|
|
111075
|
+
updateJobStatus(
|
|
111076
|
+
job,
|
|
111077
|
+
"rendering",
|
|
111078
|
+
`Streaming frame ${progress.capturedFrames}/${progress.totalFrames} (${workerCount} workers)`,
|
|
111079
|
+
Math.round(progressPct),
|
|
111080
|
+
onProgress
|
|
111081
|
+
);
|
|
111082
|
+
}
|
|
111083
|
+
},
|
|
111084
|
+
onFrameBuffer,
|
|
111085
|
+
cfg
|
|
111086
|
+
);
|
|
111087
|
+
if (probeSession) {
|
|
111088
|
+
lastBrowserConsole = probeSession.browserConsoleBuffer;
|
|
111089
|
+
await closeCaptureSession(probeSession);
|
|
111090
|
+
probeSession = null;
|
|
111091
|
+
}
|
|
111092
|
+
} else {
|
|
111093
|
+
const videoInjector = createVideoFrameInjector(frameLookup);
|
|
111094
|
+
const session = probeSession ?? await createCaptureSession(
|
|
111095
|
+
fileServer.url,
|
|
111096
|
+
framesDir,
|
|
111097
|
+
buildHdrCaptureOptions(),
|
|
111098
|
+
videoInjector,
|
|
111099
|
+
cfg
|
|
111100
|
+
);
|
|
111101
|
+
if (probeSession) {
|
|
111102
|
+
prepareCaptureSessionForReuse(session, framesDir, videoInjector);
|
|
111103
|
+
probeSession = null;
|
|
111104
|
+
}
|
|
111105
|
+
try {
|
|
111106
|
+
if (!session.isInitialized) {
|
|
111107
|
+
await initializeSession(session);
|
|
111108
|
+
}
|
|
111109
|
+
assertNotAborted();
|
|
111110
|
+
lastBrowserConsole = session.browserConsoleBuffer;
|
|
111111
|
+
for (let i = 0; i < totalFrames; i++) {
|
|
111112
|
+
assertNotAborted();
|
|
111113
|
+
const time = i / job.config.fps;
|
|
111114
|
+
const { buffer } = await captureFrameToBuffer(session, i, time);
|
|
111115
|
+
await reorderBuffer.waitForFrame(i);
|
|
111116
|
+
currentEncoder.writeFrame(buffer);
|
|
111117
|
+
reorderBuffer.advanceTo(i + 1);
|
|
111118
|
+
job.framesRendered = i + 1;
|
|
111119
|
+
const frameProgress = (i + 1) / totalFrames;
|
|
111120
|
+
const progress = 25 + frameProgress * 55;
|
|
110844
111121
|
updateJobStatus(
|
|
110845
111122
|
job,
|
|
110846
111123
|
"rendering",
|
|
110847
|
-
`Streaming frame ${
|
|
110848
|
-
Math.round(
|
|
111124
|
+
`Streaming frame ${i + 1}/${job.totalFrames}`,
|
|
111125
|
+
Math.round(progress),
|
|
110849
111126
|
onProgress
|
|
110850
111127
|
);
|
|
110851
111128
|
}
|
|
110852
|
-
}
|
|
110853
|
-
|
|
110854
|
-
|
|
110855
|
-
|
|
110856
|
-
if (probeSession) {
|
|
110857
|
-
lastBrowserConsole = probeSession.browserConsoleBuffer;
|
|
110858
|
-
await closeCaptureSession(probeSession);
|
|
110859
|
-
probeSession = null;
|
|
111129
|
+
} finally {
|
|
111130
|
+
lastBrowserConsole = session.browserConsoleBuffer;
|
|
111131
|
+
await closeCaptureSession(session);
|
|
111132
|
+
}
|
|
110860
111133
|
}
|
|
110861
|
-
|
|
110862
|
-
|
|
110863
|
-
|
|
110864
|
-
|
|
110865
|
-
|
|
110866
|
-
{ ...captureOptions, skipReadinessVideoIds: Array.from(nativeHdrVideoIds) },
|
|
110867
|
-
videoInjector,
|
|
110868
|
-
cfg
|
|
110869
|
-
);
|
|
110870
|
-
if (probeSession) {
|
|
110871
|
-
prepareCaptureSessionForReuse(session, framesDir, videoInjector);
|
|
110872
|
-
probeSession = null;
|
|
111134
|
+
const encodeResult = await currentEncoder.close();
|
|
111135
|
+
streamingEncoderClosed = true;
|
|
111136
|
+
assertNotAborted();
|
|
111137
|
+
if (!encodeResult.success) {
|
|
111138
|
+
throw new Error(`Streaming encode failed: ${encodeResult.error}`);
|
|
110873
111139
|
}
|
|
110874
|
-
|
|
110875
|
-
|
|
110876
|
-
|
|
111140
|
+
perfStages.captureMs = Date.now() - stage4Start;
|
|
111141
|
+
perfStages.encodeMs = encodeResult.durationMs;
|
|
111142
|
+
} else {
|
|
111143
|
+
if (workerCount > 1) {
|
|
111144
|
+
const tasks = distributeFrames(job.totalFrames, workerCount, workDir);
|
|
111145
|
+
await executeParallelCapture(
|
|
111146
|
+
fileServer.url,
|
|
111147
|
+
workDir,
|
|
111148
|
+
tasks,
|
|
111149
|
+
buildHdrCaptureOptions(),
|
|
111150
|
+
() => createVideoFrameInjector(frameLookup),
|
|
111151
|
+
abortSignal,
|
|
111152
|
+
(progress) => {
|
|
111153
|
+
job.framesRendered = progress.capturedFrames;
|
|
111154
|
+
const frameProgress = progress.capturedFrames / progress.totalFrames;
|
|
111155
|
+
const progressPct = 25 + frameProgress * 45;
|
|
111156
|
+
if (progress.capturedFrames % 30 === 0 || progress.capturedFrames === progress.totalFrames) {
|
|
111157
|
+
updateJobStatus(
|
|
111158
|
+
job,
|
|
111159
|
+
"rendering",
|
|
111160
|
+
`Capturing frame ${progress.capturedFrames}/${progress.totalFrames} (${workerCount} workers)`,
|
|
111161
|
+
Math.round(progressPct),
|
|
111162
|
+
onProgress
|
|
111163
|
+
);
|
|
111164
|
+
}
|
|
111165
|
+
},
|
|
111166
|
+
void 0,
|
|
111167
|
+
cfg
|
|
111168
|
+
);
|
|
111169
|
+
await mergeWorkerFrames(workDir, tasks, framesDir);
|
|
111170
|
+
if (probeSession) {
|
|
111171
|
+
lastBrowserConsole = probeSession.browserConsoleBuffer;
|
|
111172
|
+
await closeCaptureSession(probeSession);
|
|
111173
|
+
probeSession = null;
|
|
110877
111174
|
}
|
|
110878
|
-
|
|
110879
|
-
|
|
110880
|
-
|
|
110881
|
-
|
|
110882
|
-
|
|
110883
|
-
|
|
110884
|
-
|
|
110885
|
-
|
|
110886
|
-
|
|
110887
|
-
|
|
110888
|
-
|
|
110889
|
-
|
|
110890
|
-
updateJobStatus(
|
|
110891
|
-
job,
|
|
110892
|
-
"rendering",
|
|
110893
|
-
`Streaming frame ${i + 1}/${job.totalFrames}`,
|
|
110894
|
-
Math.round(progress),
|
|
110895
|
-
onProgress
|
|
110896
|
-
);
|
|
111175
|
+
} else {
|
|
111176
|
+
const videoInjector = createVideoFrameInjector(frameLookup);
|
|
111177
|
+
const session = probeSession ?? await createCaptureSession(
|
|
111178
|
+
fileServer.url,
|
|
111179
|
+
framesDir,
|
|
111180
|
+
buildHdrCaptureOptions(),
|
|
111181
|
+
videoInjector,
|
|
111182
|
+
cfg
|
|
111183
|
+
);
|
|
111184
|
+
if (probeSession) {
|
|
111185
|
+
prepareCaptureSessionForReuse(session, framesDir, videoInjector);
|
|
111186
|
+
probeSession = null;
|
|
110897
111187
|
}
|
|
110898
|
-
|
|
110899
|
-
|
|
110900
|
-
|
|
110901
|
-
|
|
110902
|
-
|
|
110903
|
-
|
|
110904
|
-
|
|
110905
|
-
|
|
110906
|
-
|
|
110907
|
-
|
|
110908
|
-
|
|
110909
|
-
|
|
110910
|
-
|
|
110911
|
-
if (workerCount > 1) {
|
|
110912
|
-
const tasks = distributeFrames(job.totalFrames, workerCount, workDir);
|
|
110913
|
-
await executeParallelCapture(
|
|
110914
|
-
fileServer.url,
|
|
110915
|
-
workDir,
|
|
110916
|
-
tasks,
|
|
110917
|
-
{ ...captureOptions, skipReadinessVideoIds: Array.from(nativeHdrVideoIds) },
|
|
110918
|
-
() => createVideoFrameInjector(frameLookup),
|
|
110919
|
-
abortSignal,
|
|
110920
|
-
(progress) => {
|
|
110921
|
-
job.framesRendered = progress.capturedFrames;
|
|
110922
|
-
const frameProgress = progress.capturedFrames / progress.totalFrames;
|
|
110923
|
-
const progressPct = 25 + frameProgress * 45;
|
|
110924
|
-
if (progress.capturedFrames % 30 === 0 || progress.capturedFrames === progress.totalFrames) {
|
|
111188
|
+
try {
|
|
111189
|
+
if (!session.isInitialized) {
|
|
111190
|
+
await initializeSession(session);
|
|
111191
|
+
}
|
|
111192
|
+
assertNotAborted();
|
|
111193
|
+
lastBrowserConsole = session.browserConsoleBuffer;
|
|
111194
|
+
for (let i = 0; i < job.totalFrames; i++) {
|
|
111195
|
+
assertNotAborted();
|
|
111196
|
+
const time = i / job.config.fps;
|
|
111197
|
+
await captureFrame(session, i, time);
|
|
111198
|
+
job.framesRendered = i + 1;
|
|
111199
|
+
const frameProgress = (i + 1) / job.totalFrames;
|
|
111200
|
+
const progress = 25 + frameProgress * 45;
|
|
110925
111201
|
updateJobStatus(
|
|
110926
111202
|
job,
|
|
110927
111203
|
"rendering",
|
|
110928
|
-
`Capturing frame ${
|
|
110929
|
-
Math.round(
|
|
111204
|
+
`Capturing frame ${i + 1}/${job.totalFrames}`,
|
|
111205
|
+
Math.round(progress),
|
|
110930
111206
|
onProgress
|
|
110931
111207
|
);
|
|
110932
111208
|
}
|
|
110933
|
-
}
|
|
110934
|
-
|
|
110935
|
-
|
|
110936
|
-
|
|
110937
|
-
await mergeWorkerFrames(workDir, tasks, framesDir);
|
|
110938
|
-
if (probeSession) {
|
|
110939
|
-
lastBrowserConsole = probeSession.browserConsoleBuffer;
|
|
110940
|
-
await closeCaptureSession(probeSession);
|
|
110941
|
-
probeSession = null;
|
|
111209
|
+
} finally {
|
|
111210
|
+
lastBrowserConsole = session.browserConsoleBuffer;
|
|
111211
|
+
await closeCaptureSession(session);
|
|
111212
|
+
}
|
|
110942
111213
|
}
|
|
110943
|
-
|
|
110944
|
-
const
|
|
110945
|
-
|
|
110946
|
-
|
|
111214
|
+
perfStages.captureMs = Date.now() - stage4Start;
|
|
111215
|
+
const stage5Start = Date.now();
|
|
111216
|
+
updateJobStatus(job, "encoding", "Encoding video", 75, onProgress);
|
|
111217
|
+
const frameExt = needsAlpha ? "png" : "jpg";
|
|
111218
|
+
const framePattern = `frame_%06d.${frameExt}`;
|
|
111219
|
+
const encoderOpts = {
|
|
111220
|
+
fps: job.config.fps,
|
|
111221
|
+
width,
|
|
111222
|
+
height,
|
|
111223
|
+
codec: preset.codec,
|
|
111224
|
+
preset: preset.preset,
|
|
111225
|
+
quality: effectiveQuality,
|
|
111226
|
+
bitrate: effectiveBitrate,
|
|
111227
|
+
pixelFormat: preset.pixelFormat,
|
|
111228
|
+
useGpu: job.config.useGpu,
|
|
111229
|
+
hdr: preset.hdr
|
|
111230
|
+
};
|
|
111231
|
+
const encodeResult = enableChunkedEncode ? await encodeFramesChunkedConcat(
|
|
110947
111232
|
framesDir,
|
|
110948
|
-
|
|
110949
|
-
|
|
110950
|
-
|
|
111233
|
+
framePattern,
|
|
111234
|
+
videoOnlyPath,
|
|
111235
|
+
encoderOpts,
|
|
111236
|
+
chunkedEncodeSize,
|
|
111237
|
+
abortSignal
|
|
111238
|
+
) : await encodeFramesFromDir(
|
|
111239
|
+
framesDir,
|
|
111240
|
+
framePattern,
|
|
111241
|
+
videoOnlyPath,
|
|
111242
|
+
encoderOpts,
|
|
111243
|
+
abortSignal
|
|
110951
111244
|
);
|
|
110952
|
-
|
|
110953
|
-
|
|
110954
|
-
|
|
111245
|
+
assertNotAborted();
|
|
111246
|
+
if (!encodeResult.success) {
|
|
111247
|
+
throw new Error(`Encoding failed: ${encodeResult.error}`);
|
|
110955
111248
|
}
|
|
111249
|
+
perfStages.encodeMs = Date.now() - stage5Start;
|
|
111250
|
+
}
|
|
111251
|
+
} finally {
|
|
111252
|
+
if (streamingEncoder && !streamingEncoderClosed) {
|
|
110956
111253
|
try {
|
|
110957
|
-
|
|
110958
|
-
|
|
110959
|
-
|
|
110960
|
-
|
|
110961
|
-
|
|
110962
|
-
for (let i = 0; i < job.totalFrames; i++) {
|
|
110963
|
-
assertNotAborted();
|
|
110964
|
-
const time = i / job.config.fps;
|
|
110965
|
-
await captureFrame(session, i, time);
|
|
110966
|
-
job.framesRendered = i + 1;
|
|
110967
|
-
const frameProgress = (i + 1) / job.totalFrames;
|
|
110968
|
-
const progress = 25 + frameProgress * 45;
|
|
110969
|
-
updateJobStatus(
|
|
110970
|
-
job,
|
|
110971
|
-
"rendering",
|
|
110972
|
-
`Capturing frame ${i + 1}/${job.totalFrames}`,
|
|
110973
|
-
Math.round(progress),
|
|
110974
|
-
onProgress
|
|
110975
|
-
);
|
|
110976
|
-
}
|
|
110977
|
-
} finally {
|
|
110978
|
-
lastBrowserConsole = session.browserConsoleBuffer;
|
|
110979
|
-
await closeCaptureSession(session);
|
|
111254
|
+
await streamingEncoder.close();
|
|
111255
|
+
} catch (err) {
|
|
111256
|
+
log.warn("streamingEncoder defensive close failed", {
|
|
111257
|
+
err: err instanceof Error ? err.message : String(err)
|
|
111258
|
+
});
|
|
110980
111259
|
}
|
|
110981
111260
|
}
|
|
110982
|
-
perfStages.captureMs = Date.now() - stage4Start;
|
|
110983
|
-
const stage5Start = Date.now();
|
|
110984
|
-
updateJobStatus(job, "encoding", "Encoding video", 75, onProgress);
|
|
110985
|
-
const frameExt = needsAlpha ? "png" : "jpg";
|
|
110986
|
-
const framePattern = `frame_%06d.${frameExt}`;
|
|
110987
|
-
const encoderOpts = {
|
|
110988
|
-
fps: job.config.fps,
|
|
110989
|
-
width,
|
|
110990
|
-
height,
|
|
110991
|
-
codec: preset.codec,
|
|
110992
|
-
preset: preset.preset,
|
|
110993
|
-
quality: preset.quality,
|
|
110994
|
-
pixelFormat: preset.pixelFormat,
|
|
110995
|
-
useGpu: job.config.useGpu,
|
|
110996
|
-
hdr: preset.hdr
|
|
110997
|
-
};
|
|
110998
|
-
const encodeResult = enableChunkedEncode ? await encodeFramesChunkedConcat(
|
|
110999
|
-
framesDir,
|
|
111000
|
-
framePattern,
|
|
111001
|
-
videoOnlyPath,
|
|
111002
|
-
encoderOpts,
|
|
111003
|
-
chunkedEncodeSize,
|
|
111004
|
-
abortSignal
|
|
111005
|
-
) : await encodeFramesFromDir(
|
|
111006
|
-
framesDir,
|
|
111007
|
-
framePattern,
|
|
111008
|
-
videoOnlyPath,
|
|
111009
|
-
encoderOpts,
|
|
111010
|
-
abortSignal
|
|
111011
|
-
);
|
|
111012
|
-
assertNotAborted();
|
|
111013
|
-
if (!encodeResult.success) {
|
|
111014
|
-
throw new Error(`Encoding failed: ${encodeResult.error}`);
|
|
111015
|
-
}
|
|
111016
|
-
perfStages.encodeMs = Date.now() - stage5Start;
|
|
111017
111261
|
}
|
|
111018
111262
|
}
|
|
111019
111263
|
if (probeSession !== null) {
|
|
@@ -111177,7 +111421,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
111177
111421
|
|
|
111178
111422
|
// src/services/hyperframeLint.ts
|
|
111179
111423
|
import { existsSync as existsSync16, readFileSync as readFileSync11, statSync as statSync6 } from "node:fs";
|
|
111180
|
-
import { resolve as
|
|
111424
|
+
import { resolve as resolve12, join as join16 } from "node:path";
|
|
111181
111425
|
function isStringRecord(value) {
|
|
111182
111426
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
111183
111427
|
return false;
|
|
@@ -111204,7 +111448,7 @@ function pickEntryFile(files, preferredEntryFile) {
|
|
|
111204
111448
|
return null;
|
|
111205
111449
|
}
|
|
111206
111450
|
function readProjectEntryFile(projectDir, preferredEntryFile) {
|
|
111207
|
-
const absProjectDir =
|
|
111451
|
+
const absProjectDir = resolve12(projectDir);
|
|
111208
111452
|
if (!existsSync16(absProjectDir) || !statSync6(absProjectDir).isDirectory()) {
|
|
111209
111453
|
return { error: `Project directory not found: ${absProjectDir}` };
|
|
111210
111454
|
}
|
|
@@ -111212,7 +111456,7 @@ function readProjectEntryFile(projectDir, preferredEntryFile) {
|
|
|
111212
111456
|
(value) => typeof value === "string" && value.trim().length > 0
|
|
111213
111457
|
);
|
|
111214
111458
|
for (const entryFile of entryCandidates) {
|
|
111215
|
-
const absoluteEntryPath =
|
|
111459
|
+
const absoluteEntryPath = resolve12(absProjectDir, entryFile);
|
|
111216
111460
|
if (!absoluteEntryPath.startsWith(absProjectDir)) {
|
|
111217
111461
|
return { error: `Entry file must stay inside project directory: ${entryFile}` };
|
|
111218
111462
|
}
|
|
@@ -111277,10 +111521,10 @@ var Semaphore = class {
|
|
|
111277
111521
|
this.active++;
|
|
111278
111522
|
return () => this.release();
|
|
111279
111523
|
}
|
|
111280
|
-
return new Promise((
|
|
111524
|
+
return new Promise((resolve14) => {
|
|
111281
111525
|
this.queue.push(() => {
|
|
111282
111526
|
this.active++;
|
|
111283
|
-
|
|
111527
|
+
resolve14(() => this.release());
|
|
111284
111528
|
});
|
|
111285
111529
|
});
|
|
111286
111530
|
}
|
|
@@ -111315,12 +111559,12 @@ async function prepareRenderBody(body) {
|
|
|
111315
111559
|
const options = parseRenderOptions(body);
|
|
111316
111560
|
const projectDir = typeof body.projectDir === "string" ? body.projectDir : void 0;
|
|
111317
111561
|
if (projectDir) {
|
|
111318
|
-
const absProjectDir =
|
|
111562
|
+
const absProjectDir = resolve13(projectDir);
|
|
111319
111563
|
if (!existsSync17(absProjectDir) || !statSync7(absProjectDir).isDirectory()) {
|
|
111320
111564
|
return { error: `Project directory not found: ${absProjectDir}` };
|
|
111321
111565
|
}
|
|
111322
111566
|
const entry = options.entryFile || "index.html";
|
|
111323
|
-
if (!existsSync17(
|
|
111567
|
+
if (!existsSync17(resolve13(absProjectDir, entry))) {
|
|
111324
111568
|
return { error: `Entry file "${entry}" not found in project directory: ${absProjectDir}` };
|
|
111325
111569
|
}
|
|
111326
111570
|
return { prepared: { input: { projectDir: absProjectDir, ...options } } };
|
|
@@ -111361,7 +111605,7 @@ function resolveOutputPath(projectDir, outputCandidate, rendersDir, log) {
|
|
|
111361
111605
|
try {
|
|
111362
111606
|
return resolveRenderPaths(projectDir, outputCandidate, rendersDir).absoluteOutputPath;
|
|
111363
111607
|
} catch (error) {
|
|
111364
|
-
const fallbackPath =
|
|
111608
|
+
const fallbackPath = resolve13(rendersDir, `producer-fallback-${Date.now()}.mp4`);
|
|
111365
111609
|
log.warn("Failed to resolve output path, using fallback", {
|
|
111366
111610
|
fallback: fallbackPath,
|
|
111367
111611
|
error: error instanceof Error ? error.message : String(error)
|
|
@@ -111740,7 +111984,7 @@ function startServer(options = {}) {
|
|
|
111740
111984
|
process.on("SIGINT", () => shutdown("SIGINT"));
|
|
111741
111985
|
return server;
|
|
111742
111986
|
}
|
|
111743
|
-
var entryScript = process.argv[1] ?
|
|
111987
|
+
var entryScript = process.argv[1] ? resolve13(process.argv[1]) : "";
|
|
111744
111988
|
var isPublicServerEntry = entryScript.endsWith("/public-server.js") || entryScript.endsWith("/src/server.ts");
|
|
111745
111989
|
if (isPublicServerEntry) {
|
|
111746
111990
|
const { values } = parseArgs({
|