HarmonyOS 鸿蒙Next 使用avrecord录制出来的音频为空文件,请帮忙看看,demo如下
HarmonyOS 鸿蒙Next 使用avrecord录制出来的音频为空文件,请帮忙看看,demo如下
Index.ets
import { AudioRecorderDemo } from '../utils/AudioRecord';
@Entry
@Component
struct Index {
@State avRecord: AudioRecorderDemo = new AudioRecorderDemo();
build() {
Column() {
Button('录制声音').onClick(() => {
let fileName = 'Audio_' + new Date().getTime() + '.wav'
this.avRecord.startRecordingProcess(fileName)
console.log('语音文件', '/data/storage/el2/base/files/chat/audio/' + fileName)
})
Button('结束录制').onClick(()=>{
this.avRecord.stopRecordingProcess()
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
AudioRecord.ets
import { media } from '@kit.MediaKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { fileIo } from '@kit.CoreFileKit';
import fs from '@ohos.file.fs';
export class AudioRecorderDemo {
private curFile: fileIo.File | undefined = undefined;
private avRecorder: media.AVRecorder | undefined = undefined;
private avProfile: media.AVRecorderProfile = {
audioBitrate: 100000, // 音频比特率
audioChannels: 2, // 音频声道数
audioCodec: media.CodecMimeType.AUDIO_AAC, // 音频编码格式,当前只支持aac
audioSampleRate: 48000, // 音频采样率
fileFormat: media.ContainerFormatType.CFT_MPEG_4A, // 封装格式,当前只支持m4a
};
private avConfig: media.AVRecorderConfig = {
audioSourceType: media.AudioSourceType.AUDIO_SOURCE_TYPE_MIC, // 音频输入源,这里设置为麦克风
profile: this.avProfile,
url: '', // 参考应用文件访问与管理开发示例新建并读写一个文件
};
// 注册audioRecorder回调函数
setAudioRecorderCallback() {
if (this.avRecorder != undefined) {
// 状态机变化回调函数
this.avRecorder.on('stateChange', (state: media.AVRecorderState, reason: media.StateChangeReason) => {
console.log(`AudioRecorder current state is ${state}`);
})
// 错误上报回调函数
this.avRecorder.on('error', (err: BusinessError) => {
console.error(`AudioRecorder failed, code is ${err.code}, message is ${err.message}`);
})
}
}
// 开始录制对应的流程
// async startRecordingProcess(fileName: string) {
// if (this.avRecorder != undefined) {
// await this.avRecorder.release();
// this.avRecorder = undefined;
// }
// // 1.创建录制实例
// this.avRecorder = await media.createAVRecorder();
// this.setAudioRecorderCallback();
// // 创建语音存放文件夹
// let res = fs.accessSync('/data/storage/el2/base/files/chat/audio');
// if (!res) {
// fs.mkdirSync('/data/storage/el2/base/files/chat/audio', true);
// }
// // 2.获取录制文件fd赋予avConfig里的url;参考FilePicker文档
// this.curFile = fileIo.openSync('/data/storage/el2/base/files/chat/audio/' + fileName, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE);
// this.avConfig.url = 'fd://' + this.curFile.fd;
// // 3.配置录制参数完成准备工作
// await this.avRecorder.prepare(this.avConfig);
// // 4.开始录制
// await this.avRecorder.start();
// }
async startRecordingProcess(fileName: string) {
console.log('语音文件', '/data/storage/el2/base/files/chat/audio/' + fileName)
// 创建语音存放文件夹
let res = fs.accessSync('/data/storage/el2/base/files/chat/audio');
if (!res) {
fs.mkdirSync('/data/storage/el2/base/files/chat/audio', true);
}
try {
if (this.avRecorder == undefined) {
// 1.创建录制实例
this.avRecorder = await media.createAVRecorder();
}
this.setAudioRecorderCallback();
// 2.获取录制文件fd赋予avConfig里的url;参考FilePicker文档
this.curFile = fileIo.openSync('/data/storage/el2/base/files/chat/audio/' + fileName, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE);
this.avConfig.url = 'fd://' + this.curFile.fd;
// 3.配置录制参数完成准备工作
await this.avRecorder.prepare(this.avConfig);
// 4.开始录制
await this.avRecorder.start();
} catch (err) {
}
}
// 暂停录制对应的流程
async pauseRecordingProcess() {
if (this.avRecorder != undefined && this.avRecorder.state === 'started') { // 仅在started状态下调用pause为合理状态切换
await this.avRecorder.pause();
}
}
// 恢复录制对应的流程
async resumeRecordingProcess() {
if (this.avRecorder != undefined && this.avRecorder.state === 'paused') { // 仅在paused状态下调用resume为合理状态切换
await this.avRecorder.resume();
}
}
// 停止录制对应的流程
async stopRecordingProcess() {
if (this.avRecorder != undefined) {
// 1. 停止录制
if (this.avRecorder.state === 'started'
|| this.avRecorder.state === 'paused') { // 仅在started或者paused状态下调用stop为合理状态切换
await this.avRecorder.stop();
}
// 2.重置
await this.avRecorder.reset();
// 3.释放录制实例
await this.avRecorder.release();
this.avRecorder = undefined;
// 4.关闭录制文件fd
fileIo.closeSync(this.curFile)
}
}
// 一个完整的【开始录制-暂停录制-恢复录制-停止录制】示例
// async audioRecorderDemo() {
// await this.startRecordingProcess('test.wav'); // 开始录制
// // 用户此处可以自行设置录制时长,例如通过设置休眠阻止代码执行
// await this.pauseRecordingProcess(); //暂停录制
// await this.resumeRecordingProcess(); // 恢复录制
// await this.stopRecordingProcess(); // 停止录制
// }
}
更多关于HarmonyOS 鸿蒙Next 使用avrecord录制出来的音频为空文件,请帮忙看看,demo如下的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
A: 伙伴,可以参考如下的index代码,咱主要是需要申请录音权限:
在module.json5中需要声明麦克风权限:
{
"name": "ohos.permission.MICROPHONE",
"reason": "$string:app_name",
"usedScene": {
"abilities": [
"FormAbility"
],
"when":"always"
}
},
import { AudioRecorderDemo } from '../utils/AudioRecord';
import { abilityAccessCtrl } from '[@kit](/user/kit).AbilityKit';
import { fileIo } from '[@kit](/user/kit).CoreFileKit';
import { media } from '[@kit](/user/kit).MediaKit';
[@Entry](/user/Entry)
[@Component](/user/Component)
struct Index {
[@State](/user/State) avRecord: AudioRecorderDemo = new AudioRecorderDemo();
[@State](/user/State) startPlayFlag: boolean = false;
[@State](/user/State) startRecordFlag: boolean = false;
[@State](/user/State) filePath: string = ''
avPlayer?: media.AVPlayer
[@State](/user/State) stopPlayFlag: boolean = false;
async applyPermissionFromUser() {
console.log(`开始申请权限...`)
const manager = abilityAccessCtrl.createAtManager()
await manager.requestPermissionsFromUser(getContext(), ['ohos.permission.MICROPHONE'])
}
// //检查权限
// checkPermission() {
// const manager = abilityAccessCtrl.createAtManager()
// //获取应用信息
// const bundleInfo = bundleManager.getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION)
// const status = manager.checkAccessTokenSync(bundleInfo.appInfo.accessTokenId, 'ohos.permission.MICROPHONE')
// if (status === abilityAccessCtrl.GrantStatus.PERMISSION_DENIED) {
// //跳转手机设置的权限授权界面
// const context = getContext() as common.UIAbilityContext
// context.startAbility({
// bundleName: 'com.huawei.hmos.settings',
// abilityName: 'com.huawei.hmos.settings.MainAbility',
// uri: 'application_info_entry',
// parameters: {
// pushParams: bundleInfo.name
// }
// })
// } else {
// this.startRecordFlag = true
// promptAction.showToast({ message: `用户已授权,可以录音` })
// }
// }
/**
* 使用AVPlayer播放音频
*/
async startPlay() {
try {
const file = fileIo.openSync(this.filePath, fileIo.OpenMode.READ_ONLY)
const avPlayer = await media.createAVPlayer()
//订阅avPlayer状态变化
avPlayer.on('stateChange', state => {
if (state === 'initialized') {
avPlayer.prepare()
} else if (state === 'prepared') {
avPlayer.loop = true
// this.total = avPlayer.duration
avPlayer.play()
}
})
// 当前播放时间改变
//播放沙箱音频
avPlayer.url = `fd://${file.fd}`
//播放在线音频
this.avPlayer = avPlayer
this.stopPlayFlag = true
} catch (e) {
console.error('startPlay', JSON.stringify(e))
}
}
build() {
Column() {
Button('录制声音').onClick(async () => {
await this.applyPermissionFromUser()
let fileName = 'Audio_' + new Date().getTime() + '.WAV'
this.avRecord.startRecordingProcess(fileName)
this.filePath = '/data/storage/el2/base/files/chat/audio/' + fileName
console.log('语音文件', '/data/storage/el2/base/files/chat/audio/' + fileName)
})
Button('结束录制').onClick(() => {
this.avRecord.stopRecordingProcess()
})
Button('play').onClick(() => {
this.startPlay()
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
申请权限参考链接:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V13/using-avrecorder-for-recording-V13#申请权限
更多关于HarmonyOS 鸿蒙Next 使用avrecord录制出来的音频为空文件,请帮忙看看,demo如下的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
针对您提到的HarmonyOS鸿蒙Next系统中使用avrecord
录制音频结果为空文件的问题,可能的原因及初步分析如下:
-
权限问题:确保您的应用已正确申请并获得了音频录制权限。在鸿蒙系统中,权限管理较为严格,未授权可能导致无法录制音频。
-
配置错误:检查
avrecord
的命令行参数配置,特别是音频源、编码格式、输出文件路径等设置是否正确。错误的配置可能导致无法正确录制或文件无法写入。 -
资源冲突:系统中可能有其他应用正在使用音频录制资源,导致
avrecord
无法获取到录制权限。 -
系统Bug:鸿蒙Next系统可能存在未修复的Bug,影响音频录制功能。
-
文件路径问题:确认输出文件的路径是否有效,且应用具有该路径的写入权限。
建议逐一排查上述可能原因,并尝试在鸿蒙开发者社区或相关论坛搜索是否有其他开发者遇到并解决了类似问题。如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html 。