KTV歌房歌词同步实现流程

2023-10-29 09:30

本文主要是介绍KTV歌房歌词同步实现流程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文讲述iOS环境下,即构平台如何实现 KTV 歌房的歌词同时实现流程。关于 KTV 歌房整体实现的详细介绍请大家阅读《KTV 歌房概述》,在此基础上以全面了解即构平台与 KTV 场景及App体验。

歌词同步实现流程

1、功能实现流程图

目前运用最广的歌词文件LRC文件内容如下。

[00:02.37] 即构KTV
[00:03.12]
[00:03.80] 作词:即构
[00:04.55] 作曲:即构
[00:05.18] 演唱:即构
[00:06.43] 出品:深圳即构科技

这种格式文件小,容易解析,歌词的精度控制到一行。

当观众、合唱、主唱都存在此歌词文件时,此时只需要知道当前音乐进度时间戳,就能达到歌词同步。

即构 SDK 支持将非媒体信息注入媒体流中。歌词信息和音视频信息是在同一个媒体通道传输的,这样可以保障歌词和音视频同步。歌词进度由主唱端发送,观众跟合唱端接收到时间戳后,再根据时间戳把关键歌词行高亮。达到歌词同步展示的效果。

具体实现流程图请参考:
在这里插入图片描述
内部约定主唱端与观众、合唱的歌词同步信息通信格式即可。

2、接收歌词时间戳数据

即构 SDK 拉流解码提取出媒体次要信息,会将其通过 setMediaSideCallback 设置的回调给应用开发者。合唱者、观众需要关注这个回调接口。

2.1 设置回调,接收媒体次要信息

ZEGO SDK 提供了相关接口,用于设置回调,接收媒体次要信息。

ZegoLiveRoomApi-Player.h/**
设置回调, 接收媒体次要信息@param onMediaSideCallback 回调函数指针, pszStreamID:流ID,标记当前回调的信息属于哪条流, buf:接收到的信息数据(具体内容参考官网对应文档中的格式说明), dataLen:buf 总长度
@discussion 开始拉流前调用。观众端在此 API 设置的回调中获取主播端发送的次要信息(要求主播端开启发送媒体次要信息开关,并调用 [ZegoLiveRoomApi (Publisher) -sendMediaSideInfo:dataLen:packet:] 发送次要信息)。当不需要接收信息时,需将 onMediaSideCallback 置空,避免内存泄漏
*/
- (void)setMediaSideCallback:(void(*)(const char *pszStreamID, const unsigned char* buf, int dataLen))onMediaSideCallback;

其中,当用户端收到媒体次要信息时,SDK 会调用之。

2.2 实现回调函数,处理媒体次要信息

媒体次要信息会作为 onReceivedMediaSideInfo 的入参传递进去,开发者需要在该函数内,根据业务要求,处理媒体次要信息。

主唱向观众、合唱端发送的数据格式为时间戳。KTV App 中处理媒体次要信息的示例代码如下:

ZegoLiveRoomApi-Player.hstatic void onReceivedMediaSideInfo(const char *pszStreamID, const unsigned char* buf, int dataLen) {if (dataLen == 0) {NSLog(@"onReceivedMediaSideInfo data is empty");return;}uint8_t *data = (uint8_t *)buf;int32_t offset = 4;// 偏移offset字节转换成intint32_t timeStamp = (data[offset] & 0xff) | ((data[offset+1] & 0xff) << 8) | ((data[offset+2] & 0xff) << 16) | ((data[offset+3] & 0xff) << 24);// 此处拿到时间戳数据 timeStamp// 拿到timeStamp后根据时间戳的值展示歌词信息
}[api setMediaSideCallback:onReceivedMediaSideInfo];

当拿到timeStamp后,解析歌词展示timeStamp时间段的歌词数据就OK了。

3、主唱端发送歌词信息

3.1 发送媒体次要信息

即构 SDK 提供了相关接口,用于发送媒体次要信息。在 KTV 场景中,歌词信息就作为媒体次要信息注入媒体流中,连同音视频数据一同发送到拉流端。观众、合唱者等拉流端接受到媒体次要信息后,得到应用进度时间戳。

如果要发送媒体次要信息,首先需要开启媒体次要信息开关。接口如下所示:

ZegoLiveRoomApi-Publisher.h/**发送媒体次要信息开关@param start 开启媒体次要信息传输,true 开启媒体次要信息传输, false 关闭媒体次要信息传输。start 为 true 时,onlyAudioPublish 开关才有效@param onlyAudioPublish 是否纯音频直播,true 纯音频直播,不传输视频数据,false 音视频直播,传输视频数据。默认为 false。如果本次只有音频直播,必须将 onlyAudioPublish 置为 true,此时将会由音频来驱动次要信息的传输,同时忽略视频流传输@discussion 初始化 SDK 后,开始推流前调用。*/
- (void)setMediaSideFlags:(bool)start onlyAudioPublish:(bool)onlyAudioPublish;

开启媒体次要信息开关后,才能使用以下接口进行发送媒体次要信息。

3.2 使用发送媒体次要信息接口,如何进行媒体次要信息发送

媒体次要信息会作为 inData 的参传入到SDK,开发者调用该函数,根据业务要求,传入媒体次要信息。

演示 Demo 中发送媒体次要信息的示例代码如下:

int timeStamp = 50; // 获取播放进度时间戳Byte mediaSideInfo[4] = {};
mediaSideInfo[0] = (Byte) (timeStamp & 0xFF);
mediaSideInfo[1] = (Byte) ((timeStamp >> 8) & 0xFF);
mediaSideInfo[2] = (Byte) ((timeStamp >> 16) & 0xFF);
mediaSideInfo[3] = (Byte) ((timeStamp >> 24) & 0xFF);[[ZegoManager api] sendMediaSideInfo:mediaSideInfo dataLen:4 packet:false];

timeStamp,是当前播放的进度时间戳,需要通过播放器SDK MediaPlayer播放器的函数,去获取该伴奏播放的进度时间戳。

关于媒体次要信息功能的详细说明,可参考文档:媒体次要信息

3.3 使用MediaPlayer播放器拿到当前播放的时间戳数据

知道怎么发送媒体次要信息了,接下来使用ZEGO SDK MediaPlayer提供的函数拿到时间戳

示例代码如下:

ZegoMediaPlayer* player = [[ZegoMediaPlayer alloc] initWithPlayerType:MediaPlayerTypeAux];
// 通过该函数获取到播放伴奏进度时间戳
long timeStamp = [player getCurrentDuration];

拿到timeStamp 后,主唱端需要做一个定时器循环去取这个时间戳使用SDK媒体次要信息接口发送出去。

每秒循环取一次,直到该首歌播放完毕, 让观众、合唱歌词展示达到同步状态。

这篇关于KTV歌房歌词同步实现流程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/299732

相关文章

使用Redis快速实现共享Session登录的详细步骤

《使用Redis快速实现共享Session登录的详细步骤》在Web开发中,Session通常用于存储用户的会话信息,允许用户在多个页面之间保持登录状态,Redis是一个开源的高性能键值数据库,广泛用于... 目录前言实现原理:步骤:使用Redis实现共享Session登录1. 引入Redis依赖2. 配置R

SpringBoot实现RSA+AES自动接口解密的实战指南

《SpringBoot实现RSA+AES自动接口解密的实战指南》在当今数据泄露频发的网络环境中,接口安全已成为开发者不可忽视的核心议题,RSA+AES混合加密方案因其安全性高、性能优越而被广泛采用,本... 目录一、项目依赖与环境准备1.1 Maven依赖配置1.2 密钥生成与配置二、加密工具类实现2.1

在Java中实现线程之间的数据共享的几种方式总结

《在Java中实现线程之间的数据共享的几种方式总结》在Java中实现线程间数据共享是并发编程的核心需求,但需要谨慎处理同步问题以避免竞态条件,本文通过代码示例给大家介绍了几种主要实现方式及其最佳实践,... 目录1. 共享变量与同步机制2. 轻量级通信机制3. 线程安全容器4. 线程局部变量(ThreadL

python使用Akshare与Streamlit实现股票估值分析教程(图文代码)

《python使用Akshare与Streamlit实现股票估值分析教程(图文代码)》入职测试中的一道题,要求:从Akshare下载某一个股票近十年的财务报表包括,资产负债表,利润表,现金流量表,保存... 目录一、前言二、核心知识点梳理1、Akshare数据获取2、Pandas数据处理3、Matplotl

Linux线程同步/互斥过程详解

《Linux线程同步/互斥过程详解》文章讲解多线程并发访问导致竞态条件,需通过互斥锁、原子操作和条件变量实现线程安全与同步,分析死锁条件及避免方法,并介绍RAII封装技术提升资源管理效率... 目录01. 资源共享问题1.1 多线程并发访问1.2 临界区与临界资源1.3 锁的引入02. 多线程案例2.1 为

分布式锁在Spring Boot应用中的实现过程

《分布式锁在SpringBoot应用中的实现过程》文章介绍在SpringBoot中通过自定义Lock注解、LockAspect切面和RedisLockUtils工具类实现分布式锁,确保多实例并发操作... 目录Lock注解LockASPect切面RedisLockUtils工具类总结在现代微服务架构中,分布

Java使用Thumbnailator库实现图片处理与压缩功能

《Java使用Thumbnailator库实现图片处理与压缩功能》Thumbnailator是高性能Java图像处理库,支持缩放、旋转、水印添加、裁剪及格式转换,提供易用API和性能优化,适合Web应... 目录1. 图片处理库Thumbnailator介绍2. 基本和指定大小图片缩放功能2.1 图片缩放的

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我

Redis客户端连接机制的实现方案

《Redis客户端连接机制的实现方案》本文主要介绍了Redis客户端连接机制的实现方案,包括事件驱动模型、非阻塞I/O处理、连接池应用及配置优化,具有一定的参考价值,感兴趣的可以了解一下... 目录1. Redis连接模型概述2. 连接建立过程详解2.1 连php接初始化流程2.2 关键配置参数3. 最大连

Python实现网格交易策略的过程

《Python实现网格交易策略的过程》本文讲解Python网格交易策略,利用ccxt获取加密货币数据及backtrader回测,通过设定网格节点,低买高卖获利,适合震荡行情,下面跟我一起看看我们的第一... 网格交易是一种经典的量化交易策略,其核心思想是在价格上下预设多个“网格”,当价格触发特定网格时执行买