在构建HarmonyOS应用程序时,实现高质量的音频录制功能是提升用户体验的关键一环。HarmonyOS生态系统提供了灵活多样的音频API,其中AVRecorder是实现音频录制的首选工具,它不仅支持丰富的音频格式,还简化了从录制到编码的全过程。本文将通过详尽的代码示例,带领开发者深入了解如何使用AVRecorder API来构建一个完整的音频录制功能,并对比其他可选方案,以便您根据项目需求作出最佳选择。

一、AVRecorder API简介

AVRecorder API是HarmonyOS提供的一个高级音频录制接口,它集成了音频捕获、编码及文件封装功能,支持从麦克风等音频源直接录制音频,并生成常见的音频文件格式,如M4A。下面,我们将通过一个完整的代码示例,展示如何使用AVRecorder进行音频录制。

HarmonyOS入门之AVRecorder音频录制_HarmonyOS

二、开发环境与准备工作

确保您的开发环境已经配置好HarmonyOS应用开发工具链,熟悉JavaScript或ArkTS编程。

三、代码示例:使用AVRecorder进行音频录制

下面的代码示例展示了如何使用AVRecorder完成从初始化到录制、暂停、恢复、停止的全过程。

1 import media from '@ohos.multimedia.media';
2
3 class AudioRecorderDemo {
4  constructor() {
5    this.avRecorder = undefined;
6    this.avProfile = {
7      audioBitrate: 100000, // 音频比特率
8      audioChannels: 2, // 音频声道数
9      audioCodec: media.CodecMimeType.AUDIO_AAC, // 音频编码格式
10      audioSampleRate: 48000, // 音频采样率
11      fileFormat: media.ContainerFormatType.CFT_MPEG_4A, // 封装格式
12    };
13    this.avConfig = {
14      audioSourceType: media.AudioSourceType.AUDIO_SOURCE_TYPE_MIC, // 麦克风作为输入源
15      profile: this.avProfile,
16      // 注意:实际应用中需要通过文件系统API获取合法的fd路径
17      url: 'fd://35',
18    };
19  }
20
21  async initRecorder() {
22    try {
23      this.avRecorder = await media.createAVRecorder();
24      this.setEventListeners();
25      await this.avRecorder.prepare(this.avConfig);
26    } catch (err) {
27      console.error("初始化AVRecorder失败:", err);
28    }
29  }
30
31  setEventListeners() {
32    this.avRecorder.on('stateChange', (state, reason) => {
33      console.log(`AVRecorder状态变更: ${state}`);
34    });
35
36    this.avRecorder.on('error', (err) => {
37      console.error("AVRecorder错误:", err);
38    });
39  }
40
41  async startRecording() {
42    if (this.avRecorder && this.avRecorder.state === 'idle') {
43      try {
44        await this.avRecorder.start();
45        console.log("开始录音");
46      } catch (err) {
47        console.error("开始录音失败:", err);
48      }
49    } else {
50      console.warn("无法开始录音,当前状态不支持");
51    }
52  }
53
54  async pauseRecording() {
55    if (this.avRecorder && this.avRecorder.state === 'started') {
56      try {
57        await this.avRecorder.pause();
58        console.log("暂停录音");
59      } catch (err) {
60        console.error("暂停录音失败:", err);
61      }
62    } else {
63      console.warn("无法暂停录音,当前状态不支持");
64    }
65  }
66
67  async resumeRecording() {
68    if (this.avRecorder && this.avRecorder.state === 'paused') {
69      try {
70        await this.avRecorder.resume();
71        console.log("恢复录音");
72      } catch (err) {
73        console.error("恢复录音失败:", err);
74      }
75    } else {
76      console.warn("无法恢复录音,当前状态不支持");
77    }
78  }
79
80  async stopRecording() {
81    if (this.avRecorder && (this.avRecorder.state === 'started' || this.avRecorder.state === 'paused')) {
82      try {
83        await this.avRecorder.stop();
84        console.log("停止录音");
85        await this.releaseResources();
86      } catch (err) {
87        console.error("停止录音失败:", err);
88      }
89    } else {
90      console.warn("无法停止录音,当前状态不支持");
91    }
92  }
93
94  async releaseResources() {
95    if (this.avRecorder) {
96      try {
97        await this.avRecorder.reset();
98        await this.avRecorder.release();
99        this.avRecorder = undefined;
100        console.log("资源释放完成");
101      } catch (err) {
102        console.error("释放资源失败:", err);
103      }
104    }
105  }
106}
107
108// 使用示例
109async function main() {
110  const audioRecorder = new AudioRecorderDemo();
111  await audioRecorder.initRecorder();
112  await audioRecorder.startRecording();
113  // 示例中省略了暂停、恢复逻辑,可根据需求调用audioRecorder.pauseRecording(), audioRecorder.resumeRecording()
114  await audioRecorder.stopRecording();
115}
116
117main().catch(err => console.error("主程序错误:", err));

四、其他可选方案

虽然AVRecorder在多数情况下足够强大且易于使用,但根据具体需求,开发者还可以考虑以下方案:

  • AudioCapturer:更适合需要直接处理原始PCM数据的高级应用,为音频处理提供更多自定义空间。
  • OpenSL ES:提供低级别音频接口,适合需要在Native层进行音频处理的场景,但使用难度较高。

五、总结

AVRecorder API以其高度集成的特性和易于上手的API设计,成为HarmonyOS应用音频录制功能的优选方案。通过上述示例代码,开发者可以快速构建出稳定高效的音频录制模块。在实际开发中,还需注意处理好权限申请、状态管理及错误处理等细节,以确保应用体验的完善。