import * as discord_js from 'discord.js';
import { Client, User, UserResolvable, GuildVoiceChannelResolvable, VoiceChannel, StageChannel, Guild, VoiceState, VoiceBasedChannel, GuildResolvable, Snowflake } from 'discord.js';
import Eris from 'eris';
import Oceanic from 'oceanic.js';
import { ListenerSignature, DefaultListener, EventEmitter, Collection, Queue, QueueStrategy } from '@discord-player/utils';
import { Readable, Duplex } from 'stream';
import * as _discord_player_equalizer from '@discord-player/equalizer';
import { SeekEvent, EqualizerBand, BiquadFilters, PCMFilters, CommonResamplerFilterPreset, ResampleParameters, CompressorParameters, ReverbParameters, SeekerParameters, FiltersChain } from '@discord-player/equalizer';
export { AF_NIGHTCORE_RATE, AF_VAPORWAVE_RATE, BASS_EQ_BANDS, FilterType as BiquadFilterType, BiquadFilters, FiltersChain, AudioFilters as PCMAudioFilters, PCMFilters, Q_BUTTERWORTH, VolumeTransformer } from '@discord-player/equalizer';
import { AudioResource, StreamType, AudioPlayerError, VoiceConnection, AudioPlayer, AudioPlayerStatus } from 'discord-voip';
export { AudioPlayer, CreateAudioPlayerOptions, JoinConfig, JoinVoiceChannelOptions, StreamType, createAudioPlayer, createAudioResource, getVoiceConnection, getVoiceConnections, joinVoiceChannel } from 'discord-voip';
import { RequestOptions } from 'http';
import { Transform, Writable, TransformCallback } from 'node:stream';
import { FFmpegLib } from '@discord-player/ffmpeg';
export * from '@discord-player/ffmpeg';

/**
 * Allows Eris clients to be used with discord-player. When this method is called, discord-player creates a proxy object that intercepts certain methods and properties to make it compatible with discord-player.
 * @param client The Eris client to be used.
 * @returns The Eris client with discord-player compatibility.
 */
declare function createErisCompat(client: Eris.Client): Client;

/**
 * Allows Oceanic.js clients to be used with discord-player. When this method is called, discord-player creates a proxy object that intercepts certain methods and properties to make it compatible with discord-player.
 * @param client The Oceanic.js client to be used.
 * @returns The Oceanic.js client with discord-player compatibility.
 */
declare function createOceanicCompat(client: Oceanic.Client): Client;

declare function isErisProxy(client: any): boolean;
declare function isOceanicProxy(client: any): boolean;

declare class PlayerEventsEmitter<L extends ListenerSignature<L> = DefaultListener> extends EventEmitter<L> {
    #private;
    requiredEvents: Array<keyof L>;
    constructor(requiredEvents?: Array<keyof L>);
    on<K extends keyof L>(name: K, listener: L[K]): this;
    once<K extends keyof L>(name: K, listener: L[K]): this;
    addListener<K extends keyof L>(name: K, listener: L[K]): this;
    off<K extends keyof L>(name: K, listener: L[K]): this;
    removeListener<K extends keyof L>(name: K, listener: L[K]): this;
    removeAllListeners<K extends keyof L>(name?: K): this;
    emit<K extends keyof L>(name: K, ...args: Parameters<L[K]>): boolean;
    get hasDebugger(): boolean;
}

type FiltersName = keyof QueueFilters;
/**
 * Represents FFmpeg filters
 */
interface QueueFilters {
    bassboost_low?: boolean;
    bassboost?: boolean;
    bassboost_high?: boolean;
    '8D'?: boolean;
    vaporwave?: boolean;
    nightcore?: boolean;
    phaser?: boolean;
    tremolo?: boolean;
    vibrato?: boolean;
    reverse?: boolean;
    treble?: boolean;
    normalizer?: boolean;
    normalizer2?: boolean;
    surrounding?: boolean;
    pulsator?: boolean;
    subboost?: boolean;
    karaoke?: boolean;
    flanger?: boolean;
    gate?: boolean;
    haas?: boolean;
    mcompand?: boolean;
    mono?: boolean;
    mstlr?: boolean;
    mstrr?: boolean;
    compressor?: boolean;
    expander?: boolean;
    softlimiter?: boolean;
    chorus?: boolean;
    chorus2d?: boolean;
    chorus3d?: boolean;
    fadein?: boolean;
    dim?: boolean;
    earrape?: boolean;
    lofi?: boolean;
    silenceremove?: boolean;
}
declare class AudioFilters {
    constructor();
    static filters: Record<FiltersName, string>;
    static get<K extends FiltersName>(name: K): Record<keyof QueueFilters, string>[K];
    static has<K extends FiltersName>(name: K): boolean;
    static [Symbol.iterator](): IterableIterator<{
        name: FiltersName;
        value: string;
    }>;
    static get names(): (keyof QueueFilters)[];
    static get length(): number;
    static toString(): string;
    /**
     * Create ffmpeg args from the specified filters name
     * @param filter The filter name
     * @returns
     */
    static create<K extends FiltersName>(filters?: (K | string)[]): string;
    /**
     * Defines audio filter
     * @param filterName The name of the filter
     * @param value The ffmpeg args
     */
    static define(filterName: string, value: string): void;
    /**
     * Defines multiple audio filters
     * @param filtersArray Array of filters containing the filter name and ffmpeg args
     */
    static defineBulk(filtersArray: {
        name: string;
        value: string;
    }[]): void;
}

/**
 * The search query type
 * This can be one of:
 * - AUTO
 * - YOUTUBE
 * - YOUTUBE_PLAYLIST
 * - SOUNDCLOUD_TRACK
 * - SOUNDCLOUD_PLAYLIST
 * - SOUNDCLOUD
 * - SPOTIFY_SONG
 * - SPOTIFY_ALBUM
 * - SPOTIFY_PLAYLIST
 * - SPOTIFY_SEARCH
 * - FACEBOOK
 * - VIMEO
 * - ARBITRARY
 * - REVERBNATION
 * - YOUTUBE_SEARCH
 * - YOUTUBE_VIDEO
 * - SOUNDCLOUD_SEARCH
 * - APPLE_MUSIC_SONG
 * - APPLE_MUSIC_ALBUM
 * - APPLE_MUSIC_PLAYLIST
 * - APPLE_MUSIC_SEARCH
 * - FILE
 * - AUTO_SEARCH
 * - DISCORD_PLAYER_BLOB
 * @typedef {string} QueryType
 */
declare const QueryType: {
    readonly AUTO: "auto";
    readonly YOUTUBE: "youtube";
    readonly YOUTUBE_PLAYLIST: "youtubePlaylist";
    readonly SOUNDCLOUD_TRACK: "soundcloudTrack";
    readonly SOUNDCLOUD_PLAYLIST: "soundcloudPlaylist";
    readonly SOUNDCLOUD: "soundcloud";
    readonly SPOTIFY_SONG: "spotifySong";
    readonly SPOTIFY_ALBUM: "spotifyAlbum";
    readonly SPOTIFY_PLAYLIST: "spotifyPlaylist";
    readonly SPOTIFY_SEARCH: "spotifySearch";
    readonly FACEBOOK: "facebook";
    readonly VIMEO: "vimeo";
    readonly ARBITRARY: "arbitrary";
    readonly REVERBNATION: "reverbnation";
    readonly YOUTUBE_SEARCH: "youtubeSearch";
    readonly YOUTUBE_VIDEO: "youtubeVideo";
    readonly SOUNDCLOUD_SEARCH: "soundcloudSearch";
    readonly APPLE_MUSIC_SONG: "appleMusicSong";
    readonly APPLE_MUSIC_ALBUM: "appleMusicAlbum";
    readonly APPLE_MUSIC_PLAYLIST: "appleMusicPlaylist";
    readonly APPLE_MUSIC_SEARCH: "appleMusicSearch";
    readonly FILE: "file";
    readonly AUTO_SEARCH: "autoSearch";
    readonly DISCORD_PLAYER_BLOB: "discordPlayerBlob";
};
type QueryType = (typeof QueryType)[keyof typeof QueryType];
type SearchQueryType = keyof typeof QueryType | QueryType;
interface ResolvedQuery {
    type: (typeof QueryType)[keyof typeof QueryType];
    query: string;
}
declare class QueryResolver {
    /**
     * Query resolver
     */
    private constructor();
    static get regex(): {
        spotifyAlbumRegex: RegExp;
        spotifyPlaylistRegex: RegExp;
        spotifySongRegex: RegExp;
        vimeoRegex: RegExp;
        reverbnationRegex: RegExp;
        attachmentRegex: RegExp;
        appleMusicAlbumRegex: RegExp;
        appleMusicPlaylistRegex: RegExp;
        appleMusicSongRegex: RegExp;
        soundcloudTrackRegex: RegExp;
        soundcloudPlaylistRegex: RegExp;
        youtubePlaylistRegex: RegExp;
        discordPlayerBlobRegex: RegExp;
    };
    /**
     * Pre-resolve redirect urls
     */
    static preResolve(query: string, maxDepth?: number): Promise<string>;
    /**
     * Resolves the given search query
     * @param {string} query The query
     */
    static resolve(query: string, fallbackSearchEngine?: (typeof QueryType)[keyof typeof QueryType]): ResolvedQuery;
    /**
     * Parses vimeo id from url
     * @param {string} query The query
     * @returns {string}
     */
    static getVimeoID(query: string): string | null | undefined;
    static validateId(q: string): boolean;
    static validateURL(q: string): boolean;
}

interface SearchResultData {
    query: string;
    queryType?: SearchQueryType | QueryExtractorSearch | null;
    extractor?: BaseExtractor | null;
    playlist?: Playlist | null;
    tracks?: Track[];
    requestedBy?: User | null;
}
interface PlayOptions {
    /**
     * If this play was triggered for filters update
     */
    filtersUpdate?: boolean;
    /**
     * FFmpeg args passed to encoder
     */
    encoderArgs?: string[];
    /**
     * Time to seek to before playing
     */
    seek?: number;
    /**
     * If it should start playing the provided track immediately
     */
    immediate?: boolean;
}
type QueryExtractorSearch = `ext:${string}`;
interface SearchOptions {
    /**
     * The user who requested this search
     */
    requestedBy?: UserResolvable;
    /**
     * The query search engine, can be extractor name to target specific one (custom)
     */
    searchEngine?: SearchQueryType | QueryExtractorSearch;
    /**
     * List of the extractors to block
     */
    blockExtractors?: string[];
    /**
     * If it should ignore query cache lookup
     */
    ignoreCache?: boolean;
    /**
     * Request options to be passed with the http request
     */
    requestOptions?: RequestOptions;
    /**
     * Fallback search engine to use
     */
    fallbackSearchEngine?: (typeof QueryType)[keyof typeof QueryType];
}
interface PlayerSearchResult {
    playlist: Playlist | null;
    tracks: Track[];
}
declare class SearchResult {
    player: Player;
    private _data;
    constructor(player: Player, _data: SearchResultData);
    setQueryType(type: SearchQueryType | QueryExtractorSearch): this;
    setRequestedBy(user: User): this;
    setExtractor(extractor: BaseExtractor): this;
    setTracks(tracks: Track[]): this;
    setQuery(query: string): this;
    setPlaylist(playlist: Playlist): this;
    /**
     * The search query
     */
    get query(): string;
    /**
     * The search query type
     */
    get queryType(): SearchQueryType | `ext:${string}`;
    /**
     * The extractor
     */
    get extractor(): BaseExtractor<object> | null;
    /**
     * Playlist result
     */
    get playlist(): Playlist | null | undefined;
    /**
     * Tracks result
     */
    get tracks(): Track<unknown>[];
    /**
     * Requested by
     */
    get requestedBy(): User | null;
    /**
     * Re-execute this search
     */
    execute(): Promise<SearchResult>;
    /**
     * If this search result is empty
     */
    isEmpty(): boolean;
    /**
     * If this search result has playlist
     */
    hasPlaylist(): boolean;
    /**
     * If this search result has tracks
     */
    hasTracks(): boolean;
    /**
     * JSON representation of this search
     */
    toJSON(): {
        query: string;
        queryType: SearchQueryType | `ext:${string}`;
        playlist: PlaylistJSON | null;
        tracks: TrackJSON[];
        extractor: string | null;
        requestedBy: {} | null;
    };
}

declare enum SerializedType {
    Track = "track",
    Playlist = "playlist"
}
type Encodable = SerializedTrack | SerializedPlaylist;
declare function serialize(data: Track | Playlist | any): any;
declare function deserialize(player: Player, data: Encodable): Track<unknown> | Playlist;
declare function encode(data: Encodable): string;
declare function decode(data: string): any;
declare function tryIntoThumbnailString(data: any): any;

type TrackResolvable = Track | string | number;
type WithMetadata<T extends object, M> = T & {
    metadata: M;
    requestMetadata(): Promise<M>;
};
type SerializedTrack = ReturnType<Track['serialize']>;
/**
 * The track source:
 * - soundcloud
 * - youtube
 * - spotify
 * - apple_music
 * - arbitrary
 */
type TrackSource = 'soundcloud' | 'youtube' | 'spotify' | 'apple_music' | 'arbitrary';
interface RawTrackData {
    /**
     * The title
     */
    title: string;
    /**
     * The description
     */
    description: string;
    /**
     * The author
     */
    author: string;
    /**
     * The url
     */
    url: string;
    /**
     * The thumbnail
     */
    thumbnail: string;
    /**
     * The duration
     */
    duration: string;
    /**
     * The duration in ms
     */
    views: number;
    /**
     * The user who requested this track
     */
    requestedBy?: User | null;
    /**
     * The playlist
     */
    playlist?: Playlist;
    /**
     * The source
     */
    source?: TrackSource;
    /**
     * The engine
     */
    engine?: any;
    /**
     * If this track is live
     */
    live?: boolean;
    /**
     * The raw data
     */
    raw?: any;
    /**
     * The query type
     */
    queryType?: SearchQueryType;
    /**
     * The serialized title
     */
    cleanTitle?: string;
}
interface TrackJSON {
    /**
     * The track id
     */
    id: string;
    /**
     * The track title
     */
    title: string;
    /**
     * The track description
     */
    description: string;
    /**
     * The track author
     */
    author: string;
    /**
     * The track url
     */
    url: string;
    /**
     * The track thumbnail
     */
    thumbnail: string;
    /**
     * The track duration
     */
    duration: string;
    /**
     * The track duration in ms
     */
    durationMS: number;
    /**
     * The track views
     */
    views: number;
    /**
     * The user id who requested this track
     */
    requestedBy: string;
    /**
     * The playlist info (if any)
     */
    playlist?: PlaylistJSON;
}
declare class Track<T = unknown> {
    #private;
    readonly player: Player;
    title: string;
    description: string;
    author: string;
    url: string;
    thumbnail: string;
    duration: string;
    views: number;
    requestedBy: User | null;
    playlist?: Playlist;
    queryType: SearchQueryType | null | undefined;
    raw: any;
    extractor: BaseExtractor | null;
    readonly id: string;
    private __metadata;
    private __reqMetadataFn;
    cleanTitle: string;
    live: boolean;
    bridgedExtractor: BaseExtractor | null;
    bridgedTrack: Track | null;
    /**
     * Track constructor
     * @param player The player that instantiated this Track
     * @param data Track data
     */
    constructor(player: Player, data: Partial<WithMetadata<RawTrackData, T>>);
    /**
     * Whether this track can be seeked
     */
    get seekable(): boolean;
    /**
     * Set the onSeek event
     * @param fn The onSeek event
     */
    handleSeek(fn: (event: SeekEvent) => Awaited<void>): void;
    /**
     * Request seek
     * @param event The seek event
     */
    seek(event: SeekEvent): Promise<void>;
    /**
     * Sets audio resource for this track. This is not useful outside of the library.
     * @param resource Audio resource
     */
    setResource(resource: AudioResource<Track> | null): void;
    /**
     * Gets audio resource for this track
     */
    get resource(): AudioResource<Track<unknown>> | null;
    /**
     * Whether this track has an audio resource
     */
    get hasResource(): boolean;
    /**
     * Request metadata for this track
     */
    requestMetadata(): Promise<T | null>;
    /**
     * Set metadata for this track
     */
    setMetadata(m: T | null): void;
    /**
     * Metadata of this track
     */
    get metadata(): T | null;
    /**
     * If this track has metadata
     */
    get hasMetadata(): boolean;
    /**
     * The queue in which this track is located
     */
    get queue(): GuildQueue;
    /**
     * The track duration in millisecond
     */
    get durationMS(): number;
    /**
     * Discord hyperlink representation of this track
     */
    toHyperlink(): string;
    /**
     * Returns source of this track
     */
    get source(): any;
    /**
     * String representation of this track
     */
    toString(): string;
    /**
     * Raw JSON representation of this track
     */
    toJSON(hidePlaylist?: boolean): TrackJSON;
    /**
     * Serialized track data that can be reconstructed
     */
    serialize(): {
        title: string;
        description: string;
        author: string;
        url: string;
        thumbnail: any;
        duration: string;
        views: number;
        requested_by: {} | null;
        source: any;
        live: boolean;
        query_type: SearchQueryType | null | undefined;
        extractor: string | null;
        metadata: T | null;
        $type: SerializedType;
        $encoder_version: string;
    };
    /**
     * Construct a track from serialized data
     * @param player Player instance
     * @param data Serialized data
     */
    static fromSerialized(player: Player, data: ReturnType<Track['serialize']>): Track<unknown>;
    /**
     * Get belonging queues of this track
     */
    getBelongingQueues(): Collection<string, GuildQueue<unknown>>;
    /**
     * Play this track to the given voice channel. If queue exists and another track is being played, this track will be added to the queue.
     * @param channel Voice channel on which this track shall be played
     * @param options Node initialization options
     */
    play<T = unknown>(channel: GuildVoiceChannelResolvable, options?: PlayerNodeInitializerOptions<T>): Promise<PlayerNodeInitializationResult<T>>;
}

interface CreateStreamOps {
    type?: StreamType;
    data: Track;
    disableVolume?: boolean;
    disableEqualizer?: boolean;
    disableBiquad?: boolean;
    disableCompressor?: boolean;
    disableResampler?: boolean;
    disableReverb?: boolean;
    disableSeeker?: boolean;
    eq?: EqualizerBand[];
    biquadFilter?: BiquadFilters;
    disableFilters?: boolean;
    defaultFilters?: PCMFilters[];
    volume?: number;
    sampleRate?: number;
    sampleRateFilters?: CommonResamplerFilterPreset;
    skipFFmpeg?: boolean;
    compressor?: {
        threshold: number;
        ratio: number;
        attack: number;
        release: number;
        makeupGain: number;
        kneeWidth: number;
    };
    reverb?: {
        roomSize: number;
        damping: number;
        wetLevel: number;
        dryLevel: number;
    };
    seeker?: {
        seekTarget: number | null;
        totalDuration: number;
    };
}
interface VoiceEvents {
    error: (error: AudioPlayerError) => any;
    debug: (message: string) => any;
    start: (resource: AudioResource<Track>) => any;
    finish: (resource: AudioResource<Track>) => any;
    dsp: (filters: PCMFilters[]) => any;
    eqBands: (filters: EqualizerBand[]) => any;
    sampleRate: (filters: ResampleParameters) => any;
    biquad: (filters: BiquadFilters) => any;
    compressor: (filters: CompressorParameters) => any;
    reverb: (filters: ReverbParameters) => any;
    seeker: (filters: SeekerParameters) => any;
    volume: (volume: number) => any;
    destroyed: () => any;
}
declare class StreamDispatcher extends EventEmitter<VoiceEvents> {
    #private;
    queue: GuildQueue;
    readonly connectionTimeout: number;
    voiceConnection: VoiceConnection;
    audioPlayer: AudioPlayer;
    channel: VoiceChannel | StageChannel;
    audioResource?: AudioResource<Track> | null;
    dsp: FiltersChain;
    /**
     * Creates new connection object
     * @param {VoiceConnection} connection The connection
     * @param {VoiceChannel|StageChannel} channel The connected channel
     * @private
     */
    constructor(connection: VoiceConnection, channel: VoiceChannel | StageChannel, queue: GuildQueue, connectionTimeout?: number, audioPlayer?: AudioPlayer);
    /**
     * Check if the player has been paused manually
     */
    get paused(): boolean;
    set paused(val: boolean);
    /**
     * Whether or not the player is currently paused automatically or manually.
     */
    isPaused(): boolean;
    /**
     * Whether or not the player is currently buffering
     */
    isBuffering(): boolean;
    /**
     * Whether or not the player is currently playing
     */
    isPlaying(): boolean;
    /**
     * Whether or not the player is currently idle
     */
    isIdle(): boolean;
    /**
     * Whether or not the voice connection has been destroyed
     */
    isDestroyed(): boolean;
    /**
     * Whether or not the voice connection has been destroyed
     */
    isDisconnected(): boolean;
    /**
     * Whether or not the voice connection is ready to play
     */
    isReady(): boolean;
    /**
     * Whether or not the voice connection is signalling
     */
    isSignalling(): boolean;
    /**
     * Whether or not the voice connection is connecting
     */
    isConnecting(): boolean;
    /**
     * Creates stream
     * @param {Readable} src The stream source
     * @param {object} [ops] Options
     * @returns {AudioResource}
     */
    createStream(src: Readable, ops: CreateStreamOps): Promise<AudioResource<Track<unknown>>>;
    get resampler(): _discord_player_equalizer.PCMResampler | null;
    get filters(): _discord_player_equalizer.AudioFilter | null;
    get biquad(): _discord_player_equalizer.BiquadStream | null;
    get equalizer(): _discord_player_equalizer.EqualizerStream | null;
    get compressor(): _discord_player_equalizer.CompressorTransformer | null;
    get reverb(): _discord_player_equalizer.ReverbTransformer | null;
    get seeker(): _discord_player_equalizer.PCMSeekerTransformer | null;
    /**
     * The player status
     * @type {AudioPlayerStatus}
     */
    get status(): AudioPlayerStatus;
    /**
     * Disconnects from voice
     * @returns {void}
     */
    disconnect(): void;
    /**
     * Destroys this dispatcher
     */
    destroy(): void;
    /**
     * Stops the player
     * @returns {void}
     */
    end(): void;
    /**
     * Pauses the stream playback
     * @param {boolean} [interpolateSilence=false] If true, the player will play 5 packets of silence after pausing to prevent audio glitches.
     * @returns {boolean}
     */
    pause(interpolateSilence?: boolean): boolean;
    /**
     * Resumes the stream playback
     * @returns {boolean}
     */
    resume(): boolean;
    /**
     * Play stream
     * @param {AudioResource<Track>} [resource=this.audioResource] The audio resource to play
     * @param {boolean} [opus=false] Whether or not to use opus
     * @returns {Promise<StreamDispatcher>}
     */
    playStream(resource?: AudioResource<Track>): Promise<this | undefined>;
    /**
     * Sets playback volume
     * @param {number} value The volume amount
     * @returns {boolean}
     */
    setVolume(value: number): boolean;
    /**
     * The current volume
     * @type {number}
     */
    get volume(): number;
    /**
     * The playback time
     * @type {number}
     */
    get streamTime(): number;
}

declare class GuildQueueHistory<Meta = any> {
    queue: GuildQueue<Meta>;
    tracks: Queue<Track<unknown>>;
    constructor(queue: GuildQueue<Meta>);
    /**
     * Current track in the queue
     */
    get currentTrack(): Track<unknown> | null;
    /**
     * Next track in the queue
     */
    get nextTrack(): Track<unknown> | null;
    /**
     * Previous track in the queue
     */
    get previousTrack(): Track<unknown> | null;
    /**
     * If history is disabled
     */
    get disabled(): boolean;
    /**
     * Gets the size of the queue
     */
    get size(): number;
    getSize(): number;
    /**
     * If history is empty
     */
    isEmpty(): boolean;
    /**
     * Add track to track history
     * @param track The track to add
     */
    push(track: Track | Track[]): boolean;
    /**
     * Clear history
     */
    clear(): void;
    /**
     * Play the next track in the queue
     */
    next(): Promise<void>;
    /**
     * Play the previous track in the queue
     */
    previous(preserveCurrent?: boolean): Promise<void>;
    /**
     * Alias to [GuildQueueHistory].previous()
     */
    back(preserveCurrent?: boolean): Promise<void>;
    /**
     * Resize history store
     */
    resize(): void;
}

interface AsyncQueueAcquisitionOptions {
    /**
     * AbortSignal to cancel this entry
     */
    signal?: AbortSignal;
}
type AsyncQueueExceptionHandler = (exception: Error) => void;
declare class AsyncQueue {
    /**
     * The queued entries
     */
    entries: Array<AsyncQueueEntry>;
    exceptionHandler?: AsyncQueueExceptionHandler;
    /**
     * Clear entries queue
     * @param consume Whether or not to consume all entries before clearing
     */
    clear(consume?: boolean): void;
    /**
     * The total number of entries in this queue. Returns `0` if no entries are available.
     */
    get size(): number;
    /**
     * Acquire an entry.
     *
     * @example // lock the queue
     * const entry = asyncQueue.acquire();
     * // wait until previous task is completed
     * await entry.getTask();
     * // do something expensive
     * await performSomethingExpensive();
     * // make sure to release the lock once done
     * asyncQueue.release();
     *
     */
    acquire(options?: AsyncQueueAcquisitionOptions): AsyncQueueEntry;
    /**
     * Release the current acquisition and move to next entry.
     */
    release(): void;
    /**
     * Cancel all entries
     */
    cancelAll(): void;
    /**
     * Remove the given entry from the queue
     * @param entry The entry to remove
     */
    removeEntry(entry: AsyncQueueEntry): boolean;
}
declare class AsyncQueueEntry {
    queue: AsyncQueue;
    options?: AsyncQueueAcquisitionOptions | undefined;
    readonly id: string;
    private readonly promise;
    signal: AbortSignal | null;
    onAbort: (() => void) | null;
    private resolve;
    private reject;
    constructor(queue: AsyncQueue, options?: AsyncQueueAcquisitionOptions | undefined);
    setAbortSignal(signal: AbortSignal): void;
    consume(): void;
    release(): void;
    cancel(): void;
    cleanup(): void;
    getTask(): Promise<void>;
}

declare const FFMPEG_SRATE_REGEX: RegExp;
interface PlayerProgressbarOptions {
    /**
     * If it should render time codes
     */
    timecodes?: boolean;
    /**
     * If it should create progress bar for the whole queue
     */
    length?: number;
    /**
     * The bar length
     */
    leftChar?: string;
    /**
     * The elapsed time track
     */
    rightChar?: string;
    /**
     * The remaining time track
     */
    separator?: string;
    /**
     * The separation between timestamp and line
     */
    indicator?: string;
    /**
     * The indicator
     */
    queue?: boolean;
}
interface ResourcePlayOptions {
    queue?: boolean;
    seek?: number;
    transitionMode?: boolean;
}
interface SkipOptions {
    reason: TrackSkipReason;
    description: string;
}
interface PlayerTimestamp {
    current: {
        label: string;
        value: number;
    };
    total: {
        label: string;
        value: number;
    };
    progress: number;
}
interface StreamConfig {
    dispatcherConfig: CreateStreamOps;
    playerConfig: ResourcePlayOptions;
}
declare class GuildQueuePlayerNode<Meta = any> {
    #private;
    queue: GuildQueue<Meta>;
    tasksQueue: AsyncQueue;
    constructor(queue: GuildQueue<Meta>);
    /**
     * If the player is currently in idle mode
     */
    isIdle(): boolean;
    /**
     * If the player is currently buffering the track
     */
    isBuffering(): boolean;
    /**
     * If the player is currently playing a track
     */
    isPlaying(): boolean;
    /**
     * If the player is currently paused
     */
    isPaused(): boolean;
    /**
     * Reset progress history
     */
    resetProgress(): void;
    /**
     * Set player progress
     */
    setProgress(progress: number): void;
    /**
     * The stream time for current session
     */
    get streamTime(): number;
    /**
     * Current playback duration with history included
     */
    get playbackTime(): number;
    /**
     * Get duration multiplier
     */
    getDurationMultiplier(): number;
    /**
     * Estimated progress of the player
     */
    get estimatedPlaybackTime(): number;
    /**
     * Estimated total duration of the player
     */
    get estimatedDuration(): number;
    /**
     * Total duration of the current audio track
     */
    get totalDuration(): number;
    /**
     * Get stream progress
     * @param ignoreFilters Ignore filters
     */
    getTimestamp(ignoreFilters?: boolean): PlayerTimestamp | null;
    /**
     * Create progress bar for current progress
     * @param options Progress bar options
     */
    createProgressBar(options?: PlayerProgressbarOptions): string | null;
    /**
     * Seek the player
     * @param duration The duration to seek to
     */
    seek(duration: number): Promise<boolean>;
    /**
     * Current volume
     */
    get volume(): number;
    /**
     * Set volume
     * @param vol Volume amount to set
     */
    setVolume(vol: number): boolean;
    /**
     * Set bit rate
     * @param rate The bit rate to set
     */
    setBitrate(rate: number | 'auto'): void;
    /**
     * Set paused state
     * @param state The state
     */
    setPaused(state: boolean): boolean;
    /**
     * Pause the playback
     */
    pause(): boolean;
    /**
     * Resume the playback
     */
    resume(): boolean;
    /**
     * Skip current track
     */
    skip(options?: SkipOptions): boolean;
    /**
     * Remove the given track from queue
     * @param track The track to remove
     * @param emitEvent Whether or not to emit the event @defaultValue true
     */
    remove(track: TrackResolvable, emitEvent?: boolean): Track<unknown> | null;
    /**
     * Jump to specific track on the queue
     * @param track The track to jump to without removing other tracks
     */
    jump(track: TrackResolvable): boolean;
    /**
     * Get track position
     * @param track The track
     */
    getTrackPosition(track: TrackResolvable): number;
    /**
     * Skip to the given track, removing others on the way
     * @param track The track to skip to
     */
    skipTo(track: TrackResolvable): boolean;
    /**
     * Insert a track on the given position in queue
     * @param track The track to insert
     * @param index The position to insert to, defaults to 0.
     */
    insert(track: Track, index?: number): void;
    /**
     * Moves a track in the queue
     * @param from The track to move
     * @param to The position to move to
     */
    move(from: TrackResolvable, to: number): void;
    /**
     * Copy a track in the queue
     * @param from The track to clone
     * @param to The position to clone at
     */
    copy(from: TrackResolvable, to: number): void;
    /**
     * Swap two tracks in the queue
     * @param first The first track to swap
     * @param second The second track to swap
     */
    swap(first: TrackResolvable, second: TrackResolvable): void;
    /**
     * Stop the playback
     * @param force Whether or not to forcefully stop the playback
     */
    stop(force?: boolean): boolean;
    /**
     * Request the source to seek
     * @param data The seek parameters
     */
    requestSeek(data: SeekEvent): Promise<boolean | void>;
    /**
     * Play the given track
     * @param res The track to play
     * @param options Options for playing the track
     */
    play(res?: Track | null, options?: ResourcePlayOptions): Promise<void>;
}

interface FFmpegStreamOptions {
    fmt?: string;
    encoderArgs?: string[];
    seek?: number;
    skip?: boolean;
    cookies?: string;
    requestOptions?: RequestOptions;
}
declare function FFMPEG_ARGS_STRING(stream: string, fmt?: string, cookies?: string, requestOptions?: RequestOptions): string[];
declare function FFMPEG_ARGS_PIPED(fmt?: string): string[];
/**
 * Creates FFmpeg stream
 * @param stream The source stream
 * @param options FFmpeg stream options
 */
declare function createFFmpegStream(stream: Readable | Duplex | string, options?: FFmpegStreamOptions): Readable;

type Filters = keyof typeof AudioFilters.filters;
type EQPreset = {
    Flat: EqualizerBand[];
    Classical: EqualizerBand[];
    Club: EqualizerBand[];
    Dance: EqualizerBand[];
    FullBass: EqualizerBand[];
    FullBassTreble: EqualizerBand[];
    FullTreble: EqualizerBand[];
    Headphones: EqualizerBand[];
    LargeHall: EqualizerBand[];
    Live: EqualizerBand[];
    Party: EqualizerBand[];
    Pop: EqualizerBand[];
    Reggae: EqualizerBand[];
    Rock: EqualizerBand[];
    Ska: EqualizerBand[];
    Soft: EqualizerBand[];
    SoftRock: EqualizerBand[];
    Techno: EqualizerBand[];
};
declare const EqualizerConfigurationPreset: Readonly<EQPreset>;
declare class FFmpegFilterer<Meta = any> {
    #private;
    af: GuildQueueAudioFilters<Meta>;
    constructor(af: GuildQueueAudioFilters<Meta>);
    /**
     * Indicates whether ffmpeg may be skipped
     */
    get skippable(): boolean;
    /**
     * Set input args for FFmpeg
     */
    setInputArgs(args: string[]): void;
    /**
     * Get input args
     */
    get inputArgs(): string[];
    /**
     * Get encoder args
     */
    get encoderArgs(): string[];
    /**
     * Get final ffmpeg args
     */
    get args(): string[];
    /**
     * Create ffmpeg stream
     * @param source The stream source
     * @param options The stream options
     */
    createStream(source: string | Readable, options: FFmpegStreamOptions): Readable;
    /**
     * Set ffmpeg filters
     * @param filters The filters
     */
    setFilters(filters: Filters[] | Record<Filters, boolean> | string[] | boolean): Promise<boolean>;
    /**
     * Currently active ffmpeg filters
     */
    get filters(): Filters[];
    set filters(filters: Filters[]);
    /**
     * Toggle given ffmpeg filter(s)
     * @param filters The filter(s)
     */
    toggle(filters: Filters[] | Filters): Promise<boolean>;
    /**
     * Set default filters
     * @param ff Filters list
     */
    setDefaults(ff: Filters[]): void;
    /**
     * Get list of enabled filters
     */
    getFiltersEnabled(): (keyof QueueFilters)[];
    /**
     * Get list of disabled filters
     */
    getFiltersDisabled(): (keyof QueueFilters)[];
    /**
     * Check if the given filter is enabled
     * @param filter The filter
     */
    isEnabled<T extends Filters>(filter: T): boolean;
    /**
     * Check if the given filter is disabled
     * @param filter The filter
     */
    isDisabled<T extends Filters>(filter: T): boolean;
    /**
     * Check if the given filter is a valid filter
     * @param filter The filter to test
     */
    isValidFilter(filter: string): filter is FiltersName;
    /**
     * Convert current filters to array
     */
    toArray(): string[];
    /**
     * Convert current filters to JSON object
     */
    toJSON(): Record<keyof QueueFilters, string>;
    /**
     * String representation of current filters
     */
    toString(): string;
}
interface GuildQueueAFiltersCache {
    equalizer: EqualizerBand[];
    biquad: BiquadFilters | null;
    filters: PCMFilters[];
    volume: number;
    sampleRate: number;
    sampleRateFilter: StreamConfig['dispatcherConfig']['sampleRateFilters'] | null;
    compressor: StreamConfig['dispatcherConfig']['compressor'] | null;
    reverb: StreamConfig['dispatcherConfig']['reverb'] | null;
}
declare class GuildQueueAudioFilters<Meta = any> {
    queue: GuildQueue<Meta>;
    graph: AFilterGraph<Meta>;
    ffmpeg: FFmpegFilterer<Meta>;
    equalizerPresets: Readonly<EQPreset>;
    _lastFiltersCache: GuildQueueAFiltersCache;
    constructor(queue: GuildQueue<Meta>);
    /**
     * Volume transformer
     */
    get volume(): _discord_player_equalizer.VolumeTransformer | null;
    /**
     * 15 Band Equalizer
     */
    get equalizer(): _discord_player_equalizer.EqualizerStream | null;
    /**
     * Digital biquad filters
     */
    get biquad(): _discord_player_equalizer.BiquadStream | null;
    /**
     * DSP filters
     */
    get filters(): _discord_player_equalizer.AudioFilter | null;
    /**
     * Audio resampler
     */
    get resampler(): _discord_player_equalizer.PCMResampler | null;
    /**
     * Compressor transformer
     */
    get compressor(): _discord_player_equalizer.CompressorTransformer | null;
    /**
     * Reverb transformer
     */
    get reverb(): _discord_player_equalizer.ReverbTransformer | null;
    /**
     * PCM Seeker transformer
     */
    get seeker(): _discord_player_equalizer.PCMSeekerTransformer | null;
    /**
     * Replay current track in transition mode
     * @param seek The duration to seek to
     */
    triggerReplay(seek?: number): Promise<boolean>;
}
declare class AFilterGraph<Meta = any> {
    af: GuildQueueAudioFilters<Meta>;
    constructor(af: GuildQueueAudioFilters<Meta>);
    get ffmpeg(): (keyof QueueFilters)[];
    get equalizer(): EqualizerBand[];
    get biquad(): "SinglePoleLowPassApprox" | "SinglePoleLowPass" | "LowPass" | "HighPass" | "BandPass" | "Notch" | "AllPass" | "LowShelf" | "HighShelf" | "PeakingEQ" | null;
    get filters(): ("8D" | "Tremolo" | "Vibrato")[];
    get volume(): _discord_player_equalizer.VolumeTransformer | null;
    get resampler(): _discord_player_equalizer.PCMResampler | null;
    dump(): FilterGraph;
}
interface FilterGraph {
    ffmpeg: Filters[];
    equalizer: EqualizerBand[];
    biquad: Exclude<BiquadFilters, number> | null;
    filters: PCMFilters[];
    volume: number;
    sampleRate: number;
}

interface GuildQueueStatisticsMetadata {
    latency: {
        eventLoop: number;
        voiceConnection: number;
    };
    status: {
        buffering: boolean;
        playing: boolean;
        paused: boolean;
        idle: boolean;
    };
    tracksCount: number;
    historySize: number;
    extractors: number;
    listeners: number;
    memoryUsage: NodeJS.MemoryUsage;
    versions: {
        node: string;
        player: string;
    };
}
declare class GuildQueueStatistics<Meta = any> {
    queue: GuildQueue<Meta>;
    constructor(queue: GuildQueue<Meta>);
    /**
     * Generate statistics of this queue
     */
    generate(): GuildQueueStatisticsMetadata;
}

type RequestEntity = () => Promise<Response>;
declare class SequentialBucket {
    limit: number;
    remaining: number;
    resetAfter: number;
    queue: AsyncQueue;
    MAX_RETRIES: number;
    /**
     * Checks if the bucket is rate limited.
     */
    isRateLimited(): boolean;
    /**
     * Enqueues a request.
     * @param req The request function to enqueue
     */
    enqueue(req: RequestEntity): Promise<Response>;
    private _request;
    private _patchHeaders;
}

interface LrcSearchParams {
    /**
     * The query to search for. Either this or trackName is required.
     */
    q?: string;
    /**
     * The track name to search for. Either this or query is required.
     */
    trackName?: string;
    /**
     * The artist name
     */
    artistName?: string;
    /**
     * The album name
     */
    albumName?: string;
}
interface LrcGetParams extends Required<Omit<LrcSearchParams, 'query'>> {
    /**
     * The duration of the track
     */
    duration: number;
}
interface LrcSearchResult {
    /**
     * The track id
     */
    id: number;
    /**
     * The track name
     */
    name: string;
    /**
     * The artist name
     */
    trackName: string;
    /**
     * The album name
     */
    artistName: string;
    /**
     * The album name
     */
    albumName: string;
    /**
     * The duration of the track
     */
    duration: number;
    /**
     * The release date of the track
     */
    instrumental: boolean;
    /**
     * The release date of the track
     */
    plainLyrics: string;
    /**
     * The release date of the track
     */
    syncedLyrics?: string;
}
type LrcGetResult = Omit<LrcSearchResult, 'name'>;
declare class LrcLib {
    readonly player: Player;
    /**
     * The API URL
     */
    api: string;
    /**
     * The request timeout. Default is 15 seconds.
     */
    timeout: number;
    /**
     * The request bucket
     */
    bucket: SequentialBucket;
    /**
     * Creates a new LrcLib instance
     * @param {Player} player The player instance
     */
    constructor(player: Player);
    /**
     * Sets the request timeout
     * @param {number} timeout The timeout in milliseconds
     */
    setRequestTimeout(timeout: number): void;
    /**
     * Sets the retry limit. Default is 5.
     * @param {number} limit The retry limit
     */
    setRetryLimit(limit: number): void;
    /**
     * Gets lyrics
     * @param params The get params
     */
    get(params: LrcGetParams): Promise<LrcSearchResult>;
    /**
     * Gets lyrics by ID
     * @param id The lyrics ID
     */
    getById(id: `${number}` | number): Promise<LrcSearchResult>;
    /**
     * Gets cached lyrics
     * @param params The get params
     */
    getCached(params: LrcGetParams): Promise<LrcSearchResult>;
    /**
     * Searches for lyrics
     * @param params The search params
     */
    search(params: LrcSearchParams): Promise<LrcSearchResult[]>;
    /**
     * Requests the API
     * @param path The path
     * @param options The request options
     */
    request<T>(path: string, options?: RequestInit): Promise<T>;
}

type LyricsData = Map<number, string>;
type Unsubscribe = () => void;
type LyricsCallback = (lyrics: string, timestamp: number) => unknown;
type LyricsAt = {
    timestamp: number;
    line: string;
};
declare class SyncedLyricsProvider {
    #private;
    readonly queue: GuildQueue;
    readonly raw?: LrcSearchResult | LrcGetResult | undefined;
    interval: number;
    readonly lyrics: LyricsData;
    constructor(queue: GuildQueue, raw?: LrcSearchResult | LrcGetResult | undefined);
    isSubscribed(): boolean;
    load(lyrics: string): void;
    /**
     * Returns the lyrics at a specific time or at the closest time (±2 seconds)
     * @param time The time in milliseconds
     */
    at(time: number): LyricsAt | null;
    /**
     * Callback for the lyrics change.
     * @param callback The callback function
     */
    onChange(callback: LyricsCallback): void;
    /**
     * Callback to detect when the provider is unsubscribed.
     * @param callback The callback function
     */
    onUnsubscribe(callback: Unsubscribe): void;
    /**
     * Unsubscribes from the queue.
     */
    unsubscribe(): void;
    /**
     * Subscribes to the queue to monitor the current time.
     * @returns The unsubscribe function
     */
    subscribe(): Unsubscribe;
    /**
     * Pauses the lyrics provider.
     */
    pause(): boolean;
    /**
     * Resumes the lyrics provider.
     */
    resume(): boolean;
}

interface GuildNodeInit<Meta = any> {
    guild: Guild;
    queueStrategy: QueueStrategy;
    equalizer: EqualizerBand[] | boolean;
    volume: number | boolean;
    biquad: BiquadFilters | boolean | undefined;
    resampler: number | boolean;
    filterer: PCMFilters[] | boolean;
    ffmpegFilters: FiltersName[];
    disableHistory: boolean;
    onBeforeCreateStream?: OnBeforeCreateStreamHandler;
    onAfterCreateStream?: OnAfterCreateStreamHandler;
    onStreamExtracted?: OnStreamExtractedHandler;
    repeatMode?: QueueRepeatMode;
    leaveOnEmpty: boolean;
    leaveOnEmptyCooldown: number;
    leaveOnEnd: boolean;
    leaveOnEndCooldown: number;
    leaveOnStop: boolean;
    leaveOnStopCooldown: number;
    connectionTimeout: number;
    selfDeaf?: boolean;
    metadata?: Meta | null;
    bufferingTimeout: number;
    noEmitInsert: boolean;
    maxSize?: number;
    maxHistorySize?: number;
    preferBridgedMetadata: boolean;
    pauseOnEmpty?: boolean;
    disableVolume: boolean;
    disableEqualizer: boolean;
    disableFilterer: boolean;
    disableBiquad: boolean;
    disableResampler: boolean;
    disableCompressor: boolean;
    disableReverb: boolean;
    disableSeeker: boolean;
    disableFallbackStream: boolean;
    enableStreamInterceptor: boolean;
    verifyFallbackStream: boolean;
}
interface VoiceConnectConfig {
    deaf?: boolean;
    timeout?: number;
    group?: string;
    audioPlayer?: AudioPlayer;
    daveEncryption?: boolean;
    decryptionFailureTolerance?: number;
}
interface PostProcessedResult {
    stream: Readable;
    type: StreamType;
}
type OnBeforeCreateStreamHandler = (track: Track, queryType: SearchQueryType, queue: GuildQueue) => Promise<Readable | null>;
type OnStreamExtractedHandler = (stream: Readable | ExtractorStreamable | string, track: Track, queue: GuildQueue) => Promise<Readable | ExtractorStreamable | string>;
type OnAfterCreateStreamHandler<T = unknown> = (stream: Readable, queue: GuildQueue, track: Track<T>) => Promise<PostProcessedResult | null>;
type PlayerTriggeredReason = 'filters' | 'normal';
declare const GuildQueueEvent: {
    /**
     * Emitted when audio track is added to the queue
     */
    readonly AudioTrackAdd: "audioTrackAdd";
    /**
     * Emitted when audio tracks were added to the queue
     */
    readonly AudioTracksAdd: "audioTracksAdd";
    /**
     * Emitted when audio track is removed from the queue
     */
    readonly AudioTrackRemove: "audioTrackRemove";
    /**
     * Emitted when audio tracks are removed from the queue
     */
    readonly AudioTracksRemove: "audioTracksRemove";
    /**
     * Emitted when a connection is created
     */
    readonly Connection: "connection";
    /**
     * Emitted when a voice connection is destroyed
     */
    readonly ConnectionDestroyed: "connectionDestroyed";
    /**
     * Emitted when the bot is disconnected from the channel
     */
    readonly Disconnect: "disconnect";
    /**
     * Emitted when the queue sends a debug info
     */
    readonly Debug: "debug";
    /**
     * Emitted when the queue encounters error
     */
    readonly Error: "error";
    /**
     * Emitted when the voice channel is empty
     */
    readonly EmptyChannel: "emptyChannel";
    /**
     * Emitted when the queue is empty
     */
    readonly EmptyQueue: "emptyQueue";
    /**
     * Emitted when the audio player starts streaming audio track
     */
    readonly PlayerStart: "playerStart";
    /**
     * Emitted when the audio player errors while streaming audio track
     */
    readonly PlayerError: "playerError";
    /**
     * Emitted when the audio player finishes streaming audio track
     */
    readonly PlayerFinish: "playerFinish";
    /**
     * Emitted when the audio player skips current track
     */
    readonly PlayerSkip: "playerSkip";
    /**
     * Emitted when the audio player is triggered
     */
    readonly PlayerTrigger: "playerTrigger";
    /**
     * Emitted when the voice state is updated. Consuming this event may disable default voice state update handler if `Player.isVoiceStateHandlerLocked()` returns `false`.
     */
    readonly VoiceStateUpdate: "voiceStateUpdate";
    /**
     * Emitted when volume is updated
     */
    readonly VolumeChange: "volumeChange";
    /**
     * Emitted when player is paused
     */
    readonly PlayerPause: "playerPause";
    /**
     * Emitted when player is resumed
     */
    readonly PlayerResume: "playerResume";
    /**
     * Biquad Filters Update
     */
    readonly BiquadFiltersUpdate: "biquadFiltersUpdate";
    /**
     * Equalizer Update
     */
    readonly EqualizerUpdate: "equalizerUpdate";
    /**
     * DSP update
     */
    readonly DSPUpdate: "dspUpdate";
    /**
     * Audio Filters Update
     */
    readonly AudioFiltersUpdate: "audioFiltersUpdate";
    /**
     * Audio player will play next track
     */
    readonly WillPlayTrack: "willPlayTrack";
    /**
     * Emitted when a voice channel is repopulated
     */
    readonly ChannelPopulate: "channelPopulate";
    /**
     * Emitted when a queue is successfully created
     */
    readonly QueueCreate: "queueCreate";
    /**
     * Emitted when a queue is deleted
     */
    readonly QueueDelete: "queueDelete";
    /**
     * Emitted when a queue is trying to add similar track for autoplay
     */
    readonly WillAutoPlay: "willAutoPlay";
    /**
     * Emitted when sample rate is updated
     */
    readonly SampleRateUpdate: "sampleRateUpdate";
    /**
     * Emitted when a named sample rate filter is updated
     */
    readonly SampleRateFilterUpdate: "sampleRateFilterUpdate";
    /**
     * Emitted when reverb filter is updated
     */
    readonly ReverbUpdate: "reverbUpdate";
    /**
     * Emitted when compressor filter is updated
     */
    readonly CompressorUpdate: "compressorUpdate";
    /**
     * Emitted when seek is performed
     */
    readonly PlayerSeek: "playerSeek";
};
type GuildQueueEvent = (typeof GuildQueueEvent)[keyof typeof GuildQueueEvent];
declare enum TrackSkipReason {
    NoStream = "ERR_NO_STREAM",
    Manual = "MANUAL",
    SEEK_OVER_THRESHOLD = "SEEK_OVER_THRESHOLD",
    Jump = "JUMPED_TO_ANOTHER_TRACK",
    SkipTo = "SKIP_TO_ANOTHER_TRACK",
    HistoryNext = "HISTORY_NEXT_TRACK"
}
interface GuildQueueEvents<Meta = any> {
    /**
     * Emitted when audio track is added to the queue
     * @param queue The queue where this event occurred
     * @param track The track
     */
    [GuildQueueEvent.AudioTrackAdd]: (queue: GuildQueue<Meta>, track: Track) => unknown;
    /**
     * Emitted when audio tracks were added to the queue
     * @param queue The queue where this event occurred
     * @param tracks The tracks array
     */
    [GuildQueueEvent.AudioTracksAdd]: (queue: GuildQueue<Meta>, track: Track[]) => unknown;
    /**
     * Emitted when audio track is removed from the queue
     * @param queue The queue where this event occurred
     * @param track The track
     */
    [GuildQueueEvent.AudioTrackRemove]: (queue: GuildQueue<Meta>, track: Track) => unknown;
    /**
     * Emitted when audio tracks are removed from the queue
     * @param queue The queue where this event occurred
     * @param track The track
     */
    [GuildQueueEvent.AudioTracksRemove]: (queue: GuildQueue<Meta>, track: Track[]) => unknown;
    /**
     * Emitted when a connection is created
     * @param queue The queue where this event occurred
     */
    [GuildQueueEvent.Connection]: (queue: GuildQueue<Meta>) => unknown;
    /**
     * Emitted when a connection is destroyed
     * @param queue The queue where this event occurred
     */
    [GuildQueueEvent.ConnectionDestroyed]: (queue: GuildQueue<Meta>) => unknown;
    /**
     * Emitted when the bot is disconnected from the channel
     * @param queue The queue where this event occurred
     */
    [GuildQueueEvent.Disconnect]: (queue: GuildQueue<Meta>) => unknown;
    /**
     * Emitted when the queue sends a debug info
     * @param queue The queue where this event occurred
     * @param message The debug message
     */
    [GuildQueueEvent.Debug]: (queue: GuildQueue<Meta>, message: string) => unknown;
    /**
     * Emitted when the queue encounters error
     * @param queue The queue where this event occurred
     * @param error The error
     */
    [GuildQueueEvent.Error]: (queue: GuildQueue<Meta>, error: Error) => unknown;
    /**
     * Emitted when the voice channel is empty
     * @param queue The queue where this event occurred
     */
    [GuildQueueEvent.EmptyChannel]: (queue: GuildQueue<Meta>) => unknown;
    /**
     * Emitted when the queue is empty
     * @param queue The queue where this event occurred
     */
    [GuildQueueEvent.EmptyQueue]: (queue: GuildQueue<Meta>) => unknown;
    /**
     * Emitted when the audio player starts streaming audio track
     * @param queue The queue where this event occurred
     * @param track The track that is being streamed
     */
    [GuildQueueEvent.PlayerStart]: (queue: GuildQueue<Meta>, track: Track) => unknown;
    /**
     * Emitted when the audio player errors while streaming audio track
     * @param queue The queue where this event occurred
     * @param error The error
     * @param track The track that is being streamed
     */
    [GuildQueueEvent.PlayerError]: (queue: GuildQueue<Meta>, error: Error, track: Track) => unknown;
    /**
     * Emitted when the audio player finishes streaming audio track
     * @param queue The queue where this event occurred
     * @param track The track that was being streamed
     */
    [GuildQueueEvent.PlayerFinish]: (queue: GuildQueue<Meta>, track: Track) => unknown;
    /**
     * Emitted when the audio player skips current track
     * @param queue The queue where this event occurred
     * @param track The track that was skipped
     * @param reason The reason for skipping
     * @param description The description for skipping
     */
    [GuildQueueEvent.PlayerSkip]: (queue: GuildQueue<Meta>, track: Track, reason: TrackSkipReason, description: string) => unknown;
    /**
     * Emitted when the audio player is triggered
     * @param queue The queue where this event occurred
     * @param track The track which was played in this event
     */
    [GuildQueueEvent.PlayerTrigger]: (queue: GuildQueue<Meta>, track: Track, reason: PlayerTriggeredReason) => unknown;
    /**
     * Emitted when the voice state is updated. Consuming this event may disable default voice state update handler if `Player.isVoiceStateHandlerLocked()` returns `false`.
     * @param queue The queue where this event occurred
     * @param oldState The old voice state
     * @param newState The new voice state
     */
    [GuildQueueEvent.VoiceStateUpdate]: (queue: GuildQueue<Meta>, oldState: VoiceState, newState: VoiceState) => unknown;
    /**
     * Emitted when audio player is paused
     * @param queue The queue where this event occurred
     */
    [GuildQueueEvent.PlayerPause]: (queue: GuildQueue<Meta>) => unknown;
    /**
     * Emitted when audio player is resumed
     * @param queue The queue where this event occurred
     */
    [GuildQueueEvent.PlayerResume]: (queue: GuildQueue<Meta>) => unknown;
    /**
     * Emitted when audio player's volume is changed
     * @param queue The queue where this event occurred
     * @param oldVolume The old volume
     * @param newVolume The updated volume
     */
    [GuildQueueEvent.VolumeChange]: (queue: GuildQueue<Meta>, oldVolume: number, newVolume: number) => unknown;
    /**
     * Emitted when equalizer config is updated
     * @param queue The queue where this event occurred
     * @param oldFilters Old filters
     * @param newFilters New filters
     */
    [GuildQueueEvent.EqualizerUpdate]: (queue: GuildQueue<Meta>, oldFilters: EqualizerBand[], newFilters: EqualizerBand[]) => unknown;
    /**
     * Emitted when biquad filters is updated
     * @param queue The queue where this event occurred
     * @param oldFilters Old filters
     * @param newFilters New filters
     */
    [GuildQueueEvent.BiquadFiltersUpdate]: (queue: GuildQueue<Meta>, oldFilters: BiquadFilters | null, newFilters: BiquadFilters | null) => unknown;
    /**
     * Emitted when dsp filters is updated
     * @param queue The queue where this event occurred
     * @param oldFilters Old filters
     * @param newFilters New filters
     */
    [GuildQueueEvent.DSPUpdate]: (queue: GuildQueue<Meta>, oldFilters: PCMFilters[], newFilters: PCMFilters[]) => unknown;
    /**
     * Emitted when ffmpeg audio filters is updated
     * @param queue The queue where this event occurred
     * @param oldFilters Old filters
     * @param newFilters New filters
     */
    [GuildQueueEvent.AudioFiltersUpdate]: (queue: GuildQueue<Meta>, oldFilters: FiltersName[], newFilters: FiltersName[]) => unknown;
    /**
     * Emitted before streaming an audio track. This event can be used to modify stream config before playing a track.
     * Listening to this event will pause the execution of audio player until `done()` is invoked.
     * @param queue The queue where this event occurred
     * @param track The track that will be streamed
     * @param config Configurations for streaming
     * @param done Done callback
     */
    [GuildQueueEvent.WillPlayTrack]: (queue: GuildQueue<Meta>, track: Track<unknown>, config: StreamConfig, done: () => void) => unknown;
    /**
     * Emitted when a voice channel is populated
     * @param queue The queue where this event occurred
     */
    [GuildQueueEvent.ChannelPopulate]: (queue: GuildQueue<Meta>) => unknown;
    /**
     * Emitted when a queue is successfully created
     * @param queue The queue where this event occurred
     */
    [GuildQueueEvent.QueueCreate]: (queue: GuildQueue<Meta>) => unknown;
    /**
     * Emitted when a queue is successfully deleted
     * @param queue The queue where this event occurred
     */
    [GuildQueueEvent.QueueDelete]: (queue: GuildQueue<Meta>) => unknown;
    /**
     * Emitted when a queue is trying to add similar track for autoplay
     * @param queue The queue where this event occurred
     * @param tracks The similar tracks that were found
     * @param done Done callback
     */
    [GuildQueueEvent.WillAutoPlay]: (queue: GuildQueue<Meta>, tracks: Track[], done: (track: Track | null) => void) => unknown;
    /**
     * Emitted when sample rate is updated
     * @param queue The queue where this event occurred
     * @param oldRate The old sample rate
     * @param newRate The new sample rate
     */
    [GuildQueueEvent.SampleRateUpdate]: (queue: GuildQueue<Meta>, oldRate: number, newRate: number) => unknown;
    /**
     * Emitted when a named sample rate filter is updated
     * @param queue The queue where this event occurred
     * @param oldRate The old sample rate filter
     * @param newRate The new sample rate filter
     */
    [GuildQueueEvent.SampleRateFilterUpdate]: (queue: GuildQueue<Meta>, oldFilter: CommonResamplerFilterPreset | null, newFilter: CommonResamplerFilterPreset | null) => unknown;
    /**
     * Emitted when reverb filter is updated
     * @param queue The queue where this event occurred
     * @param oldFilter The old reverb filter
     * @param newFilter The new reverb filter
     */
    [GuildQueueEvent.ReverbUpdate]: (queue: GuildQueue<Meta>, oldFilter: ReverbParameters | null, newFilter: ReverbParameters | null) => unknown;
    /**
     * Emitted when compressor filter is updated
     * @param queue The queue where this event occurred
     * @param oldFilter The old compressor filter
     * @param newFilter The new compressor filter
     */
    [GuildQueueEvent.CompressorUpdate]: (queue: GuildQueue<Meta>, oldFilter: CompressorParameters | null, newFilter: CompressorParameters | null) => unknown;
    /**
     * Emitted when seek is performed
     * @param queue The queue where this event occurred
     * @param position The seek position
     */
    [GuildQueueEvent.PlayerSeek]: (queue: GuildQueue<Meta>, parameters: SeekerParameters) => unknown;
}
/**
 * The queue repeat mode. This can be one of:
 * - OFF
 * - TRACK
 * - QUEUE
 * - AUTOPLAY
 */
declare const QueueRepeatMode: {
    /**
     * Disable repeat mode.
     */
    readonly OFF: 0;
    /**
     * Repeat the current track.
     */
    readonly TRACK: 1;
    /**
     * Repeat the entire queue.
     */
    readonly QUEUE: 2;
    /**
     * When last track ends, play similar tracks in the future if queue is empty.
     */
    readonly AUTOPLAY: 3;
};
type QueueRepeatMode = (typeof QueueRepeatMode)[keyof typeof QueueRepeatMode];
declare class GuildQueue<Meta = any> {
    #private;
    player: Player;
    options: GuildNodeInit<Meta>;
    private __current;
    tracks: Queue<Track>;
    history: GuildQueueHistory<Meta>;
    dispatcher: StreamDispatcher | null;
    node: GuildQueuePlayerNode<Meta>;
    filters: GuildQueueAudioFilters<Meta>;
    onBeforeCreateStream: OnBeforeCreateStreamHandler;
    onAfterCreateStream: OnAfterCreateStreamHandler;
    onStreamExtracted: OnStreamExtractedHandler;
    repeatMode: QueueRepeatMode;
    timeouts: Collection<string, NodeJS.Timeout>;
    stats: GuildQueueStatistics<Meta>;
    tasksQueue: AsyncQueue;
    syncedLyricsProvider: SyncedLyricsProvider;
    constructor(player: Player, options: GuildNodeInit<Meta>);
    /**
     * Whether this queue can intercept streams
     */
    canIntercept(): boolean;
    /**
     * Estimated duration of this queue in ms
     */
    get estimatedDuration(): number;
    /**
     * Formatted duration of this queue
     */
    get durationFormatted(): string;
    /**
     * The sync lyrics provider for this queue.
     * @example const lyrics = await player.lyrics.search({ q: 'Alan Walker Faded' });
     * const syncedLyrics = queue.syncedLyrics(lyrics[0]);
     * console.log(syncedLyrics.at(10_000));
     * // subscribe to lyrics change
     * const unsubscribe = syncedLyrics.onChange((lyrics, timestamp) => {
     *    console.log(lyrics, timestamp);
     * });
     * // unsubscribe from lyrics change
     * unsubscribe(); // or
     * syncedLyrics.unsubscribe();
     */
    syncedLyrics(lyrics: LrcGetResult | LrcSearchResult): SyncedLyricsProvider;
    /**
     * Write a debug message to this queue
     * @param m The message to write
     */
    debug(m: string): void;
    /**
     * The metadata of this queue
     */
    get metadata(): Meta;
    set metadata(m: Meta);
    /**
     * Set metadata for this queue
     * @param m Metadata to set
     */
    setMetadata(m: Meta): void;
    /**
     * Indicates current track of this queue
     */
    get currentTrack(): Track<unknown> | null;
    /**
     * Indicates if this queue was deleted previously
     */
    get deleted(): boolean;
    /**
     * The voice channel of this queue
     */
    get channel(): VoiceBasedChannel | null;
    set channel(c: VoiceBasedChannel | null);
    /**
     * The voice connection of this queue
     */
    get connection(): VoiceConnection | null;
    /**
     * The guild this queue belongs to
     */
    get guild(): Guild;
    /**
     * The id of this queue
     */
    get id(): string;
    /**
     * Set transition mode for this queue
     * @param state The state to set
     */
    setTransitioning(state: boolean): void;
    /**
     * if this queue is currently under transition mode
     */
    isTransitioning(): boolean;
    /**
     * Set repeat mode for this queue
     * @param mode The repeat mode to apply
     */
    setRepeatMode(mode: QueueRepeatMode): void;
    /**
     * Max size of this queue
     */
    get maxSize(): number;
    /**
     * Max size of this queue
     */
    getMaxSize(): number;
    /**
     * Gets the size of the queue
     */
    get size(): number;
    /**
     * The size of this queue
     */
    getSize(): number;
    /**
     * Max history size of this queue
     */
    get maxHistorySize(): number;
    /**
     * Max history size of this queue
     */
    getMaxHistorySize(): number;
    /**
     * Set max history size for this queue
     * @param size The size to set
     */
    setMaxHistorySize(size: number): void;
    /**
     * Set max size for this queue
     * @param size The size to set
     */
    setMaxSize(size: number): void;
    /**
     * Clear this queue
     */
    clear(): void;
    /**
     * Check if this queue has no tracks left in it
     */
    isEmpty(): boolean;
    /**
     * Check if this queue is full
     */
    isFull(): boolean;
    /**
     * Get queue capacity
     */
    getCapacity(): number;
    /**
     * Check if this queue currently holds active audio resource
     */
    isPlaying(): boolean;
    /**
     * Add track to the queue. This will emit `audioTracksAdd` when multiple tracks are added, otherwise `audioTrackAdd`.
     * @param track Track or playlist or array of tracks to add
     */
    addTrack(track: Track | Track[] | Playlist): void;
    /**
     * Remove a track from queue
     * @param track The track to remove
     */
    removeTrack(track: TrackResolvable): Track<unknown> | null;
    /**
     * Prepends a track or track resolvable to the queue
     * @param track The track resolvable to insert
     * @param index The index to insert the track at (defaults to 0). If > 0, the inserted track will be placed before the track at the given index.
     */
    prepend(track: Track | Queue<Track> | Array<Track>, index?: number): void;
    /**
     * Appends a track or track resolvable to the queue
     * @param track The track resolvable to insert
     * @param index The index to insert the track at (defaults to 0). If > 0, the inserted track will be placed after the track at the given index.
     */
    append(track: Track | Queue<Track> | Array<Track>, index?: number): void;
    /**
     * Inserts the track to the given index
     * @param track The track to insert
     * @param index The index to insert the track at (defaults to 0)
     */
    insertTrack(track: Track, index?: number): void;
    /**
     * Moves a track in the queue
     * @param from The track to move
     * @param to The position to move to
     */
    moveTrack(track: TrackResolvable, index?: number): void;
    /**
     * Copy a track in the queue
     * @param from The track to clone
     * @param to The position to clone at
     */
    copyTrack(track: TrackResolvable, index?: number): void;
    /**
     * Swap two tracks in the queue
     * @param src The first track to swap
     * @param dest The second track to swap
     */
    swapTracks(src: TrackResolvable, dest: TrackResolvable): void;
    /**
     * Create stream dispatcher from the given connection
     * @param connection The connection to use
     */
    createDispatcher(connection: VoiceConnection, options?: Pick<VoiceConnectConfig, 'audioPlayer' | 'timeout'>): void;
    /**
     * Connect to a voice channel
     * @param channelResolvable The voice channel to connect to
     * @param options Join config
     */
    connect(channelResolvable: GuildVoiceChannelResolvable, options?: VoiceConnectConfig): Promise<this>;
    /**
     * Enable shuffle mode for this queue
     * @param dynamic Whether to shuffle the queue dynamically. Defaults to `true`.
     * Dynamic shuffling will shuffle the queue when the current track ends, without mutating the queue.
     * If set to `false`, the queue will be shuffled immediately in-place, which cannot be undone.
     */
    enableShuffle(dynamic?: boolean): boolean;
    /**
     * Disable shuffle mode for this queue.
     */
    disableShuffle(): boolean;
    /**
     * Toggle shuffle mode for this queue.
     * @param dynamic Whether to shuffle the queue dynamically. Defaults to `true`.
     * @returns Whether shuffle is enabled or disabled.
     */
    toggleShuffle(dynamic?: boolean): boolean;
    /**
     * Whether shuffle mode is enabled for this queue.
     */
    get isShuffling(): boolean;
    /**
     * The voice connection latency of this queue
     */
    get ping(): number;
    /**
     * Delete this queue
     */
    delete(): void;
    /**
     * Revives this queue
     * @returns
     */
    revive(): void;
    /**
     * Set self deaf
     * @param mode On/Off state
     * @param reason Reason
     */
    setSelfDeaf(mode?: boolean, reason?: string): Promise<discord_js.GuildMember>;
    /**
     * Set self mute
     * @param mode On/Off state
     * @param reason Reason
     */
    setSelfMute(mode?: boolean, reason?: string): Promise<discord_js.GuildMember>;
    /**
     * Play a track in this queue
     * @param track The track to be played
     * @param options Player node initialization options
     */
    play(track: TrackLike, options?: PlayerNodeInitializerOptions<Meta>): Promise<PlayerNodeInitializationResult<Meta>>;
    /**
     * Emit an event on this queue
     * @param event The event to emit
     * @param args The args for the event
     */
    emit<K extends keyof GuildQueueEvents<Meta>>(event: K, ...args: Parameters<GuildQueueEvents<Meta>[K]>): boolean;
    get hasDebugger(): boolean;
}

interface GuildNodeCreateOptions<T = any> {
    strategy?: QueueStrategy;
    volume?: number;
    equalizer?: EqualizerBand[];
    a_filter?: PCMFilters[];
    biquad?: BiquadFilters;
    resampler?: number;
    disableHistory?: boolean;
    onBeforeCreateStream?: OnBeforeCreateStreamHandler;
    onAfterCreateStream?: OnAfterCreateStreamHandler;
    onStreamExtracted?: OnStreamExtractedHandler;
    repeatMode?: QueueRepeatMode;
    pauseOnEmpty?: boolean;
    leaveOnEmpty?: boolean;
    leaveOnEmptyCooldown?: number;
    leaveOnEnd?: boolean;
    leaveOnEndCooldown?: number;
    leaveOnStop?: boolean;
    leaveOnStopCooldown?: number;
    metadata?: T | null;
    selfDeaf?: boolean;
    connectionTimeout?: number;
    defaultFFmpegFilters?: FiltersName[];
    bufferingTimeout?: number;
    noEmitInsert?: boolean;
    maxSize?: number;
    maxHistorySize?: number;
    preferBridgedMetadata?: boolean;
    disableVolume?: boolean;
    disableEqualizer?: boolean;
    disableFilterer?: boolean;
    disableBiquad?: boolean;
    disableResampler?: boolean;
    disableCompressor?: boolean;
    disableSeeker?: boolean;
    disableReverb?: boolean;
    disableFallbackStream?: boolean;
    enableStreamInterceptor?: boolean;
    verifyFallbackStream?: boolean;
}
type NodeResolvable = GuildQueue | GuildResolvable;
declare class GuildNodeManager<Meta = any> {
    player: Player;
    cache: Collection<string, GuildQueue<any>>;
    constructor(player: Player);
    /**
     * Create guild queue if it does not exist
     * @param guild The guild which will be the owner of the queue
     * @param options Queue initializer options
     */
    create<T = Meta>(guild: GuildResolvable, options?: GuildNodeCreateOptions<T>): GuildQueue<T>;
    /**
     * Get existing queue
     * @param node Queue resolvable
     */
    get<T = Meta>(node: NodeResolvable): GuildQueue<T> | null;
    /**
     * Check if a queue exists
     * @param node Queue resolvable
     */
    has(node: NodeResolvable): boolean;
    /**
     * Delete queue
     * @param node Queue resolvable
     */
    delete(node: NodeResolvable): boolean;
    /**
     * Resolve queue
     * @param node Queue resolvable
     */
    resolve<T = Meta>(node: NodeResolvable): GuildQueue<T> | undefined;
    /**
     * Resolve queue id
     * @param node Queue resolvable
     */
    resolveId(node: NodeResolvable): string | null;
}

declare class VoiceUtils {
    player: Player;
    /**
     * Voice connection cache to store voice connections of the Player components.
     * This property is deprecated and will be removed in the future.
     * It only exists for compatibility reasons.
     * @deprecated
     */
    cache: Collection<Snowflake, StreamDispatcher>;
    /**
     * The voice utils constructor
     */
    constructor(player: Player);
    /**
     * Joins a voice channel, creating basic stream dispatch manager
     * @param {StageChannel|VoiceChannel} channel The voice channel
     * @param {object} [options] Join options
     * @returns {Promise<StreamDispatcher>}
     */
    connect(channel: VoiceChannel | StageChannel, options?: {
        deaf?: boolean;
        maxTime?: number;
        queue: GuildQueue;
        audioPlayer?: AudioPlayer;
        group?: string;
        daveEncryption?: boolean;
        decryptionFailureTolerance?: number;
    }): Promise<StreamDispatcher>;
    /**
     * Joins a voice channel
     * @param {StageChannel|VoiceChannel} [channel] The voice/stage channel to join
     * @param {object} [options] Join options
     * @returns {VoiceConnection}
     */
    join(channel: VoiceChannel | StageChannel, options?: {
        deaf?: boolean;
        maxTime?: number;
        group?: string;
        daveEncryption?: boolean;
        decryptionFailureTolerance?: number;
    }): Promise<VoiceConnection>;
    /**
     * Disconnects voice connection
     * @param {VoiceConnection} connection The voice connection
     * @returns {void}
     */
    disconnect(connection: VoiceConnection | StreamDispatcher): void;
    /**
     * Returns Discord Player voice connection
     * @param {Snowflake} guild The guild id
     * @returns {StreamDispatcher}
     */
    getConnection(guild: Snowflake, group?: string): VoiceConnection | undefined;
}

type unsafe = any;
/**
 * The receiver function that will be called when the context is provided
 */
type ContextReceiver<R> = () => R;
declare class Context<T> {
    private defaultValue?;
    private storage;
    constructor(defaultValue?: T | undefined);
    /**
     * Exit out of this context
     */
    exit(scope: ContextReceiver<void>): void;
    /**
     * Whether the context is lost
     */
    get isLost(): boolean;
    /**
     * Get the current value of the context. If the context is lost and no default value is provided, undefined will be returned.
     */
    consume(): T | undefined;
    /**
     * Run a function within the context of this provider
     */
    provide<R = unsafe>(value: T, receiver: ContextReceiver<R>): R;
}
/**
 * Create a new context. The default value is optional.
 * @param defaultValue The default value of the context
 * @example const userContext = createContext();
 *
 *  // the value to provide
 *  const user = {
 *   id: 1,
 *   name: 'John Doe'
 *  };
 *
 *  // provide the context value to the receiver
 *  context.provide(user, handler);
 *
 *  function handler() {
 *    // get the context value
 *    const { id, name } = useContext(context);
 *
 *    console.log(id, name); // 1, John Doe
 *  }
 */
declare function createContext<T = unsafe>(defaultValue?: T): Context<T>;
/**
 * Get the current value of the context. If the context is lost and no default value is provided, undefined will be returned.
 * @param context The context to get the value from
 * @example const value = useContext(context);
 */
declare function useContext<T = unsafe>(context: Context<T>): T | undefined;

/**
 * Fetch guild queue history
 * @param node guild queue node resolvable
 */
declare function useHistory<Meta = unknown>(): GuildQueueHistory<Meta> | null;
declare function useHistory<Meta = unknown>(node: NodeResolvable): GuildQueueHistory<Meta> | null;

/**
 * Fetch guild queue player node
 * @param node Guild queue node resolvable
 */
declare function usePlayer<Meta = unknown>(): GuildQueuePlayerNode<Meta> | null;
declare function usePlayer<Meta = unknown>(node: NodeResolvable): GuildQueuePlayerNode<Meta> | null;

/**
 * Fetch guild queue.
 * @param node Guild queue node resolvable. Defaults to inferred guild from context.
 */
declare function useQueue<Meta = unknown>(): GuildQueue<Meta> | null;
declare function useQueue<Meta = unknown>(node: NodeResolvable): GuildQueue<Meta> | null;

/**
 * Fetch main player instance
 */
declare function useMainPlayer(): Player;

type SetterFN$1<T, P> = (previous: P) => T;
type MetadataDispatch<T> = readonly [
    () => T,
    (metadata: T | SetterFN$1<T, T>) => void
];
/**
 * Fetch or manipulate guild queue metadata
 * @param node Guild queue node resolvable
 */
declare function useMetadata<T = unknown>(): MetadataDispatch<T>;
declare function useMetadata<T = unknown>(node: NodeResolvable): MetadataDispatch<T>;

interface TimelineDispatcherOptions {
    ignoreFilters: boolean;
    node: NodeResolvable;
}
interface GuildQueueTimeline {
    readonly timestamp: PlayerTimestamp;
    readonly volume: number;
    readonly paused: boolean;
    readonly track: Track<unknown> | null;
    pause(): boolean;
    resume(): boolean;
    setVolume(vol: number): boolean;
    setPosition(time: number): Promise<boolean>;
}
/**
 * Fetch or manipulate current track
 * @param options Options for timeline dispatcher
 */
declare function useTimeline(): GuildQueueTimeline | null;
declare function useTimeline(options: Partial<TimelineDispatcherOptions>): GuildQueueTimeline | null;

/**
 * Global onAfterCreateStream handler
 * @param handler The handler callback
 */
declare function onAfterCreateStream(handler: OnAfterCreateStreamHandler): void;

/**
 * Global onBeforeCreateStream handler
 * @param handler The handler callback
 */
declare function onBeforeCreateStream(handler: OnBeforeCreateStreamHandler): void;

/**
 * Global onStreamExtracted handler
 * @param handler The handler callback
 */
declare function onStreamExtracted(handler: OnStreamExtractedHandler): void;

type SetterFN = (previous: number) => number;
type VolumeDispatch = readonly [
    () => number,
    (volume: number | SetterFN) => boolean | undefined
];
/**
 * Fetch or manipulate player volume
 * @param node Guild queue node resolvable
 */
declare function useVolume(): VolumeDispatch;
declare function useVolume(node: NodeResolvable): VolumeDispatch;

interface ExtractorSession {
    id: string;
    attemptedExtractors: Set<string>;
    bridgeAttemptedExtractors: Set<string>;
}
interface ExtractorExecutionEvents {
    /**
     * Emitted when a extractor is registered
     * @param context The context where extractor was registered
     * @param extractor The extractor that was registered
     */
    registered: (context: ExtractorExecutionContext, extractor: BaseExtractor) => unknown;
    /**
     * Emitted when a extractor is unregistered
     * @param context The context where extractor was unregistered
     * @param extractor The extractor that was unregistered
     */
    unregistered: (context: ExtractorExecutionContext, extractor: BaseExtractor) => unknown;
    /**
     * Emitted when a extractor is activated
     * @param context The context where this event occurred
     * @param extractor The extractor which was activated
     */
    activate: (context: ExtractorExecutionContext, extractor: BaseExtractor) => unknown;
    /**
     * Emitted when a extractor is deactivated
     * @param context The context where this event occurred
     * @param extractor The extractor which was deactivated
     */
    deactivate: (context: ExtractorExecutionContext, extractor: BaseExtractor) => unknown;
    /**
     * Emitted when a extractor fails to activate/deactivate
     * @param context The context where this event occurred
     * @param extractor The extractor which was deactivated
     */
    error: (context: ExtractorExecutionContext, extractor: BaseExtractor, error: Error) => unknown;
}
declare class ExtractorExecutionContext extends PlayerEventsEmitter<ExtractorExecutionEvents> {
    player: Player;
    /**
     * The extractors store
     */
    store: Collection<string, BaseExtractor<object>>;
    readonly context: Context<ExtractorSession>;
    constructor(player: Player);
    /**
     * Get the current execution id
     */
    getExecutionId(): string | null;
    /**
     * Get the current execution context
     */
    getContext(): ExtractorSession | null;
    loadDefault(): Promise<void>;
    /**
     * Load a bundle of extractors.
     * @example import { DefaultExtractors } from '@discord-player/extractor';
     *
     * await player.extractors.loadMulti(DefaultExtractors);
     */
    loadMulti<O extends object, T extends (typeof BaseExtractor<O>)[], R extends Record<T[number]['identifier'], ConstructorParameters<T[number]>[1]>>(bundle: T, options?: R): Promise<{
        success: boolean;
        error: null;
    }>;
    /**
     * Validate if the given extractor is registered
     * @param identifier The extractor identifier
     */
    isRegistered(identifier: string): boolean;
    /**
     * The size of registered extractors
     */
    get size(): number;
    /**
     * Get single extractor
     * @param identifier The extractor to get
     */
    get(identifier: string): BaseExtractor<object> | undefined;
    /**
     * Register single extractor
     * @param _extractor The extractor to register
     * @param options Options supplied to the extractor
     */
    register<O extends object, T extends typeof BaseExtractor<O>>(_extractor: T, options: ConstructorParameters<T>['1']): Promise<InstanceType<T> | null>;
    /**
     * Unregister single extractor
     * @param _extractor The extractor to unregister
     */
    unregister<K extends string | BaseExtractor>(_extractor: K): Promise<void>;
    /**
     * Unregister all extractors
     */
    unregisterAll(): Promise<void>;
    /**
     * Run all the extractors
     * @param fn The runner function
     * @param filterBlocked Filter blocked extractors
     */
    run<T = unknown>(fn: ExtractorExecutionFN<T>, filterBlocked?: boolean): Promise<ExtractorExecutionResult<T> | ExtractorExecutionResult<false> | undefined>;
    /**
     * Request bridge for a track
     * @param track The track to request bridge for
     * @param sourceExtractor The source extractor of the track
     */
    requestBridge(track: Track, sourceExtractor?: BaseExtractor | null): Promise<ExtractorExecutionResult<ExtractorStreamable>>;
    /**
     * Request bridge from the specified extractor
     * @param track The track to request bridge for
     * @param sourceExtractor The source extractor of the track
     * @param targetExtractor The target extractor to bridge to
     */
    requestBridgeFrom(track: Track, sourceExtractor: BaseExtractor | null, targetExtractor: ExtractorResolvable): Promise<ExtractorStreamable | null>;
    /**
     * Check if extractor is disabled
     */
    isDisabled(identifier: string): boolean;
    /**
     * Check if extractor is enabled
     */
    isEnabled(identifier: string): boolean;
    /**
     * Resolve extractor identifier
     */
    resolveId(resolvable: ExtractorResolvable): string;
    /**
     * Resolve extractor
     */
    resolve(resolvable: ExtractorResolvable): BaseExtractor<object> | undefined;
}
interface ExtractorExecutionResult<T = unknown> {
    extractor: BaseExtractor;
    error: Error | null;
    result: T;
}
type ExtractorExecutionFN<T = unknown> = (extractor: BaseExtractor) => Promise<T | boolean>;
type ExtractorResolvable = string | BaseExtractor;

interface QueryCacheOptions {
    checkInterval?: number;
}
interface QueryCacheProvider<T> {
    getData(): Promise<DiscordPlayerQueryResultCache<T>[]>;
    addData(data: SearchResult): Promise<void>;
    resolve(context: QueryCacheResolverContext): Promise<SearchResult>;
}
declare class QueryCache implements QueryCacheProvider<Track> {
    #private;
    player: Player;
    options: QueryCacheOptions;
    timer: NodeJS.Timer;
    constructor(player: Player, options?: QueryCacheOptions);
    get checkInterval(): number;
    cleanup(): Promise<void>;
    clear(): Promise<void>;
    getData(): Promise<DiscordPlayerQueryResultCache<Track<unknown>>[]>;
    addData(data: SearchResult): Promise<void>;
    resolve(context: QueryCacheResolverContext): Promise<SearchResult>;
}
declare class DiscordPlayerQueryResultCache<T = unknown> {
    data: T;
    expireAfter: number;
    constructor(data: T, expireAfter?: number);
    hasExpired(): boolean;
}
interface QueryCacheResolverContext {
    query: string;
    requestedBy?: User;
    queryType?: SearchQueryType | `ext:${string}`;
}

interface HooksCtx {
    guild: Guild;
}

/**
 * Represents a stream that can be intercepted and consumed without affecting the original consumer.
 * @example const stream = new InterceptedStream();
 *
 * // real consumer
 * stream.pipe(fs.createWriteStream('file.txt'));
 *
 * // man in the middle consumer
 * const manInTheMiddle = new Writable({
 *  write(chunk, encoding, callback) {
 *   console.log(chunk.toString());
 *   callback();
 *  }
 * });
 *
 * // stream.interceptors is a Set of Writable streams
 * stream.interceptors.add(manInTheMiddle);
 */
declare class InterceptedStream extends Transform {
    #private;
    readonly interceptors: Set<Writable>;
    /**
     * Start intercepting the stream. This is the default state of InterceptedStream.
     */
    startIntercepting(): void;
    /**
     * Stop intercepting the stream. This will prevent the stream from being consumed by the interceptors.
     * This can be useful when you want to temporarily stop the interception. The stopped state can be resumed by calling startIntercepting again.
     */
    stopIntercepting(): void;
    /**
     * Whether the stream is being intercepted
     */
    isIntercepting(): boolean;
    _transform(chunk: Buffer, encoding: BufferEncoding, callback: TransformCallback): void;
    _final(callback: TransformCallback): void;
    _destroy(error: Error, callback: TransformCallback): void;
}

type Awaitable<T> = T | PromiseLike<T>;
type ShouldInterceptFunction = <T = any>(queue: GuildQueue<T>, track: Track, format: StreamType, stream: InterceptedStream) => Awaitable<boolean>;
type OnInterceptedStreamHandler = <T = any>(queue: GuildQueue<T>, track: Track, format: StreamType, stream: InterceptedStream) => Awaitable<void>;
interface PlayerStreamInterceptorOptions {
    /**
     * Determines whether the stream should be intercepted.
     */
    shouldIntercept?: ShouldInterceptFunction;
}
declare class PlayerStreamInterceptor {
    #private;
    readonly player: Player;
    private readonly options;
    /**
     * Creates a new PlayerStreamInterceptor instance.
     * @param player The player instance
     * @param options The interceptor options
     */
    constructor(player: Player, options: PlayerStreamInterceptorOptions);
    /**
     * Handles the intercepted stream.
     * @param queue The guild queue
     * @param track The track
     * @param stream The intercepted stream
     * @returns Whether the stream was intercepted
     */
    handle<T = unknown>(queue: GuildQueue<T>, track: Track, type: StreamType, stream: InterceptedStream): Promise<boolean>;
    /**
     * Adds a new intercepted stream listener.
     * @param handler The handler
     * @returns A function to remove the listener
     */
    onStream(handler: OnInterceptedStreamHandler): () => void;
}

interface PlayerEvents {
    debug: (message: string) => any;
    error: (error: Error) => any;
    voiceStateUpdate: (queue: GuildQueue, oldState: VoiceState, newState: VoiceState) => any;
}
declare const PlayerEvent: {
    readonly debug: "debug";
    readonly Debug: "debug";
    readonly error: "error";
    readonly Error: "error";
    readonly voiceStateUpdate: "voiceStateUpdate";
    readonly VoiceStateUpdate: "voiceStateUpdate";
};
type PlayerEvent = (typeof PlayerEvent)[keyof typeof PlayerEvent];
interface PlayerNodeInitializationResult<T = any> {
    track: Track;
    extractor: BaseExtractor | null;
    searchResult: SearchResult;
    queue: GuildQueue<T>;
}
type TrackLike = string | Track | SearchResult | Track[] | Playlist | AudioResource;
interface PlayerNodeInitializerOptions<T> extends SearchOptions {
    nodeOptions?: GuildNodeCreateOptions<T>;
    connectionOptions?: VoiceConnectConfig;
    audioPlayerOptions?: ResourcePlayOptions;
    signal?: AbortSignal;
    afterSearch?: (result: SearchResult) => Promise<SearchResult>;
}
type VoiceStateHandler = (player: Player, queue: GuildQueue, oldVoiceState: VoiceState, newVoiceState: VoiceState) => Awaited<void>;
interface PlayerInitOptions {
    /**
     * The voice connection timeout
     */
    connectionTimeout?: number;
    /**
     * Time in ms to re-monitor event loop lag
     */
    lagMonitor?: number;
    /**
     * Prevent voice state handler from being overridden
     */
    lockVoiceStateHandler?: boolean;
    /**
     * List of extractors to disable querying metadata from
     */
    blockExtractors?: string[];
    /**
     * List of extractors to disable streaming from
     */
    blockStreamFrom?: string[];
    /**
     * Query cache provider
     */
    queryCache?: QueryCacheProvider<any> | null;
    /**
     * Skip ffmpeg process when possible
     */
    skipFFmpeg?: boolean;
    /**
     * The probe timeout in milliseconds. Defaults to 5000.
     */
    probeTimeout?: number;
    /**
     * Configure ffmpeg path
     */
    ffmpegPath?: string;
    /**
     * Whether to override the fallback context. Defaults to `true`.
     */
    overrideFallbackContext?: boolean;
}
declare class Player extends PlayerEventsEmitter<PlayerEvents> {
    #private;
    /**
     * The version of discord-player
     */
    static readonly version: string;
    /**
     * The unique identifier of this player instance
     */
    readonly id: string;
    /**
     * The discord.js client
     */
    readonly client: Client;
    /**
     * The player options
     */
    readonly options: PlayerInitOptions;
    /**
     * The player nodes (queue) manager
     */
    nodes: GuildNodeManager<any>;
    /**
     * The voice api utilities
     */
    readonly voiceUtils: VoiceUtils;
    /**
     * The extractors manager
     */
    extractors: ExtractorExecutionContext;
    /**
     * The player events channel
     */
    events: PlayerEventsEmitter<GuildQueueEvents<any>>;
    /**
     * The player version
     */
    readonly version: string;
    /**
     * The lyrics api
     */
    readonly lyrics: LrcLib;
    /**
     * Creates new Discord Player
     * @param {Client} client The Discord Client
     * @param {PlayerInitOptions} [options] The player init options
     */
    constructor(client: Client, options?: PlayerInitOptions);
    /**
     * The hooks context for this player instance.
     */
    get context(): Context<HooksCtx>;
    /**
     * Override default voice state update handler
     * @param handler The handler callback
     */
    onVoiceStateUpdate(handler: VoiceStateHandler): void;
    debug(m: string): boolean;
    /**
     * Creates new discord-player instance.
     * @param client The client that instantiated player
     * @param options Player initializer options
     */
    static create(client: Client, options?: PlayerInitOptions): Player;
    /**
     * The current query cache provider in use
     */
    get queryCache(): QueryCacheProvider<any> | null;
    /**
     * Alias to `Player.nodes`.
     */
    get queues(): GuildNodeManager<any>;
    /**
     * Event loop latency in ms. If your bot is laggy and this returns a number above 20ms for example,
     * some expensive task is being executed on the current thread which is slowing down the event loop.
     * @type {number}
     */
    get eventLoopLag(): number;
    /**
     * Generates statistics that could be useful. Statistics generator is still experimental.
     * @example ```typescript
     * const stats = player.generateStatistics();
     *
     * console.log(stats);
     *
     * // outputs something like
     * // {
     * //   queuesCount: number,
     * //   queryCacheEnabled: boolean,
     * //   queues: [
     * //      GuildQueueStatisticsMetadata,
     * //      GuildQueueStatisticsMetadata,
     * //      GuildQueueStatisticsMetadata,
     * //      ...
     * //   ]
     * // }
     * ```
     */
    generateStatistics(): {
        queuesCount: number;
        queryCacheEnabled: boolean;
        queues: GuildQueueStatisticsMetadata[];
    };
    /**
     * Whether the player is in compatibility mode. Compatibility mode is enabled when non-discord.js client is used.
     */
    isCompatMode(): boolean;
    /**
     * Destroy every single queues managed by this master player instance
     * @example ```typescript
     * // use me when you want to immediately terminate every single queues in existence 🔪
     * await player.destroy();
     * ```
     */
    destroy(): Promise<void>;
    private _handleVoiceState;
    /**
     * Handles voice state update
     * @param {VoiceState} oldState The old voice state
     * @param {VoiceState} newState The new voice state
     * @returns {void}
     * @example ```typescript
     * // passing voice state update data to this method will trigger voice state handler
     *
     * client.on('voiceStateUpdate', (oldState, newState) => {
     *   // this is definitely a rocket science, right here
     *   player.handleVoiceState(oldState, newState);
     * });
     * ```
     */
    handleVoiceState(oldState: VoiceState, newState: VoiceState): void;
    /**
     * Lock voice state handler. When this method is called, discord-player will keep using the default voice state update handler, even if custom implementation exists.
     */
    lockVoiceStateHandler(): void;
    /**
     * Unlock voice state handler. When this method is called, discord-player will stop using the default voice state update handler if custom implementation exists.
     */
    unlockVoiceStateHandler(): void;
    /**
     * Checks if voice state handler is locked.
     */
    isVoiceStateHandlerLocked(): boolean;
    /**
     * Initiate audio player
     * @param channel The voice channel on which the music should be played
     * @param query The track or source to play
     * @param options Options for player
     * @example ```typescript
     * // no need to worry about queue management, just use this method 😄
     * const query = 'this is my super cool search query that I want to play';
     *
     * try {
     *    const { track } = await player.play(voiceChannel, query);
     *   console.log(`🎉 I am playing ${track.title} 🎉`);
     * } catch(e) {
     *   console.log(`😭 Failed to play error oh no:\n\n${e}`);
     * }
     * ```
     */
    play<T = unknown>(channel: GuildVoiceChannelResolvable, query: TrackLike, options?: PlayerNodeInitializerOptions<T>): Promise<PlayerNodeInitializationResult<T>>;
    /**
     * Search tracks
     * @param {string | Track | Track[] | Playlist | SearchResult} query The search query
     * @param {SearchOptions} options The search options
     * @returns {Promise<SearchResult>}
     * @example ```typescript
     * const searchQuery = 'pass url or text or discord-player track constructable objects, we got you covered 😎';
     * const result = await player.search(searchQuery);
     *
     * console.log(result); // Logs `SearchResult` object
     * ```
     */
    search(searchQuery: TrackLike, options?: SearchOptions): Promise<SearchResult>;
    /**
     * Generates a report of the dependencies used by the `discord-voip` module. Useful for debugging.
     * @example ```typescript
     * console.log(player.scanDeps());
     * // -> logs dependencies report
     * ```
     * @returns {string}
     */
    scanDeps(): string;
    [Symbol.iterator](): Generator<GuildQueue<any>, void, undefined>;
    /**
     * Creates `Playlist` instance
     * @param data The data to initialize a playlist
     */
    createPlaylist(data: PlaylistInitData): Playlist;
    /**
     * Creates a track from an audio resource.
     * @param resource The audio resource
     */
    createTrackFromAudioResource(resource: AudioResource): Track<Record<string, unknown>>;
    /**
     * Handles intercepting streams
     * @param stream The stream to intercept
     */
    handleInterceptingStream(queue: GuildQueue, track: Track, format: StreamType, stream: InterceptedStream): Promise<boolean | undefined>;
    /**
     * Creates a global stream interceptor
     * @param options The stream interceptor options
     */
    createStreamInterceptor(options: PlayerStreamInterceptorOptions): PlayerStreamInterceptor;
}

type SerializedPlaylist = ReturnType<Playlist['serialize']>;
interface PlaylistInitData {
    /**
     * The tracks of this playlist
     */
    tracks: Track[];
    /**
     * The playlist title
     */
    title: string;
    /**
     * The description
     */
    description: string;
    /**
     * The thumbnail
     */
    thumbnail: string;
    /**
     * The playlist type: `album` | `playlist`
     */
    type: 'album' | 'playlist';
    /**
     * The playlist source
     */
    source: TrackSource;
    /**
     * The playlist author
     */
    author: {
        /**
         * The author name
         */
        name: string;
        /**
         * The author url
         */
        url: string;
    };
    /**
     * The playlist id
     */
    id: string;
    /**
     * The playlist url
     */
    url: string;
    /**
     * The raw playlist data
     */
    rawPlaylist?: any;
}
interface PlaylistJSON {
    /**
     * The playlist id
     */
    id: string;
    /**
     * The playlist url
     */
    url: string;
    /**
     * The playlist title
     */
    title: string;
    /**
     * The playlist description
     */
    description: string;
    /**
     * The thumbnail
     */
    thumbnail: string;
    /**
     * The playlist type: `album` | `playlist`
     */
    type: 'album' | 'playlist';
    /**
     * The track source
     */
    source: TrackSource;
    /**
     * The playlist author
     */
    author: {
        /**
         * The author name
         */
        name: string;
        /**
         * The author url
         */
        url: string;
    };
    /**
     * The tracks data (if any)
     */
    tracks: TrackJSON[];
}
declare class Playlist {
    readonly player: Player;
    tracks: Track[];
    title: string;
    description: string;
    thumbnail: string;
    type: 'album' | 'playlist';
    source: TrackSource;
    author: {
        name: string;
        url: string;
    };
    id: string;
    url: string;
    readonly rawPlaylist?: any;
    /**
     * Playlist constructor
     * @param {Player} player The player
     * @param {PlaylistInitData} data The data
     */
    constructor(player: Player, data: PlaylistInitData);
    [Symbol.iterator](): Generator<Track<unknown>, void, undefined>;
    /**
     * Estimated duration of this playlist
     */
    get estimatedDuration(): number;
    /**
     * Formatted estimated duration of this playlist
     */
    get durationFormatted(): string;
    /**
     * JSON representation of this playlist
     * @param {boolean} [withTracks=true] If it should build json with tracks
     * @returns {PlaylistJSON}
     */
    toJSON(withTracks?: boolean): PlaylistJSON;
    /**
     * Serialize this playlist into reconstructable data
     */
    serialize(): {
        tracks: {
            title: string;
            description: string;
            author: string;
            url: string;
            thumbnail: any;
            duration: string;
            views: number;
            requested_by: {} | null;
            source: any;
            live: boolean;
            query_type: SearchQueryType | null | undefined;
            extractor: string | null;
            metadata: unknown;
            $type: SerializedType;
            $encoder_version: string;
        }[];
        title: string;
        description: string;
        thumbnail: any;
        type: "playlist" | "album";
        source: TrackSource;
        author: {
            name: string;
            url: string;
        };
        id: string;
        url: string;
        $type: SerializedType;
        $encoder_version: string;
    };
    /**
     * Deserialize this playlist from serialized data
     * @param player Player instance
     * @param data Serialized data
     */
    static fromSerialized(player: Player, data: SerializedPlaylist): Playlist;
    /**
     * Play this playlist to the given voice channel. If queue exists and another track is being played, this playlist will be added to the queue.
     * @param channel Voice channel on which this playlist shall be played
     * @param options Node initialization options
     */
    play<T = unknown>(channel: GuildVoiceChannelResolvable, options?: PlayerNodeInitializerOptions<T>): Promise<PlayerNodeInitializationResult<T>>;
}

type ExtractorStreamable = Readable | string | {
    $fmt: string;
    stream: Readable;
};
declare class BaseExtractor<T extends object = object> {
    context: ExtractorExecutionContext;
    options: T;
    /**
     * Identifier for this extractor
     */
    static identifier: string;
    /**
     * Priority of this extractor. Higher value means higher priority (will be executed first).
     */
    priority: number;
    /**
     * A list of query protocols that this extractor supports.
     */
    protocols: string[];
    /**
     * Handle bridge query creation
     * @param track The track to build query for
     */
    createBridgeQuery: (track: Track) => string;
    /**
     * Extractor constructor
     * @param context Context that instantiated this extractor
     * @param options Initialization options for this extractor
     */
    constructor(context: ExtractorExecutionContext, options?: T);
    /**
     * Identifier of this extractor
     */
    get identifier(): string;
    /**
     * Reconfigures this extractor
     * @param options The new options to apply
     */
    reconfigure(options: T): Promise<void>;
    /**
     * This method will be executed when this extractor is activated
     */
    activate(): Promise<void>;
    /**
     * This method will be executed when this extractor is deactivated
     */
    deactivate(): Promise<void>;
    /**
     * Validate incoming query
     * @param query The query to validate
     */
    validate(query: string, type?: SearchQueryType | null): Promise<boolean>;
    /**
     * Stream the given track
     * @param info The track to stream
     */
    stream(info: Track): Promise<ExtractorStreamable>;
    /**
     * Handle the given query
     * @param query The query to handle
     */
    handle(query: string, context: ExtractorSearchContext): Promise<ExtractorInfo>;
    /**
     * Get related tracks for the given track
     * @param track The track source
     */
    getRelatedTracks(track: Track, history: GuildQueueHistory): Promise<ExtractorInfo>;
    /**
     * A stream middleware to handle streams before passing it to the player
     * @param stream The incoming stream
     * @param next The next function
     */
    handlePostStream(stream: Readable, next: NextFunction): void;
    /**
     * Dispatch an event to the player
     * @param event The event to dispatch
     * @param args The data to dispatch
     */
    emit<K extends keyof PlayerEvents>(event: K, ...args: Parameters<PlayerEvents[K]>): boolean;
    /**
     * Create extractor response
     * @param playlist The playlist
     * @param tracks The track array
     */
    createResponse(playlist?: Playlist | null, tracks?: Track[]): ExtractorInfo;
    /**
     * Write debug message
     * @param message The debug message
     */
    debug(message: string): boolean;
    /**
     * A flag to indicate `Demuxable` stream support for `opus`/`ogg/opus`/`webm/opus` formats.
     */
    get supportsDemux(): boolean;
    /**
     * Handle stream extraction for another extractor
     * @param track The track to bridge
     * @param sourceExtractor The source extractor
     */
    bridge(track: Track, sourceExtractor: BaseExtractor | null): Promise<ExtractorStreamable | null>;
}
type NextFunction = (error?: Error | null, stream?: Readable) => void;
interface ExtractorInfo {
    playlist: Playlist | null;
    tracks: Track[];
}
interface ExtractorSearchContext {
    type?: SearchQueryType | null;
    requestedBy?: User | null;
    requestOptions?: RequestOptions;
    protocol?: string | null;
}

type RuntimeType = 'node' | 'deno' | 'bun' | 'unknown';
interface TimeData {
    /**
     * Time in days
     */
    days: number;
    /**
     * Time in hours
     */
    hours: number;
    /**
     * Time in minutes
     */
    minutes: number;
    /**
     * Time in seconds
     */
    seconds: number;
}
interface Runtime {
    name: RuntimeType;
    version: string;
}
declare class Util {
    /**
     * Utils
     */
    private constructor();
    /**
     * Gets the runtime information
     */
    static getRuntime(): Runtime;
    /**
     * Creates duration string
     * @param {object} durObj The duration object
     * @returns {string}
     */
    static durationString(durObj: Record<string, number>): string;
    /**
     * Parses milliseconds to consumable time object
     * @param {number} milliseconds The time in ms
     * @returns {TimeData}
     */
    static parseMS(milliseconds: number): TimeData;
    /**
     * Builds time code
     * @param {TimeData} duration The duration object
     * @returns {string}
     */
    static buildTimeCode(duration: TimeData): string;
    /**
     * Formats duration
     * @param {number} duration The duration in ms
     */
    static formatDuration(duration: number): string;
    /**
     * Picks last item of the given array
     * @param {any[]} arr The array
     * @returns {any}
     */
    static last<T = any>(arr: T[]): T;
    /**
     * Checks if the voice channel is empty
     * @param {VoiceChannel|StageChannel} channel The voice channel
     * @returns {boolean}
     */
    static isVoiceEmpty(channel: VoiceChannel | StageChannel): boolean;
    /**
     * Cleans the track title
     * @param title The title
     * @param source The source
     * @returns Cleaned title
     */
    static cleanTitle(title: string, source: TrackSource): string;
    /**
     * Safer require
     * @param {string} id Node require id
     * @returns {any}
     */
    static require(id: string): {
        module: any;
        error: null;
    } | {
        module: null;
        error: unknown;
    };
    static import(id: string): Promise<{
        module: any;
        error: null;
    } | {
        module: null;
        error: unknown;
    }>;
    /**
     * Asynchronous timeout
     * @param {number} time The time in ms to wait
     * @returns {Promise<unknown>}
     */
    static wait(time: number): Promise<undefined>;
    static noop(): void;
    static getFetch(): Promise<any>;
    static warn(message: string, code?: string, detail?: string): void;
    static randomChoice<T>(src: T[]): T;
    static arrayCloneShuffle<T>(src: T[]): T[];
}
declare const VALIDATE_QUEUE_CAP: (queue: GuildQueue, items: Playlist | Track | Track[] | number) => void;

declare class DiscordPlayerError extends Error {
    readonly code: ErrorCodes;
    readonly timestamp: number;
    constructor(code: ErrorCodes, message: string);
    toJSON(): {
        name: string;
        code: ErrorCodes;
        message: string;
        timestamp: number;
    };
}
declare const ErrorCodes: {
    readonly ERR_OUT_OF_SPACE: "ERR_OUT_OF_SPACE";
    readonly ERR_INVALID_ARG_TYPE: "ERR_INVALID_ARG_TYPE";
    readonly ERR_NO_RESULT: "ERR_NO_RESULT";
    readonly ERR_NOT_IMPLEMENTED: "ERR_NOT_IMPLEMENTED";
    readonly ERR_NOT_EXISTING: "ERR_NOT_EXISTING";
    readonly ERR_OUT_OF_RANGE: "ERR_OUT_OF_RANGE";
    readonly ERR_NO_VOICE_CONNECTION: "ERR_NO_VOICE_CONNECTION";
    readonly ERR_VOICE_CONNECTION_DESTROYED: "ERR_VOICE_CONNECTION_DESTROYED";
    readonly ERR_NO_VOICE_CHANNEL: "ERR_NO_VOICE_CHANNEL";
    readonly ERR_INVALID_VOICE_CHANNEL: "ERR_INVALID_VOICE_CHANNEL";
    readonly ERR_NO_RECEIVER: "ERR_NO_RECEIVER";
    readonly ERR_FFMPEG_LOCATOR: "ERR_FFMPEG_LOCATOR";
    readonly ERR_NO_AUDIO_RESOURCE: "ERR_NO_AUDIO_RESOURCE";
    readonly ERR_NO_GUILD_QUEUE: "ERR_NO_GUILD_QUEUE";
    readonly ERR_NO_GUILD: "ERR_NO_GUILD";
    readonly ERR_INFO_REQUIRED: "ERR_INFO_REQUIRED";
    readonly ERR_SERIALIZATION_FAILED: "ERR_SERIALIZATION_FAILED";
    readonly ERR_DESERIALIZATION_FAILED: "ERR_DESERIALIZATION_FAILED";
    readonly ERR_ILLEGAL_HOOK_INVOCATION: "ERR_ILLEGAL_HOOK_INVOCATION";
    readonly ERR_NOT_EXISTING_MODULE: "ERR_NOT_EXISTING_MODULE";
    readonly ERR_BRIDGE_FAILED: "ERR_BRIDGE_FAILED";
};
type ErrorCodes = (typeof ErrorCodes)[keyof typeof ErrorCodes];

declare class TypeUtil {
    private constructor();
    static isFunction(t: unknown): t is Function;
    static isNumber(t: unknown): t is number;
    static isString(t: unknown): t is string;
    static isBoolean(t: unknown): t is boolean;
    static isNullish(t: unknown): t is null | undefined;
    static isArray(t: unknown): t is unknown[];
    static isError(t: unknown): t is Error;
    static isDiscordPlayerError(t: unknown): t is DiscordPlayerError;
}

interface PackageJSON {
    name: string;
    version: string;
}
type MaybeNull<T> = T | null;
interface DependenciesReport {
    core: {
        'discord-player': string;
        'discord-voip': string;
    };
    libopus: {
        mediaplex: MaybeNull<string>;
        '@discordjs/opus': MaybeNull<string>;
        '@evan/opus': MaybeNull<string>;
        opusscript: MaybeNull<string>;
        'node-opus': MaybeNull<string>;
    };
    libsodium: {
        'sodium-native': MaybeNull<string>;
        sodium: MaybeNull<string>;
        'libsodium-wrappers': MaybeNull<string>;
        'sodium-javascript': MaybeNull<string>;
        '@stablelib/xchacha20poly1305': MaybeNull<string>;
        '@noble/ciphers': MaybeNull<string>;
    };
    DAVE: {
        '@snazzah/davey': MaybeNull<string>;
    };
    ffmpeg: FFmpegReport;
}
type FFmpegReport = Record<FFmpegLib, MaybeNull<{
    version: string;
    hasLibopus: boolean;
}>>;
/**
 * A utility to generate a report of the dependencies used by the discord-player module.
 */
declare const DependencyReportGenerator: {
    /**
     * Finds the package.json file of a package.
     * @param dir - The directory to start searching from
     * @param packageName - The name of the package to find
     * @param depth - The maximum depth to search
     * @returns The package.json file, or null if not found
     */
    findPackageJSON(dir: string, packageName: string, depth: number): PackageJSON | null;
    /**
     * Tries to find the version of a dependency.
     * @param name - The package to find the version of
     * @param maxLookupDepth - The maximum depth to search for the package.json file
     * @returns The version of the package, or null if not found
     */
    version(name: string, maxLookupDepth?: number): string | null;
    /**
     * Generates a report of the dependencies used by the discord-player module.
     * @returns The report object
     */
    generate(): DependenciesReport;
    /**
     * Generates a string representation of the dependencies report.
     * @returns The string representation
     */
    generateString(): string;
};

declare const version: string;

export { AFilterGraph, AsyncQueue, type AsyncQueueAcquisitionOptions, AsyncQueueEntry, type AsyncQueueExceptionHandler, AudioFilters, BaseExtractor, Context, type ContextReceiver, type CreateStreamOps, type DependenciesReport, DependencyReportGenerator, DiscordPlayerQueryResultCache, type Encodable, EqualizerConfigurationPreset, ExtractorExecutionContext, type ExtractorExecutionEvents, type ExtractorExecutionFN, type ExtractorExecutionResult, type ExtractorInfo, type ExtractorResolvable, type ExtractorSearchContext, type ExtractorSession, type ExtractorStreamable, FFMPEG_ARGS_PIPED, FFMPEG_ARGS_STRING, FFMPEG_SRATE_REGEX, FFmpegFilterer, type FFmpegReport, type FFmpegStreamOptions, type FilterGraph, type FiltersName, type GuildNodeCreateOptions, type GuildNodeInit, GuildNodeManager, GuildQueue, type GuildQueueAFiltersCache, GuildQueueAudioFilters, GuildQueueEvent, type GuildQueueEvents, GuildQueueHistory, GuildQueuePlayerNode, GuildQueueStatistics, type GuildQueueStatisticsMetadata, type GuildQueueTimeline, InterceptedStream, type LrcGetParams, type LrcGetResult, LrcLib, type LrcSearchParams, type LrcSearchResult, type MaybeNull, type MetadataDispatch, type NextFunction, type NodeResolvable, type OnAfterCreateStreamHandler, type OnBeforeCreateStreamHandler, type OnInterceptedStreamHandler, type OnStreamExtractedHandler, type PackageJSON, type PlayOptions, Player, PlayerEvent, type PlayerEvents, PlayerEventsEmitter, type PlayerInitOptions, type PlayerNodeInitializationResult, type PlayerNodeInitializerOptions, type PlayerProgressbarOptions, type PlayerSearchResult, PlayerStreamInterceptor, type PlayerStreamInterceptorOptions, type PlayerTimestamp, type PlayerTriggeredReason, Playlist, type PlaylistInitData, type PlaylistJSON, type PostProcessedResult, QueryCache, type QueryCacheOptions, type QueryCacheProvider, type QueryCacheResolverContext, type QueryExtractorSearch, QueryResolver, QueryType, type QueueFilters, QueueRepeatMode, type RawTrackData, type RequestEntity, type ResolvedQuery, type ResourcePlayOptions, type Runtime, type RuntimeType, type SearchOptions, type SearchQueryType, SearchResult, type SearchResultData, SequentialBucket, type SerializedPlaylist, type SerializedTrack, SerializedType, type SetterFN$1 as SetterFN, type ShouldInterceptFunction, type SkipOptions, type StreamConfig, StreamDispatcher, type TimeData, type TimelineDispatcherOptions, Track, type TrackJSON, type TrackLike, type TrackResolvable, TrackSkipReason, type TrackSource, TypeUtil, Util, VALIDATE_QUEUE_CAP, type VoiceConnectConfig, type VoiceEvents, type VoiceStateHandler, VoiceUtils, type WithMetadata, createContext, createErisCompat, createFFmpegStream, createOceanicCompat, decode, deserialize, encode, isErisProxy, isOceanicProxy, onAfterCreateStream, onBeforeCreateStream, onStreamExtracted, serialize, tryIntoThumbnailString, useContext, useHistory, useMainPlayer, useMetadata, usePlayer, useQueue, useTimeline, useVolume, version };
