美文网首页
手机录入语音翻译为文字

手机录入语音翻译为文字

作者: 呼噜噜睡 | 来源:发表于2024-07-15 08:16 被阅读0次

    也许偶尔就会有这样的需求,我是说如果,就是需要在手机端录入语音,然后发往后端,转为文字,再做对应的逻辑处理。是不是一听就很想有copy的想法呢,是的,就是有可以copy的东西。

    首先整体思路是用最小的代价,实现我们的功能。那么手机端的语音录入,我们可以借助于微信小程序去实现,小程序内部有api可以调用语音输入。然后将得到的语音发往后端,后端呢,去调用百度的语音接口,就完成了语音翻译。

    好了,接下来开启我们的代码之旅吧。

    首先需要明确一个概念,在微信的体系内,如何去标识一个用户呢,那就是openId,单个用户的openId在某个微信小程序下是唯一的,我们就用它去标识。那些微信小程序的注册和申请、域名配置啥、小程序开发工具下载啥的咱们就跳过吧。还有一个,如果我们没有https的备案域名,开发的时候也不要紧,只要我们在开发者工具里面将域名校验给关闭掉就可以。

    第一步,获取openId,这个任务自然是交给后端去做了。首先在微信小程序端,会获得一个code,这个code只有5分钟的有效期,可以根据code去兑换openId,小程序端的逻辑如下:

    App({
      onLaunch() {
        // 登录
        wxUtil.login(code => {//code自动获取
          console.log(code)
          let paramJson = {code: code};
          wxUtil是一个工具类,包装了微信的http请求,不用关注
          wxUtil.post('wx/appletcode2openid', paramJson, wxUtil.audio, { isShowLoading: true }, (result) =>{
            console.log(result);
            wxUtil.setOpenIdByStorage(result.data.openID);
          });
         });
      },
      globalData: {
        userInfo: null
      }
    })
    

    对应的后端获取openId的逻辑:

    /**
         * 微信小程序根据code获取openId等信息
         *
         * @return
         * @throws
         * @throws IOException
         */
    public static WxAppletAuthResultVO getOpenIdByAuthCodeOnApplet(String appId, String appSecret, String code) {
        if(appId==null||appId.trim().isEmpty()){
            throw new RuntimeException("appId为空");
        }
        if(appSecret==null||appSecret.trim().isEmpty()){
            throw new RuntimeException("appSecret为空");
        }
        if(code==null||code.trim().isEmpty()){
            throw new RuntimeException("code为空");
        }
        try {
            String url = "https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code".replace("APPID", appId).replace("SECRET",appSecret).replace("JSCODE", code);
            String result = HttpUtil.doPost(url, null);
            if(result==null||result.isEmpty()){
                throw new RuntimeException("微信小程序根据code获取openId等信息返回为空");
            }
            
            return JSON.parseObject(result, WxAppletAuthResultVO.class);
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
        return null;
    }
    

    有了openId,下面我们就可以获取录入的语音了,然后将语音和openId一起发往后端。微信小程序端的js代码:

    const wxUtil = require('../../utils/wxutil.js');
    const recorderManager = wx.getRecorderManager();
    const innerAudioContext = wx.createInnerAudioContext({"useWebAudioImplement": true});
    
    recorderManager.onStop((res) => {//注意  给recorderManager注册了事件  后面会触发
      var tempFilePath = res.tempFilePath;//音频文件地址
      const fs = wx.getFileSystemManager();
      fs.readFile({//读取文件并转为ArrayBuffer
        filePath: tempFilePath,
        success(res) {
          wx.showLoading({
            title: '正在语音识别中...',
          });
          const base64Data = wx.arrayBufferToBase64(res.data);
          var fileSize = res.data.byteLength ;
          var paramJson = {
            format: 'pcm',
            sampleRate: 16000,
            encodeBitRate: 48000,
            data: base64Data
          };
          wxUtil.post('wx/audioupload', paramJson, wxUtil.audio, { isShowLoading: true }, (result) =>{
            console.log( result);
          });
        }
      })
    });
    
    Page({
      data: {},
      onLoad() {},
      //语音识别
      handleTouchStart: function(e){
        //录音参数
        const options = {
          sampleRate: 16000,
          numberOfChannels: 1,
          encodeBitRate: 48000,
          format: 'pcm'
        }
        //开启录音
        recorderManager.start(options);
        wx.showLoading({
          title: '正在录音中...',
        });
      },
      handleTouchEnd: function(e){
        recorderManager.stop();//stop之后就会触发onStop事件
      }
    })
    

    这样,我们是直接把语音文件转为base64的字符串,发往后端。后端就去调用百度的接口转为文字。百度的接口虽然付费,但是有免费调用量,需要先注册账号,申请应用,然后调用。

    调用之前需要先获取百度语音的accessToken:

    public static BaiduAudioAccessTokenVO getAccessToken(String apiKey,String secretKey){
        Map<String, String> parameters = new HashMap<>();
        parameters.put("grant_type","client_credentials");
        parameters.put("client_id",apiKey);
        parameters.put("client_secret",secretKey);
        String response = HttpUtil.sendPost("https://aip.baidubce.com/oauth/2.0/token",parameters);
        log.info("调用百度语音accessToken返回:" + response);
        BaiduAudioAccessTokenVO baiduAudioAccessTokenVO = JSON.parseObject(response, BaiduAudioAccessTokenVO.class);
        ParamCheckUtil.objectNull(baiduAudioAccessTokenVO,"调用接口未获取到accessToken");
        ParamCheckUtil.stringEmpty(baiduAudioAccessTokenVO.getAccess_token(),"调用接口未获取到accessToken");
        return baiduAudioAccessTokenVO;
    }
    

    接着调用百度语音接口:

    public String transToText(String base64Audio,Integer len,String format,Integer rate) {
      //1参数校验
      ParamCheckUtil.stringEmpty(base64Audio,"语音文件为空");
      ParamCheckUtil.stringEmpty(format,"语音格式不能为空");
      ParamCheckUtil.notTrue(
              "pcm".equalsIgnoreCase(format)
                      || "wav".equalsIgnoreCase(format)
                      || "amr".equalsIgnoreCase(format),"语音文件格式不符合要求");
    
      //2 获取百度语音accessToken
      String accessToken = this.getAccessToken();
      //3 语音转为文字
      BaiduAudio2TextDTO audio2TextDTO = new BaiduAudio2TextDTO();
      audio2TextDTO.setFormat(format);
      audio2TextDTO.setRate(rate);
      audio2TextDTO.setCuid(baiduAudioProperties.getAppID());
      audio2TextDTO.setToken(accessToken);
      audio2TextDTO.setLen(len);
      audio2TextDTO.setBase64Audio(base64Audio);
      String text = BaiduAudioUtil.audio2Text(audio2TextDTO);
      log.info("翻译文字为:" + text);
      return text;
    }
    
    //工具类
    public static String audio2Text(BaiduAudio2TextDTO baiduAudio2TextDTO){
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("format",baiduAudio2TextDTO.getFormat());
        parameters.put("rate",baiduAudio2TextDTO.getRate());
        parameters.put("channel",1);
        parameters.put("cuid",baiduAudio2TextDTO.getCuid());
        parameters.put("token",baiduAudio2TextDTO.getToken());
        parameters.put("speech",baiduAudio2TextDTO.getBase64Audio());
        parameters.put("len",baiduAudio2TextDTO.getLen());
        String response = HttpUtil.sendPostJson("https://vop.baidu.com/server_api",JSON.toJSONString(parameters));
        log.info("语音转换接口返回:" + response);
        ParamCheckUtil.stringEmpty(response,"语音转换接口返回为空");
        BaiduAudio2TextVO textVO = JSON.parseObject(response, BaiduAudio2TextVO.class);
        return textVO.getResult().get(0);
    }
    

    就这样,就完成了。

    相关文章

      网友评论

          本文标题:手机录入语音翻译为文字

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