UNPKG

@seastart/srtc-web-sdk

Version:

srtc sdk for web

1,955 lines (1,954 loc) 105 kB
import Bowser$1 from 'bowser'; import EventEmitter from 'events'; import { ClientRequestArgs } from 'http'; import { IAuthPacket, IConnackPacket, IConnectPacket, IDisconnectPacket, IPacket, IPingreqPacket, IPingrespPacket, IPubackPacket, IPubcompPacket, IPublishPacket, IPubrecPacket, IPubrelPacket, ISubackPacket, ISubscribePacket, ISubscription, IUnsubackPacket, IUnsubscribePacket, Packet, PacketCmd, QoS, UserProperties } from 'mqtt-packet'; import { ClientOptions } from 'ws'; declare abstract class BaseChannel extends EventEmitter { /** 加入频道选项 */ protected options: JoinOptions; /** 加入频道api返回的数据 */ protected joinRsp: ChannelJoinRsp; /** 我自己 */ protected me?: BaseUser; /** 频道成员 */ protected users: UserContainer; /** 频道信息 */ protected info?: BaseChannelInfo; /** 心跳定时器id */ protected heartbeatIntervalID?: number; /** 频道连接状态 */ protected connectState: ChannelConnectState; /** rtc http api */ protected rtcApi: BaseRtcApi; /** rtc socket*/ protected rtcSocket: BaseRtcSocket; /** * 当前的媒体引擎 */ protected rtcStreamEngine: BaseStreamEngine; /** 混音流 */ protected audioMixTrack?: BaseTrack & (IMockRemoteAudioMixTrack | IRemoteAudioMixTrack); /** 视频合成流 */ protected videoMcuTrack?: BaseTrack; /** 频道级音频合成流(program,服务端统一混音,观众/录制用,区别于参与者本地混的 audioMixTrack) */ protected audioMcuTrack?: BaseTrack; /** 兼容回调方式的事件响应 */ protected eventCB: ((evt: ChannelEvent) => void) | null; /** * 根据userinfo实例化user * @param info */ protected abstract newUser(info: BaseUserInfo): BaseUser; /** * 进行中的流订阅/取消订阅等互斥操作mutex */ private trackMutex; /** * 流订阅/取消订阅防抖动 */ private trackDebounce; constructor(options: JoinOptions, rsp: ChannelJoinRsp, api: BaseRtcApi, streamEngine: BaseStreamEngine, socket: BaseRtcSocket, eventCB?: ((evt: ChannelEvent) => void) | null); /** * 刷新频道详情 */ protected refresh(isReconnected: boolean): Promise<void>; /** * 入会时对已有远端轨道进行自动订阅 */ private autoSubscribeExistingTracks; /** * 检查频道是否是已连接状态,不是则抛出错误 * @returns */ protected checkConnected(): void; /** * 监听socket */ private addSocketListeners; /** * 取消监听socket */ private removeSocketListeners; /** * 触发频道事件。 * * 用 rest-tuple 技巧把 data 是否必填和 map 绑定起来: * - 当 `ChannelEventDataMap[K]` 是 `undefined`(如 RECONNECTING):调用处省略第二个参数; * - 其余情况:调用处**必须**传入与 map 对应的 data 类型。 * 这样新增事件类型时 TS 会卡在对应 emit 位置,避免 data 漂移。 * * @param type 事件类型 * @param args 事件 data(类型由 map 决定) */ protected triggerEvent<K extends keyof ChannelEventDataMap>(type: K, ...args: ChannelEventDataMap[K] extends undefined ? [ ] : [ data: ChannelEventDataMap[K] ]): void; /** * 心跳 */ private heartbeat; /** * socket连接成功 */ private onConnected; /** * socket开始重连 */ private onStartReconnect; /** * 收到频道内消息 * @param pkt 消息体 */ private onChannelMessage; /** * 获取自己 * @returns */ getMe(): BaseUser; /** * 获取某用户 * @param uid 用户id */ getUser(uid: string): BaseUser; /** * 获取用户信息列表 */ getUsersInfo(map: boolean): BaseUserInfo[] | Record<string, BaseUserInfo>; /** * 离开频道 */ leave(reason: DisconnectReason, error?: any): Promise<void>; /** * 获取对sdk外部展现的频道信息 * @returns */ getInfo(): BaseChannelInfo; /** * 监听流媒体引擎事件(如质量/active speakers 等)。 * 基类默认空实现;具体引擎的 Channel 子类 override 注册自己的事件转发。 */ protected addStreamEngineListeners(): void; /** * 获取流媒体引擎供应商 */ getStreamEngineVendor(): string; /** * 获取轨道发布额外参数 */ protected getPublishExOption(track: BaseTrack, opt: AudioPublishOptions | VideoPublishOptions): Promise<Record<string, any>>; /** * 获取发布后新增的tracks * 之所以是数组是因为自研引擎支持发布流时自动simucast */ protected getAddedTracksAfterPublish(track: BaseTrack, opt: AudioPublishOptions | VideoPublishOptions): BaseTrack[]; /** * 获取取消发布后删除的tracks */ protected getDeletedTracksAfterUnpublish(track: BaseTrack): BaseTrack[]; /** * 发布本地流轨道 * @param track * @returns */ publishLocalTrack(track: BaseTrack, opt: AudioPublishOptions | VideoPublishOptions): Promise<void>; /** * 取消发布本地流 * @param track */ unpublishLocalTrack(track: BaseTrack): Promise<void>; /** * 获取轨道订阅额外参数 */ protected getSubscribeExOption(track: BaseTrack): Promise<Record<string, any>>; /** * 生成"参与者视角"混音流(mix-minus)。 * 由各平台按 vendor 决定具体类型:支持服务端混音的(OOK/wx/CDN)返回真 RemoteAudioMixTrack, * 不支持的(webrtc-seastart)返回 MockRemoteAudioMixTrack(自动订他人音频、本地混、排除自己)。 * @param filter 可选 uid 过滤;仅本地混(Mock)生效 */ protected abstract newRemoteAudioMixTrack(filter?: ((track: BaseTrack) => boolean) | string[]): BaseTrack & (IMockRemoteAudioMixTrack | IRemoteAudioMixTrack); /** * 生成远端视频合成流(Mcu,服务端统一合成,含所有人,观众/录制用)。 */ protected abstract newRemoteVideoMcuTrack(): BaseTrack; /** * 生成远端音频合成流(program,服务端统一合成,含所有人,观众/录制用)。 * 与 newRemoteAudioMixTrack 不同:本方法各平台都返回"真·服务端合成流",绝不返回本地混(Mock)。 */ protected abstract newRemoteAudioMcuTrack(): BaseTrack; /** * 获取远端频道混音流 * @param filter 音频轨道过滤器,传递string[]时,根据uid过滤 */ subscribeRemoteAudioMixTrack(filter?: ((track: BaseTrack) => boolean) | string[]): Promise<BaseTrack & (IMockRemoteAudioMixTrack | IRemoteAudioMixTrack)>; /** * 订阅远端用户音频流 * @param uid 用户id * @param id 流轨道id */ subscribeRemoteAudioTrack(uid: string, id: string): Promise<BaseTrack>; /** * 订阅远端视频合成流 */ subscribeRemoteVideoMcuTrack(): Promise<BaseTrack>; /** * 订阅服务端统一合成的混音(program,含所有人,所有订阅者收到的一致)。 * 给不发声的观众/录制/旁路用,与 subscribeRemoteVideoMcuTrack 对应;不做 vendor 降级。 * * 该流含全场(包括你自己):会发声的参与者订它会听到自己的回声—— * 参与者请改用 subscribeRemoteAudioMixTrack(本地 mix-minus,除自己)。 */ subscribeRemoteAudioMcuTrack(): Promise<BaseTrack>; /** * 订阅远端用户视频流 * @param uid 用户id * @param id 流轨道id */ subscribeRemoteVideoTrack(uid: string, id: string): Promise<BaseTrack>; /** * 取消订阅远端流 * @param track 流轨道 * @param debounceWaitMs 防取消订阅/订阅抖动ms数 */ unsubscribeRemoteTrack(track: BaseTrack, debounceWaitMs?: number): Promise<void>; } declare abstract class BaseRtcApi { /** rtc AppID */ protected appID: string; /** rtc sid */ protected sid: string; /** 客户端密钥 */ protected clientKey: string; /** 服务器地址头部 */ protected serverPrefix?: string; /** * 发起rtc api http请求 */ protected abstract http(api: string, params: Record<string, any>, headers: Record<string, string>): Promise<any>; constructor(appID: string, sid: string, clientKey: string, serverPrefix: string); /** * 加入频道 * @see https://doc.apipost.net/docs/detail/2be86df99864000?target_id=51c6ed8 */ join(params: { deviceType: DeviceType; deviceID: string; version: string; }): Promise<ChannelJoinRsp>; /** * 频道详情 * @see https://doc.apipost.net/docs/detail/2be86df99864000?target_id=520ba1f * @param listuser 是否包括在线用户列表,true则返回所有在线用户 * @returns */ detail(listuser: boolean): Promise<{ channelinfo: BaseChannelInfo; userinfos: BaseUserInfo[] | null; }>; /** * 离开频道 * @see https://doc.apipost.net/docs/detail/2be86df99864000?target_id=51d732b * @returns */ leave(): Promise<void>; /** * 发送心跳 * @see https://doc.apipost.net/docs/detail/2be86df99864000?target_id=51d38e3 * @returns */ heartbeat(): Promise<void>; /** * 断线重连 * @see https://doc.apipost.net/docs/detail/2be86df99864000?target_id=52602cf * @returns */ reconnect(params: { type: number; }): Promise<ReconnectRsp>; /** * 更新流信息 * @see https://doc.apipost.net/docs/detail/2be86df99864000?target_id=51c6eae * @returns */ updateStream(trackinfos: BaseTrackInfo[]): Promise<void>; /** * im连接 * @see https://doc.apipost.net/docs/detail/2be86df99864000?target_id=25c1132f700054 * @returns */ imConnect(params: { deviceType: DeviceType; deviceID: string; version: string; }): Promise<ImConnectRsp>; /** * im重连 * @see https://doc.apipost.net/docs/detail/2be86df99864000?target_id=25c2a79e70007f * @returns */ imReconnect(): Promise<ImConnectRsp>; /** * im发送心跳 * @see https://doc.apipost.net/docs/detail/2be86df99864000?target_id=25c2da5cb00081 * @returns */ imHeartbeat(): Promise<void>; /** * im断开连接 * @see https://doc.apipost.net/docs/detail/2be86df99864000?target_id=25c356d2300092 * @returns */ imDisconnect(): Promise<void>; /** * 发送rtc sdk api请求 * @param api api接口 * @param params 数据 * @param headers 额外http头 */ protected req(api: string, params?: Record<string, any>, headers?: Record<string, string>): Promise<any>; /** * 签名 * @param params * @returns */ private signature; } declare abstract class BaseSRTC { /** * 获取sdk编译信息 */ abstract buildInfo(): BuildInfo; /** * 获取运行环境信息 * @returns */ abstract getEnvInfo(): any; /** * 频道事件通知回调 */ onNotifyChannelEvent?: ((event: ChannelEvent) => void) | null; /** * 频道外im事件通知回调 */ onNotifyImEvent?: ((event: ImEvent) => void) | null; constructor(initParams: SdkInitParams); /** * 加入频道的version信息 */ protected get joinVersion(): string; /** * 加入频道 * @param token 加入频道token * @param options 加入频道选项 */ join(token: string, options?: JoinOptions): Promise<BaseChannelInfo>; /** * 离开频道 */ leave(): Promise<void>; /** * 获取频道信息 * @returns */ getChannelInfo(): BaseChannelInfo | null; /** * 获取某用户信息 * @returns */ getUserInfo(uid: string): BaseUserInfo; /** * 获取频道内用户信息列表 * @returns */ getUsersInfo(map: true): Record<string, BaseUserInfo>; getUsersInfo(map: false): BaseUserInfo[]; /** * 订阅频道混音流 * @param filter 音频轨道过滤器,传递string[]时,根据uid过滤 */ subscribeRemoteAudioMixTrack(filter?: ((track: BaseTrack) => boolean) | string[]): Promise<BaseTrack>; /** * 订阅远端用户音频流 * @param uid 用户id * @param id 流轨道id */ subscribeRemoteAudioTrack(uid: string, id: string): Promise<BaseTrack>; /** * 订阅远端视频合成流 */ subscribeRemoteVideoMcuTrack(): Promise<BaseTrack>; /** * 订阅远端用户视频流 * @param uid 用户id * @param id 流轨道id */ subscribeRemoteVideoTrack(uid: string, id: string): Promise<BaseTrack>; /** * 取消订阅远端流 */ unsubscribeRemoteTrack(track: BaseTrack): Promise<void>; /** * 获取远端用户音视频流实例,一般用于订阅流后您没有持有返回的流实例,可以用此方法获取对应实例 * @param uid 用户id * @param id 流轨道id,与desc二选一 * @param desc 流描述,与id二选一 */ getRemoteTrack(uid: string, id?: string, desc?: string): BaseTrack; /** * 启用频道外消息 * @param token 启用频道外消息token * @returns im会话sid */ enableIm(token: string): Promise<string>; /** * 关闭频道外消息 */ disableIm(): Promise<void>; } declare abstract class BaseStreamEngine extends EventEmitter { /** 加入频道api返回的数据 */ protected joinRsp: ChannelJoinRsp; /** 已发布轨道 */ protected published: Record<string, BaseTrackEx>; /** 已订阅轨道 */ protected subscribed: Record<string, BaseTrackEx>; /** 能力 */ protected ability?: StreamEngineAbility; /** 采集metric指标定时器(用于日志上报) */ protected monitorInterval?: number; constructor(rsp: ChannelJoinRsp, ability?: Partial<StreamEngineAbility>); /** * 流媒体服务商名 */ abstract vendor(): string; /** * 连接流媒体服务(如果需要,程博webrtc流媒体就需要) */ connect(): Promise<void>; /** * 发布本地流 * @param track * @param opt 通用发布参数 * @param exopt 该引擎特有的发布参数 */ publish(track: BaseTrack, opt: AudioPublishOptions | VideoPublishOptions, exopt: Record<string, any>): Promise<void>; /** * 取消发布本地流 * @param track */ abstract unpublish(track: BaseTrack): Promise<void>; /** * 订阅远端流 * @param track * @param exopt 该引擎特有的订阅参数 */ subscribe(track: BaseTrack, exopt: Record<string, any>): Promise<void>; /** * 是否已订阅某轨道 * @param track * @returns */ haveSubscribed(track: BaseTrack): boolean; /** * 取消订阅远端流 * @param track * @param exopt 该引擎特有的取消订阅参数 */ abstract unsubscribe(track: BaseTrack): Promise<void>; /** * 断开流媒体服务 */ disconnect(): Promise<void>; /** * 获取当前metric快照 */ getMetricSnapshot(): Record<string, any> | undefined; /** * 开始metric采集 * * 基类只做 10s 低频日志上报。 * 若子类需要更高频采样(例如 webrtc 引擎的质量评分),可 override 后 `super.startMonitor()`。 */ protected startMonitor(): void; /** * 获取metric数据 * @returns */ protected abstract getMetric(): Promise<Record<string, any>>; /** * 结束metric采集 */ protected stopMonitor(): void; } declare abstract class BaseTrack extends EventEmitter { constructor(info: BaseTrackInfo, uid: string); /** * 轨道id */ get id(): string; /** * 轨道类型 */ get kind(): TrackKind; /** * 轨道描述 */ get desc(): string; /** * 是否为 simulcast 副层 */ get variant(): boolean | undefined; /** * 获取流轨道信息 * @returns */ getInfo(): BaseTrackInfo; /** * 轨道所属用户 * @returns */ getUid(): string; toString(): string; } declare abstract class BaseUser { /** track 数组 */ protected tracks: Record<string, BaseTrack>; /** 对外输出的info */ protected info: BaseUserInfo; /** * 根据trackinfo实例化track * @param trackinfo */ protected abstract newTrack(info: BaseTrackInfo): BaseTrack; constructor(info: BaseUserInfo); /** * 获取某轨道 */ getTrack(id: string): BaseTrack | undefined; /** * 用给定 info 新造一个独立的 track 句柄(不登记进 this.tracks)。 * 用途:自订阅回环——订阅本端自己发布的轨道时,需要一个独立于本地发布轨道的远端句柄来承接下行, * 否则 seastart 订阅 PC 的 ontrack 会用收到的远端轨道 setMediaStreamTrack 顶掉本地发布源, * 导致发布端静音、编码器无输入、SFU 永等不到关键帧的死锁。此处仅暴露 protected newTrack 的建轨能力。 */ spawnTrack(info: BaseTrackInfo): BaseTrack; /** * 根据desc获取某轨道 */ getTrackByDesc(desc: string): BaseTrack | undefined; /** * 获取所有轨道 * @returns */ getTracks(): Record<string, BaseTrack>; /** * 全量更新tracks,目前会控只有全量更新某用户的所有track * @param trackinfos 新的全量trackinfos */ updateTracks(trackinfos: BaseTrackInfo[]): { added: BaseTrack[]; updated: BaseTrack[]; deleted: BaseTrack[]; }; /** * 第三方用户id */ get uid(): string; /** * 会话id */ get sid(): string; /** * 设备类型 */ get device_type(): number; /** * 设备id */ get device_id(): string; /** * 流媒体连接id */ get link_id(): number; /** * 获取对sdk外部展现的用户信息 * @returns */ getInfo(): BaseUserInfo; /** * 更新描述信息 * @param info */ updateInfo(info: Partial<BaseUserInfo>): void; } declare abstract class BaseWebrtcTrack extends BaseTrack { constructor(info: BaseTrackInfo, uid: string); setMediaStreamTrack(mediaStreamTrack?: MediaStreamTrack): void; getMediaStreamTrack(): MediaStreamTrack | undefined; getMediaStream(): MediaStream; } declare class BaseRtcSocket extends EventEmitter { /** mqtt客户端 */ private client; /** 会控协议版本头 */ private version; /** 已订阅topics:qos */ private ssTopics; /** 重连时刷新auth */ protected authReconnect?: AuthReconnect; /** 是否首次连接 */ private isFirstConnect; /** 消息解析 */ private unpacker; constructor(authReconnect?: AuthReconnect); /** * 初始化mqtt客户端 * @param server */ private initClient; /** * 转换websocket地址,主要小程序需要用wxs前缀 * @param ws * @returns */ protected getBrokerUrl(ws: string): string; /** * 连接mqtt服务器 * @param server */ connect(server: MqttServer): Promise<void>; /** * 添加socket常驻监听 */ private addListeners; /** * 封装mqtt的subscribe为promise * @param topic 话题或者话题数组 */ subscribe(topic: string | string[], qos?: QoS): Promise<void>; /** * 封装mqtt的unsubscribe为promise * @param topic 话题或者话题数组 */ unsubscribe(topic: string | string[]): Promise<void>; /** * 关闭socket * @param force 是否强制退出(不等待ack),对应mqttclient的end里的force * @returns */ close(force?: boolean): Promise<void>; /** * 发送消息 * @param data 数据 * @param type 消息类型 */ sendMsg(msg: string | Buffer, topic: string, qos?: QoS): Promise<void>; /** * 收到mqtt消息响应 * @param topic mqtt主题 * @param payload 消息载荷 * @param packet * @returns */ private onMsg; } declare class Channel extends BaseChannel { /** * override:注册 webrtc 引擎特有的质量 / active speakers 事件转发。 */ protected addStreamEngineListeners(): void; /** * 获取流媒体引擎的metric快照(全量,包含每条轨道的统计) */ getStreamMetric(): StreamMetric | undefined; /** * 获取当前网络总体统计,轻量接口,只关心网络整体指标时使用 */ getNetworkStats(): NetworkStats | undefined; /** * 获取当前连接质量评估结果(等级、MOS、原因等) */ getConnectionQuality(): QualityEvaluation | undefined; protected getPublishExOption(track: BaseTrack, opt: AudioPublishOptions | VideoPublishOptions): Promise<Record<string, any>>; protected getAddedTracksAfterPublish(track: BaseTrack, opt: AudioPublishOptions | VideoPublishOptions): BaseTrack[]; protected getDeletedTracksAfterUnpublish(track: BaseTrack): BaseTrack[]; protected getSubscribeExOption(track: BaseTrack): Promise<Record<string, any>>; protected newRemoteAudioMixTrack(filter?: ((track: BaseTrack) => boolean) | string[]): RemoteAudioMixTrack | MockRemoteAudioMixTrack; protected newRemoteVideoMcuTrack(): RemoteVideoMcuTrack; protected newRemoteAudioMcuTrack(): RemoteAudioMcuTrack; subscribeRemoteVideoTrack(uid: string, id: string): Promise<BaseTrack>; unsubscribeRemoteTrack(track: BaseTrack, debounceWaitMs?: number): Promise<void>; /** 自适应流管理器。懒初始化,避免父类构造期还未准备好 rtcStreamEngine/options 的问题。 */ private adaptiveStream?; private getAdaptiveStream; /** * 解析某路远端视频订阅的完整候选层,顺序"高到低"。 * 这一步依赖 user 结构,所以留在 Channel 里作为解析器喂给 Manager。 */ private getAdaptiveVideoCandidates; } declare class CommonChannelEventType { /** 频道自定义props更新 */ static readonly CHANNEL_UPDATE = "channel_update"; /** 首次加入频道成功 */ static readonly JOIN_SUCCEED = "join_succeed"; /** 自己信息被改变 */ static readonly ME_UPDATE = "me_update"; /** 开始断线自动重连 */ static readonly RECONNECTING = "reconnecting"; /** 重连成功,断线重连成功后会触发 */ static readonly RECONNECTED = "reconnected"; /** 自己被强制离开频道 */ static readonly DISCONNECTED = "disconnected"; /** 其他用户加入频道 */ static readonly USER_JOIN = "user_join"; /** 其他用户信息改变 */ static readonly USER_UPDATE = "user_update"; /** 其他用户离开频道 */ static readonly USER_LEAVE = "user_leave"; /** 其他用户发布流轨道 */ static readonly USER_TRACK_ADD = "user_track_add"; /** 其他用户更新流轨道 */ static readonly USER_TRACK_UPDATE = "user_track_update"; /** 其他用户删除流轨道 */ static readonly USER_TRACK_REMOVE = "user_track_remove"; /** 频道内自定义消息 */ static readonly CUSTOM_MSG = "custom_msg"; /** 流轨道没有数据 */ static readonly TRACK_MUTED = "track_muted"; /** 流轨道恢复数据 */ static readonly TRACK_UNMUTED = "track_unmuted"; /** 流轨道停止 */ static readonly TRACK_ENDED = "track_ended"; } /** 频道外事件类型 */ declare class CommonImEventType { /** 首次连接im成功 */ static readonly ENABLE_SUCCEED = "enable_succeed"; /** im开始断线自动重连 */ static readonly RECONNECTING = "reconnecting"; /** im重连成功 */ static readonly RECONNECTED = "reconnected"; /** 自己被强制断开im */ static readonly DISCONNECTED = "disconnected"; /** im消息 */ static readonly IM_MSG = "im_msg"; } declare class CommonTrackEventType { /** track info更新 */ static readonly INFO_UPDATE = "info_update"; /** temporarily unable to provide media data */ static readonly MUTED = "muted"; /** once again able to provide media data */ static readonly UNMUTED = "unmuted"; /** playback or streaming has stopped because the end of the media was reached or because no further data is available */ static readonly ENDED = "ended"; } declare class Logger { constructor(dp?: string, dclt?: string); setTarget(target: LogTarget): void; setLevel(level: LogLevel): void; debug(...args: any[]): void; info(...args: any[]): void; warn(...args: any[]): void; error(...args: any[]): void; } declare class MockRemoteAudioMixTrack extends RemoteAudioTrack implements IMockRemoteAudioMixTrack { constructor(info: BaseTrackInfo, filter?: (track: BaseTrack) => boolean); /** * 检查是否要过滤某track * @param track * @returns */ checkFilter(track: RemoteAudioTrack): boolean; /** * 添加track * @param track */ addTrack(track: RemoteAudioTrack): void; /** * 移除track * @param track */ removeTrack(track: RemoteAudioTrack): void; /** * 停止混音 */ stop(): void; } declare class MqttClient extends EventEmitter { public connected: boolean; public disconnecting: boolean; public disconnected: boolean; public reconnecting: boolean; public incomingStore: Store; public outgoingStore: Store; public options: IClientOptions; public queueQoSZero: boolean; constructor(streamBuilder: (client: MqttClient) => IStream, options: IClientOptions); public on(event: "connect", cb: OnConnectCallback): this; public on(event: "message", cb: OnMessageCallback): this; public on(event: "packetsend" | "packetreceive", cb: OnPacketCallback): this; public on(event: "disconnect", cb: OnDisconnectCallback): this; public on(event: "error", cb: OnErrorCallback): this; public on(event: "close", cb: OnCloseCallback): this; public on(event: "end" | "reconnect" | "offline" | "outgoingEmpty", cb: () => void): this; public on(event: string, cb: Function): this; public once(event: "connect", cb: OnConnectCallback): this; public once(event: "message", cb: OnMessageCallback): this; public once(event: "packetsend" | "packetreceive", cb: OnPacketCallback): this; public once(event: "disconnect", cb: OnDisconnectCallback): this; public once(event: "error", cb: OnErrorCallback): this; public once(event: "close", cb: OnCloseCallback): this; public once(event: "end" | "reconnect" | "offline" | "outgoingEmpty", cb: () => void): this; public once(event: string, cb: Function): this; /** * publish - publish <message> to <topic> * * @param {String} topic - topic to publish to * @param {(String|Buffer)} message - message to publish * * @param {Object} [opts] - publish options, includes: * @param {Number} [opts.qos] - qos level to publish on * @param {Boolean} [opts.retain] - whether or not to retain the message * @param {Function}[opts.cbStorePut] - function(){} * called when message is put into `outgoingStore` * * @param {Function} [callback] - function(err){} * called when publish succeeds or fails * * @returns {Client} this - for chaining * @api public * * @example client.publish('topic', 'message') * @example * client.publish('topic', 'message', {qos: 1, retain: true}) * @example client.publish('topic', 'message', console.log) */ public publish(topic: string, message: string | Buffer, opts: IClientPublishOptions, callback?: PacketCallback): this; public publish(topic: string, message: string | Buffer, callback?: PacketCallback): this; /** * subscribe - subscribe to <topic> * * @param {String, Array, Object} topic - topic(s) to subscribe to, supports objects in the form {'topic': qos} * @param {Object} [opts] - optional subscription options, includes: * @param {Number} [opts.qos] - subscribe qos level * @param {Function} [callback] - function(err, granted){} where: * {Error} err - subscription error (none at the moment!) * {Array} granted - array of {topic: 't', qos: 0} * @returns {MqttClient} this - for chaining * @api public * @example client.subscribe('topic') * @example client.subscribe('topic', {qos: 1}) * @example client.subscribe({'topic': 0, 'topic2': 1}, console.log) * @example client.subscribe('topic', console.log) */ public subscribe(topic: string | string[], opts: IClientSubscribeOptions, callback?: ClientSubscribeCallback): this; public subscribe(topic: string | string[] | ISubscriptionMap, callback?: ClientSubscribeCallback): this; /** * unsubscribe - unsubscribe from topic(s) * * @param {String, Array} topic - topics to unsubscribe from * @param {Object} opts - opts of unsubscribe * @param {Function} [callback] - callback fired on unsuback * @returns {MqttClient} this - for chaining * @api public * @example client.unsubscribe('topic') * @example client.unsubscribe('topic', console.log) * @example client.unsubscribe('topic', opts, console.log) */ public unsubscribe(topic: string | string[], opts?: Object, callback?: PacketCallback): this; /** * end - close connection * * @returns {MqttClient} this - for chaining * @param {Boolean} force - do not wait for all in-flight messages to be acked * @param {Object} opts - opts disconnect * @param {Function} cb - called when the client has been closed * * @api public */ public end(force?: boolean, opts?: Object, cb?: CloseCallback): this; /** * removeOutgoingMessage - remove a message in outgoing store * the outgoing callback will be called withe Error('Message removed') if the message is removed * * @param {Number} mid - messageId to remove message * @returns {MqttClient} this - for chaining * @api public * * @example client.removeOutgoingMessage(client.getLastMessageId()); */ public removeOutgoingMessage(mid: number): this; /** * reconnect - connect again using the same options as connect() * * @param {Object} [opts] - optional reconnect options, includes: * {Store} incomingStore - a store for the incoming packets * {Store} outgoingStore - a store for the outgoing packets * if opts is not given, current stores are used * * @returns {MqttClient} this - for chaining * * @api public */ public reconnect(opts?: IClientReconnectOptions): this; /** * Handle messages with backpressure support, one at a time. * Override at will. * * @param packet packet the packet * @param callback callback call when finished * @api public */ public handleMessage(packet: Packet, callback: PacketCallback): void; /** * Handle auth packages for MQTT 5 enhanced authentication methods such * as challenge response authentication. * * Challenge-response authentication flow would look something like this: * * --> CONNECT | authMethod = "mathChallenge" --> * <-- AUTH | authMethod = "mathChallenge", authData = "12 + 34" <-- * --> AUTH | authMethod = "mathChallenge", authData = "46" --> * <-- CONNACK | reasonCode = SUCCESS <-- * * This form of authentication has several advantages over traditional * credential-based approaches. For instance authentication without the direct * exchange of authentication secrets. * * @param packet the auth packet to handle * @param callback call when finished * @api public */ public handleAuth(packet: IAuthPacket, callback: PacketCallback): void; /** * getLastMessageId */ public getLastMessageId(): number; } declare class RemoteAudioMcuTrack extends RemoteAudioTrack { constructor(); } declare class RemoteVideoMcuTrack extends RemoteVideoTrack { constructor(); } declare class SdkError { /** 错误码 */ code: number; /** 错误详情 */ msg: string; /** 获取前缀错误码 */ protected prefixCode(): string; constructor(msg: string, code?: number); /** * 从err转化为sdkError * @param err 原始error * @returns */ static fromError(err: Error): SdkError; toString(): string; toJSON(): { code: number; msg: string; }; } declare class Store { /** * Store constructor * * @param {Object} [options] - store options */ constructor(options: IStoreOptions); /** * Adds a packet to the store, a packet is * anything that has a messageId property. * */ public put(packet: any, cb?: Function): this; /** * Creates a stream with all the packets in the store * */ public createStream(): any; /** * deletes a packet from the store. */ public del(packet: any, cb: Function): this; /** * get a packet from the store. */ public get(packet: any, cb: Function): this; /** * Close the store */ public close(cb: Function): void; } declare class TrackEventType extends CommonTrackEventType { /** 轨道自动播放失败,对应data为BaseTrack */ static readonly AUTOPLAY_FAIL = "autoplay_fail"; /** mediastreamtrack轨道被替换,对应data为BaseTrack,oldMsTrack为旧的MediaStreamTrack */ static readonly MSTRACK_REPLACED = "mstrack_replaced"; /** 轨道流媒体开始断线自动重连,对应data为BaseTrack*/ static readonly RECONNECTING = "reconnecting"; /** 轨道流媒体重连成功,对应data为BaseTrack */ static readonly RECONNECTED = "reconnected"; /** 进入画中画模式,对应data为BaseTrack */ static readonly PIP_ENTER = "pip_enter"; /** 退出画中画模式,对应data为BaseTrack */ static readonly PIP_EXIT = "pip_exit"; /** 弹出独立窗口,对应data为BaseTrack */ static readonly POPOUT_OPEN = "popout_open"; /** 关闭独立窗口,对应data为BaseTrack */ static readonly POPOUT_CLOSE = "popout_close"; } declare class UserContainer implements Iterable<[ string, BaseUser ]> { /** uid为key的user Map */ private ctn; /** linkid为key,与uid的映射 */ private linkids; /** * 实现Iterator接口,支持for...of迭代 * @returns 返回迭代器,每次迭代返回[uid, user]键值对 */ [Symbol.iterator](): Iterator<[ string, BaseUser ]>; /** * 添加或覆盖某user * @param uid * @param user */ set(uid: string, user: BaseUser): void; /** * 获取某user * @param uid * @returns */ get(uid: string): BaseUser; /** * 根据linkid获取某user * @param linkid * @returns */ getByLinkid(linkid: string): BaseUser; /** * 删除某account * @param uid */ del(uid: string): void; /** * 清空 */ clear(): void; /** * 获取成员对外信息列表 * @returns */ listInfo(map: boolean): BaseUserInfo[] | Record<string, BaseUserInfo>; } declare enum ChannelConnectState { /** 初始状态 */ INIT = "init", /** 已连接 */ CONNECTED = "connected", /** 重连中 */ RECONNECTING = "reconnecting", /** 已离会 */ LEAVED = "leaved" } declare function dateFormat(format: string, date?: Date): string; declare function dct(t: string): any; declare function genNonce(len?: number): string; declare function getHostnameFromUrl(url: string): string; declare function isObject(value: any): boolean; declare function isString(value: any): boolean; declare function isWxxcx(): boolean; declare function propAssign<T>(target: T, income: T, assigner?: Record<keyof T, (value: any, old: any) => void>): PropChangeItem<keyof T>[]; declare function retry<T>(f: () => Promise<T>, opt: { /** 首次执行失败后的最大重试次数,默认10次,<=0代表不限制次数 */ maxRetries?: number; /** 第一次重试间隔(ms),默认500ms,之后会以 initialDelay * 2^n 进行重试 */ initialDelay?: number; /** 每次重试前的回调,e为上次失败catch到的错误,返回false则代表放弃重试,会返回canceled */ onRetry?: (attempt: number, e?: any) => boolean | void; }): retryCallback<T>; declare function sleep(ms: number): Promise<void>; /** 扩展的频道事件 */ export declare class ChannelEventType extends CommonChannelEventType { /** 外设插入,对应data为MediaDeviceInfo */ static readonly DEVICE_ADD = "device_add"; /** 外设移除,对应data为MediaDeviceInfo */ static readonly DEVICE_REMOVE = "device_remove"; /** 轨道自动播放失败,对应data为BaseTrack */ static readonly TRACK_AUTOPLAY_FAIL = "track_autoplay_fail"; /** 轨道进入画中画模式,对应data为BaseTrack */ static readonly TRACK_PIP_ENTER = "track_pip_enter"; /** 轨道退出画中画模式,对应data为BaseTrack */ static readonly TRACK_PIP_EXIT = "track_pip_exit"; /** 轨道弹出独立窗口,对应data为BaseTrack */ static readonly TRACK_POPOUT_OPEN = "track_popout_open"; /** 轨道关闭独立窗口,对应data为BaseTrack */ static readonly TRACK_POPOUT_CLOSE = "track_popout_close"; /** 连接质量等级变化,对应data为 ConnectionQualityEventData */ static readonly CONNECTION_QUALITY_CHANGED = "connection_quality_changed"; /** 发送端被CPU持续限制,对应data为 QualityEvaluation */ static readonly CPU_CONSTRAINED = "cpu_constrained"; /** 发送端被带宽持续限制,对应data为 QualityEvaluation */ static readonly BANDWIDTH_CONSTRAINED = "bandwidth_constrained"; /** * 活跃说话人列表变化,对应data为 ActiveSpeakersEventData(全量快照)。 * * 仅 SeaStart SFU 引擎支持;其他引擎(OOK/WangsuCDN)不会触发此事件。 * 每次事件 data.speakers 都是当前正在说话的完整列表,按 level 降序, * 业务侧**直接覆盖 UI**即可,不需要自己合并增量。无人说话时会收到空列表。 */ static readonly ACTIVE_SPEAKERS_CHANGED = "active_speakers_changed"; } /** * 本地音频流轨道 */ export declare class LocalAudioTrack extends BaseWebrtcTrack { constructor(); /** * 挂载音频处理器(如 RNN 降噪、变声)。传入数组时按顺序串联。 * 需先 startCapture 采集到轨道后调用。 */ setProcessor(processor: TrackProcessor | TrackProcessor[]): Promise<void>; /** * 卸载音频处理器,还原为原始采集轨道。 */ removeProcessor(): Promise<void>; /** * 获取音量 */ getVolume(): number; /** * 是否正在播放 */ isPlaying(): boolean; /** * 播放音频(可指定播放设备) */ startPlay(opt?: AudioOutputOptions): Promise<void>; /** * 停止播放并释放对播放设备的占用 */ stopPlay(): void; } /** * 本地摄像头视频流轨道 */ export declare class LocalCameraTrack extends LocalVideoTrack { constructor(captureOptions: CameraCaptureOptions); /** * 开始采集 * @param opt 采集参数 */ startCapture(opt?: Partial<CameraCaptureOptions>): Promise<void>; /** * 停止采集 */ stopCapture(): void; /** * 切换指定摄像头 * @param deviceId * @returns */ changeDeviceId(deviceId: string): Promise<void>; /** * 是否前置摄像头。供本地预览镜像判断使用。 * 采集时显式指定的 facingMode 最可靠;未指定时按前置处理(对齐浏览器/LiveKit 的默认: * 拿不到朝向时按"自拍"看待,笔记本内置摄像头即属此类)。 */ isFrontFacing(): boolean; /** * 设置镜像开关。前置摄像头默认开启,可在此调整; * 后置摄像头不支持镜像,调用无任何反应(满足"后置操作无反应")。 * @param enabled 是否开启镜像 */ setMirror(enabled: boolean): void; /** * 当前是否处于镜像状态 = 前置摄像头 且 镜像开关开启。 * 后置摄像头恒为 false。渲染层据此决定是否水平翻转。 */ isMirrored(): boolean; /** * 切换摄像头朝向(仅手机) * @returns */ switchFacingMode(): Promise<void>; } /** * 本地合成录制器。 * * 只处理媒体合成与 MediaRecorder 生命周期,不关心会议分页、布局模式、用户名来源等业务语义。 * 调用方需要把当前要录制的视频 track、音频 track 以及每个视频在画布上的位置传进来。 */ export declare class LocalCompositeRecorder { private canvas?; private canvasContext?; private canvasStream?; private recordStream?; private mediaRecorder?; private audioContext?; private audioDestination?; private audioSources; private audioInputTracks; private trackedTrackListeners; private videoElements; private avatarImages; private avatarFailedUrls; private chunks; private videoItems; private width; private height; private fps; private background; private labelBackground; private animationFrameId; private onDataAvailable?; /** * 获取当前录制状态。 * * inactive 表示未开始或已结束;recording 表示正在写入文件;paused 表示暂停写入但仍保留同一次录制会话。 */ getState(): LocalCompositeRecorderState; /** * 开始本地合成录制。 * * 会创建内部 canvas、AudioContext、MediaRecorder,并立即开始渲染和写入。 * 如果当前不是 inactive 状态,本方法会直接返回,不会重复开启录制。 */ start(options: LocalCompositeRecorderStartOptions): Promise<void>; /** * 更新视频绘制列表。 * * 用于会议翻页、布局变化、主讲人切换等场景。更新后下一帧会按新的 rect/track/label 绘制。 */ updateVideoItems(items: LocalCompositeRecorderVideoItem[]): void; /** * 更新参与混音的音频轨道。 * * 适用于本地麦克风切换、远端混音流重订阅等场景。不会替换 MediaRecorder 持有的输出音频轨。 */ updateAudioTracks(tracks: LocalCompositeRecorderTrack[]): Promise<void>; /** * 暂停录制写入。 * * 暂停期间不会向最终文件写入黑屏或静音片段;只有 recording 状态下调用才生效。 */ pause(): void; /** * 恢复录制写入。 * * 恢复后继续写入同一个输出文件;只有 paused 状态下调用才生效。 */ resume(): void; /** * 停止录制并返回最终 Blob。 * * 会释放录制器内部创建的 canvas stream、AudioContext 和隐藏 video; * 不会停止调用方传入的原始音视频 track。 */ stop(): Promise<Blob>; /** * 强制销毁录制器内部资源。 * * 适用于页面卸载或调用方不再需要输出 Blob 的异常清理场景。 */ destroy(): void; /** * 初始化混音管线。 * * 通过 MediaStreamAudioDestinationNode 生成一条稳定的输出音频轨,供 MediaRecorder 持有。 */ private initAudio; /** * 重新连接输入音频轨道。 * * 只替换 Web Audio 的 source 节点,不替换 destination 输出轨,保证录制过程不中断。 */ private setAudioTracks; /** * 断开并清空所有输入音频 source。 */ private clearAudioSources; /** * 从原生 MediaStreamTrack 或 SDK Track 中取出当前实际媒体轨。 */ private resolveMediaStreamTrack; /** * 读取 SDK Track 的视频旋转角度(FourCC)。 * * 原生 MediaStreamTrack 不携带旋转信息,按未旋转(ANGLE_UP)处理。 * 用于让录制 canvas 与正常播放路径(CSS transform)的旋转表现保持一致。 */ private resolveTrackAngle; /** * 判断是否为可监听 MSTRACK_REPLACED 的 SDK Track。 */ private isTrackLike; /** * 同步 SDK Track 的替换监听。 * * 调用方传 SDK Track 时,录制器会监听 MSTRACK_REPLACED,自动把隐藏 video 或混音 source 切到新轨。 */ private syncTrackedTrackListeners; /** * 解绑所有 SDK Track 替换监听。 */ private clearTrackedTrackListeners; /** * 同步视频解码元素。 * * 每个视频 track 都需要一个隐藏 HTMLVideoElement 作为 canvas.drawImage 的帧来源。 * 这里以底层 MediaStreamTrack「对象引用」为 key 做复用:同一个 track 即使被多个槽位 * 引用(例如大小窗布局下同一成员同时出现在大窗和小窗),也只创建一个解码 video 共享。 * 否则同一个远端 track 被多个独立 video 同时播放会产生竞态,偶发其中一个 video * 取不到帧(videoWidth=0)导致对应槽位黑屏。 * * 注意:不能用 track.id 字符串做 key——远端 track 的 id 全局不保证唯一, * 不同用户可能碰撞,会导致多个槽位错误共享同一路画面(“都变成同一个人”)。 */ private syncVideoElements; /** * 同步头像图片。 * * 为当前 videoItems 中带 avatar 的槽位预加载头像图片,供摄像头关闭时在格子中央绘制圆形头像。 * 采用匿名跨域(crossOrigin='anonymous'):若头像 CDN 未返回 CORS 头,浏览器会触发 onerror * 而非污染 canvas——被污染的 canvas 会导致 captureStream 整条录制流失效。加载失败的 URL 记入 * avatarFailedUrls,绘制时回退为「昵称首字母彩色圆」。 */ private syncAvatarImages; /** * 渲染循环。 * * 每帧按最新 videoItems 重绘整张画布,canvas.captureStream 会把这些帧输出给 MediaRecorder。 */ private render; /** * 绘制单个视频槽位。 * * contain 会完整显示视频,cover 会填满槽位并裁剪溢出区域。 * 移动端竖屏采集的视频携带旋转角度,这里会按角度对 canvas 做等价旋转/镜像, * 与正常播放路径(PlayView.freshTransform 的 CSS transform)保持一致,避免录像横屏。 */ private drawVideo; /** * 绘制视频标签。 */ private drawLabel; /** * 在格子中央绘制圆形头像占位。 * * 优先使用已加载成功的头像图片(cover 裁剪成圆);头像 URL 缺失、加载失败或跨域被拒时, * 回退为「昵称首字母彩色圆」,底色由 id/label 稳定哈希得到,保证同一用户颜色固定。 */ private drawAvatarPlaceholder; /** * 取昵称首字符作为首字母头像文本;空昵称回退为 '?'。 * 用 Array.from 以正确处理 emoji / 代理对,拉丁字母转大写。 */ private avatarInitial; /** * 释放内部资源并重置状态。 */ private cleanup; } /** * 本地麦克风流轨道 */ export declare class LocalMicTrack extends LocalAudioTrack { constructor(captureOptions: MicCaptureOptions); /** * 开始采集 * @param opt 采集参数 */ startCapture(opt?: Partial<MicCaptureOptions>): Promise<void>; /** * 停止采集 */ stopCapture(): void; /** * 切换麦克风 * @param deviceId * @returns */ changeDeviceId(deviceId: string): Promise<void>; } /** * 屏幕共享音频流轨道 */ export declare class LocalScreenAudioTrack extends LocalAudioTrack { constructor(captureOptions: ScreenAudioCaptureOptions | true); /** * 停止采集 */ stopCapture(): void; } /** * 本地屏幕视频流轨道 */ export declare class LocalScreenTrack extends LocalVideoTrack { constructor(captureOptions: ScreenCaptureOptions); /** * 获取音频轨道 */ getAudioTrack(): LocalScreenAudioTrack | undefined; /** * 开始采集 * @param opt 采集参数 */ startCapture(opt?: Partial<ScreenCaptureOptions>): Promise<void>; /** * 停止采集 */ stopCapture(): void; } /** * 本地视频流轨道 */ export declare class LocalVideoTrack extends BaseWebrtcTrack { constructor(); /** * 挂载视频处理器(如美颜、虚化背景)。传入数组时按顺序串联。 * 需先 startCapture 采集到轨道后调用。 */ setProcessor(processor: TrackProcessor | TrackProcessor[]): Promise<void>; /** * 卸载视频处理器,还原为原始采集轨道。 */ removeProcessor(): Promise<void>; setMediaStreamTrack(mediaStreamTrack?: MediaStreamTrack): void; /** * 获取联播轨道(小流) * @param opt 联播轨道的发布参数 * @param owidth 原始宽度 * @param oheight 原始高度 */ getSimulcastTrack(opt: VideoPublishOptions, owidth?: number, oheight?: number): LocalVideoTrack; /** * 添加播放窗口 */ addPlayView(container: HTMLElement): void; /** * 是否存在播放窗口 */ hasPlayView(): boolean; /** * 移除播放窗口 */ removePlayView(container: HTMLElement): void; /** * 移除所有播放窗口 */ removeAllPlayViews(): void; /** * 将指定容器的视频进入画中画模式 * @param container 播放容器 * @param options 画中画配置 */ enterPictureInPicture(container: HTMLElement, options?: PipOptions): Promise<PipHandle>; /** * 退出指定容器的画中画 * @param container 播放容器 */ exitPictureInPicture(container: HTMLElement): Promise<void>; /** * 指定容器是否处于画中画模式 * @param container 播放容器 */ isPictureInPicture(container: HTMLElement): boolean; /** * 将指定容器的视频弹出到独立窗口(可拖到第二个显示器) * @param container 播放容器 * @param options 弹出窗口配置 */ popOutToWindow(container: HTMLElement, options?: PopOutOptions): PopOutHandle; /** * 关闭指定容器的弹出窗口 * @param container 原始播放容器 */ closePopOutWindow(container: HTMLElement): void; /** * 指定容器是否已弹出到独立窗口 * @param container 播放容器 */ isPopOut(container: HTMLElement): boolean; } /** * 处理器串联组合器:把多个 TrackProcessor 收敛成一个。 * 第一性原理——每个处理器都是 track→track 的变换,可逐级串联: * 源 → P1 → P2 → ... → processedTrack。 * * 音频链共享一个 AudioContext,避免每级单独创建上下文(浏览器对 AudioContext 数量有限制)。 */ export declare class ProcessorPipeline implements TrackProcessor { readonly name: string; processedTrack?: MediaStreamTrack; private processors; /** 仅当本组合器自建共享上下文时持有,destroy 时负责关闭 */ private ownedAudioContext?; constructor(processors: TrackProcessor[]); init(options: ProcessorOptions): Promise<void>; destroy(): Promise<void>; } /** * 远端混音流 * 参与者视角,服务端 mix-minus,排除自己以外 */ export declare class RemoteAudioMixTrack extends RemoteAudioTrack implements IRemoteAudioMixTrack { constructor(info: BaseTrackInfo, filterUids?: string[]); /** * 混音流中过滤的uid * @returns */ getFilterUids(): string[]; } /** * 远端音频流轨道 */ export declare class RemoteAudioTrack extends BaseWebrtcTrack { constructor(info: BaseTrackInfo, uid: string); /** * 是否正在播放 */ isPlaying(): boolean; /** * 播放音频(可指定播放设备) */ startPlay(opt?: AudioOutputOptions): Promise<void>; /** * 停止播放并释放对播放设备的占用 */ stopPlay(): void; } /** * 远端视频流轨道 */ export declare class RemoteVideoTrack extends BaseWebrtcTrack { /** * 业务期望的抖动缓冲目标延迟(ms)。undefined 表示使用浏览器默认自适应策略。 */ private jitterBufferTargetMs?; constructor(info: BaseTrackInfo, uid: string); /** * 添加播放窗口 */ addPlayView(container: HTMLElement): void; /** * 是否存在播放窗口 */ hasPlayView(): boolean; /** * 移除播放窗口 */ removePlayView(container: HTMLElement): void; /** * 移除所有播放窗口 */ removeAllPlayViews(): void; /** * 将指定容器的视频进入画中画模式 * @param container 播放容器 * @param options 画中画配置 */ enterPictureInPicture(container: HTMLElement, options?: PipOptions): Promise<PipHandle>; /** * 退出指定容器的画中画 * @param container 播放容器 */ exitPictureInPicture(container: HTMLElement): Promise<void>; /** * 指定容器是否处于画中画模式 * @param container 播放容器 */ isPictureInPicture(container: HTMLElement): boolean; /** * 将指定容器的视频弹出到独立窗口(可拖到第二个显示器) * @param container 播放容器 * @param options 弹出窗口配置 */ popOutToWindow(container: HTMLElement, options?: PopOutOptions): PopOutHandle; /** * 关闭指定容器的弹出窗口 * @param container 原始播放容器 */ closePopOutWindow(container: HTMLElement): void; /** * 指定容器是否已弹出到独立窗口 * @param container 播放容器 */ isPopOut(container: HTMLElement): boolean; /** * 设置接收端抗抖动缓冲的目标延迟(ms),命名与 W3C jitterBufferTarget 规范对齐。 * - 0:低延迟优先,浏览器会保持最小可用 buffer * - 较大值(如 200~500):缓冲优先,更平滑但延迟更高 * - undefined:清除设置,回到浏览器自适应 * 实际生效需要 Chrome/Edge(同时兼容 jitterBufferTarget 与老的 playoutDelayHint), * Firefox/Safari 静默忽略。 */ setJitterBufferTarget(ms?: number): void; /** * 获取业务当前设定的抖动缓冲目标延迟(ms);undefined 表示未设置。 */ getJitterBufferTarget(): number | undefined; /** * 同时写 jitterBufferTarget(W3C 标准,Chrome 113+)和 playoutDelayHint * (Chrome 私有扩展,Chrome 70+),让新老浏览器都能生效。 * 浏览器只支持其中一个时另一个不存在,'in' 判断后静默跳过。 */ private applyJitterBufferTarget; } export declare class SRTC extends BaseSRTC { /** 窄化父类的 channel 类型到 webrtc Channel,便于访问 webrtc 特有方法 */ protected channel?: Channel | null; /** * 获取流媒体引擎的metric快照(全量,含每条轨道的统计) */ getStreamMetric(): StreamMetric | undefined; /** * 获取当前网络总体统计,只关心网络全景时用,比 getStreamMetric 更轻量 */ getNetworkStats(): NetworkStats | undefined; /** * 获取当前连接质量评估结果(等级 / MOS / 触发原因) * 配合 ChannelEventType.CONNECTION_QUALITY_CHANGED 事件使用 */ getConnectionQuality(): QualityEvaluation | undefined; buildInfo(): BuildInfo; /** * 获取web运行环境信息,如是否支持webrtc等 * @returns */ getEnvInfo(): EnvWebInfo; /** * 创建本地合成录制器。 * * 该录制器只负责把调用方传入的视频轨道、音频轨道合成为本地文件; * 宫格分页、主讲人切换、共享屏幕优先级等业务视角需要由上层计算后通过 updateVideoItems 传入。 */ createLocalCompositeRecorder(): LocalCompositeRecorder; constructor(initParams: SdkInitParams); /** * 获取设备列表 * @param kind * @param requestPermissions * @returns */ getDevices(kind?: MediaDeviceKind, requestPermissions?: boolean): Promise<MediaDeviceInfo[]>; /** * 创建麦克风本地音频流 * @param preset 麦克风预设,默认为 MicPresets.music */ createLocalMicTrack(preset?: MicPreset): LocalMicTrack; /** * 创建自定义本地音频流 */ createLocalCustomAudioTrack(msTrack: MediaStreamTrack): LocalAudioTrack; /** * 创建摄像头本地视频流 * @param preset 摄像头预设,默认为 CameraPresets["720p"] */ createLocalCameraTrack(preset?: CameraPreset): LocalCameraTrack; /** * 创建屏幕共享本地视频流 * @param preset 屏幕共享预设,默认为 ScreenPresets["1080p"] * @param audioPreset 屏幕共享音频预设,默认为 ScreenAudioPresets["default"] */ createLocalScreenTrack(preset?: ScreenPreset, audioPreset?: ScreenAudioPreset): LocalScreenTrack; /** * 创建自定义本地视频流 */ createLocalCustomVideoTrack(msTrack: MediaStreamTrack): LocalVideoTrack; /** * 临时enable本地流轨道,如取消静音麦克风 */ enableLocalTrack(track: LocalAudioTrack | LocalVideoTrack): Promise<void>; /** * 临时disable本地流轨道,如临时静音麦克风 * 比unpublishLocalTrack取消发布轨道轻 */ disableLocalTrack(track: LocalAudioTrack | LocalVideoTrack): void; /** * 发布本地流轨道 * @param track * @returns */ publishLocalTrack(track: LocalAudioTrack | LocalVideoTrack, opt?: Partial<AudioPublishOptions> | Partial<VideoPublishOptions>): Promise<void>; /** * 取消发布本地流 * @param track */ unpublishLocalTrack(track: LocalAudioTrack | LocalVideoTrack): Promise<void>; /** * 订阅远端频道混音流 * @param filter 音频轨道过滤器,传递string[]时,根据uid过滤 */ subscribeRemoteAudioMixTrack(filter?: ((track: BaseTrack) => boolean) | string[]): Promise<RemoteAudioMixTrack>; /** * 订阅远端用户音频流 * @param uid 用户id * @param id 流轨道id */ subscribeRemoteAudioTrack(uid: string, id: string): Promise<RemoteAudioTrack>; /** * 订阅远端视频合成流 */ subscribeRemoteVideoMcuTrack(): Promise<RemoteVideoMcuTrack>; /** * 订阅远端用户视频流 * @param uid 用户id * @param id 流轨道id */ subscribeRemoteVideoTrack(uid: string, id: string): Promise<RemoteVideoTrack>; /** * 取消订阅远端流 */ unsubscribeRemoteTrack(track: RemoteAudioMixTrack | RemoteAudioTrack | RemoteVideoTrack): Promise<void>; getRemoteTrack(uid: string, id?: string, desc?: string): RemoteAudioTrack | RemoteVideoTrack; } /** * 摄像头预设参数 */ export declare const CameraPresets: { /** 分辨率1920*1080,帧率15,码率2.5Mbps */ "1080p": CameraPreset; /** 分辨率1280*720,帧率15,码率1.2Mbps,createLocalCameraTrack的默认预设参数 */ "720p": CameraPreset; /** 分辨率640*360,帧率15,码率550Kbps */ "360p": CameraPreset; /** 分辨率320*180,帧率15,码率250Kbps */ "180p": CameraPreset; }; /** * 麦克风预设参数 */ export declare const MicPresets: { /** 单声道,采样率48kHz,码率24Kbps */ speech: MicPreset; /** 单声道,采样率48kHz,码率32Kbps,createLocalMicTrack的默认预设参数 */ music: MicPreset; /** 双声道,采样率48kHz,码率48Kbps */ musicStereo: MicPreset; /** 单声道,采样率48kHz,码率64Kbps */ musicHighQuality: MicPreset; /** 双声道,采样率48kHz,码率96Kbps */ musicHighQualityStereo: MicPreset; }; /** * 屏幕共享系统音频预设参数 */ export declare const ScreenAudioPresets: { /** 系统音频,码率24Kbps */ default: ScreenAudioPreset; }; /** * 屏幕共享预设参数 */ export declare const ScreenPresets: { /** 分辨率1920*1080,帧率10,码率2Mbps,createLocalScreenTrack时的默认预设参数 */ "1080p": ScreenPreset; /** 分辨率1280*720,帧率10,码率1.5Mbps */ "720p": ScreenPreset; }; /** * 编码类型 */ export declare enum Codec { /** h264编码 */ H264 = 27, /** h265编码 */ H265 = 36, /** AAC编码 */ AAC = 15, /** VP8编码 */ VP8 = 56, /** VP9编码 */ VP9 = 57, /** AV1编码 */ AV1 = 58, /** OPUS编码 */ OPUS = 1398100047 } /** * 连接质量等级(对齐 LiveKit 5 档) */ export declare enum ConnectionQuality { /** 初始占位,采样不足时使用,避免误报 */ Unknown = "unknown", /** 优秀:几乎无损 */ Excellent = "excellent", /** 良好:轻微丢包或延迟 */ Good = "good", /** 较差:明显卡顿、丢包或被 cpu/bandwidth 限制 */ Poor = "poor", /** 连接已丢失,媒体无法传输,应触发重连 */ Lost = "lost" } /** * 终端类型枚举 */ export declare enum DeviceType { /** * 未知设备 */ Unknown = 0, /** * Windows */ Windows = 1, /** * Android */ Android = 2, /** * iOS */ IOS = 3, /** * Linux */ Linux = 4, /** * MacOS */ MacOS = 5, /** * webrtc */ WebRTC = 6, /** * 小程序 */ XCX = 7 } /** 用户离开频道的原因 */ export declare enum DisconnectReason { /** 错误 */ Error = -1, /** 主动离开 */ Self = 1, /** 被踢离开 */ Kicked = 2, /** 被顶号 */ Replace = 3, /** 心跳超时离开 */ Timeout = 4, /** 频道销毁离开 */ Destroy = 5 } /** 用户断开im的原因 */ export declare enum ImDisconnectReason { /** 错误 */ Error = -1, /** 主动离开 */ Self = 1, /** 被踢离开 */ Kicked = 2, /** 心跳超时离开 */ Timeout = 4 } /** * 日志打印等级 */ export declare enum LogLevel { DEBUG = "debug", INFO = "info", WARN = "warn", ERROR = "error" } /** * 日志打印目标 */ export declare enum LogTarget { /** 控制台打印 */ CONSOLE = "console", /** 微信实时日志 */ WXREALTIME = "wxrealtime", /** 不打任何日志 */ NONE = "none" } /** * 流轨道类型 */ export declare enum TrackKind { Video = "video", Audio = "audio" } /** * 编码类型转字符串 * @param codec * @returns */ export declare function codec2str(codec: Codec): string; /** * 创建混音后的音频轨 */ export declare function createMixedAudioMediaStreamTrack(canvasContext?: CanvasRenderingContext2D): MixedAudioMediaStreamTrack; /** * MessageIdProvider */ export declare interface IMessageIdProvider { /** * Allocate the first vacant messageId. The messageId become occupied status. * @return {Number} - The first vacant messageId. If all messageIds are occupied, return null. */ allocate(): Number | null; /** * Get the last allocated messageId. * @return {Number} - messageId. */ getLastAllocated(): Number | null; /** * Register the messageId. The messageId become occupied status. * If the messageId has already been occupied, then return false. * @param {Number} num - The messageId to request use. * @return {Boolean} - If `num` was not occupied, then return true, otherwise return false. */ register(num: Number): Boolean; /** * Deallocate the messageId. The messageId become vacant status. * @param {Number} num - The messageId to deallocate. The messageId must be occupied status. * In other words, the messageId must be allocated by allocate() or * occupied by register(). */ deallocate(num: Number): void; /** * Clear all occupied messageIds. * The all messageIds are set to vacant status. */ clear(): void; } export declare namespace __INNER__ { const BaseSRTC_I: typeof BaseSRTC; const CommonChannelEventType_I: typeof CommonChannelEventType; const isWxxcx_I: typeof isWxxcx; const Logger_I: typeof Logger; const SdkError_I: typeof SdkError; const propAssign_I: typeof propAssign; const isObject_I: typeof isObject; const isString_I: typeof isString; const sleep_I: typeof sleep; const retry_I: typeof retry; const dateFormat_I: typeof dateFormat; const genNonce_I: typeof genNonce; const getHostnameFromUrl_I: typeof getHostnameFromUrl; const dct_I: typeof dct; function hmac_I(msg: string, key: string): string; } export declare type ClientSubscribeCallback = (err: Error, granted: ISubscriptionGrant[]) => void; export declare type CloseCallback = (error?: Error) => void; export declare type OnCloseCallback = () => void; export declare type OnConnectCallback = (packet: IConnackPacket) => void; export declare type OnDisconnectCallback = (packet: IDisconnectPacket) => void; export declare type OnErrorCallback = (error: Error) => void; export declare type OnMessageCallback = (topic: string, payload: Buffer, packet: IPublishPacket) => void; export declare type OnPacketCallback = (packet: Packet) => void; export declare type PacketCallback = (error?: Error, packet?: Packe