@hyperframes/producer 0.8.181 → 0.8.183
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.d.ts +2 -2
- package/dist/distributed.js +411 -220
- package/dist/hyperframe.manifest.json +1 -1
- package/dist/hyperframe.runtime.iife.js +17 -17
- package/dist/index.js +433 -238
- package/dist/public-server.js +155 -105
- package/dist/services/distributed/assemble.d.ts +2 -1
- package/dist/services/distributed/chunkFrames.d.ts +6 -1
- package/dist/services/distributed/mp4Stitch.d.ts +4 -4
- package/dist/services/distributed/plan.d.ts +11 -0
- package/dist/services/distributed/planV2.d.ts +1 -0
- package/dist/services/distributed/projectHash.d.ts +1 -4
- package/dist/services/render/artifactTransaction.d.ts +7 -0
- package/dist/services/render/audioPadTrim.d.ts +20 -15
- package/dist/services/render/audioTruePeak.d.ts +1 -5
- package/dist/services/render/perfSummary.d.ts +2 -0
- package/dist/services/render/stages/audioStage.d.ts +2 -0
- package/dist/services/render/stages/captureStage.d.ts +9 -3
- package/dist/services/render/stages/freezePlan.d.ts +1 -0
- package/dist/services/renderOrchestrator.d.ts +2 -2
- package/package.json +7 -7
|
@@ -22,6 +22,8 @@ export interface ArtifactTransactionFileSystem {
|
|
|
22
22
|
export interface ArtifactDurationProbeResult {
|
|
23
23
|
durationSeconds: number;
|
|
24
24
|
frames?: number;
|
|
25
|
+
width?: number;
|
|
26
|
+
height?: number;
|
|
25
27
|
}
|
|
26
28
|
/**
|
|
27
29
|
* Pluggable probe used by `ArtifactTransaction.validate()` when the caller
|
|
@@ -60,6 +62,9 @@ export interface ArtifactValidationExpectation {
|
|
|
60
62
|
expectedDurationSeconds: number;
|
|
61
63
|
fps?: number;
|
|
62
64
|
expectedFrames?: number;
|
|
65
|
+
/** The output size the render was asked for; a route that ignores it must not publish. */
|
|
66
|
+
expectedWidth?: number;
|
|
67
|
+
expectedHeight?: number;
|
|
63
68
|
toleranceSeconds?: number;
|
|
64
69
|
/** Path relative to the staging directory to run the duration probe against. */
|
|
65
70
|
probeTarget?: string;
|
|
@@ -84,6 +89,8 @@ export declare function buildArtifactExpectation(input: {
|
|
|
84
89
|
durationSeconds: number;
|
|
85
90
|
fps: number;
|
|
86
91
|
expectedFrames: number | undefined;
|
|
92
|
+
width?: number;
|
|
93
|
+
height?: number;
|
|
87
94
|
}): ArtifactValidationExpectation | undefined;
|
|
88
95
|
/**
|
|
89
96
|
* Stages a render beside its final destination and promotes only a validated
|
|
@@ -54,12 +54,16 @@ export interface PadTrimAudioInput {
|
|
|
54
54
|
probeVideoFrameInfo?: (videoPath: string) => Promise<ProbeVideoFrameInfo>;
|
|
55
55
|
probeAudioInfo?: (audioPath: string, signal?: AbortSignal) => Promise<AudioProbeInfo>;
|
|
56
56
|
probeAudioTruePeakDbfs?: (audioPath: string, signal?: AbortSignal) => Promise<number>;
|
|
57
|
-
runFfmpeg?: (args: string[]) => Promise<
|
|
58
|
-
|
|
59
|
-
error?: string;
|
|
60
|
-
failureReason?: "external_interruption";
|
|
61
|
-
}>;
|
|
57
|
+
runFfmpeg?: (args: string[]) => Promise<StepResult>;
|
|
58
|
+
encodeAac?: AacEncoder;
|
|
62
59
|
}
|
|
60
|
+
interface StepResult {
|
|
61
|
+
success: boolean;
|
|
62
|
+
error?: string;
|
|
63
|
+
failureReason?: "external_interruption";
|
|
64
|
+
}
|
|
65
|
+
/** Encodes `filter` applied to `inputPath` as AAC of exactly `durationSeconds`. */
|
|
66
|
+
type AacEncoder = (inputPath: string, outputPath: string, durationSeconds: number, filter: string) => Promise<StepResult>;
|
|
63
67
|
export type PadTrimOperation = "pad" | "trim" | "copy";
|
|
64
68
|
export interface PadTrimAudioResult {
|
|
65
69
|
success: boolean;
|
|
@@ -77,19 +81,21 @@ export interface PadTrimAudioResult {
|
|
|
77
81
|
/** dB the true-peak limiter lowered the whole mix by; absent when it did not engage. */
|
|
78
82
|
audioLoweredDb?: number;
|
|
79
83
|
}
|
|
80
|
-
export type
|
|
81
|
-
|
|
82
|
-
kind: PadTrimAudioStepKind;
|
|
84
|
+
export type PadTrimAudioStep = {
|
|
85
|
+
kind: "copy";
|
|
83
86
|
args: string[];
|
|
84
|
-
}
|
|
87
|
+
} | {
|
|
88
|
+
kind: "trim" | "normalize";
|
|
89
|
+
filter: string;
|
|
90
|
+
};
|
|
85
91
|
export interface PadTrimAudioPlan {
|
|
86
92
|
operation: PadTrimOperation;
|
|
87
93
|
steps: PadTrimAudioStep[];
|
|
88
94
|
cleanupPaths: string[];
|
|
89
95
|
}
|
|
90
96
|
/**
|
|
91
|
-
* Pure helper: decide the pad/trim operation and
|
|
92
|
-
*
|
|
97
|
+
* Pure helper: decide the pad/trim operation and the steps that
|
|
98
|
+
* materialize it. Exported separately so unit tests can pin
|
|
93
99
|
* every branch without spawning ffmpeg.
|
|
94
100
|
*
|
|
95
101
|
* - `sourceDuration < targetDuration` → pad with `apad` to the exact target
|
|
@@ -102,10 +108,6 @@ export interface PadTrimAudioPlan {
|
|
|
102
108
|
* run ffmpeg with `-c:a copy` to materialize the output path.
|
|
103
109
|
*/
|
|
104
110
|
export declare function buildPadTrimAudioPlan(audioPath: string, outputPath: string, sourceDurationSeconds: number, targetDurationSeconds: number): PadTrimAudioPlan;
|
|
105
|
-
export declare function buildPadTrimAudioArgs(audioPath: string, outputPath: string, sourceDurationSeconds: number, targetDurationSeconds: number): {
|
|
106
|
-
args: string[];
|
|
107
|
-
operation: PadTrimOperation;
|
|
108
|
-
};
|
|
109
111
|
/**
|
|
110
112
|
* Pad or trim the mixed audio so its exact duration matches `frameCount / fps`
|
|
111
113
|
* for the assembled video.
|
|
@@ -117,6 +119,8 @@ export declare function padOrTrimAudioToVideoFrameCount(input: PadTrimAudioInput
|
|
|
117
119
|
*/
|
|
118
120
|
export declare function constrainAacTruePeak(input: {
|
|
119
121
|
audioPath: string;
|
|
122
|
+
/** The PCM `audioPath` was encoded from: a correction re-encodes it instead of decoding the AAC. */
|
|
123
|
+
sourcePath?: string;
|
|
120
124
|
targetDurationSeconds: number;
|
|
121
125
|
signal?: AbortSignal;
|
|
122
126
|
timeoutMs?: number;
|
|
@@ -128,3 +132,4 @@ export declare function constrainAacTruePeak(input: {
|
|
|
128
132
|
}>;
|
|
129
133
|
export declare function defaultProbeVideoFrameInfo(videoPath: string, signal?: AbortSignal): Promise<ProbeVideoFrameInfo>;
|
|
130
134
|
export declare function runFfprobeJson<T>(args: string[], signal?: AbortSignal): Promise<T>;
|
|
135
|
+
export {};
|
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The true peak one `ebur128=peak=true` pass over the whole file reports, measured in parallel
|
|
3
|
-
* segments when the
|
|
3
|
+
* segments when the file is 48 kHz with a known length: the same digit, not an estimate.
|
|
4
4
|
*/
|
|
5
5
|
export declare function measureTruePeakDbfs(audioPath: string, options: {
|
|
6
6
|
timeoutMs: number;
|
|
7
7
|
signal?: AbortSignal;
|
|
8
|
-
segments?: {
|
|
9
|
-
durationSeconds: number;
|
|
10
|
-
sampleRate: number;
|
|
11
|
-
};
|
|
12
8
|
}): Promise<number>;
|
|
@@ -50,6 +50,8 @@ export declare function roundDb(value: number | undefined): number | undefined;
|
|
|
50
50
|
export interface DrawElementPerfInput {
|
|
51
51
|
compileGate?: string;
|
|
52
52
|
clampReason?: string;
|
|
53
|
+
/** Engine init-time gate the pre-capture probe hit; its session may be closed before capture. */
|
|
54
|
+
probeGateReason?: string;
|
|
53
55
|
workerInversion?: "inverted" | "reverted";
|
|
54
56
|
/** Auto-resolved worker count before the inversion pinned it to 1 (set only when the inversion fired). */
|
|
55
57
|
preInversionWorkers?: number;
|
|
@@ -34,6 +34,8 @@ export interface AudioStageInput {
|
|
|
34
34
|
audios: CompositionMetadata["audios"];
|
|
35
35
|
masterFxChain?: string;
|
|
36
36
|
urlByAbsentLocalPath?: ReadonlyMap<string, string>;
|
|
37
|
+
/** Keep the float mix the AAC was encoded from here, for a later re-encode from it. */
|
|
38
|
+
keepEncoderInputAt?: string;
|
|
37
39
|
abortSignal: AbortSignal | undefined;
|
|
38
40
|
assertNotAborted: () => void;
|
|
39
41
|
/** Where a per-track failure's detail goes. Optional so tests need not pass one. */
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
import { type BeforeCaptureHook, type CaptureOptions, type CapturePerfSummary, type CaptureSession, type EngineConfig } from "@hyperframes/engine";
|
|
38
38
|
import type { FileServerHandle } from "../../fileServer.js";
|
|
39
39
|
import type { ProducerLogger } from "../../../logger.js";
|
|
40
|
-
import { type CaptureAttemptSummary, type ProgressCallback, type RenderJob } from "../../renderOrchestrator.js";
|
|
40
|
+
import { type CaptureAttemptSummary, type ProgressCallback, type RenderConfig, type RenderJob } from "../../renderOrchestrator.js";
|
|
41
41
|
import type { SdrDiskCapturePlan } from "../capturePlan.js";
|
|
42
42
|
export interface CaptureStageInput {
|
|
43
43
|
fileServer: FileServerHandle;
|
|
@@ -121,8 +121,13 @@ export type DiskCaptureHeadroom = {
|
|
|
121
121
|
};
|
|
122
122
|
/** Shared 90% disk gate used by both fallback planning and disk execution. */
|
|
123
123
|
export declare function inspectDiskCaptureHeadroom(framesDir: string, totalFrames: number, captureOptions: CaptureOptions, freeDiskBytes?: (path: string) => number | null): DiskCaptureHeadroom;
|
|
124
|
-
|
|
125
|
-
|
|
124
|
+
/**
|
|
125
|
+
* Why this render stores frames and what would take it off disk. `--workers 1`
|
|
126
|
+
* is offered only when a one-worker run of the same render would stream.
|
|
127
|
+
*/
|
|
128
|
+
export declare function diskCaptureRemedy(cfg: EngineConfig, outputFormat: NonNullable<RenderConfig["format"]>, durationSeconds: number, workerCount: number): string;
|
|
129
|
+
export declare function diskCaptureShortfallError(needBytes: number, freeBytes: number, framesDir: string, basis: "estimate" | "measured", remedy: string): Error;
|
|
130
|
+
export declare function assertDiskCaptureHeadroom(framesDir: string, totalFrames: number, captureOptions: CaptureOptions, remedy: string, freeDiskBytes?: (path: string) => number | null): void;
|
|
126
131
|
/** Frame bytes written so far: the merged frames dir plus every capture attempt's worker dirs. */
|
|
127
132
|
export declare function measureCaptureFrameBytes(workDir: string, framesDir: string): number;
|
|
128
133
|
/** Per-frame callback: after the sample frames, throws if the projected remainder exceeds 90% of free space. */
|
|
@@ -130,6 +135,7 @@ export declare function createDiskCaptureProjection(input: {
|
|
|
130
135
|
framesDir: string;
|
|
131
136
|
totalFrames: number;
|
|
132
137
|
measureBytes: () => number;
|
|
138
|
+
remedy: string;
|
|
133
139
|
freeDiskBytes?: (path: string) => number | null;
|
|
134
140
|
}): (capturedFrames: number) => void;
|
|
135
141
|
export declare function runCaptureStage(input: CaptureStageInput): Promise<CaptureStageResult>;
|
|
@@ -1152,8 +1152,8 @@ export declare function closeOrphanedProbeForRetry(probe: CaptureSession, closer
|
|
|
1152
1152
|
*/
|
|
1153
1153
|
export declare function resolveParallelCaptureMode(args: {
|
|
1154
1154
|
platform: NodeJS.Platform;
|
|
1155
|
-
/**
|
|
1156
|
-
|
|
1155
|
+
/** The chrome-headless-shell binary resolved for this render, if any. */
|
|
1156
|
+
headlessShellPath: string | undefined;
|
|
1157
1157
|
forceScreenshot: boolean;
|
|
1158
1158
|
deviceScaleFactor?: number;
|
|
1159
1159
|
}): "screenshot" | "beginframe";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hyperframes/producer",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.183",
|
|
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/
|
|
41
|
-
"@hyperframes/
|
|
42
|
-
"@hyperframes/
|
|
38
|
+
"@hyperframes/core": "0.8.183",
|
|
39
|
+
"@hyperframes/engine": "0.8.183",
|
|
40
|
+
"@hyperframes/parsers": "0.8.183",
|
|
41
|
+
"@hyperframes/studio-server": "0.8.183",
|
|
42
|
+
"@hyperframes/lint": "0.8.183"
|
|
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.183"
|
|
52
52
|
},
|
|
53
53
|
"engines": {
|
|
54
54
|
"node": ">=22"
|