add export pipeline core types

This commit is contained in:
webadderall
2026-04-04 13:07:34 +11:00
parent 215d7c40c4
commit 015d46245c
2 changed files with 66 additions and 0 deletions
+7
View File
@@ -1,4 +1,11 @@
export const DEFAULT_MP4_CODEC = "avc1.640033";
export const MP4_CODEC_FALLBACK_LIST = [
DEFAULT_MP4_CODEC,
"avc1.4d4033",
"avc1.420033",
"avc1.4d401f",
"avc1.42001f",
] as const;
export type SupportedMp4EncoderPath = {
codec: string;
+59
View File
@@ -4,21 +4,66 @@ export interface ExportConfig {
frameRate: number;
bitrate: number;
codec?: string;
encodingMode?: ExportEncodingMode;
backendPreference?: ExportBackendPreference;
experimentalNativeExport?: boolean;
maxEncodeQueue?: number;
maxDecodeQueue?: number;
maxPendingFrames?: number;
maxInFlightNativeWrites?: number;
}
export type ExportRenderBackend = 'webgpu' | 'webgl';
export type ExportEncodeBackend = 'ffmpeg' | 'webcodecs';
export type ExportBackendPreference = 'auto' | 'webcodecs' | 'breeze';
export type ExportPipelineModel = 'modern' | 'legacy';
export interface ExportProgress {
currentFrame: number;
totalFrames: number;
percentage: number;
estimatedTimeRemaining: number; // in seconds
renderFps?: number;
renderBackend?: ExportRenderBackend;
encodeBackend?: ExportEncodeBackend;
encoderName?: string;
phase?: 'extracting' | 'finalizing' | 'saving'; // Phase of export
renderProgress?: number; // 0-100, progress of GIF rendering phase
}
export interface ExportMetrics {
totalElapsedMs: number;
metadataLoadMs?: number;
rendererInitMs?: number;
nativeSessionStartMs?: number;
decodeLoopMs?: number;
frameCallbackMs?: number;
renderFrameMs?: number;
encodeWaitMs?: number;
encodeWaitEvents?: number;
peakEncodeQueueSize?: number;
peakNativeWriteInFlight?: number;
nativeCaptureMs?: number;
nativeWriteMs?: number;
finalizationMs?: number;
frameCount?: number;
renderBackend?: ExportRenderBackend;
encodeBackend?: ExportEncodeBackend;
encoderName?: string;
backpressureProfile?: string;
averageFrameCallbackMs?: number;
averageRenderFrameMs?: number;
averageEncodeWaitMs?: number;
averageNativeCaptureMs?: number;
averageNativeWriteMs?: number;
}
export interface ExportResult {
success: boolean;
blob?: Blob;
filePath?: string;
error?: string;
metrics?: ExportMetrics;
}
export interface VideoFrameData {
@@ -27,8 +72,12 @@ export interface VideoFrameData {
duration: number; // in microseconds
}
export type ExportEncodingMode = 'fast' | 'balanced' | 'quality';
export type ExportQuality = 'medium' | 'good' | 'high' | 'source';
export type ExportMp4FrameRate = 24 | 30 | 60;
// GIF Export Types
export type ExportFormat = 'mp4' | 'gif';
@@ -48,10 +97,20 @@ export interface ExportSettings {
format: ExportFormat;
// MP4 settings
quality?: ExportQuality;
encodingMode?: ExportEncodingMode;
mp4FrameRate?: ExportMp4FrameRate;
backendPreference?: ExportBackendPreference;
pipelineModel?: ExportPipelineModel;
// GIF settings
gifConfig?: GifExportConfig;
}
export const MP4_FRAME_RATES: readonly ExportMp4FrameRate[] = [24, 30, 60] as const;
export function isValidMp4FrameRate(rate: number): rate is ExportMp4FrameRate {
return MP4_FRAME_RATES.includes(rate as ExportMp4FrameRate);
}
export const GIF_SIZE_PRESETS: Record<GifSizePreset, { maxHeight: number; label: string }> = {
medium: { maxHeight: 720, label: 'Medium (720p)' },
large: { maxHeight: 1080, label: 'Large (1080p)' },