实现音视频通话
CallKit 是在 CallLib 基础上,增加了一套默认呼叫界面的音视频呼叫功能 SDK,包含了单人、多人音视频呼叫的各种场景和功能,您可以快速的集成它来实现音视频呼叫场景。我们还提供了这个模块的开源代码(GitHub · Gitee),您可以根据业务需要进行界面修改。
注意
房间人数上限
- 考虑移动设备的带宽(主要是在多路视频情况下)和 UI 交互效果,建议单次通话或房间内,视频不超过 16 人,纯音频不超过 32 人。超过此上限可能影响通话效果。
- CallKit 代码中已设置人数上限。默认发起视频呼叫时,最多可选 7 人。发起音频呼叫时,最多可选 20 人。如需调整,建议勿超过建议上限。
- CallKit 为开源 SDK,可在源码中修改上限(修改位置:
CallSelectMemberActivity.java中的NORMAL_VIDEO_NUMBER与NORMAL_AUDIO_NUMBER)。
步骤 1:服务开通
您在融云创建的应用默认不会启用音视频服务。在使用融云提供的任何音视频服务前,您需要前往控制台,为应用开通音视频服务。
注意
服务开通、关闭等设置完成后 15 分钟后生效。如需通过 SDK 判断您的 App 是否已成功开通服务,可使用 CallLib 的
isVoIPEnabled方法。
步骤 2:SDK 导入
您需要导入融云音视频通话能力库 CallLib,和 RTC 业务所依赖的即时通讯能力库 IMLib。根据您的业务需求,可选择导入美颜扩展库。
具体步骤请参阅 导入 CallLib SDK。
步骤 3:代码混淆
若开发者发布的 App 启用代码混淆,请务必在 app/proguard-rules.pro 文件添加如下配置:
-keepattributes Exceptions,InnerClasses
-keepattributes Signature
#RongRTCLib
-keep public class cn.rongcloud.** {*;}
#RongIMLib
-keep class io.rong.** {*;}
-keep class cn.rongcloud.** {*;}
-keep class * implements io.rong.imlib.model.MessageContent {*;}
-dontwarn io.rong.push.**
-dontnote com.xiaomi.**
-dontnote com.google.android.gms.gcm.**
-dontnote io.rong.**
-ignorewarnings
步骤 4:权限配置
-
在
AndroidManifest.xml中声明 SDK 需要的所有权限。xml<!-- 音视频需要网络权限 和 监听网络状态权限 -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- 摄像头采集需要 -->
<uses-permission android:name="android.permission.CAMERA" />
<!-- 音频采集需要 -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> -
如果您的应用需要支持 Android 6.0(API 级别 23)或更高版本的设备,您还 需要在 App 用户使用对应功能时(例如发起呼叫、接听)请求摄像头(
CAMERA)、麦克风(RECORD_AUDIO)权限。详见 Android 开发者官方文档运行时权限与请求权限的工作流。
步骤 5:初始化
音视频 SDK 是基于即时通信 SDK 作为信令通道的,所以要先初始化 IM SDK。如果不换 AppKey,在整个应用生命周期中,初始化一次即可。建议调用位置放在 Application 的 onCreate() 方法内,或在音视频功能模块的加载位置处。
示例代码:
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
String appKey = "YourAppKey"; // 从控制台申请 的 AppKey,example: bos9p5rlcm2ba
InitOption initOption = new InitOption.Builder().build();
IMCenter.init(this, appKey, initOption);
// 5.34.0 版本开始:如果 需要使用 TextureView 渲染视频,调用以下方法开启。默认使用 SurfaceView。
RongCallKit.enableTextureViewMode(true);
}
}
关于多进程的说明
融云 SDK 默认采用了多进程机制(如需修改进程模式,参考进程说明文档),初始化之后,应用会启动以下进程:
- 应用的主进程
<应用包名>:ipc。此进程是 IM 通信的核心进程,和主进程任务相互隔离。io.rong.push:融云默认推送进程。该进程是否启动由推送通道的启用策略决定。详细说明可参考启用推送。
步骤 6:连接 IM 服务
音视频用户之间的信令传输依赖于融云的即时通信(IM)服务,因此需要先调用 connect() 与 IM 服务建立好 TCP 长连接。建议在功能模块的加载位置处调用,之后再进行音视频呼叫业务。当模块退出后调用 disconnect() 或 logout() 断开该连接。
示例代码
RongIM.connect("用户 Token", new RongIMClient.ConnectCallback() {
@Override
public void onSuccess(String userId) {
// 连接成功
}
@Override
public void onError(RongIMClient.ConnectionErrorCode code) {
// 连接失败
}
@Override
public void onDatabaseOpened(RongIMClient.DatabaseOpenStatus databaseOpenStatus) {
// 数据库打开失败
}
});
注意
- 如调用此接口时,遇到网络不好导致连接失败,SDK 会自动启动重连机制进行最多 10 次重连,重连时间间隔分 别为 0.05, 0.25, 0.5, 1, 2, 4, 8, 16, 32, 64 秒。在这之后如果仍没有连接成功,还会在检测到设备网络状态变化,比如网络恢复或切换网络时再次尝试重连。
- 如 App 在被杀死后,接收到了推送通知,点击通知拉起应用时,需要再次调用 connect 方法进行连接。
步骤 7:呼叫方
通常 App 内呼叫和被叫方逻辑会同时存在,所以需要分别集成。
发起单人呼叫
接口
RongCallKit.startSingleCall(context, targetId, mediaType);
参数说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
context | Context | 是 | 上下文 |
targetId | String | 是 | 对方的 UserId |
mediaType | CallMediaType | 是 | 会话媒体类型,包括纯音频呼叫和音视频呼叫。 |
示例代码
RongCallKit.startSingleCall(MainActivity.this, "对方 UserId", RongCallKit.CallMediaType.CALL_MEDIA_TYPE_VIDEO);
发起多人呼叫
接口
RongCallKit.startMultiCall(context, conversationType, targetId, mediaType, userIds);
参数说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| context | Context | 是 | 上下文 |
conversationType | Conversation.ConversationType | 是 | 会话类型 |
targetId | String | 是 | 被叫用户所在共同群组的 GroupId |
mediaType | CallMediaType | 是 | 会话媒体类型,包括纯音频呼叫和音视频呼叫。 |
userIds | ArrayList<String> | 是 | 被叫用户 UserId 列表 |
示例代码
String targetId = "GroupId1";
RongCallKit.CallMediaType mediaType = RongCallKit.CallMediaType.CALL_MEDIA_TYPE_VIDEO;
ArrayList<String> userIds = new ArrayList<>();
userIds.add("UserId1");
userIds.add("UserId2");
RongCallKit.startMultiCall(MainActivity.this, Conversation.ConversationType.GROUP, targetId, mediaType, userIds);