|
@@ -8,49 +8,67 @@ export default class TtsVoice {
|
|
|
apiSecret = "";
|
|
|
apiKey = "";
|
|
|
ttsWS = null;
|
|
|
- status = "UNDEFINED";
|
|
|
- statusStr = "";
|
|
|
audioPlayer = null;
|
|
|
text = "";
|
|
|
- blob = "";
|
|
|
- cb = () => {};
|
|
|
- blobDoneCb = () => {};
|
|
|
+ playing = false;
|
|
|
+ running = false;
|
|
|
+ done = false;
|
|
|
+ error = false;
|
|
|
+ errorMsg = "";
|
|
|
+ dataFilled = false;
|
|
|
+
|
|
|
constructor(params) {
|
|
|
this.appId = params.appId;
|
|
|
this.apiSecret = params.apiSecret;
|
|
|
this.apiKey = params.apiKey;
|
|
|
- if (params.cb) {
|
|
|
- this.cb = params.cb;
|
|
|
- }
|
|
|
- if (params.blobDoneCb) {
|
|
|
- this.blobDoneCb = params.blobDoneCb;
|
|
|
- }
|
|
|
this.audioPlayer = new AudioPlayer();
|
|
|
this.audioPlayer.onPlay = () => {
|
|
|
- this.changeBtnStatus("PLAY");
|
|
|
+ this.playing = true;
|
|
|
};
|
|
|
- this.audioPlayer.onStop = (audioDatas) => {
|
|
|
- console.log(audioDatas);
|
|
|
- this.status === "PLAY" && this.changeBtnStatus("STOP");
|
|
|
+ this.audioPlayer.onStop = () => {
|
|
|
+
|
|
|
+ this.playing = false;
|
|
|
};
|
|
|
}
|
|
|
+
|
|
|
setText(text) {
|
|
|
this.text = text;
|
|
|
}
|
|
|
- changeBtnStatus(status) {
|
|
|
- this.status = status;
|
|
|
- if (status === "UNDEFINED") {
|
|
|
- this.statusStr = "立即合成";
|
|
|
- } else if (status === "CONNECTING") {
|
|
|
- this.statusStr = "正在合成";
|
|
|
- } else if (status === "PLAY") {
|
|
|
- this.statusStr = "停止播放";
|
|
|
- } else if (status === "STOP") {
|
|
|
- this.statusStr = "重新播放";
|
|
|
- }
|
|
|
- const _this = this;
|
|
|
- this.cb({ status, statusStr: _this.statusStr });
|
|
|
+
|
|
|
+ run(text) {
|
|
|
+ if (!text) return;
|
|
|
+
|
|
|
+ this.text = "";
|
|
|
+ this.playing = false;
|
|
|
+ this.done = false;
|
|
|
+ this.error = false;
|
|
|
+ this.errorMsg = "";
|
|
|
+ this.dataFilled = false;
|
|
|
+
|
|
|
+ this.text = text;
|
|
|
+ this.running = true;
|
|
|
+ this.connect();
|
|
|
}
|
|
|
+
|
|
|
+ stopRun() {
|
|
|
+ this.ttsWS?.close();
|
|
|
+ this.audioPlayer.reset();
|
|
|
+ this.running = false;
|
|
|
+ this.playing = false;
|
|
|
+ this.done = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ play() {
|
|
|
+ if (!this.playing) this.audioPlayer.play();
|
|
|
+ }
|
|
|
+ stop() {
|
|
|
+ if (this.playing) this.audioPlayer.stop();
|
|
|
+ }
|
|
|
+
|
|
|
+ getBlob() {
|
|
|
+ return this.audioPlayer.getAudioDataBlob("wav");
|
|
|
+ }
|
|
|
+
|
|
|
encodeText(text, type) {
|
|
|
if (type === "unicode") {
|
|
|
let buf = new ArrayBuffer(text.length * 4);
|
|
@@ -85,39 +103,9 @@ export default class TtsVoice {
|
|
|
url = `${url}?authorization=${authorization}&date=${date}&host=${host}`;
|
|
|
return url;
|
|
|
}
|
|
|
- stopConnect() {
|
|
|
- this.changeBtnStatus("UNDEFINED");
|
|
|
- this.ttsWS?.close();
|
|
|
- this.audioPlayer.reset();
|
|
|
- }
|
|
|
- action(text) {
|
|
|
- if (text && typeof text === "string") {
|
|
|
- if (text !== this.text) {
|
|
|
- this.changeBtnStatus("UNDEFINED");
|
|
|
- }
|
|
|
- this.setText(text);
|
|
|
- }
|
|
|
- if (this.status === "UNDEFINED") {
|
|
|
-
|
|
|
-
|
|
|
- this.connect();
|
|
|
- } else if (this.status === "CONNECTING") {
|
|
|
-
|
|
|
- this.changeBtnStatus("UNDEFINED");
|
|
|
- this.ttsWS?.close();
|
|
|
- this.audioPlayer.reset();
|
|
|
- return;
|
|
|
- } else if (this.status === "PLAY") {
|
|
|
- this.audioPlayer.stop();
|
|
|
- } else if (this.status === "STOP") {
|
|
|
- this.audioPlayer.play();
|
|
|
- }
|
|
|
- }
|
|
|
+
|
|
|
connect() {
|
|
|
- this.ttsWS?.close();
|
|
|
- this.blob = "";
|
|
|
- this.blobDoneCb && this.blobDoneCb(this.blob);
|
|
|
- const text = this.text || "请输入文字!";
|
|
|
+ const text = this.text;
|
|
|
const appId = this.appId;
|
|
|
const apiKey = this.apiKey;
|
|
|
const apiSecret = this.apiSecret;
|
|
@@ -130,7 +118,7 @@ export default class TtsVoice {
|
|
|
alert("浏览器不支持WebSocket");
|
|
|
return;
|
|
|
}
|
|
|
- this.changeBtnStatus("CONNECTING");
|
|
|
+
|
|
|
const _this = this;
|
|
|
this.ttsWS.onopen = () => {
|
|
|
_this.audioPlayer.start({
|
|
@@ -138,7 +126,6 @@ export default class TtsVoice {
|
|
|
sampleRate: 16000,
|
|
|
resumePlayDuration: 1000,
|
|
|
});
|
|
|
- _this.changeBtnStatus("PLAY");
|
|
|
var tte = "UTF8";
|
|
|
var params = {
|
|
|
common: {
|
|
@@ -161,14 +148,20 @@ export default class TtsVoice {
|
|
|
};
|
|
|
_this.ttsWS.send(JSON.stringify(params));
|
|
|
};
|
|
|
+
|
|
|
this.ttsWS.onmessage = (e) => {
|
|
|
let jsonData = JSON.parse(e.data);
|
|
|
|
|
|
if (jsonData.code !== 0) {
|
|
|
console.error(jsonData);
|
|
|
- _this.changeBtnStatus("UNDEFINED");
|
|
|
+ this.stopConnect();
|
|
|
+ this.error = true;
|
|
|
+ this.errorMsg = jsonData.message;
|
|
|
return;
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+ _this.dataFilled = true;
|
|
|
_this.audioPlayer.postMessage({
|
|
|
type: "base64",
|
|
|
data: jsonData.data.audio,
|
|
@@ -177,18 +170,30 @@ export default class TtsVoice {
|
|
|
if (jsonData.code === 0 && jsonData.data.status === 2) {
|
|
|
_this.ttsWS.close();
|
|
|
setTimeout(() => {
|
|
|
- _this.blob = this.audioPlayer.getAudioDataBlob("wav");
|
|
|
- _this.blobDoneCb && _this.blobDoneCb(_this.blob);
|
|
|
+ this.running = false;
|
|
|
+ this.done = true;
|
|
|
}, 300);
|
|
|
}
|
|
|
};
|
|
|
_this.ttsWS.onerror = (e) => {
|
|
|
console.error(e);
|
|
|
+ this.stopConnect();
|
|
|
+ this.error = true;
|
|
|
+ this.errorMsg = e.message || "tts error";
|
|
|
};
|
|
|
_this.ttsWS.onclose = (e) => {
|
|
|
console.log(e);
|
|
|
};
|
|
|
}
|
|
|
+
|
|
|
+ stopConnect() {
|
|
|
+ this.running = false;
|
|
|
+ this.playing = false;
|
|
|
+ this.ttsWS?.close();
|
|
|
+ this.audioPlayer.reset();
|
|
|
+ this.dataFilled = false;
|
|
|
+ }
|
|
|
+
|
|
|
download() {
|
|
|
const blob = this.audioPlayer.getAudioDataBlob("wav");
|
|
|
if (!blob) {
|
|
@@ -201,11 +206,18 @@ export default class TtsVoice {
|
|
|
node.click();
|
|
|
node.remove();
|
|
|
}
|
|
|
+
|
|
|
reset() {
|
|
|
- this.ttsWS?.close();
|
|
|
this.text = "";
|
|
|
- this.blob = "";
|
|
|
- this.changeBtnStatus("UNDEFINED");
|
|
|
+ this.playing = false;
|
|
|
+ this.running = false;
|
|
|
+ this.done = false;
|
|
|
+ this.error = false;
|
|
|
+ this.errorMsg = "";
|
|
|
+ this.dataFilled = false;
|
|
|
+ this.ttsWS?.close();
|
|
|
this.audioPlayer?.reset();
|
|
|
+ this.ttsWS = null;
|
|
|
+ this.audioPlayer = null;
|
|
|
}
|
|
|
}
|