/** * Homebridge FFmpeg transcoding, decoding, and encoding options, selecting codecs, pixel formats, and hardware acceleration for the host system. * * This module defines interfaces and classes for specifying, adapting, and generating FFmpeg command-line arguments tailored to the host system's capabilities. It * automates the selection of codecs, pixel formats, hardware encoders/decoders, and streaming profiles for maximum compatibility and performance. * * Key features: * * - Encapsulates all FFmpeg transcoding and streaming options (including bitrate, resolution, framerate, H.264 profiles/levels, and quality optimizations). * - Detects and configures hardware-accelerated encoding and decoding (macOS VideoToolbox, Intel Quick Sync Video, and Raspberry Pi 4), falling back to software * processing when required. * - Dynamically generates the appropriate FFmpeg command-line arguments for livestreaming, HomeKit Secure Video (HKSV) event recording, and crop filters. * - Provides strong TypeScript types and interfaces for reliable integration and extensibility in Homebridge. * * This module is intended for plugin authors and advanced users who need precise, robust control over FFmpeg processing pipelines, with platform-aware optimizations and * safe fallbacks. * * @module */ import type { H264Level as H264LevelEnum, H264Profile as H264ProfileEnum } from "homebridge"; import { AudioRecordingCodecType } from "./hap-enums.ts"; import type { FfmpegCodecs } from "./codecs.ts"; import type { Logger } from "../util.ts"; declare const H264Level: { readonly LEVEL3_1: H264LevelEnum.LEVEL3_1; readonly LEVEL3_2: H264LevelEnum.LEVEL3_2; readonly LEVEL4_0: H264LevelEnum.LEVEL4_0; }; declare const H264Profile: { readonly BASELINE: H264ProfileEnum.BASELINE; readonly HIGH: H264ProfileEnum.HIGH; readonly MAIN: H264ProfileEnum.MAIN; }; type H264Level = H264LevelEnum; type H264Profile = H264ProfileEnum; /** * Configuration options for `FfmpegOptions`, defining transcoding, decoding, logging, and hardware acceleration settings. * * @property codecSupport - FFmpeg codec capabilities and hardware support. * @property crop - Optional. Cropping rectangle for output video. * @property debug - Optional. Enable debug logging. * @property hardwareDecoding - Enable hardware-accelerated video decoding if available. * @property hardwareTranscoding - Enable hardware-accelerated video encoding if available. * @property log - Logging interface for output and errors. * @property name - Function returning the name or label for this options set. * * @remarks The `hardwareDecoding` and `hardwareTranscoding` flags are bidirectional. On input, they express the caller's desired hardware acceleration state. During * `FfmpegOptions` construction, the flags are resolved against the host's actual capabilities and the config object is mutated in place to reflect what is available. * After construction, these flags represent the resolved state...`hardwareDecoding` or `hardwareTranscoding` may be set to `false` if the required codecs or * accelerators are absent, or `hardwareDecoding` may be set to `true` if Intel Quick Sync Video is detected even when not explicitly requested. * * @example * * ```ts * const optionsConfig: FfmpegOptionsConfig = { * * codecSupport: ffmpegCodecs, * crop: { width: 1, height: 1, x: 0, y: 0 }, * debug: false, * hardwareDecoding: true, * hardwareTranscoding: true, * log, * name: () => "Camera" * }; * ``` * * @see FfmpegOptions * * @category FFmpeg */ export interface FfmpegOptionsConfig { codecSupport: FfmpegCodecs; crop?: { height: number; width: number; x: number; y: number; }; debug?: boolean; hardwareDecoding: boolean; hardwareTranscoding: boolean; log: Logger; name: () => string; } /** * Options used for configuring audio encoding in FFmpeg operations. * * The single field selects the AAC profile that drives encoder-specific arg emission in {@link FfmpegOptions.audioEncoder} - AAC-ELD (the HomeKit Secure Video event- * recording default, lower bitrate, low-latency) versus AAC-LC (higher-quality livestream variant). The chosen profile maps to `aac_at` mode switches on macOS and to * `libfdk_aac` flags elsewhere. * * @property codec - Optional. AAC profile to encode (`AudioRecordingCodecType.AAC_ELD` or `AudioRecordingCodecType.AAC_LC`). Defaults to * `AudioRecordingCodecType.AAC_ELD`. * * @example * * ```ts * const encoderOptions: AudioEncoderOptions = { * * codec: AudioRecordingCodecType.AAC_ELD * }; * * // Use with FfmpegOptions for transcoding. * const ffmpegOpts = new FfmpegOptions(optionsConfig); * const args = ffmpegOpts.audioEncoder(encoderOptions); * ``` * * @see FfmpegOptions * * @category FFmpeg */ export interface AudioEncoderOptions { codec?: AudioRecordingCodecType; } /** * Options used for configuring video encoding in FFmpeg operations. * * These options control output bitrate, framerate, resolution, H.264 profile and level, input framerate, and smart quality optimizations. * * @property bitrate - Target video bitrate, in kilobits per second. * @property fps - Target output frames per second. * @property hardwareDecoding - Optional. If `true`, the emitted encoder args assume the input stream has already been hardware-decoded (the GPU holds the frames). * Used by the transfer-filter logic to decide between `hwupload`, `hwdownload`, or neither. Defaults to the resolved * `FfmpegOptionsConfig.hardwareDecoding` value on the owning `FfmpegOptions` instance. * @property hardwareTranscoding - Optional. If `true`, the emitted args select a hardware-accelerated encoder (`h264_videotoolbox` / `h264_qsv` / `h264_v4l2m2m`) and * the matching filter pipeline. If `false`, the args fall back to the libx264 software encoder. Defaults to the resolved * `FfmpegOptionsConfig.hardwareTranscoding` value on the owning `FfmpegOptions` instance. * @property height - Output video height, in pixels. * @property idrInterval - Interval (in seconds) between keyframes (IDR frames). * @property inputFps - Input (source) frames per second. * @property level - H.264 profile level for output. * @property profile - H.264 profile for output. * @property smartQuality - Optional. Enables variable-bitrate quality-constrained encoding on encoders that support it - libx264 (`-crf 20`), Apple Silicon * VideoToolbox (`-q:v 90`), and Intel QSV (`-global_quality 20`). Intel VideoToolbox and v4l2m2m have no quality-constraint mode and * always emit a fixed `-b:v` regardless. In all cases, `smartQuality` also adds `HOMEKIT_STREAMING_HEADROOM` to `-maxrate`, giving the * encoder a narrow band of variation above the target bitrate. Defaults to `true`. * @property width - Output video width, in pixels. * * @example * * ```ts * const encoderOptions: VideoEncoderOptions = { * * bitrate: 3000, * fps: 30, * hardwareDecoding: true, * hardwareTranscoding: true, * height: 1080, * idrInterval: 2, * inputFps: 30, * level: H264Level.LEVEL4_0, * profile: H264Profile.HIGH, * smartQuality: true, * width: 1920 * }; * * // Use with FfmpegOptions for transcoding or streaming. * const ffmpegOpts = new FfmpegOptions(optionsConfig); * const args = ffmpegOpts.streamEncoder(encoderOptions); * ``` * * @see FfmpegOptions * @see {@link https://ffmpeg.org/ffmpeg-codecs.html | FFmpeg Codecs Documentation} * * @category FFmpeg */ export interface VideoEncoderOptions { bitrate: number; fps: number; hardwareDecoding?: boolean; hardwareTranscoding?: boolean; height: number; idrInterval: number; inputFps: number; level: H264Level; profile: H264Profile; smartQuality?: boolean; width: number; } /** * Every hardware-transcode context this module distinguishes, each with a source-pixel ceiling that can differ on a given host. Live streaming and HKSV recording * both transcode, but a host may admit one context to its hardware encoder and not the other (today: Raspberry Pi runs live transcoding on h264_v4l2m2m but falls * HKSV recording back to libx264). Consumed by `maxSourcePixels` and the `recordEncoder` software-fallback so both derive the same per-context hardware-capability * answer from one predicate. * * @category FFmpeg */ export type EncoderContext = "record" | "stream"; /** * Provides Homebridge FFmpeg transcoding, decoding, and encoding options, selecting codecs, pixel formats, and hardware acceleration for the host system. * * This class generates and adapts FFmpeg command-line arguments for livestreaming and event recording, optimizing for system hardware and codec availability. * * @example * * ```ts * const ffmpegOpts = new FfmpegOptions(optionsConfig); * * // Generate video encoder arguments for streaming. * const encoderOptions: VideoEncoderOptions = { * * bitrate: 3000, * fps: 30, * hardwareDecoding: true, * hardwareTranscoding: true, * height: 1080, * idrInterval: 2, * inputFps: 30, * level: H264Level.LEVEL4_0, * profile: H264Profile.HIGH, * smartQuality: true, * width: 1920 * }; * const args = ffmpegOpts.streamEncoder(encoderOptions); * * // Generate crop filter string, if cropping is enabled. * const crop = ffmpegOpts.cropFilter; * ``` * * @see AudioEncoderOptions * @see VideoEncoderOptions * @see FfmpegCodecs * @see {@link https://ffmpeg.org/ffmpeg.html | FFmpeg Documentation} * * @category FFmpeg */ export declare class FfmpegOptions { #private; /** * The configuration options used to initialize this instance. This is the single stored state on `FfmpegOptions`: every other public field on this class is either * a getter that forwards to `this.config`, or a fixed constant independent of it (`audioDecoder`), so external callers have exactly one canonical path to each * config-backed value and internal code never has to keep a parallel field in sync with `config` at construction time. */ readonly config: FfmpegOptionsConfig; /** * Creates an instance of Homebridge FFmpeg encoding and decoding options. * * @param options - FFmpeg options configuration. * * @example * * ```ts * const ffmpegOpts = new FfmpegOptions(optionsConfig); * ``` */ constructor(options: FfmpegOptionsConfig); /** * Indicates if debug logging is enabled. Normalizes `undefined` to `false` so callers always see a definite boolean regardless of whether the config object set * the field explicitly. */ get debug(): boolean; /** * Logging interface for output and errors. */ get log(): Logger; /** * Function returning the name for this options instance to be used for logging. */ get name(): () => string; /** * Returns the audio encoder arguments to use when transcoding. * * @param options - Optional. The encoder options to use for generating FFmpeg arguments. * @returns Array of FFmpeg command-line arguments for audio encoding. * * @example * * ```ts * const args = ffmpegOpts.audioEncoder(); * ``` */ audioEncoder(options?: AudioEncoderOptions): string[]; /** * Returns the audio decoder to use when decoding. * * @returns The FFmpeg audio decoder string. */ readonly audioDecoder: string; /** * Returns the video decoder arguments to use for decoding video. * * @param codec - Optional. Codec to decode (`"av1"`, `"h264"` (default), or `"hevc"`; `"h265"` is accepted as an * alias for `"hevc"`, and codec matching is case-insensitive). * @returns Array of FFmpeg command-line arguments for video decoding or an empty array if the codec isn't supported. * * @example * * ```ts * const args = ffmpegOpts.videoDecoder("h264"); * ``` */ videoDecoder(codec?: string): string[]; /** * Returns the platform-appropriate FFmpeg video filters needed to transfer hardware-decoded frames to system memory. When hardware decoding is active, decoded frames * may reside on the GPU and require explicit download before CPU-based filters (crop, scale, format conversion) can operate on them. Returns an empty array when * hardware decoding is disabled or when the platform handles the transfer implicitly (e.g. Raspberry Pi). * * @returns An array of FFmpeg filter strings to prepend to a video filter chain, or an empty array if no transfer is needed. */ get hardwareDownloadFilters(): string[]; /** * Returns the FFmpeg crop filter string, or a default no-op filter if cropping is disabled. * * @returns The crop filter string for FFmpeg. */ get cropFilter(): string; /** * Returns the video encoder options to use for HomeKit Secure Video (HKSV) event recording. * * @param options - Encoder options to use. * @returns Array of FFmpeg command-line arguments for video encoding. */ recordEncoder(options: VideoEncoderOptions): string[]; /** * Returns the video encoder options to use when transcoding for livestreaming. * * @param options - Encoder options to use. * @returns Array of FFmpeg command-line arguments for video encoding. * * @example * * ```ts * const args = ffmpegOpts.streamEncoder(encoderOptions); * ``` */ streamEncoder(options: VideoEncoderOptions): string[]; /** * Returns the maximum source pixel count the host's hardware transcode pipeline can ingest for the given encoding context, or `Infinity` when unconstrained. * * Only Raspberry Pi's GPU imposes a real limit; every other host is unconstrained. A context is capped only when it actually runs on that hardware path - so today live * streaming on a Pi returns the RPi ceiling while recording on a Pi returns `Infinity` (it software-encodes). Consumers apply this value blindly; the "why" lives here. * * @param context - The encoding context whose ceiling is requested. * @returns Maximum supported source pixel count for `context`. */ maxSourcePixels(context: EncoderContext): number; } export {}; //# sourceMappingURL=options.d.ts.map