@hyperframes/producer 0.8.198 → 0.8.200
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/distributed.js +176 -166
- package/dist/hyperframe.manifest.json +1 -1
- package/dist/hyperframe.runtime.iife.js +65 -62
- package/dist/index.js +756 -451
- package/dist/public-server.js +566 -289
- package/dist/renderRequest.d.ts +1 -0
- package/dist/server.d.ts +1 -0
- package/dist/services/distributed/chunkWeights.d.ts +2 -0
- package/dist/services/hdrCompositor.d.ts +5 -5
- package/dist/services/hdrFrameWindows.d.ts +23 -0
- package/dist/services/htmlCompiler.d.ts +0 -2
- package/dist/services/render/audioPadTrim.d.ts +2 -0
- package/dist/services/render/renderEtaGuard.d.ts +35 -0
- package/dist/services/render/stages/captureHdrResources.d.ts +5 -17
- package/dist/services/render/stages/compileStage.d.ts +1 -1
- package/dist/services/render/stages/freezePlan.d.ts +1 -0
- package/dist/services/renderOrchestrator.d.ts +7 -6
- package/package.json +7 -7
package/dist/renderRequest.d.ts
CHANGED
package/dist/server.d.ts
CHANGED
|
@@ -9,6 +9,8 @@ export declare function planFrameWeights(input: {
|
|
|
9
9
|
width: number;
|
|
10
10
|
height: number;
|
|
11
11
|
}): Float64Array;
|
|
12
|
+
export declare function withChunkCaptureCost(slices: ChunkSliceJson[], weights: Float64Array): ChunkSliceJson[];
|
|
13
|
+
export declare function effectiveChunkFrames(frames: number, captureCost?: number): number;
|
|
12
14
|
/**
|
|
13
15
|
* Cut `[0, weights.length)` into `chunkCount` ranges of ~equal summed weight, each within
|
|
14
16
|
* `[minFrames, maxFrames]` where the frame count allows. `null` when the cost is uniform.
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
* `captureHdrHybridLoop.ts`, `captureHdrFrameShared.ts`,
|
|
11
11
|
* `captureHdrResources.ts`.
|
|
12
12
|
*/
|
|
13
|
+
import type { HdrFrameWindows } from "./hdrFrameWindows.js";
|
|
13
14
|
import { type CaptureSession, type BeforeCaptureHook, type HdrTransfer, type ElementStackingInfo, type HfTransitionMeta } from "@hyperframes/engine";
|
|
14
15
|
import type { ProducerLogger } from "../logger.js";
|
|
15
16
|
import { type HdrImageTransferCache } from "./hdrImageTransferCache.js";
|
|
@@ -34,21 +35,20 @@ export interface TransitionRange extends HdrTransitionMeta {
|
|
|
34
35
|
*/
|
|
35
36
|
export interface HdrVideoFrameSource {
|
|
36
37
|
dir: string;
|
|
37
|
-
|
|
38
|
-
fd: number;
|
|
38
|
+
windows: HdrFrameWindows;
|
|
39
39
|
width: number;
|
|
40
40
|
height: number;
|
|
41
41
|
frameSize: number;
|
|
42
|
-
frameCount: number;
|
|
42
|
+
readonly frameCount: number;
|
|
43
43
|
scratch: Buffer;
|
|
44
|
-
/** The
|
|
44
|
+
/** The playable range is one source cycle and must wrap at its end. */
|
|
45
45
|
loop?: boolean;
|
|
46
46
|
mediaStart?: number;
|
|
47
47
|
videoStreamLeadSeconds?: number;
|
|
48
48
|
}
|
|
49
49
|
export declare function closeHdrVideoFrameSource(source: HdrVideoFrameSource, log?: ProducerLogger): void;
|
|
50
50
|
export declare function resolveHdrVideoFrameIndex(time: number, startTime: number, fps: number, frameCount: number, loop?: boolean): number | null;
|
|
51
|
-
export declare function blitHdrVideoLayer(canvas: Buffer, el: ElementStackingInfo, time: number, fps: number, hdrVideoFrameSources: Map<string, HdrVideoFrameSource>, hdrStartTimes: Map<string, number>, width: number, height: number, log?: ProducerLogger, sourceTransfer?: HdrTransfer, targetTransfer?: HdrTransfer, hdrPerf?: HdrPerfCollector): void
|
|
51
|
+
export declare function blitHdrVideoLayer(canvas: Buffer, el: ElementStackingInfo, time: number, fps: number, hdrVideoFrameSources: Map<string, HdrVideoFrameSource>, hdrStartTimes: Map<string, number>, width: number, height: number, log?: ProducerLogger, sourceTransfer?: HdrTransfer, targetTransfer?: HdrTransfer, hdrPerf?: HdrPerfCollector): Promise<void>;
|
|
52
52
|
/**
|
|
53
53
|
* Pre-decoded HDR image buffer with its native pixel dimensions.
|
|
54
54
|
*
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface HdrFrameLease {
|
|
2
|
+
fd: number;
|
|
3
|
+
offset: number;
|
|
4
|
+
release(): void;
|
|
5
|
+
}
|
|
6
|
+
export interface HdrWindowSpec {
|
|
7
|
+
firstFrame: number;
|
|
8
|
+
frames: number;
|
|
9
|
+
path: string;
|
|
10
|
+
}
|
|
11
|
+
export interface HdrFrameWindows {
|
|
12
|
+
readonly totalFrames: number;
|
|
13
|
+
lease(frameIndex: number): Promise<HdrFrameLease | null>;
|
|
14
|
+
close(): void;
|
|
15
|
+
}
|
|
16
|
+
export declare function createHdrFrameWindows(opts: {
|
|
17
|
+
dir: string;
|
|
18
|
+
frameSize: number;
|
|
19
|
+
totalFrames: number;
|
|
20
|
+
windowFrames: number;
|
|
21
|
+
maxResident: number;
|
|
22
|
+
extract: (spec: HdrWindowSpec) => Promise<number>;
|
|
23
|
+
}): HdrFrameWindows;
|
|
@@ -20,8 +20,6 @@ export interface CompiledComposition {
|
|
|
20
20
|
hasShaderTransitions: boolean;
|
|
21
21
|
/** Author HTML/CSS/scripts use a CSS 3D rendering context (pre-CDN-inline scan). */
|
|
22
22
|
usesThreeDTransforms: boolean;
|
|
23
|
-
/** Author HTML/CSS use mix-blend-mode (pre-CDN-inline scan). */
|
|
24
|
-
usesMixBlendMode: boolean;
|
|
25
23
|
/** Ancestors of the composition root carry a background-image (gradient/url). */
|
|
26
24
|
hasAncestorBackgroundImage: boolean;
|
|
27
25
|
}
|
|
@@ -124,6 +124,8 @@ export declare function constrainAacTruePeak(input: {
|
|
|
124
124
|
targetDurationSeconds: number;
|
|
125
125
|
signal?: AbortSignal;
|
|
126
126
|
timeoutMs?: number;
|
|
127
|
+
probeTruePeakDbfs?: (audioPath: string, signal?: AbortSignal) => Promise<number>;
|
|
128
|
+
encodeAac?: AacEncoder;
|
|
127
129
|
}): Promise<{
|
|
128
130
|
success: boolean;
|
|
129
131
|
error?: string;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
interface RenderEtaInput {
|
|
2
|
+
/** Absent or 0 means no guard. */
|
|
3
|
+
maxRenderMs?: number;
|
|
4
|
+
/** Wall time since the render started, so time already spent counts. */
|
|
5
|
+
elapsedMs: number;
|
|
6
|
+
framesCompleted: number;
|
|
7
|
+
totalFrames: number;
|
|
8
|
+
/** Wall ms per frame across all workers. */
|
|
9
|
+
msPerFrame: number;
|
|
10
|
+
}
|
|
11
|
+
export declare class RenderTooSlowError extends Error {
|
|
12
|
+
readonly code: "RENDER_TOO_SLOW";
|
|
13
|
+
readonly owner: "user";
|
|
14
|
+
readonly retryable: false;
|
|
15
|
+
readonly publicMetadata: Readonly<Record<string, unknown>>;
|
|
16
|
+
constructor(stage: string, input: Required<RenderEtaInput> & {
|
|
17
|
+
etaMs: number;
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
/** The one ETA decision, shared by the post-calibration and the measured-rate checks. */
|
|
21
|
+
export declare function checkRenderEta(stage: string, input: RenderEtaInput): RenderTooSlowError | undefined;
|
|
22
|
+
interface RenderEtaGuardOptions {
|
|
23
|
+
maxRenderMs?: number;
|
|
24
|
+
job: {
|
|
25
|
+
framesRendered?: number;
|
|
26
|
+
};
|
|
27
|
+
totalFrames: number;
|
|
28
|
+
pipelineStartMs: number;
|
|
29
|
+
onTooSlow: (error: RenderTooSlowError) => void;
|
|
30
|
+
now?: () => number;
|
|
31
|
+
pollMs?: number;
|
|
32
|
+
}
|
|
33
|
+
/** Polls `job.framesRendered`, which every capture path updates, and trips once. Returns stop(). */
|
|
34
|
+
export declare function startRenderEtaGuard(options: RenderEtaGuardOptions): () => void;
|
|
35
|
+
export {};
|
|
@@ -58,19 +58,6 @@ export declare function probeHdrExtractionDims(args: {
|
|
|
58
58
|
composition: CompositionMetadata;
|
|
59
59
|
prep: HdrResourcePrep;
|
|
60
60
|
}): Promise<void>;
|
|
61
|
-
/**
|
|
62
|
-
* Total bytes the raw rgb48le pre-extraction below will write: 6 bytes/px ×
|
|
63
|
-
* frame area × frame count, summed across HDR videos. Exposed for the
|
|
64
|
-
* disk-headroom gate — a plain iPhone HLG clip auto-detected as HDR filled a
|
|
65
|
-
* near-full disk with 16-bit raw frames before the user found --sdr (wild
|
|
66
|
-
* report, CLI 0.7.52), so the commitment must be checked and surfaced BEFORE
|
|
67
|
-
* FFmpeg starts writing.
|
|
68
|
-
*/
|
|
69
|
-
export declare function estimateHdrExtractionBytes(videos: Array<{
|
|
70
|
-
durationSeconds: number;
|
|
71
|
-
width: number;
|
|
72
|
-
height: number;
|
|
73
|
-
}>, fps: number): number;
|
|
74
61
|
export declare function resolveHdrExtractionBudgetBytes(raw: string | undefined, cgroupLimitMb?: number | null): number | undefined;
|
|
75
62
|
export declare function resolveHdrExtractionActiveBudgetBytes(configuredBudgetBytes: number | undefined, freeBytes: number): number;
|
|
76
63
|
export declare function reserveHdrExtractionBytes(estimatedBytes: number, budgetBytes: number | undefined): () => void;
|
|
@@ -91,10 +78,9 @@ export interface HdrVideoExtractionResult {
|
|
|
91
78
|
releaseReservation: () => void;
|
|
92
79
|
}
|
|
93
80
|
/**
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
* remains held until the capture-stage finally block.
|
|
81
|
+
* Plan each HDR video's frame windows; a source extracts a window with one FFmpeg pass when the
|
|
82
|
+
* capture first reaches it. The caller owns teardown and the scratch reservation (resident
|
|
83
|
+
* windows only), held until the capture-stage finally block.
|
|
98
84
|
*/
|
|
99
85
|
export declare function extractHdrVideoFrames(args: {
|
|
100
86
|
job: RenderJob;
|
|
@@ -106,6 +92,8 @@ export declare function extractHdrVideoFrames(args: {
|
|
|
106
92
|
height: number;
|
|
107
93
|
abortSignal: AbortSignal | undefined;
|
|
108
94
|
hdrDiagnostics: HdrDiagnostics;
|
|
95
|
+
maxResidentWindows?: number;
|
|
96
|
+
windowBytes?: number;
|
|
109
97
|
runFfmpegImpl?: typeof runFfmpeg;
|
|
110
98
|
extractMediaMetadataImpl?: typeof extractMediaMetadata;
|
|
111
99
|
resolveFinalFrameExtractionWindowImpl?: typeof resolveFinalFrameExtractionWindow;
|
|
@@ -101,7 +101,7 @@ export interface CompileStageResult {
|
|
|
101
101
|
*/
|
|
102
102
|
forceScreenshot: boolean;
|
|
103
103
|
/** Low-cardinality compile-time gate that disabled default drawElement:
|
|
104
|
-
* `3d` | `
|
|
104
|
+
* `3d` | `ancestor_background_image` | `shader_transitions`. Undefined when none fired. */
|
|
105
105
|
deCompileGate?: string;
|
|
106
106
|
}
|
|
107
107
|
export declare function runCompileStage(input: CompileStageInput): Promise<CompileStageResult>;
|
|
@@ -87,6 +87,7 @@ export interface ChunkSliceJson {
|
|
|
87
87
|
startFrame: number;
|
|
88
88
|
/** Exclusive upper bound — chunk workers iterate frames in `[startFrame, endFrame)`. */
|
|
89
89
|
endFrame: number;
|
|
90
|
+
captureCost?: number;
|
|
90
91
|
}
|
|
91
92
|
/**
|
|
92
93
|
* Inputs to `freezePlan`. `planDir` already contains `compiled/`,
|
|
@@ -96,6 +96,8 @@ export interface RenderConfig {
|
|
|
96
96
|
motionBlur?: MotionBlurOptions;
|
|
97
97
|
pageMotionBlur?: "off";
|
|
98
98
|
workers?: number;
|
|
99
|
+
/** Wall-time budget in ms for the whole render. Absent or 0 disables the ETA guard. */
|
|
100
|
+
maxRenderMs?: number;
|
|
99
101
|
useGpu?: boolean;
|
|
100
102
|
debug?: boolean;
|
|
101
103
|
/** Strict rejects correctness warnings; best-effort returns a qualified outcome. */
|
|
@@ -288,7 +290,7 @@ export interface RenderPerfSummary {
|
|
|
288
290
|
drawElement?: {
|
|
289
291
|
/** Final capture mode: "drawelement" | "screenshot" | "beginframe" (|-joined if workers diverge). */
|
|
290
292
|
mode: string;
|
|
291
|
-
/** Compile-time gate that disabled default DE: 3d |
|
|
293
|
+
/** Compile-time gate that disabled default DE: 3d | ancestor_background_image | shader_transitions. */
|
|
292
294
|
compileGate?: string;
|
|
293
295
|
/** Producer clamp that disabled default DE: parallel | disk_path. */
|
|
294
296
|
clampReason?: string;
|
|
@@ -365,6 +367,7 @@ export interface RenderPerfSummary {
|
|
|
365
367
|
blankRecaptures: number;
|
|
366
368
|
/** Clip-cut boundary frames captured via per-frame screenshot. */
|
|
367
369
|
boundaryFrames: number;
|
|
370
|
+
riskFrames: number;
|
|
368
371
|
/** Per-frame "No cached paint record" screenshot fallbacks. */
|
|
369
372
|
ncprFallbacks: number;
|
|
370
373
|
/**
|
|
@@ -822,19 +825,17 @@ export declare function resolveDeShortBand(args: {
|
|
|
822
825
|
elementCountSource: "live" | "static";
|
|
823
826
|
}): "applied" | "skipped_elements" | "unmeasured" | undefined;
|
|
824
827
|
/**
|
|
825
|
-
* DE priority inversion predicate: should
|
|
826
|
-
*
|
|
828
|
+
* DE priority inversion predicate: should a multi-worker render drop to
|
|
829
|
+
* single-worker verified drawElement streaming?
|
|
827
830
|
*
|
|
828
831
|
* Benchmarked 2026-07-08: above ~900 frames DE-single beats screenshot-parallel
|
|
829
832
|
* at every worker count (2,380f: 66s vs 109–127s at W2–W5); below it DE's fixed
|
|
830
833
|
* init cost (verify + dedup arming) loses by a small margin. Only fires for the
|
|
831
834
|
* exact benchmarked configuration: default-on DE, mp4, streaming-eligible,
|
|
832
|
-
* no compile gate, no forced screenshot
|
|
835
|
+
* no compile gate, no forced screenshot.
|
|
833
836
|
*/
|
|
834
837
|
export declare function shouldPreferSingleWorkerDrawElement(args: {
|
|
835
838
|
workerCount: number;
|
|
836
|
-
/** job.config.workers — a number means the user explicitly chose. */
|
|
837
|
-
requestedWorkers: number | "auto" | undefined;
|
|
838
839
|
useDrawElement: boolean;
|
|
839
840
|
deCompileGate: string | undefined;
|
|
840
841
|
forceScreenshot: boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hyperframes/producer",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.200",
|
|
4
4
|
"description": "HTML-to-video rendering engine using Chrome's BeginFrame API",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -35,11 +35,11 @@
|
|
|
35
35
|
"postcss": "^8.4.0",
|
|
36
36
|
"puppeteer": "^25.2.1",
|
|
37
37
|
"puppeteer-core": "^25.2.1",
|
|
38
|
-
"@hyperframes/core": "0.8.
|
|
39
|
-
"@hyperframes/
|
|
40
|
-
"@hyperframes/lint": "0.8.
|
|
41
|
-
"@hyperframes/
|
|
42
|
-
"@hyperframes/
|
|
38
|
+
"@hyperframes/core": "0.8.200",
|
|
39
|
+
"@hyperframes/studio-server": "0.8.200",
|
|
40
|
+
"@hyperframes/lint": "0.8.200",
|
|
41
|
+
"@hyperframes/engine": "0.8.200",
|
|
42
|
+
"@hyperframes/parsers": "0.8.200"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@types/node": "^25.0.10",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"tsx": "^4.21.0",
|
|
49
49
|
"typescript": "^5.7.2",
|
|
50
50
|
"vitest": "^4.1.11",
|
|
51
|
-
"@hyperframes/aws-lambda": "0.8.
|
|
51
|
+
"@hyperframes/aws-lambda": "0.8.200"
|
|
52
52
|
},
|
|
53
53
|
"engines": {
|
|
54
54
|
"node": ">=22"
|