1# 音频录制开发指导 2 3## 简介 4 5音频录制的主要工作是捕获音频信号,完成音频编码并保存到文件中,帮助开发者轻松实现音频录制功能。该模块允许调用者指定音频录制的采样率、声道数、编码格式、封装格式、输出文件的路径等参数。 6 7## 运作机制 8 9该模块提供了音频录制状态变化示意图和音频录制外部模块交互图。 10 11**图1** 音频录制状态变化变化示意图 12 13 14 15 16 17**图2** 音频录制外部模块交互图 18 19 20 21**说明**:三方录音应用或录音机通过调用JS接口层提供的js接口实现相应功能时,框架层会通过Native Framework的媒体服务,调用音频部件获取通过音频HDI捕获的音频数据,再通过软件编码输出编码封装后的音频数据保存至文件中,实现音频录制功能。 22 23## 约束与限制 24 25开发者在进行录制功能开发前,需要先对所开发的应用配置麦克风权限(ohos.permission.MICROPHONE),权限配置相关内容可参考:[访问控制权限申请指导](../security/accesstoken-guidelines.md) 26 27## 开发指导 28 29详细API含义可参考:[媒体服务API文档AudioRecorder](../reference/apis/js-apis-media.md#audiorecorder) 30 31### 全流程场景 32 33音频录制的全流程场景包含:创建实例,设置录制参数,开始录制,暂停录制,恢复录制,停止录制,释放资源等流程。 34 35```js 36import media from '@ohos.multimedia.media' 37import mediaLibrary from '@ohos.multimedia.mediaLibrary' 38export class AudioRecorderDemo { 39 private testFdNumber; // 用于保存fd地址 40 41 // 设置音频录制相关回调函数 42 setCallBack(audioRecorder) { 43 audioRecorder.on('prepare', () => { // 设置'prepare'事件回调 44 console.log('prepare success'); 45 audioRecorder.start(); // 调用start方法开始录制,并触发start回调 46 }); 47 audioRecorder.on('start', () => { // 设置'start'事件回调 48 console.log('audio recorder start success'); 49 audioRecorder.pause(); // 调用pause方法暂停录制,并触发pause回调 50 }); 51 audioRecorder.on('pause', () => { // 设置'pause'事件回调 52 console.log('audio recorder pause success'); 53 audioRecorder.resume(); // 调用resume方法恢复录制,并触发resume回调 54 }); 55 audioRecorder.on('resume', () => { // 设置'resume'事件回调 56 console.log('audio recorder resume success'); 57 audioRecorder.stop(); // 调用stop方法停止录制,并触发stop回调 58 }); 59 audioRecorder.on('stop', () => { // 设置'stop'事件回调 60 console.log('audio recorder stop success'); 61 audioRecorder.reset(); // 调用reset方法重置录制,并触发reset回调 62 }); 63 audioRecorder.on('reset', () => { // 设置'reset'事件回调 64 console.log('audio recorder reset success'); 65 audioRecorder.release(); // 调用release方法,释放资源,并触发release回调 66 }); 67 audioRecorder.on('release', () => { // 设置'release'事件回调 68 console.log('audio recorder release success'); 69 audioRecorder = undefined; 70 }); 71 audioRecorder.on('error', (error) => { // 设置'error'事件回调 72 console.info(`audio error called, errName is ${error.name}`); 73 console.info(`audio error called, errCode is ${error.code}`); 74 console.info(`audio error called, errMessage is ${error.message}`); 75 }); 76 } 77 78 // pathName是传入的录制文件名,例如:01.mp3,生成后的文件地址:/storage/media/100/local/files/Video/01.mp3 79 // 使用mediaLibrary需要添加以下权限, ohos.permission.MEDIA_LOCATION、ohos.permission.WRITE_MEDIA、ohos.permission.READ_MEDIA 80 async getFd(pathName) { 81 let displayName = pathName; 82 const mediaTest = mediaLibrary.getMediaLibrary(); 83 let fileKeyObj = mediaLibrary.FileKey; 84 let mediaType = mediaLibrary.MediaType.VIDEO; 85 let publicPath = await mediaTest.getPublicDirectory(mediaLibrary.DirectoryType.DIR_VIDEO); 86 let dataUri = await mediaTest.createAsset(mediaType, displayName, publicPath); 87 if (dataUri != undefined) { 88 let args = dataUri.id.toString(); 89 let fetchOp = { 90 selections : fileKeyObj.ID + "=?", 91 selectionArgs : [args], 92 } 93 let fetchFileResult = await mediaTest.getFileAssets(fetchOp); 94 let fileAsset = await fetchFileResult.getAllObject(); 95 let fdNumber = await fileAsset[0].open('Rw'); 96 this.testFdNumber = "fd://" + fdNumber.toString(); 97 } 98 } 99 100 async audioRecorderDemo() { 101 // 1.创建实例 102 let audioRecorder = media.createAudioRecorder(); 103 // 2.设置回调 104 this.setCallBack(audioRecorder); 105 await this.getFd('01.mp3'); // 调用getFd方法获取需要录制文件的fd地址 106 // 3.设置录制参数 107 let audioRecorderConfig = { 108 audioEncodeBitRate : 22050, 109 audioSampleRate : 22050, 110 numberOfChannels : 2, 111 uri : this.testFdNumber, // testFdNumber由getFd生成 112 location : { latitude : 30, longitude : 130}, 113 audioEncoderMime : media.CodecMimeType.AUDIO_AAC, 114 fileFormat : media.ContainerFormatType.CFT_MPEG_4A, 115 } 116 audioRecorder.prepare(audioRecorderConfig); // 调用prepare方法,触发prepare回调函数 117 } 118} 119``` 120 121### 正常录制场景 122 123与全流程场景不同,不包括暂停录制,恢复录制的过程。 124 125```js 126import media from '@ohos.multimedia.media' 127import mediaLibrary from '@ohos.multimedia.mediaLibrary' 128export class AudioRecorderDemo { 129 private testFdNumber; // 用于保存fd地址 130 131 // 设置音频录制相关回调函数 132 setCallBack(audioRecorder) { 133 audioRecorder.on('prepare', () => { // 设置'prepare'事件回调 134 console.log('prepare success'); 135 audioRecorder.start(); // 调用start方法开始录制,并触发start回调 136 }); 137 audioRecorder.on('start', () => { // 设置'start'事件回调 138 console.log('audio recorder start success'); 139 audioRecorder.stop(); // 调用stop方法停止录制,并触发stop回调 140 }); 141 audioRecorder.on('stop', () => { // 设置'stop'事件回调 142 console.log('audio recorder stop success'); 143 audioRecorder.release(); // 调用release方法,释放资源,并触发release回调 144 }); 145 audioRecorder.on('release', () => { // 设置'release'事件回调 146 console.log('audio recorder release success'); 147 audioRecorder = undefined; 148 }); 149 audioRecorder.on('error', (error) => { // 设置'error'事件回调 150 console.info(`audio error called, errName is ${error.name}`); 151 console.info(`audio error called, errCode is ${error.code}`); 152 console.info(`audio error called, errMessage is ${error.message}`); 153 }); 154 } 155 156 // pathName是传入的录制文件名,例如:01.mp3,生成后的文件地址:/storage/media/100/local/files/Video/01.mp3 157 // 使用mediaLibrary需要添加以下权限, ohos.permission.MEDIA_LOCATION、ohos.permission.WRITE_MEDIA、ohos.permission.READ_MEDIA 158 async getFd(pathName) { 159 let displayName = pathName; 160 const mediaTest = mediaLibrary.getMediaLibrary(); 161 let fileKeyObj = mediaLibrary.FileKey; 162 let mediaType = mediaLibrary.MediaType.VIDEO; 163 let publicPath = await mediaTest.getPublicDirectory(mediaLibrary.DirectoryType.DIR_VIDEO); 164 let dataUri = await mediaTest.createAsset(mediaType, displayName, publicPath); 165 if (dataUri != undefined) { 166 let args = dataUri.id.toString(); 167 let fetchOp = { 168 selections : fileKeyObj.ID + "=?", 169 selectionArgs : [args], 170 } 171 let fetchFileResult = await mediaTest.getFileAssets(fetchOp); 172 let fileAsset = await fetchFileResult.getAllObject(); 173 let fdNumber = await fileAsset[0].open('Rw'); 174 this.testFdNumber = "fd://" + fdNumber.toString(); 175 } 176 } 177 178 async audioRecorderDemo() { 179 // 1.创建实例 180 let audioRecorder = media.createAudioRecorder(); 181 // 2.设置回调 182 this.setCallBack(audioRecorder); 183 await this.getFd('01.mp3'); // 调用getFd方法获取需要录制文件的fd地址 184 // 3.设置录制参数 185 let audioRecorderConfig = { 186 audioEncodeBitRate : 22050, 187 audioSampleRate : 22050, 188 numberOfChannels : 2, 189 uri : this.testFdNumber, // testFdNumber由getFd生成 190 location : { latitude : 30, longitude : 130}, 191 audioEncoderMime : media.CodecMimeType.AUDIO_AAC, 192 fileFormat : media.ContainerFormatType.CFT_MPEG_4A, 193 } 194 audioRecorder.prepare(audioRecorderConfig); // 调用prepare方法,触发prepare回调函数 195 } 196} 197``` 198 199## 相关实例 200 201针对音频录制开发,有以下相关实例可供参考: 202 203- [`Recorder:`录音机(ArkTS)(API8)(Full SDK)](https://gitee.com/openharmony/applications_app_samples/tree/OpenHarmony-3.2-Release/media/Recorder) 204- [音频播放器(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Media/Audio_OH_ETS) 205