@hyperframes/studio-server 0.8.205 → 0.8.207
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/{chunk-2GPN2OSU.js → chunk-ZR3T4TKU.js} +51 -2
- package/dist/helpers/encoderOptions.d.ts +8 -1
- package/dist/helpers/encoderOptions.js +3 -1
- package/dist/helpers/mediaProxyPreview.d.ts +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +10 -5
- package/dist/{mediaProxyPreview-DeICCYb5.d.ts → mediaProxyPreview-DIEtpLJo.d.ts} +3 -0
- package/package.json +3 -3
|
@@ -29,10 +29,46 @@ function parseRateControl(body, format) {
|
|
|
29
29
|
if (isSet(body.videoBitrate)) return parseVideoBitrate(body.videoBitrate);
|
|
30
30
|
return { ok: true, options: {} };
|
|
31
31
|
}
|
|
32
|
+
function parseKeyframeInterval(value) {
|
|
33
|
+
if (typeof value !== "number" || !(value > 0)) {
|
|
34
|
+
return { ok: false, error: "keyframeIntervalSeconds must be a positive number of seconds" };
|
|
35
|
+
}
|
|
36
|
+
return { ok: true, options: { keyframeIntervalSeconds: value } };
|
|
37
|
+
}
|
|
38
|
+
function parseBitrateField(name, value) {
|
|
39
|
+
if (typeof value !== "string" || !VIDEO_BITRATE.test(value)) {
|
|
40
|
+
return { ok: false, error: `${name} must look like "8M", "5000k" or "8000000"` };
|
|
41
|
+
}
|
|
42
|
+
return { ok: true, options: { [name]: value } };
|
|
43
|
+
}
|
|
44
|
+
var DELIVERY_FIELDS = [
|
|
45
|
+
["keyframeIntervalSeconds", parseKeyframeInterval],
|
|
46
|
+
["maxBitrate", (value) => parseBitrateField("maxBitrate", value)],
|
|
47
|
+
["bufferSize", (value) => parseBitrateField("bufferSize", value)]
|
|
48
|
+
];
|
|
49
|
+
function parseDelivery(body, format) {
|
|
50
|
+
const present = DELIVERY_FIELDS.filter(([name]) => isSet(body[name]));
|
|
51
|
+
if (present.length === 0) return { ok: true, options: {} };
|
|
52
|
+
if (format !== "mp4") {
|
|
53
|
+
return { ok: false, error: "keyframeIntervalSeconds and maxBitrate apply to mp4 renders" };
|
|
54
|
+
}
|
|
55
|
+
if (isSet(body.bufferSize) && !isSet(body.maxBitrate)) {
|
|
56
|
+
return { ok: false, error: "bufferSize requires maxBitrate" };
|
|
57
|
+
}
|
|
58
|
+
const options = {};
|
|
59
|
+
for (const [name, parse] of present) {
|
|
60
|
+
const parsed = parse(body[name]);
|
|
61
|
+
if (!parsed.ok) return parsed;
|
|
62
|
+
Object.assign(options, parsed.options);
|
|
63
|
+
}
|
|
64
|
+
return { ok: true, options };
|
|
65
|
+
}
|
|
32
66
|
function parseEncoderOptions(body, format) {
|
|
33
67
|
const rate = parseRateControl(body, format);
|
|
34
68
|
if (!rate.ok) return rate;
|
|
35
|
-
const
|
|
69
|
+
const delivery = parseDelivery(body, format);
|
|
70
|
+
if (!delivery.ok) return delivery;
|
|
71
|
+
const options = { ...rate.options, ...delivery.options };
|
|
36
72
|
if (isSet(body.gifLoop)) {
|
|
37
73
|
if (typeof body.gifLoop !== "number" || !Number.isInteger(body.gifLoop) || body.gifLoop < 0 || body.gifLoop > 65535) {
|
|
38
74
|
return { ok: false, error: "gifLoop must be an integer from 0 to 65535" };
|
|
@@ -56,7 +92,20 @@ function parseEncoderOptions(body, format) {
|
|
|
56
92
|
}
|
|
57
93
|
return { ok: true, options };
|
|
58
94
|
}
|
|
95
|
+
function encoderJobOptions(opts) {
|
|
96
|
+
const { crf, videoBitrate, keyframeIntervalSeconds, maxBitrate, bufferSize } = opts;
|
|
97
|
+
return {
|
|
98
|
+
...crf !== void 0 ? { crf } : {},
|
|
99
|
+
...videoBitrate ? { videoBitrate } : {},
|
|
100
|
+
...keyframeIntervalSeconds !== void 0 ? { keyframeIntervalSeconds } : {},
|
|
101
|
+
...maxBitrate ? { maxBitrate } : {},
|
|
102
|
+
...bufferSize ? { bufferSize } : {},
|
|
103
|
+
...opts.videoFrameFormat ? { videoFrameFormat: opts.videoFrameFormat } : {},
|
|
104
|
+
...opts.hdrMode ? { hdrMode: opts.hdrMode } : {}
|
|
105
|
+
};
|
|
106
|
+
}
|
|
59
107
|
|
|
60
108
|
export {
|
|
61
|
-
parseEncoderOptions
|
|
109
|
+
parseEncoderOptions,
|
|
110
|
+
encoderJobOptions
|
|
62
111
|
};
|
|
@@ -6,6 +6,9 @@ interface EncoderOptions {
|
|
|
6
6
|
videoBitrate?: string;
|
|
7
7
|
videoFrameFormat?: (typeof VIDEO_FRAME_FORMATS)[number];
|
|
8
8
|
hdrMode?: (typeof HDR_MODES)[number];
|
|
9
|
+
keyframeIntervalSeconds?: number;
|
|
10
|
+
maxBitrate?: string;
|
|
11
|
+
bufferSize?: string;
|
|
9
12
|
}
|
|
10
13
|
interface EncoderOptionsBody {
|
|
11
14
|
gifLoop?: unknown;
|
|
@@ -13,6 +16,9 @@ interface EncoderOptionsBody {
|
|
|
13
16
|
videoBitrate?: unknown;
|
|
14
17
|
videoFrameFormat?: unknown;
|
|
15
18
|
hdrMode?: unknown;
|
|
19
|
+
keyframeIntervalSeconds?: unknown;
|
|
20
|
+
maxBitrate?: unknown;
|
|
21
|
+
bufferSize?: unknown;
|
|
16
22
|
}
|
|
17
23
|
type Parsed = {
|
|
18
24
|
ok: true;
|
|
@@ -23,5 +29,6 @@ type Parsed = {
|
|
|
23
29
|
};
|
|
24
30
|
/** Explicit encoder overrides from a render request. MOV (ProRes) takes no rate control. */
|
|
25
31
|
declare function parseEncoderOptions(body: EncoderOptionsBody, format: string): Parsed;
|
|
32
|
+
declare function encoderJobOptions(opts: EncoderOptions): Omit<EncoderOptions, "gifLoop">;
|
|
26
33
|
|
|
27
|
-
export { type EncoderOptionsBody, parseEncoderOptions };
|
|
34
|
+
export { type EncoderOptionsBody, encoderJobOptions, parseEncoderOptions };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import '@hyperframes/core';
|
|
2
|
-
export { a as PreviewApiAdapter, P as PreviewDocumentStore, i as injectMediaCodecMap, f as injectMediaCodecMapIntoHtml, g as isAutoProxyEnabled, p as proxyEtagSalt, r as resolvePreviewMediaCodecProbeCache } from '../mediaProxyPreview-
|
|
2
|
+
export { a as PreviewApiAdapter, P as PreviewDocumentStore, i as injectMediaCodecMap, f as injectMediaCodecMapIntoHtml, g as isAutoProxyEnabled, p as proxyEtagSalt, r as resolvePreviewMediaCodecProbeCache } from '../mediaProxyPreview-DIEtpLJo.js';
|
|
3
3
|
import './mediaCodecMap.js';
|
|
4
4
|
import 'sharp';
|
|
5
5
|
import '@hyperframes/parsers';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Hono } from 'hono';
|
|
2
|
-
import { S as StudioApiAdapter, P as PreviewDocumentStore, M as MediaProcessingJobState } from './mediaProxyPreview-
|
|
3
|
-
export { L as LintResult, a as PreviewApiAdapter, R as RenderJobState, b as ResolvedProject, c as StudioSelectionResponse, d as StudioSelectionSnapshot, e as StudioSelectionTextField } from './mediaProxyPreview-
|
|
2
|
+
import { S as StudioApiAdapter, P as PreviewDocumentStore, M as MediaProcessingJobState } from './mediaProxyPreview-DIEtpLJo.js';
|
|
3
|
+
export { L as LintResult, a as PreviewApiAdapter, R as RenderJobState, b as ResolvedProject, c as StudioSelectionResponse, d as StudioSelectionSnapshot, e as StudioSelectionTextField } from './mediaProxyPreview-DIEtpLJo.js';
|
|
4
4
|
export { C as ClosedWindow, D as DEFAULT_HISTORY_ROOT, S as HISTORY_START, H as HistoryClosedError, a as HistoryEntry, b as HistoryEntrySide, c as HistoryFileChange, d as HistoryListItem, e as HistoryRefusedError, f as HistoryResult, g as HistoryTarget, h as HistoryWho, i as HistoryWindow, M as MAX_WINDOW_IDLE_MS, P as ProjectHistory, j as ProjectHistoryOptions, k as ProjectHistoryView, U as UNDO_MODES, l as UndoMode, o as openProjectHistory, r as readProjectHistory } from './projectHistory-C18HDvac.js';
|
|
5
5
|
export { ArtifactCapture, ArtifactInput, ArtifactRecord, HistoryBusyError, HistoryIdError, ProjectHistoryRecord, PrunedHistory, ReclaimedHistory, RenderRecord, VideoState, artifactDirectory, beginArtifactCapture, finishSnapshotRun, forgetRecordedArtifacts, historyCache, listProjectHistories, pruneGoneProjectHistories, reclaimUncopiedBlobs, recordArtifact, recordArtifacts, recordRenderSuccess, registerRenderOutput, retainSnapshotOutput } from './history/index.js';
|
|
6
6
|
export { CACHE_DIR_NAME as PROXY_CACHE_DIR_NAME } from './helpers/proxyTranscoder.js';
|
package/dist/index.js
CHANGED
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
} from "./chunk-FJBJJURY.js";
|
|
25
25
|
import {
|
|
26
26
|
parseEncoderOptions
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-ZR3T4TKU.js";
|
|
28
28
|
import {
|
|
29
29
|
DEFAULT_HISTORY_ROOT,
|
|
30
30
|
DELETED_VERSION,
|
|
@@ -3871,6 +3871,7 @@ function registerFileRoutes(api, adapter) {
|
|
|
3871
3871
|
// src/routes/preview.ts
|
|
3872
3872
|
import { parseHTML as parseHTML7 } from "linkedom";
|
|
3873
3873
|
import { createReadStream, existsSync as existsSync5, readFileSync as readFileSync6, statSync as statSync4 } from "fs";
|
|
3874
|
+
import { stripSdrPngColourTags } from "@hyperframes/core/compiler/png-colour-tags";
|
|
3874
3875
|
import { Readable } from "stream";
|
|
3875
3876
|
import { join as join8, resolve as resolve4 } from "path";
|
|
3876
3877
|
import { createHash as createHash2 } from "crypto";
|
|
@@ -4567,8 +4568,9 @@ ${etag}`;
|
|
|
4567
4568
|
servedContentType = PROXY_VARIANT_CONFIG[proxyVariant].contentType;
|
|
4568
4569
|
}
|
|
4569
4570
|
const textBuffer = isText ? Buffer.from(readFileSync6(file, "utf-8"), "utf-8") : null;
|
|
4570
|
-
const
|
|
4571
|
-
const
|
|
4571
|
+
const heldBuffer = textBuffer ?? (contentType === "image/png" ? stripSdrPngColourTags(readFileSync6(file)) : null);
|
|
4572
|
+
const totalSize = heldBuffer ? heldBuffer.length : statSync4(servedPath).size;
|
|
4573
|
+
const bodyFor = (start, end) => heldBuffer ? new Uint8Array(heldBuffer.subarray(start, end + 1)) : (
|
|
4572
4574
|
// Node's web stream type and the DOM one do not overlap for tsc on
|
|
4573
4575
|
// every platform's lib set; the double cast is the documented bridge.
|
|
4574
4576
|
Readable.toWeb(
|
|
@@ -6670,9 +6672,12 @@ function registerHistoryRoutes(api, adapter) {
|
|
|
6670
6672
|
}
|
|
6671
6673
|
|
|
6672
6674
|
// src/helpers/previewErrorPage.ts
|
|
6673
|
-
import {
|
|
6675
|
+
import {
|
|
6676
|
+
refusedPreviewMessage,
|
|
6677
|
+
STUDIO_PREVIEW_ERRORS as STUDIO_PREVIEW_ERRORS2
|
|
6678
|
+
} from "@hyperframes/core/studio-preview-mark";
|
|
6674
6679
|
function previewErrorPage(status) {
|
|
6675
|
-
const message =
|
|
6680
|
+
const message = refusedPreviewMessage(status);
|
|
6676
6681
|
return `<!doctype html><meta charset="utf-8"><script>window.${STUDIO_PREVIEW_ERRORS2}=[${JSON.stringify(message)}]</script><p>${message}</p>`;
|
|
6677
6682
|
}
|
|
6678
6683
|
|
|
@@ -167,6 +167,9 @@ interface StudioApiAdapter {
|
|
|
167
167
|
gifLoop?: number;
|
|
168
168
|
crf?: number;
|
|
169
169
|
videoBitrate?: string;
|
|
170
|
+
keyframeIntervalSeconds?: number;
|
|
171
|
+
maxBitrate?: string;
|
|
172
|
+
bufferSize?: string;
|
|
170
173
|
videoFrameFormat?: "auto" | "jpg" | "png";
|
|
171
174
|
hdrMode?: "auto" | "force-hdr" | "force-sdr";
|
|
172
175
|
jobId: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hyperframes/studio-server",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.207",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/heygen-com/hyperframes",
|
|
@@ -84,8 +84,8 @@
|
|
|
84
84
|
"linkedom": "^0.18.12",
|
|
85
85
|
"postcss": "^8.5.8",
|
|
86
86
|
"postcss-selector-parser": "^7.1.2",
|
|
87
|
-
"@hyperframes/core": "0.8.
|
|
88
|
-
"@hyperframes/parsers": "0.8.
|
|
87
|
+
"@hyperframes/core": "0.8.207",
|
|
88
|
+
"@hyperframes/parsers": "0.8.207"
|
|
89
89
|
},
|
|
90
90
|
"devDependencies": {
|
|
91
91
|
"@types/node": "^25.0.10",
|