UNPKG

homebridge-plugin-utils

Version:

Opinionated utilities to provide common capabilities and create rich configuration webUI experiences for Homebridge plugins.

390 lines (389 loc) 14.3 kB
/** * 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 { AudioRecordingCodecType, H264Level, H264Profile, type Logging } from "homebridge"; import type { FfmpegCodecs } from "./codecs.js"; import type { HomebridgePluginLogging } from "../util.js"; /** * 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 - 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. * * @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: HomebridgePluginLogging | Logging; name: () => string; } /** * 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 codec - Optional. Audio codec 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`, encoder options will account for hardware decoding (primarily for Intel QSV scenarios). Defaults to `true`. * @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 and applicable only when not using hardware acceleration. If `true`, enables smart quality and variable bitrate optimizations. * 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; } /** * 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 { /** * FFmpeg codec and hardware capabilities for the current host. * */ codecSupport: FfmpegCodecs; /** * The configuration options used to initialize this instance. */ readonly config: FfmpegOptionsConfig; /** * Indicates if debug logging is enabled. */ readonly debug: boolean; /** * Logging interface for output and errors. */ readonly log: HomebridgePluginLogging | Logging; /** * Function returning the name for this options instance to be used for logging. */ readonly name: () => string; private readonly hwPixelFormat; /** * 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); /** * Determines and configures hardware-accelerated video decoding and transcoding for the host system. * * This internal method checks for the availability of hardware codecs and accelerators based on the host platform and updates * FFmpeg options to use the best available hardware or falls back to software processing when necessary. * It logs warnings or errors if required codecs or hardware acceleration are unavailable. * * This method is called automatically by the `FfmpegOptions` constructor and is not intended to be called directly. * * @returns `true` if hardware-accelerated transcoding is enabled after configuration, otherwise `false`. * * @example * * ```ts * // This method is invoked by the FfmpegOptions constructor: * const ffmpegOpts = new FfmpegOptions(optionsConfig); * * // Hardware acceleration configuration occurs automatically. * // Developers typically do not need to call configureHwAccel() directly. * ``` * * @see FfmpegCodecs * @see FfmpegOptions */ private configureHwAccel; /** * 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. */ get audioDecoder(): string; /** * Returns the video decoder arguments to use for decoding video. * * @param codec - Optional. Codec to decode (`"av1"`, `"h264"` (default), or `"hevc"`). * @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 FFmpeg crop filter string, or a default no-op filter if cropping is disabled. * * @returns The crop filter string for FFmpeg. */ get cropFilter(): string; /** * Generates the default set of FFmpeg video encoder arguments for software transcoding using libx264. * * This method builds command-line options for the FFmpeg libx264 encoder based on the provided encoder options, including bitrate, H.264 profile and level, pixel * format, frame rate, buffer size, and optional smart quality settings. It is used internally when hardware-accelerated transcoding is not enabled or supported. * * @param options - The encoder options to use for generating FFmpeg arguments. * * @returns An array of FFmpeg command-line arguments for software video encoding. * * @example * * ```ts * const encoderOptions: VideoEncoderOptions = { * * bitrate: 2000, * fps: 30, * height: 720, * idrInterval: 2, * inputFps: 30, * level: H264Level.LEVEL3_1, * profile: H264Profile.MAIN, * smartQuality: true, * width: 1280 * }; * * const args = ffmpegOpts['defaultVideoEncoderOptions'](encoderOptions); * ``` * * @see VideoEncoderOptions */ private defaultVideoEncoderOptions; /** * 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 pixel count supported by a specific hardware encoder on the host system, or `Infinity` if not limited. * * @returns Maximum supported pixel count. */ get hostSystemMaxPixels(): number; /** * Converts a HomeKit H.264 level enum value to the corresponding FFmpeg string or numeric representation. * * This helper is used to translate between HomeKit's `H264Level` enum and the string or numeric format expected by FFmpeg's `-level:v` argument. * * @param level - The H.264 level to translate. * @param numeric - Optional. If `true`, returns the numeric representation (e.g., "31"). If `false` or omitted, returns the standard string format (e.g., "3.1"). * * @returns The FFmpeg-compatible H.264 level string or numeric value. * * @example * * ```ts * ffmpegOpts['getH264Level'](H264Level.LEVEL3_1); // "3.1" * * ffmpegOpts['getH264Level'](H264Level.LEVEL4_0, true); // "40" * ``` * * @see H264Level */ private getH264Level; /** * Converts a HomeKit H.264 profile enum value to the corresponding FFmpeg string or numeric representation. * * This helper is used to translate between HomeKit's `H264Profile` enum and the string or numeric format expected by FFmpeg's `-profile:v` argument. * * @param profile - The H.264 profile to translate. * @param numeric - Optional. If `true`, returns the numeric representation (e.g., "100"). If `false` or omitted, returns the standard string format (e.g., "high"). * * @returns The FFmpeg-compatible H.264 profile string or numeric value. * * @example * * ```ts * ffmpegOpts['getH264Profile'](H264Profile.HIGH); // "high" * * ffmpegOpts['getH264Profile'](H264Profile.BASELINE, true); // "66" * ``` * * @see H264Profile */ private getH264Profile; }