美文网首页
微信小程序调用讯飞的音频评分接口

微信小程序调用讯飞的音频评分接口

作者: 老祝读书 | 来源:发表于2022-04-25 08:00 被阅读0次

第一步在管理端配置请求地址

  wss://ise-api.xfyun.cn

第二步接口鉴权,生成url

由于在小程序端生成的url总是失败,就把url的生成放在了服务端。

   @RequestMapping(value = "/getAuthUrl", method = RequestMethod.GET)
    public  @ResponseBody
    Message  getAuthUrl() throws Exception {

        String  hostUrl="wss://ise-api.xfyun.cn/v2/open-ise",
               host="ise-api.xfyun.cn",
            //在控制台-我的应用-语音评测(流式版)获取
               appid= "************",
            //在控制台-我的应用-语音评测(流式版)获取
               apiSecret= "**************",//在控制台-我的应用-语音评测(流式版)获取
                apiKey= "*************",
                 uri="/v2/open-ise";
        SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
        format.setTimeZone(TimeZone.getTimeZone("GMT"));
        String date = format.format(new Date());

        StringBuilder builder = new StringBuilder("host: ").append(host).append("\n").//
            append("date: ").append(date).append("\n").//
            append("GET ").append(uri).append(" HTTP/1.1");
      
        Charset charset = Charset.forName("UTF-8");
        Mac mac = Mac.getInstance("hmacsha256");
        SecretKeySpec spec = new SecretKeySpec(apiSecret.getBytes(charset), "hmacsha256");
        mac.init(spec);
        byte[] hexDigits = mac.doFinal(builder.toString().getBytes(charset));
        String sha = Base64.getEncoder().encodeToString(hexDigits);

        String authorization = String.format("api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"", apiKey, "hmac-sha256", "host date request-line", sha);


        StringBuffer httpUrl = new StringBuffer();
        httpUrl.append(hostUrl).append("?")
            .append("authorization=").append(Base64.getEncoder().encodeToString(authorization.getBytes(charset)))
            .append("&date=").append(URLEncoder.encode(date,"UTF-8"))
            .append("&host=").append(host);


        return MessageUtil.createSuccessMessage(httpUrl.toString());
    }

第三步 上传MP3文件

生成MP3文件

this.recorderManager = wx.getRecorderManager();
    const options = {
      duration: duration,
      sampleRate: 16000,
      numberOfChannels: 1,
      encodeBitRate: 48000,
      format: 'mp3',
    };
    this.recorderManager.start(options);

  
    this.recorderManager.onStop(res => {
      if (this.playAndRecordStatus == 'record') {
        //生成的临时mp3文件
        this.tempFile = res.tempFilePath;
       
         //可以直接调用上传MP3的问题
         new Promise(r=>{
            this.$emit("record-finished",{text:this.segmentItem.eng,pcmFile:this.tempFile})
         })
       
        this.playRecord();
        this.$apply();
      }
    });

创建socket并上传MP3文件

//上传MP3文件,pcmFile mp3文件的路径,text测评的文本
 checkAudio(pcmFile, text) {
 //把文本中的中文替换掉,如果有中文就会报错
      text = text.replaceAll(/[\u4E00-\u9FA5]/g, '');

   //获取服务端生成的url
    Check.getAuthUrl(wssUrl => {
      console.log(wssUrl);
      //创建socket
      this.socketTask = wx.connectSocket({
        url: wssUrl,
        complete: e => {
          console.log(e);
        }
      });

      this.socketTask.onError(e => {
        console.log('==onError=');
        console.log(e);
        //  this.readFile(pcmFile,0,1280,text)
      });
  
    
      this.socketTask.onOpen(e => {
      //socket 打开后开始上传文件
        const fs = wx.getFileSystemManager();
        fs.getFileInfo({
          filePath: pcmFile,
          complete: e => {
            this.readFileTime(fs, pcmFile, 0, 1280, text, e.size);
          }
        });
      
      });

     //处理socket返回的结果
      this.socketTask.onMessage(e => {
      
        var reslut = JSON.parse(e.data);
        //code!=0 测评出现错误
        if(reslut.code !=0){
            console.log(reslut);
            this.socketTask.close()
          return;
        }
        
        if(reslut&&reslut.data&&reslut.data.status == '2'){
          //测评完成,返回结果
          this.socketTask.close()
          const base64 = new Base64();
          var d = base64.decode(reslut.data.data);
          //处理返回的XML
          this.loadXML(d);
        }
      });
    });
  }

  readFileTime(fs, filePath, startIndex, length, text, lastTotal){
    //设置定时器,每40毫秒上传一次
    var intervalId =  setInterval(()=>{
        this.readFile(
            fs,
            filePath,
            startIndex,
            length,
            text,
            lastTotal
          );
          if(lastTotal<=length){
            clearInterval(intervalId)
            return;
          }
          startIndex =  startIndex + length;
          lastTotal =    lastTotal - length;


    },40)
  }

读取文件并上传

  readFile(fs, filePath, startIndex, length, text, lastTotal) {
 
    var isLast = false;
    if (length >= lastTotal) {
      length = lastTotal;
      isLast = true;
    }
    fs.readFile({
      filePath: filePath,
      position: startIndex,
      length: length,
      complete: e => {
       
      },
      success: e => {
      
        var baseData = wx.arrayBufferToBase64(e.data);

        if (!isLast) {
         
          if (startIndex == 0) {
            this.send(baseData, text, this.FRAME.STATUS_FIRST_FRAME);
          } else {
            if((lastTotal - length)==0){
          
              this.send(baseData, text, this.FRAME.STATUS_LAST_FRAME);
              return;
            }else{
               this.send(baseData, text, this.FRAME.STATUS_CONTINUE_FRAME);
            }
          }

        } else {

          this.send(baseData, text, this.FRAME.STATUS_LAST_FRAME);
        }
      }
    });
    //  var data = fs.readFileSync(filePath,startIndex,length)
  }

上传数据

  // 上传数据
  send(data, text, status) {
    var frame = '';
    switch (status) {
      case this.FRAME.STATUS_FIRST_FRAME:
            
        // 第一次数据发送:
        frame = {
          common: { app_id: this.config.appid },
          business: {
            //  服务类型指定 ise(开放评测)
            sub: 'ise',
            // 中文:cn_vip 英文:en_vip
            ent: 'en_vip',
            // 题型:句子朗读
            category: 'read_sentence',
            // 待评测文本编码 utf-8
            text: '\uFEFF'+text,
            check_type:"easy",
            // 待评测文本编码 utf-8 gbk
            tte: 'utf-8',
            rstcd: 'utf8',
            // 跳过ttp直接使用ssb中的文本进行评测(使用时结合cmd参数查看),默认值true
            ttp_skip: true,
            cmd: 'ssb',
            aue: 'lame',
            auf: 'audio/L16;rate=16000'
          },
          data: { status: 0 }
        };
        this.socketTask.send({
          data: JSON.stringify(frame),
          complete: e => {
          
          }
        });
        // 后续数据发送
        frame = {
          common: { app_id: this.config.appid },
          business: { aus: 1, cmd: 'auw', aue: 'lame' },
          data: { status: 1, data: data }
        };
       
        break;
      case this.FRAME.STATUS_CONTINUE_FRAME:
        
        frame = {
          common: { app_id: this.config.appid },
          business: { aus: 2, cmd: 'auw', aue: 'lame' },
          data: { status: 1, data: data }
        };
        break;
      case this.FRAME.STATUS_LAST_FRAME:
       
        frame = {
          common: { app_id: this.config.appid },
          business: { aus: 4, cmd: 'auw', aue: 'lame' },
          data: { status: 2, data: data }
        };
        break;
    }
   //上传数据
    this.socketTask.send({
      data: JSON.stringify(frame),
      complete: e => {
        console.log(e);
      }
    });
  }

解析xml


  loadXML(xml) {

   //把xml转成json
    var x2js = new X2JS();
    var json = x2js.xml2js(xml);
   
    var chapter = json.xml_result.read_sentence.rec_paper.read_chapter;
    var sentences = chapter.sentence;

    var ttsScore = {};

    ttsScore.totalScore = this.toIntScore(chapter._total_score)

    var words = [];
    if(sentences._total_score){
      words = words.concat(this.getWordList(sentences))
    }else{
      for (var i = 0; i < sentences.length; i++) {
           words = words.concat(this.getWordList(sentences[i]))
      }
    }

   

    ttsScore.wordList = words;
   
     //当前播放的文本拆成一个个的单词
    var wordItemArr = this.currentPlaySegment.wordItemArr

    var j = 0
    //对比返回的单词,和原文本的单词,给原文本的单词设置评分
    for(var i = 0 ; i < wordItemArr.length; i++){
      var wordItem = wordItemArr[i]
      if(j>=words.length){
        break;
      }
      var wordScore = words[j]
      var text = wordItem.text.toLowerCase().replaceAll(/[^a-zA-Z0-9_-]/g, '');
      var word = wordScore.word.toLowerCase().replaceAll(/[^a-zA-Z0-9_-]/g, '');
     
      if(text== word){
        j++
      }else{
        continue
      }


      if(wordScore.score>95){
        wordItemArr[i].score = 1;
      }else  if(wordScore.score>85){
         wordItemArr[i].score = 2;
      }else{
          wordItemArr[i].score = 3;
      }
    }

    

this.currentPlaySegment.totalScore = ttsScore.totalScore
//给原文本的句子设置评分
for(var i = 0 ; i< this.segmentItems.length ; i++){
  if(this.segmentItems[i].start == this.currentPlaySegment.start){
    this.segmentItems[i].totalScore = ttsScore.totalScore
    this.segmentItems[i].wordItemArr=wordItemArr
    break;
  }
}

this.$broadcast("show-score",this.currentPlaySegment)
this.$apply()
  }
  
  //给测评的结果乘20编程百分制
   toIntScore(score){
    return  parseInt(parseFloat(score)*20)
  }

扫码体验

相关文章

网友评论

      本文标题:微信小程序调用讯飞的音频评分接口

      本文链接:https://www.haomeiwen.com/subject/ngffyrtx.html