Files
hyperframes/packages/studio-server/package-subpaths.json
T
Vance IngallsandClaude Opus 5.5 9244c47328 feat(studio): normalize loudness and duck under voice, with a limiter report (4/8) (#4816)
* feat(studio-server): share loudness measurement with an absolute target and video support

normalize-audio moves its measure/plan code into @hyperframes/studio-server/loudness,
gains an absolute mode (--lufs, default -16, clamped at +12 dB and -1.5 dBTP) and
accepts <video> clips with sound. Adds the @hyperframes/core/audible-video subpath.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(studio-server): add a measure-only loudness normalize endpoint

POST /projects/:id/loudness/normalize measures a clip's played window (audio or
video) and answers the -16 LUFS data-volume plan; Studio writes the attribute.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore: register the loudness and audible-video subpaths in their descriptors

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* style: format the loudness and audible-video subpath descriptors

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(studio): add Normalize loudness and Duck under voice to the clip menu

Normalize measures the clip on studio-server and writes data-volume as one undoable
edit; Duck toggles a carve against every overlapping voice (audio or video with
sound) at the default strength. Both live in clipMenuAudioItems with one hook-in.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* refactor(studio): tighten carveOutput docs to the package comment share

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(producer): report how far the true-peak limiter lowered the export

The AAC true-peak pass now returns its attenuation; the render logs "Audio lowered
by X.X dB to stay under -1 dBTP" and sets RenderJob.audioLoweredDb, which Studio
servers carry in the complete SSE event and the /renders record. Also exports
useAudioMetersVisible from @hyperframes/studio for hosts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(studio-server): scan HTML start tags without a backtracking regex

The start-tag regex backtracked quadratically on '<' followed by many spaces
(CodeQL js/polynomial-redos). A linear character scan reads the same name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(studio): refuse to normalize a volume-automated clip and honour save outcomes

A volume lane owns the clip's gain in preview and render, so writing
data-volume changed nothing while the toast claimed success; Normalize now
refuses with a clear message. Normalize and Duck also check each quiet-save
outcome, stop at the first failed or refused write and report it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(core): drop the duplicate audible-video subpath descriptor

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 03:51:34 +00:00

97 lines
3.3 KiB
JSON

{
"package": "@hyperframes/studio-server",
"localNodeRuntime": true,
"subpaths": {
".": {
"source": "./src/index.ts",
"runtime": "./dist/index.js",
"types": "./dist/index.d.ts",
"environments": ["bun", "node"]
},
"./package.json": {
"source": "./package.json",
"runtime": "./package.json",
"types": null,
"environments": ["bun", "node"]
},
"./screenshot-clip": {
"source": "./src/helpers/screenshotClip.ts",
"runtime": "./dist/helpers/screenshotClip.js",
"types": "./dist/helpers/screenshotClip.d.ts",
"environments": ["bun", "node"]
},
"./safe-path": {
"source": "./src/helpers/safePath.ts",
"runtime": "./dist/helpers/safePath.js",
"types": "./dist/helpers/safePath.d.ts",
"environments": ["bun", "node"]
},
"./hf-ids": {
"source": "./src/helpers/hfIdPersist.ts",
"runtime": "./dist/helpers/hfIdPersist.js",
"types": "./dist/helpers/hfIdPersist.d.ts",
"environments": ["bun", "node"]
},
"./history": {
"source": "./src/history/index.ts",
"runtime": "./dist/history/index.js",
"types": "./dist/history/index.d.ts",
"environments": ["bun", "node"]
},
"./manual-edits-render-script": {
"source": "./src/helpers/manualEditsRenderScript.ts",
"runtime": "./dist/helpers/manualEditsRenderScript.js",
"types": "./dist/helpers/manualEditsRenderScript.d.ts",
"environments": ["bun", "node"]
},
"./studio-motion-render-script": {
"source": "./src/helpers/studioMotionRenderScript.ts",
"runtime": "./dist/helpers/studioMotionRenderScript.js",
"types": "./dist/helpers/studioMotionRenderScript.d.ts",
"environments": ["bun", "node"]
},
"./draft-markers": {
"source": "./src/helpers/draftMarkers.ts",
"runtime": "./dist/helpers/draftMarkers.js",
"types": "./dist/helpers/draftMarkers.d.ts",
"environments": ["browser", "bun", "node"]
},
"./finite-mutation": {
"source": "./src/helpers/finiteMutation.ts",
"runtime": "./dist/helpers/finiteMutation.js",
"types": "./dist/helpers/finiteMutation.d.ts",
"environments": ["bun", "node"]
},
"./source-mutation": {
"source": "./src/helpers/sourceMutation.ts",
"runtime": "./dist/helpers/sourceMutation.js",
"types": "./dist/helpers/sourceMutation.d.ts",
"environments": ["browser", "bun", "node"]
},
"./media-codec-map": {
"source": "./src/helpers/mediaCodecMap.ts",
"runtime": "./dist/helpers/mediaCodecMap.js",
"types": "./dist/helpers/mediaCodecMap.d.ts",
"environments": ["bun", "node"]
},
"./proxy-transcoder": {
"source": "./src/helpers/proxyTranscoder.ts",
"runtime": "./dist/helpers/proxyTranscoder.js",
"types": "./dist/helpers/proxyTranscoder.d.ts",
"environments": ["bun", "node"]
},
"./loudness": {
"source": "./src/helpers/loudness.ts",
"runtime": "./dist/helpers/loudness.js",
"types": "./dist/helpers/loudness.d.ts",
"environments": ["bun", "node"]
},
"./media-proxy-preview": {
"source": "./src/helpers/mediaProxyPreview.ts",
"runtime": "./dist/helpers/mediaProxyPreview.js",
"types": "./dist/helpers/mediaProxyPreview.d.ts",
"environments": ["bun", "node"]
}
}
}