@hyperframes/studio-server 0.8.206 → 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.
@@ -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 options = { ...rate.options };
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,6 +1,8 @@
1
1
  import {
2
+ encoderJobOptions,
2
3
  parseEncoderOptions
3
- } from "../chunk-2GPN2OSU.js";
4
+ } from "../chunk-ZR3T4TKU.js";
4
5
  export {
6
+ encoderJobOptions,
5
7
  parseEncoderOptions
6
8
  };
@@ -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-DeICCYb5.js';
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-DeICCYb5.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-DeICCYb5.js';
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-2GPN2OSU.js";
27
+ } from "./chunk-ZR3T4TKU.js";
28
28
  import {
29
29
  DEFAULT_HISTORY_ROOT,
30
30
  DELETED_VERSION,
@@ -6672,9 +6672,12 @@ function registerHistoryRoutes(api, adapter) {
6672
6672
  }
6673
6673
 
6674
6674
  // src/helpers/previewErrorPage.ts
6675
- import { STUDIO_PREVIEW_ERRORS as STUDIO_PREVIEW_ERRORS2 } from "@hyperframes/core/studio-preview-mark";
6675
+ import {
6676
+ refusedPreviewMessage,
6677
+ STUDIO_PREVIEW_ERRORS as STUDIO_PREVIEW_ERRORS2
6678
+ } from "@hyperframes/core/studio-preview-mark";
6676
6679
  function previewErrorPage(status) {
6677
- const message = `The preview page could not be loaded (HTTP ${status}).`;
6680
+ const message = refusedPreviewMessage(status);
6678
6681
  return `<!doctype html><meta charset="utf-8"><script>window.${STUDIO_PREVIEW_ERRORS2}=[${JSON.stringify(message)}]</script><p>${message}</p>`;
6679
6682
  }
6680
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.206",
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/parsers": "0.8.206",
88
- "@hyperframes/core": "0.8.206"
87
+ "@hyperframes/core": "0.8.207",
88
+ "@hyperframes/parsers": "0.8.207"
89
89
  },
90
90
  "devDependencies": {
91
91
  "@types/node": "^25.0.10",