/**
 * FFmpeg process management for HomeKit Secure Video (HKSV) events and fMP4 livestreaming.
 *
 * This module defines classes for orchestrating FFmpeg processes that produce fMP4 segments suitable for HomeKit Secure Video and realtime livestreaming scenarios. It
 * handles process lifecycle, segment buffering, initialization segment detection, and streaming event generation, abstracting away the complexity of interacting directly
 * with FFmpeg for these workflows.
 *
 * Key features:
 *
 * - Automated setup and management of FFmpeg processes for HKSV event recording and livestreaming (with support for audio and video).
 * - Parsing and generation of fMP4 boxes/segments for HomeKit, including initialization and media segments.
 * - Async generator APIs for efficient, event-driven segment handling.
 * - Flexible error handling and timeouts for HomeKit's strict realtime requirements.
 * - Designed for Homebridge plugin authors or advanced users who need robust, platform-aware FFmpeg session control for HomeKit and related integrations.
 *
 * @module
 */
import { type CameraRecordingConfiguration } from "homebridge";
import { type Nullable, type PartialWithId } from "../util.js";
import type { FfmpegOptions } from "./options.js";
import { FfmpegProcess } from "./process.js";
/**
 * Base options shared by both fMP4 recording and livestream sessions.
 *
 * @property audioFilters        - Audio filters for FFmpeg to process. These are passed as an array of filters.
 * @property audioStream         - Audio stream input to use, if the input contains multiple audio streams. Defaults to `0` (the first audio stream).
 * @property codec               - The codec for the input video stream. Valid values are `av1`, `h264`, and `hevc`. Defaults to `h264`.
 * @property enableAudio         - Indicates whether to enable audio or not.
 * @property hardwareDecoding    - Enable hardware-accelerated video decoding if available. Defaults to what was specified in `ffmpegOptions`.
 * @property hardwareTranscoding - Enable hardware-accelerated video transcoding if available. Defaults to what was specified in `ffmpegOptions`.
 * @property transcodeAudio      - Transcode audio to AAC. This can be set to false if the audio stream is already in AAC. Defaults to `true`.
 * @property videoFilters        - Video filters for FFmpeg to process. These are passed as an array of filters.
 * @property videoStream         - Video stream input to use, if the input contains multiple video streams. Defaults to `0` (the first video stream).
 */
export interface FMp4BaseOptions {
    audioFilters: string[];
    audioStream: number;
    codec: string;
    enableAudio: boolean;
    hardwareDecoding: boolean;
    hardwareTranscoding: boolean;
    transcodeAudio: boolean;
    videoFilters: string[];
    videoStream: number;
}
/**
 * Configuration for a separate audio input source in an fMP4 livestream session. This interface describes the audio source when video and audio come from different
 * endpoints, such as cameras like DoorBird that expose audio through a separate HTTP API.
 *
 * When the audio source is a raw stream (not a self-describing container), specify `format`, `sampleRate`, and optionally `channels` so FFmpeg knows how to interpret
 * the input. For self-describing sources like RTSP or container-based HTTP streams, only `url` is required.
 *
 * @property channels    - Optional. Number of audio channels. Defaults to `1`.
 * @property format      - Optional. Raw audio format for the input stream. When set, FFmpeg is told to expect this format rather than probing the stream. Valid values
 *                         are `alaw` (G.711 A-law), `mulaw` (G.711 mu-law), and `s16le` (16-bit signed little-endian PCM). Omit for self-describing sources.
 * @property sampleRate  - Optional. Audio sample rate in Hz (e.g., `8000`). Used when `format` is set. Defaults to `8000`.
 * @property url         - The URL of the audio input source.
 *
 * @example
 *
 * ```ts
 * // Raw audio from a DoorBird audio.cgi endpoint.
 * const rawAudioInput: FMp4AudioInputConfig = {
 *
 *   format: "mulaw",
 *   sampleRate: 8000,
 *   url: "http://doorbird-ip/bha-api/audio.cgi"
 * };
 *
 * // Self-describing RTSP audio stream - only URL is needed.
 * const rtspAudioInput: FMp4AudioInputConfig = {
 *
 *   url: "rtsp://camera-ip/audio"
 * };
 * ```
 *
 * @see FMp4LivestreamOptions
 *
 * @category FFmpeg
 */
export interface FMp4AudioInputConfig {
    channels?: number;
    format?: "alaw" | "mulaw" | "s16le";
    sampleRate?: number;
    url: string;
}
/**
 * Options for configuring an fMP4 HKSV recording session.
 *
 * @property fps             - The video frames per second for the session.
 * @property probesize       - Number of bytes to analyze for stream information.
 * @property timeshift       - Timeshift offset for event-based recording (in milliseconds).
 */
export interface FMp4RecordingOptions extends FMp4BaseOptions {
    fps: number;
    probesize: number;
    timeshift: number;
}
/**
 * Options for configuring an fMP4 livestream session.
 *
 * @property audioInput  - Optional. A separate audio input source. When provided, audio is read from this source instead of the primary `url`. Can be a URL string
 *                         for self-describing sources (e.g., RTSP), or an `FMp4AudioInputConfig` object for raw audio streams that require format metadata.
 * @property url         - Source URL for livestream (RTSP) remuxing to fMP4.
 *
 * @see FMp4AudioInputConfig
 *
 * @category FFmpeg
 */
export interface FMp4LivestreamOptions extends FMp4BaseOptions {
    audioInput?: FMp4AudioInputConfig | string;
    url: string;
}
/**
 * Abstract base class for fMP4 FFmpeg processes. Owns the shared command line skeleton (preamble, video mapping, movflags, audio encoding, output format) and the fMP4
 * box-parsing loop. Subclasses provide mode-specific pieces (input args, encoder selection, box handling) via protected hook methods, following the template method
 * pattern.
 *
 * @see FfmpegRecordingProcess
 * @see FfmpegLivestreamProcess
 * @see FfmpegProcess
 * @see {@link https://ffmpeg.org/ffmpeg.html | FFmpeg Documentation}
 */
declare abstract class FfmpegFMp4Process extends FfmpegProcess {
    private isLoggingErrors;
    protected readonly fMp4Options: Required<FMp4BaseOptions>;
    protected readonly recordingConfig: CameraRecordingConfiguration;
    /**
     * Constructs a new fMP4 FFmpeg process. Stores shared state and applies defaults to the base options. The command line is not assembled here...subclasses call
     * `buildCommandLine()` after their own initialization to trigger the template method assembly.
     *
     * @param ffmpegOptions     - FFmpeg configuration options.
     * @param recordingConfig   - HomeKit recording configuration for the session.
     * @param fMp4Options       - Partial base options with defaults applied for any unset fields.
     * @param isVerbose         - If `true`, enables more verbose logging for debugging purposes. Defaults to `false`.
     */
    constructor(ffmpegOptions: FfmpegOptions, recordingConfig: CameraRecordingConfiguration, fMp4Options?: Partial<FMp4BaseOptions>, isVerbose?: boolean);
    private _isVerbose;
    protected buildCommandLine(): void;
    protected abstract inputArgs(): string[];
    protected abstract separateAudioInputArgs(): string[];
    protected abstract audioInputIndex(): number;
    protected abstract videoEncoderArgs(): string[];
    protected abstract postFilterArgs(): string[];
    protected abstract metadataLabel(): string;
    protected abstract handleParsedBox(header: Buffer, data: Buffer, dataLength: number, type: number): void;
    /**
     * Prepares and configures the FFmpeg process for reading and parsing output fMP4 data. The box parsing loop is shared...each complete box is dispatched to the
     * subclass via handleParsedBox().
     */
    protected configureProcess(): void;
    /**
     * Stops the FFmpeg process and performs cleanup. Subclasses override this to emit mode-specific events before calling super, which handles the shared teardown and
     * emits the "close" event.
     */
    protected stopProcess(): void;
    /**
     * Stops the FFmpeg process and logs errors if specified.
     *
     * @param logErrors - If `true`, logs FFmpeg errors. Defaults to the internal process logging state.
     *
     * @example
     *
     * ```ts
     * process.stop();
     * ```
     */
    stop(logErrors?: boolean): void;
    /**
     * Logs errors from FFmpeg process execution, handling known benign HKSV stream errors gracefully.
     *
     * @param exitCode - The exit code from the FFmpeg process.
     * @param signal   - The signal (if any) used to terminate the process.
     */
    protected logFfmpegError(exitCode: Nullable<number>, signal: Nullable<NodeJS.Signals>): void;
}
/**
 * Manages a HomeKit Secure Video recording FFmpeg process.
 *
 * @example
 *
 * ```ts
 * const process = new FfmpegRecordingProcess(ffmpegOptions, recordingConfig, 30, true, 5000000, 0);
 * process.start();
 * ```
 *
 * @see FfmpegFMp4Process
 *
 * @category FFmpeg
 */
export declare class FfmpegRecordingProcess extends FfmpegFMp4Process {
    /**
     * Indicates whether the recording has timed out waiting for FFmpeg output.
     */
    isTimedOut: boolean;
    private readonly fps;
    private readonly probesize;
    private recordingBuffer;
    private readonly timeshift;
    /**
     * Constructs a new FFmpeg recording process for HKSV events.
     *
     * @param options          - FFmpeg configuration options.
     * @param recordingConfig  - HomeKit recording configuration for the session.
     * @param fMp4Options      - fMP4 recording options.
     * @param isVerbose        - If `true`, enables more verbose logging for debugging purposes. Defaults to `false`.
     */
    constructor(options: FfmpegOptions, recordingConfig: CameraRecordingConfiguration, fMp4Options?: Partial<FMp4RecordingOptions>, isVerbose?: boolean);
    protected inputArgs(): string[];
    protected separateAudioInputArgs(): string[];
    protected audioInputIndex(): number;
    protected videoEncoderArgs(): string[];
    protected postFilterArgs(): string[];
    protected metadataLabel(): string;
    protected handleParsedBox(header: Buffer, data: Buffer, dataLength: number, type: number): void;
    /**
     * Stops the FFmpeg process and performs cleanup, ensuring the segment generator can exit.
     */
    protected stopProcess(): void;
    /**
     * Asynchronously generates complete segments from FFmpeg output, formatted for HomeKit Secure Video.
     *
     * This async generator yields fMP4 segments as Buffers, or ends on process termination or timeout.
     *
     * @yields A Buffer containing a complete MP4 segment suitable for HomeKit.
     *
     * @example
     *
     * ```ts
     * for await(const segment of process.segmentGenerator()) {
     *
     *   // Process each segment for HomeKit.
     * }
     * ```
     */
    segmentGenerator(): AsyncGenerator<Buffer>;
}
/**
 * Manages a HomeKit livestream FFmpeg process for generating fMP4 segments.
 *
 * @example
 *
 * ```ts
 * const process = new FfmpegLivestreamProcess(ffmpegOptions, recordingConfig, url, 30, true);
 * process.start();
 *
 * const initSegment = await process.getInitSegment();
 * ```
 *
 * @see FfmpegFMp4Process
 *
 * @category FFmpeg
 */
export declare class FfmpegLivestreamProcess extends FfmpegFMp4Process {
    /**
     * Optional override for the fMP4 fragment duration, in milliseconds. When set, the `-frag_duration` argument is updated before starting the FFmpeg process.
     */
    segmentLength?: number;
    private _hasAudioInput;
    private _initSegment;
    private _initSegmentParts;
    private hasInitSegment;
    private readonly livestreamOptions;
    /**
     * Constructs a new FFmpeg livestream process.
     *
     * @param options            - FFmpeg configuration options.
     * @param recordingConfig    - HomeKit recording configuration for the session.
     * @param livestreamOptions  - livestream segmenting options.
     * @param isVerbose          - If `true`, enables more verbose logging for debugging purposes. Defaults to `false`.
     */
    constructor(options: FfmpegOptions, recordingConfig: CameraRecordingConfiguration, livestreamOptions: PartialWithId<FMp4LivestreamOptions, "url">, isVerbose?: boolean);
    protected inputArgs(): string[];
    protected separateAudioInputArgs(): string[];
    protected audioInputIndex(): number;
    protected videoEncoderArgs(): string[];
    protected postFilterArgs(): string[];
    protected metadataLabel(): string;
    protected handleParsedBox(header: Buffer, data: Buffer, _dataLength: number, type: number): void;
    /**
     * Starts the FFmpeg process, adjusting the fragment duration if segmentLength has been set.
     *
     * @example
     *
     * ```ts
     * process.start();
     * ```
     */
    start(): void;
    /**
     * Gets the fMP4 initialization segment generated by FFmpeg for the livestream.
     *
     * @returns A promise resolving to the initialization segment as a Buffer.
     *
     * @example
     *
     * ```ts
     * const initSegment = await process.getInitSegment();
     * ```
     */
    getInitSegment(): Promise<Buffer>;
    /**
     * Returns the initialization segment as a Buffer, or null if not yet available.
     *
     * @returns The initialization segment Buffer, or `null` if not yet generated.
     *
     * @example
     *
     * ```ts
     * const init = process.initSegment;
     * if(init) {
     *
     *   // Use the initialization segment.
     * }
     * ```
     */
    get initSegment(): Nullable<Buffer>;
}
export {};
