赞
踩
TUIKaraoke 是一个开源的音视频 UI 组件,集成了 腾讯云实时音视频、即时通信、正版曲库直通车等产品,通过在项目中集成 TUIKaraoke 组件,只需要编写几行代码就可以为您的应用添加在线 K 歌场景,体验 K 歌、麦位管理、收发礼物、文字聊天等 TRTC 在 KTV 场景下的相关能力。
基本功能如下图所示:
角色 | 描述 |
---|---|
房主 | 歌房创建者 |
连麦主播 | 进入歌房后,通过上麦成为连麦主播 |
主唱 | 连麦主播点歌后进行排麦演唱,正在演唱者成为主唱 |
听众 | 进入歌房的倾听者 |
今天我们来体验一下,如何使用TUIKaraoke组件来快速搭建在线K歌。
当然在实验之前需要做一些准备,诸如环境配置,获取AppID和密钥等。
如果您未开通腾讯云 TRTC 服务,可进入 腾讯云实时音视频控制台,创建一个新的 TRTC 应用后,在应用管理列表里面找到当前的应用:
点击配置管理,进入到应用信息页面,在应用信息里面就可以找到SDKAppID:
点击快速上手,第二步 获取签发UserSig的密钥Secretkey:
我们用最新版的Android Studio创建新项目,或者在你的项目里面Android Studio 需要3.5及以上版本,API Level 至少是17,官方建议 21以上。另外如果是体验官方的demo,gradle版本还是使用demo的gradle-wrapper.properties
里面的设置,jdk使用1.8。在我们的新项目里面或者现有项目里面就可以不用按照demo的来了。这里我创建的新项目语言是kotlin,gradle版本是7.4.2,当然jdk也相应的使用了jdk16。放一张我的配置
可以通过Use Gradle from
选择使用自己本地下载好的gradle,或者还是按照gradle-wrapper.properties
里面配置的去下载就行了。
1.单击进入 GitHub - tencentyun/TUIKaraoke,选择克隆/下载代码,然后拷贝 Android目录下的 tuikaraoke 和 debug 目录到您的工程中(debug :调试相关, tuikaraoke : KTV业务逻辑)。
setting.gradle
中导入如下配置:include ':tuikaraoke'
include ':debug'
3.在 app 的 build.gradle
文件中添加对 TUIKaraoke
的依赖:
api project(':tuikaraoke')
4.在根目录的 build.gradle
文件中添加 TRTC SDK
和 IM SDK
的依赖:
ext {
liteavSdk = "com.tencent.liteav:LiteAVSDK_TRTC:latest.release"
imSdk = "com.tencent.imsdk:imsdk-plus:latest.release"
}
在 AndroidManifest.xml
中配置 App 的权限,SDK 需要以下权限(6.0以上的 Android 系统需要动态申请麦克风、读取存储权限等):
// 使用场景:悬浮窗功能需要此权限;
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
// 使用场景:使用蓝牙耳机时需要此权限;
<uses-permission android:name="android.permission.BLUETOOTH" />
在 proguard-rules.pro 文件,将 SDK 相关类加入不混淆名单:
-keep class com.tencent.** { *; }
编译下载完成后项目里面已经有了tuikaraoke
和debug
两个模块了
debug/src/main/java/com/tencent/liteav/debug/GenerateTestUserSig.java
文件。GenerateTestUserSig.java
文件中的SDKAppID 和 Secretkey 为上面从腾讯云实时音视频控制台里面获取到的SDKAppID和秘钥。至此,项目的前期准备已经完成,试着编译下,不出意外的话应该可以编译成功。
接下来我们就一起一步一步来实现在线KTV场景啦。
1.设置登录用户信息
用户进入应用时,需要收集登录用户信息,包括userId,userName还有头像等信息。
我们可以构造一个简单的登录界面,输入框只允许输入字符串类型,长度不超过32字节,不支持使用特殊字符,使用英文或数字来设置userId。大致如下:
当然,我们可以根据自己具体的项目结合业务实际账号体系自行设置。
TUIKaraoke提供了两个类,UserModel
模型类和UserModelManager
管理类来管理用户信息。
构造好用户模型信息后就可以使用UserModelManager实例来存储为后续使用:
private fun login() { val userId = mEditUserId.text.toString().trim() val userModel = UserModel() userModel.apply { this.userId = userId userName = userId userSig = GenerateTestUserSig.genTestUserSig(userId) val index = Random().nextInt(AvatarConstant.USER_AVATAR_ARRAY.count()) val coverUrl = AvatarConstant.USER_AVATAR_ARRAY[index] userAvatar = coverUrl } val manager = UserModelManager.getInstance() manager.userModel = userModel val intent = Intent(this, MainActivity::class.java) startActivity(intent) finish() }
其中 userSig:根据 SDKAppId、userId,Secretkey 等信息计算得到的安全保护签名,可以使用TUIKaraoke 提供的GenerateTestUserSig.genTestUserSig
计算,或者参考 如何计算及使用 UserSig实现。
2.配置TRTCKaraokeRoom
组件,TRTCKaraokeRoom
是基于腾讯云实时音视频(TRTC)和即时通信 IM 服务组合而成的组件,支持提供一系列房间列表、房间热度、主播列表等功能,比如创建房间,管理点歌上麦,发送礼物和各种文本、自定义消息,自定义消息可用于实现弹幕、点赞等。
首先通过sharedInstance
来获取TRTCKaraokeRoom
单例对象。
public static synchronized TRTCKaraokeRoom sharedInstance(Context context);
接着通过TRTCKaraokeRoom
的login
方法登录到服务:
public abstract void login(int sdkAppId,
String userId, String userSig,
TRTCKaraokeRoomCallback.ActionCallback callback);
userId和userSig可以从我们前面登录的信息里面拿到,接下来就简单了,代码如下:
/** * 初始化实例并登录 */ private fun initData() { // 1.初始化 获取 TRTCKaraokeRoom 单例对象 mTRTCKaraokeRoom = TRTCKaraokeRoom.sharedInstance(this) // 2.登录 mTRTCKaraokeRoom.login( GenerateTestUserSig.SDKAPPID, userModel.userId, //当前用户的 ID,字符串类型,只允许包含英文字母(a-z 和 A-Z)、数字(0-9)、连词符(-)和下划线(_) userModel.userSig //签名 ) { code, _ -> if (code == 0) {//登录成功回调,成功时 code 为0。 //修改个人信息 mTRTCKaraokeRoom.setSelfProfile( userModel.userName, userModel.userAvatar ) { code, _ -> if (code == 0) { Log.d(TAG, "修改个人信息成功") } } } } }
TRTCKaraokeRoom服务配置好了后,我们就可以管理房间了,创建房间或者进入房间,也可以获取房间列表。
其中创建房间和进入房间需要按两步走,只有房主才能创建房间,销毁房间,听众只能进入房间,退出房间。
创建房间我们使用TUIKaraoke
提供的KaraokeRoomCreateDialog
弹窗就可以了,我们只需要提供登录的房主信息,具体的创建房间就由TUIKaraoke
来完成就好了。
调用弹窗的代码如下:
/**
* 创建房间(房主调用),若房间不存在,系统将自动创建一个新房间。
*/
private fun createRoom() {
val dialog = KaraokeRoomCreateDialog(this)
dialog.showRoomCreateDialog(
userModel.userId,
userModel.userId,
userModel.userAvatar,
TRTCCloudDef.TRTC_AUDIO_QUALITY_DEFAULT,
true
)
}
不幸的是,在这里,大家打开弹窗的时候可能会报错。
com.tencent.liteav.tuikaraoke.ui.room.KaraokeRoomBaseActivity
的 requestFeature
使用报错。报错信息是java.lang.RuntimeException:
Unable to start activity ComponentInfo{com.mariko.karaoke/com.tencent.liteav.tuikaraoke.ui.room.KaraokeRoomAnchorActivity}:
android.util.AndroidRuntimeException: requestFeature()must be called before adding content
需要修改KaraokeRoomBaseActivity
由继承 AppCompatActivity
改为 Activity
。
1.拷贝歌曲管理类实现。
在打开弹窗的时候还有个错误:
java.lang.RuntimeException: Unable to start activity ComponentInfo {com.mariko.karaoke/com.tencent.liteav.tuikaraoke.ui.room.KaraokeRoomAnchorActivity}: java.lang.NullPointerException:
Attempt to invoke virtual method 'void com.tencent.liteav.tuikaraoke.ui.music.KaraokeMusicService.setRoomInfo(com.tencent.liteav.tuikaraoke.model.TRTCKaraokeRoomDef$RoomInfo)'
on a null object reference
原因是在KaraokeRoomAnchorActivity
里面KaraokeMusicService.setRoomInfo
调用崩溃了,为什么会崩溃呢?原来通过KaraokeMusicService是通过 mPakcageName
反射创建管理实现的:
// 通过反射创建歌曲管理实现类的实例
public void createKTVMusicImpl() {
try {
Class clz = Class.forName(mPakcageName);
Constructor constructor = clz.getConstructor(Context.class);
mKaraokeMusicService = (KaraokeMusicService) constructor.newInstance(this);
} catch (Exception e) {
e.printStackTrace();
}
}
找到mPakcageName:
private String mPakcageName = "com.tencent.liteav.demo.karaokeimpl.KaraokeMusicServiceImpl";
在我们的项目的里面是没有的,提示我们要实现这个歌曲管理类,然后替换。
为了快速实现,我们从 GitHub - tencentyun/TUIKaraoke, 选择已经下载的demo代码里面,找到TUIKaraoke/Android/app/src/main/java/com/tencent/liteav/demo/karaokeimpl
的karaokeimpl文件夹,拷贝到我们的项目里面,记得更改下包名,最后如下图所示:
2.拷贝本地音频文件。
从demo项目里面拷贝assets
目录里面的音频文件和字幕。
3.加载音频文件。
在进入房间之前,也就是打开弹窗之前需要将本地的音频文件预先加载到内存里面。
使用一个公共方法加载音频或者字幕:
public static void copyAssetsToFile(Context context, String name) { String savePath = ContextCompat.getExternalFilesDirs(context, null)[0].getAbsolutePath(); String filename = savePath + "/" + name; File dir = new File(savePath); // 如果目录不存在,创建这个目录 if (!dir.exists()) { dir.mkdir(); } try { if (!(new File(filename)).exists()) { InputStream is = context.getResources().getAssets().open(name); FileOutputStream fos = new FileOutputStream(filename); byte[] buffer = new byte[7168]; int count = 0; while ((count = is.read(buffer)) > 0) { fos.write(buffer, 0, count); } fos.close(); is.close(); } } catch (Exception e) { e.printStackTrace(); } }
然后再分别加载所有文件:
public static void initLocalData(Context context) { copyAssetsToFile(context, "houlai_bz.mp3"); copyAssetsToFile(context, "houlai_yc.mp3"); copyAssetsToFile(context, "qfdy_yc.mp3"); copyAssetsToFile(context, "qfdy_bz.mp3"); copyAssetsToFile(context, "xq_bz.mp3"); copyAssetsToFile(context, "xq_yc.mp3"); copyAssetsToFile(context, "nuannuan_bz.mp3"); copyAssetsToFile(context, "nuannuan_yc.mp3"); copyAssetsToFile(context, "jda.mp3"); copyAssetsToFile(context, "jda_bz.mp3"); copyAssetsToFile(context, "houlai_lrc.vtt"); copyAssetsToFile(context, "qfdy_lrc.vtt"); copyAssetsToFile(context, "xq_lrc.vtt"); copyAssetsToFile(context, "nuannuan_lrc.vtt"); copyAssetsToFile(context, "jda_lrc.vtt"); }
我们使用的歌曲来自本地的,当然可以增加自己的实现,调用api从腾讯云正版曲库获取歌曲。
至此创建房间的弹窗应该可以打开了,K歌房间也可以进去啦。
打开弹窗后TUIKaraoke
是通过KaraokeRoomAnchorActivity
来创建房间和K歌主界面的,KaraokeRoomAnchorActivity
继承自KaraokeRoomBaseActivity
,KaraokeRoomBaseActivity
主要是加载界面和处理一些事件等,位于tuikaraoke.ui.room
目录下。页面布局是R.layout.trtckaraoke_activity_main
。
我们要做一些定制可以从布局上面顺藤摸瓜了。
在K歌界面我们看到了一段 欢迎消息,同时还有有跳转的链接:
很想把它换掉或者去掉对不对?
其实他就是一个欢迎消息的回显。
在房间里面我们有很多消息类型,有的是文本消息,还有的是带同意按钮的邀请等待的消息,消息的实体tuikaraoke.ui.widget.msg.MsgEntity
的MsgEntity
实体类:
package com.tencent.liteav.tuikaraoke.ui.widget.msg; public class MsgEntity { public static final int TYPE_NORMAL = 0; public static final int TYPE_WAIT_AGREE = 1; public static final int TYPE_AGREED = 2; public static final int TYPE_WELCOME = 3; public static final int TYPE_ORDERED_SONG = 4; public static final int TYPE_ERROR = -1; public String userId; public String userName; public String content; public String invitedId; public String linkUrl; public int type; public int color; public boolean isChat; public String songName; }
有6种类型:
* 普通消息: TYPE_NORMAL 消息的内容会在界面显示出来
* 邀请等待的消息: TYPE_WAIT_AGREE 消息中会有同意的按钮,可以进行事件处理
* 邀请已同意消息: TYPE_AGREED 邀请消息已被处理,事件按钮被隐藏
* 欢迎消息: TYPE_WELCOME 会出现在界面中,同时有跳转的链接url
* 点歌消息: TYPE_ORDERED_SONG 消息中会有管理点歌的按钮,房主可以进行事件处理
TUIKaraoke
提供了一个消息互动显示的适配器MsgListAdapter
,根据消息的类型显示不同的样式,消息的发送者的username可以对颜色进行设置,而且实现了监听按钮等的点击事件,当有消息添加到mList,就通知适配器刷新。
同时使用一个mRvImMsg
的RecyclerView
来展示消息的。涉及到消息的几个属性如下:
KaraokeRoomBaseActivity文件:
protected RecyclerView mRvImMsg;
protected MsgListAdapter mMsgListAdapter;
protected List<MsgEntity> mMsgEntityList;
统一添加消息的入口是在KaraokeRoomBaseActivity
的showImMsg
方法里面:
protected void showImMsg(final MsgEntity entity)
到这里我们就可以找到在KaraokeRoomBaseActivity
的onCreate
里面,开始加载页面的时候就新增了一条欢迎消息了:
消息的类型是TYPE_WELCOME,找到欢迎的文本和文本点击的链接是R.string.trtckaraoke_welcome_visit
,R.string.trtckaraoke_welcome_visit_link
,在string.xml资源文件里面我们就可以重新设置为我们自己的,或者也可以不显示欢迎信息,把上面那段欢迎消息注释掉即可。
<string name="trtckaraoke_welcome_visit">"欢迎体验TRTC Karaoke!进一步了解如何快速搭建Karaoke,请点击: "</string>
<string name="trtckaraoke_welcome_visit_link">"https://cloud.tencent.com/document/product/647/59403"</string>
首先在KTV界面的xml 布局 trtckaraoke_activity_main.xml
中找到礼物按钮
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/btn_more_gift"
style="@style/TRTCKtvRoomButtonStyle"
android:layout_marginEnd="20dp"
android:background="@drawable/trtckaraoke_ic_gift" />
接着查看礼物按钮的点击事件:
mBtnGift.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showGiftPanel();
}
});
事件中打开的就是展示礼物面板
//展示礼物面板 private void showGiftPanel() { IGiftPanelView giftPanelView = new GiftPanelViewImp(this); giftPanelView.init(mGiftInfoDataHandler); giftPanelView.setGiftPanelDelegate(new GiftPanelDelegate() { @Override public void onGiftItemClick(GiftInfo giftInfo) { sendGift(giftInfo); } @Override public void onChargeClick() { } }); giftPanelView.show(); }
可以看到我们的礼物面板是一个弹窗GiftPanelViewImp
,继承自BottomSheetDialog
。它完整实现了礼物的接口IGiftPanelView
,我们完全要定制礼物面板的话也需要实现这套接口:
public interface IGiftPanelView { /** * 面板通用接口 */ void init(GiftInfoDataHandler giftInfoDataHandler); /** * 打开礼物面板 */ void show(); /** * 关闭礼物面板 */ void hide(); //订阅礼物面板事件 void setGiftPanelDelegate(GiftPanelDelegate delegate); }
创建一个实例就是通过void init(GiftInfoDataHandler giftInfoDataHandler)
来初始化的,入参是一个GiftInfoDataHandler
,它包含了如何获取礼物信息和获取成功失败后的回调。
看下GiftInfoDataHandler
类:
public class GiftInfoDataHandler {
private static final String TAG = "GiftInfoManager";
private GiftAdapter mGiftAdapter;
private Map<String, GiftInfo> mGiftInfoMap = new HashMap<>();
public void setGiftAdapter(GiftAdapter adapter) {
mGiftAdapter = adapter;
queryGiftInfoList(null);
}
构造一个GiftInfoDataHandler
需要一个实现了GiftAdapter
的获取礼物信息的适配器mGiftAdapter
。
public abstract class GiftAdapter {
/**
* 查询礼物信息
*
* @param callback
*/
public abstract void queryGiftInfoList(OnGiftListQueryCallback callback);
}
在KaraokeRoomBaseActivity
类里可以找到initData房里初始化了mGiftInfoDataHandler
,通过传入一个默认实现的DefaultGiftAdapterImp
来构造mGiftInfoDataHandler:
// 礼物
GiftAdapter giftAdapter = new DefaultGiftAdapterImp();
mGiftInfoDataHandler = new GiftInfoDataHandler();
mGiftInfoDataHandler.setGiftAdapter(giftAdapter);
到这里已经是拨开云雾见青天啦,其实我们要找的就是这个DefaultGiftAdapterImp
,是它实现如何获取礼物的,那么先看下DefaultGiftAdapterImp 类:
public class DefaultGiftAdapterImp extends GiftAdapter implements HttpGetRequest.HttpListener { private static final String TAG = "DefaultGiftAdapterImp"; private static final int CORE_POOL_SIZE = 5; private static final String GIFT_DATA_URL = "https://liteav.sdk.qcloud.com/app/res/picture/live/gift/gift_data.json"; private GiftBeanThreadPool mGiftBeanThreadPool; private OnGiftListQueryCallback mOnGiftListQueryCallback; @Override public void queryGiftInfoList(final OnGiftListQueryCallback callback) { mOnGiftListQueryCallback = callback; ThreadPoolExecutor threadPoolExecutor = getThreadExecutor(); HttpGetRequest request = new HttpGetRequest(GIFT_DATA_URL, this); threadPoolExecutor.execute(request); }
我们看到它实现GiftAdapter接口的查询礼物信息的方法queryGiftInfoList
,在queryGiftInfoList方法里面我们看到它是通过http请求从网络服务器上获取到了礼物数据的,接口地址就是
private static final String GIFT_DATA_URL = "https://liteav.sdk.qcloud.com/app/res/picture/live/gift/gift_data.json";
试着从浏览器里面打开接口看下返回数据
接口返回的数据类型是GiftBean
,DefaultGiftAdapterImp又做了一层转换,转换成后面要方便处理的GiftData
类型:
public class GiftData {
// 礼物id
public String giftId;
//礼物图片对应的url
public String giftPicUrl;
//礼物全屏动画url
public String lottieUrl;
//礼物的名称
public String title;
//礼物价格
public int price;
//礼物类型 0为普通礼物, 1为播放全屏动画
public int type;
}
到这里我们其实就可以模仿DefaultGiftAdapterImp
做一套自己的实现,或者根据自己的业务需要实现自己的网络接口,按照GiftData
模型返回数据类型就行。
GiftPanelViewImp
的代码,它是通过一个ViewPager
来切换不同页的,每页显示的礼物是一个List<View>
。GiftPanelViewImp
类里面找到mDefalutPanelType
属性,它是个String
类型,默认值是一个常量GIFT_PANEL_TYPE_SINGLEROW
,指向的字符串是single_row
,也就是单行,我们可以修改为多行显示。GIFT_PANEL_TYPE_SINGLEROW
常量的文件里,我们找到多行显示的常量GIFT_PANEL_TYPE_MULTIROW
,替换下mDefalutPanelType
的值:private String mDefalutPanelType = GIFT_PANEL_TYPE_MULTIROW;
运行项目显示的效果如下:
显示了两行礼物,随着礼物数量增多就可以实时适配多行显示了。
public interface GiftPanelDelegate {
/**
* 礼物点击事件
*/
void onGiftItemClick(GiftInfo giftInfo);
/**
* 充值点击事件
*/
void onChargeClick();
}
在实例化礼物面板的时候,KaraokeRoomBaseActivity
已经帮我们实现了礼物的点击事件了:
giftPanelView.setGiftPanelDelegate(new GiftPanelDelegate() {
@Override
public void onGiftItemClick(GiftInfo giftInfo) {
sendGift(giftInfo);
}
@Override
public void onChargeClick() {
}
});
sendGift
方法就是发送礼物消息出去同时展示礼物动画和弹幕,还有处理弹幕消息的handleGiftMsg
方法等。
充值点击事件就需要我们根据业务的需要自己实现啦。
查看TUIKaraoke并没有提供播放礼物动画,我们可以尝试着自己在TUIKaraoke的基础上简单实现一个使用Lottie
播放动画的需求。
Lottie
是支持Android, iOS, 和React Native,并且只需简单的代码就可以实现复杂动画效果的库,具体使用我们可以参考lottie-android。
在TUIKaraoke的build.gradle文件里面引入Lottie
库:
implementation 'com.airbnb.android:lottie:5.2.0'
在KTV主页面布局trtckaraoke_activity_main
里面最外层新增LottieAnimationView
控件:
<androidx.constraintlayout.widget.ConstraintLayout
...
....
<com.airbnb.lottie.LottieAnimationView
android:id="@+id/lt_gift"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:lottie_autoPlay="false"
app:lottie_loop="false"
app:lottie_repeatMode="restart" />
</androidx.constraintlayout.widget.ConstraintLayout>
定义LottieAnimationView
属性,并新增监听动画完成事件,播放完动画后隐藏控件。
private LottieAnimationView mLottieAnimationView; mLottieAnimationView = findViewById(R.id.lt_gift); mLottieAnimationView.addAnimatorListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { mLottieAnimationView.setVisibility(View.VISIBLE); } @Override public void onAnimationEnd(Animator animation) { mLottieAnimationView.setVisibility(View.GONE); } @Override public void onAnimationCancel(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } });
新增一个方法来开始播放动画:
//展示礼物动画
private void showGiftLottieAnimation(String lottieUrl) {
mLottieAnimationView.setVisibility(View.VISIBLE);
mLottieAnimationView.setAnimationFromUrl(lottieUrl);
mLottieAnimationView.playAnimation();
}
接下来需要在两个地方添加播放动画,一个就是点击礼物的时候播放,另一个是在收到别人发送礼物的时候播放动画了。
在打开礼物面板初始化的时候,礼物面板的点击礼物的delega里面:
//展示礼物面板 private void showGiftPanel() { IGiftPanelView giftPanelView = new GiftPanelViewImp(this); giftPanelView.init(mGiftInfoDataHandler); giftPanelView.setGiftPanelDelegate(new GiftPanelDelegate() { @Override public void onGiftItemClick(GiftInfo giftInfo) { sendGift(giftInfo); //播放动画 if (!giftInfo.lottieUrl.isEmpty()) { showGiftLottieAnimation(giftInfo.lottieUrl); } } @Override public void onChargeClick() { } }); giftPanelView.show(); }
在收到消息里面,TUIKaraoke通过handleGiftMsg
方法处理弹幕消息,在这个方法里面可以播放我们的礼物动画:
/** * 处理礼物弹幕消息 */ private void handleGiftMsg(TRTCKaraokeRoomDef.UserInfo userInfo, String data) { if (mGiftInfoDataHandler != null) { Gson gson = new Gson(); GiftSendJson jsonData = gson.fromJson(data, GiftSendJson.class); String giftId = jsonData.getGiftId(); GiftInfo giftInfo = mGiftInfoDataHandler.getGiftInfo(giftId); if (giftInfo != null) { if (userInfo != null) { giftInfo.sendUserHeadIcon = userInfo.userAvatar; if (!TextUtils.isEmpty(userInfo.userName)) { giftInfo.sendUser = userInfo.userName; } else { giftInfo.sendUser = userInfo.userId; } } mGiftAnimatorLayout.show(giftInfo); //播放动画 if (!giftInfo.lottieUrl.isEmpty()) { showGiftLottieAnimation(giftInfo.lottieUrl); } } } }
至此,当我们点击了含有lottieUrl的礼物的时候就可以看到礼物动画了。
总结一下,很多UI组件和功能TUIKaraoke都帮我们实现了,我们只需要在项目里面接入就行了,然后在TUIKaraoke里面修改下配置,通过接口增加我们的实现,也可以在TUIKaraoke的基础上稍加修改就可以基本上完成我们的需求了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。