一对一通话
本页介绍了一对一呼叫的主要功能,包括如何从您的应用程序拨打、接听、处理和结束呼叫。
关键类介绍
- RCCallPlusClient:
RCCallPlusClient单例对象是 CallPlus for HarmonyOS SDK 的核心类,用于管理客户端呼叫行为,例如发起、接听、挂断通话,操作音视频设备,管理通话记录等。 - RCCallPlusSession:
RCCallPlusSession对象代表一则通话的所有信息,提供getCallId、getCallType、getMediaType、getUserList等获取通话属性的方法。 - IRCCallPlusCallRecord:
IRCCallPlusCallRecord代表一则通话记录,其中包含了与RCCallPlusSession类似的通话信息,还提供了通话开始与结束的时间戳、通话时长、通话结束原因等信息。 - ICallPlusEventListener:监听器
ICallPlusEventListener提供了来电事件 onReceivedCall 、通话建立成功 onCallConnected 、收到通话记录 onReceivedCallPlusSummaryMessage 等事件相关回调。 - IStatusReportListener:监听器
IStatusReportListener提供通话中的通话质量 数据回调。
初始化
/**
* CallPlusInstance 是 RCCallPlusClient 默认对外导出的实例
* _callPlusClient 为具体实现类声明的私有属性,后续示例代码都使用该变量。
*/
private _callPlusClient: RCCallPlusClient = CallPlusInstance
/**
* 初始化 CallPlus
* @param isPubTiny 配置是否发布视频小流,视频小流分辨率为 W176_H144,默认为 false
* 业务层有订阅视频小流的需求时,可配置 isPubTiny 为 true
*/
this._callPlusClient.init({isPubTiny: false})
设置监听器
注意
必须在 IMLib 连接之前设置监听。
CallPlus for HarmonyOS SDK 提供了两个监听器:
- ICallPlusEventListener 监听器用于接收来自远端用户或服务端的事件。
- IStatusReportListener 监听器用于通话中音视频上下行丢包数据。
请在应用程序初始化或呼叫模块初始化时设置监听器:
-
调用
RCCallPlusClient的setCallPlusEventListener方法设置 ICallPlusEventListener 监听器。TypeScript/**
* 设置事件代理
* @description 多次调用,后面设置会覆盖前面设置的通话事件监听
* @param listener 类型为 ICallPlusEventListener,详细定义可参考 apiDoc
*/
this._callPlusClient.setCallPlusEventListener({
/**
* 呼入通知
* 收到呼入时,可选择接听或挂断通话
* @param session 通话实例
* @param extra 透传呼叫方发起呼叫时携带的附加信息
*/
onReceivedCall: (session: RCCallPlusSession, extra?: string | undefined): void => {
const callId = session.getCallId();
const syncData = session.getSyncData();
const isSecret = session.isSecret();
console.log('呼入通知', callId, extra, syncData, isSecret);
},
/**
* 通话已建立,sdk 内部会发布音视频资源
*/
onCallConnected: (session: RCCallPlusSession): void => {
const callId = session.getCallId();
console.log('本端加入通话', callId);
},
/**
* 通话结束(群组通话时,客户端挂断不代表通话结束)
* @param session 通话实例
* @param reason 通话结束原因
*/
onCallEnded: (session: RCCallPlusSession, reason: RCCallPlusReason): void => {
console.log('通话结束', session.getCallId(), reason);
},
/**
* 收到通话结束的消息记录,可用于在 IM 聊天界面插入通话结束消息
* 仅单聊可收到
* 触发时机:
* 1.单聊在线通话结束后
* 2.离线时收到单聊呼叫,通话结束后,重新连接 IM 在线时
* @param message 通话记录的消息体
*/
onReceivedCallPlusSummaryMessage(message: Message) {
console.log('收到 Call Plus summary message', JSON.stringify(message));
},
/**
* 收到远端人员被邀请加入通话通知
* @param inviteeUserList 被邀请人员列表
* @param inviterUserId 邀请人员 ID
* @param callId 通话 ID
*/
onRemoteUserInvited: (inviteeUserList: string[], inviterUserId: string, callId: string): void => {
console.log('收到远端人员被邀请加入通话通知', inviteeUserList, inviterUserId, callId);
},
/**
* 远端用户的音视频首帧渲染
* @param userId 远端用户 ID
* @param mediaType 媒体类型
*/
onFirstFrame: (userId: string, mediaType: RCCallPlusMediaType): void => {
console.log(`${userId}的 ${(mediaType === RCCallPlusMediaType.AUDIO) ? '音频' : '视频'}可渲染`);
}
})
连接融云服务器
要使用 CallPlus SDK 的通话能力,必须先通过 IMEngine 的 connect 方法连接融云服务器,传入用户身份令牌(Token),向融云服务器验证用户身份。连接成功后,使用 RCCallPlusClient 的 init() 方法初始化和配置 CallPlus SDK。
let token = "用户Token";
IMEngine.getInstance().connect(token, 20).then(result => {
if (EngineError.Success === result.code) {
// 连接成功
let userId = result.userId;
} else {
// 连接失败
}
});
处理本地与远端视频视图
在主叫方发起通话前,被叫方接听通话时需要使用 setVideoView 方法设置视频视图,删除已设置的用户视频视图请调用 removeVideoView 方法。若远端用户没有设置视频渲染视图,则不会产生该用户的视频流的下行流量。
在鸿蒙开发中的渲染通常需要结合 XComponent 组件,通过设置 viewId 来标识 RCCallPlusVideoView 与 XComponent 的唯一性。
本地预览
一般在发起通话前使用 setVideoView 方法,传入当前 userId 以及 RCCallPlusVideoView 实例,同时需要配合 startCamera 接口开启摄像头,就可以实现本地预览。当通话连接成功,本地预览的流才会发布到远端。
// 可以在 .ets 文件,aboutToAppear 方法里面设置本地预览
private viewId: string
aboutToAppear(): void {
// currentUserId 取当前的 userId
const currentUserId = 'current userId'
this.viewId = currentUserId
let videoView = new RCCallPlusVideoView(this.viewId, RCRTCVideoFillMode.ASPECT_FILL)
this._callPlusClient.setVideoView([{userId: currentUserId, videoElement: videoView, isTiny: isTiny}])
}
...
XComponent({
id: this.viewId,
type: XComponentType.SURFACE,
libraryname: 'nativerender'
})
.id(this.viewId)
.height('100%')
.width('70%')
远端视频视图
远端视频渲染和本地视图渲染一样使用 setVideoView 方法,支持在通话前或者通话连接成功后设置,需要指定远端用户的 userId 并且需要设置 viewId 来标识唯一性。接通前设置时,只有接通后 SDK 收到对应视频首帧了,才会开始渲染。
// 定义 viewId 成员变量
private viewId: string
let remoteUserId = "remote UserId"
this.viewId = remoteUserId
let remoteVideoView = new RCCallPlusVideoView(this.viewId, RCRTCVideoFillMode.ASPECT_FILL)
this._callPlusClient.setVideoView([{userId: remoteUserId, videoElement: remoteVideoView, isTiny: true}])
...
// 使用 Stack 容器组件,可在 XComponent 叠加 Text 显示 userId
Stack({alignContent: Alignment.TopStart}) {
XComponent({
id: this.viewId,
type: XComponentType.SURFACE,
libraryname: 'nativerender'
})
Text(`${this.user.uid}`)
.backgroundColor('#6a000000')
.padding(5)
.fontColor(Color.White)
.fontSize(14)
}
.id(this.viewId)
.width('70%')
发起呼叫
CallPlus 定义了一对一通话类型 RCCallPlusType.SINGLE,您可以使用 startCallWithParams 方法来发起一对一通话。同时支持 在发起呼叫时配置推送属性,达到自定义远程推送标题等属性的效果;支持携带自定义数据。如不需要配置推送属性,可选择不传。
/**
* 发起呼叫
* @param IRCCallPlusStartParams.callId 可选参数,非必要不传,如果需要指定 callId,必须保证生成的 callId 唯一性
* @param IRCCallPlusStartParams.userIds 被叫人员userId列表,单人呼叫仅需在数组中放置对方一人的 userId
* @param IRCCallPlusStartParams.callType 通话类型,单人呼叫或多人呼叫,单人呼叫时 userIds 长度只能为 1。
* @param IRCCallPlusStartParams.mediaType 通话媒体类型,音频或者音视频
* @param IRCCallPlusStartParams.pushConfig 可选参数,移动端推送信息
* @param IRCCallPlusStartParams.extra 可选参数,附加信息,会透传给被呼叫方
* @param IRCCallPlusStartParams.syncData 可选参数,定义通话同步数据,该数据与 `extra` 不同点,在于数据会被服务器存储,同时可通过 `session.getSyncData()` 获取数据不可超出 1024 Bytes
* @param IRCCallPlusStartParams.encryption 可选参数,加密配置,非必要不传,用于参与通话端之间的加密公钥交换
* @returns code 返回是否呼叫成功
* @returns callId 呼叫成功后,返回的通话 id
* @returns busyUsers 被呼叫方忙线时,返回忙线人员列表
*/
this._callPlusClient.startCallWithParams({
userIds: ['userId1'],
type: RCCallPlusType.SINGLE,
mediaType: RCCallPlusMediaType.AUDIO,
extra: 'extra',
syncData: 'syncData'
}).then((result) => {
if (result.code === RCCallPlusCode.SUCCESS) {
console.log('发起通话成功');
} else {
console.log('发起通话失败', result.code);
}
});
该方法调用后,SDK 内部会以异步方式执行。在主叫与被叫端触发以下回调:
-
远端被叫用户通过 ICallPlusEventListener 的 onReceivedCall 回调获取来电通知。
-
本地主叫用户将通过 ICallPlusEventListener 的 onRemoteUserStateChanged 回调获取到被叫用户状态变更。
通话建立成功后,主叫端已经设置的 setVideoView 中会自动渲染远端被叫用户的视图。
来电处理
被叫方的客户端应用程序中必须先注册 ICallPlusEventListener 监听器,才能通过 onReceivedCall 接收来电通知。onReceivedCall 方法中会返回 RCCallPlusSession 对象,通过 getCallId 可获取 callId,使用 getCallType 可获取通话类型。
调用以下方法选择是否接听来电:
您可以在收到来电事件后打开摄像头采集,并完成本地视图设置。
/**
* 被叫用户/被邀请用户接收到通话呼叫通知
* @param session 通话实例
* @param extra 透传呼叫方发起呼叫时携带的附加信息
*/
onReceivedCall: (session: RCCallPlusSession, extra?: string): void => {
const callId = session.getCallId();
const syncData = session.getSyncData();
const isSecret = session.isSecret();
console.log('呼入通知', callId, extra, syncData, isSecret);
/// 接听
const res = await this._callPlusClient.accept(callId);
console.log(`接听通话结果, code: ${res.code}`);
}
同样在 onReceivedCall 监听到有新呼入的电话时,调用 hangup 方法直接挂断。
onReceivedCall: (session: RCCallPlusSession, extra?: string): void => {
const callId = session.getCallId();
const syncData = session.getSyncData();
const isSecret = session.isSecret();
console.log('呼入通知', callId, extra, syncData, isSecret);
/// 来电拒接
const res = await this._callPlusClient.hangup(callId);
console.log(`挂断通话结果, code: ${res.code}`);
}