import type { VideoAnalyzeOutput } from './types.js'; /** * Pure sampling-math seam: given a clip duration in seconds, produce the ffmpeg * `-vf` value and frame cap that spread {@link count} frames EVENLY across the * whole clip (one frame every `duration / count` seconds via the `fps` filter), * not clustered at the head. Returns `null` when the duration is unusable * (missing/non-finite/≤0) so the caller can fall back to head-clustered * `thumbnail` sampling without breaking the local-file path. * * The `fps` filter can emit `count` or `count ± 1` frames at clip boundaries, so * the caller MUST also pass `-frames:v frames` and tolerate fewer than `count` * outputs (the caller already slices/handles the resulting array). */ export declare function analyzeFrameSampling(durationSeconds: number | undefined, count?: number): { vf: string; frames: number; } | null; export declare function generateAnalyzeOutputWithGemini(input: { source: string; title?: string; durationSeconds?: number; endpoint?: string; fetcher?: typeof fetch; /** * Injectable frame-extraction seam (returns base64-encoded JPEG frames). * Defaults to the real ffmpeg helper; tests inject fakes so the suite never * shells out to ffmpeg. Only invoked when `source` is a readable local file. * The optional `durationSeconds` lets the extractor spread frames evenly * across the clip; injected fakes may ignore it. */ extractFrames?: (videoPath: string, durationSeconds?: number) => Promise; }): Promise; export declare function generateMultiShotWithGemini(input: { preset: import('./multi-shot-prompt.js').MultiShotPreset; imagePath: string; character?: string; action?: string; location: string; timeOfDay: string; repairInstructions?: string; /** Injectable fetch for tests; falls back to the global Gemini key pool. */ fetcher?: typeof fetch; }): Promise; //# sourceMappingURL=gemini-analyze.d.ts.map