/*!
 * 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 { EventEmitter, MaybePromise, Rotation } from './misc.js';
import { MetadataTags, TrackDisposition } from './metadata.js';
import { OutputFormat } from './output-format.js';
import { AudioSource, MediaSource, SubtitleSource, VideoSource } from './media-source.js';
import { PathedTarget, Target, TargetRequest } from './target.js';
/**
 * List of all track types.
 * @group Miscellaneous
 * @public
 */
export declare const ALL_TRACK_TYPES: readonly ["video", "audio", "subtitle"];
/**
 * Union type of all track types.
 * @group Miscellaneous
 * @public
 */
export type TrackType = typeof ALL_TRACK_TYPES[number];
/**
 * Represents a track added to an {@link Output}.
 * @group Output files
 * @public
 */
export declare abstract class OutputTrack {
    /** The {@link Output} this track belongs to. */
    readonly output: Output;
    /** The type of this track. */
    readonly type: TrackType;
    /** The media source providing data for this track. */
    readonly source: MediaSource;
    /** The metadata associated with this track. */
    readonly metadata: BaseTrackMetadata;
    /** Returns true if and only if this track is a video track. */
    isVideoTrack(): this is OutputVideoTrack;
    /** Returns true if and only if this track is an audio track. */
    isAudioTrack(): this is OutputAudioTrack;
    /** Returns true if and only if this track is a subtitle track. */
    isSubtitleTrack(): this is OutputSubtitleTrack;
    /**
     * Returns true if and only if this track can be paired with the given other track. Pairability can be set using
     * the {@link BaseTrackMetadata.group} option.
     */
    canBePairedWith(other: OutputTrack): boolean;
}
/**
 * An {@link OutputTrack} providing video data, created using {@link Output.addVideoTrack}.
 * @group Output files
 * @public
 */
export declare class OutputVideoTrack extends OutputTrack {
    readonly type: 'video';
    readonly source: VideoSource;
    readonly metadata: VideoTrackMetadata;
}
/**
 * An {@link OutputTrack} providing audio data, created using {@link Output.addAudioTrack}.
 * @group Output files
 * @public
 */
export declare class OutputAudioTrack extends OutputTrack {
    readonly type: 'audio';
    readonly source: AudioSource;
    readonly metadata: AudioTrackMetadata;
}
/**
 * An {@link OutputTrack} providing subtitle data, created using {@link Output.addSubtitleTrack}.
 * @group Output files
 * @public
 */
export declare class OutputSubtitleTrack extends OutputTrack {
    readonly type: 'subtitle';
    readonly source: SubtitleSource;
    readonly metadata: SubtitleTrackMetadata;
}
/**
 * Used to define pairability between {@link OutputTrack} instances. First create the group, then assign tracks to it
 * via {@link BaseTrackMetadata.group}.
 *
 * Two tracks are considered _pairable_ if they are in the same group but have a different {@link TrackType}, or if they
 * are in different groups that are paired with each other. Groups can be paired with each other using the
 * {@link OutputTrackGroup.pairWith} method.
 *
 * @group Output files
 * @public
 */
export declare class OutputTrackGroup {
    /** Creates a new {@link OutputTrackGroup}. */
    constructor();
    /**
     * Marks this group as being pairable with another group, symmetrically. Output tracks where each track is assigned
     * to one half of a group pairing are then considered pairable.
     *
     * You cannot pair a group with itself.
     */
    pairWith(other: OutputTrackGroup): void;
}
/**
 * Base track metadata, applicable to all tracks.
 * @group Output files
 * @public
 */
export type BaseTrackMetadata = {
    /** The three-letter, ISO 639-2/T language code specifying the language of this track. */
    languageCode?: string;
    /** A user-defined name for this track, like "English" or "Director Commentary". */
    name?: string;
    /** The track's disposition, i.e. information about its intended usage. */
    disposition?: Partial<TrackDisposition>;
    /**
     * The maximum amount of encoded packets that will be added to this track. Setting this field provides the muxer
     * with an additional signal that it can use to preallocate space in the file.
     *
     * When this field is set, it is an error to provide more packets than whatever this field specifies.
     *
     * Predicting the maximum packet count requires considering both the maximum duration as well as the codec.
     * - For video codecs, you can assume one packet per frame.
     * - For audio codecs, there is one packet for each "audio chunk", the duration of which depends on the codec. For
     * simplicity, you can assume each packet is roughly 10 ms or 512 samples long, whichever is shorter.
     * - For subtitles, assume each cue and each gap in the subtitles adds a packet.
     *
     * If you're not fully sure, make sure to add a buffer of around 33% to make sure you stay below the maximum.
     */
    maximumPacketCount?: number;
    /**
     * 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?: boolean;
    /**
     * Defines the group(s) this track is a part of. Group assignment determines track pairability, determining which
     * tracks can be presented together with other tracks. This is needed for configuring things like HLS master
     * playlists.
     *
     * Two groups are considered pairable if they are in the same group but are of different {@link TrackType}, or if
     * they are in two separate groups that have been paired with each other.
     *
     * If left blank, a track is automatically assigned to {@link Output.defaultTrackGroup}.
     */
    group?: OutputTrackGroup | OutputTrackGroup[];
};
/**
 * Additional metadata for video tracks.
 * @group Output files
 * @public
 */
export type VideoTrackMetadata = BaseTrackMetadata & {
    /** The angle in degrees by which the track's frames should be rotated (clockwise). */
    rotation?: Rotation;
    /**
     * The expected video frame rate in hertz. If set, all timestamps and durations of this track will be snapped to
     * this frame rate. You should avoid adding more frames than the rate allows, as this will lead to multiple frames
     * with the same timestamp.
     */
    frameRate?: number;
    /**
     * When true, this track is marked as being made only out of key frames (I-frames). It is an error to add a non-key
     * frame to this track.
     */
    hasOnlyKeyPackets?: boolean;
};
/**
 * Additional metadata for audio tracks.
 * @group Output files
 * @public
 */
export type AudioTrackMetadata = BaseTrackMetadata & {};
/**
 * Additional metadata for subtitle tracks.
 * @group Output files
 * @public
 */
export type SubtitleTrackMetadata = BaseTrackMetadata & {};
/**
 * The options for creating an Output object.
 * @group Output files
 * @public
 */
export type OutputOptions<F extends OutputFormat = OutputFormat, T extends Target = Target> = {
    /** The format of the output file. */
    format: F;
    /** The target to which the file will be written. */
    target: T | PathedTarget<T>;
    /**
     * Optional; the target to which the track initialization data will be written. Most formats do not make use of
     * this, but some do, such as {@link CmafOutputFormat}.
     *
     * When this is a function, it will only be called if an init target is needed.
     */
    initTarget?: T | (() => MaybePromise<T>);
    /**
     * Optional; a callback to be called at the end of {@link Output.finalize}. Can be used to run logic once the
     * output has completed. If a promise is returned, it will be awaited internally by {@link Output.finalize}.
     */
    onFinalize?: () => MaybePromise<unknown>;
};
/**
 * Describes the events that an {@link Output} emits, with each key being an event name and its value being the
 * event data.
 *
 * @group Output files
 * @public
 */
export type OutputEvents = {
    /** Emitted whenever a {@link Target} is obtained by the output. Useful to track writes. */
    target: {
        /** The target that was obtained. */
        target: Target;
        /** The request that led to the target being obtained, or `null` if the output is not pathed. */
        request: TargetRequest | null;
        /** Whether the target is the root file of the media. */
        isRoot: boolean;
    };
};
/**
 * Main class orchestrating the creation of new media files.
 * @group Output files
 * @public
 */
export declare class Output<F extends OutputFormat = OutputFormat, T extends Target = Target> extends EventEmitter<OutputEvents> {
    /** The format of the output file. */
    readonly format: F;
    /** The current state of the output. */
    state: 'pending' | 'started' | 'canceled' | 'finalizing' | 'finalized';
    /**
     * The {@link OutputTrackGroup} that all tracks are assigned to by default unless otherwise specified by
     * {@link BaseTrackMetadata.group}.
     */
    readonly defaultTrackGroup: OutputTrackGroup;
    /**
     * The target to which the root file will be written. Throws when using {@link PathedTarget} with an async callback;
     * prefer the `'target'` event for those cases.
     */
    get target(): T;
    /**
     * Creates a new instance of {@link Output} which can then be used to create a new media file according to the
     * specified {@link OutputOptions}.
     */
    constructor(options: OutputOptions<F, T>);
    /** Adds a video track to the output with the given source. Can only be called before the output is started. */
    addVideoTrack(source: VideoSource, metadata?: VideoTrackMetadata): OutputVideoTrack;
    /** Adds an audio track to the output with the given source. Can only be called before the output is started. */
    addAudioTrack(source: AudioSource, metadata?: AudioTrackMetadata): OutputAudioTrack;
    /** Adds a subtitle track to the output with the given source. Can only be called before the output is started. */
    addSubtitleTrack(source: SubtitleSource, metadata?: SubtitleTrackMetadata): OutputSubtitleTrack;
    /**
     * Sets descriptive metadata tags about the media file, such as title, author, date, or cover art. When called
     * multiple times, only the metadata from the last call will be used.
     *
     * Can only be called before the output is started.
     */
    setMetadataTags(tags: MetadataTags): void;
    /**
     * Starts the creation of the output file. This method should be called after all tracks have been added. Only after
     * the output has started can media samples be added to the tracks.
     *
     * @returns A promise that resolves when the output has successfully started and is ready to receive media samples.
     */
    start(): Promise<void>;
    /**
     * Resolves with the full MIME type of the output file, including track codecs.
     *
     * The returned promise will resolve only once the precise codec strings of all tracks are known.
     */
    getMimeType(): Promise<string>;
    /**
     * Cancels the creation of the output file, releasing internal resources like encoders and preventing further
     * samples from being added.
     *
     * @returns A promise that resolves once all internal resources have been released.
     */
    cancel(): Promise<void>;
    /**
     * Finalizes the output file. This method must be called after all media samples across all tracks have been added.
     * Once the Promise returned by this method completes, the output file is ready.
     */
    finalize(): Promise<void>;
}
//# sourceMappingURL=output.d.ts.map