更新时间:2024-12-04 GMT+08:00
分享

实时语音识别

前提条件

  • 确保已按照配置Java环境配置完毕。
  • 确保已存在待识别的音频文件。如果需要请在下载的SDK压缩包中获取示例音频。
  • 请参考SDK(websocket)获取最新版本SDK包。

初始化Client

初始化RasrClient,其参数包括AuthInfo、RasrListener、SisConfig。

RasrListener需要用户自定义实现监听逻辑,请参见表1表2

表1 AuthInfo

参数名称

是否必选

参数类型

描述

ak

String

用户的ak,可参考AK/SK认证

sk

String

用户的sk,可参考AK/SK认证

region

String

区域,如cn-north-4,参考终端节点

projectId

String

项目ID,同region一一对应,参考获取项目ID

endpoint

String

终端节点,参考地区和终端节点。一般使用默认即可。

表2 SisConfig

参数名称

是否必选

参数类型

描述

connectionTimeout

Integer

连接超时,默认10000,单位ms。

readTimeout

Integer

读取超时,默认10000,单位ms。

请求参数

请求类为RasrRequest,详见表3

表3 RasrRequest

参数名称

是否必选

参数类型

描述

audioFormat

String

音频格式,支持pcm,alaw,ulaw等,如pcm8k16bit,参见《API参考》中开始识别章节。

property

String

属性字符串,language_sampleRate_domain, 如chinese_16k_general,参见《API参考》中开始识别章节。

punc

String

表示是否在识别结果中添加标点,取值为yes 、 no,默认no。

digitNorm

String

表示是否将语音中的数字识别为阿拉伯数字,取值为yes 、 no,默认为yes。

vadHead

Integer

头部最大静音时间,[0, 60000],默认10000ms。

vadTail

Integer

尾部最大静音时间,[0, 3000],默认500ms。

maxSeconds

Integer

音频最长持续时间, [1, 60],默认30s。

intermediateResult

String

是否显示中间结果,yes 或 no,默认no。例如分3次发送音频,选择no结果一次性返回,选择yes分三次返回。

vocabularyId

String

热词表id,若没有则不填。

needWordInfo

String

表示是否在识别结果中输出分词结果信息,取值为“yes”“no”,默认为“no”

响应参数

状态响应类为StateResponse,详见表4

结果响应类为RasrResponse,详见表5

调用失败处理方法请参见错误码

表4 StateResponse

参数名称

是否必选

参数类型

描述

state

String

识别状态,包括start、end、fail。

traceId

String

用于日志问题追溯。

description

String

状态描述。

表5 RasrResponse

参数名

参数类型

说明

resp_type

String

参数值为RESULT,表示识别结果响应。

trace_id

String

服务内部的令牌,可用于在日志中追溯具体流程。

segments

Array of objects

多句结果。

请参考表6

表6 Segment

参数名

参数类型

说明

start_time

Integer

一句的起始时间戳,单位为ms。

end_time

Integer

一句的结束时间戳,单位为ms。

is_final

Boolen

true表示是最终结果, false表示为中间临时结果。

result

Object

调用成功表示识别结果,调用失败时无此字段。

请参考表7

表7 Result

参数名

参数类型

说明

text

String

识别结果。

score

Float

识别结果的置信度,取值范围:0~1。此值仅会在最终结果时被赋值,在中间结果时统一置为“0.0”

说明:

目前置信度作用不是太大,请勿过多依赖此值。

word_info

Array of Object

分词输出列表。

表8 Word_info 数据结构

参数名

是否必选

参数类型

说明

start_time

Integer

起始时间

end_time

Integer

结束时间

word

String

分词

示例代码

如下示例仅供参考,最新代码请前往SDK(websocket)章节获取并运行。

import com.huawei.sis.bean.AuthInfo;
import com.huawei.sis.bean.SisConfig;
import com.huawei.sis.bean.SisConstant;
import com.huawei.sis.bean.request.RasrRequest;
import com.huawei.sis.bean.response.RasrResponse;
import com.huawei.sis.bean.response.StateResponse;
import com.huawei.sis.client.RasrClient;
import com.huawei.sis.bean.RasrListener;
import com.huawei.sis.util.JsonUtils;

/**
 * 实时语音识别demo
 *
 * Copyright 2021 Huawei Technologies Co.,Ltd.
 */
public class RasrDemo {
  private static final int DEFAULT_HEAD_SILENCE_TIME = 1000;
  private static final int DEFAULT_TAIL_SILENCE_TIME = 500;
  private static final int DEFAULT_CONTINUE_SECONDS = 30;

  // 认证用的ak和sk硬编码到代码中或者明文存储都有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全;
  // 本示例以ak和sk保存在环境变量中来实现身份验证为例,运行本示例前请先在本地环境中设置环境变量HUAWEICLOUD_SDK_AK和HUAWEICLOUD_SDK_SK。
  private String ak = System.getenv("HUAWEICLOUD_SDK_AK");
  private String sk = System.getenv("HUAWEICLOUD_SDK_SK");


  private String region = "";         // 区域,如cn-north-1、cn-north-4
  private String projectId = "";      // 项目id。登录管理控制台,鼠标移动到右上角的用户名上,在下拉列表中选择我的凭证,在项目列表中查看项目id。多项目时,展开“所属区域”,从“项目ID”列获取子项目ID。

  private String path = "";           // 本地音频路径,如D:/test.wav, 也可将音频文件、音频流转换为byte数组后进行传送。

  private String audioFormat = "";    // 音频格式,如pcm16k16bit
  private String property = "chinese_16k_general";       // 属性字符串,language_sampleRate_domain,16模型推荐使用chinese_16k_general

  /**
   * 实时语音识别参数设置,所有参数设置均为可选,均有默认值。用户根据需求设置参数。
   *
   * @param request request请求,包含各种参数
   */
  private void setParameters(RasrRequest request) {

    // 1. 设置是否添加标点符号,yes 或 no, 默认"no"
    request.setAddPunc("yes");
    // 2. 设置头部的最大静音时间,[0,60000], 默认10000ms
    request.setVadHead(DEFAULT_HEAD_SILENCE_TIME);
    // 3. 设置尾部最大静音时间,[0, 3000], 默认500ms,
    request.setVadTail(DEFAULT_TAIL_SILENCE_TIME);
    // 4. 设置最长持续时间,仅在continue-stream,sentence-stream模式下起作用,[1, 60], 默认30s
    request.setMaxSeconds(DEFAULT_CONTINUE_SECONDS);
    // 5. 设置是否显示中间结果,yes或no,默认“no”。例如分3次发送音频,选择no结果一次性返回,选择yes分三次返回。
    request.setIntermediateResult("no");
    // 6. 设置热词表id, 若没有则设置,否则会报错。
    // request.setVocabularyId("");
    // 7. 设置是否将音频中数字转写为阿拉伯数字,yes or no,默认yes
    request.setDigitNorm("no");
  }

  /**
   * 定义config,所有参数可选,设置超时时间等。
   *
   * @return SisConfig
   */
  private SisConfig getConfig() {
    SisConfig config = new SisConfig();
    // 设置连接超时,默认10000ms
    config.setConnectionTimeout(SisConstant.DEFAULT_CONNECTION_TIMEOUT);
    // 设置读取超时,默认10000ms
    config.setReadTimeout(SisConstant.DEFAULT_READ_TIMEOUT);
    // 设置pingInterval,默认5000ms,当并发较大时,建议把此值设置大一些。如果不需要ping,可设置为-1
    // config.setPingInterval(-1);
    // 设置代理, 一定要确保代理可用才启动此设置。 代理初始化也可用不加密的代理,new ProxyHostInfo(host, port);
    // ProxyHostInfo proxy = new ProxyHostInfo(host, port, username, password);
    // config.setProxy(proxy);
    return config;
  }


  /**
   * 获取监听器,监听器的监听函数。
   *
   * @return RasrListener,用于监听实时语音识别的开始、识别结果、结束以及失败响应
   */
  private RasrListener getRasrListener() {
    RasrListener rasrListener = new RasrListener() {
      @Override
      /**
       * 连接成功回调
       */
      public void onTranscriptionConnect() {
        System.out.println("websocket connected");
      }

      @Override
      /**
       * 断开连接回调
       */
      public void onTranscriptionClose() {
        System.out.println("websocket closed");
      }

      @Override
      /**
       * 响应结果回调
       */
      public void onTranscriptionResponse(RasrResponse response) {
        printResponse(response);
      }

      @Override
      /**
       * 识别开始回调
       */
      public void onTranscriptionBegin(StateResponse response) {
        printResponse(response);
      }

      @Override
      /**
       * 识别结束回调
       */
      public void onSTranscriptionEnd(StateResponse response) {
        printResponse(response);
      }

      @Override
      /**
       * 识别出错回调
       */
      public void onTranscriptionFail(StateResponse response) {
        printResponse(response);
      }

      @Override
      public void onVoiceStart() {
        log.info("voice start event");
      }

      @Override
      public void onVoiceEnd() {
        log.info("voice end event");
      }

      @Override
      public void onExcceededSilence() {
        log.error("exceeded silence event");
      }

      @Override
      public void onExceededAudio() {
        log.error("exceeded audio event");
      }

      @Override
      public void onEvent(String event) {
        log.warn("receive event {}", event);
      }
    };
    return rasrListener;
  }


  private void printResponse(Object response) {
    try {
      System.out.println(JsonUtils.obj2Str(response, true));
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  /**
   * 实时语音识别SDK的工作流程
   */
  private void process() {
    // 1. 实现监听器接口RasrListener,用户自定义收到响应的处理逻辑。
    RasrListener rasrListener = getRasrListener();

    // 2. 初始化RasrClient
    AuthInfo authInfo = new AuthInfo(ak, sk, region, projectId);
    RasrClient rasrClient = new RasrClient(authInfo, rasrListener, getConfig());
    try {


      // 3. 配置参数
      // audioFormat为支持格式、property为属性字符串
      RasrRequest request = new RasrRequest(audioFormat, property);
      setParameters(request);

      // 4 选择连接模式,目前实时语音识别提供三种接口,流式一句话、实时语音识别连续模式、实时语音识别单句模式
      // 选择1 流式一句话连接
      // rasrClient.shortStreamConnect(request);

      // 选择2,实时语音识别单句模式
      // rasrClient.sentenceStreamConnect(request);

      // 选择3,实时语音识别连续模式
      rasrClient.continueStreamConnect(request);
      // 设置企业id, 可选
      // Map<String, String> headers = OKHttpClientUtils.getJsonHeaders();
      // headers.put(SisConstant.ENTERPRISE_PROJECT_ID_KEY, "your enterprise_id");
      // rasrClient.continueStreamConnect(headers, request);

      // 5. 发送开始请求、发送音频、发送end请求
      // 发送开始请求,即将开始请求连带配置发送至服务端
      rasrClient.sendStart();

      // 发送数据,在实时语音连续模式下可多次发送。识别结果可以通过监听器获取
      // 可以自己控制发送速率.byteLen为每次发送大小,sleepTime为每次发送后睡眠时间(ms),一些非持续获取音频场景不需要睡眠,可设置为0.
      rasrClient.sendAudio(path, 3200, 200);
      // rasrClient.sendAudio(path);
      // 可直接发送byte流,即byte数组
      // byte[] data = IOUtils.getFileData(path);
      // rasrClient.sendByte(data);
      // rasrClient.sendByte(data, byteLen, sleepTime);

      // 发送结尾请求
      rasrClient.sendEnd();




    } catch (Exception e) {
      e.printStackTrace();
    
    } finally {
      // 6. 关闭客户端。发送完毕后,此步一定要实施,否则服务端因为20s没有接受任何消息而报异常。
      rasrClient.close();
    }

  }

  public static void main(String[] args) {
    RasrDemo rasrDemo = new RasrDemo();
    rasrDemo.process();
  }
}

相关文档