实现首次通话
适用于 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}`);
}
});