一、语音合成支持流式返回,通过WS可以实时拿到音频流,那么我们如何在VUE项目中实现合成功能呢。语音合成应用非常广泛,如商家广告合成、驾校声音合成、新闻播报、在线听书等等场景都会用到语音合成。
二、VUE下实现合成并使用浏览器播放代码如下:
<template>
<div class="Login-container">
<div class="allClass">
<div class="titleClass"><b>在线语音合成流式版</b></div>
<hr/>
<textarea style=" width: 310px;height: 100px;">
{{ttsText}}
</textarea>
<el-button type="primary" @click="clickTts">立即合成</el-button>
<el-button type="primary" @click="clickWav">DOWN WAV</el-button>
</div>
</div>
</template>
<script src="../js_util/index.js"></script>
<script src="../js_util/index.umd.js"></script>
<script>
import * as base64 from 'js-base64'
import CryptoJS from '../js_util/crypto-js/crypto-js.js'
import AudioPlayer from '../../public/player'
const audioPlayer = new AudioPlayer(""); // 播放器
export default {
name: "Login",
data() {
return {
APPID: "",
API_SECRET: "",
API_KEY: "",
ttsWs: "", // 合成ws链接
ttsText: "锦瑟无端五十弦,一弦一柱思华年。庄生晓梦迷蝴蝶,望帝春心托杜鹃。沧海月明珠有泪,蓝田日暖玉生烟。" +
"此情可待成追忆,只是当时已惘然。",
vcn: "xiaoyan",
}
},
methods: {
clickTts() {
const url = this.getWebSocketUrl(this.API_KEY, this.API_SECRET);
if ("WebSocket" in window) {
this.ttsWS = new WebSocket(url);
} else if ("MozWebSocket" in window) {
this.ttsWS = new MozWebSocket(url);
} else {
alert("浏览器不支持WebSocket");
return;
}
this.ttsWS.onopen = (e) => {
console.log("链接成功...")
audioPlayer.start({
autoPlay: true,
sampleRate: 16000,
resumePlayDuration: 1000
});
let text = this.ttsText;
let tte = document.getElementById("tte") ? "unicode" : "UTF8";
let params = {
common: {
app_id: this.APPID,
},
business: {
aue: "raw",
auf: "audio/L16;rate=16000",
vcn: this.vcn,
bgs: 1,
tte,
},
data: {
status: 2,
text: this.encodeText(text, tte),
},
};
this.ttsWS.send(JSON.stringify(params));
console.log("发送成功...")
};
this.ttsWS.onmessage = (e) => {
let jsonData = JSON.parse(e.data);
console.log("合成返回的数据" + JSON.stringify(jsonData));
// 合成失败
if (jsonData.code !== 0) {
console.error(jsonData);
return;
}
audioPlayer.postMessage({
type: "base64",
data: jsonData.data.audio,
isLastData: jsonData.data.status === 2,
});
if (jsonData.code === 0 && jsonData.data.status === 2) {
this.ttsWS.close();
}
};
this.ttsWS.onerror = (e) => {
console.error(e);
};
this.ttsWS.onclose = (e) => {
console.log(e + "链接已关闭");
};
},
getWebSocketUrl(apiKey, apiSecret) {
let url = "wss://tts-api.xfyun.cn/v2/tts";
let host = location.host;
let date = new Date().toGMTString();
let algorithm = "hmac-sha256";
let headers = "host date request-line";
let signatureOrigin = `host: ${host}\ndate: ${date}\nGET /v2/tts HTTP/1.1`;
let signatureSha = CryptoJS.HmacSHA256(signatureOrigin, apiSecret);
let signature = CryptoJS.enc.Base64.stringify(signatureSha);
let authorizationOrigin = `api_key="${apiKey}", algorithm="${algorithm}", headers="${headers}", signature="${signature}"`;
let authorization = btoa(authorizationOrigin);
url = `${url}?authorization=${authorization}&date=${date}&host=${host}`;
return url;
},
// 文本编码
encodeText(text, type) {
if (type === "unicode") {
let buf = new ArrayBuffer(text.length * 4);
let bufView = new Uint16Array(buf);
for (let i = 0, strlen = text.length; i < strlen; i++) {
bufView[i] = text.charCodeAt(i);
}
let binary = "";
let bytes = new Uint8Array(buf);
let len = bytes.byteLength;
for (let i = 0; i < len; i++) {
binary += String.fromCharCode(bytes[i]);
}
return window.btoa(binary);
} else {
return base64.encode(text);
}
},
clickPcm() {
},
clickWav() {
const blob = audioPlayer.getAudioDataBlob("wav")
if (!blob) {
return
}
let defaultName = new Date().getTime();
let node = document.createElement("a");
node.href = window.URL.createObjectURL(blob);
node.download = `${defaultName}.wav`;
node.click();
node.remove();
}
}
}
</script>
<style scoped>
.Login-container {
height: 100vh;
background-image: linear-gradient(to bottom right, deepskyblue, darkcyan);
overflow: hidden;
}
.allClass {
margin: 200px auto;
background-color: #ffffff;
width: 350px;
height: 390px;
padding: 20px;
border-radius: 10px;
}
.titleClass {
margin: 20px 0;
text-align: center;
font-size: 24px;
}
.inputOneClass {
margin: 10px 0;
}
.buttonClass {
margin: 10px 0;
text-align: right;
}
</style>
三、除了调用浏览器麦克风播报,我们还可以一键下载为WAV音频,实现效果如下!
四、感兴趣的可以加我获取源码!