@hyperframes/producer 0.8.179 → 0.8.180
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 +52 -19
- package/dist/hyperframe.manifest.json +1 -1
- package/dist/hyperframe.runtime.iife.js +54 -54
- package/dist/index.js +51 -19
- package/dist/public-server.js +2 -1
- package/dist/services/distributed/assemble.d.ts +4 -2
- package/dist/services/distributed/chunkAudio.d.ts +8 -0
- package/dist/services/distributed/chunkFrames.d.ts +2 -1
- package/dist/services/distributed/planProtocol.d.ts +1 -0
- package/dist/services/distributed/planV2Execution.d.ts +4 -4
- package/dist/services/distributed/renderChunk.d.ts +23 -3
- package/package.json +7 -7
package/dist/distributed.d.ts
CHANGED
|
@@ -33,8 +33,8 @@ export { buildChunkSlices, measurePlanDirBytes, plan, rejectUnsupportedDistribut
|
|
|
33
33
|
export { createPlanV2FromExecutionPlan, createPlanV2FromV1, getPlanV2ExecutionPlanHash, isPlanV2DeferredSourceArtifact, listPlanV2ArtifactsForTarget, materializePlanV2Target, planV2, planV2WithPublisher, publishPlanV2FromExecutionPlan, publishPlanV2FromV1, readPlanV2Manifest, validatePlanV2MaterializedTarget, PLAN_V2_INTEGRITY_UNRECOVERABLE, PLAN_V2_MATERIALIZATION_MARKER, PlanV2IntegrityError, type PlanV2Artifact, type PlanV2Limitations, type PlanV2Manifest, type PlanV2MaterializeOptions, type PlanV2MaterializationResult, type PlanV2MaterializationTarget, type PlanV2RemoteSources, type PlanV2Result, type PlanV2WithPublisherOptions, } from "./services/distributed/planV2.js";
|
|
34
34
|
export { LocalPlanV2ArtifactPublisher, type LocalPlanV2ArtifactPublisherOptions, type PlanV2ArtifactPublisher, type PlanV2PublishBlob, } from "./services/distributed/planV2Publisher.js";
|
|
35
35
|
export { assembleV2, renderChunkV2 } from "./services/distributed/planV2Execution.js";
|
|
36
|
-
export { applyRuntimeEnvSnapshot, readWebGlVendorInfoFromCanvas, renderChunk, type ChunkRenderer, type ChunkResult, type EffectiveChunkResult, FFMPEG_VERSION_MISMATCH, INVALID_VIDEO_METADATA, PLAN_HASH_MISMATCH, RenderChunkValidationError, } from "./services/distributed/renderChunk.js";
|
|
37
|
-
export { assemble, chunksAreStitchedMp4, type AssembleResult, } from "./services/distributed/assemble.js";
|
|
36
|
+
export { applyRuntimeEnvSnapshot, readWebGlVendorInfoFromCanvas, renderChunk, type ChunkFrameRange, type ChunkRenderer, type ChunkResult, type EffectiveChunkResult, type RenderChunkOptions, CHUNK_FRAME_RANGE_INVALID, FFMPEG_VERSION_MISMATCH, INVALID_VIDEO_METADATA, PLAN_HASH_MISMATCH, RenderChunkValidationError, } from "./services/distributed/renderChunk.js";
|
|
37
|
+
export { assemble, chunksAreStitchedMp4, type AssembleChunkPaths, type AssembleResult, } from "./services/distributed/assemble.js";
|
|
38
38
|
export { muxChunkWithAudio } from "./services/distributed/chunkAudio.js";
|
|
39
39
|
export { buildStitchedHeader, readMp4Layout, type Mp4Layout, type ReadRange, } from "./services/distributed/mp4Stitch.js";
|
|
40
40
|
export { InvalidConfigError, type SerializableDistributedRenderConfig, validateDistributedRenderConfig, validateVariablesPayload, } from "./services/distributed/renderConfigValidation.js";
|
package/dist/distributed.js
CHANGED
|
@@ -6773,6 +6773,7 @@ var FFMPEG_VERSION_MISMATCH = "FFMPEG_VERSION_MISMATCH";
|
|
|
6773
6773
|
var PLAN_HASH_MISMATCH = "PLAN_HASH_MISMATCH";
|
|
6774
6774
|
var MISSING_PLAN_ARTIFACT = "MISSING_PLAN_ARTIFACT";
|
|
6775
6775
|
var CHUNK_INDEX_OUT_OF_RANGE = "CHUNK_INDEX_OUT_OF_RANGE";
|
|
6776
|
+
var CHUNK_FRAME_RANGE_INVALID = "CHUNK_FRAME_RANGE_INVALID";
|
|
6776
6777
|
var MISSING_RUNTIME_ENV_SNAPSHOT = "MISSING_RUNTIME_ENV_SNAPSHOT";
|
|
6777
6778
|
var RenderChunkValidationError = class extends Error {
|
|
6778
6779
|
code;
|
|
@@ -7024,7 +7025,8 @@ var DISTRIBUTED_RENDER_CAPABILITIES = Object.freeze({
|
|
|
7024
7025
|
accepts: Object.freeze([PLAN_PROTOCOL_V1, PLAN_PROTOCOL_V2]),
|
|
7025
7026
|
acceptsLegacyV1WithoutDescriptor: true
|
|
7026
7027
|
})
|
|
7027
|
-
})
|
|
7028
|
+
}),
|
|
7029
|
+
chunkFrameRange: true
|
|
7028
7030
|
});
|
|
7029
7031
|
function getDistributedRenderCapabilities() {
|
|
7030
7032
|
return DISTRIBUTED_RENDER_CAPABILITIES;
|
|
@@ -7739,6 +7741,18 @@ function audioCutForChunk(grid, chunks, index, fps) {
|
|
|
7739
7741
|
const durationSeconds = end === grid.packetCount ? null : cutSeconds(end) - (seekSeconds ?? 0);
|
|
7740
7742
|
return { seekSeconds, durationSeconds, firstPacket: first, packetCount: end - first };
|
|
7741
7743
|
}
|
|
7744
|
+
function chunksWithSubRange(chunks, index, range) {
|
|
7745
|
+
const slice = chunks[index];
|
|
7746
|
+
const parts = [
|
|
7747
|
+
{ startFrame: slice.startFrame, endFrame: range.startFrame },
|
|
7748
|
+
range,
|
|
7749
|
+
{ startFrame: range.endFrame, endFrame: slice.endFrame }
|
|
7750
|
+
].filter((part) => part.endFrame > part.startFrame);
|
|
7751
|
+
const split = [...chunks.slice(0, index), ...parts, ...chunks.slice(index + 1)].map(
|
|
7752
|
+
(chunk, i) => ({ index: i, startFrame: chunk.startFrame, endFrame: chunk.endFrame })
|
|
7753
|
+
);
|
|
7754
|
+
return { chunks: split, index: range.startFrame > slice.startFrame ? index + 1 : index };
|
|
7755
|
+
}
|
|
7742
7756
|
async function probeAacPacketGrid(audioPath) {
|
|
7743
7757
|
const probe = await runFfprobeJson([
|
|
7744
7758
|
"-v",
|
|
@@ -9699,11 +9713,12 @@ function cfrRateControlArgs(locked) {
|
|
|
9699
9713
|
}
|
|
9700
9714
|
return ["-preset", preset.preset, "-crf", String(locked.crf ?? preset.quality)];
|
|
9701
9715
|
}
|
|
9702
|
-
async function assemble(planDir,
|
|
9716
|
+
async function assemble(planDir, chunkOutputs, audioPath, outputPath, options) {
|
|
9703
9717
|
const start = Date.now();
|
|
9704
9718
|
const log = options?.logger ?? defaultLogger;
|
|
9705
9719
|
const cfr = options?.cfr === true;
|
|
9706
|
-
const plan2 = readAssemblePlan(planDir,
|
|
9720
|
+
const plan2 = readAssemblePlan(planDir, chunkOutputs);
|
|
9721
|
+
const chunkPaths = chunkOutputs.flat();
|
|
9707
9722
|
if (plan2.dimensions.format === "png-sequence") {
|
|
9708
9723
|
return mergePngFrameDirs(chunkPaths, outputPath, plan2.totalFrames, audioPath, start);
|
|
9709
9724
|
}
|
|
@@ -9786,7 +9801,12 @@ function readAssemblePlan(planDir, chunkPaths) {
|
|
|
9786
9801
|
`[assemble] chunkPaths length (${chunkPaths.length}) does not match chunks.json length (${chunks.length}). Adapters must pass one path per chunk, ordered by index.`
|
|
9787
9802
|
);
|
|
9788
9803
|
}
|
|
9789
|
-
for (const
|
|
9804
|
+
for (const [index, entry] of chunkPaths.entries()) {
|
|
9805
|
+
if (typeof entry !== "string" && entry.length === 0) {
|
|
9806
|
+
throw new Error(`[assemble] chunk ${index} has an empty list of parts`);
|
|
9807
|
+
}
|
|
9808
|
+
}
|
|
9809
|
+
for (const path of chunkPaths.flat()) {
|
|
9790
9810
|
if (!existsSync18(path)) {
|
|
9791
9811
|
throw new Error(`[assemble] chunk path does not exist: ${path}`);
|
|
9792
9812
|
}
|
|
@@ -10005,6 +10025,17 @@ function validatePlanVideosForChunk(value) {
|
|
|
10005
10025
|
);
|
|
10006
10026
|
}
|
|
10007
10027
|
}
|
|
10028
|
+
function resolveChunkFrameRange(slice, chunkIndex, frameRange) {
|
|
10029
|
+
if (frameRange === void 0) return { startFrame: slice.startFrame, endFrame: slice.endFrame };
|
|
10030
|
+
const { startFrame, endFrame } = frameRange;
|
|
10031
|
+
if (!Number.isSafeInteger(startFrame) || !Number.isSafeInteger(endFrame) || startFrame < slice.startFrame || endFrame > slice.endFrame || endFrame <= startFrame) {
|
|
10032
|
+
throw new RenderChunkValidationError(
|
|
10033
|
+
CHUNK_FRAME_RANGE_INVALID,
|
|
10034
|
+
`[renderChunk] frameRange ${JSON.stringify(frameRange)} must be a non-empty integer range inside chunk ${chunkIndex}'s slice [${slice.startFrame}, ${slice.endFrame})`
|
|
10035
|
+
);
|
|
10036
|
+
}
|
|
10037
|
+
return { startFrame, endFrame };
|
|
10038
|
+
}
|
|
10008
10039
|
var distributedCaptureSessionDependencies = {
|
|
10009
10040
|
createCaptureSession: createCaptureSession9,
|
|
10010
10041
|
assertSwiftShader,
|
|
@@ -10075,7 +10106,7 @@ function resolveLockedVp9CpuUsed(lockedEncoder) {
|
|
|
10075
10106
|
if (lockedEncoder.encoder !== "libvpx-vp9-software") return void 0;
|
|
10076
10107
|
return lockedEncoder.vp9CpuUsed ?? LEGACY_DISTRIBUTED_VP9_CPU_USED;
|
|
10077
10108
|
}
|
|
10078
|
-
async function renderChunk(planDir, chunkIndex, outputChunkPath) {
|
|
10109
|
+
async function renderChunk(planDir, chunkIndex, outputChunkPath, options) {
|
|
10079
10110
|
const start = Date.now();
|
|
10080
10111
|
const log = defaultLogger;
|
|
10081
10112
|
const planJsonPath = join27(planDir, "plan.json");
|
|
@@ -10129,13 +10160,15 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath) {
|
|
|
10129
10160
|
if (slice === void 0) {
|
|
10130
10161
|
throw new RenderChunkValidationError(CHUNK_INDEX_OUT_OF_RANGE, "[renderChunk] missing slice");
|
|
10131
10162
|
}
|
|
10132
|
-
const
|
|
10133
|
-
if (
|
|
10163
|
+
const sliceFrames = slice.endFrame - slice.startFrame;
|
|
10164
|
+
if (sliceFrames <= 0) {
|
|
10134
10165
|
throw new RenderChunkValidationError(
|
|
10135
10166
|
CHUNK_INDEX_OUT_OF_RANGE,
|
|
10136
|
-
`[renderChunk] chunk ${chunkIndex} has non-positive frame count: ${
|
|
10167
|
+
`[renderChunk] chunk ${chunkIndex} has non-positive frame count: ${sliceFrames}`
|
|
10137
10168
|
);
|
|
10138
10169
|
}
|
|
10170
|
+
const range = resolveChunkFrameRange(slice, chunkIndex, options?.frameRange);
|
|
10171
|
+
const framesInChunk = range.endFrame - range.startFrame;
|
|
10139
10172
|
const compiledDir = join27(planDir, "compiled");
|
|
10140
10173
|
if (!existsSync19(compiledDir)) {
|
|
10141
10174
|
throw new RenderChunkValidationError(
|
|
@@ -10200,10 +10233,7 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath) {
|
|
|
10200
10233
|
const deferredVideoFrames = planVideos ? await extractDeferredVideoFramesForChunk({
|
|
10201
10234
|
planDir,
|
|
10202
10235
|
planVideos,
|
|
10203
|
-
frames: Array.from(
|
|
10204
|
-
{ length: slice.endFrame - slice.startFrame },
|
|
10205
|
-
(_, i) => slice.startFrame + i
|
|
10206
|
-
),
|
|
10236
|
+
frames: Array.from({ length: framesInChunk }, (_, i) => range.startFrame + i),
|
|
10207
10237
|
fps: { num: plan2.dimensions.fpsNum, den: plan2.dimensions.fpsDen },
|
|
10208
10238
|
outputRoot: videoFramesDir,
|
|
10209
10239
|
cfg,
|
|
@@ -10359,7 +10389,7 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath) {
|
|
|
10359
10389
|
abortSignal: void 0,
|
|
10360
10390
|
assertNotAborted: () => {
|
|
10361
10391
|
},
|
|
10362
|
-
frameRange:
|
|
10392
|
+
frameRange: range
|
|
10363
10393
|
});
|
|
10364
10394
|
const observedModes = new Set(capturePerfs.map((perf) => perf.captureMode));
|
|
10365
10395
|
if (observedModes.size !== 1 || ![...observedModes].every(isCaptureMode)) {
|
|
@@ -10453,12 +10483,13 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath) {
|
|
|
10453
10483
|
});
|
|
10454
10484
|
if (encoder.chunksCarryAudio) {
|
|
10455
10485
|
const audioScratchPath = `${outputChunkPath}.audio.m4a`;
|
|
10486
|
+
const audioChunks = options?.frameRange ? chunksWithSubRange(chunks, chunkIndex, range) : { chunks, index: chunkIndex };
|
|
10456
10487
|
await muxChunkWithAudio({
|
|
10457
10488
|
videoPath: videoOnlyPath,
|
|
10458
10489
|
audioPath: chunkAudioSource(planDir, chunkIndex, audioScratchPath),
|
|
10459
10490
|
outputPath: outputChunkPath,
|
|
10460
|
-
chunks,
|
|
10461
|
-
chunkIndex,
|
|
10491
|
+
chunks: audioChunks.chunks,
|
|
10492
|
+
chunkIndex: audioChunks.index,
|
|
10462
10493
|
fps: { num: plan2.dimensions.fpsNum, den: plan2.dimensions.fpsDen },
|
|
10463
10494
|
timeoutMs: cfg.ffmpegProcessTimeout
|
|
10464
10495
|
});
|
|
@@ -10487,8 +10518,8 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath) {
|
|
|
10487
10518
|
const perfPayload = {
|
|
10488
10519
|
planHash: plan2.planHash,
|
|
10489
10520
|
chunkIndex,
|
|
10490
|
-
startFrame:
|
|
10491
|
-
endFrame:
|
|
10521
|
+
startFrame: range.startFrame,
|
|
10522
|
+
endFrame: range.endFrame,
|
|
10492
10523
|
framesEncoded,
|
|
10493
10524
|
durationMs,
|
|
10494
10525
|
planHashMs,
|
|
@@ -10517,6 +10548,7 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath) {
|
|
|
10517
10548
|
outputPath: outputChunkPath,
|
|
10518
10549
|
outputKind,
|
|
10519
10550
|
framesEncoded,
|
|
10551
|
+
frameRange: range,
|
|
10520
10552
|
sha256,
|
|
10521
10553
|
durationMs,
|
|
10522
10554
|
planHashMs,
|
|
@@ -10533,12 +10565,12 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath) {
|
|
|
10533
10565
|
}
|
|
10534
10566
|
|
|
10535
10567
|
// src/services/distributed/planV2Execution.ts
|
|
10536
|
-
async function renderChunkV2(planV2Dir, chunkIndex, outputChunkPath) {
|
|
10568
|
+
async function renderChunkV2(planV2Dir, chunkIndex, outputChunkPath, options) {
|
|
10537
10569
|
const workRoot = mkdtempSync7(join28(tmpdir2(), "hf-plan-v2-chunk-"));
|
|
10538
10570
|
const materializedPlanDir = join28(workRoot, "plan");
|
|
10539
10571
|
try {
|
|
10540
10572
|
materializePlanV2Target(planV2Dir, { role: "chunk", chunkIndex }, materializedPlanDir);
|
|
10541
|
-
return await renderChunk(materializedPlanDir, chunkIndex, outputChunkPath);
|
|
10573
|
+
return await renderChunk(materializedPlanDir, chunkIndex, outputChunkPath, options);
|
|
10542
10574
|
} finally {
|
|
10543
10575
|
rmSync13(workRoot, { recursive: true, force: true });
|
|
10544
10576
|
}
|
|
@@ -10852,6 +10884,7 @@ function hashProjectDir(projectDir, files = listSiteFiles(projectDir)) {
|
|
|
10852
10884
|
}
|
|
10853
10885
|
export {
|
|
10854
10886
|
CHUNK_EXCEEDS_WORKER_TIMEOUT,
|
|
10887
|
+
CHUNK_FRAME_RANGE_INVALID,
|
|
10855
10888
|
CURRENT_PLAN_PROTOCOL,
|
|
10856
10889
|
ChunkExceedsWorkerTimeoutError,
|
|
10857
10890
|
DEFAULT_CHUNK_SIZE,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": "0.1.0",
|
|
3
3
|
"buildId": "dev",
|
|
4
|
-
"sha256": "
|
|
4
|
+
"sha256": "2ae4b2eb24c5dea85f83bd9af6c14abc153ad59fc3f338d1ca9142d9df0c662e",
|
|
5
5
|
"artifacts": {
|
|
6
6
|
"iife": "hyperframe.runtime.iife.js",
|
|
7
7
|
"esm": "hyperframe.runtime.mjs"
|