实现语聊房
- Android
更新时间不可用
了解语聊房在不同平台上的语聊房方式,包括接入流程、关键配置和平台差异。
示例项目
本文介绍如何实现语聊房,包含登录系统、初始化引擎、创建房间、麦位管理、退出房间。声网在 agora-ent-scenarios 仓库中提供实现语聊房的源代码供你参考。
业务流程
本节展示语聊房中常见的业务流程。
进出房间
下图展示创建、进入、退出房间的流程。
房主邀请听众上麦
下图展示房主邀请听众上麦的流程。在这个流程中,房主发起上麦邀请。如果听众接受邀请,房主会收到通知并修改麦位信息,让听众上麦。听众随后发布自己的音频流。
听众申请上麦
下图展示听众向房主申请上麦的流程。在这个流程中,听众主动发起上麦申请,如果房主接受申请,房主修改麦位信息以让听众上麦。听众收到上麦消息后,发布自己的音频流。
准备开发环境
前提条件
开始前,请确保你的开发环境满足如下要求:
- Android Studio 3.5 及以上。
- Android 手机,版本 Android 5.0(API Level 21)及以上。
- 可以访问互联网的计算机。确保你的网络环境没有部署防火墙,否则无法正常使用声网服务。
- 参考开通语聊房 SDK 相关服务创建声网开发者账号和声网项目,并获取项目的 App ID 和临时 Token,以及登录即时通讯系统所需的用户名 (ID) 和 Token。
集成 SDK
声动语聊用到声网实时互动 (RTC) SDK 和即时通讯 (IM) SDK。本节介绍如何在 Android Studio 创建项目并集成这两个 SDK:
-
如需创建新项目,在 Android Studio 里,依次选择 Phone and Tablet > Empty Activity,创建 Android 项目。
信息
创建项目后,Android Studio 会自动开始同步 Gradle,稍等片刻至同步成功后再进行下一步操作。
-
使用 Maven Central 将声网 RTC SDK 和 IM SDK 集成到你的项目中。
-
在
/Gradle Scripts/build.gradle(Project: <projectname>)文件中添加如下代码,添加 Maven Central 依赖:groovy buildscript { repositories { ... mavenCentral() } ... } allprojects { repositories { ... mavenCentral() } }信息
如果你的 Android 项目设置了 dependencyResolutionManagement,添加 Maven Central 依赖的方式可能存在差异。
-
在
/Gradle Scripts/build.gradle(Module: <projectname>.app)文件中添加如下代码,将声网 RTC SDK 和 IM SDK 集成到你的 Android 项目中:groovy ... dependencies { ... // x.y.z,请填写具体的 SDK 版本号,如:4.0.0 或 4.1.0-1 // 通过实时互动产品发版说明获取最新版本号 implementation 'io.agora.rtc:full-sdk:x.y.z' // 指定 IM SDK 1.1.0 版 implementation 'io.agora.rtc:chat-sdk:1.1.0' }
-
-
添加网络及设备权限。
在
/app/Manifests/AndroidManifest.xml文件中,在</application>后面添加如下权限:XML <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.CAMERA"/> <uses-permission android:name="android.permission.RECORD_AUDIO"/> <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.BLUETOOTH"/> <!-- 对于 Android 12.0 及以上且集成 v4.1.0 以下声网 RTC SDK 的设备,还需要添加以下权限 --> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/> <!-- 对于 Android 12.0 及以上设备,还需要添加以下权限 --> <uses-permission android:name="android.permission.READ_PHONE_STATE"/> <uses-permission android:name="android.permission.BLUETOOTH_SCAN"/> -
在
/Gradle Scripts/proguard-rules.pro文件中添加如下行,以防止声网 SDK 的代码被混淆:Kotlin -keep class io.agora.**{*;} -dontwarn javax.** -dontwarn com.google.devtools.build.android.**
实现语聊房
你需要声网 RTC SDK、IM SDK 和云服务 (Service) 共同搭建语聊房场景。其中:
- 实时互动 RTC SDK 承担实时音频的业务。
- 即时通讯 IM SDK 实现房间内的信令通信。
- 云服务 (Service) 实现了房间列表的存储和房间生命周期的管理。
本节会详细介绍如何调用声网云服务(voiceServiceProtocol)、IM SDK 和 RTC SDK 的 API 完成登录即时通讯系统、获取房间列表、创建房间、进入房间、加入 RTC 房间、离开 RTC 房间等关键逻辑。完整的调用时序可以参考 API 时序图。
注意
声网云服务为内部自研服务,暂不对外提供。你可以调用声网云服务的 API 用于测试,但是对于正式环境,声网建议你参考文档自行实现相似的一套服务。如需协助,请联系技术支持。
1. 获取房间列表
调用声网云服务中 voiceServiceProtocol 类的 fetchRoomList 方法获取房间列表。获取到房间列表后刷新 UI 并将房间列表展示在界面上。
voiceServiceProtocol.fetchRoomList(page, completion = { error, result ->
...
})2. 登录即时通讯系统
参考如下步骤登录即时通讯 (IM) 系统:
- 根据前提条件开启声网即时通讯服务,并获取登录即时通讯系统所需的用户名 (ID) 和 Token。
- 调用声网即时通讯 (IM) SDK 中
ChatClient类的loginWithToken方法并传入即时通讯服务的用户名和 Token 以登录即时通讯系统。
public void login(String uid,String token,CallBack callBack){
ChatClient.getInstance().loginWithToken(uid, token, new CallBack() {
@Override
public void onSuccess() {
ThreadManager.getInstance().runOnMainThread(new Runnable() {
@Override
public void run() {
callBack.onSuccess();
}
});
LogTools.d("ChatroomConfigManager","Login success");
}
@Override
public void onError(int code, String msg) {
ThreadManager.getInstance().runOnMainThread(new Runnable() {
@Override
public void run() {
callBack.onError(code,msg);
}
});
LogTools.e("ChatroomConfigManager", "Login onError code:" + code + " desc: " + msg);
}
});
}3. 初始化 RtcEngine
参考如下步骤初始化 RtcEngine:
- 根据开通语聊房 SDK 相关服务在声网控制台创建声网项目后,复制界面的 App ID。
- 调用声网 RTC SDK 中的
create方法创建并初始化RtcEngine。
// 初始化配置
val config = RtcEngineConfig()
// 设置 App ID
config.mAppId = "YourAppId"
// 创建 RtcEngine 实例
val rtcEngine = RtcEngineEx.create(config) as RtcEngineEx4. 创建并进入房间
参考如下步骤创建并进入房间:
-
调用
voiceServiceProtocol对象中的createRoom方法创建一个房间。Kotlin val voiceCreateRoomModel = VoiceCreateRoomModel( roomName = roomName, soundEffect = soundEffect, isPrivate = !TextUtils.isEmpty(password), password = password ?: "", roomType = roomType ) voiceServiceProtocol.createRoom(voiceCreateRoomModel, completion = { error, result -> when (error) { VoiceServiceProtocol.ERR_OK -> { callBack.onSuccess(createLiveData(result)) } VoiceServiceProtocol.ERR_ROOM_NAME_INCORRECT -> { callBack.onError(error, "") } else -> { callBack.onError(error, "") } } }) -
调用
voiceServiceProtocol对象的joinRoom方法进入房间。Kotlin voiceServiceProtocol.joinRoom(roomId, completion = { error, result -> when (error) { VoiceServiceProtocol.ERR_OK -> { callBack.onSuccess(createLiveData(result)) } VoiceServiceProtocol.ERR_ROOM_UNAVAILABLE -> { callBack.onError(error, "room is not existent") } else -> { callBack.onError(error, "") } } }) -
语聊房里需要有消息聊天和语音聊天,因此你还需进行如下操作:
-
调用声网 IM SDK 中
joinChatRoom实现房间内的消息互动。方法中的参数含义和取值请参考joinChatRoom。Kotlin // 实现房间内的消息互动 public void joinRoom(String chatroomId, ValueCallBack<ChatRoom> callBack){ ChatClient.getInstance().chatroomManager() .joinChatRoom(chatroomId, new ValueCallBack<ChatRoom>() { @Override public void onSuccess(ChatRoom value) { ThreadManager.getInstance().runOnMainThreadDelay(new Runnable() { @Override public void run() { callBack.onSuccess(value); } },200); } @Override public void onError(int error, String errorMsg) { ThreadManager.getInstance().runOnMainThread(new Runnable() { @Override public void run() { callBack.onError(error,errorMsg); } }); } }); } -
调用声网 RTC SDK 中
RtcEngine类的joinChannel加入 RTC 频道以实现房间内的实时音频通话。方法中的参数含义和支持取值请参考joinChannel。在这一步里需要填写声网 RTC Token。你可以使用开通语聊房 SDK 相关服务中获取的临时 Token,也可以参考使用 Token 鉴权获取正式用途的声网 RTC Token。临时 Token 的有效期为 24 小时,建议你仅在测试用途下使用。你还可以调用
setChannelProfile、setAudioProfile、setAudioScenario、setParameters为不同业务场景(语聊社交、KTV、游戏陪玩、专业音频直播场景)配置语聊房的推荐音效参数。Kotlin // 实现房间内的语音互动 rtcEngine?.apply { when (soundEffect) { // 在线 K 歌房和泛娱乐社交场景下推荐设置 ConfigConstants.SoundSelection.Social_Chat, ConfigConstants.SoundSelection.Karaoke -> { // 设置频道属性为直播 setChannelProfile(Constants.CHANNEL_PROFILE_LIVE_BROADCASTING) // 设置 48 kHz 采样率,音乐编码,单声道,编码码率最大值为 96 Kbps setAudioProfile(Constants.AUDIO_PROFILE_MUSIC_HIGH_QUALITY) // 设置为高音质场景 setAudioScenario(Constants.AUDIO_SCENARIO_GAME_STREAMING) } // 1 对 1 游戏陪玩通话场景下推荐 ConfigConstants.SoundSelection.Gaming_Buddy -> { // 设置频道属性为通信 setChannelProfile(Constants.CHANNEL_PROFILE_COMMUNICATION) } else -> { // 专业音频直播场景下推荐设置 // 设置频道属性为直播 setChannelProfile(Constants.CHANNEL_PROFILE_LIVE_BROADCASTING) // 指定 48 kHz 采样率,音乐编码,双声道,编码码率最大值为 128 Kbps setAudioProfile(Constants.AUDIO_PROFILE_MUSIC_HIGH_QUALITY) // 设置为高音质场景 setAudioScenario(Constants.AUDIO_SCENARIO_GAME_STREAMING) // 设置私有参数以获得好的实时音频互动体验 setParameters("{\"che.audio.custom_payload_type\":73}") setParameters("{\"che.audio.custom_bitrate\":128000}") setParameters("{\"che.audio.input_channels\":2}") } } } // 加入 RTC 频道 // 此处的 Token 为声网 RTC Token val status = rtcEngine?.joinChannel(VoiceBuddyFactory.get().getVoiceBuddy().rtcToken(), channelId, "", rtcUid)
-
5. 麦位管理
具体步骤详见麦位管理。
6. 退出房间
参考如下步骤退出并销毁语聊房。
-
调用
voiceServiceProtocol对象的leaveRoom方法离开房间。Kotlin voiceServiceProtocol.leaveRoom(roomId, isRoomOwnerLeave, completion = { error, result -> ... }) -
调用
RtcEngine类的leaveChannel方法离开 RTC 频道。Kotlin rtcEngine?.leaveChannel() -
调用
leaveChatRoom离开聊天室,调用asyncDestroyChatRoom销毁聊天室。调用destroy销毁 RTC 引擎。Kotlin ChatroomIMManager.getInstance().leaveChatRoom(roomKitBean.chatroomId) ChatroomIMManager.getInstance().asyncDestroyChatRoom(roomKitBean.chatroomId, object : CallBack { override fun onSuccess() {} override fun onError(code: Int, error: String?) {} }) RtcEngineEx.destroy() rtcEngine = null
API 时序图
如下时序图展示了如何登录即时通讯系统、获取房间列表、创建房间、进入房间、加入 RTC 频道、麦位管理、退出房间、离开 RTC 频道。