import * as http from 'http'; import { WebSocketServer } from 'ws'; import { type CaptureCodec } from './capture-file.js'; export declare const RECORD_STREAM_PATH = "/api/dev/record-stream"; export declare const FRAME_HEADER_BYTES = 4; /** Sanity bounds on a start request — nothing a real recorder sends is refused. */ export declare const MAX_FRAME_DIMENSION = 8192; export interface StreamStart { recordingName: string; width: number; height: number; /** Absent for raw RGBA frames. */ codec?: CaptureCodec; } export interface StreamError { error: string; } /** Validate the `start` message. */ export declare function parseStreamStart(raw: unknown): StreamStart | StreamError; /** Split a binary message into its frame index and pixel bytes; null when it is not a frame. */ export declare function parseFrameMessage(data: Buffer, frameBytes: number): { frameIndex: number; pixels: Buffer; } | null; /** * Keeps the raw encoder's input contiguous. The encoder numbers frames sequentially from 0, so the * frame written Nth becomes `_00000N.png`; feeding it exactly one frame per index — the real one * when it arrived, the previous one when it did not — is what keeps the files aligned with the * recorder's own frame count (the trailer's clock). */ export declare class FrameSequencer { private expected; private previous; readonly missing: number[]; /** The buffers to hand to the encoder for this arrival, in order. Empty for a duplicate/late frame. */ accept(frameIndex: number, pixels: Buffer): Buffer[]; /** Pad up to the recorder's declared count at stop, so the sequence ends where the timeline says. */ finish(frameCount: number): Buffer[]; get written(): number; } /** * Raw path ffmpeg arguments: RGBA on stdin, one PNG per frame at `