本文为您介绍如何使用阿里云智能语音服务提供的HarmonyOS Next NUI SDK,包括SDK下载安装、关键接口及代码示例。
前提条件
下载安装
下载V1.5.016.napi.003.005_897e7d182c0a1977605046800113155067e93ac0.tar.gz。
以arkts HAR包的形式进行集成。解压压缩包,其中entry/libs/neonui.har 是SDK生成的HAR包文件,在用户工程项目中导入调用即可。如果需要HarmonyOS Next CPP接入方式,可在压缩包的native/libs和native/include中获得动态库和头文件。
使用DevEco Studio打开工程,其中录音文件识别的示例代码为FileTranscriberPage.ets文件,替换UserKey.ets中 UserKey类的Appkey和Token后,即可直接运行。
SDK关键接口
initialize:初始化SDK。
/** * 初始化SDK,SDK为单例,请先释放后再次进行初始化。请勿在UI线程调用,可能会引起阻塞 * @param callback: 事件监听回调,参见下文回调说明 * @param parameters: 初始化参数,参见接口说明 * @param level: log打印级别,值越小打印越多 * @param save_log: 是否保存log信息,使用默认值false即可。 * @return: 参见错误码 */ public initializeFileTrans(callback:INativeFileTransCallback , parameters:string , level:number , save_log:boolean=false):number其中,INativeFileTransCallback类型需要实现的回调是onFileTransEventCallback。
onFileTransEventCallback:文件识别事件回调。
/** * SDK主要事件回调 * @param event: 回调事件,参见如下事件列表 * @param resultCode: 参见错误码,在出现EVENT_ASR_ERROR事件时有效 * @param arg2: 保留参数 * @param asrResult: 语音识别结果 * @param taskId: 转写任务ID */ onFileTransEventCallback(event:Constants.NuiEvent, resultCode:number, arg2:number, asrResult:AsrResult, taskId:string):void事件列表:
名称
说明
EVENT_FILE_TRANS_CONNECTED
连接文件识别服务成功
EVENT_FILE_TRANS_UPLOADED
上传文件成功
EVENT_FILE_TRANS_RESULT
识别最终结果
EVENT_ASR_ERROR
根据错误码信息判断出错原因
setParams:以JSON格式设置SDK参数。
/** * 以JSON格式设置参数 * @param params: 参见接口说明 * @return: 参见错误码 */ public setParams(params:string):numberstartFileTranscriber:开始文件识别。
/** * 开始识别 * @param params: 识别参数,参见接口说明 * @param taskId: 开始转写的任务ID,SDK生成随机字符串 * @return: 参见错误码 */ public startFileTranscriber(params:string, task_id:ArrayBuffer):numbercancelFileTranscriber:结束识别。
/** * 结束识别 * @return: 参见错误码 */ public cancelFileTranscriber(task_id:string):numberrelease:释放SDK。
/** * 释放SDK资源 * @return: 参见错误码 */ public release():number
调用步骤
创建SDK类对象实例
初始化SDK。
根据业务需求设置参数。
调用startFileTranscriber开始识别。
在EVENT_FILE_TRANS_RESULT事件中获取最终识别结果。
结束调用,使用release接口释放SDK资源。
代码示例
接口默认采用GetInstance获得单例,您如果有多例需求,也可以直接new对象进行使用。
NUI SDK初始化
//初始化SDK,注意用户需要在Auth.getAliYunTicket中填入相关ID信息才可以使用。
    let ret:number = this.g_asrinstance.initializeFileTrans(this.cbhandle, this.genInitParams(asset_path,debug_path), Constants.LogLevel.LOG_LEVEL_VERBOSE, false);
    console.info("result = " + ret);
    if (ret == Constants.NuiResultCode.SUCCESS) {
    } else {
      //抛出错误异常信息。
    }
    //设置相关识别参数,具体参考API文档
    this.g_asrinstance.setParams(this.genParams());其中,genInitParams生成为String JSON字符串,包含资源目录和用户信息。其中用户信息包含如下字段。 genParams生成String JSON字符串格式的部分参数,在initializeFileTrans()之后, start之前进行设置。
  genInitParams(workpath:string, debugpath:string):string {
    let str:string = "";
    //获取token方式:
    let object:Map<string, string|number|boolean|object> = new Map();
    //账号和项目创建
    //  ak_id ak_secret app_key如何获得,请查看https://help.aliyun.com/document_detail/72138.html
    object.set("app_key", UserKey.app_key); // 必填
    //方法1:
    //  首先ak_id ak_secret app_key如何获得,请查看https://help.aliyun.com/document_detail/72138.html
    //  然后请看 https://help.aliyun.com/document_detail/466615.html 使用其中方案一获取临时凭证
    //  此方案简介: 远端服务器生成具有有效时限的临时凭证, 下发给移动端进行使用, 保证账号信息ak_id和ak_secret不被泄露
    //  获得Token方法(运行在APP服务端): https://help.aliyun.com/document_detail/450255.html?spm=a2c4g.72153.0.0.79176297EyBj4k
    object.set("token", UserKey.token); // 必填
    //方法2:
    //  STS获取临时凭证方法暂不支持
    //方法3:(强烈不推荐,存在阿里云账号泄露风险)
    //  参考Auth类的实现在端上访问阿里云Token服务获取SDK进行获取。请勿将ak/sk存在本地或端侧环境。
    //  此方法优点: 端侧获得Token, 无需搭建APP服务器。
    //  此方法缺点: 端侧获得ak/sk账号信息, 极易泄露。
    //            JSONObject object = Auth.getAliYunTicket();
    object.set("device_id", "***"/*Utils.getDeviceId()*/); // 必填, 推荐填入具有唯一性的id, 方便定位问题
    object.set("url", UserKey.url_file_trans); // 默认
    object.set("workspace", workpath); // 必填, 且需要有读写权限
    //当初始化SDK时的save_log参数取值为true时,该参数生效。表示是否保存音频debug,该数据保存在debug目录中,需要确保debug_path有效可写。
    //            object.put("save_wav", "true");
    //debug目录,当初始化SDK时的save_log参数取值为true时,该目录用于保存中间音频文件。
    object.set("debug_path", debugpath);
    // FullMix = 0   // 选用此模式开启本地功能并需要进行鉴权注册
    // FullCloud = 1
    // FullLocal = 2 // 选用此模式开启本地功能并需要进行鉴权注册
    // AsrMix = 3    // 选用此模式开启本地功能并需要进行鉴权注册
    // AsrCloud = 4
    // AsrLocal = 5  // 选用此模式开启本地功能并需要进行鉴权注册
    object.set("service_mode", Constants.ModeFullCloud); // 必填
    str = MapToJson(object)
    console.info("configinfo genInitParams:" + str);
    return str;
  }
  genParams():string {
    let params:string = "";
    let nls_config:Map<string, string|number|boolean|object> = new Map();
    nls_config.set("enable_intermediate_result", true);
    let parameters:Map<string, string|number|boolean|object> = new Map();
    parameters.set("nls_config", Object( JSON.parse(MapToJson(nls_config)) ) );
    params = MapToJson(parameters);//parameters.toString();
    console.log("configinfo genParams" + params)
    return params;
  }开始识别
调用startFileTranscriber方法开启识别。
let task_id:ArrayBuffer = new ArrayBuffer(32);
let ret:number = this.g_asrinstance.startFileTranscriber(this.genDialogParams(), task_id);
genDialogParams():string {
    let params:string = "";
    let dialog_param:Map<string, string|number|boolean|object> = new Map();
    //若想在运行时切换app_key
    //dialog_param.put("app_key", "");
    let debug_path:string = this.resourceDir
    dialog_param.set("file_path", debug_path + "/2.wav"); //使用DevEcoStudio工程目录resources/resfile/2.wav文件作为输入文件进行转写
    
    let nls_config:Map<string, string|number|boolean|object> = new Map();
    nls_config.set("format", "wav"); //和 "file_path"字段的语音文件编码格式匹配。
    dialog_param.set("nls_config", Object( JSON.parse(MapToJson(nls_config)) ) );
    params = MapToJson(dialog_param);
    console.info("configinfo dialog params: " + params);
    return params;
  }回调处理
onFileTransEventCallback:NUI SDK事件回调,请勿在事件回调中调用SDK的接口,可能引起死锁。
class NativeNuiCallbackHandle implements  INativeFileTransCallback{
  asrmessage:string;
  message:string;
  task_result: Map<string, string> = new Map();  //缓存多个文件的识别结果
  task_result_all:string="";                     //所有文件的识别结果汇总字符串
  constructor() {
    this.asrmessage=""
    this.message=""
  }
  onFileTransEventCallback(event:Constants.NuiEvent, resultCode:number, finish:number,
				asrResult:AsrResult, taskId:string):void{
    let asrinfo:string = ""
    console.info("event=" + event + " task_id " + taskId);
    if (event == Constants.NuiEvent.EVENT_FILE_TRANS_UPLOADED) {
      this.message = "EVENT_FILE_TRANS_UPLOADED"
      showToast("完成上传,正在转写...");
    } else if (event == Constants.NuiEvent.EVENT_FILE_TRANS_RESULT) {
      this.message = "EVENT_FILE_TRANS_RESULT"
      showToast("转写完成");
    } else if (event == Constants.NuiEvent.EVENT_ASR_ERROR) {
      this.message = "EVENT_ASR_ERROR"
      console.info("error happened: " + resultCode);
      showToast("error happened: " + resultCode);
    }
    if (asrResult) {
      asrinfo = asrResult.asrResult
      console.log(`asrinfo is ${asrinfo}`)
      if (!asrinfo){
        console.log(`asrinfo is null, with event ${event}`)
        return
      }
      let asrresult_json:object|null = JSON.parse(asrResult.asrResult)
      console.log(JSON.stringify(asrresult_json))
      if (asrresult_json) {
        let payload:object|null = asrresult_json["flash_result"];
        if (payload) {
          //console.log(JSON.stringify(payload))
          let filetransresultarray:Array<object> = payload["sentences"]
          let result_temp:string=""
          for (let i=0;i<filetransresultarray.length;i++){
            result_temp = result_temp +filetransresultarray[i]["text"]
          }
          this.asrmessage=result_temp
          this.task_result.set(taskId, this.asrmessage)
        }
      }
    }
    this.task_result_all=""
    let index:number = 0
    this.task_result.forEach((value:string, key:string)=>{
      this.task_result_all += `${index}==>${key}:${value};;\n`
      index += 1
    })
  }
}取消识别