import { Transform, TransformCallback } from 'node:stream';

/**
 * Demuxes an Ogg stream (containing Opus audio) to output an Opus stream.
 */
declare class OggDemuxer extends Transform {
    private _remainder;
    private _head;
    private _bitstream;
    /**
     * Creates a new OggOpus demuxer.
     * @param {Object} [options] options that you would pass to a regular Transform stream.
     * @memberof opus
     */
    constructor(options?: {});
    _transform(chunk: Buffer, encoding: BufferEncoding, done: TransformCallback): void;
    /**
     * Reads a page from a buffer
     * @private
     * @param {Buffer} chunk the chunk containing the page
     * @returns {boolean|Buffer} if a buffer, it will be a slice of the excess data of the original, otherwise it will be
     * false and would indicate that there is not enough data to go ahead with reading this page.
     */
    _readPage(chunk: Buffer): false | Buffer;
    _destroy(err: Error, cb: (error: Error | null) => void): void;
    _final(cb: TransformCallback): void;
    /**
     * Cleans up the demuxer when it is no longer required.
     * @private
     */
    _cleanup(): void;
}

type IEncoder = {
    new (rate: number, channels: number, application: number): {
        encode(buffer: Buffer): Buffer;
        encode(buffer: Buffer, frameSize: number): Buffer;
        encode(buffer: Buffer, frameSize?: number): Buffer;
        decode(buffer: Buffer): Buffer;
        decode(buffer: Buffer, frameSize: number): Buffer;
        decode(buffer: Buffer, frameSize?: number): Buffer;
        applyEncoderCTL?(ctl: number, value: number): void;
        encoderCTL?(ctl: number, value: number): void;
        delete?(): void;
    };
    Application?: any;
};
type IMod = [
    string,
    (mod: any) => {
        Encoder: IEncoder;
    }
];
declare const CTL: {
    readonly BITRATE: 4002;
    readonly FEC: 4012;
    readonly PLP: 4014;
};
/**
 * Add a new Opus provider to the registry. This will be tried to load in order at runtime.
 * @param provider - The provider to add
 */
declare const addLibopusProvider: (provider: IMod) => void;
/**
 * Remove an Opus provider from the registry.
 * @param name - The name of the provider to remove
 */
declare const removeLibopusProvider: (name: string) => boolean;
/**
 * Set the Opus provider to use. This will override the automatic provider selection.
 * @param provider - The provider to use
 */
declare const setLibopusProvider: (provider: IEncoder, name: string) => void;
interface IOpusStreamInit {
    frameSize: number;
    channels: number;
    rate: number;
    application?: number;
}
/**
 * Takes a stream of Opus data and outputs a stream of PCM data, or the inverse.
 * **You shouldn't directly instantiate this class, see opus.Encoder and opus.Decoder instead!**
 * @memberof opus
 * @extends TransformStream
 * @protected
 */
declare class OpusStream extends Transform {
    encoder: InstanceType<IEncoder> | null;
    _options: IOpusStreamInit;
    _required: number;
    /**
     * Creates a new Opus transformer.
     * @private
     * @memberof opus
     * @param {Object} [options] options that you would pass to a regular Transform stream
     */
    constructor(options?: IOpusStreamInit);
    _encode(buffer: Buffer): Buffer;
    _decode(buffer: Buffer): Buffer;
    /**
     * Returns the Opus module being used - `mediaplex`, `opusscript`, `node-opus`, or `@discordjs/opus`.
     * @type {string}
     * @readonly
     * @example
     * console.log(`Using Opus module ${OpusEncoder.type}`);
     */
    static get type(): string | undefined;
    /**
     * Sets the bitrate of the stream.
     * @param {number} bitrate the bitrate to use use, e.g. 48000
     * @public
     */
    setBitrate(bitrate: number): void;
    /**
     * Enables or disables forward error correction.
     * @param {boolean} enabled whether or not to enable FEC.
     * @public
     */
    setFEC(enabled: boolean): void;
    /**
     * Sets the expected packet loss over network transmission.
     * @param {number} [percentage] a percentage (represented between 0 and 1)
     */
    setPLP(percentage: number): void;
    _final(cb: () => void): void;
    _destroy(err: Error | null, cb: (err: Error | null) => void): void;
    /**
     * Cleans up the Opus stream when it is no longer needed
     * @private
     */
    _cleanup(): void;
}
/**
 * An Opus encoder stream.
 *
 * Outputs opus packets in [object mode.](https://nodejs.org/api/stream.html#stream_object_mode)
 * @extends opus.OpusStream
 * @memberof opus
 * @example
 * const encoder = new prism.opus.Encoder({ frameSize: 960, channels: 2, rate: 48000 });
 * pcmAudio.pipe(encoder);
 * // encoder will now output Opus-encoded audio packets
 */
declare class OpusEncoder extends OpusStream {
    _buffer: Buffer;
    /**
     * Creates a new Opus encoder stream.
     * @memberof opus
     * @param {Object} options options that you would pass to a regular OpusStream, plus a few more:
     * @param {number} options.frameSize the frame size in bytes to use (e.g. 960 for stereo audio at 48KHz with a frame
     * duration of 20ms)
     * @param {number} options.channels the number of channels to use
     * @param {number} options.rate the sampling rate in Hz
     */
    constructor(options?: IOpusStreamInit);
    _transform(newChunk: Buffer, encoding: BufferEncoding, done: TransformCallback): void;
    _destroy(err: Error, cb: (err: Error | null) => void): void;
}
/**
 * An Opus decoder stream.
 *
 * Note that any stream you pipe into this must be in
 * [object mode](https://nodejs.org/api/stream.html#stream_object_mode) and should output Opus packets.
 * @extends opus.OpusStream
 * @memberof opus
 * @example
 * const decoder = new OpusDecoder({ frameSize: 960, channels: 2, rate: 48000 });
 * input.pipe(decoder);
 * // decoder will now output PCM audio
 */
declare class OpusDecoder extends OpusStream {
    _transform(chunk: Buffer, encoding: BufferEncoding, done: (e?: Error | null, chunk?: Buffer) => void): void;
}

declare class WebmBaseDemuxer extends Transform {
    static readonly TAGS: {
        '1a45dfa3': boolean;
        '18538067': boolean;
        '1f43b675': boolean;
        '1654ae6b': boolean;
        ae: boolean;
        d7: boolean;
        '83': boolean;
        a3: boolean;
        '63a2': boolean;
    };
    static readonly TOO_SHORT: unique symbol;
    private _remainder;
    private _length;
    private _count;
    private _skipUntil;
    private _track;
    private _incompleteTrack;
    private _ebmlFound;
    /**
     * Creates a new Webm demuxer.
     * @param {Object} [options] options that you would pass to a regular Transform stream.
     */
    constructor(options?: {});
    _checkHead(data: Buffer): void;
    _transform(chunk: Buffer, encoding: BufferEncoding, done: TransformCallback): void;
    /**
     * Reads an EBML ID from a buffer.
     * @private
     * @param {Buffer} chunk the buffer to read from.
     * @param {number} offset the offset in the buffer.
     * @returns {Object|Symbol} contains an `id` property (buffer) and the new `offset` (number).
     * Returns the TOO_SHORT symbol if the data wasn't big enough to facilitate the request.
     */
    _readEBMLId(chunk: Buffer, offset: number): typeof WebmBaseDemuxer.TOO_SHORT | {
        id: Buffer;
        offset: number;
    };
    /**
     * Reads a size variable-integer to calculate the length of the data of a tag.
     * @private
     * @param {Buffer} chunk the buffer to read from.
     * @param {number} offset the offset in the buffer.
     * @returns {Object|Symbol} contains property `offset` (number), `dataLength` (number) and `sizeLength` (number).
     * Returns the TOO_SHORT symbol if the data wasn't big enough to facilitate the request.
     */
    _readTagDataSize(chunk: Buffer, offset: number): typeof WebmBaseDemuxer.TOO_SHORT | {
        offset: number;
        dataLength: number | symbol;
        sizeLength: number;
    };
    /**
     * Takes a buffer and attempts to read and process a tag.
     * @private
     * @param {Buffer} chunk the buffer to read from.
     * @param {number} offset the offset in the buffer.
     * @returns {Object|Symbol} contains the new `offset` (number) and optionally the `_skipUntil` property,
     * indicating that the stream should ignore any data until a certain length is reached.
     * Returns the TOO_SHORT symbol if the data wasn't big enough to facilitate the request.
     */
    _readTag(chunk: Buffer, offset: number): typeof WebmBaseDemuxer.TOO_SHORT | {
        offset: number;
        _skipUntil?: undefined;
    } | {
        offset: number;
        _skipUntil: number;
    };
    _destroy(err: Error, cb: (error: Error | null) => void): void;
    _final(cb: TransformCallback): void;
    /**
     * Cleans up the demuxer when it is no longer required.
     * @private
     */
    _cleanup(): void;
}

/**
 * Demuxes a Webm stream (containing Opus audio) to output an Opus stream.
 * @example
 * const fs = require('fs');
 * const file = fs.createReadStream('./audio.webm');
 * const demuxer = new WebmDemuxer();
 * const opus = file.pipe(demuxer);
 * // opus is now a ReadableStream in object mode outputting Opus packets
 */
declare class WebmDemuxer extends WebmBaseDemuxer {
    _checkHead(data: Buffer): void;
}

declare const version: string;

export { CTL, type IEncoder, type IOpusStreamInit, OggDemuxer, OpusDecoder, OpusEncoder, OpusStream, WebmDemuxer, addLibopusProvider, removeLibopusProvider, setLibopusProvider, version };
