引入方式
通过
<script> 标签引入 SDK,加载后通过全局变量 window.TcccUserCall 获取所有对外接口。<script src="https://tccc.qcloud.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 = 1400000000;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();
createUser(创建用户)
创建并返回一个用户实例。
说明:
SDK 同一时间只允许存在一个
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',});
TcccSipUser(用户实例)
代表一个用户实例。通过
createUser() 创建,负责管理与服务器的连接、发起呼叫等。方法
初始化
user.init(): Promise<void>
初始化 SDK,建立与服务器的 WebSocket 连接。连接成功后会首次触发
ready 事件。销毁
user.unInit(): Promise<void>
销毁实例,断开连接,清理所有事件监听和活跃会话。页面卸载或不再需要时应调用此方法释放资源。销毁后方可通过
createUser() 创建新实例。更新用户签名
user.updateUserSig(userSig, userClientData): void
更新用户签名。当外呼时遇到报错,且错误码
code 为 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) 监听。初始化完成事件
ready
SDK 首次就绪(连接建立成功),此后可发起呼叫。无事件对象参数。
ws 连接中事件
connecting
WebSocket 正在连接中。
事件对象参数:
字段 | 类型 | 说明 |
attempts | number | 当前连接尝试次数。 |
ws 已连接事件
connected
WebSocket 连接成功(包括重连成功)。无事件对象参数。
ws 连接断开事件
disconnected
WebSocket 连接断开。
事件对象参数:
字段 | 类型 | 说明 |
error | boolean | 是否为异常断开。 |
code | number | 断开状态码(可选)。 |
reason | string | 断开原因描述(可选)。 |
Session(通话会话)
Session 是通话会话对象,由 user.startAudioCall() 返回。提供通话控制方法和通话状态事件。说明:
代表一次通话过程,如果通话结束了,不要再使用该对象做任何操作
方法
挂断通话
session.terminate(): void
挂断 / 结束当前通话。
session.terminate();
静音本地麦克风
session.muteAudio(mute): Promise<void>
本地麦克风静音或取消静音。
说明:
参数 | 类型 | 说明 |
mute | boolean | true 静音,false 取消静音。 |
await session.muteAudio(true); // 静音await session.muteAudio(false); // 取消静音
发送 DTMF
session.sendDTMFTone(tone, options?): Promise<void>
发送单个 DTMF 按键信号(例如 IVR 按键导航)。连续调用时会自动排队依次发送。
参数 | 类型 | 必填 | 说明 |
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(): boolean
判断当前通话是否已结束。
查询通话是否正在建立中
session.isInProgress(): boolean
判断当前通话是否正在建立中。
查询通话是否已建立
session.isEstablished(): boolean
判断当前通话是否已建立。
事件
通过
session.on(eventName, callback) 监听。通话建立进度事件
progress
收到对方振铃。事件对象参数中的
response 是一个对象,包含以下字段:字段 | 类型 | 说明 |
response.status_code | number | SIP 状态码,例如 180 表示振铃、183 表示会话进展。 |
response.reason_phrase | string | SIP 状态描述,例如 'Ringing'、'Session Progress'。 |
对方已接听事件
accepted
对方接听通话。无事件对象参数。
通话已确定事件
confirmed
当对方已接听并且本地协议栈确认后(发送了 ack 信令)会触发该事件。无事件对象参数。
已进入 TRTC 房间事件
onRoomEntered
本地已进入音频房间,音频通道就绪。无事件对象参数。
通话正常结束事件
ended
通话正常结束。事件对象参数:
字段 | 类型 | 说明 |
cause | string |
通话失败结束事件
failed
通话失败(被拒、超时等)。该事件触发后,当前会话已结束,可重新发起新的呼叫。事件对象参数:
字段 | 类型 | 说明 |
cause | string |
通话结束原因(cause 对照表)
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 超时(媒体流中断)。 |
错误码参考
SDK 所有调用方法异常均以
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 模块
错误码 | 常量 | 说明 |
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()。 |
Rtc 模块
设备与音视频相关错误。部分错误的
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 附加错误码,用于进一步区分原因。 |
Cgi 模块
网络请求相关错误。部分错误的
detail 可能包含 CgiDetail 信息(见下方说明)。错误码 | 常量 | 说明 | detail |
Cgi.BizError | ErrorCode.Cgi.BizError | 服务端业务逻辑错误(HTTP 成功但业务返回失败)。 | CgiDetail |
Cgi.Error | ErrorCode.Cgi.Error | 网络请求异常(超时/网络不可达等)。 | CgiDetail |
CgiDetail:
detail 不一定存在,即使存在,其中的各字段也不一定有值。排查问题时请将 requestId 提供给技术支持。字段 | 类型 | 说明 |
bizCode | string | 服务端返回的业务错误码。 |
httpStatus | number | HTTP 响应状态码。 |
requestId | string | 请求唯一标识,排查问题时请提供给技术支持。 |
code | string | 网络层错误码(例如 ERR_NETWORK)。 |
Session 模块
通话会话相关错误。
错误码 | 常量 | 说明 |
Session.TrtcClientNotExist | ErrorCode.Session.TrtcClientNotExist | TRTC 客户端实例不存在,通话可能尚未建立或已结束 |
Dtmf 模块
DTMF 按键发送相关错误。
错误码 | 常量 | 说明 |
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 响应错误。 |
浏览器要求
必须在 HTTPS 环境下使用(或
localhost),否则浏览器将禁止访问麦克风。推荐浏览器:Chrome 75+、Edge 80+、Firefox 80+。
常见问题
Q1: 调用 createUser 报错 User.InstanceExists?
SDK 同一时间只允许存在一个用户实例。请先调用已有实例的
unInit() 方法销毁后,再创建新实例。Q2: 调用 startAudioCall 报错 User.NotReady?
请确保在
ready 事件触发之后再发起呼叫。ready 事件表示连接已建立,SDK 已就绪。Q3: 报错 Rtc.MicNotAllowed?
浏览器弹出了麦克风授权弹窗但被用户拒绝。请引导用户点击浏览器地址栏左侧的锁图标,重新开启麦克风权限。
Q4: 报错 User.InvalidUserSig?
userSig 已过期或签名计算有误。请检查后端签名生成逻辑,并调用 user.updateUserSig() 更新后重新发起呼叫。Q5: 报错 Rtc.InsecureContext?
页面未通过 HTTPS 加载。浏览器出于安全策略禁止在 HTTP 页面中使用麦克风。请将页面部署在 HTTPS 环境下,或在本地开发时使用
localhost。Q6: 能否同时发起多个通话?
不支持。SDK 同一时间只允许一个活跃通话。若已有通话进行中再次调用
startAudioCall 会抛出 User.CallInProgress 错误。