import { Flame } from '../generated/driveningress/v1/driveningress';
import { Avatar } from './Avatar';
import { AnimationPlayer } from '../audio/AnimationPlayer';
import { AvatarState, ConnectionState, DrivingServiceMode, ConversationState } from '../types';
export declare class AvatarController {
    private networkLayer?;
    private readonly playbackMode;
    protected avatar: Avatar;
    protected animationPlayer: AnimationPlayer | null;
    protected currentKeyframes: Flame[];
    protected pendingAudioChunks: Array<{
        data: Uint8Array;
        isLast: boolean;
    }>;
    protected isPlaying: boolean;
    protected isConnected: boolean;
    protected currentState: AvatarState;
    private currentConversationId;
    private reqEnd;
    onConnectionState: ((state: ConnectionState) => void) | null;
    onConversationState: ((state: ConversationState) => void) | null;
    onError: ((error: Error) => void) | null;
    private eventListeners;
    private renderCallback?;
    private characterHandle;
    private playbackLoopId;
    private lastRenderedFrameIndex;
    private keyframesOffset;
    private readonly MAX_KEYFRAMES;
    private readonly KEYFRAMES_CLEANUP_THRESHOLD;
    private readonly MAX_PENDING_AUDIO_CHUNKS;
    private isAudioOnlyMode;
    constructor(avatar: Avatar, options?: {
        playbackMode?: DrivingServiceMode;
    });
    /**
     * Get current conversation ID
     * Returns the current conversation ID for the active audio session
     * @returns Current conversation ID, or null if no active session
     */
    getCurrentConversationId(): string | null;
    /**
     * Start service (SDK mode only)
     */
    start(): Promise<void>;
    /**
     * Send audio to server (SDK mode only)
     * Also cache to data layer for playback
     * @returns conversationId - Conversation ID for this audio session
     */
    send(audioData: ArrayBuffer, end?: boolean): string | null;
    /**
     * Close service (SDK mode only)
     */
    close(): void;
    /**
     * Playback existing audio and animation data (host mode)
     * Starts a new conversation by generating a new conversation ID and interrupting any existing conversation
     * @param initialAudioChunks - Existing audio chunks to playback
     * @param initialKeyframes - Existing animation keyframes to playback
     * @returns conversationId - New conversation ID for this conversation session
     */
    playback(initialAudioChunks?: Array<{
        data: Uint8Array;
        isLast: boolean;
    }>, initialKeyframes?: Flame[]): Promise<string>;
    /**
     * Send audio data (host mode)
     * Stream additional audio data after playback()
     * @returns conversationId - Conversation ID for this audio session
     */
    yieldAudioData(data: Uint8Array, isLast?: boolean): string | null;
    /**
     * Send animation keyframes (host mode or SDK mode)
     * Stream additional animation data after playback()
     * @param keyframes - Animation keyframes to send
     * @param conversationId - Conversation ID (required). If conversationId doesn't match current conversationId, keyframes will be discarded.
     *                Use getCurrentConversationId() to get the current conversationId.
     */
    yieldFramesData(keyframes: Flame[], conversationId: string): void;
    /**
     * Pause playback (can be resumed later)
     * Pause audio playback and stop render loop, but preserve all state (keyframes, audio buffers, etc.)
     */
    pause(): void;
    /**
     * Resume playback (from paused state)
     * Resume audio playback and restart render loop
     * Animation will continue from paused frame (because animation time base comes from audio, will auto-sync)
     */
    resume(): Promise<void>;
    /**
     * Interrupt current playback
     */
    interrupt(): void;
    /**
     * Clear all data and resources
     */
    clear(): void;
    /**
     * Generate new conversation ID and log conversation started event
     * @private
     */
    private generateAndLogNewConversationId;
    /**
     * Clear playback data (keyframes, audio chunks, and playback state)
     * @private
     */
    private clearPlaybackData;
    /**
     * Reset conversation ID state (for both network and external modes)
     * @private
     */
    private resetConversationIdState;
    /**
     * Get effective conversation ID (handles both SDK and host modes)
     * @private
     */
    private getEffectiveConversationId;
    /**
     * 设置音频播放音量
     * 注意：这仅控制数字人音频播放器的音量，不影响系统音量
     * @param volume 音量值，范围 0.0 到 1.0（0.0 为静音，1.0 为最大音量）
     */
    setVolume(volume: number): void;
    /**
     * 获取当前音频播放音量
     * @returns 当前音量值 (0.0 - 1.0)
     */
    getVolume(): number;
    /**
     * Start streaming playback (internal implementation)
     */
    private startStreamingPlaybackInternal;
    /**
     * Playback loop: Calculate animation frame based on audio time, notify render layer to render
     */
    private startPlaybackLoop;
    /**
     * Stop playback loop
     */
    private stopPlaybackLoop;
    /**
     * 启用音频独立播放模式（当服务器错误或超时时调用）
     * 此模式下，音频会独立播放，不依赖动画数据
     * 一旦启用，本次会话后续的动画数据将被忽略
     * @private
     */
    private enableAudioOnlyMode;
    /**
     * 音频独立播放（完全独立的逻辑，不影响正常播放流程）
     * @private
     */
    private startAudioOnlyPlayback;
    /**
     * 音频监控循环（仅用于音频独立模式）
     * 只检测音频是否结束，不进行动画渲染
     * @private
     */
    private startAudioMonitoringLoop;
    /**
     * Stop playback
     */
    protected stopPlayback(): void;
    /**
     * Clean up players
     */
    protected cleanupPlayers(): void;
    /**
     * Add audio chunk to buffer
     */
    private addAudioChunkToBuffer;
    /**
     * Event system
     */
    private registerEventListener;
    /**
     * Emit event
     */
    protected emit(event: string, data?: any): void;
}
//# sourceMappingURL=AvatarController.d.ts.map