mirror of
https://github.com/webadderallorg/Recordly.git
synced 2026-10-03 11:07:47 +00:00
135 lines
4.3 KiB
TypeScript
135 lines
4.3 KiB
TypeScript
import type { ExportFormat, ExportPipelineModel, ExportProgress } from "@/lib/exporter";
|
|
|
|
export type ExportStatusModel = {
|
|
isExportSaving: boolean;
|
|
isExportPreparing: boolean;
|
|
isExportFinalizing: boolean;
|
|
isRenderingAudio: boolean;
|
|
exportFinalizingProgress: number | null;
|
|
exportFinalizingPercent: number | null;
|
|
isExportMuxingAndSaving: boolean;
|
|
isExportFinalSaveIndeterminate: boolean;
|
|
isLightningExportInProgress: boolean;
|
|
shouldSuspendPreviewRendering: boolean;
|
|
isLegacyExportInProgress: boolean;
|
|
renderSpeedFps: string | null;
|
|
runtimeLabel: string | null;
|
|
nativeSkipReasons: string[];
|
|
nativeSkipLabel: string | null;
|
|
};
|
|
|
|
export function resolveExportStatusModel({
|
|
isExporting,
|
|
exportProgress,
|
|
exportFormat,
|
|
exportPipelineModel,
|
|
}: {
|
|
isExporting: boolean;
|
|
exportProgress: ExportProgress | null;
|
|
exportFormat: ExportFormat;
|
|
exportPipelineModel: ExportPipelineModel;
|
|
}): ExportStatusModel {
|
|
const isExportSaving = exportProgress?.phase === "saving";
|
|
const isExportPreparing =
|
|
isExporting && (!exportProgress || exportProgress.phase === "preparing");
|
|
const isExportFinalizing = exportProgress?.phase === "finalizing";
|
|
const isRenderingAudio =
|
|
isExportFinalizing && typeof exportProgress?.audioProgress === "number";
|
|
const rawFinalizingProgress =
|
|
typeof exportProgress?.renderProgress === "number"
|
|
? exportProgress.renderProgress
|
|
: (exportProgress?.percentage ?? 100);
|
|
const exportFinalizingProgress = isExportFinalizing
|
|
? Math.max(
|
|
0,
|
|
Math.min(100, Number.isFinite(rawFinalizingProgress) ? rawFinalizingProgress : 0),
|
|
)
|
|
: null;
|
|
const exportFinalizingPercent = isExportFinalizing
|
|
? Math.round(exportFinalizingProgress ?? 100)
|
|
: null;
|
|
const isExportMuxingAndSaving =
|
|
isExportFinalizing &&
|
|
exportFormat === "mp4" &&
|
|
exportPipelineModel === "modern" &&
|
|
!isRenderingAudio;
|
|
const isExportFinalSaveIndeterminate =
|
|
isExportMuxingAndSaving && (exportFinalizingPercent ?? 0) >= 98;
|
|
const isLightningExportInProgress =
|
|
exportFormat === "mp4" &&
|
|
exportPipelineModel === "modern" &&
|
|
(isExporting || exportProgress !== null);
|
|
const shouldSuspendPreviewRendering =
|
|
isExporting && exportFormat === "mp4" && exportPipelineModel === "modern";
|
|
const isLegacyExportInProgress =
|
|
exportFormat === "mp4" &&
|
|
exportPipelineModel === "legacy" &&
|
|
(isExporting || exportProgress !== null);
|
|
const renderSpeedFps =
|
|
!isExportPreparing &&
|
|
!isExportFinalizing &&
|
|
!isExportSaving &&
|
|
typeof exportProgress?.renderFps === "number" &&
|
|
Number.isFinite(exportProgress.renderFps) &&
|
|
exportProgress.renderFps > 0
|
|
? exportProgress.renderFps.toFixed(1)
|
|
: null;
|
|
const runtimeLabel = resolveRuntimeLabel(exportProgress);
|
|
const nativeSkipReasons =
|
|
exportProgress?.nativeStaticLayoutSkipReasons &&
|
|
exportProgress.nativeStaticLayoutSkipReasons.length > 0
|
|
? exportProgress.nativeStaticLayoutSkipReasons
|
|
: exportProgress?.nativeStaticLayoutSkipReason
|
|
? [exportProgress.nativeStaticLayoutSkipReason]
|
|
: [];
|
|
const nativeSkipLabel =
|
|
nativeSkipReasons.length > 0
|
|
? `Native skipped: ${nativeSkipReasons[0]}${
|
|
nativeSkipReasons.length > 1 ? ` (+${nativeSkipReasons.length - 1} more)` : ""
|
|
}`
|
|
: null;
|
|
|
|
return {
|
|
isExportSaving,
|
|
isExportPreparing,
|
|
isExportFinalizing,
|
|
isRenderingAudio,
|
|
exportFinalizingProgress,
|
|
exportFinalizingPercent,
|
|
isExportMuxingAndSaving,
|
|
isExportFinalSaveIndeterminate,
|
|
isLightningExportInProgress,
|
|
shouldSuspendPreviewRendering,
|
|
isLegacyExportInProgress,
|
|
renderSpeedFps,
|
|
runtimeLabel,
|
|
nativeSkipReasons,
|
|
nativeSkipLabel,
|
|
};
|
|
}
|
|
|
|
function resolveRuntimeLabel(exportProgress: ExportProgress | null): string | null {
|
|
const renderBackend = exportProgress?.renderBackend;
|
|
const encodeBackend = exportProgress?.encodeBackend;
|
|
const encoderName = exportProgress?.encoderName;
|
|
|
|
if (!renderBackend && !encodeBackend && !encoderName) {
|
|
return null;
|
|
}
|
|
|
|
const rendererLabel =
|
|
renderBackend === "webgpu" ? "WebGPU" : renderBackend === "webgl" ? "WebGL" : null;
|
|
const encoderLabel =
|
|
encodeBackend === "ffmpeg" ? "Breeze" : encodeBackend === "webcodecs" ? "WebCodecs" : null;
|
|
const pathLabel =
|
|
rendererLabel && encoderLabel
|
|
? `${rendererLabel} + ${encoderLabel}`
|
|
: (rendererLabel ?? encoderLabel);
|
|
|
|
if (!pathLabel) {
|
|
return encoderName ?? null;
|
|
}
|
|
|
|
return encoderName ? `${pathLabel} (${encoderName})` : pathLabel;
|
|
}
|