本文主要是介绍三文带你轻松上手鸿蒙的AI语音02-声音文件转文本,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
三文带你轻松上手鸿蒙的AI语音02-声音文件转文本
接上一文
前言
本文主要实现 使用鸿蒙的AI语音功能将声音文件识别并转换成文本
实现流程
- 利用
AudioCapturer
录制声音,生成录音文件 - 利用AI语音功能,实现识别
两个录音库介绍
在HarmonyOS NEXT 应用开中,实现录音的两个核心库分别为
- AudioCapturer
- AVRecorder
AVRecorder录制出来的声音封装格式只能是aac,这个文件格式我们的AI语音引擎不支持,AI语音引擎只支持pcm格式,而 AudioCapturer录制的声音封装格式则是pcm。因此我们选择使用 AudioCapturer 来录制声音
AudioCapturer 介绍
AudioCapturer是音频采集器,用于录制PCM(Pulse Code Modulation)音频数据,适合有音频开发经验的开发者实现更灵活的录制功
能。
状态变化示意图
能看到使用 AudioCapturer 的主要流程为
- 创建 AudioCapturer 实例
- 调用 start 方法开始录音
- 调用stop方法停止录音
- 调用release方法释放实例
创建 AudioCapturer 实例
文末会提供封装好,可以直接使用的代码 下面的代码示例都是基于封装好的代码进行的
我们通过调用 createAudioCapturer方法实现创建 AudioCapturer 实例,其中该方法需要传递相关参数。
调用 start 方法开始录音
开始调用 start 方法时,需要准备相关数据。如
- 提供录音的文件名,可以自定义
- 写入录音数据的回调函数(在录制声音的过程中持续触发)
- 调用start方法
调用stop方法停止录音
调用stop方法则相对简单,直接调用即可
调用release方法释放实例
同理
封装好的录音代码
\entry\src\main\ets\utils\AudioCapturerManager.ets
下面是这个类的属性和方法的总结:
属性
- static audioCapturer:
- 类型是
audio.AudioCapturer | null
,是一个静态属性,用于存储当前的音频捕获器实例。
- 类型是
- private static recordFilePath:
- 类型是
string
,是一个静态私有属性,用于存储录音文件的路径。
- 类型是
方法
- static async createAudioCapturer():
- 如果
audioCapturer
已经存在,则直接返回该实例;否则创建一个新的音频捕获器实例,并设置其音频流信息和音频捕获信息,然后创建并返回新的实例。
- 如果
- static async startRecord(fileName: string):
- 异步静态方法,用于启动录音过程。首先调用
createAudioCapturer()
方法确保有一个音频捕获器实例。之后初始化缓冲区大小,并打开或创建一个指定名称的.wav
录音文件。定义一个读取数据的回调函数,用于将捕获到的数据写入文件中。最后开始录音,并记录下录音文件的路径。
- 异步静态方法,用于启动录音过程。首先调用
- static async stopRecord():
- 异步静态方法,用于停止录音过程。停止音频捕获器的工作,释放其资源,并清除
audioCapturer
实例。
- 异步静态方法,用于停止录音过程。停止音频捕获器的工作,释放其资源,并清除
// 导入音频处理模块
import { audio } from '@kit.AudioKit';
// 导入文件系统模块
import fs from '@ohos.file.fs';// 定义一个管理音频录制的类
export class AudioCapturerManager {// 静态属性,用于存储当前的音频捕获器实例static audioCapturer: audio.AudioCapturer | null = null;// 静态私有属性,用于存储录音文件的路径private static recordFilePath: string = "";// 静态异步方法,用于创建音频捕获器实例static async createAudioCapturer() {if (AudioCapturerManager.audioCapturer) {return AudioCapturerManager.audioCapturer}// 设置音频流信息配置let audioStreamInfo: audio.AudioStreamInfo = {samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_16000, // 设置采样率为16kHzchannels: audio.AudioChannel.CHANNEL_1, // 设置单声道sampleFormat: audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE, // 设置样本格式为16位小端encodingType: audio.AudioEncodingType.ENCODING_TYPE_RAW // 设置编码类型为原始数据};// 设置音频捕获信息配置let audioCapturerInfo: audio.AudioCapturerInfo = {source: audio.SourceType.SOURCE_TYPE_MIC, // 设置麦克风为音频来源capturerFlags: 0 // 捕获器标志,此处为默认值};// 创建音频捕获选项对象let audioCapturerOptions: audio.AudioCapturerOptions = {streamInfo: audioStreamInfo, // 使用上面定义的音频流信息capturerInfo: audioCapturerInfo // 使用上面定义的音频捕获信息};// 创建音频捕获器实例AudioCapturerManager.audioCapturer = await audio.createAudioCapturer(audioCapturerOptions);// 返回创建的音频捕获器实例return AudioCapturerManager.audioCapturer;}// 静态异步方法,用于启动录音过程static async startRecord(fileName: string) {await AudioCapturerManager.createAudioCapturer()// 初始化缓冲区大小let bufferSize: number = 0;// 定义一个内部类来设置写入文件时的选项class Options {offset?: number; // 文件写入位置偏移量length?: number; // 写入数据的长度}// 获取应用的文件目录路径let path = getContext().filesDir;// 设置录音文件的完整路径let filePath = `${path}/${fileName}.wav`;// 打开或创建录音文件let file = fs.openSync(filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);// 定义一个读取数据的回调函数let readDataCallback = (buffer: ArrayBuffer) => {// 创建一个写入文件的选项对象let options: Options = {offset: bufferSize, // 文件当前位置偏移量length: buffer.byteLength // 数据长度};// 将数据写入文件fs.writeSync(file.fd, buffer, options);// 更新缓冲区大小bufferSize += buffer.byteLength;};// 给音频捕获器实例注册读取数据的事件监听器AudioCapturerManager.audioCapturer?.on('readData', readDataCallback);// 开始录音AudioCapturerManager.audioCapturer?.start();AudioCapturerManager.recordFilePath = filePath;// 返回录音文件的路径return filePath;}// 静态异步方法,用于停止录音过程static async stopRecord() {// 停止音频捕获器的工作await AudioCapturerManager.audioCapturer?.stop();// 释放音频捕获器的资源await AudioCapturerManager.audioCapturer?.release();// 清除音频捕获器实例AudioCapturerManager.audioCapturer = null;}
}
页面中开始录音
可以通过以下路径查看录音文件是否真实生成
/data/app/el2/100/base/你的项目的boundle名称/haps/entry/files
页面代码
Index.ets
import { PermissionManager } from '../utils/permissionMananger'
import { Permissions } from '@kit.AbilityKit'
import SpeechRecognizerManager from '../utils/SpeechRecognizerManager'
import { AudioCapturerManager } from '../utils/AudioCapturerManager'@Entry
@Component
struct Index {@Statetext: string = ""fileName: string = ""// 1 申请权限fn1 = async () => {// 准备好需要申请的权限 麦克风权限const permissions: Permissions[] = ["ohos.permission.MICROPHONE"]// 检查是否拥有权限const isPermission = await PermissionManager.checkPermission(permissions)if (!isPermission) {// 如果没权限,就主动申请PermissionManager.requestPermission(permissions)}}// 2 实时语音识别fn2 = () => {SpeechRecognizerManager.init(res => {console.log("实时语音识别", JSON.stringify(res))this.text = res.result})}// 3 开始录音fn3 = () => {this.fileName = Date.now().toString()AudioCapturerManager.startRecord(this.fileName)}// 4 接收录音fn4 = () => {AudioCapturerManager.stopRecord()}build() {Column({ space: 10 }) {Text(this.text)Button("申请权限").onClick(this.fn1)Button("实时语音识别").onClick(this.fn2)Button("开始录音").onClick(this.fn3)Button("结束录音").onClick(this.fn4)}.width("100%").height("100%").justifyContent(FlexAlign.Center)}
}
使用AI语音功能 实现声音文件转文本
这篇关于三文带你轻松上手鸿蒙的AI语音02-声音文件转文本的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!