zoukankan      html  css  js  c++  java
  • 微信小程序 语音转换

    今天,终于成功使用nodejs研究出百度语音识别了。目前使用小程序最新录音管理api测试,小程序录音只支持aac,mp3格式,并且保持的是临时地址。而百度语音识别目前只支持pcm,wav,amr格式。因此服务端需要先存储好录音文件并经过一次音频转换。具体步骤如下:

    1、安装ffmpeg插件。我使用的windows系统,具体安装方法看http://blog.csdn.net/yy3097/article/details/51063950,该博主文章讲的非常详细,按照步骤走即可。这个插件是使用fluent-ffmpeg依赖的前提条件

    2、使用express生成器生成项目开发接口。需要提前安装好几个个依赖: 
    npm install fluent-ffmpeg –save-dev//mp3转wav依赖 
    npm install multiparty –save-dev//获取multipart/form-data上传文件依赖 
    npm install baidu-aip-sdk –save-dev//百度AI依赖

    routes文件夹下创建AiSpeechRecognition.js::

    var express=require('express');
    var router=express.Router();
    var fs=require('fs');
    var Multiparty =require('multiparty');
    var ffmpeg=require('fluent-ffmpeg');//创建一个ffmpeg命令
    var AipSpeechServer=require('baidu-aip-sdk').speech;
    
    //设置appid/appkey/appsecret
    var APP_ID = "申请的应用appid";
    var API_KEY = "申请的应用appkey";
    var SECRET_KEY = "申请的应用secretkey";
    
    // 新建一个对象,建议只保存一个对象调用服务接口
    var client =new AipSpeechServer(APP_ID, API_KEY, SECRET_KEY);
    router.post('/recognition', function(req, res, next){
      //生成multiparty对象,并配置上传目标路径
      var form =new Multiparty.Form({ uploadDir: './public/audio'});
      //上传完成后处理
      form.parse(req, function(err, fields, files){
        var filesTemp=JSON.stringify(files, null, 2);
        if(err){
          //console.log('parse error: '+err);
          res.json({
            ret: -1,
            data:{},
            msg: '未知错误'
          });
        }else{
          //console.log('parse files: '+filesTemp);
          var inputFile=files.file[0];
          var uploadedPath=inputFile.path;
          var command=ffmpeg();
          command.addInput(uploadedPath)
          //.saveToFile('./public/audio/222.wav')//保存编码文件到文件夹 --保存成wav是可以的,但是pcm报错
          .saveToFile('./public/audio/16k.wav')
          .on('error', function(err){
            console.log(err)
          })
          .on('end', function(){
            //调用百度语音合成接口
            var voice = fs.readFileSync('./public/audio/16k.wav');
            var voiceBuffer=new Buffer(voice);
            client.recognize(voiceBuffer, 'wav', 16000).then(function(result){
              //console.log(result);
              var data=[];
              if(result.err_no===0){
                data=result.result;
              }
              res.json({
                ret: result.err_no,
                data: {
                  data: data
                },
                msg: result.err_msg
              });
            }, function(err){
              console.log(err);
            });
            //语音识别 end
    
            //删除上传的临时音频文件
            fs.unlink(uploadedPath, function(err){
              if(err){
                console.log(uploadedPath+'文件删除失败');
                console.log(err);
              }else{
                console.log(uploadedPath+'文件删除成功');
              }
            });
            //删除mp3转成wav格式的音频
            fs.unlink('./public/audio/16k.wav', function(err){
              if(err){
                console.log('16k.wav文件删除失败');
                console.log(err);
              }else{
                console.log('16k.wav文件删除成功');
              }
            });
          });
        }
      });
    });
    
    module.exports=router;
    

     前端代码

    const recorderManager = wx.getRecorderManager();
    Page({
      data: {
        result: '',//语音识别结果
        recording: false//是否正在录音
      },
      //开始录制语音
      startRecord(e){
        this.setData({recording: true});
        recorderManager.start({
          duration: 60000,//百度最多支持60s语音
          sampleRate: 16000,
          //encodeBitRate: 48000,
          numberOfChannels: 1,//必须指定录音通道数
          format: 'mp3'
        });
        recorderManager.onStart(() => {
          //console.log('recorder start')
        });
      },
      //停止录音
      stopRecord(e) {
        let that=this;
        this.setData({ recording: false });
        recorderManager.stop();//停止录音
        recorderManager.onStop((res)=>{
          const { tempFilePath } = res;
          //uploadfile start
          wx.uploadFile({
            url: 'http://你的ip:3000/baiduAI2/recognition',
            filePath: tempFilePath,
            name: 'file',
            success(res){
              //console.log(res);
              let data=typeof res.data==='string'? JSON.parse(res.data) : res.data;
              if(data.ret==0){
                //console.log(data.data.data[0])
                that.setData({
                  result: data.data.data[0]
                });
              }else{
                that.setData({
                  result: '我不知道你在说什么'
                });
              }
            },
            fail(err){
              console.log(err);
            }
          });
        })
      }
    })
    <view class="title">语音识别</view>
    <view class="test" bindtap="startRecord" wx:if="{{!recording}}">开始录音</view>
    <view class="test" bindtap="stopRecord" wx:if="{{recording}}">停止录音</view>
    
    <view class="result" wx:if="{{result}}">
    <view class="title">语音识别结果:</view>
    {{result}}
    </view>
  • 相关阅读:
    什么是语义化的HTML?有何意义?为什么要做到语义化?
    Doctype作用?严格模式与混杂模式如何区分?它们有何差异?
    js和jq中常见的各种位置距离之offsetLeft和position().left的区别(四)
    js和jq中常见的各种位置距离之offset和offset()的区别(三)
    js和jq中常见的各种位置距离之offset()和position()的区别(二)
    js和jq中常见的各种位置距离之offsetLeft/clientLeft/scrollLeft (一)
    剖析js中的数据类型
    js数组去重几种方法
    SSE and Websocket
    鲜为人知的空元素╮(╯▽╰)╭
  • 原文地址:https://www.cnblogs.com/xqdotnet/p/8276545.html
Copyright © 2011-2022 走看看