/** * Icon palette available on the overlay tray. Rendered as unicode emojis * drawn onto a canvas then fed to ffmpeg as PNG sprites at export time. */ export type OverlayIcon = 'heart' | 'smile' | 'arrow' | 'warning' | 'forbidden' | 'obligation' | 'check'; export declare const OVERLAY_ICONS: Record; export interface Overlay { id: string; icon: OverlayIcon; /** 0..1 — relative X in the frame */ xFrac: number; /** 0..1 — relative Y in the frame */ yFrac: number; /** Display size in pixels on the output video */ sizePx: number; /** Seconds from the start of the host clip when the overlay appears */ startSec: number; /** Seconds from the start of the host clip when the overlay disappears */ endSec: number; } export type ClipKind = 'video' | 'image'; /** * A single editable segment of the composition. Video clips reference a * region of the source Blob ; image clips just render a still for * `durationSec` seconds. */ export interface Clip { id: string; kind: ClipKind; /** For video : region of the source. For image : the PNG/JPG URL. */ sourceUrl: string; /** Video clips only — start inside the source media (seconds) */ srcStartSec?: number; /** Video clips only — end inside the source media (seconds) */ srcEndSec?: number; /** Playback speed modifier (1 = native). Applied via setpts / fps. */ speed: number; /** For images — duration shown (seconds). For video — computed : (srcEnd - srcStart) / speed */ durationSec: number; /** Stickers on this clip */ overlays: Overlay[]; } export type SubtitlePosition = 'bottom' | 'top' | 'center'; export interface Subtitle { id: string; /** The displayed text (may contain line breaks) */ text: string; /** ISO 639-1 language code ('en', 'fr', 'ar', 'es', …) */ lang: string; /** Absolute start time in the composition (seconds) */ startSec: number; /** Absolute end time in the composition (seconds) */ endSec: number; /** Font size in pixels (default 48) */ fontSize: number; /** CSS/hex colour for the text (default '#FFFFFF') */ color: string; /** Background box colour (default '#000000AA') */ bgColor: string; /** Vertical position (default 'bottom') */ position: SubtitlePosition; } export declare const SUBTITLE_LANGUAGES: readonly [{ readonly code: "en"; readonly label: "English"; }, { readonly code: "fr"; readonly label: "Français"; }, { readonly code: "ar"; readonly label: "العربية"; }, { readonly code: "es"; readonly label: "Español"; }, { readonly code: "de"; readonly label: "Deutsch"; }, { readonly code: "pt"; readonly label: "Português"; }, { readonly code: "zh"; readonly label: "中文"; }, { readonly code: "ja"; readonly label: "日本語"; }]; export type OutputFormat = 'webm' | 'gif' | 'mp4'; export interface AudioTrackInput { /** The audio file (MP3 / M4A / WAV / OGG). */ blob: Blob; /** 0..1, default 1 (100%). Use 0.2-0.4 for background music behind narration. */ volume?: number; /** Offset in seconds before the audio track starts in the final output. */ startOffsetSec?: number; /** If true, video clips' embedded audio is dropped — only this track plays. */ replaceSourceAudio?: boolean; } /** v1.11.20+ : multi-track input. Chaque track a son startSec/endSec, peut * overlap, chainer ou laisser des gaps. Mixé avec amix côté ffmpeg. */ export interface AudioTrackMultiInput { blob: Blob; volume?: number; startSec: number; endSec?: number; } /** v1.11.24+ : logo / signature en overlay watermark. Position fixe, taille * en % de la largeur vidéo, opacité réglable. Appliqué après concat + burn, * juste avant le format final. */ export type LogoPosition = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left'; export interface LogoInput { blob: Blob; position?: LogoPosition; sizePct?: number; opacity?: number; marginPct?: number; } /** v1.11.21+ : réservation de placements pub. * Les slots ne sont PAS gravés dans la vidéo — ils sont exportés en sidecar * `.adslots.json` qu'un player runtime peut lire pour servir une pub via * AdMob, Facebook Audience Network, GAM, etc. au moment du playback. */ export type AdSlotKind = 'preroll' | 'midroll' | 'postroll' | 'banner'; export interface AdSlot { id: string; kind: AdSlotKind; /** Identifiant ad-network (ex: AdMob unit-id, FB placement-id). */ adUnitId?: string; /** Réseau cible (informatif, libre). */ network?: 'admob' | 'facebook' | 'gam' | 'custom' | string; /** Pour midroll : timestamp en secondes. */ midrollSec?: number; /** Pour banner : région overlay et fenêtre temporelle. Coords en % (0..1). */ banner?: { xFrac: number; yFrac: number; widthFrac: number; heightFrac: number; startSec: number; endSec?: number; }; /** Durée max attendue de la pub (info player). */ maxDurationSec?: number; } export interface ExportOptions { format: OutputFormat; /** Target width in pixels (keeps aspect, -1 for source width) */ width?: number; /** Frames per second (gif default 15, webm default 30) */ fps?: number; /** Burn subtitles into the video via ffmpeg drawtext (default false) */ burnSubtitles?: boolean; /** Which language track to burn (default: first available) */ burnLang?: string; /** Progress callback 0..1 */ onProgress?: (ratio: number) => void; /** Log callback for ffmpeg stderr */ onLog?: (line: string) => void; /** Optional audio track (MP3 / M4A / WAV) to mix over the final video. * Legacy single-track field — pour multi-track utilise `audioTracks`. */ audioTrack?: AudioTrackInput; /** v1.11.20+ : multiple tracks avec timing per-track. Si fourni, prévaut * sur `audioTrack` (legacy). Mixé via filter_complex amix côté ffmpeg. */ audioTracks?: AudioTrackMultiInput[]; /** v1.11.24+ : logo / signature en overlay watermark. */ logo?: LogoInput; /** Keep audio embedded in source video clips. Default true. */ preserveSourceAudio?: boolean; } /** Serializable project file — clips + subtitles + inline images (base64) */ export interface ProjectFile { /** Format version. v1 = clips/subtitles/settings/adSlots. v2 = + logo + audioTracks * (états locaux du composant VideoEditor lift-és pour persistence complète). */ version: 1 | 2; /** Nom user-friendly du projet (saisi avant Save). Optionnel — si absent, * le consumer affiche `Project ` par défaut. */ name?: string; clips: Array; subtitles: Subtitle[]; settings: { format: OutputFormat; width: number; burnSubtitles?: boolean; burnLang?: string; }; /** v1.11.21+ : ad slots réservés. Optionnel pour rétro-compat lecture * des projets antérieurs. */ adSlots?: AdSlot[]; /** v2.0.10+ : logo / signature watermark — état du composant VideoEditor * (logoFile + position + size + opacity + margin). Le fichier est sérialisé * en base64 inlineData pour reload offline. */ logo?: { inlineData?: string; filename?: string; position?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left'; sizePct?: number; opacity?: number; marginPct?: number; }; /** v2.0.10+ : audio tracks chaînés (présentation → nostalgie → action…). * Chaque piste sérialisée en base64 pour reprise complète sans dépendance * fichier externe. Ordre = ordre de lecture pendant le playback. */ audioTracks?: Array<{ id: string; filename: string; inlineData?: string; mimeType?: string; durationSec?: number; startSec?: number; volume?: number; fadeInSec?: number; fadeOutSec?: number; label?: string; }>; } export interface ExportResult { blob: Blob; url: string; filename: string; mime: string; durationSec: number; } //# sourceMappingURL=editor.d.ts.map