鸿蒙---使用AudioCapturer录制音频

功能介绍:​​​​​​       

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那里查看文档

了解OpenHarmony开源项目

     

  • 21
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值