import type { AudioFrame } from '@livekit/rtc-node';
import { type StreamChannel } from '../../stream/stream_channel.js';
import { AudioOutput } from '../io.js';
/**
 * Sentinel value pushed onto the {@link QueueAudioOutput} stream when a segment of agent
 * speech has finished (i.e. `flush()` was called). Consumers should treat it as an
 * end-of-segment marker and emit the corresponding "speech ended" signal on their
 * downstream protocol (websocket, RPC, etc.).
 *
 * Ref: python livekit-agents/livekit/agents/voice/avatar/_types.py (AudioSegmentEnd)
 */
export declare class AudioSegmentEnd {
}
/**
 * One value emitted by {@link QueueAudioOutput.stream}: either an {@link AudioFrame}
 * or an {@link AudioSegmentEnd} sentinel marking the end of a speech segment.
 */
export type QueueAudioOutputItem = AudioFrame | AudioSegmentEnd;
/**
 * Payload emitted with the {@link QueueAudioOutput} `'clear_buffer'` event.
 *
 * `wasCapturing` is set synchronously inside {@link QueueAudioOutput.clearBuffer}
 * based on whether {@link QueueAudioOutput.captureFrame} had been called for the
 * current segment. Consumers should use this — not their own asynchronous
 * "is the avatar speaking?" flag — to decide whether to call
 * {@link QueueAudioOutput.notifyPlaybackFinished}, otherwise an interrupt that
 * lands in the window between `captureFrame` and the consumer's reader can leak
 * `playbackSegmentsCount > playbackFinishedCount` and deadlock
 * {@link AudioOutput.waitForPlayout}.
 */
export interface QueueAudioOutputClearEvent {
    wasCapturing: boolean;
}
/**
 * AudioOutput implementation that buffers agent speech frames into a stream/queue so
 * they can be consumed by an external transport (e.g. a custom websocket protocol used
 * by an avatar plugin). Frames captured via {@link captureFrame} flow through the
 * underlying stream as-is; on {@link flush} an {@link AudioSegmentEnd} sentinel is
 * appended; on {@link clearBuffer} a `'clear_buffer'` event is emitted with a
 * {@link QueueAudioOutputClearEvent} payload so the consumer can drop any in-flight
 * bytes and notify upstream of an interruption.
 *
 * Mirrors Python's `livekit.agents.voice.avatar.QueueAudioOutput`.
 *
 * Ref: python livekit-agents/livekit/agents/voice/avatar/_queue_io.py
 */
export declare class QueueAudioOutput extends AudioOutput {
    private readonly channel;
    private startedSegment;
    constructor(sampleRate?: number);
    /**
     * Returns the underlying readable stream of audio frames + end-of-segment sentinels.
     *
     * Each call returns the same shared stream; do not split between concurrent readers.
     */
    stream(): ReturnType<StreamChannel<QueueAudioOutputItem>['stream']>;
    /** True once {@link aclose} has been called. */
    get closed(): boolean;
    captureFrame(frame: AudioFrame): Promise<void>;
    flush(): void;
    clearBuffer(): void;
    /** Close the underlying stream so consumers see a graceful end-of-stream. */
    aclose(): Promise<void>;
    /**
     * Convenience wrapper around {@link AudioOutput.onPlaybackStarted} so a remote
     * transport can announce "first byte played" without needing access to the
     * protected method.
     */
    notifyPlaybackStarted(createdAt?: number): void;
    /**
     * Convenience wrapper around {@link AudioOutput.onPlaybackFinished} so a remote
     * transport can announce segment completion (or interruption) without needing
     * access to the protected method.
     */
    notifyPlaybackFinished(playbackPosition: number, interrupted: boolean): void;
}
//# sourceMappingURL=queue_io.d.ts.map