export interface FfmpegInputSpec { /** Port UDP où mediasoup pousse le RTP. */ rtpPort: number; /** Payload type RTP (= consumer.rtpParameters.codecs[0].payloadType). */ payloadType: number; /** 'audio' ou 'video'. */ kind: 'audio' | 'video'; /** Codec name (e.g. 'opus', 'VP8', 'H264'). */ codec: string; /** Clock rate (48000 pour opus, 90000 pour video). */ clockRate: number; /** Channels (audio uniquement, 2 pour opus stéréo). */ channels?: number; } export type McuLayout = 'single' | 'grid' | 'pip' | 'focus-speaker' | 'program'; /** Sélection de la source PROGRAM (bus programme) : ses ordinaux vidéo/audio * parmi les flux SDP. La vidéo passe plein écran, l'audio est pris SEUL (solo). */ export interface ProgramSelect { /** Ordinal de la vidéo programme (→ `0:v:`). */ videoIndex?: number; /** Ordinal de l'audio programme (→ `0:a:`, audio SOLO sans amix). */ audioIndex?: number; } /** * Génère un fichier SDP que ffmpeg utilisera comme input pour décrire les flux * RTP entrants (un m-line par PlainTransport). ffmpeg expose alors chaque flux * comme `[0:v:N]` / `[0:a:N]` (Nème vidéo/audio de l'input 0). */ export declare function buildSdpForFfmpeg(inputs: FfmpegInputSpec[]): string; export interface FilterPlan { /** Contenu `-filter_complex` (null = pas de filtre → mapping direct, copy possible). */ filterComplex: string | null; /** Cible vidéo pour `-map` (ex. '[vout]' ou '0:v:0' ou null si audio-only). */ videoMap: string | null; /** Cible audio pour `-map` (ex. '[aout]' ou '0:a:0' ou null si video-only). */ audioMap: string | null; /** true si un re-encodage vidéo/audio est requis (compositing/amix). */ needsEncode: boolean; } /** * Construit le graphe `-filter_complex` pour composer N vidéos en 1 selon le layout * (et mixer N audios). Fonction PURE (testable sans ffmpeg). * - 0/1 vidéo + layout simple → pas de filtre (mapping direct, copy possible) * - ≥2 vidéos ou grid/pip → xstack (grid) / overlay (pip) → re-encode * - ≥2 audios → amix → re-encode audio */ export declare function buildFilterComplex(layout: McuLayout, videoCount: number, audioCount: number, resolution: string, program?: ProgramSelect): FilterPlan; export interface SpawnFfmpegOptions { ffmpegPath?: string; inputs: FfmpegInputSpec[]; /** Sortie primaire (sert aussi de base au .sdp). */ outputPath: string; /** Sorties SIMULTANÉES (défaut [outputPath]). Une même passe ffmpeg écrit chaque * format (ex: ['…/recording.m3u8','…/recording.mp4'] = HLS live + archive MP4). */ outputPaths?: string[]; /** Layout de composition (défaut 'single'). */ layout?: McuLayout; /** Sélection PROGRAM (bus programme) : vidéo plein écran + audio solo. */ program?: ProgramSelect; /** Résolution de sortie (défaut '720p'). */ resolution?: string; extraArgs?: string[]; verbose?: boolean; onExit?: (code: number | null, signal: string | null) => void; onError?: (err: Error) => void; } export interface FfmpegProcess { readonly pid: number; readonly outputPath: string; readonly sdpPath: string; stop(graceful?: boolean): Promise; } export declare function spawnFfmpeg(opts: SpawnFfmpegOptions): Promise; //# sourceMappingURL=ffmpeg.d.ts.map