手把手教你使用AVRecorder完成鸿蒙录音

前言

录音功能是手机常见的功能,在HarmonyOS中应该如何实现这一功能呢?

获取权限

向系统权限

由于鸿蒙操作系统的安全性的问题首先需要在module.json5中配置允许使用麦克风功能。

没啥好说的直接上代码

js 复制代码
"requestPermissions": [
      {
        "name":"ohos.permission.MICROPHONE",
        "usedScene": {},
        "reason":"$string:EntryAbility_desc"
      }
    ],

向用户请求

首次请求

由于上一步操作只是向系统请求麦克风权限,下一步还需要向用户也就是手机哦持有者申请权限。

核心API 使用到了abilityAccessCtrl

js 复制代码
import { abilityAccessCtrl } from '@kit.AbilityKit'
@Entry
@Component
struct myTest {
  async aboutToAppear() {
    // 向用户发起麦克风的授权提示
    let mgr = abilityAccessCtrl.createAtManager()
    //  利用mgr对象向用户发起麦克风的授权
    let result = await mgr.requestPermissionsFromUser(getContext(), ['ohos.permission.MICROPHONE'])
  }

  build() {
    Column() {

    }
    .height('100%')
    .width('100%')
    .backgroundColor(Color.Pink)

  }
}

res打印能发现当选择了允许和不允许时authResults分别对应0和-1,dialogShownResults分别对应true和false

二次请求

当用户选择不允许时,可以通过直接跳转want来管理开启麦克风的权限

主要使用Want API 来完成,Want是对象间信息传递的载体, 可以用于应用组件间的信息传递。

首先配置Want的参数

js 复制代码
const want: Want = {
  bundleName: 'com.huawei.hmos.settings',
  abilityName: 'com.huawei.hmos.settings.MainAbility',
  uri: 'application_info_entry',
  parameters: {
    // 可以在AppScope下的app.json5中对应的bundleName查看
    pushParams: '改成自己的包名'
  }
}

利用Want配合第一次请求的参数判断完成直接跳转到系统权限的设置界面

js 复制代码
let ctx = getContext() as common.UIAbilityContext
      ctx.startAbility(want)

获取录音文件

准备文件

我们需要提前准备好一个文件用来存放录音的信息

使用了fs.openSync来创建和打开文件, getContext().filesDir 用来获取当前上下文的路径,使用时间戳获得唯一标识符作为文件名字。fd代表着文件的操作符,后续对文件的操作只需调用fd即可。

js 复制代码
const filePath = getContext().filesDir + '/' + Date.now() + '.m4a'
const file = fs.openSync(filePath, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE)
const fd = file.fd 

配置录音对象

配置一些录音的基本信息,从官方文档参考即可

js 复制代码
const config: media.AVRecorderConfig = {
  audioSourceType: media.AudioSourceType.AUDIO_SOURCE_TYPE_MIC,  //音频采集源为麦克风
  profile: {
    audioBitrate: 100000, // 音频比特率
    audioChannels: 1, // 音频声道数
    audioCodec: media.CodecMimeType.AUDIO_AAC, // 音频编码格式,当前只支持aac
    audioSampleRate: 48000, // 音频采样率
    fileFormat: media.ContainerFormatType.CFT_MPEG_4A, // 封装格式,当前只支持m4a
  },
  url: `fd://${file.fd}`  //第一步中的文件地址
}

开始录音与结束录音

首先实例化AVRecorder,调用AVRecorder上自带的方法即可。使用完毕记得销毁对象。

js 复制代码
// 创建录音对象
const avRecorder = await media.createAVRecorder()
// 设置录制参数
await avRecorder.prepare(config)  
// 开启录音
await avRecorder.start() 
// 停止录制
await avRecorder.stop()
// 销毁实例,退出录制。
await avRecorder.release()

播放录音

使用了avPlayer创建的实力,调用方法对stateChange进行监听,当其处于prepare状态时,使用.play进行播放。打开之前存好的录音的文件地址,进行播放即可。

js 复制代码
          const file = fs.openSync(this.filePath, fs.OpenMode.READ_ONLY) //以只读方式打开录音文件
          // 创建播放对象 AVPlayer
          const avPlayer = await media.createAVPlayer()
          // 注册stateChange监听
          avPlayer.on('stateChange', (state) => {
            if (state == 'initialized') {
              avPlayer.prepare()
            }
            if (state == 'prepared') {
              avPlayer.play()
            }
          })
          // 赋值播放源
          avPlayer.url = `fd://${file.fd}`

完整代码参考

js 复制代码
import { abilityAccessCtrl, common, Want } from '@kit.AbilityKit'
import fs from '@ohos.file.fs';
import { media } from '@kit.MediaKit';

@Entry
@Component
struct myTest {
  @StorageProp('topHeight') topHeight: number = 0
  avRecorder: media.AVRecorder = Object()  // 初始化空对象

  async aboutToAppear() {
    let mgr = abilityAccessCtrl.createAtManager()
    let result = await mgr.requestPermissionsFromUser(getContext(), ['ohos.permission.MICROPHONE'])
    if (result.authResults[0] == -1) {

      const want: Want = {
        bundleName: 'com.huawei.hmos.settings',
        abilityName: 'com.huawei.hmos.settings.MainAbility', 
        uri: 'application_info_entry',
        parameters: {

          pushParams: 'com.itcast.interview_bjhm4App' 
        }
      }


      let ctx = getContext() as common.UIAbilityContext
      ctx.startAbility(want)
    }
  }

  build() {
    Column() {

      Button('开始录制').onClick(async () => {

        let filePath = getContext().filesDir + '/' + Date.now() + '.m4a'

        let file = fs.openSync(filePath, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE)

        const config: media.AVRecorderConfig = {
          audioSourceType: media.AudioSourceType.AUDIO_SOURCE_TYPE_MIC, //音频采集源为麦克风
          profile: {
            audioBitrate: 100000, // 音频比特率
            audioChannels: 1, // 音频声道数
            audioCodec: media.CodecMimeType.AUDIO_AAC, // 音频编码格式,当前只支持aac
            audioSampleRate: 48000, // 音频采样率
            fileFormat: media.ContainerFormatType.CFT_MPEG_4A, 
          },
          url: `fd://${file.fd}` 
        }

        const avRecorder = await media.createAVRecorder()
        this.avRecorder = avRecorder

        await avRecorder.prepare(config)
        await avRecorder.start()
        AlertDialog.show({ message: JSON.stringify('录音开始') })
      })

      Button('停止录制').onClick(async () => {
        await this.avRecorder.stop() //停止录音
        await this.avRecorder.release() //销毁和释放录音对象
      })
      Button('播放').onClick(async () => {
        const avPlayer = await media.createAVPlayer()
        avPlayer.on('stateChange', (state) => {
          if (state == 'initialized') {
            avPlayer.prepare()
          }
          if (state == 'prepared') {
            avPlayer.play()
          }
        })
        //   3. 设置播放源 fd://句柄
        const file = fs.openSync(item, fs.OpenMode.READ_ONLY)
        avPlayer.url = `fd://${file.fd}`
      })

    }
    .height('100%')
    .width('100%')
    .padding({ top: this.topHeight })

  }
}
相关推荐
宁酱醇6 分钟前
CSS基础_@拉钩教育【笔记】
前端·css
建群新人小猿7 分钟前
CRMEB-PRO系统定时任务扩展开发指南
android·java·开发语言·前端
牧天白衣.8 分钟前
vue 和 html 的区别
前端
知识分享小能手16 分钟前
JavaScript学习教程,从入门到精通,Ajax数据交换格式与跨域处理(26)
xml·开发语言·前端·javascript·学习·ajax·css3
好名字082119 分钟前
el-tabs与table样式冲突导致高度失效问题解决(vue2+elementui)
前端·vue.js·elementui
qq_2780637125 分钟前
vue elementui 去掉默认填充 密码input导致的默认填充
前端·vue.js·elementui
黄同学real1 小时前
HTML5 新增的主要标签整理
前端·html·html5
liwulin05061 小时前
【JAVAFX】实现屏幕指定区域截图,带尺寸显示
服务器·前端·python
沉迷...1 小时前
tsconfig.json和tsconfig.node.json和tsconfig.app.json有什么区别
前端·vue.js·node.js
码上飞扬2 小时前
Nginx功能全解析:你的高性能Web服务器解决方案
服务器·前端·nginx