refactor(export): wire lightning route policy

This commit is contained in:
wiiiii123
2026-05-22 18:47:30 +07:00
parent b5132de3e2
commit 90ad8a694b
2 changed files with 70 additions and 7 deletions
@@ -118,6 +118,64 @@ describe("ModernVideoExporter native fallback routing", () => {
expect(mocks.muxerFinalize).toHaveBeenCalledTimes(1);
}, 15_000);
it("tries Windows auto static-layout before starting the streaming native encoder", async () => {
vi.stubGlobal("navigator", {
platform: "Win32",
userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
});
const { ModernVideoExporter } = await import("./modernVideoExporter");
const staticLayoutResult = {
success: true,
blob: new Blob([], { type: "video/mp4" }),
};
const exporter = new ModernVideoExporter({
videoUrl: "file:///recording.mp4",
width: 1920,
height: 1080,
frameRate: 30,
bitrate: 8_000_000,
wallpaper: "#101010",
padding: 0,
borderRadius: 0,
backgroundBlur: 0,
shadowIntensity: 0,
showShadow: false,
cropRegion: { x: 0, y: 0, width: 1, height: 1 },
experimentalNativeExport: true,
backendPreference: "auto",
} as never) as unknown as {
export: () => Promise<{ success: boolean; blob?: Blob; error?: string }>;
initializeEncoder: () => Promise<unknown>;
loadNativeStaticLayoutVideoInfo: () => Promise<unknown>;
tryExportNativeStaticLayout: () => Promise<unknown>;
tryStartNativeVideoExport: () => Promise<boolean>;
};
const initializeEncoder = vi.spyOn(exporter, "initializeEncoder").mockResolvedValue({
codec: "avc1.640034",
hardwareAcceleration: "prefer-hardware",
});
const loadNativeStaticLayoutVideoInfo = vi
.spyOn(exporter, "loadNativeStaticLayoutVideoInfo")
.mockResolvedValue(mocks.videoInfo);
const tryExportNativeStaticLayout = vi
.spyOn(exporter, "tryExportNativeStaticLayout")
.mockResolvedValue(staticLayoutResult);
const tryStartNativeVideoExport = vi
.spyOn(exporter, "tryStartNativeVideoExport")
.mockResolvedValue(true);
const result = await exporter.export();
expect(result).toBe(staticLayoutResult);
expect(loadNativeStaticLayoutVideoInfo).toHaveBeenCalledTimes(1);
expect(tryExportNativeStaticLayout).toHaveBeenCalledTimes(1);
expect(tryStartNativeVideoExport).not.toHaveBeenCalled();
expect(initializeEncoder).not.toHaveBeenCalled();
expect(mocks.streamingDecoderLoadMetadata).not.toHaveBeenCalled();
}, 15_000);
it("retries the main decode path once with a readable file-backed source", async () => {
const { ModernVideoExporter } = await import("./modernVideoExporter");
mocks.streamingDecoderGetEffectiveDuration.mockReturnValue(1);
+12 -7
View File
@@ -8,8 +8,8 @@ import type {
CursorStyle,
CursorTelemetryPoint,
Padding,
SpeedRegion,
SourceAudioTrackSettings,
SpeedRegion,
TrimRegion,
WebcamOverlaySettings,
ZoomMotionBlurTuning,
@@ -49,7 +49,11 @@ import {
isVideoWallpaperSource,
} from "@/lib/wallpapers";
import { AudioProcessor, isAacAudioEncodingSupported } from "./audioEncoder";
import { normalizeLightningRuntimePlatform, shouldPreferNativeAutoBackend } from "./backendPolicy";
import {
normalizeLightningRuntimePlatform,
shouldPreferNativeAutoBackend,
shouldPreferNativeStaticLayoutBeforeBreeze,
} from "./backendPolicy";
import { buildEditedTrackSourceSegments, classifyEditedTrackStrategy } from "./editedTrackStrategy";
import {
type ExportBackpressureProfile,
@@ -376,14 +380,15 @@ export class ModernVideoExporter {
const runtimePlatform = this.getRuntimePlatform();
let useNativeEncoder = false;
let triedNativeStaticLayoutWithProbe = false;
let shouldDeferNativeEncoderStart = backendPreference === "breeze";
let shouldDeferNativeEncoderStart =
backendPreference === "breeze" ||
shouldPreferNativeStaticLayoutBeforeBreeze(runtimePlatform, backendPreference);
this.lastNativeExportError = null;
let stageStartedAt = this.getNowMs();
if (backendPreference === "breeze") {
// Defer the streaming native encoder until after metadata is known.
// Static-layout exports can then use the faster Windows D3D compositor
// instead of unnecessarily rendering every frame through JS first.
if (shouldDeferNativeEncoderStart) {
// Defer the streaming native encoder until after metadata is known so
// static-layout exports can use the fastest compatible compositor first.
} else if (
backendPreference === "auto" &&
shouldPreferNativeAutoBackend(runtimePlatform)