@hyperframes/studio-server 0.8.154 → 0.8.156
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-GR4TX52A.js +56 -0
- package/dist/helpers/encoderOptions.d.ts +25 -0
- package/dist/helpers/encoderOptions.js +6 -0
- package/dist/helpers/mediaProxyPreview.d.ts +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +6 -0
- package/dist/{mediaProxyPreview-DB1EEdxc.d.ts → mediaProxyPreview-J8vlAvrx.d.ts} +4 -0
- package/package.json +7 -3
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// src/helpers/encoderOptions.ts
|
|
2
|
+
var CRF_MAX_BY_FORMAT = { mp4: 51, webm: 63 };
|
|
3
|
+
var VIDEO_BITRATE = /^\d+(\.\d+)?[kKmMgG]?$/;
|
|
4
|
+
var VIDEO_FRAME_FORMATS = ["auto", "jpg", "png"];
|
|
5
|
+
var HDR_MODES = ["auto", "force-hdr", "force-sdr"];
|
|
6
|
+
var isSet = (value) => value !== void 0 && value !== null;
|
|
7
|
+
function oneOf(value, allowed) {
|
|
8
|
+
return typeof value === "string" && allowed.includes(value);
|
|
9
|
+
}
|
|
10
|
+
function parseCrf(crf, format, max) {
|
|
11
|
+
if (typeof crf !== "number" || !Number.isInteger(crf) || crf < 0 || crf > max) {
|
|
12
|
+
return { ok: false, error: `crf must be an integer from 0 to ${max} for ${format}` };
|
|
13
|
+
}
|
|
14
|
+
return { ok: true, options: { crf } };
|
|
15
|
+
}
|
|
16
|
+
function parseVideoBitrate(videoBitrate) {
|
|
17
|
+
if (typeof videoBitrate !== "string" || !VIDEO_BITRATE.test(videoBitrate)) {
|
|
18
|
+
return { ok: false, error: 'videoBitrate must look like "10M", "2500k" or "8000000"' };
|
|
19
|
+
}
|
|
20
|
+
return { ok: true, options: { videoBitrate } };
|
|
21
|
+
}
|
|
22
|
+
function parseRateControl(body, format) {
|
|
23
|
+
const max = CRF_MAX_BY_FORMAT[format];
|
|
24
|
+
if (max === void 0) return { ok: true, options: {} };
|
|
25
|
+
if (isSet(body.crf) && isSet(body.videoBitrate)) {
|
|
26
|
+
return { ok: false, error: "use either crf or videoBitrate, not both" };
|
|
27
|
+
}
|
|
28
|
+
if (isSet(body.crf)) return parseCrf(body.crf, format, max);
|
|
29
|
+
if (isSet(body.videoBitrate)) return parseVideoBitrate(body.videoBitrate);
|
|
30
|
+
return { ok: true, options: {} };
|
|
31
|
+
}
|
|
32
|
+
function parseEncoderOptions(body, format) {
|
|
33
|
+
const rate = parseRateControl(body, format);
|
|
34
|
+
if (!rate.ok) return rate;
|
|
35
|
+
const options = { ...rate.options };
|
|
36
|
+
if (isSet(body.videoFrameFormat)) {
|
|
37
|
+
if (!oneOf(body.videoFrameFormat, VIDEO_FRAME_FORMATS)) {
|
|
38
|
+
return {
|
|
39
|
+
ok: false,
|
|
40
|
+
error: `videoFrameFormat must be one of ${VIDEO_FRAME_FORMATS.join(", ")}`
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
options.videoFrameFormat = body.videoFrameFormat;
|
|
44
|
+
}
|
|
45
|
+
if (isSet(body.hdrMode)) {
|
|
46
|
+
if (!oneOf(body.hdrMode, HDR_MODES)) {
|
|
47
|
+
return { ok: false, error: `hdrMode must be one of ${HDR_MODES.join(", ")}` };
|
|
48
|
+
}
|
|
49
|
+
options.hdrMode = body.hdrMode;
|
|
50
|
+
}
|
|
51
|
+
return { ok: true, options };
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export {
|
|
55
|
+
parseEncoderOptions
|
|
56
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
declare const VIDEO_FRAME_FORMATS: readonly ["auto", "jpg", "png"];
|
|
2
|
+
declare const HDR_MODES: readonly ["auto", "force-hdr", "force-sdr"];
|
|
3
|
+
interface EncoderOptions {
|
|
4
|
+
crf?: number;
|
|
5
|
+
videoBitrate?: string;
|
|
6
|
+
videoFrameFormat?: (typeof VIDEO_FRAME_FORMATS)[number];
|
|
7
|
+
hdrMode?: (typeof HDR_MODES)[number];
|
|
8
|
+
}
|
|
9
|
+
interface EncoderOptionsBody {
|
|
10
|
+
crf?: unknown;
|
|
11
|
+
videoBitrate?: unknown;
|
|
12
|
+
videoFrameFormat?: unknown;
|
|
13
|
+
hdrMode?: unknown;
|
|
14
|
+
}
|
|
15
|
+
type Parsed = {
|
|
16
|
+
ok: true;
|
|
17
|
+
options: EncoderOptions;
|
|
18
|
+
} | {
|
|
19
|
+
ok: false;
|
|
20
|
+
error: string;
|
|
21
|
+
};
|
|
22
|
+
/** Explicit encoder overrides from a render request. MOV (ProRes) takes no rate control. */
|
|
23
|
+
declare function parseEncoderOptions(body: EncoderOptionsBody, format: string): Parsed;
|
|
24
|
+
|
|
25
|
+
export { type EncoderOptionsBody, 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-J8vlAvrx.js';
|
|
3
3
|
import './mediaCodecMap.js';
|
|
4
4
|
import '@hyperframes/parsers';
|
|
5
5
|
import '@hyperframes/core/compiler';
|
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-J8vlAvrx.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-J8vlAvrx.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 HistoryResult, f as HistoryTarget, g as HistoryWho, h as HistoryWindow, M as MAX_WINDOW_IDLE_MS, P as ProjectHistory, i as ProjectHistoryOptions, j as ProjectHistoryView, U as UNDO_MODES, k as UndoMode, o as openProjectHistory, r as readProjectHistory } from './projectHistory-C5dpCjPU.js';
|
|
5
5
|
export { ArtifactCapture, ArtifactInput, ArtifactRecord, HistoryBusyError, HistoryIdError, ProjectHistoryRecord, PrunedHistory, RenderRecord, VideoState, artifactDirectory, beginArtifactCapture, forgetRecordedArtifacts, historyCache, listProjectHistories, pruneGoneProjectHistories, recordArtifact, recordArtifacts, recordRenderSuccess, registerRenderOutput } from './history/index.js';
|
|
6
6
|
export { CACHE_DIR_NAME as PROXY_CACHE_DIR_NAME } from './helpers/proxyTranscoder.js';
|
package/dist/index.js
CHANGED
|
@@ -22,6 +22,9 @@ import {
|
|
|
22
22
|
isCompositionSource,
|
|
23
23
|
stampProjectHfIds
|
|
24
24
|
} from "./chunk-6RICWA3B.js";
|
|
25
|
+
import {
|
|
26
|
+
parseEncoderOptions
|
|
27
|
+
} from "./chunk-GR4TX52A.js";
|
|
25
28
|
import {
|
|
26
29
|
DEFAULT_HISTORY_ROOT,
|
|
27
30
|
DELETED_VERSION,
|
|
@@ -4634,6 +4637,8 @@ function registerRenderRoutes(api, adapter) {
|
|
|
4634
4637
|
}
|
|
4635
4638
|
variables = body.variables;
|
|
4636
4639
|
}
|
|
4640
|
+
const encoder = parseEncoderOptions(body, format);
|
|
4641
|
+
if (!encoder.ok) return c.json({ error: encoder.error }, 400);
|
|
4637
4642
|
const now = /* @__PURE__ */ new Date();
|
|
4638
4643
|
const jobId = `${project.id}_${formatRenderOutputTimestamp(now)}`;
|
|
4639
4644
|
const rendersDir = adapter.rendersDir(project);
|
|
@@ -4650,6 +4655,7 @@ function registerRenderRoutes(api, adapter) {
|
|
|
4650
4655
|
outputResolution,
|
|
4651
4656
|
composition,
|
|
4652
4657
|
variables,
|
|
4658
|
+
...encoder.options,
|
|
4653
4659
|
useGpu: body.gpu === true && format === "mp4",
|
|
4654
4660
|
distinctId: typeof body.telemetryDistinctId === "string" ? body.telemetryDistinctId : void 0,
|
|
4655
4661
|
telemetryOptOut: body.telemetryOptOut === true
|
|
@@ -161,6 +161,10 @@ interface StudioApiAdapter {
|
|
|
161
161
|
*/
|
|
162
162
|
fps: _hyperframes_core.Fps;
|
|
163
163
|
quality: string;
|
|
164
|
+
crf?: number;
|
|
165
|
+
videoBitrate?: string;
|
|
166
|
+
videoFrameFormat?: "auto" | "jpg" | "png";
|
|
167
|
+
hdrMode?: "auto" | "force-hdr" | "force-sdr";
|
|
164
168
|
jobId: string;
|
|
165
169
|
/**
|
|
166
170
|
* The triggering browser profile has telemetry disabled (localStorage
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hyperframes/studio-server",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.156",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/heygen-com/hyperframes",
|
|
@@ -70,6 +70,10 @@
|
|
|
70
70
|
"./media-proxy-preview": {
|
|
71
71
|
"import": "./dist/helpers/mediaProxyPreview.js",
|
|
72
72
|
"types": "./dist/helpers/mediaProxyPreview.d.ts"
|
|
73
|
+
},
|
|
74
|
+
"./encoder-options": {
|
|
75
|
+
"import": "./dist/helpers/encoderOptions.js",
|
|
76
|
+
"types": "./dist/helpers/encoderOptions.d.ts"
|
|
73
77
|
}
|
|
74
78
|
},
|
|
75
79
|
"publishConfig": {
|
|
@@ -81,8 +85,8 @@
|
|
|
81
85
|
"postcss": "^8.5.8",
|
|
82
86
|
"postcss-selector-parser": "^7.1.2",
|
|
83
87
|
"sharp": "^0.35.0",
|
|
84
|
-
"@hyperframes/core": "0.8.
|
|
85
|
-
"@hyperframes/parsers": "0.8.
|
|
88
|
+
"@hyperframes/core": "0.8.156",
|
|
89
|
+
"@hyperframes/parsers": "0.8.156"
|
|
86
90
|
},
|
|
87
91
|
"devDependencies": {
|
|
88
92
|
"@types/node": "^25.0.10",
|