HarmonyOS 鸿蒙Next中AudioCapturer录音采集readData事件回调频率问题
HarmonyOS 鸿蒙Next中AudioCapturer录音采集readData事件回调频率问题
最近在做录音跟播放,两个功能都遇到问题,首先是录音,先贴代码:
private initAudio(){
let audioStreamInfo: audio.AudioStreamInfo = {
samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_8000, // 采样率。
channels: audio.AudioChannel.CHANNEL_1, // 通道。
sampleFormat: audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE, // 采样格式。
encodingType: audio.AudioEncodingType.ENCODING_TYPE_RAW // 编码格式。
};
let audioCapturerInfo: audio.AudioCapturerInfo = {
source: audio.SourceType.SOURCE_TYPE_MIC, // 音源类型:Mic音频源。根据业务场景配置,参考SourceType。
capturerFlags: 0 // 音频采集器标志。
};
let audioCapturerOptions: audio.AudioCapturerOptions = {
streamInfo: audioStreamInfo,
capturerInfo: audioCapturerInfo
};
audio.createAudioCapturer(audioCapturerOptions, (err, data) => {
if (err) {
console.error(`AudioCapturer Created : Error: ${err}`);
} else {
console.info('AudioCapturer Created : Success : SUCCESS');
this.audioCapturer = data;
AudioManager.instance.initCapturerEvent();
}
});
}
上面是初始化代码,我选择8K 16bit 单声道采样,然后在下面的方法获取采集的回调
private initCapturerEvent(){
if (!this.audioCapturer) return;
this.audioCapturer.on("readData", (buffer:ArrayBuffer)=>{
console.log(buffer.byteLength.toString());
if (buffer.byteLength > 0) {
//
}
})
}
在readData 事件中,获取到录音数据回调,每一帧的长度是320byte,这个是对的,但是回调的频率不对,正常一帧是20ms,也就是说20ms要回调一次才能保证录音的连贯,但是实际是1秒回调一次,我不知道我哪里做错了,请大家帮忙看看,谢谢🙏
更多关于HarmonyOS 鸿蒙Next中AudioCapturer录音采集readData事件回调频率问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html
伙伴您好,在真机上验证没有问题,建议切换到真机验证。或者重启模拟器试下。
更多关于HarmonyOS 鸿蒙Next中AudioCapturer录音采集readData事件回调频率问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
20ms的数据量计算应为:8000Hz * 16bit * 1通道 * 0.02秒 = 320字节,而实际回调间隔1秒说明系统分配的缓冲区远大于该值
现在我从回调接口拿到的数据只有320字节,我试试你提供的办法看看,非常感谢!
AudioCapturer
的readData
回调频率由音频流参数和系统调度机制共同决定。看了下你的代码因为readData
回调频率与bufferSize
参数直接相关,如果没有显式设置缓冲区大小,系统可能会基于samplingRate
和sampleFormat
自动计算默认值。当bufferSize
设置过大时,会导致回调间隔变长。通过AudioCapturerOptions.streamInfo
补充bufferSize
参数:
let audioStreamInfo: audio.AudioStreamInfo = {
samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_8000,
channels: audio.AudioChannel.CHANNEL_1,
sampleFormat: audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE,
encodingType: audio.AudioEncodingType.ENCODING_TYPE_RAW,
bufferSize: 320 // 根据20ms数据量设置
};
在订阅readData
回调后,必须调用start()
方法激活音频采集:
private initCapturerEvent() {
if (!this.audioCapturer) return;
this.audioCapturer.on("readData", (buffer: ArrayBuffer) => {
console.log(`Buffer size: ${buffer.byteLength}`);
// 处理音频数据
});
// 启动音频采集
this.audioCapturer.start((err: BusinessError) => {
if (err) {
console.error(`Capturer start failed: ${err.message}`);
}
});
}
不行,audio.AudioStreamInfo
没有bufferSize
的构造方法,无法编译。
请问你用的是哪个版本的API,如果可以,我也去试试看,
我是API20,
通过 on(‘readData’) 订阅音频数据回调时,系统会根据实际硬件性能和数据传输效率动态调整每次回调的数据块大小(即 ArrayBuffer 的 byteLength)。这个数据块大小一般与系统计算的缓冲区大小一致。
若需限制单次处理的数据量,可以通过以下方式间接实现:
在 readData 回调中,将接收到的 ArrayBuffer 按需分块处理,这个官方文档有示例代码:
let bufferSize: number = 0;
let readDataCallback = (buffer: ArrayBuffer) => {
let options: Options = { offset: bufferSize, length: buffer.byteLength };
fs.writeSync(file.fd, buffer, options);
bufferSize += buffer.byteLength;
};
audioCapturer.on('readData', readDataCallback);
补充一下,我现在的版本是API18,5.1.0。另外用的是模拟器测试,非真机
在鸿蒙Next中,AudioCapturer
的readData
事件回调频率由音频采样率、帧大小和缓冲区配置决定。回调触发条件为缓冲区数据填满时,计算公式为:
回调频率=采样率/(缓冲区大小/每帧字节数)
若采样率为48kHz,16位单声道,缓冲区设置为4800字节,则回调频率为100Hz(10ms一次)。可通过setBufferSizeInBytes()
调整缓冲区大小来改变回调间隔。系统默认采用低延迟策略,实际频率可能因硬件性能微调。
根据您提供的代码和描述,问题可能出在AudioCapturer的缓冲区设置上。在HarmonyOS Next中,AudioCapturer的readData回调频率是由缓冲区大小和采样参数共同决定的。
对于8K采样率、16bit、单声道的配置,20ms的数据量确实是320字节(800020.02=320)。但默认情况下系统可能使用了较大的缓冲区,导致回调间隔变长。
建议您尝试以下修改:
- 在AudioCapturerOptions中添加bufferSizeInBytes参数:
let audioCapturerOptions: audio.AudioCapturerOptions = {
streamInfo: audioStreamInfo,
capturerInfo: audioCapturerInfo,
bufferSizeInBytes: 320 // 设置为20ms的数据量
};
- 确保在开始采集前正确设置了回调:
this.audioCapturer.on("readData", callback);
this.audioCapturer.start();
如果问题仍然存在,可能需要检查系统音频服务的配置或设备硬件支持情况。