HarmonyOS鸿蒙Next中播放MP3怎么获取振幅?
HarmonyOS鸿蒙Next中播放MP3怎么获取振幅? 录制的时候可以使用。recorder.getAudioCapturerMaxAmplitude() 。那我播放的时候怎么获取?
播放(Playback)时获取音频最大振幅(电平值)需要使用 AVPlayer 的 on('amplitudeUpdate') 事件订阅机制,而不是像录制时那样调用 getAudioCapturerMaxAmplitude() 方法。
| 场景 | 组件 | 方法/事件 | 说明 |
|---|---|---|---|
| 录制 (Recording) | AVRecorder |
getAudioCapturerMaxAmplitude() |
主动调用获取,返回的是上一次调用到当前时间区间内的音频最大振幅 |
| 播放 (Playback) | AVPlayer |
on('amplitudeUpdate') |
订阅事件,音频播放时系统定时自动上报当前音频的最大电平值 |
播放时获取音频最大振幅的详细步骤
步骤1:创建AVPlayer并准备资源
import { media } from '@kit.MediaKit';
// 创建AVPlayer实例
let avPlayer: media.AVPlayer = await media.createAVPlayer();
// 设置资源并准备
avPlayer.url = '您的音频/视频文件路径或URL';
await avPlayer.prepare();
步骤2:订阅 amplitudeUpdate 事件
// 订阅音频最大电平值更新事件
avPlayer.on('amplitudeUpdate', (value: Array<number>) => {
// value是一个数字数组,包含左右声道的最大电平值
console.info(`音频最大电平值: ${value}`);
// 例如: [0.75, 0.68] 表示左声道0.75,右声道0.68
// 取值范围通常在[0, 1]之间
});
步骤3:开始播放
// 开始播放
avPlayer.play();
// 事件会在音频资源播放时定时触发
步骤4:取消订阅(不需要时)
// 取消订阅特定回调
avPlayer.off('amplitudeUpdate', callbackFunction);
// 或取消所有amplitudeUpdate事件的订阅
avPlayer.off('amplitudeUpdate');
关键参数说明
- 事件类型:
'amplitudeUpdate'(API version 13+ 支持) - 回调参数:
Array<number>- 数组包含左右声道的最大电平值
- 例如
[左声道值, 右声道值] - 取值范围通常为
[0, 1],其中0表示无声,1表示最大电平
- 触发时机: 音频资源播放时系统定时自动上报
注意事项!
- API版本要求:
on('amplitudeUpdate')需要 API version 13+ - 系统能力: 需要
SystemCapability.Multimedia.Media.AVPlayer能力 - 播放状态: 只有在音频实际播放时才会触发该事件
- 与录制的区别:
- 录制: 主动拉取 (
getAudioCapturerMaxAmplitude()) - 播放: 被动接收 (
on('amplitudeUpdate'))
- 录制: 主动拉取 (
- 数据类型: 播放返回的是电平值数组,而录制返回的是单个振幅数值
更多关于HarmonyOS鸿蒙Next中播放MP3怎么获取振幅?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
import { BusinessError } from '@kit.BasicServicesKit';
let rendererInfo: audio.AudioRendererInfo = {
usage: audio.StreamUsage.STREAM_USAGE_MUSIC, // 音频流使用类型:音乐。根据业务场景配置,参考StreamUsage。
rendererFlags: 0 // 音频渲染器标志。
};
audio.getAudioManager().getRoutingManager().getPreferOutputDeviceForRendererInfo(rendererInfo).then((data) => {
audioVolumeGroupManager.getMaxAmplitudeForOutputDevice(data[0]).then((value) => {
console.info(`max amplitude is: ${value}`);
}).catch((err: BusinessError) => {
console.error(`getMaxAmplitudeForOutputDevice error. Code: ${err.code}, message: ${err.message}`);
})
}).catch((err: BusinessError) => {
console.error(`getPreferOutputDeviceForRendererInfo error. Code: ${err.code}, message: ${err.message}`);
})
参考地址
如果你使用 AVPlayer 进行播放的话,可以试试,监听 ‘amplitudeUpdate’
on(type: ‘amplitudeUpdate’, callback: Callback<Array<number>>): void
订阅音频最大电平值,音频资源播放时定时上报。
async function test(){
let avPlayer = await media.createAVPlayer();
avPlayer.on('amplitudeUpdate', (value: Array<number>) => {
console.info(`amplitudeUpdate called,and amplitudeUpdate = ${value}`);
});
}
在HarmonyOS Next中,获取MP3振幅可通过AudioRenderer实现。使用getAudioTime获取时间戳,结合on('audioInterrupt')监听音频中断事件,通过AudioRenderer的getBufferSize和on('dataReceived')回调获取原始音频数据。计算振幅需处理PCM数据,取绝对值并计算均方根。示例代码涉及AudioRenderer的创建、配置及数据回调处理。
在HarmonyOS Next中,播放音频时获取实时振幅数据,需要使用AudioRenderer的getAudioTime和getBufferSize等接口结合音频数据处理来实现,因为系统没有直接提供类似getAudioCapturerMaxAmplitude的播放振幅查询方法。
核心思路是:在播放音频前,先解码或读取音频文件(如MP3)的PCM数据,然后对这些原始音频数据进行分析计算,得到振幅信息。播放时,可以将计算好的振幅数据与播放进度进行同步。
简要步骤如下:
-
准备音频数据:使用
AudioDecoder等组件将MP3文件解码为PCM格式的原始音频数据(通常为16位有符号整数)。你需要读取这些数据到内存中(例如ArrayBuffer)。 -
计算振幅:对解码后的PCM数据块(例如每1024个采样点为一个窗口)进行计算。振幅通常指该窗口内采样点绝对值的最大值,或计算均方根值(RMS)来反映平均能量。
// 示例:计算一个数据块(Int16Array)的最大振幅(绝对值) function calculateMaxAmplitude(pcmData, startIndex, windowSize) { let max = 0; for (let i = 0; i < windowSize && startIndex + i < pcmData.length; i++) { const sample = Math.abs(pcmData[startIndex + i]); if (sample > max) { max = sample; } } return max; // 值范围通常为0~32767(对于16位有符号PCM) } -
播放与同步:使用
AudioRenderer播放原始PCM数据。同时,你需要根据AudioRenderer的播放进度(可通过getAudioTime获取已渲染的帧数或时间),映射到对应的音频数据块,并取出或实时计算该数据块的振幅值。
注意:这个过程需要你在应用层管理音频数据和播放状态,实现数据解析、振幅计算和播放进度同步。如果音频文件较大,需注意内存和性能管理。对于简单的波形显示,可以预先计算并存储关键点的振幅值,播放时根据进度进行插值查询。

