homebridge-plugin-utils
Version:
Opinionated utilities to provide common capabilities and create rich configuration webUI experiences for Homebridge plugins.
91 lines (90 loc) • 4.46 kB
TypeScript
/**
* ISO BMFF (fMP4) box parsing utilities for working with fragmented MP4 data.
*
* This module provides lightweight, Buffer-based utilities for inspecting ISO Base Media File Format (ISO BMFF) structures commonly found in fragmented MP4 (fMP4)
* streams. It enables locating specific box types, splitting fragments into their moof/mdat components, detecting keyframe (sync sample) segments by parsing the TRUN
* sample flags, and identifying audio track presence in initialization segments.
*
* These utilities operate on complete Buffers and are independent of FFmpeg processes or streaming pipelines.
*
* @module
*/
import type { Nullable } from "../util.js";
/**
* ISO BMFF box header size in bytes: 4 bytes big-endian size + 4 bytes ASCII type.
*
* @category FFmpeg
*/
export declare const BOX_HEADER_SIZE = 8;
/**
* Describes the location of an ISO BMFF box within a buffer.
*
* @property offset - The byte offset of the box start (including the header).
* @property size - The total box size in bytes (including the header).
*
* @category FFmpeg
*/
export interface FMp4Box {
offset: number;
size: number;
}
/**
* Locates the first ISO BMFF box of a given type within a byte range.
*
* Walks the standard box headers (4-byte big-endian size + 4-byte ASCII type) starting at `start` and ending at `end`. Returns the offset and size of the first
* matching box, or `null` if no match is found. Does not handle extended-size boxes (64-bit size field) as these are uncommon in fMP4 livestream contexts.
*
* @param buffer - The buffer containing ISO BMFF box data.
* @param type - The 4-character ASCII box type to search for (e.g. "moof", "traf", "trun"). Must be exactly 4 characters.
* @param start - Optional. The byte offset to begin searching from. Defaults to 0.
* @param end - Optional. The byte offset to stop searching at. Defaults to the buffer length.
*
* @returns The box location, or `null` if not found.
*
* @category FFmpeg
*/
export declare function findBox(buffer: Buffer, type: string, start?: number, end?: number): Nullable<FMp4Box>;
/**
* Determines whether an fMP4 segment contains a keyframe (sync sample) by parsing the TRUN sample flags.
*
* Traverses the box hierarchy `moof -> traf -> trun` and inspects the sample flags to determine if the first sample is a sync sample (keyframe/IDR frame). Checks
* `first_sample_flags` first (the common case for fragments generated with `frag_keyframe`), then falls back to per-sample flags if available. Returns `false` if the
* box structure cannot be parsed or if the flags indicate a non-sync sample.
*
* @param segment - A buffer containing a complete fMP4 segment (typically a moof+mdat pair).
*
* @returns `true` if the segment's first sample is a sync sample (keyframe), `false` otherwise.
*
* @category FFmpeg
*/
export declare function isKeyframe(segment: Buffer): boolean;
/**
* Determines whether an fMP4 initialization segment contains an audio track by inspecting the handler type in each track's media handler box.
*
* Traverses the box hierarchy `moov -> trak -> mdia -> hdlr` for every track in the init segment and checks the handler_type field for "soun" (0x736F756E). This is the
* standard ISO BMFF mechanism for identifying track media types - "soun" for audio, "vide" for video, "subt" for subtitles, etc.
*
* @param initSegment - A buffer containing a complete fMP4 initialization segment (typically ftyp + moov).
*
* @returns `true` if the init segment contains at least one audio track, `false` otherwise.
*
* @category FFmpeg
*/
export declare function hasAudioTrack(initSegment: Buffer): boolean;
/**
* Splits an fMP4 fragment into its moof and mdat components.
*
* Locates the `mdat` box and returns everything before it as the moof portion (which includes the moof box and any preceding metadata boxes) and everything from the
* mdat box to the end of the fragment as the mdat portion. The returned buffers are subarray views into the original buffer, so no data is copied. Returns `null` if
* the mdat box cannot be found.
*
* @param fragment - A buffer containing a complete fMP4 fragment.
*
* @returns An object with `moof` and `mdat` sub-buffers, or `null` if the structure cannot be parsed.
*
* @category FFmpeg
*/
export declare function splitMoofMdat(fragment: Buffer): Nullable<{
mdat: Buffer;
moof: Buffer;
}>;