音乐,是生活中不可缺少的一部分。我们依靠耳朵接收声音,感受音乐节奏的变化,体会其中的情感变化。除了听觉外,我们借助频谱,可以显示音乐的起伏变化,让音乐节奏不仅听得见还能看得见。 频谱是频率谱密度的简称,是频率的分布曲线。声音频谱一般分为高音频段、中高音频段、中低音频段和低音频段。高音频段的声音幅度影响音色的表现力;中高音频段是人耳听觉比较灵敏的频段,它影响音色的明亮度、清晰度、透明度;中低音频段是人声和主要乐器的主音区基音的频段。由此可见,一首动听的曲子离不开各个频段声音的协调和配合。
随着语音社交应用的兴起,直播、语聊房、K歌房等玩法花样频出,跟着音乐的节奏一起跳动的频谱增加了产品的趣味性和互动性。让用户在唱歌、连麦时不仅可以看到歌词、进度条,还能通过频谱的变化调整自己的歌声,让声音的表现更加的丰富。
针对客户对频谱的需求,Zego SDK 新增了展现音频功率谱的能力。即把时域的音频数字信号经 Zego SDK 内部处理,转换成频域的音频数字信号。开发者无需具备专业的数字信号领域相关知识,即可使用 Zego SDK 从采集到的音频数据或所拉的流里音频的数据里得到音频的功率谱数据。业务端再把数据用自己想要的UI展示出来,就可以做出各种炫酷的频谱动效。
zego 音频频谱功能体验 Demo 源码下载地址:
https://github.com/zegodev/liveroom-topics-android
音频功率谱与声浪模块源码请查看 /src/LiveRoomPlayground/frequencySpectrum 目录下的源文件,该模块展示了音频功率谱与声浪相关接口的使用方法。
功能使用步骤如下:
1、初始化SDK
根据获取的 AppID 与 AppSign 在项目 Applicaiton 类 onCreate() 中添加如下代码。由于后续逻辑需要用到 ZegoLiveRoom 对象的实例, 所以需要将该实例做为项目 Application 类的成员变量或者存储到某个单实例中。
注意:在 java 中 appSign 需要强制成 byte 原因:在 java 中,整数默认是 int 类型, 其次初始化SDK必须要先设置SDKContext
示例代码如下:
public class ZegoApplication extends Application { private ZegoLiveRoom g_ZegoApi; public static ZegoApplication zegoApplication; static final public long appID = 123456789L; // 需要强转成 byte 类型,原因: 在java中,整数默认是 int 类型 static final public long appSign = new byte[]{ (byte) 0x91, (byte) 0x93, (byte) 0xcc, (byte) 0x66 }; @Override public void onCreate() { super.onCreate(); zegoApplication = this; ZegoLiveRoom.setSDKContext(new ZegoLiveRoom.SDKContextEx() {...}); ZegoLiveRoom.setTestEnv(true); // 创建 ZegoLiveRoom 实例, 只创建一个实例。后续逻辑直接引用g_ZegoApi使用SDK功能 g_ZegoApi = new ZegoLiveRoom(); // 初始化sdk, appID与appSign 开发者如果还没有申请, 可通过 <a>https://console.zego.im/acount/login</a> 申请 AppID // AppID 和 AppSign 由 Zego 分配给各 App。其中,为了安全考虑,建议将 AppSign 存储在 App 的业务后台,需要使用时从后台获取 // 如果不需要再继续使用 SDK 可调用 g_ZegoApi.unInitSDK() 释放SDK g_ZegoApi.initSDK(appID, appSign, new IZegoInitSDKCompletionCallback() { @Override public void onInitSDK(int errorCode) { // errorCode 非0 代表初始化sdk失败 } }); } }2、使用音频功率谱关键步骤
• 导入音频功率谱的类
import com.zego.zegoavkit2.frequencyspectrum.ZegoFrequencySpectrumMonitor; import com.zego.zegoavkit2.frequencyspectrum.IZegoFrequencySpectrumCallback; import com.zego.zegoavkit2.frequencyspectrum.ZegoFrequencySpectrumInfo;• 获取 ZegoFrequencySpectrumMonitor 的单例对象
// 该方法为静态单例,可以直接全局获取 ZegoFrequencySpectrumMonitor frequencySpectrumMonitor = ZegoFrequencySpectrumMonitor.getInstance();• 设置监控/回调周期
// 设置音频功率谱监听的周期,即回调抛出数据的频率,单位为ms,最小值为10ms,不设默认为500ms; frequencySpectrumMonitor.setCycle(millisecond);注意:修改监控周期需要先停止监控器再开启监控器
• 监听对应回调接口抛出的数据并处理
/ 设置频谱相关回调,由于SDK内部会抛出己方推流和拉到的流的音频频谱的数据,所以需要设置相关回调来监听抛出的数据并处理 ZegoFrequencySpectrumMonitor.getInstance().setCallback(new IZegoFrequencySpectrumCallback() { /** * 拉流频率功率谱数据回调,停止拉流之后不会再抛出 * * @param zegoFrequencySpectrumInfos */ @Override public void onFrequencySpectrumUpdate(ZegoFrequencySpectrumInfo[] zegoFrequencySpectrumInfos) { // 这里会抛出拉流的音频功率谱的数据,业务方可以根据自己的场景或需求进行展现,也可以参考Demo里的处理方式 ... } /** * 本地音量采集回调,由于是全局有效,即使停止推流还会回调 * * @param zegoFrequencySpectrumInfo */ @Override public void onCaptureFrequencySpectrumUpdate(ZegoFrequencySpectrumInfo zegoFrequencySpectrumInfo) { // 这里会抛出推流的音频功率谱的数据,业务方可以根据自己的场景或需求进行展现,也可以参考Demo里的处理方式 ... } });• 启动音频功率谱的监听器,启动引擎(推流或拉流后)之后上述步骤的回调会开始触发
ZegoFrequencySpectrumMonitor.getInstance().start();• 关闭音频功率谱的监听器,相关回调不再触发
ZegoFrequencySpectrumMonitor.getInstance().stop();想了解SDK的更多功能请至即构官网开发者中心:https://doc.zego.im/