同学们,大家好,本节内容以一个简单的发送语音消息为案例,来给大家讲解一下在鸿蒙上面如何实现语音的录制与播放,也就是用arkTs语音来实现语音录制/播放,话不多说,进入正题。
要实现这个需求,我们可以按以下步骤来:
整体实现思路:
- 申请录音权限;
- 实现录制语音功能;
- 语音消息播放
目录
一 基础环境搭建
@Entry
@Component
struct VoiceMessageCase {
build() {
Row(){
Column({
space:20}){
Text('收到一条语音消息')
.onClick(()=>{
//语音播放
})
Button('长按录制消息')
}
.width('100%')
}
.height('100%')
}
}
二 申请录音权限
我们在点击长按的时候,就需要开始录制语音,但是录制语音的前提是,得有录音的权限才可以录制,也就是说长按之后,第一步应该是检测是否有录音权限,如果有,则开始录制语音,没有的话,就去向用户申请权限。
检测录音权限方法
//导包
import {
abilityAccessCtrl, bundleManager, common } from '@kit.AbilityKit'
// 检查权限方法
async checkPermission() {
try {
const manager = abilityAccessCtrl.createAtManager() // 创建程序控制管理器
// 获取应用信息
const buildInfo = bundleManager.
getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION)
// 获取该应用是否有录音权限
const status = manager.
checkAccessTokenSync(buildInfo.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: buildInfo.name
}
})
} else {
// 有权限,可以开始录音
}
} catch (error) {
}
}
给Button按钮绑定长按事件
Button('长按录制消息')
.gesture(LongPressGesture()
.onAction(() => {
//长按
this.checkPermission()
})
.onActionEnd(() => {
//松手
}))
三 实现录制语音功能
当我们有了录音权限后,我们就可以开始录制语音了。
我们首先要明白,一条语音消息的本质就是一个音频文件(.mp3、.wav等)。
录制语音消息的原理就是:①通过手机录制一段音频;②音频形成文件;③写入磁盘
1 创建音频文件
大家可以根据实际的业务场景来选择将音频文件存放在什么位置,我这里选择存入沙箱。因为涉及到了要操作磁盘,所以我们在录制语音之前,应该先实现一个方法——在磁盘中创建一个音频文件,并返回文件的路径,拿到文件之后,就可以使用IO流往文件中输入音频数据了。
// 创建一个文件 并返回路径
createAudioFile() {
//定义一个文件夹
let path = getContext().filesDir + '/' + 'audio'
// 判断有无path,没有就创建
if (!fileIo.accessSync(path)) {
fileIo.mkdirSync(path)
}
//定义一个文件路径
let filePath = path + '/' + Date.now() + '.wav'
//打开filePath文件,如果文件不存在,则创建
const file = fileIo.openSync(filePath, fileIo.OpenMode.CREATE)
//关闭filePath文件
fileIo.closeSync(file)
return filePath // 返回文件路径
}
2 音频采集器
拿到可以存放音频的文件之后,就可以把采集到的音频流写入文件了,我们需要定义一个音频采集器的工具类,来完成将采集到的音频流写入文件的方法。
音频采集器的实现思路:
- 准备创建音频捕捉器所需要的参数
- 参数一:音频流信息
- 参数二:音频采集器信息
- 根据参数去初始化音频采集器
- 定义开始采集音频并写入音频文件方法
- 定义停止采集音频的方法
- 定义释放资源方法——当不再使用音频采集器时,可以释放音频采集器占用的资源
① 实现过程
定义音频采集器类
//音频采集器类,主要用于采集音频,写入文件
export default class AudioCapturer{
}
//导包
import {
audio } from '@kit.AudioKit'
import {
fileIo } from '@kit.CoreFileKit'
定义创建音频采集器所需要的参数
//定义音频流信息
static audioStreamInfo:audio.AudioStreamInfo = {
//彩样率
samplingRate:audio.AudioSamplingRate.SAMPLE_RATE_44100,
//通道数
channels:audio.AudioChannel.CHANNEL_1,
//采样格式
sampleFormat:audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE,
//编码格式
encodingType:audio.AudioEncodingType.ENCODING_TYPE_RAW
}
//定义音频采集器信息
static audioCapturerInfo:audio.AudioCapturerInfo={
//音源
source:audio.SourceType.SOURCE_TYPE_MIC,
//音频采集器标志
capturerFlags:0
}
初始化音频采集器
//定义音频采集器
static audioCapturer:audio.AudioCapturer
//初始化音频采集器
static async init(){
AudioCapturer.audioCapturer = await audio.createAudioCapturer({
//需要音频流信息和音频采集器信息
streamInfo:AudioCapturer.audioStreamInfo,
capturerInfo:AudioCapturer.audioCapturerInfo
})
}
定义采集音频并写入音频文件的方法
定义一个变量,用于控制音频的开始采集与停止
//是否正在录制
static recordIng:boolean = false
采集音频写入文件的方法:核心思路就是,音频采集器会不停地将采集到的音频存入缓冲区,我们获取缓冲区中的数据,写入目标文件即可
//开始采集音频
static async start(filePath: