import { EventEmitter } from "node:events";
import type { Nullable } from "./protect-types.js";
import type { ProtectApi } from "./protect-api.js";
import type { ProtectLogging } from "./protect-logging.js";
import { Readable } from "node:stream";
/**
 * Options for configuring a livestream session.
 *
 * @property chunkSize        - Optionally specify the maximum payload size of each websocket packet. Larger sizes mean lower fragmentation. Defaults to 4096.
 * @property emitTimestamps   - Optionally emit the decode timestamps of frames as timestamp events. This is the same information that appears in `tfdt` boxes.
 * @property lens             - Optionally specify alternate cameras on a Protect device, such as a package camera.
 * @property segmentLength    - Optionally specify the segment length, in milliseconds, of each fMP4 segment. Defaults to 100ms.
 * @property requestId        - Optionally specify a request ID to the Protect controller. This is primarily used for logging purposes.
 * @property useStream        - If `true`, a Node.js Readable stream interface will be created for consuming raw fMP4 segments instead of using EventEmitter events.
 *                              Defaults to false.
 */
export interface LivestreamOptions {
    chunkSize: number;
    emitTimestamps: boolean;
    lens: number;
    requestId: string;
    segmentLength: number;
    useStream: boolean;
}
/**
 * This class provides a complete event-driven API to access the UniFi Protect Livestream API endpoint.
 *
 * 1. Create an instance of the {@link ProtectApi | UniFi Protect API} to connect to the Protect controller.
 *
 * 2. Create an instance of {@link ProtectLivestream | Protect Livestream} using the API instance above either directly, or through calling
 * {@link ProtectApi.createLivestream | createLivestream} method on an instance of {@link ProtectApi} (preferred).
 *
 * 3. Start a livestream using {@link start}, stop it with {@link stop}, and listen for events.
 *
 * 4. Listen for `message` events emitted by {@link ProtectLivestream} which provides Buffers containing the raw fMP4 segment data as it's produced by Protect. You can
 *    alternatively listen individually for the initialization segment or regular fMP4 segments if you'd like to distinguish between the two types of segments.
 *
 * Those are the basics that gets us up and running.
 *
 * @event close       - Emitted when the livestream WebSocket connection has been closed. This event fires after cleanup is complete and the connection is fully
 *                      terminated.
 * @event codec       - Emitted when codec information is received from the controller. The codec string is passed as an argument in the format "codec,container"
 *                      (e.g., "hev1.1.6.L150,mp4a.40.2"). Only emitted when not using stream mode.
 * @event initsegment - Emitted when an fMP4 initialization segment (FTYP and MOOV boxes) is received. The complete initialization segment Buffer is passed as an
 *                      argument. Only emitted when not using stream mode.
 * @event mdat        - Emitted when an MDAT box (media data) has been received as part of a segment. The MDAT Buffer is passed as an argument. Only emitted when not
 *                      using stream mode.
 * @event message     - Emitted when any complete fMP4 segment is received, whether initialization or regular segment. The complete segment Buffer is passed as an
 *                      argument. Only emitted when not using stream mode.
 * @event moof        - Emitted when a MOOF box (movie fragment metadata) has been received as part of a segment. The MOOF Buffer is passed as an argument. Only emitted
 *                      when not using stream mode.
 * @event segment     - Emitted when a non-initialization fMP4 segment (MOOF/MDAT pair) is fully assembled. The complete segment Buffer is passed as an argument. Only
 *                      emitted when not using stream mode.
 * @event timestamps  - Emitted when decode timestamp information is received from the controller. An array of numbers containing the decode timestamps of frames in the
 *                      next segment is passed as an argument, mirroring the tfdt box contents.
 */
export declare class ProtectLivestream extends EventEmitter {
    private _initSegment;
    private _codec;
    private _stream;
    private api;
    private heartbeat;
    private initSegmentPromise?;
    private lastMessage;
    private log;
    private sessionAbort;
    private ws;
    constructor(api: ProtectApi, log: ProtectLogging);
    /**
     * Start an fMP4 livestream session from the Protect controller.
     *
     * @param cameraId         - Protect camera device ID property from the camera's {@link ProtectTypes.ProtectCameraConfigInterface | ProtectCameraConfig}.
     * @param channel          - Camera channel to use, indexing the channels array in the camera's {@link ProtectTypes.ProtectCameraConfigInterface | ProtectCameraConfig}.
     * @param options          - Optional parameters to further customize the livestream session.
     *
     * @returns Returns `true` if the livestream has successfully started, `false` otherwise.
     *
     * @event close       - Emitted when the livestream connection terminates for any reason, including manual stops or errors.
     * @event codec       - Emitted with the codec information string when received from the controller (stream mode disabled only).
     * @event initsegment - Emitted with the initialization segment Buffer containing FTYP and MOOV boxes (stream mode disabled only).
     * @event message     - Emitted with each complete fMP4 segment Buffer, both initialization and regular segments (stream mode disabled only).
     * @event segment     - Emitted with each complete non-initialization segment Buffer containing MOOF/MDAT pairs (stream mode disabled only).
     * @event timestamps  - Emitted with decode timestamp arrays when emitTimestamps is enabled in options.
     *
     * @remarks Once a livestream session has started, the following events can be listened for (unless you've specified `useStream` in `options`, in which case only the
     *          `close` event is available):
     *
     * | Event         | Description                                                                                                                                  |
     * |---------------|----------------------------------------------------------------------------------------------------------------------------------------------|
     * | `close`       | Livestream has been closed.                                                                                                                  |
     * | `codec`       | The codec and container format in use in the livestream. The codec information will be passed as an argument to any listeners.               |
     * | `initsegment` | An fMP4 initialization segment has been received. The segment will be passed as an argument to any listeners.                                |
     * | `message`     | An fMP4 segment has been received. No distinction is made between segment types. The segment will be passed as an argument to any listeners. |
     * | `segment`     | A non-initialization fMP4 segment has been received. The segment will be passed as an argument to any listeners.                             |
     * | `timestamps`  | An array of numbers containing the decode timestamps of the frames in the next segment. It mirrors what is provided in the `tfdt` box.       |
     */
    start(cameraId: string, channel: number, options?: Partial<LivestreamOptions>): Promise<boolean>;
    /**
     * Stop an fMP4 livestream session from the Protect controller.
     */
    stop(): void;
    /**
     * Configure the websocket to populate the prebuffer.
     *
     * @event close - Emitted when the WebSocket connection closes or encounters an error requiring termination.
     *
     * @internal
     */
    private launchLivestream;
    /**
     * Process fMP4 packets as they arrive over the websocket.
     *
     * @event codec       - Emitted when we have received a codec packet.
     * @event initsegment - Emitted when we have received the initialization segment.
     * @event mdat        - Emitted at segment end with the accumulated MDAT box data.
     * @event message     - Emitted with complete segments (both initialization and regular).
     * @event moof        - Emitted at segment end with the accumulated MOOF box data.
     * @event segment     - Emitted when we have received a complete non-initialization segment.
     * @event timestamps  - Emitted when we have received the decode timestamp arrays (when we have extendedVideoMetadata enabled).
     *
     * @internal
     */
    private processLivestream;
    /**
     * Retrieve the initialization segment that must be at the start of every fMP4 stream.
     *
     * @remarks If the stream is stopped before the initialization segment is received, the returned promise rejects with an AbortError. Callers should handle this
     *   rejection or wrap the call with a timeout.
     *
     * @returns Returns a promise that resolves once the initialization segment has been seen, or returning it immediately if it already has been.
     */
    getInitSegment(): Promise<Buffer>;
    private awaitInitSegment;
    /**
     * The initialization segment that must be at the start of every fMP4 stream.
     *
     * @returns Returns the initialization segment if it exists, or `null` otherwise.
     */
    get initSegment(): Nullable<Buffer>;
    /**
     * The codecs in use for this livestream session.
     *
     * @returns Returns a string containing the codec information, if it exists, or `null` otherwise.
     *
     * @remarks Codec information is provided as `codec,container` where codec is either `avc` (H.264) or `hev` (H.265). The container format is always `mp4`.
     *
     * @example `hev1.1.6.L150,mp4a.40.2`
     */
    get codec(): string;
    /**
     * Retrieve a Node.js Readable stream if `useStream` was set to true (defaults to false) when starting the livestream.
     * Otherwise, returns `null`.
     */
    get stream(): Nullable<Readable>;
}
