科大讯飞语音合成WebApi

本来一开始是因为项目中需要用到听书功能,就想用科大讯飞的语音合成Web API,本来官方文档已经提供了一个完整demo,不过根据自己的需求还是弄了一天左右o(╥﹏╥)o
官方文档: https://www.xfyun.cn/doc/tts/online_tts/API.html

根据文档接口调用流程
使用WebSocket请求接口与返回

  • 接口授权
function getAuthStr(date) {
    let signatureOrigin = `host: ${config.host}\ndate: ${date}\nGET ${config.uri} HTTP/1.1`
    let signatureSha = CryptoJS.HmacSHA256(signatureOrigin, config.apiSecret)
    let signature = CryptoJS.enc.Base64.stringify(signatureSha)
    let authorizationOrigin = `api_key="${config.apiKey}", algorithm="hmac-sha256", headers="host date request-line", signature="${signature}"`
    let authStr = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(authorizationOrigin))
    return authStr
}

  • 创建wssUrl
// 获取当前时间 RFC1123格式
let date = (new Date().toUTCString())
let wssUrl = config.hostUrl + "?authorization=" + getAuthStr(date) + "&date=" + date + "&host=" + config.host
let ws = new WebSocket(wssUrl)
  • 接口数据传输
    请求参数一共有三个
  • common: app_id,见账号控制台
  • business:业务参数,只有两个参数是必填的
    • aue:音频编码格式,当需要生成mp3格式时需要(aue=lame且sfl=1)
    • vcn:发音人
  • data:需要合成的文本
//连接建立完毕,读取数据识别
    ws.on('open', ()=>{
        log.info("websocket connect!")
        // send(text) //传输数据
        let frame = {
            "common": {
                "app_id": config.appid
            },
            // 填充business
            "business": {
                "aue": "lame",
                "auf": "audio/L16;rate=16000",
                "vcn": "xiaoyan",
                "tte": "UTF8",
                "sfl": 1
            },
            // 填充data
            "data": {
                "text": Buffer.from(text).toString('base64'),
                "status": 2
            }
        }
        ws.send(JSON.stringify(frame))
    })
  • 接收数据: 合成返回的帧长度较大,服务端是可能会出现一个消息分为多个websocket 帧返回给客户端。这时候我的处理是每返回一次写入相同文件mp3
ws.on('message', (data, err)=>{      
        if(err){
            return;
        }  
        let res_data = JSON.parse(data)
        if(!res_data || res_data.code!==0){
            return;
        }               
        audioBuf.push(res_data.data.audio)
        let audio = Buffer.from(res_data.data.audio, 'base64')
        fs.appendFile(filePath, audio, 'binary', err=>{
        })                  
        if (res_data.code == 0 && res_data.data.status == 2) {
            //状态为2才表示合成结束,需要合并           
            ws.close()
        }
    })

到这里就结束了,真的很简单但是为什么弄了这么久呢o(╥﹏╥)o

你可能感兴趣的:(前端,websocket,语音识别,前端,nodejs)