node对接百度语音识别

官方文档
第一步
  • 进入控制台
  • 人工智能
  • 语音识别
  • 先创建应用:获得appid、apikey、secritkey
第二步
  • 创建一个文件夹test
  • cd test 进入文件夹
  • 创建index.js文件
  • 安装依赖:npm i baidu-aip-sdk
环境配置说明
  • 百度语音需要的格式是pcm,所以需要转码

  • 转码用的是ffmpeg:
    1、由于node版本更新后,npm上的ffmpeg 包使用不上,则采用命令行使用官方下载的 build 包
    2、官方地址:点这里:http://ffmpeg.org/ffmpeg.html
    3、百度语音使用ffmpeg的使用说明:点这里:https://ai.baidu.com/docs#/ASR-Tool-convert/ec5eb053

  • 这里比较烦的是ffmpeg的配置,由于linux和Windows不同,所以配置环境变量的方式也不一样

  • 配置windows:设置命令行执行指令

set path=D:\dev\ffmpeg-20180903-23fe072-win64-static\bin;%path%
ffmpeg -y -i <音频路径> -acodec pcm_s16le -f s16le -ac 1 -ar 16000 <转码后存放音频路径>

  • 配置linux:设置命令行执行指令

export PATH=$PATH:/data/ffmpeg/ffmpeg-git-20180831-64bit-static
ffmpeg -y -i <音频路径> -acodec pcm_s16le -f s16le -ac 1 -ar 16000 <转码后存放音频路径>

注释:由于linux涉及到用户权限问题,每一个node子进程的用户不一样,会导致找不到ffmpeg模块,所以需要将ffmpeg设置为永久性全局环境变量

  • 如何在代码中执行指令:nodejs给我们提供了,子进程的方法,官方文档有提供示例
const exec = require('child_process').exec; // node自带的子进程方法
// 代码中自执行,执行时会出现编码问题,设置参数,编码格式gbk或者utf-8
// 这句是设置ffmpeg路径,注意到bin目录即可
exec('set path=D:\\dev\\ffmpeg-20180903-23fe072-win64-static\\bin;%path%', { 'encoding': 'GBK' });
  • 代码示例如下:百度ai(人工智能)接入
const BD_API_SDK = require('baidu-aip-sdk'); // 引入百度api sdk
const AipSpeechClient = BD_API_SDK.speech; // 获取客户端
const incfg = {
  appid: appid, apikey: apikey, secretkey: secretkey,
  inEncoding: 'GBK', // 设置dos命令行的编码格式
}; // 指定参数

const { appid, apikey, secretkey, inEncoding } = incfg;

// 实例化客户端,建议只保存一个对象调用服务接口
const client = new AipSpeechClient(appid, apikey, secretkey);
const fs = require('fs'); // node文件系统
const os = require('os'); // 系统参数
const util = require('util');
const child_process = require('child_process'); // node子进程
const log = require('../util/log')('logic/baidu'); // 日志

export default class Baidu {
  static async parse(data) {
    let RS = null;
    try {
      if (!data) { return RS; }
      const indos = [];
      const entry = `${data.filePath}${data.fileName}`;
      const output = `${data.filePath}${new Date().getTime()}.pcm`;

      if (os && os.EOL === '\r\n') { // Windows系统
        indos.push('set path=D:\\dev\\ffmpeg-20180903-23fe072-win64-static\\bin;%path%');
        indos.push(`ffmpeg -y  -i ${entry} -acodec pcm_s16le -f s16le -ac 1 -ar 16000 ${output}`);
      } else { // Linux系统
        indos.push('export PATH=$PATH:/data/ffmpeg/ffmpeg-git-20180831-64bit-static');
        indos.push(`ffmpeg -y  -i ${entry} -acodec pcm_s16le -f s16le -ac 1 -ar 16000 ${output}`);
      }
      log.debug(`parse entry:${entry}; output:${output}; indos:${util.inspect(indos)}`);

      await toFFmpeg(indos[0]);
      await toFFmpeg(indos[1]);
      log.debug(`toFFmpeg 转换完成`);

      const voice = fs.readFileSync(output);
      log.debug(`读取文件 voice:${typeof voice}`);

      if (voice) {
        const voiceBuffer = new Buffer(voice); // 转换Buffer数据流
        // 调用百度语音api
        RS = await new Promise((resolve, reject) => {
          client.recognize(voiceBuffer, 'pcm', 16000).then((rs) => {
            log.debug(`recognize rs:${util.inspect(rs)}`);
            resolve(rs);
          }, function (err) {
            log.debug(`recognize err:${util.inspect(err)}`);
            reject(err);
          });
        });
      }
      return RS;
    } catch (e) {
      log.error('baidu parse error:', e.message);
      return RS;
    }
  }

  /**
   * 命令行调用ffmpeg指令,每次只能运行一条指令
   * 注:node在Linux下运行多个子程序,每个子程序对于一个用户(类似于作用域),导致设置的临时环境变量,运行命令时找不到模块或者程序
   * @param {String} instructs 指令
   * @param {String} encoding 编码格式,缺省gbk
   * @returns {Object}
   */
  static toFFmpeg(...args /* instructs, encoding */) {
    console.log(`toFFmpeg arguments:${util.inspect(arguments)}; args[0]:${args[0]}; args[1]:${args[1]}`);
    if (!args || args.length <= 0) return '';

    console.log(`toFFmpeg start`);
    return new Promise((resolve, reject) => {
      console.log(`toFFmpeg start Promise`);

      child_process.exec(args[0], { encoding: args[1] || 'GBK' }, (error, stdout, stderr) => {
        console.log(`toFFmpeg error:${error}; stdout:${stdout && stdout.toString()}; stderr:${stderr};`);

        if (error) {
          reject(false);
        } else {
          resolve({ error, stdout, stderr });
        }
      });
    });
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值