import { RetryConfiguration, TurnServerConfigWithMode, UID, Candidate, Setup, PayloadAttribute, Extmap, FingerPrint, EventEmitter, PromiseMutex, SDKStore, SDK_CODEC, AgoraPCStats, NetworkQuality as NetworkQuality$1, AgoraVideoReceiverStats, WebSocketQuitReason, ConnectionDisconnectedReason } from '@agora-js/shared';
import { IRemoteAudioTrack, IRemoteVideoTrack, IRemoteDataChannel, RemoteAudioTrack, RemoteVideoTrack, RemoteDataChannel, LocalTrack, LocalDataChannel, LowStreamParameter, AudioMetadata, VideoEncoderConfiguration, AudioEncoderConfiguration, MediaStats, LocalAudioTrackStats, LocalVideoTrackStats, RemoteAudioTrackStats, RemoteVideoTrackStats, AgoraRTCStats } from '@agora-js/media';

interface SignalSpec {
    clientId: string;
    retryConfig: RetryConfiguration;
    forceWaitGatewayResponse: boolean;
}
declare enum SignalConnectionState {
    CONNECTING = "connecting",
    CONNECTED = "connected",
    RECONNECTING = "reconnecting",
    CLOSED = "closed"
}
declare enum SignalRequestType {
    PING = "ping",
    PING_BACK = "ping_back",
    JOIN = "join_v3",
    REJOIN = "rejoin_v3",
    LEAVE = "leave",
    SET_CLIENT_ROLE = "set_client_role",
    PUBLISH = "publish",
    PUBLISH_DATASTREAM = "publish_datastream",
    UNPUBLISH = "unpublish",
    UNPUBLISH_DATASTREAM = "unpublish_datastream",
    SUBSCRIBE = "subscribe",
    PRE_SUBSCRIBE = "pre_subscribe",
    SUBSCRIBE_DATASTREAM = "subscribe_datastream",
    SUBSCRIBE_STREAMS = "subscribe_streams",
    UNSUBSCRIBE = "unsubscribe",
    UNSUBSCRIBE_DATASTREAM = "unsubscribe_datastream",
    UNSUBSCRIBE_STREAMS = "unsubscribe_streams",
    SUBSCRIBE_CHANGE = "subscribe_change",
    TRAFFIC_STATS = "traffic_stats",
    RENEW_TOKEN = "renew_token",
    SWITCH_VIDEO_STREAM = "switch_video_stream",
    DEFAULT_VIDEO_STREAM = "default_video_stream",
    SET_FALLBACK_OPTION = "set_fallback_option",
    GATEWAY_INFO = "gateway_info",
    CONTROL = "control",
    SEND_METADATA = "send_metadata",
    DATA_STREAM = "data_stream",
    PICK_SVC_LAYER = "pick_svc_layer",
    RESTART_ICE = "restart_ice",
    CONNECT_PC = "connect_pc",
    SET_VIDEO_PROFILE = "set_video_profile",
    SET_PARAMETER = "set_parameter",
    SET_RTM2_FLAG = "set_rtm2_flag"
}
declare enum SignalUploadType {
    WRTC_STATS = "wrtc_stats",
    WS_INFLATE_DATA_LENGTH = "ws_inflate_data_length",
    DENOISER_STATS = "denoiser_stats",
    EXTENSION_USAGE_STATS = "extension_usage_stats"
}
declare enum SignalNotifyType {
    ON_USER_ONLINE = "on_user_online",
    ON_USER_OFFLINE = "on_user_offline",
    ON_STREAM_FALLBACK_UPDATE = "on_stream_fallback_update",
    ON_PUBLISH_STREAM = "on_publish_stream",
    ON_UPLINK_STATS = "on_uplink_stats",
    ON_P2P_LOST = "on_p2p_lost",
    ON_REMOVE_STREAM = "on_remove_stream",
    ON_ADD_AUDIO_STREAM = "on_add_audio_stream",
    ON_ADD_VIDEO_STREAM = "on_add_video_stream",
    ON_TOKEN_PRIVILEGE_WILL_EXPIRE = "on_token_privilege_will_expire",
    ON_TOKEN_PRIVILEGE_DID_EXPIRE = "on_token_privilege_did_expire",
    ON_USER_BANNED = "on_user_banned",
    ON_USER_LICENSE_BANNED = "on_user_license_banned",
    ON_NOTIFICATION = "on_notification",
    ON_CRYPT_ERROR = "on_crypt_error",
    MUTE_AUDIO = "mute_audio",
    MUTE_VIDEO = "mute_video",
    UNMUTE_AUDIO = "unmute_audio",
    UNMUTE_VIDEO = "unmute_video",
    ON_P2P_OK = "on_p2p_ok",
    RECEIVE_METADATA = "receive_metadata",
    ON_DATA_STREAM = "on_data_stream",
    ON_RTP_CAPABILITY_CHANGE = "on_rtp_capability_change",
    ON_REMOTE_DATASTREAM_UPDATE = "on_remote_datastream_update",
    ON_REMOTE_FULL_DATASTREAM_INFO = "on_remote_full_datastream_info",
    ENABLE_LOCAL_VIDEO = "enable_local_video",
    DISABLE_LOCAL_VIDEO = "disable_local_video",
    ENABLE_LOCAL_AUDIO = "enable_local_audio",
    DISABLE_LOCAL_AUDIO = "disable_local_audio",
    ON_PUBLISHED_USER_LIST = "on_published_user_list"
}

interface PeerConnectionSpec {
    iceServers?: RTCIceServer[];
    turnServer?: TurnServerConfigWithMode;
    enableEncodedTransform?: boolean;
}
declare enum P2PConnectionDirection {
    SEND_ONLY = "SEND_ONLY",
    RECEIVE_ONLY = "RECEIVE_ONLY"
}

type WebSocketConnectionState = "connected" | "connecting" | "reconnecting" | "closed" | "failed";
type ReconnectMode = "retry" | "tryNext" | "recover";

/**
 * Information about a remote user. You can get this through [AgoraRTCClient.remoteUsers]{@link IAgoraRTCClient.remoteUsers}.
 */
interface IAgoraRTCRemoteUser {
    /**
     * The ID of the remote user.
     */
    uid: UID;
    /**
     * The subscribed audio track.
     */
    audioTrack?: IRemoteAudioTrack;
    /**
     * The subscribed video track.
     */
    videoTrack?: IRemoteVideoTrack;
    /**
     * Whether the remote user is sending an audio track.
     * - `true`: The remote user is sending an audio track.
     * - `false`: The remote user is not sending an audio track.
     */
    hasAudio: boolean;
    /**
     * Whether the remote user is sending a video track.
     * - `true`: The remote user is sending an audio track.
     * - `false`: The remote user is not sending an audio track.
     */
    hasVideo: boolean;
    /**
    * @ignore
    */
    dataChannels?: IRemoteDataChannel[];
}

declare class AgoraRTCRemoteUser implements IAgoraRTCRemoteUser {
    uid: UID;
    _uintid: number;
    _trust_audio_enabled_state_: boolean;
    _trust_video_enabled_state_: boolean;
    _trust_audio_mute_state_: boolean;
    _trust_video_mute_state_: boolean;
    _audio_muted_: boolean;
    _video_muted_: boolean;
    _audio_enabled_: boolean;
    _video_enabled_: boolean;
    _audio_added_: boolean;
    _video_added_: boolean;
    _is_pre_created: boolean;
    _video_pre_subscribed: boolean;
    _audio_pre_subscribed: boolean;
    _trust_video_stream_added_state_: boolean;
    _trust_audio_stream_added_state_: boolean;
    get hasVideo(): boolean;
    get hasAudio(): boolean;
    get audioTrack(): undefined | RemoteAudioTrack;
    get videoTrack(): undefined | RemoteVideoTrack;
    get dataChannels(): RemoteDataChannel[];
    constructor(uid: UID, uintid: number);
}

interface ConfigDistributeLimitBitrate {
    uplink: {
        max_bitrate: number;
        min_bitrate: number;
    };
    low_stream_uplink?: {
        bitrate: number;
    };
    id: number;
}

declare enum LocalTrackType {
    LocalVideoTrack = "videoTrack",
    LocalAudioTrack = "audioTrack",
    LocalVideoLowTrack = "videoLowTrack"
}
interface LocalTrackStruct {
    track: LocalTrack;
    id: string;
    ssrcs: SSRCMessage;
}
type PublishMessage = {
    stream_type: PubStreamType;
    attributes: Record<string, any>;
    ssrcs: SSRCMessage;
}[];
type UnPublishMessage = {
    stream_type: PubStreamType;
    ssrcs: SSRCMessage;
}[];
type PublishAnswer = {
    ssrcs: SSRCMessage;
    stream_type: PubStreamType;
    attributes?: RemoteConfig;
}[];
type SubscribeOrtc = {
    ssrcs: SSRCMessage;
    stream_type: Kind;
    attributes?: RemoteConfig;
}[];
type UnsubscribeMessage = {
    stream_type: Kind;
    ssrcId: number;
}[];
type MassUnsubscribeMessage = {
    users: {
        stream_id: UID;
        stream_type: MediaTypeMask;
    }[];
};
interface RemoteConfig {
    tcc?: boolean;
    remb?: boolean;
    twcc?: boolean;
}
type NetworkQuality = 0 | 1 | 2 | 3 | 4 | 5;
type MassUnsubscribeParams = {
    user: AgoraRTCRemoteUser;
    mediaType?: Kind;
};

interface RTPCapabilities {
    audioCodecs: PayloadAttribute[];
    videoCodecs: PayloadAttribute[];
    audioExtensions: Extmap[];
    videoExtensions: Extmap[];
}
interface ICEParameters {
    iceUfrag: string;
    icePwd: string;
}
interface DtlsParameters {
    fingerprints: FingerPrint[];
}
declare enum Kind {
    VIDEO = "video",
    AUDIO = "audio"
}
declare enum ICERestartType {
    UDP_RELAY = "udp_relay",
    UDP_TCP_RELAY = "udp_tcp_relay",
    TCP_RELAY = "tcp_relay",
    RELAY = "relay"
}
type EstablishParams = {
    iceParameters: ICEParameters;
    dtlsParameters: DtlsParameters;
    rtpCapabilities: RTPCapabilitiesBeforeMerge;
    offerSDP?: string;
};
type ConnectionParams = {
    iceParameters: ICEParameters;
    dtlsParameters: DtlsParameters;
    candidates: Candidate[];
    rtpCapabilities: RTPCapabilitiesWithDirection;
    setup: Setup;
    cname: string;
    preallocation?: boolean;
    preSSRCs?: PreSSRCMessage[];
};
type SSRCMessage = {
    ssrcId: number;
    rtx?: number;
}[];
type PreSSRCMessage = {
    kind: Kind;
    ssrcId: number;
    mslabel: string;
    rtx?: number;
};
interface RTPCapabilitiesWithDirection {
    send: RTPCapabilities;
    recv: RTPCapabilities;
}
interface RTPCapabilitiesBeforeMerge extends Partial<RTPCapabilitiesWithDirection> {
    sendrecv?: RTPCapabilities;
}

type Transmission = WebSocket | RTCDataChannel;

interface TransmissonInfo {
    transmitter: Transmission;
    close: () => void;
}

declare enum ExternalSignalRequestType {
    CALL = "call",
    CANDIDATE = "candidate",
    PUBLISH = "publish",
    UNPUBLISH = "unpublish",
    CONTROL = "control",
    RESTART_ICE = "restart_ice",
    ACK = "ack",
    RESPONSE = "response",
    JOIN = "join",
    CHECK = "check"
}

declare class P2PChannel extends EventEmitter {
    readonly isPlanB: any;
    private readonly store;
    private statsUploader;
    private connection?;
    private localTrackMap;
    private remoteUserMap;
    private localDataChannels;
    private remoteDataChannelMap;
    private pendingLocalTracks;
    private pendingRemoteTracks;
    private pendingLocalDataChannels;
    private pendingRemoteDataChannels;
    private readonly statsCollector;
    private shouldForwardP2PCreation;
    private iceFailedCount;
    private dtlsFailedCount;
    protected mutex: PromiseMutex;
    private _state;
    private _pcStatsUploadType;
    private _isStartRestartIce;
    private _restartTimer;
    private _isTryConnecting;
    private _iceError;
    private _forceTurn;
    private _isWaitPcToRePub;
    private get state();
    private set state(value);
    constructor(store: SDKStore, statsCollector: AgoraRTCStatsCollector);
    startP2PConnection(spec: PeerConnectionSpec): Promise<EstablishParams>;
    connect(connectParams: ConnectionParams): Promise<void>;
    updateRemoteRTPCapabilities(codecs: SDK_CODEC[]): void;
    getEstablishParams(): Promise<EstablishParams | void>;
    publishDataChannel(datachannels: LocalDataChannel[]): Promise<PublishDataChannelOptions[]>;
    publish(localTracks: LocalTrack[], enableVideoDualStream?: boolean, lowStreamParameter?: LowStreamParameter): AsyncGenerator<PublishMessage | undefined, void, PublishAnswer>;
    private doPublish;
    updateVideoStreamParameter(parameter: LowStreamParameter, type: Exclude<LocalTrackType, LocalTrackType.LocalAudioTrack>): Promise<void>;
    publishLowStream(lowStreamParameter: LowStreamParameter | undefined): AsyncGenerator<PublishMessage | undefined, void, PublishAnswer>;
    republish(): Promise<void>;
    reSubscribe(needSignal?: boolean): Promise<void>;
    unpublish(tracks: LocalTrack[]): Promise<UnPublishMessage | undefined>;
    unpublishDataChannel(dataChannels: LocalDataChannel[]): Promise<number[] | void>;
    unpublishLowStream(): Promise<UnPublishMessage | undefined>;
    private doUnpublish;
    subscribeDataChannel(user: AgoraRTCRemoteUser, remoteDataChannels: RemoteDataChannel[]): Promise<number[] | void>;
    subscribe(user: AgoraRTCRemoteUser, mediaType: Kind, ssrcId: number, rtxSsrcId?: number, subOrtc?: SubscribeOrtc): Promise<void>;
    massSubscribe(subscribeList: {
        user: AgoraRTCRemoteUser;
        mediaType: Kind;
        ssrcId: number;
        rtxSsrcId?: number;
    }[]): Promise<void>;
    massSubscribeNoLock(subscribeList: {
        user: AgoraRTCRemoteUser;
        mediaType: Kind;
        ssrcId: number;
        rtxSsrcId?: number;
    }[]): Promise<void>;
    unsubscribe(user: AgoraRTCRemoteUser, mediaType?: Kind, reserveTrack?: boolean): Promise<UnsubscribeMessage | undefined>;
    unsubscribeDataChannel(user: AgoraRTCRemoteUser, remoteDataChannels: RemoteDataChannel[]): Promise<number[] | undefined>;
    massUnsubscribe(unsubscribeList: MassUnsubscribeParams[]): Promise<MassUnsubscribeMessage | undefined>;
    massUnsubscribeNoLock(unsubscribeList: MassUnsubscribeParams[]): Promise<MassUnsubscribeMessage | undefined>;
    isPreSubScribe(ssrcId: number): boolean;
    muteRemote(user: AgoraRTCRemoteUser, kind: Kind): Promise<void>;
    unmuteRemote(user: AgoraRTCRemoteUser, kind: Kind): Promise<void>;
    unmuteRemoteNoLock(user: AgoraRTCRemoteUser, kind: Kind): Promise<void>;
    addAudioMetadata(metadata: AudioMetadata): void;
    getAllTracks(filterLowVideoTrack?: boolean): LocalTrack[];
    getAllDataChannels(): LocalDataChannel[];
    reportPublishEvent(succ: boolean, ec: string | null, failedTracks?: LocalTrack[], isLowStream?: boolean, extend?: string): void;
    reportSubscribeEvent(succ: boolean, ec: string | null, user: AgoraRTCRemoteUser, mediaType: Kind): void;
    reset(): void;
    getStats(): AgoraPCStats | undefined;
    getRemoteVideoIsReady(ssrcId: number): boolean;
    getLocalAudioVolume(): number | undefined;
    getLocalVideoSize(): {
        width: number;
        height: number;
    } | undefined;
    getEncoderConfig(type: LocalTrackType): VideoEncoderConfiguration | AudioEncoderConfiguration | undefined;
    getLocalMedia(type: LocalTrackType): LocalTrackStruct | undefined;
    hasLocalMedia(): boolean;
    hasRemoteMedia(user?: AgoraRTCRemoteUser, kind?: Kind): boolean;
    hasRemoteMediaWithLock(user?: AgoraRTCRemoteUser, kind?: Kind): Promise<boolean>;
    getRemoteMedia(uid: UID): {
        audioTrack?: RemoteAudioTrack;
        videoTrack?: RemoteVideoTrack;
        audioSSRC?: number;
        videoSSRC?: number;
    };
    getAudioLevels(): {
        uid: UID;
        level: number;
    }[];
    disconnectForReconnect(): Promise<void>;
    hasPendingRemoteDataChannel(remoteUser: AgoraRTCRemoteUser | UID, streamId: number): boolean;
    setPendingRemoteDataChannel(remoteUser: AgoraRTCRemoteUser, id: number): void;
    hasPendingRemoteMedia(remoteUser: AgoraRTCRemoteUser | UID, mediaType: string): boolean;
    setPendingRemoteMedia(remoteUser: AgoraRTCRemoteUser, mediaType: Kind): void;
    restartICE(type?: ICERestartType): AsyncGenerator<ICEParameters, void, {
        remoteIceParameters: ICEParameters;
    }>;
    getUplinkNetworkQuality(): 0 | 1 | 2 | 3 | 4 | 5;
    getDownlinkNetworkQuality(): 0 | 1 | 2 | 3 | 4 | 5;
    muteLocalTrack(track: LocalTrack): Promise<void>;
    private handleMuteLocalTrack;
    private handleUnmuteLocalTrack;
    private handleUpdateVideoEncoder;
    private handleUpdateVideoSendParameters;
    private handleReplaceMixingTrack;
    private handleReplaceTrack;
    private replaceTrack;
    private filterTobePublishedTracks;
    private filterTobeUnpublishedTracks;
    private filterTobePublishedDataChannels;
    private filterTobeUnpublishedDataChannels;
    private bindLocalTrackEvents;
    private bindLocalAudioTrackEvents;
    private unbindLocalTrackEvents;
    private unbindLocalAudioTrackEvents;
    private bindRemoteTrackEvents;
    private unbindRemoteTrackEvents;
    private unbindAllRemoteTrackEvents;
    private createGatewayPublishMessage;
    private createGatewayUnpublishMessage;
    private assignLocalTracks;
    private withdrawLocalTracks;
    private bindConnectionEvents;
    private resetConnection;
    private filterTobeMutedTracks;
    private filterTobeUnmutedTracks;
    private createMuteMessage;
    private createUnmuteMessage;
    private filterTobeUnSubscribedTracks;
    private filterTobeUnSubscribedDataChannels;
    private createUnsubscribeMessage;
    private createUnsubscribeAllMessage;
    private withdrawRemoteTracks;
    updateBitrateLimit(bitrateLimit: ConfigDistributeLimitBitrate): Promise<void>;
    private handleGetRTCStats;
    private handleGetLocalVideoStats;
    private handleGetLocalAudioStats;
    private handleGetRemoteVideoStats;
    private handleGetRemoteAudioStats;
    isP2PDisconnected(): boolean;
    private mapPubResToRemoteConfig;
    private tryToUnmuteAudio;
    private bindStatsUploaderEvents;
    private unbindStatsUploaderEvents;
    requestReconnect(): Promise<void>;
    reconnectP2P(): Promise<void>;
    canPublishLowStream(): boolean;
    private throwIfTrackTypeNotMatch;
    private getLowVideoTrack;
    globalLock(): Promise<() => void>;
    private reportPCStats;
    private reportVideoFirstFrameDecoded;
    remoteMediaSsrcChanged(user: AgoraRTCRemoteUser, mediaType: Kind, ssrcId: number): Promise<boolean>;
    private unbindRtpTransceiver;
}

declare class AgoraRTCStatsCollector {
    private store;
    onStatsException?: (code: number, message: string, uid: UID) => void;
    onUploadPublishDuration?: (peer: UID, audioDuration: number, videoDuration: number, subscribeElapse: number) => void;
    onStatsChanged?: <K extends keyof MediaStats>(key: K, value: MediaStats[K]) => void;
    onVideoCodecChanged?: (codec: string) => void;
    private localStats;
    private remoteStats;
    private updateStatsInterval?;
    trafficStats?: GatewayTrafficStats;
    private trafficStatsPeerList;
    private uplinkStats?;
    private exceptionMonitor;
    private p2pChannel?;
    private scalabilityMode;
    constructor(store: SDKStore);
    startUpdateStats(): void;
    stopUpdateStats(): void;
    reset(): void;
    getLocalAudioTrackStats(): LocalAudioTrackStats;
    getLocalVideoTrackStats(): LocalVideoTrackStats;
    getRemoteAudioTrackStats(uid?: UID): {
        [uid: string]: RemoteAudioTrackStats;
    };
    getRemoteNetworkQualityStats(uid?: UID): {
        [uid: string]: NetworkQuality$1;
    };
    getRemoteVideoTrackStats(uid?: UID): {
        [uid: string]: RemoteVideoTrackStats;
    };
    getRTCStats(): AgoraRTCStats;
    addLocalStats(type: LocalTrackType): void;
    removeLocalStats(type?: LocalTrackType): void;
    addRemoteStats(uid: UID): void;
    removeRemoteStats(uid?: UID): void;
    addP2PChannel(p2pChannel: P2PChannel): void;
    updateTrafficStats(stats: GatewayTrafficStats): void;
    updateUplinkStats(stats: GatewayUplinkStats): void;
    private updateStats;
    static isRemoteVideoFreeze(track: RemoteVideoTrack | undefined, stats: AgoraVideoReceiverStats, lastStats?: AgoraVideoReceiverStats): boolean;
    static isRemoteAudioFreeze(track?: RemoteAudioTrack): boolean;
    private isLocalVideoFreeze;
    private updateLocalStats;
    private updateRemoteStats;
}

declare enum PubStreamType {
    High = "high",
    Low = "low",
    Audio = "audio",
    Screen = "screen",
    ScreenLow = "screen_low"
}
interface PublishDataChannelOptions {
    streamId: number;
    ordered: boolean;
    maxRetransmits: number | null;
    metadata: string;
    channelId: number;
}
interface GatewayTrafficStats {
    B_acd: number;
    B_dnq: number;
    B_palr4: number;
    B_pvlr4: number;
    B_unq: number;
    ntp_offset?: number;
    peer_delay: {
        B_ad: number;
        B_deb: number;
        B_ealr4: number;
        B_ed: number;
        B_evlr4: number;
        B_st: number;
        B_vd: number;
        B_ppad: number;
        B_ppvd: number;
        B_punq: 0 | 1 | 2 | 3 | 4 | 5;
        B_pdnq: 0 | 1 | 2 | 3 | 4 | 5;
        peer_uid: UID;
    }[];
    timestamp: number;
}
interface GatewayUplinkStats {
    B_uab: number;
    B_ucl: number;
    B_ufl: number;
    B_fir: boolean;
}
declare enum MediaTypeMask {
    Nothing = 0,
    Audio = 1,
    LwoVideo = 2,
    Video = 4,
    Data = 8,
    DataStream0 = 256,
    DataStream1 = 512,
    DataStream2 = 1024,
    DataStream3 = 2048,
    DataStream4 = 4096,
    DataStream5 = 8192,
    DataStream6 = 16384,
    DataStream7 = 32768
}

type P2PPublishMessage = {
    kind: Kind;
    stream_type: PubStreamType;
    mid: string;
    ssrcs: SSRCMessage;
    isMuted?: boolean;
}[];
interface ConnectionParameters {
    iceParameters: ICEParameters;
    dtlsParameters: DtlsParameters;
}
type P2PEstablishParams = {
    sdp: string;
} & ConnectionParameters;

declare class P2PChannel2 extends EventEmitter {
    readonly isPlanB = false;
    private readonly store;
    private statsUploader;
    private sendConnection?;
    private recvConnection?;
    private localTrackMap;
    private remoteUserMap;
    private localDataChannels;
    private pendingLocalTracks;
    private pendingRemoteTracks;
    private readonly statsCollector;
    private dtlsFailedCount;
    protected sendMutex: PromiseMutex;
    protected recvMutex: PromiseMutex;
    private _state;
    private _restartStates;
    private reconnectInterval;
    private uploadUnplinkStarted;
    private uploadDownlinkStarted;
    private uplinkStateUploadInterval?;
    private downlinkStatsUploadInterval?;
    private get state();
    private set state(value);
    constructor(store: SDKStore, statsCollector: AgoraRTCStatsCollector);
    startP2PConnection(spec: PeerConnectionSpec, isDataChannel?: boolean): Promise<EstablishParams>;
    connect(connectParams: ConnectionParams): Promise<void>;
    startP2P(spec: PeerConnectionSpec, establishParams?: P2PEstablishParams): Promise<P2PEstablishParams>;
    p2pConnect(establishParams: P2PEstablishParams): Promise<void>;
    addRemoteCandidate(candidate: RTCIceCandidateInit, direction: P2PConnectionDirection): Promise<void>;
    publish(localTracks: LocalTrack[], enableVideoDualStream?: boolean, lowStreamParameter?: LowStreamParameter): AsyncGenerator<P2PPublishMessage>;
    unpublish(tracks: LocalTrack[]): Promise<UnPublishMessage | void>;
    private startUploadUplinkState;
    private stopUploadUplinkState;
    publishLowStream(lowStreamParameter: LowStreamParameter | undefined): AsyncGenerator<PublishMessage | undefined, void, PublishAnswer>;
    republish(): Promise<void>;
    unpublishLowStream(): Promise<UnPublishMessage | undefined>;
    subscribe(user: AgoraRTCRemoteUser, mediaType: Kind, ssrcId: number, mid: string): Promise<string | void>;
    mockSubscribe(user: AgoraRTCRemoteUser, mediaType: Kind, ssrcId: number, mid: string): Promise<string | void>;
    unsubscribe(user: AgoraRTCRemoteUser, mediaType?: Kind, reserveTrack?: boolean): Promise<void>;
    private startUploadDownlinkState;
    private stopUploadDownlinkState;
    getAllDataChannels(): LocalDataChannel[];
    massSubscribe(subscribeList: {
        user: AgoraRTCRemoteUser;
        mediaType: Kind;
        ssrcId: number;
        rtxSsrcId?: number;
    }[]): Promise<void>;
    massSubscribeNoLock(subscribeList: {
        user: AgoraRTCRemoteUser;
        mediaType: Kind;
        ssrcId: number;
        rtxSsrcId?: number;
    }[]): Promise<void>;
    massUnsubscribe(unsubscribeList: {
        user: AgoraRTCRemoteUser;
        mediaType?: Kind;
    }[]): Promise<MassUnsubscribeMessage | undefined>;
    massUnsubscribeNoLock(unsubscribeList: {
        user: AgoraRTCRemoteUser;
        mediaType?: Kind;
    }[]): Promise<MassUnsubscribeMessage | undefined>;
    muteRemote(user: AgoraRTCRemoteUser, kind: Kind): Promise<void>;
    unmuteRemote(user: AgoraRTCRemoteUser, kind: Kind): Promise<void>;
    unmuteRemoteNoLock(user: AgoraRTCRemoteUser, kind: Kind): Promise<void>;
    getAllTracks(filterLowVideoTrack?: boolean): LocalTrack[];
    reportPublishEvent(succ: boolean, ec: string | null, failedTracks?: LocalTrack[], isLowStream?: boolean, extend?: string): void;
    reportSubscribeEvent(succ: boolean, ec: string | null, user: AgoraRTCRemoteUser, mediaType: Kind): void;
    reset(): void;
    getStats(isDownlink?: boolean): AgoraPCStats | undefined;
    getRemoteVideoIsReady(ssrcId: number): boolean;
    getLocalAudioVolume(): number | undefined;
    getLocalVideoSize(): {
        width: number;
        height: number;
    } | undefined;
    getEncoderConfig(type: LocalTrackType): VideoEncoderConfiguration | AudioEncoderConfiguration | undefined;
    getLocalMedia(type: LocalTrackType): LocalTrackStruct | undefined;
    hasLocalMedia(): boolean;
    hasRemoteMedia(user?: AgoraRTCRemoteUser, kind?: Kind): boolean;
    hasRemoteMediaWithLock(user?: AgoraRTCRemoteUser, kind?: Kind): Promise<boolean>;
    getRemoteMedia(uid: UID): {
        audioTrack?: RemoteAudioTrack;
        videoTrack?: RemoteVideoTrack;
        audioSSRC?: number;
        videoSSRC?: number;
    };
    getAudioLevels(): {
        uid: UID;
        level: number;
    }[];
    disconnectForReconnect(): Promise<void>;
    hasPendingRemoteMedia(remoteUser: AgoraRTCRemoteUser | UID, mediaType: string): boolean;
    setPendingRemoteMedia(remoteUser: AgoraRTCRemoteUser, mediaType: Kind): void;
    restartICE(direction: P2PConnectionDirection, remoteIceParameter: ICEParameters): Promise<ICEParameters>;
    restartICE(direction: P2PConnectionDirection): Promise<void>;
    getUplinkNetworkQuality(): NetworkQuality;
    getDownlinkNetworkQuality(): NetworkQuality;
    muteLocalTrack(track: LocalTrack): Promise<void>;
    private handleMuteLocalTrack;
    private handleUnmuteLocalTrack;
    private handleUpdateVideoEncoder;
    private handleUpdateVideoSendParameters;
    private handleReplaceTrack;
    private filterTobePublishedTracks;
    private filterTobeUnpublishedTracks;
    private bindLocalTrackEvents;
    private bindLocalAudioTrackEvents;
    private unbindLocalTrackEvents;
    private unbindLocalAudioTrackEvents;
    private bindRemoteTrackEvents;
    private unbindRemoteTrackEvents;
    private unbindAllRemoteTrackEvents;
    private createGatewayPublishMessage;
    private createGatewayUnpublishMessage;
    private assignLocalTracks;
    private withdrawLocalTracks;
    private bindConnectionEvents;
    private unbindConnectionEvents;
    handleDisconnect(direction: P2PConnectionDirection): Promise<void>;
    private filterTobeMutedTracks;
    private filterTobeUnmutedTracks;
    private createMuteMessage;
    private createUnmuteMessage;
    private filterTobeUnSubscribedTracks;
    private createUnsubscribeMessage;
    private withdrawRemoteTracks;
    updateBitrateLimit(bitrateLimit: ConfigDistributeLimitBitrate): Promise<void>;
    private handleGetLocalVideoStats;
    private handleGetLocalAudioStats;
    private handleGetRemoteVideoStats;
    private handleGetRemoteAudioStats;
    isP2PDisconnected(): boolean;
    private tryToUnmuteAudio;
    private bindStatsUploaderEvents;
    private unbindStatsUploaderEvents;
    requestReconnect(): Promise<void>;
    reconnectP2P(): Promise<void>;
    canPublishLowStream(): boolean;
    private throwIfTrackTypeNotMatch;
    private getLowVideoTrack;
    globalLock(): Promise<() => void>;
    private reportVideoFirstFrameDecoded;
    remoteMediaSsrcChanged(user: AgoraRTCRemoteUser, mediaType: Kind, ssrcId: number): Promise<boolean>;
    isPreSubScribe(ssrcId: number): boolean;
    publishDataChannel(datachannels: LocalDataChannel[]): Promise<PublishDataChannelOptions[]>;
    unpublishDataChannel(dataChannels: LocalDataChannel[]): Promise<number[] | void>;
    subscribeDataChannel(user: AgoraRTCRemoteUser, remoteDataChannels: RemoteDataChannel[]): Promise<number[] | void>;
    unsubscribeDataChannel(user: AgoraRTCRemoteUser, remoteDataChannels: RemoteDataChannel[]): Promise<number[] | undefined>;
    hasPendingRemoteDataChannel(remoteUser: AgoraRTCRemoteUser | UID, streamId: number): boolean;
    setPendingRemoteDataChannel(remoteUser: AgoraRTCRemoteUser, id: number): void;
    preConnect(connectionParams: ConnectionParams): Promise<TransmissonInfo>;
    getEstablishParams(): EstablishParams;
    reSubscribe(needSignal?: boolean): Promise<void>;
    updateVideoStreamParameter(parameter: LowStreamParameter, type: Exclude<LocalTrackType, LocalTrackType.LocalAudioTrack>): Promise<void>;
    private unbindRtpTransceiver;
}

interface WebsocketUrl {
    host: string;
    port: string;
    proxy?: string;
}

declare abstract class BaseWebSocket extends EventEmitter {
    private _websocketUrl;
    get url(): string | null;
    connectionID: number;
    currentURLIndex: number;
    urls: (WebsocketUrl | string)[];
    protected _reconnectMode: "retry" | "tryNext" | "recover";
    get reconnectMode(): "retry" | "tryNext" | "recover";
    set reconnectMode(newMode: "retry" | "tryNext" | "recover");
    reconnectReason?: WebSocketQuitReason;
    private _initMutex;
    protected readonly name: string;
    protected _state: WebSocketConnectionState;
    protected reconnectInterrupter?: () => void;
    get state(): WebSocketConnectionState;
    set state(newState: WebSocketConnectionState);
    protected websocket?: WebSocket;
    protected retryConfig: RetryConfiguration;
    protected reconnectCount: number;
    protected forceCloseTimeout: number;
    protected resetReconnectCount(reason: string): void;
    protected onlineReconnectListener?: Promise<void>;
    protected useCompress: boolean;
    tryDoubleDomain: boolean;
    use443PortOnly: boolean;
    protected wsInflateLength: number;
    protected wsDeflateLength: number;
    protected closeEstablishingWs?: () => void;
    protected store?: SDKStore;
    protected joinGatewayRecordIndex?: number;
    constructor(name: string, retryConfig: RetryConfiguration, useCompress?: boolean, tryDoubleDomain?: boolean, use443PortOnly?: boolean, store?: SDKStore);
    getConnection(): WebSocket | undefined;
    init(urls: (WebsocketUrl | string)[], forceCloseTimeout?: number): Promise<void>;
    close(failed?: boolean, lazyClose?: boolean): void;
    reconnect(reconnectMode?: ReconnectMode, reason?: WebSocketQuitReason): void;
    sendMessage(message: any, immediately?: boolean, isUint8ArrayMessage?: boolean): void;
    private setWsInflateData;
    getWsInflateData(): {
        wsInflateLength: number;
        wsDeflateLength: number;
    };
    private clearWsInflateData;
    private createWebSocketConnection;
    private reconnectWithAction;
    protected abstract chooseBestWebsocketConnection(url: WebsocketUrl | string, recordIndex?: number): Promise<WebSocket>;
}

declare class GatewayWebSocket extends BaseWebSocket {
    constructor(name: string, retryConfig: RetryConfiguration, useCompress?: boolean, tryDoubleDomain?: boolean, use443PortOnly?: boolean, store?: SDKStore);
    protected chooseBestWebsocketConnection(url: WebsocketUrl | string, recordIndex?: number): Promise<WebSocket>;
}

type StatsCounter = StatsCounter6s | StatsCounter3s | StatsCounter1s;
declare enum StatsCounter6s {
    Video_Send_Qp_Sum = 2143,
    Video_Send_Freeze = 2082,
    Video_Recv_Qp_Sum = 2144,
    Video_Recv_Freeze = 2084,
    Video_Render_Freeze_Time = 2109,
    Video_Render_Freeze_Time_Render = 2147,
    Video_Render_Freeze_Time_Render2 = 2223,
    Audio_Recv_Freeze = 2083,
    Video_Send_Type = 2225
}
declare enum StatsCounter3s {
    Video_Send_Retransmit = 2062,
    Video_Send_Target_Encoded = 2064,
    Video_Send_Actual_Encoded = 2060,
    Video_Send_Transmit = 2066,
    Video_Send_Bandwidth = 2061,
    Video_Capture_Height = 2033,
    Video_Capture_Width = 2035,
    Video_Capture_Frame_Rate = 2034,
    Video_Send_Low_Height = 2073,
    Video_Send_Low_Frame_Rate = 2075,
    Video_Send_Low_Width = 2077,
    Video_Send_Low_Bitrate = 2069,
    Video_Send_Low_Package_Lost = 2070,
    Video_Send_Low_Package_Rate = 2071,
    Video_Send_Frame_Rate = 2002,
    Video_Send_Width = 2003,
    Video_Send_Height = 2004,
    Video_Send_Disabled = 2095,
    Video_Send_Adaptation = 2032,
    Video_Send_Player_Status = 2128,
    Video_Send_Nacks = 2009,
    Video_Send_Plis = 2010,
    Video_Send_Firs = 2011,
    Video_Send_Avg_Encode = 2007,
    Video_Send_Huge_Frame_Sent = 2174,
    Video_Send_Bytes_Retransmit = 2173,
    Video_Send_Packages_Retransmit = 2172,
    Video_Send_Key_Frames_Encoded = 2207,
    Video_Send_Bitrate = 2012,
    Video_Send_Package_Rate = 2031,
    Video_Send_Package_Lost = 2005,
    Audio_Capture_PCM_Level = 2104,
    Audio_Send_Level = 2038,
    Audio_Send_Bitrate = 2039,
    Audio_Send_Package_Rate = 2040,
    Audio_Send_AEC_Return_Loss = 2041,
    Audio_Send_AEC_Return_Loss_Enhancement = 2042,
    Audio_Send_Freeze = 2081,
    Audio_Send_Disabled = 2096,
    Audio_Send_Bytes_Retransmit = 2179,
    Audio_Send_Packages_Retransmit = 2180,
    Video_Recv_Height = 2019,
    Video_Recv_Width = 2018,
    Video_Recv_Frame_Rate_Output = 2155,
    Video_Recv_Jitter_Buffer = 2023,
    Video_Recv_Current_Delay = 2024,
    Video_Recv_Nacks = 2026,
    Video_Recv_Plis = 2027,
    Video_Recv_Firs = 2028,
    Video_Recv_Disabled = 2101,
    Video_Recv_Player_Status = 2129,
    Video_Recv_I_Frame_Delay = 2149,
    Video_Render_Frame_Rate_Render = 2022,
    Video_Render_Freeze_Duration = 2156,
    Audio_Render_Level = 2043,
    Audio_Render_Freeze_Time_80ms = 2226,
    Audio_Render_Freeze_Time_200ms = 2227,
    Audio_Render_Freeze_Samples_80ms = 2228,
    Audio_Render_Freeze_Samples_200ms = 2229,
    Audio_Recv_PCM_Level = 2105,
    Audio_Recv_Disabled = 2102,
    Audio_Recv_Jitter_Buffer = 2054,
    Audio_Recv_Current_Delay = 2047,
    Audio_Recv_Player_Status = 2130,
    Audio_Recv_Bitrate = 2044,
    Audio_Recv_Concealed_Samples = 2148,
    Audio_Recv_Total_Samples_Received = 2224
}
declare enum StatsCounter1s {
    Video_Render_Frame_Rate_Decode = 2021,
    Video_Recv_Frame_Rate = 2020,
    Video_Recv_Frame_Dropped = 2181,
    Video_Recv_Bytes_Retransmit = 2175,
    Video_Recv_Packages_Retransmit = 2176,
    Video_Recv_Packages_Discarded = 2198,
    Video_Recv_Avg_Decode = 2200,
    Video_Recv_Avg_Processing_Delay = 2202,
    Video_Recv_Avg_Assembly_Time = 2203,
    Video_Recv_Avg_Inter_Frame_Delay = 2204,
    Video_Recv_Key_Frames_Decoded = 2206,
    Video_Recv_Package_Lost = 2014,
    Video_Recv_Bitrate = 2029,
    Video_Recv_Package_Rate = 2078,
    Audio_Recv_Jitter = 2055,
    Audio_Recv_Bytes_Retransmit = 2178,
    Audio_Recv_Packages_Retransmit = 2177,
    Audio_Recv_Packages_Discarded = 2199,
    Audio_Recv_Avg_Processing_Delay = 2201,
    Audio_Recv_Package_Rate = 2046,
    Audio_Recv_Package_Lost = 2045
}
interface UploadOutboundStats {
    high?: Partial<Record<StatsCounter, number>>;
    low?: Partial<Record<StatsCounter, number>>;
    audio?: Partial<Record<StatsCounter, number>>;
}
interface UploadInboundStats {
    peer: UID;
    video?: Partial<Record<StatsCounter, number>>;
    audio?: Partial<Record<StatsCounter, number>>;
}
declare enum TransportStatsCounter {
    RTT = 2006,
    CONN_TYPE = 801,
    STATS_UPDATE_INTERVAL = 2205
}
declare enum BaseTransportCounter {
    RTC_PEER_CONNECTION_STATE = 2219
}
interface UploadMixedStats {
    peer?: UID;
    video?: Record<StatsCounter, number>;
    audio?: Record<StatsCounter, number>;
    addition?: (Record<TransportStatsCounter, number | undefined> & Partial<Record<BaseTransportCounter, number>>) | Record<BaseTransportCounter, number>;
}
interface UploadStatsInfo {
    inbound?: UploadInboundStats[];
    outbound?: UploadOutboundStats[];
    misc?: UploadMixedStats[];
}

declare class P2PSignal extends EventEmitter {
    get connectionState(): SignalConnectionState;
    set connectionState(state: SignalConnectionState);
    get currentURLIndex(): number;
    private _disconnectedReason?;
    private _websocketReconnectReason?;
    private _connectionState;
    private reconnectToken?;
    private p2pToken;
    get url(): string | null;
    get rtt(): number;
    websocket: GatewayWebSocket;
    openConnectionTime?: number;
    private clientId;
    private lastMsgTime;
    private uploadCache;
    private uploadCacheInterval?;
    private rttRolling;
    private pingpongTimer?;
    private pingpongTimeoutCount;
    private joinResponse?;
    private multiIpOption?;
    private initError?;
    private spec;
    private store;
    private _external_signal;
    constructor(spec: SignalSpec, store: SDKStore);
    request(type: SignalRequestType, payload?: any, noNeedToReSend?: boolean, noNeedResponse?: boolean): Promise<any>;
    waitMessage<T = any>(type: SignalNotifyType, filter?: (message: T) => boolean): Promise<T>;
    uploadWRTCStats(stats: UploadStatsInfo): void;
    upload(type: SignalUploadType, payload?: any): void;
    send(type: SignalRequestType, payload?: any): void;
    sendExtensionMessage(type: ExternalSignalRequestType, payload?: any, noNeedResponse?: boolean): Promise<any>;
    init(urls: WebsocketUrl[]): Promise<any>;
    close(reason?: ConnectionDisconnectedReason): void;
    private join;
    reconnect(reconnectMode?: ReconnectMode, reason?: WebSocketQuitReason): void;
    private handleDataStream;
    private handleNotification;
    private handlePingPong;
    private handleWebsocketEvents;
    private onWebsocketMessage;
}

type TRteServiceName = "ChannelMediaRelay" | "LiveStreaming" | "ImageModeration" | "ContentInspect" | "DataStream" | "P2PChannel" | "PlanBConnection" | "InterceptFrame";
interface IRteService<T = any, R = any> {
    name: TRteServiceName;
    create: (...args: any[]) => T;
    createSubmodule?: (...args: any[]) => R;
}

interface IP2PChannelOptions {
    store: SDKStore;
    statsCollector: AgoraRTCStatsCollector;
}
interface IP2PSignalOptions {
    store: SDKStore;
    spec: SignalSpec;
}
declare const P2PChannelService: IRteService<P2PChannel2, P2PSignal>;

export { P2PChannel2, P2PChannelService };
export type { IP2PChannelOptions, IP2PSignalOptions };
