node对接百度语音识别
官方文档
第一步
- 进入控制台
- 人工智能
- 语音识别
- 先创建应用:获得appid、apikey、secritkey
第二步
- 创建一个文件夹test
- cd test 进入文件夹
- 创建index.js文件
- 安装依赖:npm i baidu-aip-sdk
示例代码说明
- 百度语音需要的格式是pcm,所以需要转码
转码用的是ffmpeg:
- 由于node版本更新后,npm上的ffmpeg 包使用不上,则采用命令行使用官方下载的 build 包
- 官方地址:点这里:http://ffmpeg.org/ffmpeg.html
- 百度语音使用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%
call 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 【转码后存放音频路径】
如何在代码中执行指令:
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 BDAIPSDK = require('baidu-aip-sdk');
const AipSpeechClient = BDAIPSDK.speech;
const incfg = {
appid: appid,
apikey: apikey,
secretkey: secretkey
};
// 新建一个对象,建议只保存一个对象调用服务接口
const client = new AipSpeechClient(incfg.appid, incfg.apikey, incfg.secretkey);
const fs = require('fs');
const os = require('os');
const exec = require('child_process').exec; // node自带的子进程方法
/* 设置dos命令行的参数编码格式 */
const inEncoding = "GBK";
const log = require('../util/log')('logic/baidu');
export default class Baidu {
static async parseAudio(data) {
let rc = null;
try {
if (!data) {
return;
}
let indos = '';
let indos2 = '';
const entry = `${data.filePath}${data.fileName}`;
const outPath = `${data.filePath}${new Date().getTime()}.pcm`;
if (os && os.EOL === '\r\n') {
indos = 'set path=D:\\dev\\ffmpeg-20180903-23fe072-win64-static\\bin;%path%';
indos2 = `call ffmpeg -y -i ${entry} -acodec pcm_s16le -f s16le -ac 1 -ar 16000 ${outPath}`;
} else {
indos = 'export PATH=$PATH:/data/ffmpeg/ffmpeg-git-20180831-64bit-static';
indos2 = `ffmpeg -y -i ${entry} -acodec pcm_s16le -f s16le -ac 1 -ar 16000 ${outPath}`;
}
log.debug('parse param:', { entry, outPath, indos, indos2 });
await new Promise((resolve, reject) => {
exec(indos, { 'encoding': inEncoding });
exec(indos2, { 'encoding': inEncoding }, function (error, stdout, stderr) {
/* log.debug('indos2',{error,stdout: iconv.decode(stdout, inEncoding),stderr: iconv.decode(stderr, inEncoding)}); */
if (error) {
reject(error);
} else {
resolve(stderr);
}
});
});
const voice = fs.readFileSync(outPath);
log.debug('voice:', voice);
if (voice) {
const voiceBuffer = new Buffer(voice);
rc = await new Promise((resolve, reject) => {
client.recognize(voiceBuffer, 'pcm', 16000).then(function (result) {
log.debug('parse result:', result);
resolve(result);
}, function (err) {
log.debug('parse err:', err);
reject(err);
});
});
}
} catch (e) {
log.error('baidu parse error:', e.message);
}
return rc;
}
}