当前位置:首页 » 《休闲阅读》 » 正文

三文带你轻松上手鸿蒙的AI语音01-实时语音识别

24 人参与  2024年10月04日 08:40  分类 : 《休闲阅读》  评论

点击全文阅读


三文带你轻松上手鸿蒙的AI语音01-实时语音识别

前言

HarmonyOSNext中集成了强大的AI功能。Core Speech Kit(基础语音服务)是它提供的众多AI功能中的一种。

Core Speech Kit(基础语音服务)集成了语音类基础AI能力,包括文本转语音(TextToSpeech)及语音识别(SpeechRecognizer)能

力,便于用户与设备进行互动,实现将实时输入的语音与文本之间相互转换。

简单来讲Core Speech Kit主要提供了两大语音AI功能:

语音识别文本转语音

语音识别介绍

语音识别功能可以将一段音频信息(短语音模式不超过60s,长语音模式不超过8h)转换为文本。

其中语音识别又可以实现:

实时语音转文本声音文件转文本

实时语音转文本

实现流程

先介绍语音识别的流程,后面的文字转语音大同小异

申请权限创建AI语音引擎设置监听回调开始监听

tips: 完整代码在每一个功能的末尾,可以结合封装后的代码来阅读

申请权限

image-20240828222453973

因为在开发功能过程中,需要调用手机的麦克风功能。所以需要主动申请权限。

image-20240828222047223

申请权限分成3个步骤

声明权限检查是否拥有权限申请权限

声明权限

\entry\src\main\module.json5中添加以下配置代码 requestPermissions

{  "module": {    ...    "requestPermissions": [      {        "name": "ohos.permission.MICROPHONE",        "reason": "$string:voice_reason",        "usedScene": {          "abilities": [            "FormAbility"          ],          "when": "always"        }      }    ],  }}

\entry\src\main\resources\base\element\string.json 添加 申请原因 voice_reason

{  "string": [    {      "name": "module_desc",      "value": "module description"    },    {      "name": "EntryAbility_desc",      "value": "description"    },    {      "name": "EntryAbility_label",      "value": "label"    },    {      "name": "voice_reason",      "value": "用于获取用户的录音"    }  ]}

检查权限

实际开发中,我们在申请权限之前可以先调用接口checkAccessTokenSync,检查下是否已经拥有权限。如果没有,则主动申请权限

申请权限

当我们需要申请某个功能的权限时,可以通过调用 requestPermissionsFromUser 来实现

封装好的权限代码

因为HarmonyOSNext中关于权限的代码,都是没有经过封装的,难以使用。所以这里提供了封装好的版本。

没有封装过的示例代码:

image-20240828224125035


封装好的代码

entry\src\main\ets\utils\permissionMananger.ets

// 导入必要的模块,包括权限管理相关的功能import { abilityAccessCtrl, bundleManager, common, Permissions } from '@kit.AbilityKit';export class PermissionManager {  // 静态方法用于检查给定的权限是否已经被授予  static checkPermission(permissions: Permissions[]): boolean {    // 创建一个访问令牌管理器实例    let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();    // 初始化tokenID为0,稍后将获取真实的tokenID    let tokenID: number = 0;    // 获取本应用的包信息    const bundleInfo =      bundleManager.getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);    // 设置tokenID为应用的访问令牌ID    tokenID = bundleInfo.appInfo.accessTokenId;    // 如果没有传入任何权限,则返回false表示没有权限    if (permissions.length === 0) {      return false;    } else {      // 检查所有请求的权限是否都被授予      return permissions.every(permission =>      abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED ===      atManager.checkAccessTokenSync(tokenID, permission)      );    }  }  // 异步静态方法用于请求用户授权指定的权限  static async requestPermission(permissions: Permissions[]): Promise<boolean> {    // 创建一个访问令牌管理器实例    let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();    // 获取上下文(这里假设getContext是一个可以获取到UI能力上下文的方法)    let context: Context = getContext() as common.UIAbilityContext;    // 请求用户授权指定的权限    const result = await atManager.requestPermissionsFromUser(context, permissions);    // 检查请求结果是否成功(authResults数组中每个元素都应该是0,表示成功)    return !!result.authResults.length && result.authResults.every(authResults => authResults === 0);  }}

页面中使用权限代码

Index.ets

import { PermissionManager } from '../utils/permissionMananger'import { Permissions } from '@kit.AbilityKit'@Entry@Componentstruct Index {  // 1 申请权限  fn1 = async () => {    // 准备好需要申请的权限 麦克风权限    const permissions: Permissions[] = ["ohos.permission.MICROPHONE"]    // 检查是否拥有权限    const isPermission = await PermissionManager.checkPermission(permissions)    if (!isPermission) {      //   如果没权限,就主动申请      PermissionManager.requestPermission(permissions)    }  }  build() {    Column() {      Button("申请权限")        .onClick(this.fn1)    }    .width("100%")    .height("100%")    .justifyContent(FlexAlign.Center)  }}

image-20240828224918956

实时语音识别相关步骤

以下主要实现实时语音识别

创建AI语音引擎

创建AI语音引擎主要有以下几个步骤

声明AI语音引擎配置参数,主要有语种、区域信息等

image-20240828225611828

调用开始创建 createEngine 方法开始创建,并且返回 AI语音实例引擎

设置AI语音监听回调

在开始语音识别之前,需要先设置语音识别回调 setListener 。它主要有以下几个分类

开始识别回调事件回调识别结果回调识别完成回调识别错误回调

image-20240828225832286

开始监听实时语音

需要先配置监听的参数,便可以调用startListening实现语音识别了

参数配置 其中,实时语音识别和语音文件识别的主要配置在 recognitionMode 字段, 0 表示实时语音识别

image-20240828230419298

封装好的语音识别代码

\entry\src\main\ets\utils\SpeechRecognizerManager.ets

import { speechRecognizer } from '@kit.CoreSpeechKit';class SpeechRecognizerManager {  /**   * 语种信息   * 语音模式:长   */  private static extraParam: Record<string, Object> = { "locate": "CN", "recognizerMode": "long" };  private static initParamsInfo: speechRecognizer.CreateEngineParams = {    /**     * 地区信息     * */    language: 'zh-CN',    /**     * 离线模式:1     */    online: 1,    extraParams: this.extraParam  };  /**   * 引擎   */  private static asrEngine: speechRecognizer.SpeechRecognitionEngine | null = null  /**   * 录音结果   */  static speechResult: speechRecognizer.SpeechRecognitionResult | null = null  /**   * 会话ID   */  private static sessionId: string = "asr" + Date.now()  /**   * 创建引擎   */  private static async createEngine() {    // 设置创建引擎参数    SpeechRecognizerManager.asrEngine = await speechRecognizer.createEngine(SpeechRecognizerManager.initParamsInfo)  }  /**   * 设置回调   */  private static setListener(callback: (srr: speechRecognizer.SpeechRecognitionResult) => void = () => {  }) {    // 创建回调对象    let setListener: speechRecognizer.RecognitionListener = {      // 开始识别成功回调      onStart(sessionId: string, eventMessage: string) {      },      // 事件回调      onEvent(sessionId: string, eventCode: number, eventMessage: string) {      },      // 识别结果回调,包括中间结果和最终结果      onResult(sessionId: string, result: speechRecognizer.SpeechRecognitionResult) {        SpeechRecognizerManager.speechResult = result        callback && callback(result)      },      // 识别完成回调      onComplete(sessionId: string, eventMessage: string) {      },      // 错误回调,错误码通过本方法返回      // 如:返回错误码1002200006,识别引擎正忙,引擎正在识别中      // 更多错误码请参考错误码参考      onError(sessionId: string, errorCode: number, errorMessage: string) {      },    }    // 设置回调    SpeechRecognizerManager.asrEngine?.setListener(setListener);  }  /**   * 开始监听   * */  static startListening() {    // 设置开始识别的相关参数    let recognizerParams: speechRecognizer.StartParams = {      // 会话id      sessionId: SpeechRecognizerManager.sessionId,      // 音频配置信息。      audioInfo: {        // 音频类型。 当前仅支持“pcm”        audioType: 'pcm',        // 音频的采样率。 当前仅支持16000采样率        sampleRate: 16000,        // 音频返回的通道数信息。 当前仅支持通道1。        soundChannel: 1,        // 音频返回的采样位数。 当前仅支持16位        sampleBit: 16      },      //   录音识别      extraParams: {        // 0:实时录音识别  会自动打开麦克风 录制实时语音        "recognitionMode": 0,        //   最大支持音频时长        maxAudioDuration: 60000      }    }    // 调用开始识别方法    SpeechRecognizerManager.asrEngine?.startListening(recognizerParams);  };  /**   * 取消识别   */  static cancel() {    SpeechRecognizerManager.asrEngine?.cancel(SpeechRecognizerManager.sessionId)  }  /**   * 释放ai语音转文字引擎   */  static shutDown() {    SpeechRecognizerManager.asrEngine?.shutdown()  }  /**   * 停止并且释放资源   */  static async release() {    SpeechRecognizerManager.cancel()    SpeechRecognizerManager.shutDown()  }  /**   * 初始化ai语音转文字引擎   */  static async init(callback: (srr: speechRecognizer.SpeechRecognitionResult) => void = () => {  }) {    await SpeechRecognizerManager.createEngine()    SpeechRecognizerManager.setListener(callback)    SpeechRecognizerManager.startListening()  }}export default SpeechRecognizerManager

页面中调用语音识别代码

import { PermissionManager } from '../utils/permissionMananger'import { Permissions } from '@kit.AbilityKit'import SpeechRecognizerManager from '../utils/SpeechRecognizerManager'@Entry@Componentstruct Index {  @State  text: 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    })  }  build() {    Column({ space: 10 }) {      Text(this.text)      Button("申请权限")        .onClick(this.fn1)      Button("实时语音识别")        .onClick(this.fn2)    }    .width("100%")    .height("100%")    .justifyContent(FlexAlign.Center)  }}

PixPin_2024-08-28_23-19-49


语音识别结果分析

语音识别成功后的数据格式如下

实时语音识别 {"isFinal":false,"isLast":false,"result":"是"}I     实时语音识别 {"isFinal":false,"isLast":false,"result":"是否"}I     实时语音识别 {"isFinal":false,"isLast":false,"result":"是否"}I     实时语音识别 {"isFinal":false,"isLast":false,"result":"是否"}I     实时语音识别 {"isFinal":false,"isLast":false,"result":"是否给"}I     实时语音识别 {"isFinal":false,"isLast":false,"result":"是否给"}I     实时语音识别 {"isFinal":false,"isLast":false,"result":"是否给你"}I     实时语音识别 {"isFinal":false,"isLast":false,"result":"是否给你"}I     实时语音识别 {"isFinal":false,"isLast":false,"result":"是否给你"}I     实时语音识别 {"isFinal":false,"isLast":false,"result":"是否给你"}I     实时语音识别 {"isFinal":false,"isLast":false,"result":"是否给你"}I     实时语音识别 {"isFinal":false,"isLast":false,"result":"是否给你"}I     实时语音识别 {"isFinal":false,"isLast":false,"result":"是否给你承"}I     实时语音识别 {"isFinal":false,"isLast":false,"result":"是否给你承"}I     实时语音识别 {"isFinal":false,"isLast":false,"result":"是否给你承诺"}I     实时语音识别 {"isFinal":false,"isLast":false,"result":"是否给你承诺"}I     实时语音识别 {"isFinal":false,"isLast":false,"result":"是否给你承诺的"}I     实时语音识别 {"isFinal":false,"isLast":false,"result":"是否给你承诺的"}I     实时语音识别 {"isFinal":false,"isLast":false,"result":"是否给你承诺的"}I     实时语音识别 {"isFinal":false,"isLast":false,"result":"是否给你承诺的"}I     实时语音识别 {"isFinal":false,"isLast":false,"result":"是否给你承诺的"}I     实时语音识别 {"isFinal":false,"isLast":false,"result":"是否给你承诺的太"}I     实时语音识别 {"isFinal":false,"isLast":false,"result":"是否给你承诺的太多"}I     实时语音识别 {"isFinal":false,"isLast":false,"result":"是否给你承诺的太多"}I     实时语音识别 {"isFinal":false,"isLast":false,"result":"是否给你承诺的太多"}I     实时语音识别 {"isFinal":false,"isLast":false,"result":"是否给你承诺的太多"}I     实时语音识别 {"isFinal":false,"isLast":false,"result":"是否给你承诺的太多"}I     实时语音识别 {"isFinal":false,"isLast":false,"result":"是否给你承诺的太多"}I     实时语音识别 {"isFinal":false,"isLast":false,"result":"是否给你承诺的太多"}I     实时语音识别 {"isFinal":false,"isLast":false,"result":"是否给你承诺的太多"}I     实时语音识别 {"isFinal":false,"isLast":false,"result":"是否给你承诺的太多"}I     实时语音识别 {"isFinal":false,"isLast":false,"result":"是否给你承诺的太多"}I     实时语音识别 {"isFinal":false,"isLast":false,"result":"是否给你承诺的太多"}I     实时语音识别 {"isFinal":false,"isLast":false,"result":"是否给你承诺的太多"}I     实时语音识别 {"isFinal":false,"isLast":false,"result":"是否给你承诺的太多"}I     实时语音识别 {"isFinal":true,"isLast":false,"result":"是否给你承诺的太多?"}I     实时语音识别 {"isFinal":false,"isLast":false,"result":""}

其中需要关注的是:

识别功能是持续触发的,当收集到声音时持续触发

isFinal 表示一个句子是否结束

image-20240828232352345

isLast 表示这一次语音识别是否结束

总结

HarmonyOSNext中集成了强大的AI功能。Core Speech Kit(基础语音服务)是它提供的众多AI功能中的一种。

Core Speech Kit(基础语音服务)集成了语音类基础AI能力,包括文本转语音(TextToSpeech)及语音识别(SpeechRecognizer)能

力,便于用户与设备进行互动,实现将实时输入的语音与文本之间相互转换。

简单来讲Core Speech Kit主要提供了两大语音AI功能:

语音识别文本转语音

其中语音识别又可以实现:

实时语音转文本声音文件转文本

本文主要实现了 实时语音转文本声音文件转文本 将会在下文讲解。


点击全文阅读


本文链接:http://zhangshiyu.com/post/167504.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1