import type { Clip, Subtitle, ExportOptions, ExportResult } from '../types/editor'; /** * Payload written to the `manifest` field. The server receives : * - `manifest` : JSON.stringify(ComposeManifest) * - `src_0`..`src_N` : multipart blobs (webm video / images) * - `sticker_0`.. : multipart PNG blobs (emoji rendered client-side) */ export interface ComposeManifest { format: 'webm' | 'gif' | 'mp4'; width: number; fps: number; /** Map of sourceUrl → multipart field name (src_N) */ sourceMap: Record; /** Map of `${icon}_${sizePx}` → multipart field name (sticker_N) */ stickerMap: Record; clips: Array<{ id: string; kind: 'video' | 'image'; /** Matching key in `sourceMap` */ sourceRef: string; srcStartSec?: number; srcEndSec?: number; speed: number; durationSec: number; overlays: Array<{ id: string; /** Matching key in `stickerMap` */ stickerRef: string; xFrac: number; yFrac: number; sizePx: number; startSec: number; endSec: number; }>; }>; /** * Optional audio track mixed over the final concatenated video. * Source audio from video clips is PRESERVED by default and mixed with * this track (set `replaceSourceAudio: true` to override). */ audioTrack?: { /** Multipart field name (audio_0) */ sourceRef: string; /** 0..1, default 1 (100%). Use 0.2-0.4 for background music behind narration. */ volume?: number; /** Offset before the audio track starts playing in the final output (seconds). */ startOffsetSec?: number; /** If true, video clips' audio is dropped and only this track plays. Default false. */ replaceSourceAudio?: boolean; }; /** Multi-track : v1.11.20+. Chaque track a son startSec/endSec/volume. * Quand fourni, prévaut sur `audioTrack` (legacy single). */ audioTracks?: Array<{ sourceRef: string; volume?: number; startSec: number; endSec?: number; }>; /** v1.11.24+ : logo / signature en overlay watermark. */ logo?: { sourceRef: string; position?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left'; sizePct?: number; opacity?: number; marginPct?: number; }; /** Whether to keep the audio embedded in video clips. Default true. */ preserveSourceAudio?: boolean; } export interface ComposeClipsServerOptions extends ExportOptions { /** Endpoint accepting the multipart body. Default `/api/compose`. */ url?: string; /** Extra headers merged into the POST */ headers?: Record; /** * Direct Blob map keyed by sourceUrl — lets the client skip the * `fetch(blob:...)` round-trip that Firefox sometimes rejects under * COEP. Populated automatically by `useVideoEditor` for the root * recording and any image inserted via `insertImage`. */ blobsByUrl?: Map; /** Subtitles to burn into the video (when burnSubtitles=true) */ subtitles?: Subtitle[]; /** * Optional audio track (MP3 / M4A / WAV) mixed over the final video. * Use for background music or narration voice-over. */ audioTrack?: { blob: Blob; volume?: number; startOffsetSec?: number; replaceSourceAudio?: boolean; }; /** Multi-track audio (v1.11.20+). Quand fourni, prévaut sur `audioTrack`. * Chaque track est mixé indépendamment via filter_complex amix côté ffmpeg * (adelay = startSec*1000, atrim = duration). */ audioTracks?: Array<{ blob: Blob; volume?: number; startSec: number; endSec?: number; }>; /** v1.11.24+ : logo / signature watermark. */ logo?: { blob: Blob; position?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left'; sizePct?: number; opacity?: number; marginPct?: number; }; /** Keep audio embedded in source video clips. Default true. */ preserveSourceAudio?: boolean; } export declare function composeClipsServer(clips: Clip[], options: ComposeClipsServerOptions): Promise; //# sourceMappingURL=server-compose.d.ts.map