mirror of
https://github.com/webadderallorg/Recordly.git
synced 2026-09-24 23:05:49 +00:00
perf(export): default MP4 exports to modern pipeline
This commit is contained in:
@@ -55,6 +55,45 @@ import {
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const IS_SMOKE_EXPORT = process.env.RECORDLY_SMOKE_EXPORT === "1";
|
||||
|
||||
function isBrokenPipeError(error: unknown): boolean {
|
||||
return (
|
||||
typeof error === "object" &&
|
||||
error !== null &&
|
||||
"code" in error &&
|
||||
(error as NodeJS.ErrnoException).code === "EPIPE"
|
||||
);
|
||||
}
|
||||
|
||||
function configureSmokeExportPipeGuards() {
|
||||
if (!IS_SMOKE_EXPORT) {
|
||||
return;
|
||||
}
|
||||
|
||||
const ignoreBrokenPipe = (error: Error) => {
|
||||
if (!isBrokenPipeError(error)) {
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
process.stdout.on("error", ignoreBrokenPipe);
|
||||
process.stderr.on("error", ignoreBrokenPipe);
|
||||
|
||||
for (const method of ["log", "warn", "error"] as const) {
|
||||
const original = console[method].bind(console);
|
||||
console[method] = (...args: unknown[]) => {
|
||||
try {
|
||||
original(...args);
|
||||
} catch (error) {
|
||||
if (!isBrokenPipeError(error)) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
configureSmokeExportPipeGuards();
|
||||
|
||||
app.commandLine.appendSwitch("ignore-gpu-blocklist");
|
||||
app.commandLine.appendSwitch("enable-unsafe-webgpu");
|
||||
app.commandLine.appendSwitch("enable-gpu-rasterization");
|
||||
|
||||
@@ -11,7 +11,7 @@ import ffmpegStatic from "ffmpeg-static";
|
||||
const execFileAsync = promisify(execFile);
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const repoRoot = path.resolve(__dirname, "..");
|
||||
const mainEntry = path.join(repoRoot, "dist-electron", "main.js");
|
||||
const mainEntry = path.join(repoRoot, "dist-electron", "main.cjs");
|
||||
const rendererEntry = path.join(repoRoot, "dist", "index.html");
|
||||
|
||||
const width = parseEvenInteger(process.env.RECORDLY_BENCH_EXPORT_WIDTH ?? "1280", "Width");
|
||||
|
||||
@@ -519,6 +519,7 @@ export default function VideoEditor() {
|
||||
const [isSavingProjectName, setIsSavingProjectName] = useState(false);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [smokeExportReadinessTick, setSmokeExportReadinessTick] = useState(0);
|
||||
const [isPlaying, setIsPlaying] = useState(false);
|
||||
const [currentTime, setCurrentTime] = useState(0);
|
||||
const [duration, setDuration] = useState(0);
|
||||
@@ -4042,7 +4043,7 @@ export default function VideoEditor() {
|
||||
: (settings.mp4FrameRate ?? mp4FrameRate);
|
||||
const pipelineModel = smokeExportConfig.enabled
|
||||
? (smokeExportConfig.pipelineModel ??
|
||||
(smokeExportConfig.useNativeExport ? "modern" : "legacy"))
|
||||
(smokeExportConfig.useNativeExport ? "modern" : exportPipelineModel))
|
||||
: (settings.pipelineModel ?? exportPipelineModel);
|
||||
const backendPreference =
|
||||
pipelineModel === "legacy"
|
||||
@@ -4423,14 +4424,65 @@ export default function VideoEditor() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
const writeSmokeStartupFailure = (reason: string, detail: Record<string, unknown> = {}) => {
|
||||
smokeExportStartedRef.current = true;
|
||||
console.error(`[smoke-export] ${error}`);
|
||||
window.close();
|
||||
void writeSmokeExportReport(smokeExportConfig.outputPath, {
|
||||
success: false,
|
||||
phase: "startup",
|
||||
reason,
|
||||
...detail,
|
||||
}).finally(() => window.close());
|
||||
};
|
||||
|
||||
if (error) {
|
||||
writeSmokeStartupFailure("editor-error", { error });
|
||||
return;
|
||||
}
|
||||
|
||||
if (!videoPath || loading) {
|
||||
if (smokeExportReadinessTick >= 80) {
|
||||
writeSmokeStartupFailure("video-not-loaded", {
|
||||
videoPath,
|
||||
loading,
|
||||
duration,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const retryTimeout = window.setTimeout(() => {
|
||||
setSmokeExportReadinessTick((tick) => tick + 1);
|
||||
}, 100);
|
||||
return () => window.clearTimeout(retryTimeout);
|
||||
}
|
||||
|
||||
const videoElement = videoPlaybackRef.current?.video;
|
||||
if (!videoElement || videoElement.readyState < 1 || duration <= 0) {
|
||||
if (smokeExportReadinessTick >= 80) {
|
||||
writeSmokeStartupFailure("video-metadata-not-ready", {
|
||||
hasVideoElement: Boolean(videoElement),
|
||||
readyState: videoElement?.readyState ?? null,
|
||||
duration,
|
||||
videoPath,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const retryTimeout = window.setTimeout(() => {
|
||||
setSmokeExportReadinessTick((tick) => tick + 1);
|
||||
}, 100);
|
||||
return () => window.clearTimeout(retryTimeout);
|
||||
}
|
||||
|
||||
if (
|
||||
smokeExportConfig.projectPath &&
|
||||
videoSourcePath &&
|
||||
cursorTelemetrySourcePath !== videoSourcePath &&
|
||||
smokeExportReadinessTick >= 80
|
||||
) {
|
||||
writeSmokeStartupFailure("cursor-telemetry-not-ready", {
|
||||
videoSourcePath,
|
||||
cursorTelemetrySourcePath,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4457,9 +4509,12 @@ export default function VideoEditor() {
|
||||
error,
|
||||
handleExport,
|
||||
loading,
|
||||
duration,
|
||||
smokeExportConfig.enabled,
|
||||
smokeExportConfig.encodingMode,
|
||||
smokeExportConfig.outputPath,
|
||||
smokeExportConfig.projectPath,
|
||||
smokeExportReadinessTick,
|
||||
videoPath,
|
||||
videoSourcePath,
|
||||
]);
|
||||
|
||||
@@ -56,6 +56,10 @@ describe("editorPreferences", () => {
|
||||
expect(DEFAULT_EDITOR_PREFERENCES.exportQuality).toBe("source");
|
||||
});
|
||||
|
||||
it("defaults MP4 exports to the modern pipeline", () => {
|
||||
expect(DEFAULT_EDITOR_PREFERENCES.exportPipelineModel).toBe("modern");
|
||||
});
|
||||
|
||||
it("loads stored editor control preferences", () => {
|
||||
vi.stubGlobal(
|
||||
"localStorage",
|
||||
@@ -282,7 +286,13 @@ describe("editorPreferences", () => {
|
||||
cursorClickBounceDuration: 350,
|
||||
cursorSway: 1.5,
|
||||
borderRadius: 18,
|
||||
padding: 30,
|
||||
padding: {
|
||||
top: 30,
|
||||
bottom: 30,
|
||||
left: 30,
|
||||
right: 30,
|
||||
linked: true,
|
||||
},
|
||||
frame: DEFAULT_EDITOR_PREFERENCES.frame,
|
||||
aspectRatio: "4:5",
|
||||
exportEncodingMode: "quality",
|
||||
|
||||
@@ -156,7 +156,7 @@ export function normalizeExportPipelineModel(value: unknown): ExportPipelineMode
|
||||
return value;
|
||||
}
|
||||
|
||||
return "legacy";
|
||||
return "modern";
|
||||
}
|
||||
|
||||
export function normalizeExportMp4FrameRate(value: unknown): ExportMp4FrameRate {
|
||||
|
||||
Reference in New Issue
Block a user