import type { Logger } from "../util.ts"; /** * Parse the stdout of `ffmpeg -version` and return the version string. Returns `"unknown"` when the expected `"ffmpeg version X Copyright..."` line is not found - * matching the behavior of the class-level probe, which records the literal `"unknown"` when it cannot identify the binary. * * Exposed as a module-scope helper (rather than remaining a closure inside the class) so the parse logic is unit-testable against fixture strings without spinning up * the probe plumbing. * * @param stdout - Captured stdout from `ffmpeg -hide_banner -version`. * * @returns The version string, or `"unknown"` if the version line is absent. * * @category FFmpeg */ export declare function parseFfmpegVersion(stdout: string): string; /** * A parsed FFmpeg version, split into its numeric triple. Produced by {@link parseFfmpegVersionParts}; consumed by {@link ffmpegVersionAtLeast}. * * @property major - The leading integer (e.g., 6, 7, 8, 10). 0 when the version string doesn't begin with a digit. * @property minor - The second numeric segment. 0 when absent or non-numeric. * @property patch - The third numeric segment. 0 when absent or non-numeric. * * @category FFmpeg */ export interface FfmpegVersionParts { major: number; minor: number; patch: number; } /** * Parse an FFmpeg version string into its numeric triple. Splits on `.` and `-` so real-world version strings parse correctly across release tarballs ("8.1.1"), * distributor suffixes ("8.1.1-tessus"), distro packages ("4.4.2-0ubuntu0.22.04.1"), and git snapshots ("N-123456-gabcdef"). Any non-numeric segment yields `0` via the * `|| 0` fallback, which gives a safe, conservative result: an unknown build parses as `{ major: 0, minor: 0, patch: 0 }` and fails every {@link ffmpegVersionAtLeast} * check where the requested major is >= 1. * * @param version - An FFmpeg version string as produced by {@link parseFfmpegVersion} or by `FfmpegCodecs.ffmpegVersion`. * * @returns The parsed numeric triple. * * @example * * ```ts * parseFfmpegVersionParts("8.1.1"); // { major: 8, minor: 1, patch: 1 } * parseFfmpegVersionParts("8.1.1-tessus"); // { major: 8, minor: 1, patch: 1 } * parseFfmpegVersionParts("N-123456-gabcdef"); // { major: 0, minor: 123456, patch: 0 } - git snapshot, effectively "unknown" * parseFfmpegVersionParts("unknown"); // { major: 0, minor: 0, patch: 0 } * ``` * * @category FFmpeg */ export declare function parseFfmpegVersionParts(version: string): FfmpegVersionParts; /** * Return `true` when `parts` represents an FFmpeg version at least as new as the requested major/minor/patch. Compares major, then minor, then patch - the canonical * semver ordering. This is the single source of truth for version-gating comparisons across the library; both the `FfmpegCodecs.ffmpegAtLeast` instance method and the * test-side fixtures delegate here so the boundary logic lives in one implementation. * * @param parts - A parsed version triple as produced by {@link parseFfmpegVersionParts}. * @param major - The minimum major version to accept. * @param minor - The minimum minor version, when major is equal. Defaults to `0`. * @param patch - The minimum patch version, when major and minor are equal. Defaults to `0`. * * @returns `true` if `parts` is >= the requested version; `false` otherwise. * * @example * * ```ts * const parts = parseFfmpegVersionParts("8.1.2"); * * ffmpegVersionAtLeast(parts, 8); // true - 8.1.2 >= 8.0.0 * ffmpegVersionAtLeast(parts, 8, 1, 3); // false - 8.1.2 < 8.1.3 * ffmpegVersionAtLeast(parts, 9); // false - 8.1.2 < 9.0.0 * ``` * * @category FFmpeg */ export declare function ffmpegVersionAtLeast(parts: FfmpegVersionParts, major: number, minor?: number, patch?: number): boolean; /** * Parse the stdout of `ffmpeg -hwaccels` and return the list of hardware-acceleration method names in lowercase, in the order they appeared. Skips blank lines and * the leading `"Hardware acceleration methods:"` banner. * * @param stdout - Captured stdout from `ffmpeg -hide_banner -hwaccels`. * * @returns Lowercased acceleration method names, one per entry. * * @category FFmpeg */ export declare function parseFfmpegHwAccels(stdout: string): string[]; /** * Parse the stdout of `ffmpeg -codecs` into a format-keyed index of decoders and encoders. Both sets are lowercased for case-insensitive `hasDecoder` / * `hasEncoder` lookups. Formats with only decoders or only encoders still produce a full entry (the opposite set is simply empty). * * @param stdout - Captured stdout from `ffmpeg -hide_banner -codecs`. * * @returns A record keyed by codec format, each entry carrying the decoders and encoders reported for that format. * * @category FFmpeg */ export declare function parseFfmpegCodecs(stdout: string): Record; encoders: Set; }>; /** * Parse the stdout of `vcgencmd get_mem gpu` into a megabyte value. Returns `0` when the expected `gpu=M` shape is absent or the captured digits fail integer * parsing - matching the class-level fallback. * * @param stdout - Captured stdout from `vcgencmd get_mem gpu`. * * @returns The reported GPU memory size in megabytes, or `0` when the value could not be read. * * @category FFmpeg */ export declare function parseRpiGpuMem(stdout: string): number; /** * Options for configuring FFmpeg probing. * * @category FFmpeg */ export interface FOptions { /** * Optional. The path or command used to execute FFmpeg. Defaults to "ffmpeg". */ ffmpegExec?: string; /** * Logging interface for output and errors. */ log: Logger; /** * Optional. Enables or disables verbose logging output. Defaults to `false`. */ verbose?: boolean; } /** * Immutable state shape that a populated `FfmpegCodecs` instance holds. Produced by {@link FfmpegCodecs.probe} from live probing, or by {@link FfmpegCodecs.fromState} * for callers that already have the capability data (tests, cached probe results, plugin-side injection of pre-computed capabilities). The state is the single source * of truth for every getter and predicate on the class - the instance is a thin accessor facade. * * @property codecs - Format-keyed index of advertised decoders and encoders. * @property cpuGeneration - Detected CPU generation for Intel Linux hosts and Apple Silicon macOS hosts; `0` when unknown. * @property ffmpegExec - The path or command used to invoke FFmpeg. * @property ffmpegVersion - FFmpeg version string as reported by `ffmpeg -version`; `"unknown"` when the version line was absent. * @property ffmpegVersionParts - Pre-parsed numeric triple derived from `ffmpegVersion`; produced by {@link parseFfmpegVersionParts}. * @property gpuMem - Raspberry Pi GPU memory in megabytes (from `vcgencmd get_mem gpu`); `0` on non-RPi hosts. * @property hostSystem - `"generic"`, `"macOS.Apple"`, `"macOS.Intel"`, or `"raspbian"`. * @property hwAccels - Advertised and capability-validated hardware accelerator names in lowercase. * @property verbose - Controls verbose logging behavior propagated to consumers. * * @category FFmpeg */ export interface FfmpegCodecsState { readonly codecs: Readonly; readonly encoders: ReadonlySet; }>>; readonly cpuGeneration: number; readonly ffmpegExec: string; readonly ffmpegVersion: string; readonly ffmpegVersionParts: FfmpegVersionParts; readonly gpuMem: number; readonly hostSystem: string; readonly hwAccels: ReadonlySet; readonly verbose: boolean; } /** * Probe FFmpeg capabilities and codecs on the host system. * * Construct via the static factory {@link FfmpegCodecs.probe} to run the live probe pipeline, or via {@link FfmpegCodecs.fromState} to inject pre-assembled state * (tests, cached capability data). Instances are immutable value objects - every getter and predicate reads from a frozen {@link FfmpegCodecsState} snapshot * assembled at construction, so callers holding a reference know its state cannot shift underneath them. * * @example * * ```ts * const codecs = await FfmpegCodecs.probe({ ffmpegExec: "ffmpeg", log: console, verbose: true }); * * if(codecs) { * * console.log("Available FFmpeg version:", codecs.ffmpegVersion); * * if(codecs.hasDecoder("h264", "h264_v4l2m2m")) { * * console.log("Hardware H.264 decoder is available."); * } * } * ``` * * @category FFmpeg */ export declare class FfmpegCodecs { #private; private constructor(); /** * Async factory. Runs the full probe pipeline (host-system detection, optional Raspberry Pi GPU memory, FFmpeg version + codec inventory + hardware-accel inventory * with per-accel capability validation) and returns a populated instance on success, or `null` when any required probe fails. Every inner probe runs under a * watchdog timeout so a slow or hung FFmpeg binary cannot stall the caller indefinitely; the optional `init.signal` composes with that timeout so callers can cancel * probing from outside (for example, during plugin shutdown). * * @param options - Options used to configure the probe (FFmpeg executable, logger, verbose flag). * @param init - Optional probe options. `signal` cancels in-flight probes; the per-call watchdog still applies. * * @returns A promise that resolves to a populated `FfmpegCodecs` instance, or `null` if probing failed. * * @example * * ```ts * const codecs = await FfmpegCodecs.probe({ log: plugin.log }, { signal: shutdown.signal }); * * if(!codecs) { * * plugin.log.error("FFmpeg probing failed."); * } * ``` */ static probe(options: FOptions, init?: { signal?: AbortSignal; }): Promise; /** * Sync factory. Wraps a pre-assembled {@link FfmpegCodecsState} in a `FfmpegCodecs` instance without running any probes. Intended for tests that build a stand-in * capability snapshot and for plugins that cache probe results across restarts and want to rehydrate the class without re-probing. * * @param state - Fully-assembled capability snapshot. * * @returns A populated `FfmpegCodecs` instance backed by the supplied state. * * @example * * ```ts * const codecs = FfmpegCodecs.fromState({ * * codecs: {}, * cpuGeneration: 0, * ffmpegExec: "ffmpeg", * ffmpegVersion: "8.0", * ffmpegVersionParts: parseFfmpegVersionParts("8.0"), * gpuMem: 0, * hostSystem: "macOS.Apple", * hwAccels: new Set([ "videotoolbox" ]), * verbose: false * }); * ``` */ static fromState(state: FfmpegCodecsState): FfmpegCodecs; /** * The path or command name used to invoke FFmpeg. */ get ffmpegExec(): string; /** * Indicates whether verbose logging is enabled for FFmpeg probing and downstream consumers. */ get verbose(): boolean; /** * Returns the amount of GPU memory available on the host system, in megabytes. * * @remarks Always returns `0` on non-Raspberry Pi systems. */ get gpuMem(): number; /** * Returns the detected FFmpeg version string. `"unknown"` when the probe ran but the `ffmpeg version X Copyright...` line was not found in stdout. Any other value * is the literal version string reported by the binary and may carry suffixes (`"8.1.1-tessus"`, `"4.4.2-0ubuntu0.22.04.1"`, etc.). For version-comparison decisions, * prefer {@link ffmpegAtLeast} over parsing this string directly. */ get ffmpegVersion(): string; /** * Returns the detected FFmpeg major version as a number, or `0` when detection failed or the version string doesn't begin with an integer. Useful for display * ("Running FFmpeg 8") and for callers that need the raw major number. Use {@link ffmpegAtLeast} for version-gating comparisons so all version logic flows through * a single boundary-correct comparison primitive. * * @returns The major version number (e.g., `6`, `7`, `8`, `10`), or `0` if the version is unknown or non-numeric. */ get ffmpegMajorVersion(): number; /** * Return `true` when the detected FFmpeg build is at least the requested version. Compares major, then minor, then patch - the canonical semver ordering. This is * the single source of truth for version-gating decisions across the library; callers prefer this over hand-rolled comparisons so the boundary logic (major-equal * but minor-greater means "newer", etc.) lives in one place and stays consistent. * * @param major - The minimum major version to accept. * @param minor - The minimum minor version, when major is equal. Defaults to `0`. * @param patch - The minimum patch version, when major and minor are equal. Defaults to `0`. * * @returns `true` if the detected version is >= the requested version; `false` otherwise. Returns `false` for unknown or unparseable version strings (major = 0). * * @example * * ```ts * if(codecs.ffmpegAtLeast(8)) { * * // FFmpeg 8.0.0 or later. * } * * if(codecs.ffmpegAtLeast(8, 1)) { * * // FFmpeg 8.1.0 or later. * } * ``` */ ffmpegAtLeast(major: number, minor?: number, patch?: number): boolean; /** * Returns the host system type we are running on as one of `"generic"`, `"macOS.Apple"`, `"macOS.Intel"`, or `"raspbian"`. * * @remarks We are only trying to detect host capabilities to the extent they impact which FFmpeg options we are going to use. */ get hostSystem(): string; /** * Returns the CPU generation if we're on Linux and have an Intel processor or on macOS and have an Apple Silicon processor. * * @returns Returns the CPU generation or 0 if it can't be detected or an invalid platform. */ get cpuGeneration(): number; /** * Checks whether a specific decoder is available for a given codec. * * @param codec - The codec name, e.g., `"h264"`. * @param decoder - The decoder name to check for, e.g., `"h264_qsv"`. * * @returns `true` if the decoder is available for the codec, `false` otherwise. * * @example * * ```ts * if(codecs.hasDecoder("h264", "h264_qsv")) { * * // Use hardware decoding. * } * ``` */ hasDecoder(codec: string, decoder: string): boolean; /** * Checks whether a specific encoder is available for a given codec. * * @param codec - The codec name, e.g., `"h264"`. * @param encoder - The encoder name to check for, e.g., `"h264_videotoolbox"`. * * @returns `true` if the encoder is available for the codec, `false` otherwise. * * @example * * ```ts * if(codecs.hasEncoder("h264", "h264_videotoolbox")) { * * // Use hardware encoding. * } * ``` */ hasEncoder(codec: string, encoder: string): boolean; /** * Checks whether a given hardware acceleration method is available and validated on the host, as provided by the output of `ffmpeg -hwaccels` and the per-accel * capability probe. * * @param accel - The hardware acceleration method name, e.g., `"videotoolbox"`. * * @returns `true` if the hardware acceleration method is available, `false` otherwise. * * @example * * ```ts * if(codecs.hasHwAccel("videotoolbox")) { * * // Hardware acceleration is supported. * } * ``` */ hasHwAccel(accel: string): boolean; } //# sourceMappingURL=codecs.d.ts.map