add alternate windows tts

This commit is contained in:
polv committed 2026-07-19 09:51:15 +07:00
1 parent 045f62d951
commit ea5991cc4e
3 files changed
+49 -4

No files matched your search

+9
View File
@@ -30,5 +30,14 @@
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.maxTokenizationLineLength": 2500
},
"[rust]": {
"editor.quickSuggestions": {
"other": true,
"comments": false,
"strings": true
},
"editor.tabSize": 4,
"editor.formatOnSave": true,
},
"vue3snippets.enable-compile-vue-file-on-did-save-code": false
}
+10
View File
@@ -1,3 +1,13 @@
Contents edited from <https://www.howtostudykorean.com> is at [/docs/howtostudykorean/](/docs/howtostudykorean/).
For specifics of how this is created, see <https://git.polv.cc/polv/zh-grammar#how-it-works-for-android>
## TTS
For Windows TTS, I don't like Korean language support pack sound, so I use
```shell
docker run -it -p 5500:5500 synesthesiam/opentts:ko
```
It's required to have Docker running.
+30 -4
View File
@@ -3,6 +3,7 @@
<span ref="main" :class="class" :lang="lang">
<slot />
</span>
<audio style="display: none" ref="audio"></audio>
<span>
<button type="button" @click="playAudio()">🗣️</button>
</span>
@@ -23,12 +24,37 @@ const { lang = "ko-KR" } = defineProps<{
}>();
const mainEl = useTemplateRef("main");
const audioEl = useTemplateRef("audio");
function getMainText() {
if (!mainEl.value) return "";
return mainEl.value.innerText
.replace(/[*]/gu, " ")
.replace(/[\p{Ps}\p{Pe}]/gu, "");
}
async function playAudio() {
if (!mainEl.value) return;
if (navigator.platform === "Win32" || !(await playAudioTTSPlugin())) {
if (!audioEl.value) return;
const url = new URL("http://localhost:5500/api/tts");
url.searchParams.set("voice", "glow-speak:ko_kss");
url.searchParams.set("text", getMainText());
audioEl.value.src = url.href;
audioEl.value.currentTime = 0;
audioEl.value.play();
}
}
async function playAudioTTSPlugin(): Promise<boolean> {
if (!mainEl.value) return false;
const voices = await getVoices(lang);
if (!voices.length) return;
if (!voices.length) return false;
document.querySelectorAll("audio").forEach((el) => {
el.pause();
@@ -37,9 +63,7 @@ async function playAudio() {
const v = voices[Math.floor(Math.random() * voices.length)];
console.log(JSON.stringify(v));
await speak({
text: mainEl.value.innerText
.replace(/[*]/gu, " ")
.replace(/[\p{Ps}\p{Pe}]/gu, ""),
text: getMainText(),
language: null,
rate: null,
volume: null,
@@ -47,6 +71,8 @@ async function playAudio() {
queueMode: null,
voiceId: v.id,
});
return true;
}
</script>