# 实现视频通话
本文档为您展示通过 SDK 实现视频通过(访客侧)的相关步骤,帮助您在远程银行和视频客服的场景下实现智能排队、屏幕共享、全景录像、访客管理的相关能力。
# 1. 前提条件
请确认您已完成以下操作:
- 已获取 App Key。
AppKey 作为同个环境的分域依据,同一个域的终端才能实现互通,AppKey 由 Juphoon 视频平台提供。
- 集成 SDK。
TIP
请扫描下方二维码联系 Juphoon 市场售前工程师获取 AppKey。

集成 SDK(Harmony)。
TIP
如需集成指导,请扫描上方二维码联系 Juphoon 市场售前工程师获取相关咨询。
# 2.快速跑通Sample
在 Juphoon SDK RTC 文档中心,选择视频客服-访客选择项,在SDK下载页面下载体验 Sample 示例项目。访问下载地址 (opens new window),示例如下:
下载完成后,打开安装包,解压 JCCSample,然后安装 JCCSample.apk
打开应用程序后,设置正确的 appkey,环境地址以及账号。
a.首先点击初始化按钮,成功后,登入按钮变为可点击。
b.确认座席账号输入无误之后,点击登入按钮,按钮字样变为登出,即登录成功。
C.点击座席按钮,即可进入对应座席页面。
进入座席页面后,点击签入即可回呼访客及等待访客来电。
# 3. 实现视频通话
# 初始化
注:我们所有的方法都建议在主线程调用,否则可能会出现异常无法正常使用,回调接口也都在主线程上报。
在使用业务接口前,需对 Juphoon RTC SDK 进行初始化操作。
| 类 | 模块 | 描述 |
|---|---|---|
| JRTCClient (opens new window) | 登录模块 | 负责视频平台的登录登出,只有登录到视频平台才可以使用视频相关的业务 |
| JRTCMediaDevice (opens new window) | 媒体模块 | 负责本地的媒体设备操作,视频画面渲染等功能 |
| JRTCAgent (opens new window) | 座席模块 | 负责座席的视频业务的处理,比如接听来电,控制音视频流等 这些模块初始化的时候需要有 callback 作为入参来监听各模块的事件 |
| JRTCRecord (opens new window) | 录制模块 | 实现本地音视频录制(不需要建立通话),本地分片录制等功能 |
class JRTCManager implements JRTCClientCallback, JRTCCallCallback, JRTCMediaDeviceCallback {
private client: JRTCClient;
private mediaDevice: JRTCMediaDevice;
private agent: JRTCAgent;
private record: JRTCRecord;
public init(context: Context) {
let param: JRTCClientInitParam = new JRTCClientInitParam();
param.appName = "appName" // 设置应用名称
param.SDKInfoDir = "SDKInfoDir" // 设置SDK信息存储目录
param.appKey = "appKey" // 设置AppKey
param.server = "server" //设置接入服务器地址
param.logConsole = true // 设置是否控制台日志输出,默认true
param.logLocalFile = true // 获取是否是否本地文件日志输出,默认true
param.looseTimeoutControl = true // 设置是否开启 RPC 抗信令丢包控制(70%的上下行信令丢包),默认false
this.client = JRTCClient.create(context.getApplicationContext(), this, initParam);
this.mediaDevice = JRTCMediaDevice.create(this.mClient, this, undefined);
this.agent = JRTCAgent.create(this.client, this.mediaDevice, this);
this.record = JRTCRecord.create(this.client,this.mediaDevice, this);
// 设置基本参数
this.client.setServer("server"); // 设置接入服务器地址
this.client.setAppKey("appKey"); // 设置AppKey
this.client.setDisplayName("displayName"); // 设置显示名称
this.client.setAppName("appName"); // 设置应用名称
}
}
根据需求实现 对应 Callback 的接口即可。
# 登录
SDK 初始化之后,即可进行登录的集成,登录接口调用流程如下所示:
登录到 Juphoon 视频平台主要调用的是 JRTCClient (opens new window) 的登录接口 login (opens new window)。
/**
* 登录 Juphoon RTC 平台,只有登录成功后才能进行平台上的各种业务
* <p>
* 登录结果通过 {@link JRTCClientCallback.onLogin onLogin} 回调通知
*
* @param { string } userId 用户ID
* @param { string } password 密码,不能为空
* @param { JRTCClientLoginParam? } clientLoginParam 登录参数,一般不需要设置,如需设置请询问客服,传 undefined 则按默认值
* @return { boolean } 接口调用结果
* - true:接口调用成功
* - false:接口调用异常
* @warning 目前只支持免鉴权模式,服务器不校验账号密码,免鉴权模式下当账号不存在时会自动去创建该账号
* @warning 用户名为英文数字和'+' '-' '_' '.',长度不要超过64字符,'-' '_' '.'不能作为第一个字符
*/
public abstract login(userId: string, password: string, clientLoginParam?: JRTCClientLoginParam): boolean;
JRTCClientLoginParam (opens new window) 属性介绍
| 属性 | 描述 |
|---|---|
| accountEntry | 设置账户分录参数,如果支持国密S3则需要设置 certificate 参数,否则可以不设置 certificate 参数 |
| certificate | 设置 S3 国密证书 Base64 编码内容 |
| acceptExpiredCertificate | 设置是否允许过期证书校验通过 |
| token | 设置token |
| tokenType | 设置 token 校验类型 |
| deviceId | 设置设备id |
| logFilter | 设置日志过滤标签(用于日志管理平台过滤终端日志使用) |
| terminalType | 设置终端登录类型,支持多终端登录,默认所有终端相同会导致互踢 |
| autoCreateAccount | 是否自动创建账号(免鉴权使用),默认true |
| accelerateKey | 设置加速云KEY |
| accelerateKeySecret | 设置加速云KEY密钥 |
| optimizeDataRouter | 设置是否开启数据路由优化,默认true |
登录的结果将会通过 JRTCClientCallback 的接口上报:
/**
* 登录结果回调
*
* @param { boolean } result 登录结果
* - true:表示登录成功,
* - false:表示登录失败
* @param { JRTCReasonCode } reason 登录失败原因,当 result 为 false 时该值有效
*/
onLogin?: (result: boolean, reason: JRTCReasonCode) => void;
示例代码:
// 创建登录配置参数
const loginParam: JRTCClientLoginParam = new JRTCClientLoginParam();
// 登录
client.login("juphoon", "123456", loginParam);
public onLogin(result: boolean, reason: number): void {
if (result) {
// 登录成功
} else {
// 登录失败,具体原因查询 reason 错误码
}
}
# 获取业务号列表
通过调用 queryAllGroups (opens new window) 接口获取当前业务号列表。
/**
* 获取业务号列表
*
* @return 接口调用结果
* - true: 接口调用成功,返回结果通过 {@link JRTCAgentCallback#onGetAllGroups onGetAllGroups} 回调上报
* - false: 接口调用异常
*/
public abstract queryAllGroups(): boolean;
获取结果通过实现 JRTCAgentCallback (opens new window) 中的 onGetAllGroups (opens new window) 接口获取。
/**
* 获取业务号列表结果回调
*
* 访客调用 {@link JRTCAgent#queryAllGroups queryAllGroups} 接口获取业务号列表,会收到此回调。
* @param groups 座席业务实体对象列表,获取失败时为 undefined
* @param result 获取结果,true 表示获取成功,false 表示获取失败
*/
onGetAllGroups?: (result: boolean, groups: ArrayList<JRTCCallCenterGroupItem>) => void;
示例代码:
//获取业务号列表
agent.queryAllGroups();
onGetAllGroups: (result: boolean, groups: ArrayList<JRTCCallCenterGroupItem>) => {
if(result) {
//获取成功
} else {
//获取失败
}
}
# 查询指定业务号的空闲座席
通过业务号查询空闲的座席。
/**
* 查询指定业务号的空闲座席
* <p>
* 查询结果通过 {@link JRTCAgentCallback#onQueryAvailableAgentList onQueryAvailableAgentList} 回调上报
*
* @param businessNumber 业务号,例如 10087
* @return 操作id,与 {@link JRTCAgentCallback#onQueryAvailableAgentList onQueryAvailableAgentList} 的 operationId 参数对应
*/
public abstract queryAvailableAgentList(businessNumber: string): number;
指定业务号的空闲座席查询结果通过实现 JRTCAgentCallback (opens new window) 中的 onQueryAvailableAgentList (opens new window) 接口上报。
/**
* 查询空闲座席回调
*
* 座席调用 {@link JRTCAgent#queryAvailableAgentList queryAvailableAgentList} 接口查询空闲座席成功时,会收到此回调。
* @param operationId 操作id,对应 {@link JRTCAgent#queryAvailableAgentList queryAvailableAgentList} 接口的返回值
* @param result 查询结果
* - true: 查询成功
* - false: 查询失败
* @param userIds 查询到的空闲座席列表
*/
onQueryAvailableAgentList?: (operationId: number, result: boolean, userIds: ArrayList<string>) => void;
示例代码:
// 查询空闲座席
agent.queryAvailableAgentList("10086");
onQueryAvailableAgentList: (operationId: number, result: boolean, userIds: ArrayList<string>) => {
if (result) {
// 查询成功,具体查看 userIds
} else {
// 查询失败
}
}
# 座席签入
登录视频能力平台成功后,需要调用 checkin (opens new window) 签入到排队机才能由排队机进行路由分配。
/**
* 签入
* <p>
* 签入到排队机,签入后示忙/示闲状态由 busy 参数决定 <br>
* 示闲状态下正常呼叫进线 <br>
* 调用接口前确定 JRTCClient 登录成功 <br>
* 调用该接口前需先确定 {@link #getOperatorState operatorState} 来获取到当前的签入状态
*
* @param userId 座席用户ID,需与业务管理平台上配置的座席staffId对应,如果传空,则默认用当前登录用户ID签入
* @param busy 签入后示忙/示闲状态
* - true: 示忙
* - false: 示闲
* @return 接口调用结果
* - true: 接口调用成功,签入结果会触发 {@link JRTCAgentCallback#onCheckin onCheckin} 回调上报
* - false: 接口调用异常
* @oaram checkinParam 签入其他参数
*/
public abstract checkin(userId: string, busy: boolean, checkInParam: JRTCAgentCheckinParam): boolean;
签入方法包含几个重载,用来适应各种可配置的参数,比如签入后默认为示闲还是示忙、比如座席的角色。这些方法的需结合具体的需求来使用。
签入结果通过实现 JRTCAgentCallback (opens new window) 中的 onCheckin (opens new window) 接口上报。
/**
* 签入回调
* <p>
* 座席调用 {@link JRTCAgent#checkin checkin} 接口成功,会收到此回调。
*
* @param result 签入结果
* - true: 签入成功
* - false: 签入失败
* @param pause 签入后的示闲/示忙状态
* - true: 签入后示忙
* - false: 签入后示闲
* @param reason 失败原因
*/
onCheckin?: (result: boolean, pause: boolean, reason: string) => void;
示例代码:
// 签入
agent.checkin(JRTCAgent.MANAGER, false, checkInParam);
// 签入结果回调
onCheckin: (result: boolean, pause: boolean, reason: string) => {
if(result) {
// 签入成功
} else {
// 签入失败,具体原因查询 reason 错误码
}
}
# 座席签出
当所有业务处理完毕,座席可以使用 Agent 对象中的 checkout (opens new window) 签出排队机,签出后将不会分发访客到这个座席终端,业务管理平台上该座席的状态将变为离线。
/**
* 签出
* <p>
* 签出后将不会收到排队机的呼叫分配 <br>
* 签出排队机不影响 JRTCClient 的登录状态 <br>
* 调用 {@link #getOperatorState operatorState} 可获取当前签入状态
*
* @return 接口调用结果
* - true: 接口调用成功,签出结果通过 {@link JRTCAgentCallback#onCheckout onCheckout} 回调上报
* - false: 接口调用异常
*/
public abstract checkout(): boolean;
签出结果通过实现 JRTCAgentCallback (opens new window) 中的 onCheckout (opens new window) 接口上报。
/**
* 签出回调
*
* 座席调用 {@link JRTCAgent#checkout checkout} 接口签出排队机,会收到此回调。
* @param result 签出结果
* - true: 签出成功
* - false: 签出失败
* @param reason 签出原因
*/
onCheckout?: (result: boolean, reason: JRTCCallCenterAgentCheckoutReason) => void;
座席签出原因详见 JRTCCallCenterCheckoutReason (opens new window)
示例代码:
// 座席签出
agent.checkout();
onCheckout:(result: boolean, reason: JRTCCallCenterAgentCheckoutReason) => {
if(result) {
// 签出成功
} else {
// 签出失败,具体原因查询 reason 错误码
}
}
# 座席签入签出状态改变
座席签入签出状态发生变化都会通过 JRTCAgentCallback (opens new window) 中 onCheckStateChanged (opens new window) 接口上报。
/**
* 签入/签出状态改变
*
* @param currState 当前座席状态
* @param oldState 旧的座席状态
*/
onCheckStateChanged?: (currState: JRTCCallCenterOperatorState, oldState: JRTCCallCenterAgentOperatorState) => void;
座席签入签出状态详见 JRTCCallCenterOperatorState (opens new window)
示例代码:
onCheckStateChanged: (currState: JRTCCallCenterOperatorState,oldState: JRTCCallCenterAgentOperatorState) => {
if (currState == JRTCCallCenterOperatorState.CHECKING_IN) {
//正在签入中
} else if (currState == JRTCCallCenterOperatorState.CHECKED_IN) {
//已签入
} else if (currState == JRTCCallCenterOperatorState.CHECKING_OUT) {
//已签出
} else if (currState == JRTCCallCenterOperatorState.IDLE) {
//初始状态
}
}
# 获取座席签入状态
通过调用 getOperatorState (opens new window) 获取座席签入状态。
/**
* 获取座席签入状态
*
* @return 座席签入状态
*/
public abstract getOperatorState(): JRTCCallCenterAgentOperatorState;
# 示忙示闲
通过调用 JRTCAgent (opens new window) 对象的 applyStatePause (opens new window) 方法来切换该状态。
- 示忙:座席暂停服务,访客无法呼到该座席。
- 示闲:座席保持服务,访客可以呼到该座席。
/**
* 示忙/示闲
* <p>
* 示忙状态下不会收到呼叫来电,示闲状态下正常呼叫进线 <br>
* 通话过程中调用该接口不会影响当前通话,从下个通话开始状态生效 <br>
* 示忙/示闲的结果通过 {@link JRTCAgentCallback#onApplyResult onApplyResult} 回调上报
*
* @param pause 示忙或是示闲
* - true: 示忙
* - false: 示闲
* @return 接口调用结果
* - > 0: 操作id,对应 {@link JRTCAgentCallback#onApplyResult onApplyResult} 回调的 operationId 参数
* - -1:接口调用异常
*/
public abstract applyStatePause(pause: boolean): number;
如果需要在通话结束后设置默认示闲示忙,可以通过调用调用 JRTCAgent (opens new window) 对象的 setTermState (opens new window) 方法实现。
/**
* 获取结束通话后的示闲/示忙状态,默认为示闲状态
*
* @return 通话结束后状态
*/
public abstract getTermState(): JRTCCallCenterAgentTermState;
/**
* 设置通话结束后示闲/示忙状态,默认为示闲状态
*
* @param state 示闲/示忙状态
*/
public abstract setTermState(state: JRTCCallCenterAgentTermState);
示忙示闲结果通过实现 JRTCAgentCallback (opens new window) 中的 onApplyResult (opens new window) 接口上报。
/**
* 示忙/示闲回调
*
* 座席示忙/示闲状态发生改变时,会收到此回调,例如调用 {@link JRTCAgent#applyStatePause applyStatePause} 接口修改忙闲状态。 <br>
* 可以通过 {@link JRTCAgent#isPause pause} 获取当前的忙闲状态。
* @param operationId 对应 {@link JRTCAgent#applyStatePause applyStatePause} 接口的返回值
* @param result 示忙/示闲操作结果
* - true: 示忙/示闲成功
* - false: 示忙/示闲失败
*/
onApplyResult?: (operationId: number, result: boolean) => void;
还可以调用 isPause (opens new window) 查询当前示闲示忙的状态。
/**
* 获取示忙/示闲状态
* <p>
* 调用 {@link #checkIn(int)} 或 {@link #checkIn(String, int)} 接口签入,状态为示闲 <br>
* 调用 {@link #checkIn(String, int, boolean)} 接口签入,状态与 busy 参数一致 <br>
* 调用 {@link #applyStatePause} 接口主动发起示忙示闲,状态与 pause 参数一致 <br>
*
* @return 示忙/示闲状态
* - true: 示忙状态
* - false: 示闲状态
*/
public abstract isPause(): boolean;
示例代码:
//座席示忙
agent.applyStatePause(false);
//座席示忙示闲结果
onApplyResult: (operationId: number, result: boolean) => {
if (result) {
// 示忙示闲的操作成功
}
// 可以通过_agent对象获取当前的忙闲状态
agent.isPause();
}
# 座席回呼
座席可以通过调用 recall (opens new window) 接口回呼访客。
/**
* 座席回呼
* * @note 需要先签入并且示闲
*
* @param userId 访客用户ID
* @param callParam 呼叫参数设置,此参数可传 undefined 则使用默认配置,详见 {@link JRTCCallCenterCallParam}
* @return 接口调用结果
* - true: 接口调用成功,通话状态会通过 {@link JRTCAgentCallback#onCallStateChanged onCallStateChanged} 回调上报
* - false: 接口调用异常
*/
public abstract recall(userId: string, callParam: JRTCCallCenterCallParam): boolean;
示例代码:
// 创建呼叫参数配置
let callParam:JRTCCallCenterCallParam = new JRTCCallCenterCallParam();
......
callParam.extraInfo = "extraInfo"; // 设置随路参数
callParam.svcResolution = "1 180 250 360 600 720 1400"; // 设置SVC参数
......
agent.recall("guestUserId", callParam);
# 接听来电
在座席收到来电的通知后,可以通过调用 answer (opens new window) 接口来接起访客的呼叫。
来电类型详见 JRTCCallCenterIncomingType (opens new window)
CALL (opens new window):普通来电,访客调用 call (opens new window) 接口呼叫;
INVITE (opens new window):三方邀请来电,座席调用 inviteThirdAgent (opens new window) 接口邀请三方座席;
FORWARD (opens new window):转接来电,座席调用 transferCall (opens new window)接口转接当前通话;
DIRECT_CALL (opens new window):直呼来电,访客调用 oneToOneCall (opens new window) 接口进行直呼座席;
/**
* 接听
* <p>
* 主座席、第三方座席或是被转接的座席,都调用此接口接听通话 <br>
*
* @return 接口调用结果
* - true: 接口调用成功,会收到 {@link JRTCAgentCallback#onCallStateChanged onCallStateChanged} 回调
* - false: 接口调用异常
*/
public abstract answer(): boolean;
示例代码:
onCallStateChanged: (type: JRTCCallCenterCallState, incomingType: JRTCCallCenterIncomingType,
inviter: JRTCInviter | undefined, reason: JRTCCallCenterTermReason) =>{
if (type == JRTCCallCenterCallState.INCOMING) {
if(incomingType == JRTCCallCenterIncomingType.CALL){
// 接听
agent.answer();
}
}
}
接听的结果同样通过 JRTCAgentCallback (opens new window) 的 onCallStateChanged (opens new window) 接口上报通话状态改变。
# 通话状态通知
座席签入成功后即为一个等待通话接入的状态,具体的通话由排队机进行分配,
- 访客呼叫场景:
- 座席收到来电,通话状态就改变为 INCOMING (opens new window);
- 座席接听,成功进入通话,通话状态改变为 TALKING (opens new window);
- 座席挂断或者其他成员挂断导致通话结束,通话状态改变为 IDLE (opens new window);
回呼场景
- 座席回呼访客,通话状态就改变为CALLING (opens new window)
- 访客接听,成功进入通话,通话状态改变为 TALKING (opens new window);
- 座席挂断或者其他成员挂断导致通话结束,通话状态改变为 IDLE (opens new window)
通过实现 JRTCAgentCallback (opens new window) 中的 onCallStateChanged (opens new window) 接口上报。
/**
* 通话状态改变回调
*
* @param type 通话状态改变类型,即以下情况会收到此回调:
* - {@link JRTCAgent#INCOMING} 收到来电(访客呼叫、座席邀请、转接)
* - {@link JRTCAgent#TALKING} 通话接通
* - {@link JRTCAgent#TERMED} 通话挂断或被挂断
* @param incomingType 来电类型,当 type == {@link JRTCAgent#INCOMING} 时有效
* @param inviter 邀请成员对象,当 type == {@link JRTCAgent#INCOMING} 时有效
* @param reason 挂断原因,只在 type 为 {@link JRTCCallCenter#TERMED} 时需要关注,详见 {@link JRTCAgent.CallTermReason CallTermReason}
*/
onCallStateChanged?: (type: JRTCCallCenterAgentCallStateChangeType, incomingType: JRTCCallCenterIncomingType,inviter: JRTCInviter | undefined, reason: JRTCCallCenterTermReason) => void;
通话状态详见 JRTCCallCenterCallState (opens new window)
通话结束原因详见 JRTCCallCenterTermReason (opens new window)
示例代码:
onCallStateChanged: (type: JRTCCallCenterCallState, incomingType: JRTCCallCenterIncomingType,inviter: JRTCInviter | undefined, reason: JRTCCallCenterTermReason) => {
switch (type) {
case JRTCCallCenterCallState.CALLING:
// 呼叫(座席回呼)
break;
case JRTCCallCenterCallState.TALKING:
// 通话建立
break;
case JRTCCallCenterCallState.IDLE:
// 通话挂断
break;
case JRTCCallCenterCallState.INCOMING:
// 收到来电
break;
case JRTCCallCenterCallState.JOINING:
// 加入通话中
break;
}
}
# 获取通话状态
/**
* 获取当前通话状态
*
* @return 当前通话状态
*/
public abstract getCallState(): number;
示例代码:
let callState:number = agent.getCallState();
if (callState == JRTCCallCenterCallState.IDLE) {
// 空闲状态
} else if (callState == JRTCCallCenterCallState.INCOMING) {
// 收到来电
} else if (callState == JRTCCallCenterCallState.TALKING) {
// 通话中
} else if (callState == JRTCCallCenterCallState.CALLING) {
// 呼叫中(回呼场景)
}
# 创建本地视频画面
初始化成功后,可以创建本地的视频画面,创建本地视频画面的时机没有具体要求,在通话前通话中皆可。
通过调用JRTCMediaDevice (opens new window) 里的 startCamera (opens new window)
/**
* 开启摄像头
*
* @note 调用此方法时需要保证默认摄像头不为空,即 {@link defaultCamera} 不为空,否则将直接返回 false
*
* @return 接口调用结果
* - true: 接口调用成功
* - 若调用此方法前摄像头已打开,不会收到回调通知
* - 若调用此方法前摄像头未打开,会收到 {@link JRTCMediaDeviceCallback#onCameraUpdate onCameraUpdate} 回调
* - false: 接口调用异常
*/
public abstract startCamera(): Promise<boolean>;
示例代码:
@Component
struct Agent {
//摄像头ID
@State cameraId: string = '';
//开启摄像头渲染
startCameraVideo(): void {
//打开摄像头绑定渲染组件
mediaDevice?.startCamera().then(() => {
this.cameraId = mediaDevice.getCurrentCamera()?.cameraId;
});
}
build() {
Column() {
Row() {
// 定义视频渲染组件
JRTCVideoComponent({
streamId: this.cameraId,
mediaDevice: mediaDevice
})
.width(this.videoHeight * 9 / 16)
.height(this.videoHeight)
.backgroundColor(Color.Black)
.align(Alignment.Center)
}
}
}
}
# 创建远端视频画面
当通话建立后,除了本地的视频画面,还有通话成员的远端视频画面,如果通话成员有视频流的上传,访客端可以获取到座席的视频流并进行渲染。
访客可在收到以下回调时进行界面处理:
- 收到 onCallStateChanged (opens new window) 回调且通话状态改为 。TALKING (opens new window) 时,表示座席加入了通话。
- 收到 onMemberJoin (opens new window) 回调时,表示有其他成员加入通话。
- 收到 onMemberUpdate (opens new window)回调时,表示通话中用户的通话状态变化。例如,可通过 JRTCRoomParticipantChangeParam (opens new window).video (opens new window) 属性判断用户视频流状态是否发送改变;当 JRTCRoomParticipant (opens new window).video (opens new window)的值为 true ,表示远端用户已上传视频流,本端通过订阅远端视频流,获取远端视图渲染对象。
- 使用组件JRTCVideoComponent给participantArray赋值上当前成员对象
示例代码:
@State participantArray: Array<JRTCRoomParticipant> = [];
onMemberUpdate: (participant: JRTCRoomParticipant | undefined,changeParam: JRTCRoomParticipantChangeParam | undefined) => {
for (const participant of agent.getParticipants() || []) {
this.participantArray.push(participant);
}
}
ForEach(this.participantArray, (participant: JRTCRoomParticipant) => {
JRTCVideoComponent({
streamId: participant.streamId,
mediaDevice: JRTCManager.getInstance().mMediaDevice
})
})
# 结束通话
调用 term (opens new window) 接口主动结束通话。
/**
* 结束通话
* <p>
* 来电过程中调用此接口拒绝接听,访客分配到其他座席继续呼叫等待不会挂断。<br>
* 主座席调用此接口会结束通话,通话中所有成员都会离开,此通通话销毁,所有成员会收到 {@link JRTCAgentCallback#onCallStateChanged onCallStateChanged} 或 {@link JRTCGuestCallback#onCallStateChanged onCallStateChanged} 通话结束回调。<br>
* 第三方座席调用此接口仅自身离开通话,通话中其他成员会收到该成员离开的回调 {@link JRTCGuestCallback#onMemberLeave onMemberLeave} 或 {@link JRTCAgentCallback#onMemberLeave onMemberLeave} 回调,通话继续进行。
*
* @return 接口调用结果
* - true: 接口调用成功,会收到 {@link JRTCAgentCallback#onCallStateChanged onCallStateChanged} 回调
* - false: 接口调用异常
*/
public abstract term(): boolean;
主动和被动的挂断事件与来电、接通一样,都通过 onCallStateChanged (opens new window) 接口上报,其中 JRTCCallCenterTermReason (opens new window) 可以用来判断挂断原因,如:主动挂断、对端挂断等,详细可参考 API 文档。
示例代码:
// 座席主动结束通话
agent.term();
// 通话状态改变回调
onCallStateChanged: (type: JRTCCallCenterIncomingType, incomingType: JRTCCallCenterIncomingType,inviter: JRTCInviter | undefined, reason: JRTCCallCenterTermReason) => {
if (type == JRTCCallCenterIncomingType.IDLE) {
// 通话结束,结束原因查看 reason
}
}
# 登出
登出结果通过 JRTCClientCallback (opens new window) 中的 onLogout (opens new window) 接口上报:
/**
* 登出回调
*
* @param { JRTCReasonCode } reason 登出原因
*/
onLogout?: (reason: JRTCReasonCode) => void;
示例代码:
// 调用登出接口
client.logout();
// 监听登出结果回调
public onLogout(reason: number) {
// 登出完成
}
# 登录状态改变通知
登录状态通过 JRTCClientCallback (opens new window) 中的 onClientStateChanged (opens new window) 接口上报
/**
* 登录状态变化通知
*
* @param { JRTCClientState } state 当前状态值
* @param { JRTCClientState } oldState 之前状态值
*/
onClientStateChanged?: (state: JRTCClientState, oldState: JRTCClientState) => void;
登录状态详见 JRTCClientState (opens new window)
示例代码:
//登录状态改变通知
onClientStateChanged(state: JRTCClientState, oldState: JRTCClientState) {
//state 当前状态
//oldState 之前状态
}
# 4.3.19 销毁SDK
每个模块都有对应的销毁接口。如不需再使用 SDK 的相关功能,可以强制释放 SDK 的资源。
注:该方法为同步调用,调用此方法后,你将无法再使用该模块的其它方法和回调。 我们不建议在 JRTCSDK 的所有回调方法中调用此方法销毁对象,否则可能出现崩溃现象。
/**
* 销毁 JRTCCall 对象
*
* @note 该方法为同步调用,需要等待 JRTCCall 实例资源释放后才能执行其他操作,调用此方法后,你将无法再使用 JRTCCall 的其它方法和回调。<br>
* 我们 **不建议** 在 JRTCSDK 的回调中调用此方法销毁 JRTCCall 对象,否则可能出现崩溃现象。<br>
* 如需在销毁后再次创建 JRTCCall 实例,需要等待 destroy 方法执行结束后再创建实例。
*/
public static destroy(): void;
示例代码:
JRTCAgent.destroy();
JRTCMediaDevice.destroy();
JRTCClient.destroy();
