import type { ClipOptions } from './types.js'; /** * Resolve the system ffmpeg binary path. Throws if not found. */ export declare function ensureFfmpegAvailable(): Promise; /** * Convert a WebM recording to an optimized GIF using a 2-pass palette approach. * Pass 1: generate an optimal palette. Pass 2: encode with that palette. */ export declare function convertToGif(webmPath: string, outputPath: string, opts?: { fps?: number; maxWidth?: number; loop?: boolean; }): Promise; /** * Convert a WebM recording to an MP4 with web-optimized settings. */ export declare function convertToMp4(webmPath: string, outputPath: string, opts?: { width?: number; height?: number; trimStartSec?: number; maxDurationSec?: number; holdLastFrameSec?: number; fps?: number; }): Promise; /** * Extract the first frame of a WebM as a PNG thumbnail. */ export declare function extractThumbnail(webmPath: string, outputPath: string): Promise; /** * Assemble a sequence of JPEG frames into an H.264 MP4. * Expects frames named `frame_000000.jpg`, `frame_000001.jpg`, ... in framesDir. * * When `frameOffsetsMs` is provided (one offset per frame, ms from first * frame), uses ffmpeg's concat demuxer to preserve the actual capture timing * (VFR). This matters when the compositor is CPU-bound on heavy React UIs: * frames arrive in bursts during idle periods and gaps during paint-heavy * periods. Encoding those at uniform CFR would stretch bursts and compress * gaps — viewers see temporally-distorted playback even though the average * rate is correct. VFR lets each frame hold the screen for its true wall- * clock duration. * * When `frameOffsetsMs` is absent, falls back to CFR at `fps` (useful for * uniform-cadence captures like the synthetic smoke tests). */ export declare function assembleMp4FromFrames(opts: { framesDir: string; outputPath: string; fps: number; frameOffsetsMs?: number[]; }): Promise; /** * Trim a recording: skip dead frames at the start and cap duration. */ export declare function trimRecording(inputPath: string, outputPath: string, startSec?: number, maxDurationSec?: number): Promise; /** * Get the duration of a media file in milliseconds. */ export declare function getMediaDurationMs(filePath: string): Promise; export interface ClipPostProcessResult { gifPath?: string; mp4Path?: string; thumbnailPath?: string; durationMs: number; fileSizeBytes?: number; } /** * Full post-processing pipeline for a single clip recording: * encode a normalized master MP4 → derive GIF + thumbnail → measure. */ export declare function postProcessClipRecording(webmPath: string, outputDir: string, clipId: string, options?: ClipOptions): Promise;