是时候静下心来写写东西了,记录一下自己的日常,梳理梳理自己掌握的知识。
今天,上头给了个活,让我用node结合 AI百度的语音识别客户端,测试一下百度开放的语音识别接口的准确性,由于这个接口规定音频必须为60s内【60s内都是说大话,明明只有30s内才能用】,所以我需要把我测试的10min的音频切割成10s一份(这时候我还很开心的在做着切割,脑补一会得到一个完美的音频转成文字的.txt文件,完全没想到会被node戏弄一把)。要把这么多分合起来转成一份.txt,需要用:
var path = require('path');
var filePath = path.resolve('/Users/yangjinggang/tool/cut/speech-vad-demo/output_pcm/');//解析需要遍历的文件夹 由于是mac所以是这个路径
fs.readdir(filePath,function(err,files){
if(err){
...
}else{
files.forEach(string =>{
//使用AI百度接口实现
//并写入 .txt文件
})
}
}
我按照平时写java的习惯,读取一行直接写入txt文件内,然后!!!我发现得到的文本里面的内容毫无章法,根本就对不上音频,那怎么办,咱们怎么能去摔锅百度呢,必然是自己使用姿势不对,所以去打印了下日志,发现虽然文件名是排好序有序进行的,但是写入操作是异步的,导致结果稀奇古怪。
那我这么刚的人肯定不能怂啊,我得找到办法,查到的资料是用timeout嵌套来达到同步的效果,但是我总感怪怪的,一个小程序员的直觉告诉我,我得自己想个办法。方法如下:【设置的值为i 数组为result】
//设置一个值,以及数组 一个用来标记当前操作,一个用来存储当前操作得到的值,当进行完后再把数组中的值按顺序写入.txt
let i=0;
f.forEach(string =>{
let index = i;
client.recognize(voiceBuffer,'pcm',8000).then(function (result) {//AI百度的音转字工具
//具体操作省略
if(!result){
results[index] = "++++++++err++++++++";
has_recognize_num++;
return;// 如果result没有得到结果又没有错,就返回结果;开始下一次操作
}
//具体操作省略
},function (err) {
console.log(err);
results[index] = "++++++++err++++++++";
has_recognize_num++;
});
i++;
});
这样就能即使用异步,又生成了正确的结果,很舒服
但是有的时候需要强制同步,不能使用异步,就可以用Promise,让代码层次看起来更加清晰,切异步变为同步,
将上述方法改为使用Promise【bluebrid】(只列出最关键的部分):
var fs = Promise.promisifyAll(require('fs'));
fs.readdirAsync(filePath).then(A => {
A = A.reverse();
return Promise.each(A, (s, index) => {
return fs.readFileAsync(`/Users/yangjinggang/tool/cut/speech-vad-demo/output_pcm/` + s).then(path => {
// console.log(path);
let voiceBuffer = new Buffer(path);
return client.recognize(voiceBuffer, 'pcm', 8000).then(function (result) {
let data = result.result;
if (!data) {
return new Promise((resolve, reject) =>
writerStream.write(data[0] + ">>>>>" + 'have not data' + "<<<<<<", 'UTF8', () => {
console.log('写入失败');
return resolve();
}));
}
console.log(data);
return new Promise((resolve, reject) => writerStream.write(data[0].toString()+'。', 'UTF8', () => {
console.log('完成写入');
return resolve();
}));
}, function (err) {
console.log(err);
writerStream.write(">>>>>" + "error" + "<<<<<<", 'UTF8');
});
})
});
});
x.then() 方法代表着x已经完成,在()内写入需要同步的方法继续,要return new Promise(function(resolve,reject)) 其中resolve()代表完成成功,reject()代表失败。