fix(export): scale mp4 bitrate with frame rate

This commit is contained in:
wiiiii123
2026-05-09 12:06:34 +07:00
parent 34f46697d8
commit d653f43e28
2 changed files with 28 additions and 0 deletions
+22
View File
@@ -15,6 +15,28 @@ describe("export bitrate policy", () => {
).toBe(27_000_000);
});
it("raises high-resolution 60fps source-quality exports above the 30fps budget", () => {
const sharedOptions = {
width: 2560,
height: 1440,
quality: "source" as const,
encodingMode: "quality" as const,
};
const thirtyFpsBitrate = getMp4ExportBitrate({
...sharedOptions,
frameRate: 30,
});
const sixtyFpsBitrate = getMp4ExportBitrate({
...sharedOptions,
frameRate: 60,
});
expect(thirtyFpsBitrate).toBe(45_000_000);
expect(sixtyFpsBitrate).toBeGreaterThan(thirtyFpsBitrate);
expect(sixtyFpsBitrate).toBe(63_639_610);
});
it("keeps modern native static-layout source exports high enough for screen text", () => {
expect(
getMp4ExportBitrate({
+6
View File
@@ -2,6 +2,7 @@ import type { ExportEncodingMode, ExportMp4FrameRate, ExportQuality } from "./ty
const MIN_MP4_BITRATE = 2_000_000;
const REFERENCE_PIXEL_RATE = 1920 * 1080 * 30;
const REFERENCE_FRAME_RATE = 30;
export function getEncodingModeBitrateMultiplier(encodingMode: ExportEncodingMode): number {
switch (encodingMode) {
@@ -41,6 +42,10 @@ function getBaseMp4ExportBitrate(width: number, height: number, quality: ExportQ
return 30_000_000;
}
function getFrameRateBitrateMultiplier(frameRate: ExportMp4FrameRate): number {
return Math.sqrt(Math.max(1, frameRate / REFERENCE_FRAME_RATE));
}
function getModernNativeStaticLayoutBitrateCap(
width: number,
height: number,
@@ -87,6 +92,7 @@ export function getMp4ExportBitrate(options: {
}): number {
const requestedBitrate = Math.round(
getBaseMp4ExportBitrate(options.width, options.height, options.quality) *
getFrameRateBitrateMultiplier(options.frameRate) *
getEncodingModeBitrateMultiplier(options.encodingMode),
);
const nativeStaticLayoutBitrate =