三文带你轻松上手鸿蒙的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. 声音文件转文本

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

相关实践学习
达摩院智能语音交互 - 声纹识别技术
声纹识别是基于每个发音人的发音器官构造不同,识别当前发音人的身份。按照任务具体分为两种: 声纹辨认:从说话人集合中判别出测试语音所属的说话人,为多选一的问题 声纹确认:判断测试语音是否由目标说话人所说,是二选一的问题(是或者不是) 按照应用具体分为两种: 文本相关:要求使用者重复指定的话语,通常包含与训练信息相同的文本(精度较高,适合当前应用模式) 文本无关:对使用者发音内容和语言没有要求,受信道环境影响比较大,精度不高 本课程主要介绍声纹识别的原型技术、系统架构及应用案例等。 讲师介绍: 郑斯奇,达摩院算法专家,毕业于美国哈佛大学,研究方向包括声纹识别、性别、年龄、语种识别等。致力于推动端侧声纹与个性化技术的研究和大规模应用。
目录
相关文章
|
7天前
|
人工智能 API 语音技术
TEN Agent:开源的实时多模态 AI 代理框架,支持语音、文本和图像的实时通信交互
TEN Agent 是一个开源的实时多模态 AI 代理框架,集成了 OpenAI Realtime API 和 RTC 技术,支持语音、文本和图像的多模态交互,具备实时通信、模块化设计和多语言支持等功能,适用于智能客服、实时语音助手等多种场景。
83 15
TEN Agent:开源的实时多模态 AI 代理框架,支持语音、文本和图像的实时通信交互
|
7天前
|
人工智能 自然语言处理 语音技术
Ultravox:端到端多模态大模型,能直接理解文本和语音内容,无需依赖语音识别
Ultravox是一款端到端的多模态大模型,能够直接理解文本和人类语音,无需依赖单独的语音识别阶段。该模型通过多模态投影器技术将音频数据转换为高维空间表示,显著提高了处理速度和响应时间。Ultravox具备实时语音理解、多模态交互、低成本部署等主要功能,适用于智能客服、虚拟助手、语言学习等多个应用场景。
56 14
Ultravox:端到端多模态大模型,能直接理解文本和语音内容,无需依赖语音识别
|
3月前
|
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/ . # 加载音频驱动,设备启动之后只
254 83
|
24天前
|
人工智能 机器人 Shell
AI语音机器人安装方法 AI机器人安装代码
AI语音机器人安装方法 AI机器人安装代码
27 2
|
27天前
|
人工智能 自然语言处理 机器人
手把手带你搭建一个语音对话机器人,5分钟定制个人AI小助手(新手入门篇)
本文介绍了如何从零开始搭建一个语音对话机器人,涵盖自动语音识别(ASR)、自然语言处理(NLP)和文本到语音合成(TTS)三大核心模块。通过使用开源工具如FunASR、LLaMA3-8B和ChatTTS,以及FastAPI和Gradio等技术,详细指导读者轻松实现个人AI小助手的构建,适合技术新手快速上手。
193 1
|
1月前
|
机器学习/深度学习 人工智能 自然语言处理
医疗行业的语音识别技术解析:AI多模态能力平台的应用与架构
AI多模态能力平台通过语音识别技术,实现实时转录医患对话,自动生成结构化数据,提高医疗效率。平台具备强大的环境降噪、语音分离及自然语言处理能力,支持与医院系统无缝集成,广泛应用于门诊记录、多学科会诊和急诊场景,显著提升工作效率和数据准确性。
|
2月前
|
人工智能
三文带你轻松上手鸿蒙的AI语音03-文本合成声音
三文带你轻松上手鸿蒙的AI语音03-文本合成声音
64 1
三文带你轻松上手鸿蒙的AI语音03-文本合成声音
|
2月前
|
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/ . # 加载
|
2月前
|
存储 人工智能 开发者
三文带你轻松上手鸿蒙的AI语音02-声音文件转文本
三文带你轻松上手鸿蒙的AI语音02-声音文件转文本
102 0
三文带你轻松上手鸿蒙的AI语音02-声音文件转文本
|
3月前
|
机器学习/深度学习 人工智能 编解码
深入探索AI文生语音技术的奥秘:从文本输入到逼真语音输出的全链条语音合成过程解析
【9月更文挑战第2天】深入探索AI文生语音技术的奥秘:从文本输入到逼真语音输出的全链条语音合成过程解析
 深入探索AI文生语音技术的奥秘:从文本输入到逼真语音输出的全链条语音合成过程解析