快速集成 AUIKaraoke
AUIKaraoke 是一个基于 AUIKit 搭建的、针对 K 歌场景的开源 UI 组件,提供 K 歌房间相关功能。asceneskit 是 K 歌房的容器组件,你可以通过 asceneskit 自定义 K 歌房间的用户界面逻辑、实现房间管理等。
本文介绍如何通过 AUIKaraoke 快速搭建一个含 UI 界面的在线 K 歌房。
示例项目
声网在 GitHub 上提供一个开源的示例项目 供你参考。
准备开发环境
本节介绍集成 AUIKaraoke 的前提条件和项目相关配置。
前提条件
-
Android API Level 24 及以上
-
Android Studio 3.5 及以上
-
Android 设备,版本 Android 7.0 及以上
注意声网推荐使用真机运行项目。部分模拟机可能存在功能缺失或者性能问题。
-
Java Development Kit 17 及以上
-
你的声网项目的 App ID、证书,以及环信项目的 APPKEY、Client ID 以及 Client Secret,如何获取请参考开通服务
创建项目并配置权限
本节介绍如何创建项目并为项目添加体验实时互动所需的权限。
-
如需创建新项目,在 Android Studio 里,依次选择 Phone and Tablet > Empty Activity,创建 Android 项目,如果你已有 Android 项目,可跳过这一步骤。
信息创建项目后,Android Studio 会自动开始同步 gradle, 稍等片刻至同步成功后再进行下一步操作。
-
配置项目权限。在
app/src/main/AndroidManifest.xml
文件中添加下列内容:XML<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="io.agora.app.karaoke">
<!-- asceneskit 运行所需权限 -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CALL_PHONE" />
...
</manifest>如果你使用的不是 https 的业务服务器域名,还需要在
app/src/main/AndroidManifest.xml
文件中将usersCleartextTraffic
属性设为true
以允许所有明文请求:XML<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="io.agora.app.karaoke">
...
<application
...
android:usesCleartextTraffic="true">
...
</application>
</manifest> -
防止代码混淆。打开
app/proguard-rules.pro
文件,添加如下行以防止代码混淆:Java-keep class io.agora.**{*;}
-dontwarn javax.**
-dontwarn com.google.devtools.build.android.**
添加依赖库
-
下载声网提供的 AUIKaraoke 源码。运行以下命令克隆项目到本地:
Shellgit clone git@github.com:AgoraIO-Community/AUIKaraoke.git
-
将 AUIKaraoke 源码目录下
Android/asceneskit
文件夹复制到与你的 App 文件夹所在的同一级目录下。 -
将 AUIKaraoke 源码目录下
Android/app/src/main/java/io/agora/app/karaoke/KaraokeUIKit.kt
类复制到你的项目的app/src/main/java/<package_name>
目录下。 -
添加
asceneskit
库到你的项目中。在settings.gradle.kts
文件中,将dependencyResolutionManagement
替换为下列代码:KotlindependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
// 添加 jitpack 仓库
maven { url = java.net.URI.create("https://www.jitpack.io") }
}
}
rootProject.name = "KaraokeApp"
include(":app")
// 添加 asceneskit 库到项目里
include(":asceneskit") -
添加 namespace。(可选)
信息如果你使用的 Android Gradle Plugin 版本为 8.0,则需要添加 namespace,否则可跳过该步骤。
添加 namespace在
asceneskit/build.gradle
文件中添加 namespace。Javaandroid {
// Android Gradle Plugin 8.0 要求添加 namespace
namespace = "io.agora.asceneskit"
compileSdkVersion 30
...
} -
修改 Java 版本号。(可选)
信息如果你使用的 Java Development Kit 版本为 17,则需要修改版本号,否则可跳过该步骤。
修改版本在
asceneskit/build.gradle
文件中修改 Java 版本号。Javaandroid {
...
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = '17'
}
...
} -
设置主题样式。
-
在
app/src/main/res/values/themes.xml
文件中修改主题(Theme)为 K 歌房主题:XML<resources>
<!-- Karaoke 主题 -->
<style name="Theme.KaraokeApp" parent="Theme.AKaraoke" />
</resources> -
在
app/src/main/AndroidManifest.xml
文件中添加主题:XML<application
···
android:theme="@style/Theme.KaraokeApp">
···
</application>
-
-
添加 asceneskit 依赖。
在
app/build.gradle.kts
文件中添加 asceneskit 依赖。Kotlindependencies {
...
// asceneskit依赖
implementation(project(":asceneskit"))
} -
点击 Sync Project with Gradle Files 来同步项目。
创建在线 K 歌房
本节介绍如何以房主身份快速搭建一个在线 K 歌房来体验 K 歌场景。
1. 初始化 AUIKaraoke
调用 setup
初始化 KaraokeUIKit。打开 app/src/main/java/MainActivity.kt
文件,在 onCreate
方法里调用 setup
进行初始化。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
...
// 初始化 KaraokeUiKit
val config = AUICommonConfig()
config.context = this
// 你的业务服务器域名
config.host = ""
// 你的声网 AppID
config.appId = ""
// 你的声网 App 证书
config.appCert = ""
// 你的 IM AppKey
config.imAppKey = ""
// 你的 IM Client ID
config.imClientId = ""
// 你的 IM Client Secret
config.imClientSecret = ""
config.owner = AUIUserThumbnailInfo().apply {
// 用户 ID
userId = (Random().nextInt(1000) + 10000).toString()
// 用户名
userName = "User-$userId"
// 用户头像
userAvatar = "https://accktvpic.oss-cn-beijing.aliyuncs.com/pic/sample_avatar/sample_avatar_1.png"
}
// Setup KaraokeUIKit
KaraokeUIKit.setup(
commonConfig = config, // must
apiConfig = AUIAPIConfig(
ktvApi = null,
rtcEngineEx = null,
rtmClient = null
)
)
}
2. 创建并进入房间
-
添加创建房间按钮。
- 在
app/src/main/res
路径下新建一个名为 layout 的文件夹,在该文件夹下创建一个.xml
文件,文件名为 main_activity.xml,然后将下列代码复制到该文件中:
Kotlin<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<Button
android:id="@+id/btnCreateRoom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="12dp"
android:text="创建房间"/>
</LinearLayout>-
设置 UI 布局。打开
app/src/main/java/MainActivity.kt
文件,设置 xml 布局并设置按钮点击事件。Kotlinoverride fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 将 jectpack compose 布局改成 xml 布局
setContentView(R.layout.main_activity)
// 设置点击事件并弹窗
findViewById<Button>(R.id.btnCreateRoom).setOnClickListener {
// 创建房间按钮点击
}
}
- 在
-
创建房间详情页界面。
-
在
app/src/main/res/layout/
路径下新建一个.xml
文件,文件名为 room_activity.xml,然后将下列代码复制到该文件中:XML<?xml version="1.0" encoding="utf-8"?>
<io.agora.asceneskit.karaoke.KaraokeRoomView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/karaokeRoomView"
android:layout_width="match_parent"
android:layout_height="match_parent" /> -
在
app/src/main/java/MainActivity.kt
同级目录下创建一个RoomActivity
类用于显示和处理与在线 K 歌房间相关的用户界面和逻辑。Kotlinclass RoomActivity : FragmentActivity() {
companion object {
const val EXTRA_ROOM_INFO = "RoomInfo"
const val EXTRA_IS_CREATE = "isCreate"
fun launch(context: Context, roomInfo: AUIRoomInfo, isCreate: Boolean){
val intent = Intent(context, RoomActivity::class.java)
intent.putExtra(EXTRA_ROOM_INFO, roomInfo)
intent.putExtra(EXTRA_IS_CREATE, isCreate)
context.startActivity(intent)
}
}
// 房间信息
private val isCreate by lazy {
intent.getSerializableExtra(EXTRA_ROOM_INFO) as AUIRoomInfo
}
// 是否创建房间
private val isCreate by lazy {
intent.getBooleanExtra(EXTRA_IS_CREATE, false)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 设置布局
setContentView(R.layout.room_activity)
// 初始化布局
val karaokeRoomView = findViewById<KaraokeRoomView>(R.id.karaokeRoomView)
karaokeRoomView.setFragmentActivity(this@RoomActivity)
}
} -
在
app/src/main/AndroidManifest.xml
文件中配置RoomActivity
:XML<application>
...
<activity android:name=".RoomActivity"
android:windowSoftInputMode="adjustNothing"/>
</application>
-
-
进入 K 歌房间。用户点击创建房间按钮后,随机生成一个房间名和 ID 并进入到新创建的房间中。在
MainActivity.kt
文件中,将下列示例代码添加至findViewById<Button>(R.id.btnCreateRoom).setOnClickListener {
之后:KotlinfindViewById<Button>(R.id.btnCreateRoom).setOnClickListener {
// 点击创建房间按钮
// 随机生成房间名
val roomName = "${Random().nextInt(100) + 1000}"
val roomInfo = AUIRoomInfo()
roomInfo.roomId = UUID.randomUUID().toString()
roomInfo.roomName = roomName
roomInfo.thumbnail = "https://accktvpic.oss-cn-beijing.aliyuncs.com/pic/sample_avatar/sample_avatar_1.png"
roomInfo.owner = AUIRoomContext.shared().currentUserInfo
RoomActivity.launch(this@MainActivity, roomInfo, true)
} -
启动房间。
在
RoomActivity
的onCreate
方法里,调用createRoom
创建并启动房间。在app/src/main/java/RoomActivity
文件中,将下列代码添加至初始化布局之后:Kotlinclass RoomActivity : FragmentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
...
// 检查并申请运行时权限
PermissionHelp(this).checkMicPerm(
granted = {
// 获取到权限
// 生成 RoomConfig 配置
KaraokeUIKit.generateToken(roomInfo.roomId,
onSuccess = { roomConfig ->
// 启动房间
if(isCreate){
// 创建并进入房间
KaraokeUIKit.createRoom(roomInfo, roomConfig, karaokeRoomView){ ex, roomInfo ->
if(ex != null){
// 创建房间失败,直接退出
finish()
}
}
}
},
onFailure = {
// 获取 Token 失败,直接退出
finish()
})
},
unGranted = {
// 没有获取到权限
finish()
})
}
}
至此,你已经成功创建一个在线 K 歌房。
测试 App
按照以下步骤测试你的 App:
-
开启 Android 设备的开发者选项,打开 USB 调试,通过 USB 连接线将 Android 设备接入电脑,并在 Android 设备选项中勾选你的 Android 设备。
-
在 Android Studio 中,点击 Sync Project with Gradle Files 按钮,以让项目与 Gradle 文件同步。
-
待同步成功后,点击 开始编译。
-
编译成功后,你的 Android 设备上会出现 AUIKaraoke App。打开 App,点击创建房间创建一个新的房间来体验在线 K 歌。
后续步骤
成功搭建一个在线 K 歌房间后,你还可以参考本节来进一步了解启动 K 歌房间后的后续步骤。
听众进入房间
-
添加加入房间按钮。
-
在
app/src/main/java/res/layout/main_activity.xml
文件中,添加下列代码:XML<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
...
<Button
android:id="@+id/btnJoinRoom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="12dp"
android:text="加入房间"/>
</LinearLayout> -
在
app/src/main/java/MainActivity.kt
文件中设置点击事件,并弹出输入房间名的弹窗。KotlinfindViewById<Button>(R.id.btnJoinRoom).setOnClickListener {
// 弹出房间名输入弹窗
val input = EditText(this@MainActivity)
input.hint = "Room Name"
AlertDialog.Builder(this@MainActivity)
.setTitle("Launch Room")
.setView(input)
.setPositiveButton("Confirm"){ dialog: DialogInterface, i: Int ->
// 确认加入房间
}
.setNegativeButton("Cancel"){ dialog: DialogInterface, i: Int ->
dialog.dismiss()
}
.show()
}
-
-
获取房间信息以加入房间。
在
app/src/main/java/MainActivity.kt
文件中,将下列代码添加至setPositiveButton
之后:Kotlinval roomName = input.text.toString()
if(TextUtils.isEmpty(roomName)){
Toast.makeText(this@MainActivity, "Room name is empty", Toast.LENGTH_SHORT).show()
dialog.dismiss()
return@setPositiveButton
}
// 查询房间信息
KaraokeUIKit.getRoomList(0, 50,
success = { list ->
val roomInfo = list.findLast { it.roomName == roomName }
if(roomInfo == null){
Toast.makeText(this@MainActivity, "The room is unavailable. RoomName=$roomName", Toast.LENGTH_SHORT).show()
dialog.dismiss()
return@getRoomList
}
// 启动房间
RoomActivity.launch(this@MainActivity, roomInfo, false)
},
failure = {
Toast.makeText(this@MainActivity, "Get room list failed. ${it.code} - ${it.message}", Toast.LENGTH_SHORT).show()
dialog.dismiss()
}) -
进入房间。
在
RoomActivity
获取到roomConfig
后,调用enterRoom
进入房间。在app/src/main/java/RoomActivity
文件中,将下列代码添加至获取到roomConfig
之后:KotlinKaraokeUIKit.generateToken(roomInfo.roomId,
onSuccess = {roomConfig ->
// 启动房间
if(isCreate){
// 创建并进入房间
...
}else{
// 进入房间
KaraokeUIKit.enterRoom(roomInfo, roomConfig, karaokeRoomView){ ex, roomInfo ->
if(ex != null){
// 进入房间失败,直接退出
finish()
}
}
}
},
onFailure = {
// 获取 Token 失败,直接退出
finish()
})
退出及销毁房间
-
当房间被销毁时,退出该房间。
调用
registerRoomRespObserver
方法来注册房间事件观测器。通过onRoomDestroy
回调来房间销毁事件。当房间被销毁时,调用leaveRoom
来退出该房间。在app/src/main/java/RoomActivity.kt
文件中,添加下列代码:Kotlin// 房间事件观测器
private val roomManagerRespObserver = object: AUIKaraokeRoomServiceRespObserver{
override fun onRoomDestroy(roomId: String) {
super.onRoomDestroy(roomId)
// 房间被销毁
destroyRoom()
finish()
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
...
// 注册房间事件观测器
KaraokeUIKit.registerRoomRespObserver(roomInfo.roomId, roomManagerRespObserver)
}
private fun destroyRoom() {
// 退出房间
KaraokeUIKit.leaveRoom(roomInfo.roomId)
// 取消注册房间事件观测器
KaraokeUIKit.unRegisterRoomRespObserver(roomInfo.roomId, roomManagerRespObserver)
} -
主动退出并销毁房间。
当你结束 K 歌并需要释放 K 歌房使用的所有资源时,调用
leaveRoom
来退出并销毁房间。然后调用unRegisterRoomRespObserver
来取消注册房间事件观察器,取消后不会再收到任何房间事件的通知。在app/src/main/java/RoomActivity.kt
文件中,添加下列代码:Kotlinoverride fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 设置布局
setContentView(R.layout.room_activity)
// 初始化布局
val karaokeRoomView = findViewById<KaraokeRoomView>(R.id.karaokeRoomView)
karaokeRoomView.setFragmentActivity(this@RoomActivity)
karaokeRoomView.setOnShutDownClick {
// 主动退出房间
destroyRoom()
finish()
}
...
}
override fun onBackPressed() {
destroyRoom()
super.onBackPressed()
}
private fun destroyRoom() {
// 退出、销毁房间
KaraokeUIKit.leaveRoom(roomInfo.roomId)
// 取消注册房间事件观察器
KaraokeUIKit.unRegisterRoomRespObserver(roomInfo.roomId, roomManagerRespObserver)
}