百度短语音识别api(JavaScript调用)
前言
百度官方网不提倡用js来调用他的短语音识别接口,因为会跨域。所以网上大多数都是使用各种语言来实现这个需求,找了好久都没有相关博客可供参考,所以做个记录。这个跨域问题的解决方案就是配置代理就行,我这开发环境使用的是webpack的proxyTable设置来跨域。在部署环境可以换为用nginx来配置代理。
页面效果预览
页面效果:
页面效果(GIF):
配置代理
在开发环境我们在\config\index.js中配置代理信息以解决跨域问题:
proxyTable: {
'/oauth': {
target: 'https://openapi.baidu.com',//后端接口地址
changeOrigin: true,
pathRewrite: {
'^/oauth': '/oauth'
}
},
'/server_api': {
target: 'https://vop.baidu.com',//后端接口地址
changeOrigin: true,
pathRewrite: {
'^/server_api': '/server_api'
}
},
},
获取百度鉴权机制token请求
百度官方获取token文档鉴权认证机制:
/**
* @params String client_id
* @params String client_secret
* @params String grant_type
*/
function getBaiduTokenAjax(postData,fn1,fn2) {
axios.post('/oauth/2.0/token',qs.stringify(postData))
.then(function(data){
fn1 && fn1(data);
})
.catch(function(err){
fn2 && fn2(err.message);
});
}
百度短语音识别请求
百度短语音识别官方文档短语音识别api:
/**
* @params String format
* @params Number rate
* @params Number dev_pid
* @params Number channel
* @params String token
* @params String cuid(baidu_workshop)
* @params String len
* @params base64 speech (FILE_CONTENT)
* @returns Promise
*/
function getBaiduServer_api_Ajax(postData,fn1,fn2) {
axios.post('/server_api',postData)
.then(function(data){
fn1 && fn1(data);
})
.catch(function(err){
fn2 && fn2(err.message);
});
}
获取百度Access Token
在初始化页面的时候或者用户需要用到语音识别的时候获取百度的token,写死也可以,token的有效期是一个月,建议实时获取。详情可看官方的获取方式AppID、API Key、Secret Key,并通过请求鉴权接口换取 token
/*
* 获取百度语音token
* */
getBaiduToken: function () {
/**
* @params String client_id
* @params String client_secret
* @params String grant_type
*/
getBaiduTokenAjax({
client_id: '填上自己的API Key', //必须参数,应用的API Key
client_secret: '填上自己的Secret Key', //必须参数,应用的Secret Key
grant_type: 'client_credentials', //必须参数,固定为client_credentials
},data=>{
//保存百度Token
baiduToken = data.data.access_token
})
},
调用短语音识别接口
支持音频格式:pcm、wav、amr、m4a
音频编码要求:采样率 16000,16bit 位深,单声道
(只能在https或者localhost中录音,在http或者ip访问是不行的)
在本地获取录音文件后转为base64,我这边使用的是recorderx录制语音。使用wavesurfer进行了音频可视化效果,可参考相关官网文档
//录制完成获取录制的WAVBlob文件
var WAVBlob = this.rc.getRecord({
encodeTo: ENCODE_TYPE.WAV,
});
/*
* blob转base64
* */
let blobToDataURL=(blob, callback)=> {
var a = new FileReader();
a.onload = function (e) { callback(e.target.result.split('data:audio/wav;base64,')[1]); }
a.readAsDataURL(blob);
}
blobToDataURL(WAVBlob,(base_64)=>{
let vaudioItem =
{
isMyMasg: true,
masgType: 'vaudio',
headL: that.$store.state.logInfo.headimgurl?that.$store.state.logInfo.headimgurl:require('../../static/img/testGame/userBai.png'),
name: that.$store.state.logInfo.nickName?that.$store.state.logInfo.nickName:'我',
audioUrl: WAVBlob,
isPlayAudio: false,
data: null
// data: data_data.data.result[0]
}
that.datas=that.datas.concat(vaudioItem);
/**
* @params String format
* @params Number rate
* @params Number dev_pid
* @params Number channel
* @params String token
* @params String cuid(baidu_workshop)
* @params String len
* @params base64 speech (FILE_CONTENT)
* @returns Promise
*/
getBaiduServer_api_Ajax({
speech: base_64,
len: WAVBlob.size, //是文件大小,不是时长
dev_pid: 1537,
cuid: 'zhongwenhui',
rate: 16000,
token: baiduToken,
channel: 1,
format: 'wav',
lan: 'ct',
},baidu_data=>{
//清除录音给下一个录音初始化
this.rc.clear()
if (baidu_data.data.err_msg == 'success.'){
alert('识别结果:'+baidu_data.data.result[0])
}else {
alert('识别失败')
};
})
})
使用本地文件测试接口
这里再提供个加载本地wav文件语音识别方法,可下载文档中的相关文件16k.wav文件下载
/*
* 这里再提供个加载本地wav文件语音识别方法,可下载文档中的相关文件
* */
var file = new Audio(require('../../static/img/16k.wav'))
let base64Data;
let loadSound = (url)=> {
var request = new XMLHttpRequest(); //建立一个请求
request.open('GET', url, true); //配置好请求类型,文件路径等
request.responseType = 'arraybuffer'; //配置数据返回类型
// 一旦获取完成,对音频进行进一步操作,比如解码
request.onload = function() {
console.log(request.response)
var binary = '';
var bytes = new Uint8Array( request.response );
var len = bytes.byteLength;
for (var i = 0; i < len; i++) {
binary += String.fromCharCode( bytes[ i ] );
}
base64Data = window.btoa( binary );
getBaiduServer_api_Ajax({
speech: base64Data,
len: len,
dev_pid: 1537,
cuid: 'zhongwenhui',
rate: 16000,
token: data.data.access_token,
channel: 1,
format: 'wav',
lan: 'ct',
},baiduServer_data=>{
console.log(baiduServer_data)
})
}
request.send();
}
loadSound(require('../../static/img/16k.wav'))