<script> 标签引入 SDK,加载后通过全局变量 window.TcccUserCall 获取所有对外接口。<script src="https://connect.tencentcloud.com/sdk/tccc-user-call-sdk.umd.js?sdkAppId=your_sdkAppId&userId=your_userId"></script><script>const { createUser, TcccSipError, ErrorCode } = window.TcccUserCall;</script>
名称 | 类型 | 说明 |
createUser | Function | 创建用户实例的工厂函数。 |
TcccSipError | Class | SDK 统一错误类,所有异常均为此类或其子类的实例。 |
ErrorCode | Object | 错误码常量对象,用于判断具体错误类型。 |
async function start () {const sdkAppId = 20000000;const userId = 'xxx';const audioChannelId = 'xxx';// 1. 调用业务方后台接口获取 userSig// 参考 “前置准备” 里 nodejs的例子const response = await fetch('https://example.api.com/genUserSig?userId=' + encodeURIComponent(userId), {method: 'GET',});if (!response.ok) {throw new Error(`HTTP 错误!状态码: ${response.status}`);}const { userSig } = await response.json();// 2. 创建用户实例const { createUser, TcccSipError, ErrorCode } = window.TcccUserCall;const user = createUser({sdkAppId,userId,userSig,});// 3. 监听ready事件user.on('ready', () => {console.log('SDK 就绪,可以发起呼叫');// 5. 发起音频呼叫(需在 ready 事件触发后调用)makeCall(audioChannelId)});// 4. 初始化(建立连接)user.init();async function makeCall(audioChannelId) {try {const session = await user.startAudioCall(audioChannelId);session.on('progress', (event) => {const { status_code, reason_phrase } = event.response;if (status_code === 180 || status_code === 183) {console.log('对方振铃中', reason_phrase);}});session.on('accepted', () => {console.log('对方已接听');});session.on('ended', (event) => {console.log('通话结束', event.cause);});session.on('failed', (event) => {console.error('呼叫失败', event.cause);});} catch (err) {if (err instanceof TcccSipError) {console.error('呼叫出错 [' + err.code + ']: ' + err.message);}}}// 6. 当不再需要外呼时(如页面销毁),调用 cleanup 释放资源async function cleanup() {await user.unInit();}}start();
TcccSipUser 实例。若需创建新实例,必须先调用当前实例的 unInit() 方法销毁,否则会抛出 User.InstanceExists 错误。参数 | 类型 | 必填 | 说明 |
sdkAppId | number | 是 | 腾讯云联络中心的 SDKAppId。 |
userId | string | 是 | 业务侧用户 ID,不能为空且不能包含 @ 字符。若使用邮箱作为用户标识,请替换为 URL 安全的标识符。 |
userSig | string | 是 | |
userClientData | string | 否 |
TcccSipUser — 用户实例对象。const user = createUser({sdkAppId: 1400000000, // 类型为numberuserId: 'your_userId',userSig: 'your_userSig',});
createUser() 创建,负责管理与服务器的连接、发起呼叫等。user.init(): Promise<void>ready 事件。user.unInit(): Promise<void>createUser() 创建新实例。user.updateUserSig(userSig, userClientData): voidcode 为 User.InvalidUserSig 时,可调用此方法更新签名后重新发起呼叫。参数 | 类型 | 必填 | 说明 |
userSig | string | 是 | |
userClientData | string | 否 |
try {await user.startAudioCall('xxx');} catch (err) {if (err.code === ErrorCode.User.InvalidUserSig) {user.updateUserSig('新的userSig');// 更新后重新发起呼叫}}
user.startAudioCall(audioChannelId): Promise<Session>ready 事件触发后才能调用。User.CallInProgress 错误。需等待当前通话结束或主动调用 session.terminate() 挂断后,才能发起新的呼叫。参数 | 类型 | 必填 | 说明 |
audioChannelId | string | 是 |
try {const session = await user.startAudioCall('xxx');} catch (err) {if (err.code === ErrorCode.User.CallInProgress) {console.error('当前已有进行中的通话');}}
user.on(eventName, callback) 监听。字段 | 类型 | 说明 |
attempts | number | 当前连接尝试次数。 |
字段 | 类型 | 说明 |
error | boolean | 是否为异常断开。 |
code | number | 断开状态码(可选)。 |
reason | string | 断开原因描述(可选)。 |
Session 是通话会话对象,由 user.startAudioCall() 返回。提供通话控制方法和通话状态事件。session.terminate(): voidsession.terminate();
session.muteAudio(mute): Promise<void>参数 | 类型 | 说明 |
mute | boolean | true 静音,false 取消静音。 |
await session.muteAudio(true); // 静音await session.muteAudio(false); // 取消静音
session.sendDTMFTone(tone, options?): Promise<void>参数 | 类型 | 必填 | 说明 |
tone | string | 是 | 单个 DTMF 按键字符,取值范围为 0-9、#、*。 |
options.duration | number | 否 | DTMF 信号持续时间(ms)。 |
options.interToneGap | number | 否 | 与下一个 DTMF 信号的间隔时间(ms)。 |
await session.sendDTMFTone('1');await session.sendDTMFTone('#');
session.isMuted(): { audio: boolean }const { audio } = session.isMuted();console.log('是否静音:', audio);
session.isEnded(): booleansession.isInProgress(): booleansession.isEstablished(): booleansession.on(eventName, callback) 监听。response 是一个对象,包含以下字段:字段 | 类型 | 说明 |
response.status_code | number | SIP 状态码,例如 180 表示振铃、183 表示会话进展。 |
response.reason_phrase | string | SIP 状态描述,例如 'Ringing'、'Session Progress'。 |
字段 | 类型 | 说明 |
cause | string |
字段 | 类型 | 说明 |
cause | string |
ended 和 failed 事件中 cause 字段的可能值:cause 值 | 说明 |
Terminated | 通话正常挂断。 |
Canceled | 主叫在对方接听前取消了呼叫。 |
Busy | 对方忙线。 |
Rejected | 呼叫被拒绝。 |
Not Found | 被叫号码不存在。 |
Unavailable | 被叫暂时不可用。 |
No Answer | 对方无应答。 |
Expires | 通话超时。 |
Request Timeout | 请求超时。 |
Connection Error | 网络连接错误。 |
SIP Failure Code | 其他 SIP 错误。 |
Internal Error | 内部错误。 |
Address Incomplete | 号码地址不完整。 |
Authentication Error | 认证错误。 |
Dialog Error | 对话错误。 |
User Denied Media Access | 用户拒绝媒体访问权限。 |
WebRTC Error | WebRTC 错误。 |
RTP Timeout | RTP 超时(媒体流中断)。 |
TcccSipError(或其子类)的形式抛出。属性 | 类型 | 说明 |
code | string | 错误码,格式为 模块.描述,例如 User.NotReady。 |
message | string | 人类可读的错误描述。 |
detail | object | undefined | 结构化附加信息(部分错误码有此字段)。 |
fullMessage | string | 完整错误链信息,多层错误以换行连接。 |
const { TcccSipError, ErrorCode } = window.TcccUserCall;try {await user.startAudioCall('xxx');} catch (err) {// 方式一:instanceof 判断if (err instanceof TcccSipError) {console.error(err.code, err.message);}// 方式二:使用 ErrorCode 常量精确匹配if (err.code === ErrorCode.User.InvalidUserSig) {user.updateUserSig('新的userSig');}// 方式三:查看完整错误链if (err instanceof TcccSipError) {console.error(err.fullMessage);}}
错误码 | 常量 | 说明 |
User.InvalidUserId | ErrorCode.User.InvalidUserId | userId 不合法:不能为空、不能包含 @。 |
User.InstanceExists | ErrorCode.User.InstanceExists | 已存在一个用户实例,请先调用 unInit() 销毁后再创建新实例。 |
User.NotReady | ErrorCode.User.NotReady | SDK 尚未就绪,请在 ready 事件后再发起呼叫。 |
User.Disconnected | ErrorCode.User.Disconnected | WebSocket 连接已断开。 |
User.CallInProgress | ErrorCode.User.CallInProgress | 当前已有一个进行中的通话。 |
User.InvalidUserSig | ErrorCode.User.InvalidUserSig | userSig 无效或已过期。 |
User.Destroyed | ErrorCode.User.Destroyed | 实例已被销毁,请勿重复调用 unInit()。 |
detail 可能包含 RtcDetail 信息(见下方说明)。错误码 | 常量 | 说明 | detail |
Rtc.NotInRoom | ErrorCode.Rtc.NotInRoom | 不在房间中,无法执行静音等操作。 | — |
Rtc.Destroyed | ErrorCode.Rtc.Destroyed | TRTC 实例已被销毁。 | — |
Rtc.PublishStopped | ErrorCode.Rtc.PublishStopped | 音频发布失败或被停止。 | RtcDetail |
Rtc.JoinRoomFailed | ErrorCode.Rtc.JoinRoomFailed | 进入音频房间失败。 | RtcDetail |
Rtc.Trtc | ErrorCode.Rtc.Trtc | TRTC 通用错误。 | RtcDetail |
Rtc.KickedOut | ErrorCode.Rtc.KickedOut | 被踢出房间(如重复登录)。 | — |
Rtc.CheckDeviceFailed | ErrorCode.Rtc.CheckDeviceFailed | 设备检测失败(其他未知原因)。 | — |
Rtc.MicNotFound | ErrorCode.Rtc.MicNotFound | 未检测到麦克风设备。 | RtcDetail |
Rtc.MicNotAllowed | ErrorCode.Rtc.MicNotAllowed | 用户拒绝了麦克风权限。 | RtcDetail |
Rtc.MicNotReadable | ErrorCode.Rtc.MicNotReadable | 麦克风不可读(可能被其他应用占用)。 | RtcDetail |
Rtc.MicTimeout | ErrorCode.Rtc.MicTimeout | 麦克风采集超时(用户未响应授权弹窗)。 | — |
Rtc.InsecureContext | ErrorCode.Rtc.InsecureContext | 非 HTTPS 环境,浏览器禁止访问麦克风。 | — |
字段 | 类型 | 说明 |
code | number | TRTC 错误码。 |
extraCode | number | TRTC 附加错误码,用于进一步区分原因。 |
detail 可能包含 CgiDetail 信息(见下方说明)。错误码 | 常量 | 说明 | detail |
Cgi.BizError | ErrorCode.Cgi.BizError | 服务端业务逻辑错误(HTTP 成功但业务返回失败)。 | CgiDetail |
Cgi.Error | ErrorCode.Cgi.Error | 网络请求异常(超时/网络不可达等)。 | CgiDetail |
detail 不一定存在,即使存在,其中的各字段也不一定有值。排查问题时请将 requestId 提供给技术支持。字段 | 类型 | 说明 |
bizCode | string | 服务端返回的业务错误码。 |
httpStatus | number | HTTP 响应状态码。 |
requestId | string | 请求唯一标识,排查问题时请提供给技术支持。 |
code | string | 网络层错误码(例如 ERR_NETWORK)。 |
错误码 | 常量 | 说明 |
Session.TrtcClientNotExist | ErrorCode.Session.TrtcClientNotExist | TRTC 客户端实例不存在,通话可能尚未建立或已结束 |
错误码 | 常量 | 说明 |
Dtmf.InvalidParam | ErrorCode.Dtmf.InvalidParam | DTMF 参数不合法(例如 tone 为空或非单字符)。 |
Dtmf.InvalidState | ErrorCode.Dtmf.InvalidState | 当前通话状态不允许发送 DTMF(通话未建立)。 |
Dtmf.SendFailed | ErrorCode.Dtmf.SendFailed | DTMF 发送失败。 |
Dtmf.Timeout | ErrorCode.Dtmf.Timeout | DTMF 发送超时。 |
Dtmf.TransportError | ErrorCode.Dtmf.TransportError | DTMF 传输层错误。 |
Dtmf.DialogError | ErrorCode.Dtmf.DialogError | DTMF 对话错误。 |
Dtmf.ResponseError | ErrorCode.Dtmf.ResponseError | DTMF 响应错误。 |
localhost),否则浏览器将禁止访问麦克风。createUser 报错 User.InstanceExists?unInit() 方法销毁后,再创建新实例。startAudioCall 报错 User.NotReady?ready 事件触发之后再发起呼叫。ready 事件表示连接已建立,SDK 已就绪。Rtc.MicNotAllowed?User.InvalidUserSig?userSig 已过期或签名计算有误。请检查后端签名生成逻辑,并调用 user.updateUserSig() 更新后重新发起呼叫。Rtc.InsecureContext?localhost。startAudioCall 会抛出 User.CallInProgress 错误。文档反馈