import type { CaptureBackend } from "./screen_capture.js"; export interface CaptureConfig { /** Which capture input to use: Linux grabs the X display, macOS grabs a screen via avfoundation. */ platform: "linux" | "darwin"; /** X display to grab (DISPLAY, default ":0"). Linux only — meaningless on macOS. */ display: string; /** Recording capture frame rate (fps). */ fps: number; /** Screen dimensions (must match the ambient desktop — SCREEN_CAPTURE §1.3). */ width: number; height: number; /** Recording segment roll interval (seconds). A suspend/resume also forces a boundary. */ segmentSeconds: number; /** Live-view push cadence (ms) — how often the latest frame is pushed while a viewer is attached. */ liveFrameIntervalMs: number; /** How often (ms) the capture polls the broker for viewer presence. */ wantedPollIntervalMs: number; /** Longest (ms) a viewer goes without a frame while the screen is unchanged. */ liveKeepaliveMs: number; } export declare const DESKTOP_THUMBNAIL_WIDTH = 320; export declare const DESKTOP_THUMBNAIL_HEIGHT = 200; /** Read the capture config from env, or null when the desktop stack is absent or recording is off. */ export declare function loadCaptureConfig(env: NodeJS.ProcessEnv, platform?: NodeJS.Platform): CaptureConfig | null; /** * Which avfoundation device index is the SCREEN. Discovered, never assumed: `ffmpeg -list_devices` * enumerates cameras first, so the screen's index is whatever a given Mac's hardware makes it (on a * machine with four cameras it is 4). Hardcoding one would silently record a WEBCAM instead of the * screen — the worst possible failure for a session recording. Returns null when no screen device is * listed (ffmpeg missing, or Screen Recording not granted), so the caller degrades instead of * recording garbage. * * The device list is written to STDERR, and ffmpeg exits non-zero after listing — both expected. */ export declare function parseAvfoundationScreenIndex(listOutput: string, display?: number): number | null; /** Run ffmpeg's device enumeration and resolve the screen index (null ⇒ no screen capturable). */ export declare function detectAvfoundationScreenIndex(exec?: (cmd: string, args: readonly string[]) => Promise): Promise; /** * The INPUT half of the ffmpeg graph, per platform. Linux pins the geometry because x11grab needs it * (the Xvfb screen is snapshot-fixed); macOS captures the screen device at its NATIVE resolution — * avfoundation takes no `-video_size`, and a Mac's screen is whatever the operator's panel is. * `screenIndex` is DISCOVERED (see detectAvfoundationScreenIndex), never assumed: the device list is * machine-specific, and a wrong index would record a WEBCAM instead of the screen. */ export declare function ffmpegInputArgs(cfg: CaptureConfig, screenIndex: number): string[]; /** ffmpeg args: one platform input, three outputs (change-driven segmented MP4 + full-size and * bandwidth-bounded overwritten JPEGs). Exported for unit testing. */ export declare function ffmpegArgs(cfg: CaptureConfig, dir: string, screenIndex?: number): string[]; /** * True when an MP4 head positively shows an `mdat` box carrying NO payload — the shape ffmpeg leaves * when it is stopped before encoding a single frame: `ftyp` + an 8-byte (header-only) `mdat` + a `moov` * holding no track at all, 262 bytes in all. No player can open that file. * * Deliberately conservative: a missing `mdat`, a walk that runs past the head, a `size === 0` box (runs * to EOF) or any malformed length answers false. Dropping a real segment is worse than uploading an odd * one, so only the husk we can PROVE empty is rejected. Pure — exported for unit tests. */ export declare function mp4HasEmptyMdat(head: Buffer): boolean; /** Read a finalized segment's head and answer whether it is the frameless husk. Unreadable answers * false (see {@link mp4HasEmptyMdat} — only a proven-empty file is dropped). */ export declare function isFramelessSegment(path: string): Promise; /** * The macOS screen's PIXEL dimensions, for segment metadata. avfoundation captures the panel's real * resolution, so the configured 1280x800 (an Xvfb assumption) would mislabel every Mac recording. * Read from CoreGraphics via JXA; null ⇒ the caller keeps the configured values. */ export declare function detectDarwinScreenSize(exec?: (cmd: string, args: readonly string[]) => Promise): Promise<{ width: number; height: number; } | null>; export declare function makeCaptureBackend(cfg: CaptureConfig): CaptureBackend;