web通话呼叫中⼼接⼊说明
<h2>⼀ 通话接⼊基本流程</h2>
<h3>1.1 初始化rtcsdk</h3>
<p><img src="https://dumi-dueros-bj-tob.cdn.bcebos.com/amis/2023-9/1694689929246/WX20230914-191122%402x.png" alt="" />
<code>说明: </code></p>
<ul>
<li>
<p><strong>rtc_appid:</strong>⼩度分配给接⼊⽅的通话应⽤标识,标识⼀个⾳视频服务接⼊⽅</p>
</li>
<li>
<p><strong>rtc_appsecret:</strong>⼩度分配给接⼊的rtc_appid对应的密钥,⽤于⽣成rtctoken,要保存在云端,不可放置在web端</p>
</li>
<li>
<p><strong>uid:</strong>接⼊⽅为呼叫中⼼⼈员分配的唯⼀标识,可以⽤系统的⽤户id、⼿机号或其他⽤户唯⼀标识,需要保证在分配的appid下唯⼀</p>
</li>
<li><strong>rtctoken:</strong>基于rtc_appid、rtc_appsecret、uid等信息⽣成,⽤于初始化rtcsdk,因为rtc_appsecret需要保密(平台基于rtctoken鉴权,如果rtc_appsecret泄露会 导致⾮法的⾳视频访问),需要由接⼊⽅云端提供接⼝给⾃⼰的web端获取,⽣成⽅法详⻅《[token⽣成算法](<a href="https://www.showdoc.com.cn/2104324603939229/10560921702509284">https://www.showdoc.com.cn/2104324603939229/10560921702509284</a> "token⽣成算法")》</li>
</ul>
<p><code>rtctoken有有效期概念,⼀般建议设置⼀天,过期之后再从云端获取</code></p>
<h3>1.2 web拨打⾳箱</h3>
<p><img src="https://dumi-dueros-bj-tob.cdn.bcebos.com/amis/2023-9/1694690560131/WX20230914-192111%402x.png" alt="" /></p>
<p><code>说明:</code></p>
<p><strong>callAppid、callAddress</strong>:</p>
<ul>
<li>通过接⼝获取,详⻅接⼝⽂档:<a href="https://dueros.baidu.com/business/emp/view/doc?md=%2Fmd%2Felder%2Fget-device-info.md">https://dueros.baidu.com/business/emp/view/doc?md=%2Fmd%2Felder%2Fget-device-info.md</a> </li>
</ul>
<p><strong>web呼出鉴权逻辑:</strong>web打给⾳箱系统会判断,⾳箱的⾏业联系⼈列表⾥是否有该呼叫中⼼号码,将⼀个呼叫中⼼号码添加到⾳箱的联系⼈分两步</p>
<ul>
<li>步骤⼀:把呼叫中⼼号码添加为⾳箱联系⼈</li>
<li>步骤⼆:将呼叫中⼼⼈员的uid与呼叫中⼼号码建⽴关联通过接⼝对接,详⻅以下接⼝⽂档</li>
</ul>
<p><strong>接口文档</strong></p>
<ul>
<li>同步联系⼈:<a href="https://dueros.baidu.com/business/emp/view/doc?md=%2Fmd%2Felder%2Fcontact.md">https://dueros.baidu.com/business/emp/view/doc?md=%2Fmd%2Felder%2Fcontact.md</a></li>
<li>呼叫中⼼挂uid:<a href="https://dueros.baidu.com/business/emp/view/doc?md=%2Fmd%2Felder%2Fvirtual-uid.md">https://dueros.baidu.com/business/emp/view/doc?md=%2Fmd%2Felder%2Fvirtual-uid.md</a></li>
</ul>
<h3>1.3 ⾳箱拨打web</h3>
<p></p>
<ul>
<li>WEB⻚⾯需要保持rtcsdk的⻓连接⼀直处于连接状态,才能收到rtcsdk回调的来电通知</li>
<li>来电通知的intent结构⾥的serviceinfo字段中包含来电的设备sn信息,可以基于 sn到云端查询来电⼈姓名</li>
</ul>
<h2>⼆ sdk引⼊⽅式</h2>
<p><code>sdk的使⽤案例可参考[js_sdk_demo](https://www.showdoc.com.cn/2104324603939229/10560908748024821 &quot;js_sdk_demo&quot;)</code></p>
<h3>2.1 html静态引⼊</h3>
<pre><code class="language-html">&lt;!doctype html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;title&gt;xxx&lt;/title&gt;
&lt;meta charset='UTF-8'&gt;
&lt;meta name='viewport' content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no'&gt;
&lt;!-- 引⼊通话web sdk --&gt;
&lt;script src=&quot;//dumi-dueros-bj-tob.cdn.bcebos.com/amis/2023-7/1689057679200/duerwebsdk.1.3.0.js&quot;&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
<h3>2.2 局部⻚⾯动态引⼊</h3>
<pre><code class="language-html">/**
*动态引⼊js脚本
*@param url https://dumi-dueros-bj-tob.cdn.bcebos.com/amis/2023-7/1689057679200/duerwebsdk.1.3.0.js
*@param cb sdk加载成功后的回调
*/
function importScript(url, cb) {
let head = document.getElementsByTagName('head')[0]; let script = document.createElement('script'); script.src = url;
if (script.addEventListener) { script.addEventListener('load', function () {
if (cb) {
cb();
}
}, false);
}
else if (script.attachEvent) { script.attachEvent('onreadystatechange', function () {
if (cb) {
cb();
}
});
}
head.appendChild(script);
}
importScript('https://dumi-dueros-bj-tob.cdn.bcebos.com/amis/2023-7/1689057679200/duerwebsdk.1.3.0.js', _ =&gt; {
// ⽅法加载完成回调,可进⾏sdk⽅法调⽤
});</code></pre>
<p> </p>
<h3>2.3 ⽀持浏览器及版本</h3>
<ul>
<li>Chrome70+浏览器</li>
<li>Firefox66+浏览器</li>
<li>Edge90+浏览器</li>
<li>360 12.2+浏览器</li>
<li>QQ 10.8+浏览器</li>
<li>猎豹8+浏览器</li>
</ul>
<h2>三 建⽴⻓连接</h2>
<h3>3.1 相关定义</h3>
<table>
<thead>
<tr>
<th> </th>
<th>字段名</th>
<th>类型</th>
<th>取值说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>appName</td>
<td>String</td>
<td>应⽤名称,⽤于区分相同appId下的不同应⽤</td>
</tr>
<tr>
<td>token</td>
<td>String</td>
<td>⽣成规则⻅《token⽣成算法.zip》</td>
</tr>
<tr>
<td>rui</td>
<td>Object</td>
<td>应⽤⽤户唯⼀标识,⽣成规则参⻅下⽅示例代码</td>
</tr>
<tr>
<td>uid</td>
<td>String</td>
<td>应⽤账号体系中⽤户唯⼀标识</td>
</tr>
<tr>
<td>appid</td>
<td>String</td>
<td>应⽤程序唯⼀标识,由⼩度分配</td>
</tr>
</tbody>
</table>
<h3>3.2 代码</h3>
<pre><code class="language-html">// sdk挂载的⽅法
const duerRtcSdk = window.DUER_rtcsdk;
// 初始化rtc对象
const duerRtc = new duerRtcSdk.RtcContext ({ onAuthStatusChanged: auth =&gt; {
// 鉴权状态发⽣变化回调,对不同状态auth.code做分别处理
// 5000表示鉴权通过,可在此处进⾏⼊席操作duerRtc.enableCustomer(true);
// auth.code常⽤值⻅下⾯的常⽤值部分
},
}, enbaleRtcDebugLog); // 是否打印⽇志,建议线下调试设置为true,上线设置为false
// 构造参数建⽴⻓连接参数
/**
*uri RTC呼叫系统唯⼀标识定义
*@param uid 应⽤⽤户唯⼀标识
*@param appId 应⽤程序唯⼀标识,这⾥是rtc_appid,邮件分配的
*/
const uri = new duerRtcSdk.CallUri(uid, appId); const loginParams = {
uri: uri, uid: uid, appId: appId,
appName: appName, token: token
};
// 建⽴⻓连接
duerRtc.login(loginParams);</code></pre>
<p><code>注意:RTC只要调⽤login后,在明确调⽤logout之前⼀直维护⻓连接, 期间不论什么原因断开都会⾃动重连。但鉴权失败或者多登被踢下线的不会⾃动重试。</code></p>
<h3>3.1 离席⼊席说明(1.3.0版本新增)</h3>
<p><code>背景:1.3.0之前的版本,web在建⽴⻓连接成功之后,坐席可能需要⼏⼗秒的预热时间,在这期间web⽆法收到来电。1.3.0新增了⼊席离席功能,web在成功建⽴⻓连接之后,可以调⽤⼿动或⾃动⼊席操作,这样就可以跳过预热,收到来电。</code></p>
<h4>3.1.1 ⾃动⼊席离席(推荐)</h4>
<p>rtc⻓连接连接成功后调⽤duerRtc.enableCustomer(true),此后rtc⻓连接连上,就⾃动调⽤⼊席,断开就⾃动调⽤离席。被踢下线的坐席不会进⾏⼊席重试。</p>
<pre><code class="language-html">duerRtc.enableCustomer(true);</code></pre>
<h4>3.1.2 ⼿动⼊席离席</h4>
<p>rtc⻓连接连接成功后调⽤duerRtc.enableCustomer(false),在需要的地⽅再⼿动调⽤⼊席离席。当调⽤离席后,web将⽆法收到来电,但可以正常呼出,呼出后 就能正常收到来电。</p>
<pre><code class="language-html">const customer = duerRtc.enableCustomer(false);
// 在需要的地⽅⼿动调⽤离席⼊席操作
customer.join(); // ⼊席
customer.leave(); // 离席</code></pre>
<p><code>注意:⾃动和⼿动⼊席离席只能选择其⼀,要么⼀直⾃动,要么⼀直⼿动。</code></p>
<h2>四 通话相关监听事件设置</h2>
<h3>4.1 相关定义</h3>
<ul>
<li>通话intent(呼⼊、呼出)</li>
</ul>
<table>
<thead>
<tr>
<th>字段名</th>
<th>类型</th>
<th>取值说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>callMode</td>
<td>Number</td>
<td>⻅下⽅『常⽤值』CallMode</td>
</tr>
<tr>
<td>callerRole</td>
<td>Number</td>
<td>主叫⽅⻆⾊类型定义,⻅下⽅『常⽤值』CallerRole</td>
</tr>
<tr>
<td>direction</td>
<td>Number</td>
<td>呼⼊或呼出,⻅下⽅『常⽤值』CallDirection</td>
</tr>
<tr>
<td>index</td>
<td>Number</td>
<td>会话唯⼀标识(客户端⽣成),⼀次完整的通话流程中,所有消息拥有相同的值</td>
</tr>
<tr>
<td>peerUri</td>
<td>Object</td>
<td>对端uri,呼出场景是被叫uri,呼⼊是主叫uri</td>
</tr>
<tr>
<td>peerName</td>
<td>String</td>
<td>呼⼊⽅名字</td>
</tr>
<tr>
<td>peerNumber</td>
<td>String</td>
<td>呼⼊⽅号码</td>
</tr>
<tr>
<td>nickName</td>
<td>String</td>
<td>⽤户昵称,此字段将直接从主叫侧透传到被叫侧</td>
</tr>
<tr>
<td>serviceInfo</td>
<td>String</td>
<td>呼⼊⽅透传到被叫⽅,⽬前⾳箱端呼叫web端会带回⾳箱 serviceInfo.sn ,可⽤sn查询到呼⼊⽅姓名作为来电展示;serviceInfo.isEmergencyCall为true是紧急呼叫</td>
</tr>
</tbody>
</table>
<ul>
<li>stateInfo</li>
</ul>
<table>
<thead>
<tr>
<th>字段名</th>
<th>类型</th>
<th>取值说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>index</td>
<td>Number</td>
<td>会话唯⼀标识(客户端⽣成),⼀次完整的通话流程中,所有消息拥有相同的值</td>
</tr>
<tr>
<td>reason</td>
<td>Number</td>
<td>系统内置通话断开原因,取值参⻅duerRtcSdk.CallReason,可根据reason值查找对应的中⽂说明, 参⻅duerRtcSdk.CallReasonMap</td>
</tr>
<tr>
<td>peerUri</td>
<td>Object</td>
<td>对端uri</td>
</tr>
<tr>
<td>state</td>
<td>Number</td>
<td>当前通话状态,⻅下⽅『常⽤值』CallState</td>
</tr>
</tbody>
</table>
<ul>
<li>layouts</li>
</ul>
<p><img src="https://dumi-dueros-bj-tob.cdn.bcebos.com/amis/2023-9/1694693467642/%E5%9B%BE%E7%89%871.png" alt="" /></p>
<table>
<thead>
<tr>
<th>字段名</th>
<th>类型</th>
<th>取值说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>audioMute</td>
<td>Boolean</td>
<td>⽤户⾳频mute</td>
</tr>
<tr>
<td>audioTrack</td>
<td>Object</td>
<td>⽤户⾳频流信息</td>
</tr>
<tr>
<td>videoMute</td>
<td>Boolean</td>
<td>⽤户视频mute</td>
</tr>
<tr>
<td>videoTrack</td>
<td>Object</td>
<td>⽤户视频流信息</td>
</tr>
<tr>
<td>isLocal</td>
<td>Boolean</td>
<td>是否为本地窗⼝,⼀般⽤于处理显示哪⼀⽅的⾳频流</td>
</tr>
<tr>
<td>diaplayName</td>
<td>String</td>
<td>同建⽴⻓连接的callerName</td>
</tr>
<tr>
<td>callUri</td>
<td>String</td>
<td>与会者CallUri</td>
</tr>
<tr>
<td>callMode</td>
<td>Number</td>
<td>当前通话模式,⻅下⽅『常⽤值』CallMode</td>
</tr>
</tbody>
</table>
<h3>4.2 代码</h3>
<pre><code class="language-html">duerRtc.setCallListener({
// 收到来电时回调
onIncomingCall: intent =&gt; {
// 可在这⾥处理显示来电提示ui逻辑
// console.log(&quot;onIncomingCall&quot;, intent); const serviceInfo = intent.serviceInfo || {},
//获取⾳箱sn
const sn = serviceInfo.sn;
// 是否紧急呼叫
const isEmergencyCall = serviceInfo.isEmergencyCall;
},
// 通话状态改变时回调
onCallStateChanged: stateInfo =&gt; {
// stateInfo.state取值:5振铃 6呼叫已接通 7呼叫已断开,⻅『常⻅值』CallState
// 可根据该值判断操作按钮和呼叫窗⼝的显示隐藏
if(stateInfo.state === duerRtcSdk.CallState.RINGBACK) {
// 被叫收到new-call后的状态(振铃)
// 可在此处提示⽤户对⽅已响铃
} else if (stateInfo.state === duerRtcSdk.CallState.RINGBACK) {
// 呼叫已接通,应⽤可以从呼⼊/呼出状态进⼊媒体载⼊状态
// 可在此处进⾏视频⾳频展示逻辑处理
} else if (stateInfo.state === duerRtcSdk.CallState.DISCONNECTED) {
// 呼叫已断开
// 可在此处进⾏通话⻚⾯隐藏等处理
}
// console.log(&quot;onCallStateChanged&quot;, stateInfo);
}
onConfereeLayout: layouts =&gt; {
// loyouts:与会者布局信息回调,包含本机和邀请中的成员信息,⽤于⾳视频处理展示
//(本机信息始终在第1个元素,邀请中成员在数组末尾)
// console.log(&quot;onConfereeLayout&quot;, layouts);
// 获取⻚⾯audio、video元素,不同的项⽬根据实际情况拿到
const { audioRefLocal, videoRefLocal } = this.$localRefs; const { audioRefPeer, videoRefPeer } = this.$peerRefs;
// 双向通话layouts⻓度为2,第⼀个是本机视频信息,第⼆个是邀请成员信息
// ⼀般通话中处理成主窗⼝和⼩窗⼝,根据业务需求可⾃⾏优化处理
const layoutLocal = layouts[0]; const layoutPeer = layouts[1];
// 本地⾳视频流展示
//当关闭本地视频输⼊layoutLocal.videoTrack返回null
if (layoutLocal.videoTrack) { const stream = new MediaStream;
stream.addTrack(layoutLocal.videoTrack); videoRefLocal.srcObject = stream;
}
// 本地预览的⾳频不需要回放,当关闭本地⾳频输⼊ layoutLocal.audioTrack返回null
if (layoutLocal.audioTrack &amp;&amp; !layoutLocal.isLocal) { const stream = new MediaStream; stream.addTrack(layoutLocal.audioTrack); audioRefLocal.srcObject = stream;
}
// 对端⾳视频流展示
// 当⾳箱关闭视频输⼊layoutPeer.videoTrack返回null
if (layoutPeer.videoTrack) {
const stream = new MediaStream; stream.addTrack(layoutPeer.videoTrack); videoRefPeer.srcObject = stream;
}
// 当⾳箱关闭⾳频输⼊layoutPeer.audioTrack返回null if (layoutPeer.audioTrack) {
const stream = new MediaStream; stream.addTrack(layoutPeer.audioTrack); audioRefPeer.srcObject = stream;
}
}
});
</code></pre>
<pre><code class="language-html">// ⻓连接状态监听器
duerRtc.setConnectListener({
onConnectionChanged: conn =&gt; {
// 常⻅取值参⻅『常⽤值』Connection
// console.log(&quot;onConnectionChanged&quot;, conn);
if (conn === duerRtcSdk.Connection.CONNECTING) {
// 连接中
}
else if (conn === duerRtcSdk.Connection.CONNECTED) {
// 已连接
}
else if (conn === duerRtcSdk.Connection.DISCONNECTED) {
// 已断开,根据需要,可通过调⽤duerRtc.login尝试重新建⽴rtc⻓
}
}
});
/**
* 设置媒体设备监听器,获得摄像头与⻨克⻛状态
* @param device 设备类型: 0 ⾳频采集设备 1 视频采集设备
* @param state 设备状态:0 已打开 1 已关闭 2 打开过程遇到错误
* @param error 错误
*/
duerRtc.setMediaDeviceListener({
// 本机媒体设备操作状态改变回调,可根据业务需要进⾏提示⽤户是否已打开⻨克⻛和摄像头,⾮必须
onMediaDeviceStateChanged: (device, state, error) =&gt; {
// console.log('onMediaDeviceStateChanged', device, state, error);
}
});</code></pre>
<pre><code class="language-html">&lt;!-- video、audio标签记得加上autoPlay属性,否则没有视频和声⾳ --&gt;
&lt;video id='video-peer' autoPlay&gt;&lt;/video&gt;
&lt;audio id='audio-peer' autoPlay&gt;&lt;/audio&gt;</code></pre>
<h2>五 通话相关操作</h2>
<h3>5.1 拨打电话</h3>
<pre><code class="language-html">/**
* 封装打电话⽅法示例:
* uid和appid为要拨打⾳箱的uid和appid,分别对应使⽤接⼝获取的callAddress和callAppid
* callMode 通话模式,⾳频,视频,⾳视频,具体⻅duerRtcSdk.CallMode
* callerRole ⻆⾊,固定传duerRtcSdk.CallerRole.CALL_CENTER
*/
makeCall(appId, uid, callMode, callerRole = duerRtcSdk.CallerRole.CALL_CENTER) {
const calleeUri = new duerRtcSdk.CallUri(uid, appId);
let intent = duerRtcSdk.MakeCallIntent(calleeUri, duerRtcSdk.CallMode.AUDIO_VIDEO);
if (callMode) {
intent.callMode = callMode;
}
if (callerRole) {
intent.callerRole = callerRole;
}
const result = duerRtc.makeCall(intent);
// 呼出成功
if (duerRtcSdk.CallReason.NORMAL == result) {
// 进⾏后续处理
// console.log('makeCall intent', intent);
} else if (duerRtcSdk.CallReason.ALREADY_IN_CALL == result || duerRtcSdk.CallReason.EXCEPTION_INPUT_ILLEGAL == result) {
console.error('web-sdk', 'makeCall', duerRtcSdk.CallReasonMap.get(result))
}
else {
// 其他原因,⽬前不会出现
console.warn('web-sdk', 'makeCall', result)
}
}
makeCall⽅法调⽤成功后,可以通过上⾯设置的setCallListener通话监听器进⾏相关通话状态的处理</code></pre>
<h3>5.2 挂断当前电话</h3>
<pre><code class="language-html">dropCallClick() {
duerRtc.dropCall('DROP_CALL_USER_REASON');
}</code></pre>
<h3>5.3 来电处理</h3>
<pre><code class="language-html">/**
* 接电话:
* @param intent 上⾯通话onIncomingCall监听获取intent
* @param callMode根据实际情况取值
*/
duerRtc.answerCall(intent.index, intent.callMode, false);
// 来电⾳视频流处理同拨打电话,上⽅onConfereeLayout监听获取</code></pre>
<h3>5.4 拒接来电</h3>
<pre><code class="language-html">// 当web端为客服坐席时,⾳箱呼叫web不存在拒接
// 当前web客服坐席拒绝了通话会继续放⼊呼叫队列,等着分配可⽤客服坐席
// 5分钟没接⾳箱就超时提示并⾃动挂断
rejectCallClick() {
duerRtc.rejectIncomingCall(intent.index, 'REJECT_CALL_USER_REASON')
}</code></pre>
<h3>5.5 ⾳视频互转</h3>
<pre><code class="language-html">// mode可⽤值查看duerRtcSdk.CallMode
callModeChanged(mode) {
duerRtc.changeCallMode(mode)
}</code></pre>
<h3>5.6 本端⾳视频输⼊控制</h3>
<pre><code class="language-html">// 关闭本端视频输⼊,此时layouts[0].videoTrack返回null
duerRtc.muteVideo(true)
// 默认,开启本端视频输⼊,此时layouts[0].videoTrack返回视频信息
duerRtc.muteVideo(false)
// 关闭本端⾳频输⼊,此时layouts[0].audioTrack返回null
duerRtc.muteAudio(true)
// 默认,开启本端⾳频输⼊,此时layouts[0].audioTrack返回⾳频信息
duerRtc.muteAudio(false)</code></pre>
<h2>六 断开rtc⻓连接</h2>
<p><code>断开⻓连接之后将不会收到任何来电,也⽆法发起通话</code></p>
<pre><code class="language-html">duerRtc.logout()</code></pre>
<h2>七 常⽤值</h2>
<p><code>参数的具体取值可参考demo,也可通过打印duerRtcSdk查看全部⽅法取值根据不同取值监听进⾏具体处理</code></p>
<pre><code class="language-html">AuthCode常⽤值:
AuthCode.PARAM_ERROR 5100 // (联调阶段出现)参数错误,通常是Token设置错误
AuthCode.APPID_INVALID 5200 // (联调阶段出现)APPID⽆效,并未在Rtc云端注册
AuthCode.TOKEN_INVALID 5300 // token⽆效,uid与token内容不匹配,或token⽣成服务更换appSecret后出现
AuthCode.TOKEN_EXPIRED 5301 // token过期
AuthCode.NO_ERROR 5000 // ⽆任何异常
AuthCode.OTHER_DEVICE_LOGIN 5400 // 相同uid重复登录时,旧的连接会收到该提示
// RTC内部⻓连接状态
Connection.CONNECTING 1 // 连接中
Connection.CONNECTED 2 // 已连接
Connection.DISCONNECTED 3 // 已断开
// RTC⽀持的呼叫协议类型
CallUriType.NORMAL 1 // 普通类型
CallUriType.SERVICE 2 // 呼叫中⼼
// 主叫呼出⻆⾊,呼叫中⼼坐席等特殊业务主叫呼出时使⽤
CallerRole.NORMAL 1 // 普通类型
CallerRole.CALL_CENTER 2 // 呼叫中⼼
// RTC呼叫流程状态定义
CallState.IDLE 1 // 空闲,基本上感知不到,很快会转换到其他状态
CallState.OFFERING 2 // 客户端向服务端发送offer后的状态
CallState.PROCESSING 3 // 客户端向服务端发送offer后,并收到服务端回复trying时的状态
CallState.EARLY_MEDIA 4 // 主叫⽅呼出,发⽣转呼PSTN时的状态,此时会开始播放运营商反馈的声⾳(如被叫彩铃等)
CallState.RINGBACK 5 // 被叫收到new-call后的状态(振铃)
CallState.CONNECTED 6 // 呼叫已接通,应⽤可以从呼⼊/呼出状态进⼊媒体载⼊状态
CallState.DISCONNECTED 7 // 呼叫已断开
// RTC呼叫⽅向定义
CallDirection.INCOMING 1 // 呼⼊
CallDirection.OUTGOING 2 // 呼出
// RTC⽀持的通话模式定义
CallMode.AUDIO_VIDEO 0 // ⾳视频模式:本端同时接收和发送⾳频、视频数据。
CallMode.AUDIO_ONLY 1 // 语⾳模式:本端只接收和发送⾳频数据
CallMode.OBSERVER 2 // 观察模式:本端只接收⾳频、视频数据,不发送⾳频、视频数据
CallMode.OBSERVED 3 // 被观察模式:本端只发送⾳频、视频数据,不接收⾳频、视频数据
// RTC呼叫流程状态定义
CallState.NORMAL: 54 //正常
CallState.SYSTEM_ERROR: 34 //呼叫系统异常,请稍后再试
CallState.UNSUPPORTED_SERVICE: 35 //暂不⽀持此服务
CallState.AUTHENTICATION_ERROR: 0 //对⽅不允许陌⽣⼈呼叫
CallState.STATUS_OK: 1 //通话已结束
CallState.PEER_STATUS_OK: 2 //对⽅结束通话
CallState.PEER_NOT_FOUND: 3 //对⽅不在线,请稍后重试
CallState.TIMEOUT: 7 //对⽅没有应答,请稍后重试
CallState.BUSY: 4 //对⽅忙,请稍后重试
CallState.PEER_CALLING_OUT: 29 //对⽅忙,请稍后重试
CallState.CANCEL: 8 //呼叫已取消
CallState.CANCEL_BY_TIMEOUT: 9 //呼叫已取消
CallState.PSTN_NO_BALANCE: 14 //抱歉,通话时⻓已⽤完
CallState.PSTN_TIME_LIMIT: 15 //已达最⼤呼叫时⻓,呼叫已断开
CallState.EXPIRED: 5 //对⽅试⽤已到期
CallState.PSTN_UNSUPPORT_REGION: 16 //抱歉,不⽀持呼叫该号码
CallState.LOCAL_NET_DISCONNECT: 17 //⽹络异常,呼叫已断开
CallState.SIGNAL_TIMEOUT: 10 //⽹络异常,呼叫已断开
CallState.MEDIA_TIMEOUT: 18 //⽹络异常,呼叫已断开
CallState.SDP_INVALID: 19 //通讯失败,请升级到最新版本
CallState.PEER_NET_DISCONNECT: 20 //对⽅⽹络中断,呼叫已断开
CallState.UDP_UNAVAILABLE: 21 //当前⽹络UDP被禁⽤,⽆法通话,请联系⽹络管理员或切换其他⽹络
CallState.CHARGE_ARREARAGE: 23 //您的帐户已⽋费,请及时充值
CallState.LOCAL_VERSION_STALE: 30 //版本过低,请升级后再试
CallState.PEER_VERSION_STALE: 31 //对⽅版本过低,通话⽆法接通
CallState.UNSUPPORT_CALL: 24 //您的终端⽬前⽆法⽀持此类呼叫
CallState.PSTN_LOW_BALANCE: 25 //电话时⻓已⽤完,⽆法⾃动转呼对⽅⼿机
CallState.PSTN_UNSUPPORT_DISTRICT: 26 //暂不⽀持呼叫国际电话号码
CallState.SERVICE_EXPIRED: 6 //服务已过期
CallState.SERVICE_MAX_LIMIT: 27 //当前在线呼叫数已达服务上限,请稍后再试
CallState.SERVICE_CUSTOMER_BLACKLIST: 28 //您的呼叫过于频繁,已被暂时锁定,请稍后再试
CallState.SERVICE_CUSTOMER_BUSY: 55 //客服坐席忙,请稍后再试
CallState.JOIN_CONFERENCE: 11 //您已经成功加⼊当前会议
CallState.JOIN_OTHER_CONFERENCE: 12 //您正在加⼊其他会议
CallState.PEER_JOIN_OTHER_CONFERENCE: 13 //对⽅已经加⼊其他会议
CallState.CALL_FAIL: 22 //抱歉,呼叫失败,请重试
CallState.TIME_LIMIT: 32 //已达最⼤呼叫时⻓,呼叫已断开
CallState.ILLEGAL_CALL: 36 //⾮法呼叫,请检查登录账号是否正确
CallState.ALREADY_IN_CALL: 39 //已处于通话中,⽆法发起其他呼出请求
CallState.NOT_IN_CALL: 57 //未处于通话中,⽆法发起邀请操作
CallState.TELECOM_CALL: 37 //电信电话通话中,呼叫已断开
CallState.PEER_TELECOM_CALL: 38 //对⽅电信电话通话中,呼叫已断开
CallState.EXCEPTION_INPUT_ILLEGAL: 58 //输⼊参数不符合要求
CallState.EXCEPTION_CALL_EXIST: 40 //发起的呼叫已存在
CallState.EXCEPTION_CALL_NOT_EXIST: 41 //发起的呼叫不存在
CallState.EXCEPTION_HOST_UNKNOWN: 48 //本地⽹络异常,呼叫已断开
CallState.EXCEPTION_PARAM_ERROR: 43 //被叫号码⻓度不符合要求
CallState.EXCEPTION_CONFIG_ERROR: 42 //未完成服务初始化
CallState.EXCEPTION_ALLOCATE_PORT: 44 //本地端⼝分配失败
CallState.EXCEPTION_TEL_INPUT_ILLEGAL: 45 //被叫号码格式不符合要求
CallState.EXCEPTION_TEL_NOT_SUPPORT: 46 //被叫号码不被⽀持
CallState.EXCEPTION_TEL_NO_ZONE: 47 //被叫号码⽆区号
CallState.EXCEPTION_WSS_NOT_CONNECT: 49 //未连接服务,请稍后重试
CallState.EXCEPTION_TERMINAL_ABNORMAL: 50 //呼叫太频繁,请稍后重试
CallState.EXCEPTION_SERVICE_FORBIDDEN: 51 //服务被禁⽤,请稍后重试
CallState.EXCEPTION_SERVER_BUSY: 52 //服务繁忙,请稍后重试
CallState.EXCEPTION_SIGNATURE_INVALID: 53 //认证服务异常,请联系客服
// getCallReason可能出现的错误码
// 1xxx RTCSDK错误 2xxx正常 3xxx基础服务错误 4xxx⽤户错误 5xxx RTC服务错误 6xxx客户端业务层错误
4029 // 错误的坐席呼叫,主叫的⽤户不是客服坐席或者呼叫过程中坐席变更为其他客服的坐席,建议查看uid是否绑定正确</code></pre>
<h2>八、接入demo</h2>
<ul>
<li><a href="https://www.showdoc.com.cn/2104324603939229/10560908748024821">https://www.showdoc.com.cn/2104324603939229/10560908748024821</a></li>
</ul>