hyperframes 0.8.23 → 0.8.25
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/cli.js +192 -13
- package/dist/fontLocalizeCli.js +158 -8
- package/dist/hyperframes-player.global.js +1 -1
- package/dist/studio/assets/{hyperframes-player-oZ6g4tHJ.js → hyperframes-player-CTP_00ix.js} +1 -1
- package/dist/studio/assets/{index-UyvIa_cE.js → index-Bjb4YqS_.js} +1 -1
- package/dist/studio/assets/{index-Tiu74FPg.js → index-DSk_ALFr.js} +218 -218
- package/dist/studio/assets/{index-DW-H7Y2b.js → index-Di-8Jxqc.js} +1 -1
- package/dist/studio/assets/index-DnRfAiK2.css +1 -0
- package/dist/studio/{chunk-6BT6DTB4.js → chunk-A7S5SGNA.js} +2 -2
- package/dist/studio/chunk-A7S5SGNA.js.map +1 -0
- package/dist/studio/{domEditingLayers-URA7BLWE.js → domEditingLayers-JMMVOGTO.js} +2 -2
- package/dist/studio/index.d.ts +4 -0
- package/dist/studio/index.html +2 -2
- package/dist/studio/index.js +6206 -5011
- package/dist/studio/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/studio/assets/index-yGhfxxoL.css +0 -1
- package/dist/studio/chunk-6BT6DTB4.js.map +0 -1
- /package/dist/studio/{domEditingLayers-URA7BLWE.js.map → domEditingLayers-JMMVOGTO.js.map} +0 -0
package/dist/cli.js
CHANGED
|
@@ -50,7 +50,7 @@ var VERSION;
|
|
|
50
50
|
var init_version = __esm({
|
|
51
51
|
"src/version.ts"() {
|
|
52
52
|
"use strict";
|
|
53
|
-
VERSION = true ? "0.8.
|
|
53
|
+
VERSION = true ? "0.8.25" : "0.0.0-dev";
|
|
54
54
|
}
|
|
55
55
|
});
|
|
56
56
|
|
|
@@ -73411,7 +73411,22 @@ async function downloadWithRetry(url, localPath, timeoutMs, signal, onTransientR
|
|
|
73411
73411
|
return await runDownloadAttempt(url, localPath, timeoutMs, attempt + 1, options, signal);
|
|
73412
73412
|
} catch (error) {
|
|
73413
73413
|
const classified = classifyDownloadFailure(error);
|
|
73414
|
-
if (!classified.locallyRetryable || attempt >= maxTransientRetries)
|
|
73414
|
+
if (!classified.locallyRetryable || attempt >= maxTransientRetries) {
|
|
73415
|
+
const identity2 = safeDownloadUrlIdentity(url);
|
|
73416
|
+
throw new UrlDownloadError(
|
|
73417
|
+
classified.kind,
|
|
73418
|
+
classified.retryable,
|
|
73419
|
+
classified.message,
|
|
73420
|
+
classified.status,
|
|
73421
|
+
{
|
|
73422
|
+
...classified.telemetry,
|
|
73423
|
+
urlFingerprint: identity2.urlFingerprint,
|
|
73424
|
+
initialHost: identity2.host,
|
|
73425
|
+
attempt: attempt + 1
|
|
73426
|
+
},
|
|
73427
|
+
classified.locallyRetryable
|
|
73428
|
+
);
|
|
73429
|
+
}
|
|
73415
73430
|
if (classified.retryable) onTransientRetry?.(classified);
|
|
73416
73431
|
const identity = safeDownloadUrlIdentity(url);
|
|
73417
73432
|
emitDownloadTelemetry(options, {
|
|
@@ -87249,6 +87264,37 @@ function extractionFrameCountForDuration(durationSeconds, fps, isVFR) {
|
|
|
87249
87264
|
function sdrToHdrTransformKey(transfer) {
|
|
87250
87265
|
return `sdr2hdr-${transfer}`;
|
|
87251
87266
|
}
|
|
87267
|
+
function safeVideoExtractionSourceIdentity(source) {
|
|
87268
|
+
if (!isHttpUrl(source)) return null;
|
|
87269
|
+
const identity = safeDownloadUrlIdentity(source);
|
|
87270
|
+
return {
|
|
87271
|
+
sourceFingerprint: `sha256:${identity.urlFingerprint}`,
|
|
87272
|
+
host: identity.host ?? "other"
|
|
87273
|
+
};
|
|
87274
|
+
}
|
|
87275
|
+
function downloadStatusClass(error) {
|
|
87276
|
+
const status = error.status ?? error.telemetry?.status;
|
|
87277
|
+
if (typeof status === "number" && status >= 400 && status < 500) return "http_4xx";
|
|
87278
|
+
if (typeof status === "number" && status >= 500 && status < 600) return "http_5xx";
|
|
87279
|
+
if (error.kind === "timeout") return "timeout";
|
|
87280
|
+
if (error.kind === "network") return "network";
|
|
87281
|
+
return "other";
|
|
87282
|
+
}
|
|
87283
|
+
function downloadFailureGroup(source, error) {
|
|
87284
|
+
const sourceIdentity = safeVideoExtractionSourceIdentity(source);
|
|
87285
|
+
const failureHost = error.telemetry?.finalHost ?? error.telemetry?.initialHost;
|
|
87286
|
+
const attempt = error.telemetry?.attempt;
|
|
87287
|
+
return {
|
|
87288
|
+
...sourceIdentity ? { sourceFingerprint: sourceIdentity.sourceFingerprint } : {},
|
|
87289
|
+
...failureHost ?? sourceIdentity?.host ? { host: failureHost ?? sourceIdentity?.host } : {},
|
|
87290
|
+
statusClass: downloadStatusClass(error),
|
|
87291
|
+
retry: {
|
|
87292
|
+
phase: "download",
|
|
87293
|
+
used: typeof attempt === "number" && attempt >= 2 ? 1 : 0,
|
|
87294
|
+
budget: 1
|
|
87295
|
+
}
|
|
87296
|
+
};
|
|
87297
|
+
}
|
|
87252
87298
|
function isVideoSourceExtractionError(error) {
|
|
87253
87299
|
return typeof error === "object" && error !== null && "hyperframesVideoSourceExtractionError" in error && error.hyperframesVideoSourceExtractionError === true;
|
|
87254
87300
|
}
|
|
@@ -88040,6 +88086,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config, c
|
|
|
88040
88086
|
videoId: video.id,
|
|
88041
88087
|
kind: classified.kind,
|
|
88042
88088
|
retryable: classified.retryable,
|
|
88089
|
+
...err instanceof UrlDownloadError ? { group: downloadFailureGroup(video.src, err) } : {},
|
|
88043
88090
|
error: classified.diagnostic
|
|
88044
88091
|
});
|
|
88045
88092
|
}
|
|
@@ -93137,6 +93184,7 @@ __export(src_exports, {
|
|
|
93137
93184
|
runFfmpeg: () => runFfmpeg,
|
|
93138
93185
|
runVideoExtractionWithRetry: () => runVideoExtractionWithRetry,
|
|
93139
93186
|
safeDownloadUrlIdentity: () => safeDownloadUrlIdentity,
|
|
93187
|
+
safeVideoExtractionSourceIdentity: () => safeVideoExtractionSourceIdentity,
|
|
93140
93188
|
sampleRgb48le: () => sampleRgb48le,
|
|
93141
93189
|
scaleProtocolTimeoutForComposition: () => scaleProtocolTimeoutForComposition,
|
|
93142
93190
|
selectVerifySampleIndicesForTask: () => selectVerifySampleIndicesForTask,
|
|
@@ -110027,6 +110075,7 @@ function collectProjectSignatureFiles(projectDir, dir, files) {
|
|
|
110027
110075
|
files.push({
|
|
110028
110076
|
file,
|
|
110029
110077
|
mtimeMs: stat3.mtimeMs,
|
|
110078
|
+
ctimeMs: stat3.ctimeMs,
|
|
110030
110079
|
size: stat3.size,
|
|
110031
110080
|
textContentEligible: isTextContentEligible(file, stat3.size)
|
|
110032
110081
|
});
|
|
@@ -110048,6 +110097,7 @@ function collectProjectSignatureManifestFiles(projectDir, files) {
|
|
|
110048
110097
|
files.push({
|
|
110049
110098
|
file,
|
|
110050
110099
|
mtimeMs: stat3.mtimeMs,
|
|
110100
|
+
ctimeMs: stat3.ctimeMs,
|
|
110051
110101
|
size: stat3.size,
|
|
110052
110102
|
textContentEligible: isTextContentEligible(file, stat3.size)
|
|
110053
110103
|
});
|
|
@@ -110063,6 +110113,8 @@ function createProjectFingerprint(projectDir, files) {
|
|
|
110063
110113
|
hash2.update("\0");
|
|
110064
110114
|
hash2.update(String(entry.mtimeMs));
|
|
110065
110115
|
hash2.update("\0");
|
|
110116
|
+
hash2.update(String(entry.ctimeMs));
|
|
110117
|
+
hash2.update("\0");
|
|
110066
110118
|
hash2.update(entry.textContentEligible ? "text" : "binary");
|
|
110067
110119
|
hash2.update("\0");
|
|
110068
110120
|
}
|
|
@@ -111075,6 +111127,9 @@ function validateGsapMutationRequest(c3, body) {
|
|
|
111075
111127
|
if (!body || typeof body !== "object" || !("type" in body) || !body.type) {
|
|
111076
111128
|
return c3.json({ error: "mutation type required" }, 400);
|
|
111077
111129
|
}
|
|
111130
|
+
if (containsRawGsapExpression(body)) {
|
|
111131
|
+
return c3.json({ error: "raw JavaScript expressions are not accepted" }, 400);
|
|
111132
|
+
}
|
|
111078
111133
|
const unsafeFields = findUnsafeMutationValues(body);
|
|
111079
111134
|
if (unsafeFields.length > 0) return rejectUnsafeMutationValues(c3, unsafeFields);
|
|
111080
111135
|
if (body.type === "shift-positions-batch" && (!("shifts" in body) || !Array.isArray(body.shifts))) {
|
|
@@ -111082,6 +111137,12 @@ function validateGsapMutationRequest(c3, body) {
|
|
|
111082
111137
|
}
|
|
111083
111138
|
return null;
|
|
111084
111139
|
}
|
|
111140
|
+
function containsRawGsapExpression(value) {
|
|
111141
|
+
if (typeof value === "string") return value.startsWith("__raw:");
|
|
111142
|
+
if (Array.isArray(value)) return value.some(containsRawGsapExpression);
|
|
111143
|
+
if (!value || typeof value !== "object") return false;
|
|
111144
|
+
return Object.values(value).some(containsRawGsapExpression);
|
|
111145
|
+
}
|
|
111085
111146
|
async function prepareGsapMutationScript(c3, res, firstMutation) {
|
|
111086
111147
|
const beforeHtml = readFileSync52(res.absPath, "utf-8");
|
|
111087
111148
|
let html = beforeHtml;
|
|
@@ -112380,27 +112441,32 @@ function registerFileRoutes(api, adapter2) {
|
|
|
112380
112441
|
parsed.body.operations
|
|
112381
112442
|
);
|
|
112382
112443
|
if (patched === originalContent) {
|
|
112444
|
+
const version22 = fileContentVersion(originalContent);
|
|
112445
|
+
c3.header("ETag", version22);
|
|
112383
112446
|
return c3.json({
|
|
112384
112447
|
ok: true,
|
|
112385
112448
|
changed: false,
|
|
112386
112449
|
matched,
|
|
112387
112450
|
content: originalContent,
|
|
112388
|
-
path: ctx.filePath
|
|
112451
|
+
path: ctx.filePath,
|
|
112452
|
+
version: version22
|
|
112389
112453
|
});
|
|
112390
112454
|
}
|
|
112391
|
-
const { backupPath } = writeMutationResult(
|
|
112455
|
+
const { backupPath, version: version2 } = writeMutationResult(
|
|
112392
112456
|
c3,
|
|
112393
112457
|
ctx.project.dir,
|
|
112394
112458
|
ctx.filePath,
|
|
112395
112459
|
ctx.absPath,
|
|
112396
112460
|
patched
|
|
112397
112461
|
);
|
|
112462
|
+
c3.header("ETag", version2);
|
|
112398
112463
|
return c3.json({
|
|
112399
112464
|
ok: true,
|
|
112400
112465
|
changed: true,
|
|
112401
112466
|
matched,
|
|
112402
112467
|
content: patched,
|
|
112403
112468
|
path: ctx.filePath,
|
|
112469
|
+
version: version2,
|
|
112404
112470
|
backupPath
|
|
112405
112471
|
});
|
|
112406
112472
|
});
|
|
@@ -113605,8 +113671,9 @@ function registerThumbnailRoutes(api, adapter2) {
|
|
|
113605
113671
|
if (!adapter2.generateThumbnail) {
|
|
113606
113672
|
return c3.json({ error: "Thumbnails not available" }, 501);
|
|
113607
113673
|
}
|
|
113608
|
-
const
|
|
113609
|
-
if (!
|
|
113674
|
+
const resolved2 = await resolveProjectAndSignature(adapter2, c3.req.param("id"));
|
|
113675
|
+
if (!resolved2) return c3.json({ error: "not found" }, 404);
|
|
113676
|
+
const { project, signature: projectSignature } = resolved2;
|
|
113610
113677
|
let compPath = decodeURIComponent(
|
|
113611
113678
|
c3.req.path.replace(`/projects/${project.id}/thumbnail/`, "").split("?")[0] ?? ""
|
|
113612
113679
|
);
|
|
@@ -113659,6 +113726,7 @@ function registerThumbnailRoutes(api, adapter2) {
|
|
|
113659
113726
|
const cacheDir = join112(project.dir, ".thumbnails");
|
|
113660
113727
|
const selectorKey = selector ? `_${selector.replace(/[^a-zA-Z0-9_-]+/g, "_").slice(0, 80)}_${selectorIndex ?? 0}` : "";
|
|
113661
113728
|
const urlVersionKey = urlVersion ? `_${urlVersion.replace(/[^a-zA-Z0-9_-]+/g, "_").slice(0, 32)}` : "";
|
|
113729
|
+
const projectSignatureKey = `_${createHash42("sha1").update(projectSignature).digest("hex").slice(0, 16)}`;
|
|
113662
113730
|
const outputScale = outputMode === "source" ? 1 : outputMode === "storyboard" ? Math.min(
|
|
113663
113731
|
1,
|
|
113664
113732
|
STORYBOARD_MAX_OUTPUT_DIMENSION / compW,
|
|
@@ -113666,7 +113734,7 @@ function registerThumbnailRoutes(api, adapter2) {
|
|
|
113666
113734
|
) : Math.min(1, THUMBNAIL_MAX_OUTPUT_WIDTH / compW, THUMBNAIL_MAX_OUTPUT_HEIGHT / compH);
|
|
113667
113735
|
const outputWidth = Math.max(1, Math.round(compW * outputScale));
|
|
113668
113736
|
const outputHeight = Math.max(1, Math.round(compH * outputScale));
|
|
113669
|
-
const cacheKey = `${THUMBNAIL_CACHE_VERSION}${urlVersionKey}${manualEditsKey}${motionKey}${sourceKey}_${format}_${outputMode}_${compPath.replace(/\//g, "_")}_${compW}x${compH}_${outputWidth}x${outputHeight}_${sourceMtime}_${seekTime.toFixed(2)}${selectorKey}.${format === "png" ? "png" : "jpg"}`;
|
|
113737
|
+
const cacheKey = `${THUMBNAIL_CACHE_VERSION}${urlVersionKey}${projectSignatureKey}${manualEditsKey}${motionKey}${sourceKey}_${format}_${outputMode}_${compPath.replace(/\//g, "_")}_${compW}x${compH}_${outputWidth}x${outputHeight}_${sourceMtime}_${seekTime.toFixed(2)}${selectorKey}.${format === "png" ? "png" : "jpg"}`;
|
|
113670
113738
|
const cachePath2 = join112(cacheDir, cacheKey);
|
|
113671
113739
|
if (!prunedCacheDirs.has(cacheDir)) {
|
|
113672
113740
|
prunedCacheDirs.add(cacheDir);
|
|
@@ -113700,6 +113768,11 @@ function registerThumbnailRoutes(api, adapter2) {
|
|
|
113700
113768
|
signal
|
|
113701
113769
|
});
|
|
113702
113770
|
if (!generated) return null;
|
|
113771
|
+
const afterGeneration = await resolveProjectAndSignature(adapter2, project.id);
|
|
113772
|
+
const freshSignature = createProjectSignature(project.dir);
|
|
113773
|
+
if (!afterGeneration || afterGeneration.project.dir !== project.dir || afterGeneration.signature !== projectSignature || freshSignature !== projectSignature) {
|
|
113774
|
+
return generated;
|
|
113775
|
+
}
|
|
113703
113776
|
if (!existsSync82(cacheDir)) mkdirSync52(cacheDir, { recursive: true });
|
|
113704
113777
|
writeThumbnailAtomically(cachePath2, generated);
|
|
113705
113778
|
return generated;
|
|
@@ -125740,12 +125813,88 @@ var init_planValidation = __esm({
|
|
|
125740
125813
|
}
|
|
125741
125814
|
});
|
|
125742
125815
|
|
|
125816
|
+
// ../producer/src/services/render/extractionFailureMetadata.ts
|
|
125817
|
+
function stringOrEmpty(value) {
|
|
125818
|
+
return value === void 0 ? "" : value;
|
|
125819
|
+
}
|
|
125820
|
+
function retrySortTuple(retry) {
|
|
125821
|
+
return retry === void 0 ? ["", -1, -1] : [retry.phase, retry.used, retry.budget];
|
|
125822
|
+
}
|
|
125823
|
+
function extractionFailureGroupSortTuple(group) {
|
|
125824
|
+
const retry = retrySortTuple(group.retry);
|
|
125825
|
+
return [
|
|
125826
|
+
group.kind,
|
|
125827
|
+
stringOrEmpty(group.sourceFingerprint),
|
|
125828
|
+
stringOrEmpty(group.host),
|
|
125829
|
+
stringOrEmpty(group.statusClass),
|
|
125830
|
+
retry[0],
|
|
125831
|
+
retry[1],
|
|
125832
|
+
retry[2]
|
|
125833
|
+
];
|
|
125834
|
+
}
|
|
125835
|
+
function compareExtractionFailureGroups(left, right) {
|
|
125836
|
+
const leftTuple = extractionFailureGroupSortTuple(left);
|
|
125837
|
+
const rightTuple = extractionFailureGroupSortTuple(right);
|
|
125838
|
+
for (let index = 0; index < leftTuple.length; index += 1) {
|
|
125839
|
+
const leftValue = leftTuple[index];
|
|
125840
|
+
const rightValue = rightTuple[index];
|
|
125841
|
+
if (leftValue < rightValue) return -1;
|
|
125842
|
+
if (leftValue > rightValue) return 1;
|
|
125843
|
+
}
|
|
125844
|
+
return 0;
|
|
125845
|
+
}
|
|
125846
|
+
function extractionFailureGroupIdentityKey(group) {
|
|
125847
|
+
return JSON.stringify(extractionFailureGroupSortTuple(group));
|
|
125848
|
+
}
|
|
125849
|
+
var init_extractionFailureMetadata = __esm({
|
|
125850
|
+
"../producer/src/services/render/extractionFailureMetadata.ts"() {
|
|
125851
|
+
"use strict";
|
|
125852
|
+
}
|
|
125853
|
+
});
|
|
125854
|
+
|
|
125743
125855
|
// ../producer/src/services/render/stages/extractVideosStage.ts
|
|
125744
125856
|
import { existsSync as existsSync51 } from "fs";
|
|
125745
125857
|
import { join as join50 } from "path";
|
|
125746
125858
|
function shouldCopyExtractedFrames(platform11) {
|
|
125747
125859
|
return platform11 === "win32";
|
|
125748
125860
|
}
|
|
125861
|
+
function buildExtractionFailureMetadata(inputs) {
|
|
125862
|
+
const kindCounts = /* @__PURE__ */ new Map();
|
|
125863
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
125864
|
+
for (const input2 of inputs) {
|
|
125865
|
+
kindCounts.set(input2.kind, (kindCounts.get(input2.kind) ?? 0) + input2.affectedElementCount);
|
|
125866
|
+
const key2 = extractionFailureGroupIdentityKey(input2);
|
|
125867
|
+
const existing = grouped.get(key2);
|
|
125868
|
+
if (existing) {
|
|
125869
|
+
existing.affectedElementCount += input2.affectedElementCount;
|
|
125870
|
+
} else {
|
|
125871
|
+
grouped.set(key2, { ...input2 });
|
|
125872
|
+
}
|
|
125873
|
+
}
|
|
125874
|
+
const allGroups = [...grouped.values()].sort(compareExtractionFailureGroups);
|
|
125875
|
+
return {
|
|
125876
|
+
schemaVersion: 1,
|
|
125877
|
+
kindCounts: [...kindCounts].map(([kind, affectedElementCount]) => ({
|
|
125878
|
+
kind,
|
|
125879
|
+
affectedElementCount
|
|
125880
|
+
})).sort((a, b2) => a.kind < b2.kind ? -1 : a.kind > b2.kind ? 1 : 0),
|
|
125881
|
+
groups: allGroups.slice(0, MAX_EXTRACTION_FAILURE_GROUPS),
|
|
125882
|
+
omittedGroupCount: Math.max(0, allGroups.length - MAX_EXTRACTION_FAILURE_GROUPS)
|
|
125883
|
+
};
|
|
125884
|
+
}
|
|
125885
|
+
function extractionFailureMetadataFromResult(result) {
|
|
125886
|
+
return buildExtractionFailureMetadata(
|
|
125887
|
+
result.errors.map((failure) => ({
|
|
125888
|
+
kind: failure.kind ?? "internal",
|
|
125889
|
+
affectedElementCount: 1,
|
|
125890
|
+
...failure.group
|
|
125891
|
+
}))
|
|
125892
|
+
);
|
|
125893
|
+
}
|
|
125894
|
+
function safeVideoExtractionSourceLogMetadata(source) {
|
|
125895
|
+
const identity = safeVideoExtractionSourceIdentity(source);
|
|
125896
|
+
return identity ? { sourceType: "remote", ...identity } : { sourceType: "local" };
|
|
125897
|
+
}
|
|
125749
125898
|
function resolveVideoExtractionPolicy(env = process.env) {
|
|
125750
125899
|
const rawMode = env.HF_VIDEO_EXTRACTION_FAILURE_MODE?.trim().toLowerCase();
|
|
125751
125900
|
const failureMode = rawMode === "observe" || rawMode === "off" ? rawMode : "enforce";
|
|
@@ -125779,7 +125928,8 @@ function buildVideoExtractionStageError(result) {
|
|
|
125779
125928
|
return new VideoExtractionStageError(
|
|
125780
125929
|
retryable ? "VIDEO_EXTRACTION_FAILED" : "VIDEO_SOURCE_UNRENDERABLE",
|
|
125781
125930
|
retryable,
|
|
125782
|
-
failures
|
|
125931
|
+
failures,
|
|
125932
|
+
extractionFailureMetadataFromResult(result)
|
|
125783
125933
|
);
|
|
125784
125934
|
}
|
|
125785
125935
|
function buildHdrProbeStageError(failures) {
|
|
@@ -125794,7 +125944,13 @@ function buildHdrProbeStageError(failures) {
|
|
|
125794
125944
|
return new VideoExtractionStageError(
|
|
125795
125945
|
retryable ? "VIDEO_EXTRACTION_FAILED" : "VIDEO_SOURCE_UNRENDERABLE",
|
|
125796
125946
|
retryable,
|
|
125797
|
-
summary
|
|
125947
|
+
summary,
|
|
125948
|
+
buildExtractionFailureMetadata(
|
|
125949
|
+
failures.map((failure) => ({
|
|
125950
|
+
kind: failure.kind,
|
|
125951
|
+
affectedElementCount: 1
|
|
125952
|
+
}))
|
|
125953
|
+
)
|
|
125798
125954
|
);
|
|
125799
125955
|
}
|
|
125800
125956
|
function isHdrProbeFailure(failure) {
|
|
@@ -125921,7 +126077,10 @@ async function runExtractVideosStage(input2) {
|
|
|
125921
126077
|
const totalVideos = composition.videos.length;
|
|
125922
126078
|
for (let i2 = 0; i2 < totalVideos; i2++) {
|
|
125923
126079
|
const v2 = composition.videos[i2];
|
|
125924
|
-
log2?.info(
|
|
126080
|
+
log2?.info(
|
|
126081
|
+
`Extracting frames from video ${i2 + 1}/${totalVideos}`,
|
|
126082
|
+
safeVideoExtractionSourceLogMetadata(v2.src)
|
|
126083
|
+
);
|
|
125925
126084
|
}
|
|
125926
126085
|
extractionResult = await extractAllVideoFrames(
|
|
125927
126086
|
composition.videos,
|
|
@@ -125993,7 +126152,7 @@ function appendAutoDetectedVideoAudio(composition, extracted) {
|
|
|
125993
126152
|
existingAudioSrcs.add(video.src);
|
|
125994
126153
|
}
|
|
125995
126154
|
}
|
|
125996
|
-
var VideoExtractionStageError;
|
|
126155
|
+
var MAX_EXTRACTION_FAILURE_GROUPS, VideoExtractionStageError;
|
|
125997
126156
|
var init_extractVideosStage = __esm({
|
|
125998
126157
|
"../producer/src/services/render/stages/extractVideosStage.ts"() {
|
|
125999
126158
|
"use strict";
|
|
@@ -126001,19 +126160,35 @@ var init_extractVideosStage = __esm({
|
|
|
126001
126160
|
init_renderOrchestrator();
|
|
126002
126161
|
init_shared();
|
|
126003
126162
|
init_encoderInterruption();
|
|
126163
|
+
init_extractionFailureMetadata();
|
|
126164
|
+
MAX_EXTRACTION_FAILURE_GROUPS = 8;
|
|
126004
126165
|
VideoExtractionStageError = class extends Error {
|
|
126005
|
-
constructor(code, retryable, failures
|
|
126166
|
+
constructor(code, retryable, failures, extractionFailure = buildExtractionFailureMetadata(
|
|
126167
|
+
failures.map((failure) => ({
|
|
126168
|
+
kind: failure.kind,
|
|
126169
|
+
affectedElementCount: failure.count
|
|
126170
|
+
}))
|
|
126171
|
+
)) {
|
|
126006
126172
|
const total = failures.reduce((sum, failure) => sum + failure.count, 0);
|
|
126007
126173
|
const breakdown = failures.map((failure) => `${failure.kind}=${failure.count}`).join(",");
|
|
126008
126174
|
super(`Video extraction failed for ${total} source(s) [${code}; ${breakdown}]`);
|
|
126009
126175
|
this.code = code;
|
|
126010
126176
|
this.retryable = retryable;
|
|
126011
126177
|
this.failures = failures;
|
|
126178
|
+
this.extractionFailure = extractionFailure;
|
|
126012
126179
|
this.name = "VideoExtractionStageError";
|
|
126180
|
+
this.publicMetadata = { extractionFailure };
|
|
126013
126181
|
}
|
|
126014
126182
|
code;
|
|
126015
126183
|
retryable;
|
|
126016
126184
|
failures;
|
|
126185
|
+
extractionFailure;
|
|
126186
|
+
/**
|
|
126187
|
+
* Producer servers may expose this explicitly public, JSON-compatible data
|
|
126188
|
+
* without knowing its schema. Boundary adapters remain responsible for
|
|
126189
|
+
* validating and applying policy to it.
|
|
126190
|
+
*/
|
|
126191
|
+
publicMetadata;
|
|
126017
126192
|
};
|
|
126018
126193
|
}
|
|
126019
126194
|
});
|
|
@@ -132321,10 +132496,12 @@ function extractSafeRenderErrorMetadata(error) {
|
|
|
132321
132496
|
if (!errorCode || typeof error !== "object" || error === null) return void 0;
|
|
132322
132497
|
const owner = "owner" in error ? error.owner : void 0;
|
|
132323
132498
|
const retryable = "retryable" in error ? error.retryable : void 0;
|
|
132499
|
+
const publicMetadata = "publicMetadata" in error ? error.publicMetadata : void 0;
|
|
132324
132500
|
return {
|
|
132325
132501
|
errorCode,
|
|
132326
132502
|
errorOwner: owner === "user" || owner === "system" ? owner : void 0,
|
|
132327
|
-
retryable: typeof retryable === "boolean" ? retryable : void 0
|
|
132503
|
+
retryable: typeof retryable === "boolean" ? retryable : void 0,
|
|
132504
|
+
...isPlainObject4(publicMetadata) ? { errorMetadata: publicMetadata } : {}
|
|
132328
132505
|
};
|
|
132329
132506
|
}
|
|
132330
132507
|
function parseServerFps(value) {
|
|
@@ -132646,6 +132823,7 @@ async function writeRenderStreamFailure(input2) {
|
|
|
132646
132823
|
errorCode: safeError?.errorCode,
|
|
132647
132824
|
errorOwner: safeError?.errorOwner,
|
|
132648
132825
|
retryable: safeError?.retryable,
|
|
132826
|
+
errorMetadata: safeError?.errorMetadata,
|
|
132649
132827
|
stage: job.currentStage,
|
|
132650
132828
|
elapsedMs,
|
|
132651
132829
|
errorDetails: job.errorDetails ?? null,
|
|
@@ -132771,6 +132949,7 @@ function createRenderHandlers(options = {}) {
|
|
|
132771
132949
|
errorCode: safeError?.errorCode,
|
|
132772
132950
|
errorOwner: safeError?.errorOwner,
|
|
132773
132951
|
retryable: safeError?.retryable,
|
|
132952
|
+
errorMetadata: safeError?.errorMetadata,
|
|
132774
132953
|
stage: job.currentStage,
|
|
132775
132954
|
durationMs,
|
|
132776
132955
|
errorDetails: job.errorDetails ?? null
|
package/dist/fontLocalizeCli.js
CHANGED
|
@@ -62903,7 +62903,22 @@ async function downloadWithRetry(url, localPath, timeoutMs, signal, onTransientR
|
|
|
62903
62903
|
return await runDownloadAttempt(url, localPath, timeoutMs, attempt + 1, options, signal);
|
|
62904
62904
|
} catch (error) {
|
|
62905
62905
|
const classified = classifyDownloadFailure(error);
|
|
62906
|
-
if (!classified.locallyRetryable || attempt >= maxTransientRetries)
|
|
62906
|
+
if (!classified.locallyRetryable || attempt >= maxTransientRetries) {
|
|
62907
|
+
const identity2 = safeDownloadUrlIdentity(url);
|
|
62908
|
+
throw new UrlDownloadError(
|
|
62909
|
+
classified.kind,
|
|
62910
|
+
classified.retryable,
|
|
62911
|
+
classified.message,
|
|
62912
|
+
classified.status,
|
|
62913
|
+
{
|
|
62914
|
+
...classified.telemetry,
|
|
62915
|
+
urlFingerprint: identity2.urlFingerprint,
|
|
62916
|
+
initialHost: identity2.host,
|
|
62917
|
+
attempt: attempt + 1
|
|
62918
|
+
},
|
|
62919
|
+
classified.locallyRetryable
|
|
62920
|
+
);
|
|
62921
|
+
}
|
|
62907
62922
|
if (classified.retryable) onTransientRetry?.(classified);
|
|
62908
62923
|
const identity = safeDownloadUrlIdentity(url);
|
|
62909
62924
|
emitDownloadTelemetry(options, {
|
|
@@ -74981,6 +74996,37 @@ function extractionFrameCountForDuration(durationSeconds, fps, isVFR) {
|
|
|
74981
74996
|
function sdrToHdrTransformKey(transfer) {
|
|
74982
74997
|
return `sdr2hdr-${transfer}`;
|
|
74983
74998
|
}
|
|
74999
|
+
function safeVideoExtractionSourceIdentity(source) {
|
|
75000
|
+
if (!isHttpUrl(source)) return null;
|
|
75001
|
+
const identity = safeDownloadUrlIdentity(source);
|
|
75002
|
+
return {
|
|
75003
|
+
sourceFingerprint: `sha256:${identity.urlFingerprint}`,
|
|
75004
|
+
host: identity.host ?? "other"
|
|
75005
|
+
};
|
|
75006
|
+
}
|
|
75007
|
+
function downloadStatusClass(error) {
|
|
75008
|
+
const status = error.status ?? error.telemetry?.status;
|
|
75009
|
+
if (typeof status === "number" && status >= 400 && status < 500) return "http_4xx";
|
|
75010
|
+
if (typeof status === "number" && status >= 500 && status < 600) return "http_5xx";
|
|
75011
|
+
if (error.kind === "timeout") return "timeout";
|
|
75012
|
+
if (error.kind === "network") return "network";
|
|
75013
|
+
return "other";
|
|
75014
|
+
}
|
|
75015
|
+
function downloadFailureGroup(source, error) {
|
|
75016
|
+
const sourceIdentity = safeVideoExtractionSourceIdentity(source);
|
|
75017
|
+
const failureHost = error.telemetry?.finalHost ?? error.telemetry?.initialHost;
|
|
75018
|
+
const attempt = error.telemetry?.attempt;
|
|
75019
|
+
return {
|
|
75020
|
+
...sourceIdentity ? { sourceFingerprint: sourceIdentity.sourceFingerprint } : {},
|
|
75021
|
+
...failureHost ?? sourceIdentity?.host ? { host: failureHost ?? sourceIdentity?.host } : {},
|
|
75022
|
+
statusClass: downloadStatusClass(error),
|
|
75023
|
+
retry: {
|
|
75024
|
+
phase: "download",
|
|
75025
|
+
used: typeof attempt === "number" && attempt >= 2 ? 1 : 0,
|
|
75026
|
+
budget: 1
|
|
75027
|
+
}
|
|
75028
|
+
};
|
|
75029
|
+
}
|
|
74984
75030
|
function isVideoSourceExtractionError(error) {
|
|
74985
75031
|
return typeof error === "object" && error !== null && "hyperframesVideoSourceExtractionError" in error && error.hyperframesVideoSourceExtractionError === true;
|
|
74986
75032
|
}
|
|
@@ -75772,6 +75818,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config, c
|
|
|
75772
75818
|
videoId: video.id,
|
|
75773
75819
|
kind: classified.kind,
|
|
75774
75820
|
retryable: classified.retryable,
|
|
75821
|
+
...err instanceof UrlDownloadError ? { group: downloadFailureGroup(video.src, err) } : {},
|
|
75775
75822
|
error: classified.diagnostic
|
|
75776
75823
|
});
|
|
75777
75824
|
}
|
|
@@ -80869,6 +80916,7 @@ __export(src_exports, {
|
|
|
80869
80916
|
runFfmpeg: () => runFfmpeg,
|
|
80870
80917
|
runVideoExtractionWithRetry: () => runVideoExtractionWithRetry,
|
|
80871
80918
|
safeDownloadUrlIdentity: () => safeDownloadUrlIdentity,
|
|
80919
|
+
safeVideoExtractionSourceIdentity: () => safeVideoExtractionSourceIdentity,
|
|
80872
80920
|
sampleRgb48le: () => sampleRgb48le,
|
|
80873
80921
|
scaleProtocolTimeoutForComposition: () => scaleProtocolTimeoutForComposition,
|
|
80874
80922
|
selectVerifySampleIndicesForTask: () => selectVerifySampleIndicesForTask,
|
|
@@ -90808,9 +90856,83 @@ function validateRenderDuration(input) {
|
|
|
90808
90856
|
init_src();
|
|
90809
90857
|
import { existsSync as existsSync26 } from "fs";
|
|
90810
90858
|
import { join as join30 } from "path";
|
|
90859
|
+
|
|
90860
|
+
// ../producer/src/services/render/extractionFailureMetadata.ts
|
|
90861
|
+
function stringOrEmpty(value) {
|
|
90862
|
+
return value === void 0 ? "" : value;
|
|
90863
|
+
}
|
|
90864
|
+
function retrySortTuple(retry) {
|
|
90865
|
+
return retry === void 0 ? ["", -1, -1] : [retry.phase, retry.used, retry.budget];
|
|
90866
|
+
}
|
|
90867
|
+
function extractionFailureGroupSortTuple(group) {
|
|
90868
|
+
const retry = retrySortTuple(group.retry);
|
|
90869
|
+
return [
|
|
90870
|
+
group.kind,
|
|
90871
|
+
stringOrEmpty(group.sourceFingerprint),
|
|
90872
|
+
stringOrEmpty(group.host),
|
|
90873
|
+
stringOrEmpty(group.statusClass),
|
|
90874
|
+
retry[0],
|
|
90875
|
+
retry[1],
|
|
90876
|
+
retry[2]
|
|
90877
|
+
];
|
|
90878
|
+
}
|
|
90879
|
+
function compareExtractionFailureGroups(left, right) {
|
|
90880
|
+
const leftTuple = extractionFailureGroupSortTuple(left);
|
|
90881
|
+
const rightTuple = extractionFailureGroupSortTuple(right);
|
|
90882
|
+
for (let index = 0; index < leftTuple.length; index += 1) {
|
|
90883
|
+
const leftValue = leftTuple[index];
|
|
90884
|
+
const rightValue = rightTuple[index];
|
|
90885
|
+
if (leftValue < rightValue) return -1;
|
|
90886
|
+
if (leftValue > rightValue) return 1;
|
|
90887
|
+
}
|
|
90888
|
+
return 0;
|
|
90889
|
+
}
|
|
90890
|
+
function extractionFailureGroupIdentityKey(group) {
|
|
90891
|
+
return JSON.stringify(extractionFailureGroupSortTuple(group));
|
|
90892
|
+
}
|
|
90893
|
+
|
|
90894
|
+
// ../producer/src/services/render/stages/extractVideosStage.ts
|
|
90811
90895
|
function shouldCopyExtractedFrames(platform3) {
|
|
90812
90896
|
return platform3 === "win32";
|
|
90813
90897
|
}
|
|
90898
|
+
var MAX_EXTRACTION_FAILURE_GROUPS = 8;
|
|
90899
|
+
function buildExtractionFailureMetadata(inputs) {
|
|
90900
|
+
const kindCounts = /* @__PURE__ */ new Map();
|
|
90901
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
90902
|
+
for (const input of inputs) {
|
|
90903
|
+
kindCounts.set(input.kind, (kindCounts.get(input.kind) ?? 0) + input.affectedElementCount);
|
|
90904
|
+
const key2 = extractionFailureGroupIdentityKey(input);
|
|
90905
|
+
const existing = grouped.get(key2);
|
|
90906
|
+
if (existing) {
|
|
90907
|
+
existing.affectedElementCount += input.affectedElementCount;
|
|
90908
|
+
} else {
|
|
90909
|
+
grouped.set(key2, { ...input });
|
|
90910
|
+
}
|
|
90911
|
+
}
|
|
90912
|
+
const allGroups = [...grouped.values()].sort(compareExtractionFailureGroups);
|
|
90913
|
+
return {
|
|
90914
|
+
schemaVersion: 1,
|
|
90915
|
+
kindCounts: [...kindCounts].map(([kind, affectedElementCount]) => ({
|
|
90916
|
+
kind,
|
|
90917
|
+
affectedElementCount
|
|
90918
|
+
})).sort((a, b) => a.kind < b.kind ? -1 : a.kind > b.kind ? 1 : 0),
|
|
90919
|
+
groups: allGroups.slice(0, MAX_EXTRACTION_FAILURE_GROUPS),
|
|
90920
|
+
omittedGroupCount: Math.max(0, allGroups.length - MAX_EXTRACTION_FAILURE_GROUPS)
|
|
90921
|
+
};
|
|
90922
|
+
}
|
|
90923
|
+
function extractionFailureMetadataFromResult(result) {
|
|
90924
|
+
return buildExtractionFailureMetadata(
|
|
90925
|
+
result.errors.map((failure) => ({
|
|
90926
|
+
kind: failure.kind ?? "internal",
|
|
90927
|
+
affectedElementCount: 1,
|
|
90928
|
+
...failure.group
|
|
90929
|
+
}))
|
|
90930
|
+
);
|
|
90931
|
+
}
|
|
90932
|
+
function safeVideoExtractionSourceLogMetadata(source) {
|
|
90933
|
+
const identity = safeVideoExtractionSourceIdentity(source);
|
|
90934
|
+
return identity ? { sourceType: "remote", ...identity } : { sourceType: "local" };
|
|
90935
|
+
}
|
|
90814
90936
|
function resolveVideoExtractionPolicy(env = process.env) {
|
|
90815
90937
|
const rawMode = env.HF_VIDEO_EXTRACTION_FAILURE_MODE?.trim().toLowerCase();
|
|
90816
90938
|
const failureMode = rawMode === "observe" || rawMode === "off" ? rawMode : "enforce";
|
|
@@ -90818,18 +90940,32 @@ function resolveVideoExtractionPolicy(env = process.env) {
|
|
|
90818
90940
|
return { failureMode, maxTransientRetries };
|
|
90819
90941
|
}
|
|
90820
90942
|
var VideoExtractionStageError = class extends Error {
|
|
90821
|
-
constructor(code, retryable, failures
|
|
90943
|
+
constructor(code, retryable, failures, extractionFailure = buildExtractionFailureMetadata(
|
|
90944
|
+
failures.map((failure) => ({
|
|
90945
|
+
kind: failure.kind,
|
|
90946
|
+
affectedElementCount: failure.count
|
|
90947
|
+
}))
|
|
90948
|
+
)) {
|
|
90822
90949
|
const total = failures.reduce((sum, failure) => sum + failure.count, 0);
|
|
90823
90950
|
const breakdown = failures.map((failure) => `${failure.kind}=${failure.count}`).join(",");
|
|
90824
90951
|
super(`Video extraction failed for ${total} source(s) [${code}; ${breakdown}]`);
|
|
90825
90952
|
this.code = code;
|
|
90826
90953
|
this.retryable = retryable;
|
|
90827
90954
|
this.failures = failures;
|
|
90955
|
+
this.extractionFailure = extractionFailure;
|
|
90828
90956
|
this.name = "VideoExtractionStageError";
|
|
90957
|
+
this.publicMetadata = { extractionFailure };
|
|
90829
90958
|
}
|
|
90830
90959
|
code;
|
|
90831
90960
|
retryable;
|
|
90832
90961
|
failures;
|
|
90962
|
+
extractionFailure;
|
|
90963
|
+
/**
|
|
90964
|
+
* Producer servers may expose this explicitly public, JSON-compatible data
|
|
90965
|
+
* without knowing its schema. Boundary adapters remain responsible for
|
|
90966
|
+
* validating and applying policy to it.
|
|
90967
|
+
*/
|
|
90968
|
+
publicMetadata;
|
|
90833
90969
|
};
|
|
90834
90970
|
function throwIfEncoderInterrupted(result) {
|
|
90835
90971
|
const interrupted = result.errors.find((failure) => failure.kind === "external_interruption");
|
|
@@ -90853,7 +90989,8 @@ function buildVideoExtractionStageError(result) {
|
|
|
90853
90989
|
return new VideoExtractionStageError(
|
|
90854
90990
|
retryable ? "VIDEO_EXTRACTION_FAILED" : "VIDEO_SOURCE_UNRENDERABLE",
|
|
90855
90991
|
retryable,
|
|
90856
|
-
failures
|
|
90992
|
+
failures,
|
|
90993
|
+
extractionFailureMetadataFromResult(result)
|
|
90857
90994
|
);
|
|
90858
90995
|
}
|
|
90859
90996
|
function buildHdrProbeStageError(failures) {
|
|
@@ -90868,7 +91005,13 @@ function buildHdrProbeStageError(failures) {
|
|
|
90868
91005
|
return new VideoExtractionStageError(
|
|
90869
91006
|
retryable ? "VIDEO_EXTRACTION_FAILED" : "VIDEO_SOURCE_UNRENDERABLE",
|
|
90870
91007
|
retryable,
|
|
90871
|
-
summary
|
|
91008
|
+
summary,
|
|
91009
|
+
buildExtractionFailureMetadata(
|
|
91010
|
+
failures.map((failure) => ({
|
|
91011
|
+
kind: failure.kind,
|
|
91012
|
+
affectedElementCount: 1
|
|
91013
|
+
}))
|
|
91014
|
+
)
|
|
90872
91015
|
);
|
|
90873
91016
|
}
|
|
90874
91017
|
function isHdrProbeFailure(failure) {
|
|
@@ -90995,7 +91138,10 @@ async function runExtractVideosStage(input) {
|
|
|
90995
91138
|
const totalVideos = composition.videos.length;
|
|
90996
91139
|
for (let i = 0; i < totalVideos; i++) {
|
|
90997
91140
|
const v = composition.videos[i];
|
|
90998
|
-
log?.info(
|
|
91141
|
+
log?.info(
|
|
91142
|
+
`Extracting frames from video ${i + 1}/${totalVideos}`,
|
|
91143
|
+
safeVideoExtractionSourceLogMetadata(v.src)
|
|
91144
|
+
);
|
|
90999
91145
|
}
|
|
91000
91146
|
extractionResult = await extractAllVideoFrames(
|
|
91001
91147
|
composition.videos,
|
|
@@ -96941,10 +97087,12 @@ function extractSafeRenderErrorMetadata(error) {
|
|
|
96941
97087
|
if (!errorCode || typeof error !== "object" || error === null) return void 0;
|
|
96942
97088
|
const owner = "owner" in error ? error.owner : void 0;
|
|
96943
97089
|
const retryable = "retryable" in error ? error.retryable : void 0;
|
|
97090
|
+
const publicMetadata = "publicMetadata" in error ? error.publicMetadata : void 0;
|
|
96944
97091
|
return {
|
|
96945
97092
|
errorCode,
|
|
96946
97093
|
errorOwner: owner === "user" || owner === "system" ? owner : void 0,
|
|
96947
|
-
retryable: typeof retryable === "boolean" ? retryable : void 0
|
|
97094
|
+
retryable: typeof retryable === "boolean" ? retryable : void 0,
|
|
97095
|
+
...isPlainObject3(publicMetadata) ? { errorMetadata: publicMetadata } : {}
|
|
96948
97096
|
};
|
|
96949
97097
|
}
|
|
96950
97098
|
function parseServerFps(value) {
|
|
@@ -97266,6 +97414,7 @@ async function writeRenderStreamFailure(input) {
|
|
|
97266
97414
|
errorCode: safeError?.errorCode,
|
|
97267
97415
|
errorOwner: safeError?.errorOwner,
|
|
97268
97416
|
retryable: safeError?.retryable,
|
|
97417
|
+
errorMetadata: safeError?.errorMetadata,
|
|
97269
97418
|
stage: job.currentStage,
|
|
97270
97419
|
elapsedMs,
|
|
97271
97420
|
errorDetails: job.errorDetails ?? null,
|
|
@@ -97391,6 +97540,7 @@ function createRenderHandlers(options = {}) {
|
|
|
97391
97540
|
errorCode: safeError?.errorCode,
|
|
97392
97541
|
errorOwner: safeError?.errorOwner,
|
|
97393
97542
|
retryable: safeError?.retryable,
|
|
97543
|
+
errorMetadata: safeError?.errorMetadata,
|
|
97394
97544
|
stage: job.currentStage,
|
|
97395
97545
|
durationMs,
|
|
97396
97546
|
errorDetails: job.errorDetails ?? null
|
|
@@ -97748,8 +97898,8 @@ async function runFontLocalize(io, localize) {
|
|
|
97748
97898
|
}
|
|
97749
97899
|
|
|
97750
97900
|
// src/version.ts
|
|
97751
|
-
var VERSION = true ? "0.8.
|
|
97752
|
-
var PRODUCER_VERSION = true ? "0.8.
|
|
97901
|
+
var VERSION = true ? "0.8.25" : "0.0.0-dev";
|
|
97902
|
+
var PRODUCER_VERSION = true ? "0.8.25" : "0.0.0-dev";
|
|
97753
97903
|
|
|
97754
97904
|
// src/fontLocalizeCli.ts
|
|
97755
97905
|
async function readStdin() {
|