HarmonyOS NEXT 鸿蒙中使用 AvRecorder API版本11+ 录音的振幅组件
·
应用场景
在上一篇文章中,我们完成了一个简单的录音功能,但是我们在录音的过程中,并不能看见看到自己说话的音量大小,所以要完成一个实时显示音量大小的组件。
上一篇文章:
实现效果

核心API 版本API 11+
通过 getAudioCapturerMaxAmplitude 观察音频区间
异步方式获取当前音频最大振幅。通过注册回调函数获取返回值。
在prepare()成功触发后,才能调用此方法。
首先通过打印的方式实时打印音量大小
在开始录制的方法中,使用延时器,每隔100毫秒打印一次声音的音量大小。
// 记录声音的振幅
@State maxAmplitude: number = 0
// 定时器id
timerId = 0
// 开始录制方法
async startRecord() {
...... 省略之前的录制代码,最后附上完整版
// 监听声音的振幅
this.timerId = setInterval(async () => {
// 获取 振幅
const res = await avRecorder.getAudioCapturerMaxAmplitude()
// 记录用于 一会传递给视图的振幅
this.maxAmplitude = res
// 打印
console.log('振幅:' + res)
}, 100)
}
开始录制后,在日志中能实时打印出音量即可。经过观察,很大声说话的振幅在30000左右。

封装振幅组件
逻辑:
- 父组件传入振幅maxAmplitude,子组件通过@Prop接收
- 子组件@Watch 监听 maxAmplitude 的实时变化
- 根据刚才打印的声音振幅,发现 500 以下基本没声音,30000基本封顶了
- 所以我们就定义 500 以下不让显示,30000就达到最大音量了
- 500到30000中间的平均分为 一百份,决定条状结构的高度
- 使用 animateTo 使得条状的高度变化时有动画效果而不是一卡一卡的
- 最后在 一个row容器中循环生成30个条状结构。
- 那么可能有疑问?我30 个条传入同一个高度变量,怎么做到波形效果呢?
- 这里就用 乘以 随机数的办法,让每个条的高度不一样。
@Component
export struct AudioBoComp {
@Prop @Watch('onChange') maxAmplitude: number
@State per: number = 0
// 监听 maxAmplitude 变化
onChange() {
// 为了减少动画的卡顿,使用 animateTo 来做动画
animateTo({ duration: 100 }, () => {
// 大于 30000 基本就是最大声音了
if (this.maxAmplitude >= 30000) {
this.per = 1
// 小于 500 基本就是静音了
} else if (this.maxAmplitude <= 500) {
this.per = 0
// 中间按比例算
} else {
this.per = this.maxAmplitude / 30000
}
})
}
build() {
Row({ space: 3 }) {
// 这里虽然30个竖条传入同一个变量,但是乘以随机数,但是会生成30个不同的值,就模拟了音浪
ForEach(Array.from({ length: 30 }), () => {
Column()
.height(this.per * 100 * Math.random())
.layoutWeight(1)
.backgroundColor(Color.Blue)
})
}
.width(200)
.height(100)
}
}
在父组件中使用并传入maxAmplitude
Column({ space: 10 }) {
// 振幅组件
AudioBoComp({ maxAmplitude: this.maxAmplitude })
Button('开始录制')
.onClick(() => {
this.startRecord()
promptAction.showToast({ message: '开始录制' })
})
Button('停止录制')
.onClick(() => {
this.stopRecord()
promptAction.showToast({ message: '停止录制' })
})
}
点击开始录制就会出现振幅,但是这时候还有问题,当我们点击停止录制后,maxAmplitude并不会重置为0,所以振幅组件会停止在最后一个振幅

这时候就要在停止录制时手动将maxAmplitude归零。
this.maxAmplitude = 0 加在 stopRecord() 方法最后即可。
更多推荐



所有评论(0)