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

本文涉及的产品
语音服务,语音通知 50分钟
简介: 三文带你轻松上手鸿蒙的AI语音01-实时语音识别

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

前言

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

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

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

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

  1. 语音识别
  2. 文本转语音

语音识别介绍

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

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

  1. 实时语音转文本
  2. 声音文件转文本

实时语音转文本

实现流程

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

  1. 申请权限
  2. 创建AI语音引擎
  3. 设置监听回调
  4. 开始监听

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

申请权限

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

申请权限分成3个步骤

  1. 声明权限
  2. 检查是否拥有权限
  3. 申请权限

声明权限

  1. \entry\src\main\module.json5中添加以下配置代码 requestPermissions
{
  "module": {
    ...
    "requestPermissions": [
      {
        "name": "ohos.permission.MICROPHONE",
        "reason": "$string:voice_reason",
        "usedScene": {
          "abilities": [
            "FormAbility"
          ],
          "when": "always"
        }
      }
    ],
  }
}

  1. \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中关于权限的代码,都是没有经过封装的,难以使用。所以这里提供了封装好的版本。

没有封装过的示例代码:


封装好的代码

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
@Component
struct 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)
  }
}

实时语音识别相关步骤

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

创建AI语音引擎

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

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

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

设置AI语音监听回调

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

  1. 开始识别回调
  2. 事件回调
  3. 识别结果回调
  4. 识别完成回调
  5. 识别错误回调

开始监听实时语音

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

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

封装好的语音识别代码

\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
@Component
struct 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)
  }
}



语音识别结果分析

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

实时语音识别 {"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":""}

其中需要关注的是:

  1. 识别功能是持续触发的,当收集到声音时持续触发
  2. isFinal 表示一个句子是否结束

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

总结

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

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

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

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

  1. 语音识别
  2. 文本转语音

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

  1. 实时语音转文本
  2. 声音文件转文本

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

相关实践学习
达摩院智能语音交互 - 声纹识别技术
声纹识别是基于每个发音人的发音器官构造不同,识别当前发音人的身份。按照任务具体分为两种: 声纹辨认:从说话人集合中判别出测试语音所属的说话人,为多选一的问题 声纹确认:判断测试语音是否由目标说话人所说,是二选一的问题(是或者不是) 按照应用具体分为两种: 文本相关:要求使用者重复指定的话语,通常包含与训练信息相同的文本(精度较高,适合当前应用模式) 文本无关:对使用者发音内容和语言没有要求,受信道环境影响比较大,精度不高 本课程主要介绍声纹识别的原型技术、系统架构及应用案例等。 讲师介绍: 郑斯奇,达摩院算法专家,毕业于美国哈佛大学,研究方向包括声纹识别、性别、年龄、语种识别等。致力于推动端侧声纹与个性化技术的研究和大规模应用。
目录
相关文章
|
1月前
|
Ubuntu 机器人 语音技术
语音识别与语音控制的原理介绍
硬件平台 机器硬件:OriginBot(导航版/视觉版)PC主机:Windows(>=10)/Ubuntu(>=20.04)扩展硬件:X3语音版 运行案例 首先进入OriginBot主控系统,运行一下指令。请注意,部分操作OriginBot内暂未放入,请根据内容进行适当处理。 cd /userdata/dev_ws/ # 配置TogetheROS环境 source /opt/tros/setup.bash # 从tros.b的安装路径中拷贝出运行示例需要的配置文件。 cp -r /opt/tros/lib/hobot_audio/config/ . # 加载音频驱动,设备启动之后只
184 83
|
1天前
|
人工智能
三文带你轻松上手鸿蒙的AI语音03-文本合成声音
三文带你轻松上手鸿蒙的AI语音03-文本合成声音
12 1
三文带你轻松上手鸿蒙的AI语音03-文本合成声音
|
3天前
|
Ubuntu 机器人 语音技术
语音识别与语音控制
【10月更文挑战第4天】硬件平台 机器硬件:OriginBot(导航版/视觉版)PC主机:Windows(>=10)/Ubuntu(>=20.04)扩展硬件:X3语音版 运行案例 首先进入OriginBot主控系统,运行一下指令。请注意,部分操作OriginBot内暂未放入,请根据内容进行适当处理。 cd /userdata/dev_ws/ # 配置TogetheROS环境 source /opt/tros/setup.bash # 从tros.b的安装路径中拷贝出运行示例需要的配置文件。 cp -r /opt/tros/lib/hobot_audio/config/ . # 加载
17 4
|
1天前
|
存储 人工智能 开发者
三文带你轻松上手鸿蒙的AI语音02-声音文件转文本
三文带你轻松上手鸿蒙的AI语音02-声音文件转文本
10 0
三文带你轻松上手鸿蒙的AI语音02-声音文件转文本
|
1月前
|
机器学习/深度学习 人工智能 编解码
深入探索AI文生语音技术的奥秘:从文本输入到逼真语音输出的全链条语音合成过程解析
【9月更文挑战第2天】深入探索AI文生语音技术的奥秘:从文本输入到逼真语音输出的全链条语音合成过程解析
 深入探索AI文生语音技术的奥秘:从文本输入到逼真语音输出的全链条语音合成过程解析
|
1月前
|
人工智能 Linux iOS开发
AI超强语音转文本SenseVoice,本地化部署教程!
【9月更文挑战第7天】以下是AI超强语音转文本工具SenseVoice的本地化部署教程:首先确保服务器或计算机满足硬件和软件要求,包括处理器性能、内存及操作系统等。接着从官网下载适合的安装包,并按操作系统进行安装。配置音频输入设备和语言模型后,启动SenseVoice并测试其语音转文本功能。最后根据实际使用情况进行优化调整,并定期更新以获取最新功能。详细步骤需参照官方文档。
196 1
|
2月前
|
人工智能 数据处理 语音技术
通义语音AI技术问题之查看KAN-TTS在ModelScope上的模型列表如何解决
通义语音AI技术问题之查看KAN-TTS在ModelScope上的模型列表如何解决
43 10
|
2月前
|
人工智能 自然语言处理 语音技术
使用AI识别语音和B站视频并通过GPT生成思维导图原创
AI脑图现新增语音及B站视频内容识别功能,可自动生成思维导图。用户可通过发送语音或上传语音文件,系统自动转换为文本并生成结构化的思维导图;对于B站视频,仅需提供链接即可。其工作流程包括:语音转文本、文本结构化、生成Markdown、Markdown转思维导图HTML以及输出最终的思维导图图片给用户。
51 0
|
2月前
|
机器学习/深度学习 人工智能 自然语言处理
|
5月前
|
机器学习/深度学习 自然语言处理 算法
基于深度学习的语音识别技术应用与发展
在当今数字化时代,语音识别技术已经成为人机交互领域的重要组成部分。本文将介绍基于深度学习的语音识别技术在智能助手、智能家居和医疗健康等领域的应用与发展,同时探讨该技术在未来的潜在应用和发展方向。
180 4