2024/08/27 13:21:22
歌词强同步
歌词强同步功能指演唱者将歌词的播放进度等信息作为音频的附属信息(Metadata)发送到频道内,频道内的听众接收后可直接渲染歌词进度。相较于通过数据流来实现歌词同步,该功能可确保即便在弱网情况下,歌词和音乐也能保持完全同步。
前提条件
在使用歌词强同步功能前,请按照以下要求准备开发环境:
-
Android Studio 4.0.0 或以上版本。
-
Android 4.1 或以上版本的设备。
-
集成 4.1.1.24 版本的 SDK。
通过 Maven Central 集成-
打开你的项目根目录下的
settings.gradle
文件,添加 Maven Central 依赖 (如果已有可忽略):Javarepositories {
...
mavenCentral()
...
} -
打开
/app/build.gradle
文件,在dependencies
中添加声网实时互动 SDK 的依赖。Javaimplementation "io.agora.rtc:agora-special-full:4.1.1.24"
-
实现流程
本节介绍如何通过发送、接收音频附属信息来实现歌词强同步功能。
演唱者发送歌词进度信息
在调用相关 API 前,你需要在初始化 rtcEngine
后调用 setParameters
设置下列私有参数,才可以发送、接收音频附属信息。
Kotlin
mRtcEngine.setParameters("{\"rtc.enable_nasa2\": true}")
mRtcEngine.setParameters("{\"rtc.use_audio4\": true}")
-
打包歌词信息。为降低数据量,提高歌词解析速度,建议将歌词信息序列化成 Protobuf 格式,下面是一个示例:
protobufsyntax = "proto3";
enum MsgType {
UNKNOWN_TYPE = 0;
LRC_TIME = 1001;
}
message LrcTime {
MsgType type = 1;
bool forward = 2;
int64 ts = 3;
string songId = 4;
int32 uid = 5;
} -
主唱调用
sendAudioMetadata
将歌词及播放进度等信息作为音频附属信息发送到主频道内。Kotlinval lrcTime = LrcTimeOuterClass.LrcTime.newBuilder()
.setTypeValue(LrcTimeOuterClass.MsgType.LRC_TIME.number)
.setForward(true)
.setSongId(songIdentifier)
.setTs(curTs)
.setUid(ktvApiConfig.localUid)
.build()
mRtcEngine.sendAudioMetadata(lrcTime.toByteArray())
听众接收歌词进度信息
当主唱在频道中调用 sendAudioMetadata
发送歌词及歌词进度等信息后,SDK 会触发 onAudioMetadataReceived
回调报告接收到的歌词相关信息及发送端的用户 ID。听众端可以直接通过该回调来获取歌词的播放进度并同步给歌词组件来渲染。
Kotlin
override fun onAudioMetadataReceived(uid: Int, data: ByteArray?) {
super.onAudioMetadataReceived(uid, data)
val messageData = data ?: return
try {
// 解析 metadata
val lrcTime = LrcTimeOuterClass.LrcTime.parseFrom(messageData)
if (lrcTime.type == LrcTimeOuterClass.MsgType.LRC_TIME) { //同步歌词
val realPosition = lrcTime.ts
runOnMainThread {
// 拿到收到的进度传给歌词组件
lrcView?.onUpdateProgress(realPosition)
}
}
} catch (exp: Exception) {
Log.e(TAG, "onAudioMetadataReceived:$exp")
}
}
注意事项
- 调用
sendAudioMetadata
方法发送的信息长度最长为 64 字节。为降低数据量,提高解析速度,声网建议将歌词信息序列化成 Protobuf 格式。 - 为使歌词进度和音乐同步,主唱需要将歌词信息发送到音乐流所在的频道内。在不同场景下,发送歌词信息的方式略有不同:
- 小合唱场景:主唱通过
joinChannel
加入频道,并在主频道发送麦克风和音乐的混流,可直接调用sendAudioMetadata
发送歌词进度到频道内。 - 大合唱场景:主唱通过
joinChannelEx
在频道内发布音乐流,需调用sendAudioMetadataEx
发送歌词进度。调用sendAudioMetadataEx
时使用的RtcConnection
和需和调用joinChannelEx
发布音乐流时使用的RtcConnection
一致。
- 大合唱场景中同步歌词进度还涉及云端合流方案,需要在合流侧也转发 audioMetadata,相关配置方法请联系技术支持。