微信小程序实现语音识别详细过程分享

使用微信小程序实现语音识别功能的过程中,爬了很多坑,主要的原因竟然是微信小程序发展太快,网上的资料跟不上,旧的一些资料让自己走了错误的路线,希望后面的小伙伴不要在走弯路,所以分享给大家。

语音识别整体思路

  • 使用微信小程序录音功能,获取录音文件
  • 发送录音文件到后台服务器
  • 后台服务器对录音文件进行转码,推荐转码成pcm格式
  • 调用百度语音识别 API 进行语音识别
  • 后台服务器获取 API 返回的识别结果
  • 返回识别结果给微信小程序

看一个图加深记忆

微信小程序实现语音识别详细过程分享_第1张图片
image

语音转换

为什么会有语音转换这一步呢?简单说就是微信小程序录音文件的格式,各大语音转换 API 都不支持,不转也用不了啊。

微信小程序从基础库 1.6.0 开始,录音推荐使用 wx.getRecorderManager() 方法,录音文件的格式可以自己指定,有 aac 和 mp3 两种格式。

由于之前没有了解过音频转换这块,所以直接上网搜索微信小程序语音转换的相关资料,此时坑已经挖好,并且跳进去了。

网上大部分资料都是说,微信小程序的录音文件是变种的 silk 文件(可能以前的小程序确实是这样),需要特殊处理,然后使用 silk-v3-decoder 或者 ffmepg 进行转码,经过各种折腾后发现还是不行,在坑里徘徊不前好久。

最后真是一个无意识的操作发现了转机,录音文件我一直用的 mp3 格式,双击后居然可以正常打开,并且播放声音,这是什么鬼?你不是变种得么,好吧,你居然是个正常"人"。

一切都了然了,微信小程序可能对这块做了优化,减少了复杂的处理,就这样一切都通顺了之后,剩下的就简单了。

微信小程序代码

  • 录音开始
/** 录音开始 */
function speechStart(e,that) {
    const recorderManager = wx.getRecorderManager();
    const options = {
        duration: 10000,
        sampleRate: 16000,
        numberOfChannels: 1,
        encodeBitRate: 64000,
        format: 'mp3',
        frameSize: 50
    }
    recorderManager.start(options);
}
  • 录音结束后,调用后台服务
/** 语音识别 */
function speechRecognition (that,res) {
  console.log("语音识别");
  wx.uploadFile({
    url: API_URL,
    filePath: res.tempFilePath,
    name: 'file',
    formData: {
      'user': 'test'
    },
    success: function (res) {
      console.log(res);    console.log(res.data);
    },
    fail:function(){
      console.log("语音识别失败");
    }
  })
}

后台服务器 Java 实现

  • 添加 mp3plugin.jar

    百度网盘:链接: https://pan.baidu.com/s/1pLZHzJl 密码: zxgc

  • 添加百度 API 依赖

    
        com.baidu.aip
        java-sdk
        4.1.0
    
  • 测试代码
    // 设置APPID/AK/SK,注册百度语音识别API即可获取
    public static final String APP_ID = "******";
    public static final String API_KEY = "******";
    public static final String SECRET_KEY = "******";

    /**
     * @Description TODO
     * @return
     * @author liuyang
     * @blog http://www.pqsky.me
     * @date 2018年1月27日
     */
    @RequestMapping(value = "/speechRecognition")
    public Object speechReco(HttpServletRequest request) {
        MultipartFile file = ((MultipartHttpServletRequest) request).getFile("file");
        try {
            byte[] pcmBytes = mp3Convertpcm(file.getInputStream());
            JSONObject resultJson = speechBdApi(pcmBytes);
            System.out.println(resultJson.toString());
            if (null != resultJson && resultJson.getInt("err_no") == 0) {
                return resultJson.getJSONArray("result").get(0).toString().split(",")[0];
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return "";
    }

    /**
     * @Description MP3转换pcm
     * @param mp3Stream
     *            原始文件流
     * @return 转换后的二进制
     * @throws Exception
     * @author liuyang
     * @blog http://www.pqsky.me
     * @date 2018年1月30日
     */
    public byte[] mp3Convertpcm(InputStream mp3Stream) throws Exception {
        // 原MP3文件转AudioInputStream
        AudioInputStream mp3audioStream = AudioSystem.getAudioInputStream(mp3Stream);
        // 将AudioInputStream MP3文件 转换为PCM AudioInputStream
        AudioInputStream pcmaudioStream = AudioSystem.getAudioInputStream(AudioFormat.Encoding.PCM_SIGNED,
                mp3audioStream);
        byte[] pcmBytes = IOUtils.toByteArray(pcmaudioStream);
        pcmaudioStream.close();
        mp3audioStream.close();
        return pcmBytes;
    }

    /**
     * @Description 调用百度语音识别API
     * @param pcmBytes
     * @return
     * @author liuyang
     * @blog http://www.pqsky.me
     * @date 2018年1月30日
     */
    public static JSONObject speechBdApi(byte[] pcmBytes) {
        // 初始化一个AipSpeech
        AipSpeech client = new AipSpeech(APP_ID, API_KEY, SECRET_KEY);
        // 可选:设置网络连接参数
        client.setConnectionTimeoutInMillis(2000);
        client.setSocketTimeoutInMillis(60000);
        // 调用接口
        JSONObject res = client.asr(pcmBytes, "pcm", 16000, null);
        return res;
    }

总结

以上代码都是作为测试用例,帮助理清整体思路和实现简单的调用,更详细的设计就需要结合具体的业务了,希望可以帮到看到的人。

你可能感兴趣的:(微信小程序实现语音识别详细过程分享)