功能介绍:
AudioCapturer是一种音频采集器,用来录制PCM音频数据。因为AudioCapturer允许开发者直接直接操作音频数据,使开发者能够自由地控制包括采样率、位深度、声道数等关键参数。此外AudioCapturer提供了丰富的API和回调机制。这种灵活性使得开发者可以根据应用场景的不同,对音频数据进行各种复杂的操作。
开发指导:
使用AudioCapturer录制音频涉及到AudioCapturer实例的创建、音频采集参数的配置、采集的开始与停止、资源的释放等。本开发指导将以一次录制音频数据的过程为例,向开发者讲解如何使用AudioCapturer进行音频录制。
下图展示了AudioCapturer的状态变化,在创建实例后,调用对应的方法可以进入指定的状态实现对应的行为。需要注意的是在确定的状态执行不合适的方法可能导致AudioCapturer发生错误,建议开发者在调用状态转换的方法前进行状态检查,避免程序运行产生预期以外的结果。
图1 AudioCapturer状态变化示意图
使用on('stateChange')方法可以监听AudioCapturer的状态变化,每个状态对应值与说明见
AudioState(如图2所示)。
开发步骤:
1.录音需要 ohos.permission.MICROPHONE 权限
// 申请权限
permissionManager.requestPermissions("ohos.permission.MICROPHONE")
2.配置音频采集参数并创建 AudioCapturer 实例
@Entry
@Component
struct RouterPage {
@State message: string = 'Hello HarmonyOS';build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
}
.width('100%')
}
.height('100%')
}
}
3.调用on('readData')方法,订阅监听音频数据读入回调。
import { BusinessError } from '@ohos.base';
import fs from '@ohos.file.fs';let bufferSize: number = 0;
// 创建音频文件
let path = getContext().cacheDir;
let filePath = path + Date.now()+'.wav';
//根据 filePath 打开文件,可读可写模式,如果文件不存在自动创建
let file: fs.File = fs.openSync(filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);// 调用on('readData')方法
audioCapturer.on('readData', (buffer) => {
// 把采集的音频信息写入到打开的文件中
fileIo.writeSync(file.fd, buffer, { offset: bufferSize, length: buffer.byteLength })
// 累加偏移值
bufferSize += buffer.byteLength
})
4.调用start()方法进入running状态,开始录制音频。
// 开始录音采集
audioCapturer.start()
5.调用stop()方法停止录制。
// 停止采集
audioCapturer.stop()
6. 调用release()方法销毁实例,释放资源。
// 释放资源
audioCapturer.release()
完整示例
下面展示了使用AudioCapturer录制音频的完整示例代码。
import { audio } from '@kit.AudioKit'
import fs from '@ohos.file.fs';
import { Logger } from '../common/utils/Logger';export class AudioCaptureServices {
static currentCapturer: audio.AudioCapturer = Object()
static isrunning: boolean = false // 用来标记当前是否录音//初始化
static async init() {
try {
// 创建录制音频对象
const caputure = await audio.createAudioCapturer({
streamInfo: {
samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_16000, // 采样率 16K
channels: audio.AudioChannel.CHANNEL_1, // 声道数 1
sampleFormat: audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE, //音频采样深度
encodingType: audio.AudioEncodingType.ENCODING_TYPE_RAW //音频编码格式:PCM
},
capturerInfo: {
source: audio.SourceType.SOURCE_TYPE_VOICE_COMMUNICATION, // 语音通话场景的音频源
capturerFlags: 0
}
})// 将音频录制对象赋值给类的全局静态变量
AudioCaptureServices.currentCapturer = caputure
} catch (err) {
Logger.error('初始化录音对象错误:', JSON.stringify(err))
}}
//开始录音
static async start() {
try {
// 创建音频文件
let path = getContext().cacheDir;
let filePath = path + Date.now()+'.wav';
//根据 filePath 打开文件,可读可写模式,如果文件不存在自动创建
let file: fs.File = fs.openSync(filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
// 开始录音
await AudioCaptureServices.currentCapturer.start()// 将录音标记置为true
AudioCaptureServices.isrunning = true// 收集录音数据写入到具体的文件
let bufferSize = AudioCaptureServices.currentCapturer.getBufferSizeSync()
let offSet = 0
while (AudioCaptureServices.isrunning) {// 从录音对象中读取bufferSize长度的数据
let bufferArr = await AudioCaptureServices.currentCapturer.read(bufferSize, true)
// bufferArr数据写入到wav文件中去
fs.writeSync(file.fd, bufferArr, {
offset: offSet * bufferSize, // 每次写块数据的时候是要追加到文件的后面
length: bufferSize
})offSet++
}} catch (err) {
Logger.error('录音异常:', JSON.stringify(err))
}}
//停止录音
static async stop() {
try {
AudioCaptureServices.isrunning = false // 停止写数据
setTimeout(async () => {
await AudioCaptureServices.currentCapturer.stop()
},100)} catch (err) {
Logger.error('停止录音异常:', JSON.stringify(err))
AudioCaptureServices.isrunning = false // 停止写数据
}
}
}
总结
AudioCapturer用于音频输入的的ArkTS/JS API,仅支持PCM格式,需要应用持续读取音频数据进行工作。应用可以在音频输出后添加数据处理,要求开发者具备音频处理的基础知识,适用于更专业、更多样化的媒体录制应用开发。
以上便是我自己的理解和使用了,参考了华为HarmonyOS Next的开发文档,如果有不对的地方欢迎指正。
如果了解更多harnonyOS相关,可以去OpenHarmony那里查看文档