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

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

作者: 老祝读书 | 来源:发表于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