mirror of
https://github.com/webadderallorg/Recordly.git
synced 2026-09-25 15:25:44 +00:00
Split all source files exceeding 500 lines into smaller, focused modules:
- electron/main.ts → mainBootstrapHelpers, mainRuntimeState, mainUpdateIntegration, mainWindowControls
- electron/windows.ts → editorWindows, hudWindows, windowShared
- electron/updater.ts → updaterDialogs, updaterEventHandlers, updaterShared
- electron/preload.ts → preloadExtensionsBridge, preloadUpdateBridge
- electron/ipc/register/recording.ts → recording/ directory with focused handlers
- src/components/video-editor/VideoEditor.tsx → EditorContent, EditorHeader, EditorSidebar, EditorToolbar, hooks/
- src/components/video-editor/SettingsPanel.tsx → settings/ directory with per-section components
- src/components/video-editor/AnnotationSettingsPanel.tsx → tab components
- src/components/video-editor/ExtensionManager.tsx → extension-manager/ directory
- src/components/video-editor/VideoPlayback.tsx → videoPlaybackComponent/ directory
- src/components/video-editor/projectPersistence.ts → projectPersistence{Normalization,Paths,Regions,Shared}.ts
- src/components/video-editor/timeline/TimelineEditor.tsx → TimelineEditor/ directory
- src/components/video-editor/types.ts → focused type modules
- src/components/launch/LaunchWindow.tsx → LaunchWindow/ directory
- src/hooks/useScreenRecorder.ts → useScreenRecorder/ directory
- src/lib/exporter/audioEncoder.ts → audioEncoder/ directory
- src/lib/exporter/frameRenderer.ts → frameRenderer modules
- src/lib/exporter/modernFrameRenderer.ts → filters and lifecycle modules
- src/lib/exporter/modernVideoExporter.ts → modernVideoExporter/ directory
- src/lib/exporter/videoExporter.ts → video-exporter/ directory
- src/lib/exporter/streamingDecoder.ts → streamingDecoderHelpers.ts
- src/lib/extensions/extensionHost.ts → extensionHost{ApiFactory,QueryApi,RegistrationApi,Shared,State}.ts
- src/lib/extensions/types.ts → focused type modules
- electron/native/ScreenCaptureKitRecorder.swift → ScreenCaptureKitRecorder/ directory
- scripts/benchmark-export-queues.mjs → benchmark-export-queues/ directory
- .github/workflows/release.yml → extracted merge-macos-metadata composite action
- scripts/build-native-helpers.mjs → updated for multi-file Swift compilation
Also incorporates upstream default export quality change (good → source).
253 lines
6.6 KiB
JavaScript
253 lines
6.6 KiB
JavaScript
import path from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
|
|
const MODERN_BACKEND_SWEEP = ["auto", "webcodecs", "breeze"];
|
|
const VARIANT_PRESETS = {
|
|
adaptive: { name: "adaptive" },
|
|
baseline: { name: "baseline", maxEncodeQueue: 120, maxDecodeQueue: 10, maxPendingFrames: 24 },
|
|
tuned: { name: "tuned", maxEncodeQueue: 240, maxDecodeQueue: 12, maxPendingFrames: 32 },
|
|
};
|
|
|
|
function parsePositiveInteger(rawValue, label) {
|
|
const parsed = Number.parseInt(rawValue, 10);
|
|
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
throw new Error(`${label} must be a positive integer`);
|
|
}
|
|
|
|
return parsed;
|
|
}
|
|
|
|
function parseEvenInteger(rawValue, label) {
|
|
const parsed = parsePositiveInteger(rawValue, label);
|
|
if (parsed % 2 !== 0) {
|
|
throw new Error(`${label} must be even`);
|
|
}
|
|
|
|
return parsed;
|
|
}
|
|
|
|
function parseExportPipeline(rawValue) {
|
|
if (rawValue === null || rawValue === "") {
|
|
return null;
|
|
}
|
|
|
|
if (rawValue === "legacy" || rawValue === "modern") {
|
|
return rawValue;
|
|
}
|
|
|
|
throw new Error("RECORDLY_BENCH_EXPORT_PIPELINE must be 'legacy' or 'modern'");
|
|
}
|
|
|
|
function parseExportBackend(rawValue) {
|
|
if (rawValue === null || rawValue === "") {
|
|
return null;
|
|
}
|
|
|
|
if (rawValue === "auto" || rawValue === "webcodecs" || rawValue === "breeze") {
|
|
return rawValue;
|
|
}
|
|
|
|
throw new Error("RECORDLY_BENCH_EXPORT_BACKEND must be 'auto', 'webcodecs', or 'breeze'");
|
|
}
|
|
|
|
function parseExportBackendList(rawValue) {
|
|
if (rawValue === null || rawValue === "") {
|
|
return null;
|
|
}
|
|
|
|
if (rawValue === "all") {
|
|
return [...MODERN_BACKEND_SWEEP];
|
|
}
|
|
|
|
const values = rawValue
|
|
.split(",")
|
|
.map((value) => value.trim())
|
|
.filter((value) => value.length > 0)
|
|
.map((value) => parseExportBackend(value))
|
|
.filter((value) => value !== null);
|
|
|
|
if (values.length === 0) {
|
|
throw new Error(
|
|
"RECORDLY_BENCH_EXPORT_BACKENDS must include at least one of: auto, webcodecs, breeze",
|
|
);
|
|
}
|
|
|
|
return [...new Set(values)];
|
|
}
|
|
|
|
function parseBenchmarkVariantList(rawValue) {
|
|
if (rawValue === null || rawValue === "") {
|
|
return null;
|
|
}
|
|
|
|
const values = rawValue
|
|
.split(",")
|
|
.map((value) => value.trim())
|
|
.filter((value) => value.length > 0);
|
|
|
|
if (values.length === 0) {
|
|
throw new Error(
|
|
"RECORDLY_BENCH_EXPORT_VARIANTS must include at least one of: adaptive, baseline, tuned",
|
|
);
|
|
}
|
|
|
|
for (const value of values) {
|
|
if (!(value in VARIANT_PRESETS)) {
|
|
throw new Error(
|
|
"RECORDLY_BENCH_EXPORT_VARIANTS must include only: adaptive, baseline, tuned",
|
|
);
|
|
}
|
|
}
|
|
|
|
return [...new Set(values)];
|
|
}
|
|
|
|
function parseExportEncodingMode(rawValue) {
|
|
if (rawValue === null || rawValue === "") {
|
|
return null;
|
|
}
|
|
|
|
if (rawValue === "fast" || rawValue === "balanced" || rawValue === "quality") {
|
|
return rawValue;
|
|
}
|
|
|
|
throw new Error("RECORDLY_BENCH_EXPORT_ENCODING_MODE must be 'fast', 'balanced', or 'quality'");
|
|
}
|
|
|
|
function parseExportShadowIntensity(rawValue) {
|
|
if (rawValue === null || rawValue === "") {
|
|
return null;
|
|
}
|
|
|
|
const parsed = Number.parseFloat(rawValue);
|
|
if (!Number.isFinite(parsed) || parsed < 0) {
|
|
throw new Error("RECORDLY_BENCH_EXPORT_SHADOW_INTENSITY must be a non-negative number");
|
|
}
|
|
|
|
return parsed;
|
|
}
|
|
|
|
function parseExportWebcamSize(rawValue) {
|
|
if (rawValue === null || rawValue === "") {
|
|
return null;
|
|
}
|
|
|
|
const parsed = Number.parseFloat(rawValue);
|
|
if (!Number.isFinite(parsed) || parsed <= 0 || parsed > 100) {
|
|
throw new Error("RECORDLY_BENCH_EXPORT_WEBCAM_SIZE must be a number between 0 and 100");
|
|
}
|
|
|
|
return parsed;
|
|
}
|
|
|
|
export function createBenchmarkConfig(env = process.env) {
|
|
const repoRoot = path.resolve(__dirname, "..", "..");
|
|
const mainEntry = path.join(repoRoot, "dist-electron", "main.js");
|
|
const rendererEntry = path.join(repoRoot, "dist", "index.html");
|
|
const width = parseEvenInteger(env.RECORDLY_BENCH_EXPORT_WIDTH ?? "1280", "Width");
|
|
const height = parseEvenInteger(env.RECORDLY_BENCH_EXPORT_HEIGHT ?? "720", "Height");
|
|
const frameRate = parsePositiveInteger(env.RECORDLY_BENCH_EXPORT_FPS ?? "60", "Frame rate");
|
|
const durationSeconds = parsePositiveInteger(
|
|
env.RECORDLY_BENCH_EXPORT_DURATION ?? "15",
|
|
"Duration",
|
|
);
|
|
const timeoutMs = parsePositiveInteger(
|
|
env.RECORDLY_BENCH_EXPORT_TIMEOUT_MS ?? "180000",
|
|
"Timeout",
|
|
);
|
|
const runsPerVariant = parsePositiveInteger(env.RECORDLY_BENCH_EXPORT_RUNS ?? "2", "Runs");
|
|
const useNativeExport = env.RECORDLY_BENCH_EXPORT_USE_NATIVE === "1";
|
|
const useWebcamOverlay = env.RECORDLY_BENCH_EXPORT_ENABLE_WEBCAM === "1";
|
|
const exportEncodingMode = parseExportEncodingMode(
|
|
env.RECORDLY_BENCH_EXPORT_ENCODING_MODE ?? null,
|
|
);
|
|
const exportShadowIntensity = parseExportShadowIntensity(
|
|
env.RECORDLY_BENCH_EXPORT_SHADOW_INTENSITY ?? null,
|
|
);
|
|
const webcamWidth = parseEvenInteger(
|
|
env.RECORDLY_BENCH_EXPORT_WEBCAM_WIDTH ?? "640",
|
|
"Webcam width",
|
|
);
|
|
const webcamHeight = parseEvenInteger(
|
|
env.RECORDLY_BENCH_EXPORT_WEBCAM_HEIGHT ?? "360",
|
|
"Webcam height",
|
|
);
|
|
const webcamShadowIntensity = parseExportShadowIntensity(
|
|
env.RECORDLY_BENCH_EXPORT_WEBCAM_SHADOW ?? null,
|
|
);
|
|
const webcamSize = parseExportWebcamSize(env.RECORDLY_BENCH_EXPORT_WEBCAM_SIZE ?? null);
|
|
const exportPipeline = parseExportPipeline(env.RECORDLY_BENCH_EXPORT_PIPELINE ?? null);
|
|
const exportBackend = parseExportBackend(env.RECORDLY_BENCH_EXPORT_BACKEND ?? null);
|
|
const exportBackendList = parseExportBackendList(env.RECORDLY_BENCH_EXPORT_BACKENDS ?? null);
|
|
const variantNameList = parseBenchmarkVariantList(
|
|
env.RECORDLY_BENCH_EXPORT_VARIANTS ?? null,
|
|
);
|
|
|
|
return {
|
|
repoRoot,
|
|
mainEntry,
|
|
rendererEntry,
|
|
width,
|
|
height,
|
|
frameRate,
|
|
durationSeconds,
|
|
timeoutMs,
|
|
runsPerVariant,
|
|
useNativeExport,
|
|
useWebcamOverlay,
|
|
exportEncodingMode,
|
|
exportShadowIntensity,
|
|
webcamWidth,
|
|
webcamHeight,
|
|
webcamShadowIntensity,
|
|
webcamSize,
|
|
exportPipeline,
|
|
exportBackend,
|
|
exportBackendList,
|
|
variants: variantNameList
|
|
? variantNameList.map((variantName) => VARIANT_PRESETS[variantName])
|
|
: [VARIANT_PRESETS.baseline, VARIANT_PRESETS.tuned],
|
|
};
|
|
}
|
|
|
|
export function buildBenchmarkRequests(config) {
|
|
if (config.exportBackendList) {
|
|
return config.exportBackendList.map((backend) => ({
|
|
pipeline: config.exportPipeline,
|
|
backend,
|
|
label: backend,
|
|
slug: backend,
|
|
}));
|
|
}
|
|
|
|
if (config.exportBackend) {
|
|
return [
|
|
{
|
|
pipeline: config.exportPipeline,
|
|
backend: config.exportBackend,
|
|
label: config.exportBackend,
|
|
slug: config.exportBackend,
|
|
},
|
|
];
|
|
}
|
|
|
|
if (config.exportPipeline === "modern") {
|
|
return MODERN_BACKEND_SWEEP.map((backend) => ({
|
|
pipeline: config.exportPipeline,
|
|
backend,
|
|
label: backend,
|
|
slug: backend,
|
|
}));
|
|
}
|
|
|
|
return [
|
|
{
|
|
pipeline: config.exportPipeline,
|
|
backend: null,
|
|
label: "default",
|
|
slug: "default",
|
|
},
|
|
];
|
|
} |