mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-11-06 14:47:29 +00:00
* perf(studio): preview decodes hard-to-play videos at the size they are shown Studio's copy of an HEVC or ProRes clip was made at the source's full size, so a 4K clip was decoded at 4K inside a preview a few hundred pixels wide, and back-to-back 4K clips flashed the background at their cuts. The player now reports how large it shows the composition, the runtime asks for a copy sized to the shown video (on a ladder of sizes, never above the source), and Studio stops pre-warming source-size copies. CLI play, static serving, publish and renders keep the source-size copy. * fix(studio): sized preview copies follow zoom, hover previews and the newest size Studio reports the preview's on-screen scale when a zoom settles and for composition hover previews, which no player measures. The runtime loads only the newest size asked for, regrows a first copy made while the frame grew, and never replaces a copy with one smaller on either side. The player's scale is measured against the frame's own layout width. * fix(studio): keep comment shares and file sizes within the repo ratchets * test(studio-server): end the sizing test's ffprobe options before its input * fix(studio): hover previews report their size once their runtime is ready
33 lines
1.3 KiB
TypeScript
33 lines
1.3 KiB
TypeScript
/** Query parameter carrying the largest box, in device pixels, a preview shows a proxied video at. */
|
|
export const PREVIEW_PROXY_BOX_PARAM = "hf-proxy-box";
|
|
|
|
export type PreviewProxyBox = { width: number; height: number };
|
|
|
|
// 256 * 2^(k/2), even: nearby boxes share one cached copy, and a rung overshoots by at most ~41%.
|
|
const RUNGS = [256, 362, 512, 724, 1024, 1448, 2048, 2896, 4096, 5792, 8192];
|
|
|
|
function rungAtLeast(pixels: number): number | null {
|
|
if (!(pixels > 0)) return null;
|
|
return RUNGS.find((rung) => rung >= pixels) ?? null;
|
|
}
|
|
|
|
/** Rounds a shown box up to the size ladder; null when it is empty or larger than any rung. */
|
|
export function quantizePreviewProxyBox(width: number, height: number): PreviewProxyBox | null {
|
|
const w = rungAtLeast(width);
|
|
const h = rungAtLeast(height);
|
|
return w && h ? { width: w, height: h } : null;
|
|
}
|
|
|
|
export function formatPreviewProxyBox(box: PreviewProxyBox): string {
|
|
return `${box.width}x${box.height}`;
|
|
}
|
|
|
|
/** Accepts only ladder rungs, so a client cannot make one cached copy per pixel. */
|
|
export function parsePreviewProxyBox(raw: string): PreviewProxyBox | null {
|
|
const match = /^(\d{3,4})x(\d{3,4})$/.exec(raw);
|
|
if (!match) return null;
|
|
const width = Number(match[1]);
|
|
const height = Number(match[2]);
|
|
return RUNGS.includes(width) && RUNGS.includes(height) ? { width, height } : null;
|
|
}
|