实现音视频通话
更新时间: 2024/09/27 10:50:00
本文介绍如何通过 IM UIKit 引入和初始化呼叫组件,进而在您的 IM 应用中实现音视频通话。
应用场景
自网易云信即时通讯 IM UIKit v9.4.0 开始,会话消息模块(chatkit-ui
)支持音视频通话功能,满足即时通讯应用拨打音视频电话的场景。该功能基于 网易云信呼叫组件 实现。
效果预览
实现音视频通话功能后,用户在会话界面的输入区域单击 更多>音视频,即可快速发起 音频通话 或 视频通话。
开发环境
环境要求 | 说明 |
---|---|
JDK 版本 | 1.8.0 及以上版本 |
Android API 版本 | API 31、Android 5.0 及以上版本 |
CPU 架构 | ARM64、ARMV7 |
IDE | Android Studio |
其他 | 依赖 Androidx,不支持 support 库。Android 系统 5.0 或以上版本的移动设备。 |
前提条件
根据本文操作前,请确保您已经完成了以下准备工作:
第一步:引入呼叫组件
在您的工程的 build.gradle
中引入呼叫组件。
Groovydependencies {
// 引入呼叫组件安装包
implementation("com.netease.yunxin.kit.call:call-ui:2.2.0")// UI 包
// 呼叫组件依赖的信令 SDK,信令 SDK 版本保持和依赖的 NIM SDK 一致
implementation("com.netease.nimlib:avsignalling:10.2.6-beta") //呼叫组件 依赖信令包
}
- 建议引入呼叫组件 2.2.0 及以上版本。
- 如果引入之前的版本,则不支持下文 第四步 提及的通过
XKitRouter
路由方式发起音视频通话。您需要修改源码来调用呼叫组件的音视频通话能力。
第二步:代码防混淆
代码混淆是指使用简短无意义的名称重命名已存在的类、方法、属性等,增加逆向工程的难度,保障 Android 程序源码的安全性。
为了避免因上述的重命名而导致调用呼叫组件异常,请在 proguard-rules.pro
文件中加入以下代码,将呼叫组件相关类加入不混淆名单。
ProGuard-keep class com.netease.lava.** {*;}
-keep class com.netease.yunxin.** {*;}
-dontwarn com.netease.yunxin.kit.**
-keep class com.netease.yunxin.kit.** {*;}
-keep public class * extends com.netease.yunxin.kit.corekit.XKitInitOptions
-keep class * implements com.netease.yunxin.kit.corekit.XKitService {*;}
第三步:初始化呼叫组件
对于不同的呼叫 UI 组件版本,初始化接口不同。
场景一:呼叫 UI 组件低于 v2.1.0
在发起音视频通话前,需先调用 CallKitUI.init
方法初始化呼叫组件。
- 呼叫组件初始化相关代码内容,建议放在工程的
MainActivity
中执行,尽量避免在MainActivity#onDestroy()
方法中做组件的释放。建议在 App 用户登出时释放,登入时进行初始化。 - 在 IM Demo 中,网易云信将该初始化方法,放在了
MainActiviy
页面。
参数 |
类型 |
必传 | 说明 |
---|---|---|---|
rtcAppKey |
String | 是 | 在网易云信控制台创建应用时获取到的 App Key。 |
currentUserAccId |
String | 是 | 当前用户的 IM 账号(accid),可通过如下两种方式注册:
|
timeOutMillisecond |
Long | 否 | 呼叫/接听的超时时间,默认 30 秒。单位:毫秒。 |
notificationConfigFetcher |
Function1<InvitedInfo, CallKitNotificationConfig> | 否 | 根据呼叫邀请信息 InvitedInfo 确定展示的通知提示,可配置通知图标、通知 channelId、标题、通知内容。 |
resumeBGInvitation |
Boolean | 否 | 应用在后台时,收到呼叫邀请未唤起应用被叫页面,此时单击桌面图标唤起应用时,是否展示被叫页面。默认为 true。 |
rtcTokenService |
TokenService | 否 | 请求 RTC Token,需自行实现。如果使用呼叫组件 v1.8.0 及以上版本,调试环境中无需设置,应用正式上线后的 生产环境中必须设置。RTC Token 相关详情,请参考 RTC Token 鉴权。
|
rtcSdkOption |
NERtcOption |
否 | NERTC SDK 初始化的配置,会透传给 SDK。 |
rtcInitScope |
Boolean | 否 | 呼叫组件初始化范围,默认为 true:
|
更多呼叫组件的初始化参数说明,请参考 初始化参数配置。
示例代码:
JavaCallKitUIOptions options = new CallKitUIOptions.Builder()
.rtcAppKey("<your appKey>") // 您在网易云信控制台申请的 App KEY
.currentUserAccId(IMKitClient.account()) // 修改为您当前的 IM 用户账号 ID
.timeOutMillisecond(30 * 1000L)
.notificationConfigFetcher(invitedInfo -> new CallKitNotificationConfig(R.drawable.ic_logo))
.resumeBGInvitation(true)
// 请求 NERTC Token 服务,若非安全模式则不需设置(V1.8.0 版本之前需要配置,V1.8.0 及之后版本无需配置)
//.rtcTokenService((uid, callback) -> requestRtcToken(appKey, uid, callback)) // 自己实现的 Token 请求方法
// 设置初始化 NERTC SDK 相关配置,按照所需进行配置
.rtcSdkOption(new NERtcOption())
.rtcInitScope(true)
.build();
// 若重复初始化会销毁之前的初始化实例,重新初始化
CallKitUI.init(getApplicationContext(), options);
场景二:呼叫 UI 组件 v2.1.0 及以上
在发起音视频通话前,需先调用 CallKitUI.init
方法初始化呼叫组件(登录完成之后进行)。
- 呼叫组件初始化相关代码内容,建议放在工程的
MainActivity
中执行,尽量避免在MainActivity#onDestroy()
方法中做组件的释放。建议在 App 用户登出时释放,登入时进行初始化。 - 在 IM Demo 中,网易云信将该初始化方法,放在了
MainActiviy
页面。
参数 |
类型 |
必传 | 说明 |
---|---|---|---|
appKey |
String | 是 | 在 网易云信控制台 创建应用时获取到的 App Key |
currentUserAccId |
String | 否 | 当前用户的 IM 账号 ID(accid) |
currentUserRtcUid |
Long | 否 | 当前用户的 RTC 账号 ID(uid) |
rtcConfig |
NERtcOption | 否 | RTC 私有化配置初始化对象,不需要私有化可空 |
enableAutoJoinSignalChannel |
Boolean | 否 | 被叫是否自动加入 channel,默认 NO,不加入 |
enableJoinRtcWhenCall |
Boolean | 否 | 主叫是否在呼叫时加入 RTC,默认 NO,不加入 |
initRtcMode |
Integer | 否 | 是否在初始化呼叫组件时初始化 RTC,默认为 NECallInitRtcMode.GLOBAL(全局初始化),具体请参考 NECallInitRtcMode |
rtcCallExtension |
CallExtension |
否 | 扩展字段,可以通过该参数实现修改音视频功能 |
更多呼叫组件的初始化参数说明,请参考 初始化参数配置。
示例代码:
JavaCallKitUIOptions options = new CallKitUIOptions.Builder()
// 必要:音视频通话中使用,您的网易云信控制台申请的 App KEY
.rtcAppKey("<your App KEy >")
// 必要:当前用户 AccId
.currentUserAccId(IMKitClient.account())
// 通话接听成功的超时时间单位 毫秒,默认 30s
.timeOutMillisecond(30 * 1000L)
// 此处为 收到来电时展示的 notification 相关配置,如图标,提示语等。
.notificationConfigFetcher(neInviteInfo -> new CallKitNotificationConfig(R.drawable.ic_logo))
// 收到被叫时若 app 在后台,在恢复到前台时是否自动唤起被叫页面,默认为 true
.resumeBGInvitation(true)
// 请求 NERTC Token 服务,若非安全模式则不需设置(V1.8.0 版本之前需要配置,V1.8.0 及之后版本无需配置)
//.rtcTokenService((uid, callback) -> requestRtcToken(appKey, uid, callback)) // 自己实现的 Token 请求方法
// 设置初始化 NERTC SDK 相关配置,按照所需进行配置
.rtcSdkOption(new NERtcOption())
// 呼叫组件初始化 NERTC 范围,NECallInitRtcMode.GLOBAL-全局初始化,
// NECallInitRtcMode.IN_NEED-每次通话进行初始化以及销毁,全局初始化有助于更快进入首帧页面,
// 当结合其他组件使用时存在 NERTC 初始化冲突可设置 NECallInitRtcMode.IN_NEED
// 或当结合其他组件使用时存在 NERTC 初始化冲突可设置 NECallInitRtcMode.IN_NEED_DELAY_TO_ACCEPT
.initRtcMode(NECallInitRtcMode.IN_NEED)
.build();
// 不要重复初始化组件可能会产生 sdk 初始化失败问题
CallKitUI.init(getApplicationContext(), options);
第四步:发起音视频通话
网易云信已将呼叫组件的语音通话和视频通话能力注册到路由 XKitRouter
中。因此您可通过该路由发起音视频通话。
调用 navigate
方法,即可发起语音通话或视频通话。
方法原型如下:
Java//带参数的界面跳转
XKitRouter.withKey(path).withParam(paramKey,param).withContext(context).navigate();
参数 |
类型 | 说明 |
---|---|---|
path |
String | 需跳转至的目标界面对应的路由地址 |
paramKey |
String | 传递到目标界面的参数 KEY |
param |
Serializable | 传递到目标界面的参数值 |
context |
Context | Activity 上下文 |
-
语音通话:发起语音通话的示例代码如下。
Java
XKitRouter.withKey(RouterConstant.PATH_CALL_SINGLE_PAGE) .withContext(getContext()) // Activity 上下文 .withParam(RouterConstant.KEY_CALLER_ACC_ID, IMKitClient.account()) // 呼叫方的 IM 账号(accid) .withParam(RouterConstant.KEY_CALLED_ACC_ID, sessionID) // 被呼叫方的 IM 账号(accid)或者单聊会话 ID .withParam(RouterConstant.KEY_CALL_TYPE, RouterConstant.KEY_CALL_TYPE_AUDIO) // 呼叫类型 .navigate();
-
视频通话:发起视频通话的示例代码如下。
Java
XKitRouter.withKey(RouterConstant.PATH_CALL_SINGLE_PAGE) .withContext(getContext()) // Activity 上下文 .withParam(RouterConstant.KEY_CALLER_ACC_ID, IMKitClient.account())// 呼叫方的 IM 账号(accid) .withParam(RouterConstant.KEY_CALLED_ACC_ID, sessionID) // 被呼叫方的 IM 账号(accid)或者单聊会话 ID .withParam(RouterConstant.KEY_CALL_TYPE, RouterConstant.KEY_CALL_TYPE_VIDEO) // 呼叫类型 .navigate();
第五步:销毁呼叫组件
在退出登录或者应用退出的时候,进行呼叫组件销毁。示例代码如下(在退出登录时进行销毁):
Java// 添加登录监听
IMKitClient.addLoginListener(new V2NIMLoginListener() {
@Override
public void onLoginStatus(V2NIMLoginStatus status) {
// 登出
if (status == V2NIMLoginStatus.V2NIM_LOGIN_STATUS_LOGOUT) {
CallKitUI.destroy();
}
}
@Override
public void onLoginFailed(V2NIMError error) {
}
@Override
public void onKickedOffline(V2NIMKickedOfflineDetail detail) {
}
@Override
public void onLoginClientChanged(
V2NIMLoginClientChange change,
List<V2NIMLoginClient> clients
) {
}
});
相关信息
其他功能开通
如果需要实现 屏蔽黑名单用户发起的语音/视频通话请求,需要在 网易云信控制台 开启该功能。如未开通该功能,黑名单用户仍可以向将其拉黑的用户发起通话请求。
-
在 网易云信控制台 首页 应用管理 中选择应用,然后单击 IM 即时通讯 下的 功能配置 按钮进入功能配置页。
-
在顶部选择 基础功能 页签,开启 被拉黑时被拉黑者无法唤起呼叫。
错误码
呼叫组件相关错误码,请参考 错误码。
常见问题
集成组件后出现编译错误怎么办?
如果集成组件后出现报错 expected reference but got (raw string) code example
,请在应用的主工程 styles.xml
文件中添加如下代码:
XML<style name="BottomDialogTheme" parent="ThemeOverlay.AppCompat.Dialog">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:colorBackgroundCacheHint">@null</item>
<item name="android:backgroundDimEnabled">true</item>
<item name="android:windowIsTranslucent">false</item>
</style>
更多问题,请参考 呼叫组件常见问题。