Start Broadcasting and Listen

适用场景

我们的主播开播观众观看功能主要依赖于我们语音聊天室的核心控件(SeatGridView),该核心控件提供了开启语音聊天室、关闭语音聊天室,直播间内麦位管理,如申请上麦,邀请上麦,移动麦位,踢人下麦等丰富的 API。
当您通过 快速接入 接入语音聊天室 UIKit 后,如果 UI 风格和您的理想中 UI 风格有出入,您可以使用我们的核心控件半小时内快速搭建语音聊天室的主流程。然后在其之上添加您自己的业务 UI 视图。

开发环境要求

Android 5.0(SDK API Level 21)及以上版本。
Gradle 7.0 及以上的版本。
Android 5.0 及以上的手机设备。
环境配置或编译运行期间,如有问题,请参见 常见问题

步骤一:开通服务

请参见 开通服务(TUILiveKit),领取体验版或者开通付费版。

步骤二:工程配置

1. 在 app 目录下找到build.gradle.kts(或build.gradle)文件,并在其中增加如下代码,加入对 SeatGridView 组件的依赖:
build.gradle.kts
build.gradle
api("io.trtc.uikit:voice-room-core:latest.release")
api 'io.trtc.uikit:voice-room-core:latest.release'
2. 由于我们在 SDK 内部使用了Java 的反射特性,需要将 SDK 中的部分类加入不混淆名单,因此需要您在proguard-rules.pro文件中添加如下代码:
-keep class com.tencent.** { *; }
-keep class com.trtc.uikit.livekit.voiceroomcore.** { *; }
3. 在 app 目录下找到AndroidManifest.xml 文件,在 application 节点中添加 tools:replace="android:allowBackup" 和android:allowBackup="false",覆盖组件内的设置,使用自己的设置。
// app/src/main/AndroidManifest.xml
<application
...
// 添加如下配置覆盖 依赖的 sdk 中的配置
android:allowBackup="false"
tools:replace="android:allowBackup">

步骤三:登录

在您的项目中添加如下代码,它的作用是通过调用 TUICore 中的相关接口完成 TUI 组件的登录。这一步骤至关重要,只有在成功登录之后,您才能正常使用 SeatGridView 提供的各项功能。
Kotlin
Java
//登录
TUILogin.login(applicationContext,
1400000001, // 请替换为步骤一取到的 SDKAppID
"denny", // 请替换为您的 UserID
"xxxxxxxxxxx", // 您可以在控制台中计算一个 UserSig 并填在这个位置
object : TUICallback() {
override fun onSuccess() {
Log.i(TAG, "login success")
}

override fun onError(errorCode: Int, errorMessage: String) {
Log.e(TAG, "login failed, errorCode: $errorCode msg:$errorMessage")
}
})
//登录
TUILogin.login(context,
1400000001, // 请替换为步骤一取到的 SDKAppID
"denny", // 请替换为您的 UserID
"xxxxxxxxxxx", // 您可以在控制台中计算一个 UserSig 并填在这个位置
new TUICallback() {
@Override
public void onSuccess() {
Log.i(TAG, "login success");
}

@Override
public void onError(int errorCode, String errorMessage) {
Log.e(TAG, "login failed, errorCode: " + errorCode + " msg:" + errorMessage);
}
});
参数说明
这里详细介绍一下 login 函数中所需要用到的几个关键参数:
参数
类型
说明
SDKAppID
int
在步骤一中的最后一步中您已经获取到,这里不再赘述。
UserID
String
当前用户的 ID,字符串类型,只允许包含英文字母(a-z 和 A-Z)、数字(0-9)、连词符和下划线。
userSig
String
使用 步骤一 的第3步中获取的 SecretKey 对 SDKAppID、UserID 等信息进行加密,就可以得到 UserSig,它是一个鉴权用的票据,用于腾讯云识别当前用户是否能够使用 TRTC 的服务。您可以通过控制台中的 辅助工具 生成一个临时可用的 UserSig。更多信息请参见 如何计算及使用 UserSig
说明:
开发环境:如果您正在本地开发调试阶段,可以采用本地 GenerateTestUserSig.genTestSig函数生成 userSig。该方法中 SDKSecretKey 很容易被反编译逆向破解,一旦您的密钥泄露,攻击者就可以盗用您的腾讯云流量。
生产环境:如果您的项目要发布上线,请采用 服务端生成 UserSig 的方式。

步骤四:使用核心控件实现直播功能

创建核心控件

创建核心控件:您可以在您 Activity 中通过 java 代码或者 xml 方式加载我们的核心控件,其中代码方式示例如下(XML 方式也类似):
kotlin
java
val seatGridView = SeatGridView(this)
SeatGridView seatGridView = new SeatGridView(this);

主播开启直播间和观众加入直播间

主播开启直播间:开启一个直播间,并打开本地麦克风采集。
kotlin
java
val roomInfo = TUIRoomDefine.RoomInfo()
roomInfo.roomId = "roomId_123456"
seatGridView.startVoiceRoom(roomInfo, null)

seatGridView.startMicrophone(null)
TUIRoomDefine.RoomInfo roomInfo = new TUIRoomDefine.RoomInfo();
roomInfo.roomId = "roomId_123456";
seatGridView.startVoiceRoom(roomInfo, null);

seatGridView.startMicrophone(null);
观众加入直播间
kotlin
java
seatGridView.joinVoiceRoom("roomId_123456", null)
seatGridView.joinVoiceRoom("roomId_123456", null);
主播开启直播间开始直播
观众加入直播间观看直播








麦位管理

您如果需要实现麦位管理功能,可参见 麦位管理 文档。

设置麦位列表布局排列

您可以通过以下方式快速设置您的麦位列表布局。
kotlin
java
// 设置宫格布局
seatGirdView.setLayoutMode(VoiceRoomDefine.LayoutMode.GRID, null)

// 设置元素布局
seatGirdView.setLayoutMode(VoiceRoomDefine.LayoutMode.FOCUS, null)

// 设置纵向布局
seatGirdView.setLayoutMode(VoiceRoomDefine.LayoutMode.VERTICAL, null)

// 设置自定义布局
val layoutConfig = VoiceRoomDefine.SeatViewLayoutConfig().apply {
rowConfigs = ArrayList()
rowSpacing = dp2px(10); //每行的间距
}
// 第一行配置
val rowConfig1 = VoiceRoomDefine.SeatViewLayoutRowConfig().apply {
count = 3 //第一行显示的数量
seatSize = VoiceRoomDefine.Size(dp2px(50), dp2px(50)) //第一行显示的每个麦位视图大小
seatSpacing = dp2px(10) //第一行每个麦位的水平间距
alignment = VoiceRoomDefine.SeatViewLayoutRowAlignment.CENTER //第一行麦位的对齐方式
}
layoutConfig.rowConfigs.add(rowConfig1)
// 第二行配置
val rowConfig2 = VoiceRoomDefine.SeatViewLayoutRowConfig().apply {
count = 3 //第二行显示的数量
seatSize = VoiceRoomDefine.Size(dp2px(50), dp2px(50)) //第二行显示的每个麦位大小
seatSpacing = dp2px(10) //第二行每个麦位的水平间距
alignment = VoiceRoomDefine.SeatViewLayoutRowAlignment.SPACE_AROUND //第二行麦位的对齐方式
}
layoutConfig.rowConfigs.add(rowConfig2)
seatGirdView.setLayoutMode(VoiceRoomDefine.LayoutMode.FREE, layoutConfig)
// 设置宫格布局
seatGirdView.setLayoutMode(VoiceRoomDefine.LayoutMode.GRID, null)

// 设置元素布局
seatGirdView.setLayoutMode(VoiceRoomDefine.LayoutMode.FOCUS, null)

// 设置纵向布局
seatGirdView.setLayoutMode(VoiceRoomDefine.LayoutMode.VERTICAL, null)

// 设置自由布局
VoiceRoomDefine.SeatViewLayoutConfig layoutConfig = new VoiceRoomDefine.SeatViewLayoutConfig();
layoutConfig.rowConfigs = new ArrayList<>();
layoutConfig.rowSpacing = dp2px(10); //每行的间距
//第一行配置
VoiceRoomDefine.SeatViewLayoutRowConfig rowConfig1 = new VoiceRoomDefine.SeatViewLayoutRowConfig();
rowConfig1.count = 3; //第一行显示的数量
rowConfig1.seatSize = new VoiceRoomDefine.Size(dp2px(50),dp2px(50)); //第一行显示的每个麦位视图大小
rowConfig1.seatSpacing = dp2px(10); //第一行每个麦位的水平间距
rowConfig1.alignment = VoiceRoomDefine.SeatViewLayoutRowAlignment.CENTER; //第一行麦位的对齐方式
layoutConfig.rowConfigs.add(rowConfig1);
//第二行配置
VoiceRoomDefine.SeatViewLayoutRowConfig rowConfig2 = new VoiceRoomDefine.SeatViewLayoutRowConfig();
rowConfig2.count = 3; //第二行显示的数量
rowConfig2.seatSize = new VoiceRoomDefine.Size(dp2px(50),dp2px(50)); //第二行显示的每个麦位视图大小
rowConfig1.seatSpacing = dp2px(10); //第二行每个麦位的水平间距
rowConfig2.alignment = VoiceRoomDefine.SeatViewLayoutRowAlignment.SPACE_AROUND; //第二行麦位的对齐方式
layoutConfig.rowConfigs.add(rowConfig2);
seatGirdView.setLayoutMode(VoiceRoomDefine.LayoutMode.FREE, layoutConfig);
说明:
自定义布局的参数设置可查看 SeatViewLayoutRowConfig 中参数说明,其中对齐方式 alignment 可参考 SeatViewLayoutRowAlignment 中描述 对齐方式效果可参见 自定义布局对齐方式示意图
宫格布局
元素布局
纵向布局
自定义布局

















自定义布局对齐方式示意图:





自定义麦位视图

如果您认为我们默认的UI不满足您的需求,你想自定义自己的麦位 UI,您可以通过以下方式快速设置您的麦位布局, 完全自定义自己的麦位视图 UI。
kotlin
java
val adapter = object : VoiceRoomDefine.SeatViewAdapter {
override fun createSeatView(seatGridView: SeatGridView, seatInfo: TUIRoomDefine.SeatInfo): View {
return TestSeatInfoView(context, seatGridView, seatInfo)
}

override fun updateSeatView(seatGridView: SeatGridView,seatInfo: TUIRoomDefine.SeatInfo, seatView: View) {
(seatView as TestSeatInfoView).updateSeatView(seatGridView, seatInfo)
}

override fun updateUserVolume(seatGridView: SeatGridView, volume: Int, customSeatView: View) {
(customSeatView as TestSeatInfoView).updateUserVolume(seatGridView, volume)
}
}

seatGirdView.setSeatViewAdapter(adapter)

class TestSeatInfoView constructor(context: Context, seatGirdView: SeatGridView, seatInfo: TUIRoomDefine.SeatInfo) : FrameLayout(context) {
init {
initView() //初始化view
}

fun updateSeatView(seatGirdView: SeatGridView, seatInfo: TUIRoomDefine.SeatInfo) {
updateView(seatInfo) //更新自定义麦位视图UI
}

fun updateUserVolume(seatGirdView: SeatGridView, volume: Int) {
updateUserVolume(volume) //更新音量变化UI
}
}
VoiceRoomDefine.SeatViewAdapter adapter = new VoiceRoomDefine.SeatViewAdapter() {
@Override
public View createSeatView(SeatGridView seatGridView, TUIRoomDefine.SeatInfo seatInfo) {
return new TestSeatInfoView(getApplicationContext(), seatGridView, seatInfo);
}

@Override
public void updateSeatView(SeatGridView seatGridView, TUIRoomDefine.SeatInfo seatInfo,
View customSeatView) {
((TestSeatInfoView) customSeatView).updateSeatView(seatGridView, seatInfo);
}

@Override
public void updateUserVolume(SeatGridView seatGridView, int volume, View customSeatView) {
((TestSeatInfoView) customSeatView).updateUserVolume(seatGridView, volume);
}
};
seatGirdView.setSeatViewAdapter(adapter);

public class TestSeatInfoView extends FrameLayout {

public TestSeatInfoView(@NonNull Context context, SeatGridView seatGirdView, TUIRoomDefine.SeatInfo seatInfo) {
super(context);
initView();
}

public void updateSeatView(SeatGridView seatGirdView, TUIRoomDefine.SeatInfo seatInfo) {
updateView(seatInfo);
}

public void updateUserVolume(SeatGridView seatGirdView, int volume) {
updateUserVolume(volume);
}
}
默认麦位视图
自定义麦位视图示例