TUIKaraoke 是一个开源的音视频 UI 组件,集成了 腾讯云实时音视频、即时通信、正版曲库直通车等产品,通过在项目中集成 TUIKaraoke 组件,只需要编写几行代码就可以为您的应用添加在线 K 歌场景,体验 K 歌、麦位管理、收发礼物、文字聊天等 TRTC 在 KTV 场景下的相关能力。

基本功能如下图所示:

  • 房主创建新的 Karaoke 房间开播,听众进入 Karaoke 房间收听/互动。
  • 房主可以管理点歌、将座位上的麦上主播踢下麦。
  • 房主还能对座位进行封禁,其他听众就不能再进行申请上麦了。
  • 听众可以申请上麦,变成麦上主播,上麦后可以点歌和唱歌,也可以随时下麦成为普通的听众。
  • 支持发送礼物和各种文本、自定义消息,自定义消息可用于实现弹幕、点赞等。

房间内的角色及描述

角色 描述
房主 歌房创建者
连麦主播 进入歌房后,通过上麦成为连麦主播
主唱 连麦主播点歌后进行排麦演唱,正在演唱者成为主唱
听众 进入歌房的倾听者

核心功能

  • 实时音频互动:超低延时观看,听众实时接收房主和连麦主播的音频流,保证互动的流畅性。
  • 互动连麦:听众可上麦成为连麦主播,房间内所有用户都可以实时收听麦上主播互动。
  • 正版曲库:正版曲库直通车提供超20w热门曲目,全套高精度伴奏歌词,多码率音质灵活应用,搜索/榜单/歌手分类多维选曲。
  • 排麦模块:连麦主播点歌后,歌曲进入已点列表;当同时上麦人数大于 1 时,根据每首点播歌曲的排麦顺序上麦演唱。
  • 歌词模块:歌曲播放时,根据播放进度显示对应的歌词;听众收听的歌曲进度与歌词进度实时同步。

今天我们来体验一下,如何使用TUIKaraoke组件来快速搭建在线K歌。
当然在实验之前需要做一些准备,诸如环境配置,获取AppID和密钥等。

获取应用的SDKAppID和密钥

如果您未开通腾讯云 TRTC 服务,可进入 腾讯云实时音视频控制台,创建一个新的 TRTC 应用后,在应用管理列表里面找到当前的应用:

点击配置管理,进入到应用信息页面,在应用信息里面就可以找到SDKAppID:

点击快速上手,第二步 获取签发UserSig的密钥Secretkey:

环境准备

  • 最低兼容 Android 4.2(SDK API Level 17),建议使用 Android 5.0 (SDK API Level 21)及以上版本
  • Android Studio 3.5及以上版本

我们用最新版的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里面配置的去下载就行了。

组件集成

下载并导入 TUIKaraoke 组件

1.单击进入 GitHub - tencentyun/TUIKaraoke,选择克隆/下载代码,然后拷贝 Android目录下的 tuikaraokedebug 目录到您的工程中(debug :调试相关, tuikaraoke : KTV业务逻辑)。

  1. 接着在 setting.gradle 中导入如下配置:
include ':tuikaraoke'
include ':debug'

3.在 app 的 build.gradle 文件中添加对 TUIKaraoke 的依赖:

api project(':tuikaraoke')

4.在根目录的 build.gradle 文件中添加 TRTC SDKIM 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.** { *; }

配置工程

编译下载完成后项目里面已经有了tuikaraokedebug两个模块了

  1. 在项目里找到并打开 debug/src/main/java/com/tencent/liteav/debug/GenerateTestUserSig.java 文件。
    配置 GenerateTestUserSig.java 文件中的SDKAppIDSecretkey 为上面从腾讯云实时音视频控制台里面获取到的SDKAppID和秘钥。

至此,项目的前期准备已经完成,试着编译下,不出意外的话应该可以编译成功。

接下来我们就一起一步一步来实现在线KTV场景啦。

实现在线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 = userIduserName = userIduserSig = 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 = userModelval 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);

userIduserSig可以从我们前面登录的信息里面拿到,接下来就简单了,代码如下:

 /*** 初始化实例并登录*/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.KaraokeRoomBaseActivityrequestFeature使用报错。报错信息是
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.MsgEntityMsgEntity实体类:

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,就通知适配器刷新。
同时使用一个mRvImMsgRecyclerView来展示消息的。涉及到消息的几个属性如下:
KaraokeRoomBaseActivity文件:

protected RecyclerView               mRvImMsg;
protected MsgListAdapter             mMsgListAdapter;
protected List<MsgEntity>            mMsgEntityList;

统一添加消息的入口是在KaraokeRoomBaseActivityshowImMsg方法里面:

 protected void showImMsg(final MsgEntity entity)

到这里我们就可以找到在KaraokeRoomBaseActivityonCreate里面,开始加载页面的时候就新增了一条欢迎消息了:

消息的类型是TYPE_WELCOME,找到欢迎的文本和文本点击的链接是R.string.trtckaraoke_welcome_visitR.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.AppCompatImageButtonandroid:id="@+id/btn_more_gift"style="@style/TRTCKtvRoomButtonStyle"android:layout_marginEnd="20dp"android:background="@drawable/trtckaraoke_ic_gift" />

接着查看礼物按钮的点击事件:

 mBtnGift.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {showGiftPanel();}});

事件中打开的就是展示礼物面板

//展示礼物面板private void showGiftPanel() {IGiftPanelView giftPanelView = new GiftPanelViewImp(this);giftPanelView.init(mGiftInfoDataHandler);giftPanelView.setGiftPanelDelegate(new GiftPanelDelegate() {@Overridepublic void onGiftItemClick(GiftInfo giftInfo) {sendGift(giftInfo);}@Overridepublic 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;@Overridepublic 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 {// 礼物idpublic String giftId;//礼物图片对应的urlpublic String giftPicUrl;//礼物全屏动画urlpublic String lottieUrl;//礼物的名称public String title;//礼物价格public int    price;//礼物类型 0为普通礼物, 1为播放全屏动画public int    type;
}

到这里我们其实就可以模仿DefaultGiftAdapterImp做一套自己的实现,或者根据自己的业务需要实现自己的网络接口,按照GiftData模型返回数据类型就行。

  • 调整礼物面板显示
    通过查看礼物面板GiftPanelViewImp的代码,它是通过一个ViewPager来切换不同页的,每页显示的礼物是一个List<View>
  1. 设置礼物多行显示。
    默认的list是单行显示的,我们可以设置为多行。
    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;

运行项目显示的效果如下:

显示了两行礼物,随着礼物数量增多就可以实时适配多行显示了。

  1. 实现礼物点击和充值事件。
    在礼物面板上我们已经看到了各种礼物还有右下角的充值按钮了。我们只需要订阅礼物面板的事件就可以实现我们自己的需求了。
    礼物面板事件:
public interface GiftPanelDelegate {/*** 礼物点击事件*/void onGiftItemClick(GiftInfo giftInfo);/*** 充值点击事件*/void onChargeClick();
}

在实例化礼物面板的时候,KaraokeRoomBaseActivity已经帮我们实现了礼物的点击事件了:

giftPanelView.setGiftPanelDelegate(new GiftPanelDelegate() {@Overridepublic void onGiftItemClick(GiftInfo giftInfo) {sendGift(giftInfo);}@Overridepublic 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.LottieAnimationViewandroid: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() {@Overridepublic void onAnimationStart(Animator animation) {mLottieAnimationView.setVisibility(View.VISIBLE);}@Overridepublic void onAnimationEnd(Animator animation) {mLottieAnimationView.setVisibility(View.GONE);}@Overridepublic void onAnimationCancel(Animator animation) {}@Overridepublic 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() {@Overridepublic void onGiftItemClick(GiftInfo giftInfo) {sendGift(giftInfo);//播放动画if (!giftInfo.lottieUrl.isEmpty()) {showGiftLottieAnimation(giftInfo.lottieUrl);}}@Overridepublic 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的基础上稍加修改就可以基本上完成我们的需求了。

新知实验室 TUIKaraoke在线 K 歌相关推荐

  1. 快速接入腾讯TUIKaraoke在线 K 歌场景

    组件介绍 TUIKaraoke 是一个开源的音视频 UI 组件,集成了 腾讯云实时音视频.即时通信.正版曲库直通车等产品,通过在项目中集成 TUIKaraoke 组件,只需要编写几行代码就可以为您的应 ...

  2. 如何把在线K歌“玩起来”——专访撕歌音视频架构师程乐

    编者按:在线K歌的业务已经发展了十年,程乐在音视频领域也闯荡了十年,甚至更久.为什么选择在线K歌领域?如何走过"漫长的季节",迎来新的风景?如何在"在线K歌"这 ...

  3. k歌的录音伴奏合成技术如何实现_2019年中国在线K歌行业市场现状,在线K歌用户女性占比较高...

    一.在线K歌行业概况 中国在线K歌行业经历了萌芽期.探索期.成长期和发展期.上世纪90年代,量贩式KTV进入中国市场,我国在线K歌行业开始萌芽.随着移动互联网应用范围扩大与移动设备性能提升,唱吧.全民 ...

  4. c语言k歌4.0编程,一次在线K歌玩法的尝试

    最近在产品中推出了一个在线K歌玩法,除了满足用户的娱乐交友需求,也总算是做了一件跟个人兴趣有关的事情了. 做这个需求,主要基于一些用户洞察: 交友场景,用户的表现欲需要窗口. 在现实或虚拟社交场景,为 ...

  5. 在线K歌又现新模式 音遇APP能否站稳脚跟?

    从11月底开始,一款名叫「音遇」的K歌应用突然冲上App Store榜单,并且持续保持在社交免费榜的前列.这款应用主打歌曲接唱的游戏玩法,被认为是声音社交的一种新尝试,不过目前还处于早期阶段,社交和声 ...

  6. xm在线转换成mp3_全民K歌月花费25万,95后表示在线K歌可以换一种玩法

    作者:田巧云,新零售商业评论高级编辑 "在线K歌有望进入3.0时代,开放出更多赛道." "来左边儿,跟我一起画个龙,在你右边儿,画一道彩虹:来左边儿,跟我一起画彩虹,在你 ...

  7. 声网在线K歌房解决方案:一站式接入版权曲库与K歌组件

    9月8日,实时互动云服务商声网Agora在北京举办主题为"K歌有声·想唱就唱"的发布会,正式发布了在线K歌房场景化解决方案,开发者与企业可一站式接入海量正版曲库与K歌组件.场景功能 ...

  8. 在线K歌的发展和优势

    互联网娱乐一直是中国互联网应用的重要部分,中国网络游戏的成功已充分证明了这一点.除了网络游戏之外,在线卡拉OK也是一个非常具有潜力的网络服务项目.随着网络音乐的发展,在电脑上K歌已经越来越流行,被很多 ...

  9. 上市搁浅背后:唱吧、全民K歌们的在线K歌如今活得咋样

    今年5月,唱吧终于完成了将近一年半的上市辅导工作.网上有消息称,唱吧在一个月后,就会正式向证监会递交招股书,踏上A股创业板的上市征途.但眼看着2018年就快要过去,却迟迟未见唱吧上市的消息.对此,唱吧 ...

  10. 在线K歌如何基于zego sdk实现音视频社交玩法

    无处不在的在线K歌. 在线K歌一直是泛娱乐领域的热门赛道,艾媒咨询最新数据表示,2021年中国在线K歌用户规模约为5.1亿人,渗透率约为49.7%,这意味着每两个网民中,就有一个体验过在线K歌. 尽管 ...

最新文章

  1. integer比较_傻傻分不清?Integer、new Integer() 和 int 的面试题
  2. (每日一题)P3723 [AH2017/HNOI2017]礼物(经典FFT)
  3. B 站的前端崩了,后端的你别慌!
  4. jndi weblogic mysql_Tomcat配置JNDI数据源连接池
  5. 「高并发秒杀」linux安装软件有哪几种方式
  6. AcWing算法基础课 Level-2 第二讲 数据结构
  7. 01. Node js Hello world
  8. python关键字驱动框架搭建_python webdriver混合驱动测试框架(数据驱动+关键字驱动)...
  9. c++模板类静态成员变量_一文讲透父子类中静态变量,成员变量初始化顺序原理...
  10. Android开发实战二之Hello Android实例
  11. 创业期的软件开发管理(一)
  12. 【渝粤教育】国家开放大学2018年秋季 0032-21T农业经济学 参考试题
  13. 【转载】一份不可多得的深度学习技巧指南
  14. 按要求编写Java程序(阶乘)
  15. 用户故事与敏捷方法笔记---估算用户故事
  16. 技术分享| 如何部署安装分布式序列号生成器系统
  17. 计算机提示应用程序无法启动,告诉你电脑提示应用程序无法正常启动0x000007b怎么办...
  18. 双绞线传输器的常见问题解析
  19. Modbus CRC计算器(编译环境:C-Free 5.0)
  20. C语言/C++常见习题问答集锦(六十四) 之兔子繁殖(递归与非递归)

热门文章

  1. linux 学习感悟
  2. **Unity环境光遮蔽(Ambient Occlusion)Shader实现逻辑**
  3. TreeMap排序是怎么样的?
  4. java treemap的排序_Java TreeMap的排序(转)
  5. Tomcat安装时提示:No Java Virtual Machine found in folder:XXX
  6. 俄亥俄州立大学计算机科学转学成功,国内普二本学生成功转学美国俄亥俄州立大学...
  7. 什么是服务器的高并发
  8. zip、rar等密码破解软件
  9. linux图片编辑器下载软件,Pix图片编辑器
  10. npm install 报警告npm WARN