实现首次通话
适用于 Web 的 CallPlus 可在您的应用程序中为用户之间的一对一和多人通信提供语音和视频通话能力。
CallPlus 支持 一对一通话 和 多人通话。按照下面的指南使用从头开始实现一对一通话和多人通话。
环境要求
- 浏览器页面地址必须为 https 协议地址,或使用 localhost 域名。
- WebRTC API 支持的浏览器兼容性可参考此文档。
前置条件
-
注册开发者账号。 注册成功后,控制台会默认自动创建您的首个应用,默认生成开发环境下的 App Key,使用国内数据中心。
-
获取开发环境的应用 App Key。如不使用默认应用,请参考 如何创建应用,并获取对应环境 App Key 和 App Secret。
注意
每个应用具有两个不同的 App Key,分别对应开发环境与生产环境,两个环境之间数据隔离。在您的应用正式上线前,可切换到使用生产环境的 App Key,以便上线前进行测试和最终发布。
-
完成开通音视频服务。您需要开通音视频通话服务。
Demo 项目
融云提供了一个 Web 端 CallPlus Demo 项目: https://github.com/rongcloud/web-quickdemo-callplus
快速上手
可以按下面的步骤快速集成音视频通话。
步骤 1 安装 SDK
CallPlus for Web SDK 是融云 @rongcloud/imlib-next
的一个插件。CallPlus SDK 提供音视频呼叫能力,通讯能力依赖融云 @rongcloud/engine
和 @rongcloud/imlib-next
,音视频基础能力依赖融云 @rongcloud/plugin-rtc
。
NPM
使用 NPM 需要安装四个 SDK 包
# npm
npm install @rongcloud/engine @rongcloud/imlib-next
npm install @rongcloud/plugin-rtc
npm install @rongcloud/plugin-call-plus
在 ES6
模块中导入 CallPlus SDK,如下所示:
import * as RongIMLib from '@rongcloud/imlib-next';
import { installer as rtcInstaller } from '@rongcloud/plugin-rtc';
import { installer as callPlusInstaller } from '@rongcloud/plugin-call-plus';
注意
如果您使用的是 TypeScript,请将
--esModuleInterop
选项设置为true
以进行默认导入或使用import * as callPlus from '@rongcloud/plugin-call-plus'
。
CDN
您可以使用 <script>
标签外联 Javascript 文件以引入 CallPlus 及其依赖的 SDK。
<!-- RongIMLib -->
<script src="https://cdn.ronghub.com/RongIMLib-5.9.5.prod.js"></script>
<!-- RTCLib v5 -->
<script src="https://cdn.ronghub.com/RCRTC-5.7.1.prod.js"></script>
<!-- CallPlus -->
<script src="https://cdn.ronghub.com/CallPlus-2.1.5.prod.js"></script>
步骤 2 请求访问媒体设备
CallPlus for Web SDK 需要访问麦克风和摄像头。请在集成页面的浏览器控制台中执行 navigator.mediaDevices.getUserMedia({ audio: true, video: true })
,浏览器可能会提示用户授予麦克风和摄像头访问权限。
步骤 3 使用 App Key 初始化
CallPlus SDK 需要依赖 IMLib 作为信令通道。要在您的应用程序中集成和运行 CallPlus SDK,您需要先对 IM SDK 进行初始化。您需要按照以下步骤完成所有 SDK 初始化:
- 使用您的在融云应用的 App Key 初始化
RongIMLib
实例。如果使用不同的APP_Key
初始化实例,客户端应用程序中所有现有的与调用相关的数据将被清除。 - 初始化 RTC SDK,此步骤可返回 RCRTCClient 对象。
- 初始化 CallPlus SDK,此步骤可返回 RCCallPlusClient 对象。
注意
每个融云应用提供开发环境与生产环境,分别使用不同的 App Key,两个环境之间数据隔离。只要客户端应用使用同一个环境的 App Key,用户可以跨所有平台相互通信。
初始化(NPM)
import * as RongIMLib from '@rongcloud/imlib-next';
import { installer as rtcInstaller } from '@rongcloud/plugin-rtc';
import { installer as callPlusInstaller } from '@rongcloud/plugin-call-plus';
// im 初始化
RongIMLib.init({
appkey: '<Your-Appkey>',
});
// RTC 初始化
const rtcClient = RongIMLib.installPlugin(rtcInstaller, {});
// CallPlus 初始化
const callPlusClient = RongIMLib.installPlugin(callPlusInstaller, {
rtcClient
});
初始化(CDN)
// im 初始化
RongIMLib.init({
appkey: '<Your-Appkey>',
});
// RTC 初始化
const rtcClient = RongIMLib.installPlugin(RCRTC.installer);
// CallPlus 初始化
const callPlusClient = RongIMLib.installPlugin(CallPlus.installer, { rtcClient });
步骤 4 获取用户 Token
用户身份令牌(Token)与用户 ID 对应,是应用程序用户在融云的唯一身份标识。应用客户端在使用融云服务前必须与融云建立 IM 连接,连接时必须传入 Token。
在体验和调试阶段,我们将使用控 制台「北极星」开发者工具箱,从 API 调试页面调用 获取 Token 接口,获取到 userId 为 1 的用户的 Token。提交后,可在返回正文中取得 Token 字符串。
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{"code":200,"userId":"1","token":"gxld6GHx3t1eDxof1qtxxYrQcjkbhl1V@sgyu.cn.example.com;sgyu.cn.example.com"}
融云的客户端 SDK 不提供获取 token 的 API。在实际业务运行过程中,调用融云 Server API
/user/getToken.json
, 传入您的应用分配的用户标识(userId)申请 Token。详见 Server API 文档 注册用户。
步骤 5 连接融云服务器
要拨打和接听一对一对呼叫或开始多人呼叫,必须先通过 connect
方法连接融云服务器,传入用户身份令牌(Token),向融云服务器验证用户身份。
获取 Token 以后,可以调用 RongIMLib.connect
方法连接到融云服务器。
RongIMLib.connect('<Your-Token>').then(({code, data}) => {
if (code === RongIMLib.ErrorCode.SUCCESS) {
console.log('connect success', data?.userId);
return;
}
console.log(`connect error: ${code}`);
})
步骤 6 添加事件处理程序
CallPlus SDK 提供了 ICallPlusEventListener 事件处理程序,用于处理通话相关事件。例如收到通话呼入时可选择接听或挂断、收到通话媒体类型升级请求时可选择同意或拒绝、收到通话开始计时可在页面显示通话时长。
使用 RCCallPlusClient
对象的 setCallPlusEventListener 方法添加 ICallPlusEventListener
监听器。
// 注册 callPlus 业务层监听事件
callPlusClient.setCallPlusEventListener({
/**
* 呼入通知
* 收到呼入时,可选择接听或挂断通话
* @param session 通话实例
* @param extra 透传呼叫方发起呼叫时携带的附加信息
*/
async onReceivedCall(session: RCCallPlusSession, extra?: string) {
const callId = session.getCallId();
console.log(`呼入通知, callId: ${callId}`);
/**
* 接听电话
*/
const { code } = await callPlusClient.accept(callId);
console.log(`接听通话结果, code: ${code}`);
},
/**
* 收到某个人的音频或视频可播放
* 业务层可调 playMedia(userId, mediaType) 播放
* 请务必根据用户 ID 和媒体类型对流进行判断,如果是本地采集的音频流,请不要在本端播放,避免造成回声或啸叫问题。
*
* @param userId 用户 id
* @param mediaType 媒体类型
*/
onUserMediaAvailable(userId: string, mediaType: RCCallPlusMediaType) {
/**
* 播放
*/
callPlusClient.playMedia(userId, mediaType);
},
/**
* 人员状态变更
* @param callId 通话 id
* @param userId 状态变更人员 id
* @param state 人员变更后状态
* @param reason 变更原因
*/
onRemoteUserStateChanged(
// 增量
callId: string,
userId: string,
state: RCCallPlusSessionUserState,
reason?: RCCallPlusReason,
) {
console.log(`人员状态变更, callId: ${callId}, ${userId}状态: ${RCCallPlusSessionUserState[state]}, reason: ${reason}`);
},
/**
* 通话结束(群组通话时,客户端挂断不代表通话结束)
* @param session 通话实例
* @param reason 通话结束原因
*/
onCallEnded(session: RCCallPlusSession, reason: RCCallPlusReason) {
console.log(`通话结束, callId: ${session.getCallId()}, reason: ${reason}`);
}
});
注意
如果未注册
ICallPlusEventListener
事件处理程序,则用户无法接收 onReceivedCall 通话呼入事件。因此,应在您注册完callPlusInstaller
后立即执行以上代码,完成注册事件处理程序步骤。
步骤 7 添加视频媒体流播放元素
视频媒体播放元素是一个 HTMLVideoElement <video>
,用于显示视频流。要显示本端和远程视频媒体流,以下两个元素是必需添加在页面中的。id 为 local_video_element_id
的 video
标签用于播放本端视频,id 为 remote_video_element_id
的 video
标签用于播放远端视频。音频播放依赖 SDK 内部创建的 Audio 对象,业务层无需关注。
<video id="local_video_element_id"></video>
<video id="remote_video_element_id"></video>
在页面准备好以上两个标签后,调 callPlusClient.setVideoView
可以设置要观看某些人的画面。如设置了要观看人员 A 的视频视图后,SDK 在获取到 A 的视频后,会在 ICallPlusEventListener
的 onUserMediaAvailable
事件通知业务层,此时业务层可调 callPlusClient.playMedia()
播放媒体资源。
/**
* 设置要观看人员(包括自己和对方)的媒体播放器
* @param list 为一个列表,可传入多人的媒体播放器
* @param item.userId 用户 id
* @param item.videoElement 一个 video 元素,用于播放视频,需要挂载在业务层页面上
* @param item.isTiny 是否观看别人的小流,小窗口时可以配置为 true,可节省带宽,userId 为远端用户时有效
* @returns code 返回是否设置成功
*/
setVideoView(list: {userId: string, videoElement: HTMLVideoElement, isTiny: boolean}[]): { code: RCCallPlusCode }
呼叫和接听前设置本端和远端的视频播放器。
callPlusClient.setVideoView([
{
userId: '<local-userId>',
videoElement: document.getElementById('local_video_element_id')
},
{
userId: '<remote-userId>',
videoElement: document.getElementById('remote_video_element_id')
},
]);
本端的视频播放器需在呼叫和接听前设置。远端人员的视频播放器可以按需设置,既可以在通话前提前设置好,也可以在
ICallPlusEventListener
的 onRemoteUserStateChanged 事件中,收到远端人员状态为RCCallPlusSessionUserState.ONCALL
确认远端接通时设置,如果需要看远端人员的小流,可以指定isTiny
为 true。
进行一对一通话
CallPlus for Web SDK 提供了一对一通话类型 RCCallPlusType.SINGLE
和多人通话类型 RCCallPlusType.MULTI
。此处以一对一通话为例,一对一呼叫只允许传入一个被叫用户 ID,被叫接听成功后才会建立通话。
步骤 8 发起呼叫
注意
从 CallPlus 2.0 开始,startCall 方法新增可选参数
pushConfig
和extra
。pushConfig
支持携带移动端推送配置 IRCCallPlusPushConfig,可用于自定义推送通知标题等属性extra
支持携带透传的自定义数据。
现在可以使用 startCall 方法,传入要呼叫的人员 userId,拨打您的第一通音视频电话了。通话建立成功时,会生成一个 callId。
调用 startCall
成功后,被呼叫人将在步骤 4 中的 onReceivedCall 监听中收到您的呼叫,被呼叫人执行步骤 7 即可建立通话。
/**
* 发起呼叫
* @param userIds 被叫人员 userId 列表,单人呼叫仅需在数组中放置对方一人的 userId
* @param mediaType 通话媒体类型: 音频 or 音视频
* @param type 单人呼叫 or 多人呼叫
* @returns callId 呼叫成功后,产生的会话 id
*/
callPlusClient.startCall(['<userId>'], RCCallPlusType.SINGLE, RCCallPlusMediaType.AUDIO_VIDEO);
步骤 9 接听通话
被叫用户通过 ICallPlusEventListener
监听器的 onReceivedCall
方法接到来电通知后,可以使用 RCCallPlusClient
实例的 accept 方法开始接听。
/**
* 呼入通知
* 收到呼入时,可选择接听或挂断通话
* @param session 通话实例
* @param extra 透传呼叫方发起呼叫时携带的附加信息
*/
async onReceivedCall(session: RCCallPlusSession, extra?: string) {
/**
* 接听电话
*/
const callId = session.getCallId();
const { code } = await callPlusClient.accept(callId);
console.log(`接听通话结果, code: ${code}`);
}
当您接听电话成功后,CallPlus SDK 会自动建立媒体会话。
发起多人通话
CallPlus for Web SDK 提供了支持多人呼叫的通话类型 RCCallPlusType.MULTI
。发起多人通话与一对一通话使用相同的方法,但通话类型必须指定为 RCCallPlusType.MULTI
。多人通话一旦发起成功,融云即开始计时计费。
在一对一通话过程中可以邀请用户加入通话。一旦邀请成功,通话类型会自动转为多人通话。详见多人通话。
步骤 10 拨打多人通话
使用 callPlusClient.startCall
发起多人通话时,除了传入远端被叫用户用户 ID 、媒体类型外,必须指定通话类型为 RCCallPlusType.GROUP
。建议视频通话最多不超过 16 人,音频通话最多不超过 32 人。
/**
* 发起呼叫
* @param userIds 被叫人员 userId 列表,单人呼叫仅需在数组中放置对方一人的 userId
* @param mediaType 通话媒体类型: 音频 or 音视频
* @param type 单人呼叫 or 多人呼叫
* @returns callId 呼叫成功后,产生的会话 id
*/
callPlusClient.startCall(['<userId1>', '<userId2>'], RCCallPlusType.MULTI, RCCallPlusMediaType.AUDIO_VIDEO);
多人通话的接听方法与一对一通话一致。
注意
有关在您的应用程序中构建语音和视频通话功能的详细指南,请参阅完整的 一对一通话和多人通话 文档。我们建议您先按照一对一通话实现完整的通话流程,再按照多人通话补充实现与一对一通话有差异的步骤。