/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */
import { AudioCodec, MediaCodec, VideoCodec } from './codec.js';
import { Input } from './input.js';
import { PacketRetrievalOptions } from './media-sink.js';
import { MaybePromise, Rational, Rotation } from './misc.js';
import { TrackType } from './output.js';
import { EncodedPacket, PacketType } from './packet.js';
import { TrackDisposition } from './metadata.js';
import { DurationMetadataRequestOptions } from './demuxer.js';
/**
 * Contains aggregate statistics about the encoded packets of a track.
 * @group Input files & tracks
 * @public
 */
export type PacketStats = {
    /** The total number of packets. */
    packetCount: number;
    /** The average number of packets per second. For video tracks, this will equal the average frame rate (FPS). */
    averagePacketRate: number;
    /** The average number of bits per second. */
    averageBitrate: number;
};
export interface InputTrackBacking {
    getType(): TrackType;
    getId(): number;
    getNumber(): number;
    getCodec(): MaybePromise<MediaCodec | null>;
    getInternalCodecId(): MaybePromise<string | number | Uint8Array | null>;
    getName(): MaybePromise<string | null>;
    getLanguageCode(): MaybePromise<string>;
    getTimeResolution(): MaybePromise<number>;
    isRelativeToUnixEpoch(): MaybePromise<boolean>;
    getDisposition(): MaybePromise<TrackDisposition>;
    getPairingMask(): bigint;
    getBitrate(): MaybePromise<number | null>;
    getAverageBitrate(): MaybePromise<number | null>;
    getDurationFromMetadata(options: DurationMetadataRequestOptions): Promise<number | null>;
    getLiveRefreshInterval(): Promise<number | null>;
    getHasOnlyKeyPackets?(): MaybePromise<boolean | null>;
    getDecoderConfig(): Promise<VideoDecoderConfig | AudioDecoderConfig | null>;
    getMetadataCodecParameterString?(): MaybePromise<string | null>;
    getFirstPacket(options: PacketRetrievalOptions): Promise<EncodedPacket | null>;
    getPacket(timestamp: number, options: PacketRetrievalOptions): Promise<EncodedPacket | null>;
    getNextPacket(packet: EncodedPacket, options: PacketRetrievalOptions): Promise<EncodedPacket | null>;
    getKeyPacket(timestamp: number, options: PacketRetrievalOptions): Promise<EncodedPacket | null>;
    getNextKeyPacket(packet: EncodedPacket, options: PacketRetrievalOptions): Promise<EncodedPacket | null>;
}
/**
 * Represents a media track in an input file.
 * @group Input files & tracks
 * @public
 */
export declare abstract class InputTrack {
    /** The input file this track belongs to. */
    readonly input: Input;
    /** The type of the track. */
    abstract get type(): TrackType;
    /** Returns the codec of the track's packets. */
    abstract getCodec(): Promise<MediaCodec | null>;
    /**
     * The codec of the track's packets.
     * @deprecated Use {@link InputTrack.getCodec} instead.
     */
    abstract get codec(): MediaCodec | null;
    /** Returns the full codec parameter string for this track. */
    abstract getCodecParameterString(): Promise<string | null>;
    /** Checks if this track's packets can be decoded by the browser. */
    abstract canDecode(): Promise<boolean>;
    /**
     * For a given packet of this track, this method determines the actual type of this packet (key/delta) by looking
     * into its bitstream. Returns null if the type couldn't be determined.
     */
    abstract determinePacketType(packet: EncodedPacket): Promise<PacketType | null>;
    /**
     * Returns whether the track metadata says that this track only contains key packets. The actual packets may
     * differ.
     */
    abstract hasOnlyKeyPackets(): Promise<boolean>;
    /** Returns true if and only if this track is a video track. */
    isVideoTrack(): this is InputVideoTrack;
    /** Returns true if and only if this track is an audio track. */
    isAudioTrack(): this is InputAudioTrack;
    /** The unique ID of this track in the input file. */
    get id(): number;
    /**
     * The 1-based index of this track among all tracks of the same type in the input file. For example, the first
     * video track has number 1, the second video track has number 2, and so on. The index refers to the order in
     * which the tracks are returned by {@link Input.getTracks}.
     */
    get number(): number;
    /**
     * Returns the identifier of the codec used internally by the container. It is not homogenized by Mediabunny
     * and depends entirely on the container format.
     *
     * This method can be used to determine the codec of a track in case Mediabunny doesn't know that codec.
     *
     * - For ISOBMFF files, this resolves to the name of the Sample Description Box (e.g. `'avc1'`).
     * - For Matroska files, this resolves to the value of the `CodecID` element.
     * - For WAVE files, this resolves to the value of the format tag in the `'fmt '` chunk.
     * - For ADTS files, this resolves to the `MPEG-4 Audio Object Type`.
     * - For MPEG-TS files, this resolves to the `streamType` value from the Program Map Table.
     * - In all other cases, this resolves to `null`.
     */
    getInternalCodecId(): Promise<string | number | Uint8Array<ArrayBufferLike> | null>;
    /**
     * See {@link InputTrack.getInternalCodecId}.
     * @deprecated Use {@link InputTrack.getInternalCodecId} instead.
     */
    get internalCodecId(): string | number | Uint8Array<ArrayBufferLike> | null;
    /**
     * Returns the ISO 639-2/T language code for this track. If the language is unknown, this resolves to `'und'`
     * (undetermined).
     */
    getLanguageCode(): Promise<string>;
    /**
     * The ISO 639-2/T language code for this track. If the language is unknown, this field is `'und'` (undetermined).
     * @deprecated Use {@link InputTrack.getLanguageCode} instead.
     */
    get languageCode(): string;
    /** Returns the user-defined name for this track. */
    getName(): Promise<string | null>;
    /**
     * A user-defined name for this track.
     * @deprecated Use {@link InputTrack.getName} instead.
     */
    get name(): string | null;
    /**
     * Returns a positive number x such that all timestamps and durations of all packets of this track are
     * integer multiples of 1/x.
     */
    getTimeResolution(): Promise<number>;
    /**
     * A positive number x such that all timestamps and durations of all packets of this track are
     * integer multiples of 1/x.
     * @deprecated Use {@link InputTrack.getTimeResolution} instead.
     */
    get timeResolution(): number;
    /**
     * Returns whether the timestamps of this track are relative to the Unix epoch (January 1, 1970 00:00:00 UTC).
     * When `true`, each timestamp maps to a definitive point in time.
     */
    isRelativeToUnixEpoch(): Promise<boolean>;
    /** Returns the track's disposition, i.e. information about its intended usage. */
    getDisposition(): Promise<TrackDisposition>;
    /**
     * The track's disposition, i.e. information about its intended usage.
     * @deprecated Use {@link InputTrack.getDisposition} instead.
     */
    get disposition(): TrackDisposition;
    /**
     * Returns the peak bitrate of the track in bits per second, as specified in the track's metadata. This might not
     * match the actual media data's bitrate.
     */
    getBitrate(): Promise<number | null>;
    /**
     * Returns the average bitrate of the track in bits per second, as specified in the track's metadata. This might
     * not match the actual media data's bitrate.
     */
    getAverageBitrate(): Promise<number | null>;
    /**
     * Returns the start timestamp of the first packet of this track, in seconds. While often near zero, this value
     * may be positive or even negative. A negative starting timestamp means the track's timing has been offset. Samples
     * with a negative timestamp should not be presented.
     */
    getFirstTimestamp(): Promise<number>;
    /**
     * Returns the end timestamp of the last packet of this track, in seconds.
     *
     * By default, when the underlying media is live, this method will only resolve once the live stream ends. If you
     * want to query the current end timestamp of the stream, set {@link PacketRetrievalOptions.skipLiveWait} to `true`
     * in the options.
     */
    computeDuration(options?: PacketRetrievalOptions): Promise<number>;
    /**
     * Gets the duration (end timestamp) in seconds of this track from metadata stored in the file. This value may be
     * approximate or diverge from the actual, precise duration returned by `.computeDuration()`, but compared to that
     * method, this method is cheaper. When the duration cannot be determined from the file metadata, `null`
     * is returned.
     *
     * By default, when the underlying media is live, this method will only resolve once the live stream
     * ends. If you want to query the current duration of the media, set
     * {@link DurationMetadataRequestOptions.skipLiveWait} to `true` in the options.
     */
    getDurationFromMetadata(options?: DurationMetadataRequestOptions): Promise<number | null>;
    /**
     * Computes aggregate packet statistics for this track, such as average packet rate or bitrate.
     *
     * @param targetPacketCount - This optional parameter sets a target for how many packets this method must have
     * looked at before it can return early; this means, you can use it to aggregate only a subset (prefix) of all
     * packets. This is very useful for getting a great estimate of video frame rate without having to scan through the
     * entire file.
     *
     * By default, when the underlying media is live and `targetPacketCount` is not set, this method will only resolve
     * once the live stream ends. If you want to query the current packet statistics of the stream, set
     * {@link PacketRetrievalOptions.skipLiveWait} to `true` in the options.
     */
    computePacketStats(targetPacketCount?: number, options?: PacketRetrievalOptions): Promise<PacketStats>;
    /**
     * Whether or not this track is currently live, meaning the media's end is still unknown.
     *
     * The value returned by this method may change over time as the track stops being live. To keep track of the
     * track's live status, poll this method at the track's refresh interval
     * via {@link InputTrack.getLiveRefreshInterval}.
     */
    isLive(): Promise<boolean>;
    /**
     * Returns the track's live refresh interval in seconds, or `null` if the track is not live. This interval describes
     * the time it takes, on average, for new live media data to become available.
     */
    getLiveRefreshInterval(): Promise<number | null>;
    /**
     * Returns `true` if this track can be paired with the given track. Two tracks being pairable means they can be
     * presented (displayed) together.
     *
     * Returns `false` if `other` equals `this`.
     */
    canBePairedWith(other: InputTrack): boolean;
    /**
     * Gets the list of other tracks that can be paired with this track. An optional query can be provided to narrow
     * down the results.
     */
    getPairableTracks(query?: InputTrackQuery<InputTrack>): Promise<InputTrack[]>;
    /**
     * Gets the list of other video tracks that can be paired with this track. An optional query can be provided to
     * narrow down the results.
     */
    getPairableVideoTracks(query?: InputTrackQuery<InputVideoTrack>): Promise<InputVideoTrack[]>;
    /**
     * Gets the list of other audio tracks that can be paired with this track. An optional query can be provided to
     * narrow down the results.
     */
    getPairableAudioTracks(query?: InputTrackQuery<InputAudioTrack>): Promise<InputAudioTrack[]>;
    /** Returns the primary track that can be paired with this track, optionally steered by the provided query. */
    getPrimaryPairableVideoTrack(query?: InputTrackQuery<InputVideoTrack>): Promise<InputVideoTrack | null>;
    /** Returns the primary track that can be paired with this track, optionally steered by the provided query. */
    getPrimaryPairableAudioTrack(query?: InputTrackQuery<InputAudioTrack>): Promise<InputAudioTrack | null>;
    /** Returns `true` if there is another track that can be paired with this track. */
    hasPairableTrack(predicate?: (track: InputTrack) => MaybePromise<boolean>): Promise<boolean>;
    /** Returns `true` if there is a video track that can be paired with this track. */
    hasPairableVideoTrack(predicate?: (track: InputVideoTrack) => MaybePromise<boolean>): Promise<boolean>;
    /** Returns `true` if there is an audio track that can be paired with this track. */
    hasPairableAudioTrack(predicate?: (track: InputAudioTrack) => MaybePromise<boolean>): Promise<boolean>;
}
export interface InputVideoTrackBacking extends InputTrackBacking {
    getType(): 'video';
    getCodec(): MaybePromise<VideoCodec | null>;
    getCodedWidth(): MaybePromise<number>;
    getCodedHeight(): MaybePromise<number>;
    getSquarePixelWidth(): MaybePromise<number>;
    getSquarePixelHeight(): MaybePromise<number>;
    getMetadataDisplayWidth?(): MaybePromise<number | null>;
    getMetadataDisplayHeight?(): MaybePromise<number | null>;
    getRotation(): MaybePromise<Rotation>;
    getColorSpace(): Promise<VideoColorSpaceInit>;
    canBeTransparent(): Promise<boolean>;
    getDecoderConfig(): Promise<VideoDecoderConfig | null>;
}
/**
 * Represents a video track in an input file.
 * @group Input files & tracks
 * @public
 */
export declare class InputVideoTrack extends InputTrack {
    get type(): TrackType;
    /** The codec of the track's packets. */
    getCodec(): Promise<VideoCodec | null>;
    /**
     * The codec of the track's packets.
     * @deprecated Use {@link InputVideoTrack.getCodec} instead.
     */
    get codec(): VideoCodec | null;
    hasOnlyKeyPackets(): Promise<boolean>;
    /** Returns the width in pixels of the track's coded samples, before any transformations or rotations. */
    getCodedWidth(): Promise<number>;
    /**
     * The width in pixels of the track's coded samples, before any transformations or rotations.
     * @deprecated Use {@link InputVideoTrack.getCodedWidth} instead.
     */
    get codedWidth(): number;
    /** Returns the height in pixels of the track's coded samples, before any transformations or rotations. */
    getCodedHeight(): Promise<number>;
    /**
     * The height in pixels of the track's coded samples, before any transformations or rotations.
     * @deprecated Use {@link InputVideoTrack.getCodedHeight} instead.
     */
    get codedHeight(): number;
    /** Returns the angle in degrees by which the track's frames should be rotated (clockwise). */
    getRotation(): Promise<Rotation>;
    /**
     * The angle in degrees by which the track's frames should be rotated (clockwise).
     * @deprecated Use {@link InputVideoTrack.getRotation} instead.
     */
    get rotation(): Rotation;
    /**
     * Returns the width of the track's frames in square pixels, adjusted for pixel aspect ratio but before rotation.
     */
    getSquarePixelWidth(): Promise<number>;
    /**
     * The width of the track's frames in square pixels, adjusted for pixel aspect ratio but before rotation.
     * @deprecated Use {@link InputVideoTrack.getSquarePixelWidth} instead.
     */
    get squarePixelWidth(): number;
    /**
     * Returns the height of the track's frames in square pixels, adjusted for pixel aspect ratio but before rotation.
     */
    getSquarePixelHeight(): Promise<number>;
    /**
     * The height of the track's frames in square pixels, adjusted for pixel aspect ratio but before rotation.
     * @deprecated Use {@link InputVideoTrack.getSquarePixelHeight} instead.
     */
    get squarePixelHeight(): number;
    /**
     * Returns the pixel aspect ratio of the track's frames as a rational number in its reduced form. Most videos use
     * square pixels (1:1).
     */
    getPixelAspectRatio(): Promise<Rational>;
    /**
     * The pixel aspect ratio of the track's frames, as a rational number in its reduced form. Most videos use
     * square pixels (1:1).
     * @deprecated Use {@link InputVideoTrack.getPixelAspectRatio} instead.
     */
    get pixelAspectRatio(): Rational;
    /** Returns the display width of the track's frames in pixels, after aspect ratio adjustment and rotation. */
    getDisplayWidth(): Promise<number>;
    /**
     * The display width of the track's frames in pixels, after aspect ratio adjustment and rotation.
     * @deprecated Use {@link InputVideoTrack.getDisplayWidth} instead.
     */
    get displayWidth(): number;
    /** Returns the display height of the track's frames in pixels, after aspect ratio adjustment and rotation. */
    getDisplayHeight(): Promise<number>;
    /**
     * The display height of the track's frames in pixels, after aspect ratio adjustment and rotation.
     * @deprecated Use {@link InputVideoTrack.getDisplayHeight} instead.
     */
    get displayHeight(): number;
    /** Returns the color space of the track's samples. */
    getColorSpace(): Promise<VideoColorSpaceInit>;
    /** If this method returns true, the track's samples use a high dynamic range (HDR). */
    hasHighDynamicRange(): Promise<boolean>;
    /** Checks if this track may contain transparent samples with alpha data. */
    canBeTransparent(): Promise<boolean>;
    /**
     * Returns the [decoder configuration](https://www.w3.org/TR/webcodecs/#video-decoder-config) for decoding the
     * track's packets using a [`VideoDecoder`](https://developer.mozilla.org/en-US/docs/Web/API/VideoDecoder). Returns
     * null if the track's codec is unknown.
     */
    getDecoderConfig(): Promise<VideoDecoderConfig | null>;
    getCodecParameterString(): Promise<string | null>;
    canDecode(): Promise<boolean>;
    determinePacketType(packet: EncodedPacket): Promise<PacketType | null>;
}
export interface InputAudioTrackBacking extends InputTrackBacking {
    getType(): 'audio';
    getCodec(): MaybePromise<AudioCodec | null>;
    getNumberOfChannels(): MaybePromise<number>;
    getSampleRate(): MaybePromise<number>;
    getDecoderConfig(): Promise<AudioDecoderConfig | null>;
}
/**
 * Represents an audio track in an input file.
 * @group Input files & tracks
 * @public
 */
export declare class InputAudioTrack extends InputTrack {
    get type(): TrackType;
    /** The codec of the track's packets. */
    getCodec(): Promise<AudioCodec | null>;
    /**
     * The codec of the track's packets.
     * @deprecated Use {@link InputAudioTrack.getCodec} instead.
     */
    get codec(): AudioCodec | null;
    hasOnlyKeyPackets(): Promise<boolean>;
    /** Returns the number of audio channels in the track. */
    getNumberOfChannels(): Promise<number>;
    /**
     * The number of audio channels in the track.
     * @deprecated Use {@link InputAudioTrack.getNumberOfChannels} instead.
     */
    get numberOfChannels(): number;
    /** Returns the track's audio sample rate in hertz. */
    getSampleRate(): Promise<number>;
    /**
     * The track's audio sample rate in hertz.
     * @deprecated Use {@link InputAudioTrack.getSampleRate} instead.
     */
    get sampleRate(): number;
    /**
     * Returns the [decoder configuration](https://www.w3.org/TR/webcodecs/#audio-decoder-config) for decoding the
     * track's packets using an [`AudioDecoder`](https://developer.mozilla.org/en-US/docs/Web/API/AudioDecoder). Returns
     * null if the track's codec is unknown.
     */
    getDecoderConfig(): Promise<AudioDecoderConfig | null>;
    getCodecParameterString(): Promise<string | null>;
    canDecode(): Promise<boolean>;
    determinePacketType(packet: EncodedPacket): Promise<PacketType | null>;
}
/**
 * Defines a query for input tracks. Can be used to query tracks tersely and expressively, which is especially useful
 * for media inputs with many tracks, such as HLS manifests.
 *
 * @group Input files & tracks
 * @public
 */
export type InputTrackQuery<T extends InputTrack> = {
    /**
     * A filter predicate function called for every track. Returning or resolving to `false` excludes the track from
     * the result.
     */
    filter?: (track: T) => MaybePromise<boolean>;
    /**
     * A function called for every track, used to define a track ordering. Tracks are ordered in ascending order using
     * the value returned by this function. When the function returns an array of numbers `arr`, tracks will be sorted
     * by `arr[0]` unless they have the same value, in which case they will be sorted by `arr[1]`, and so on. This
     * allows you to construct a list of ordering criteria, sorted by importance.
     *
     * To help construct complex ordering criteria, the {@link asc}, {@link desc}, and {@link prefer} helper functions
     * can be used.
     */
    sortBy?: (track: T) => MaybePromise<number | number[]>;
};
/**
 * Helper function for use in {@link InputTrackQuery.sortBy}, used to describe sorting tracks by a numeric property in
 * ascending order. `null` and `undefined` are accepted too and are last in the order (sorted to the end).
 *
 * @group Input files & tracks
 * @public
 */
export declare const asc: (value: number | null | undefined) => number;
/**
 * Helper function for use in {@link InputTrackQuery.sortBy}, used to describe sorting tracks by a numeric property in
 * descending order. `null` and `undefined` are accepted too and are last in the order (sorted to the end).
 *
 * @group Input files & tracks
 * @public
 */
export declare const desc: (value: number | null | undefined) => number;
/**
 * Helper function for use in {@link InputTrackQuery.sortBy}, used to sort tracks by boolean properties. `true` is
 * sorted to the start, `false` to the end. Useful for expressing soft preferences (e.g., "I'd prefer 1080p, but other
 * resolutions are fine too") as opposed to {@link InputTrackQuery.filter} which expresses hard requirements for
 * tracks.
 *
 * @group Input files & tracks
 * @public
 */
export declare const prefer: (value: boolean) => number;
export declare const toValidatedInputTrackQuery: <T extends InputTrack>(query: InputTrackQuery<T>) => InputTrackQuery<T>;
export declare const mergeInputTrackQueries: <T extends InputTrack>(queryA: InputTrackQuery<T> | undefined, queryB: InputTrackQuery<T> | undefined) => InputTrackQuery<T>;
export declare const queryInputTracks: <T extends InputTrack>(tracks: T[], query?: InputTrackQuery<T>) => Promise<T[]>;
//# sourceMappingURL=input-track.d.ts.map