@seastart/srtc-web-sdk
Version:
srtc sdk for web
1,955 lines (1,954 loc) • 105 kB
TypeScript
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