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
TypeScript
/**
* 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;
}