Update tts/

This commit is contained in:
retoor 2025-06-29 20:08:13 +02:00
parent c366f8f0d3
commit cf95fea6c3

69
src/snek/static/tts.js Normal file
View File

@ -0,0 +1,69 @@
class SnekSpeaker extends HTMLElement {
_enabled = false
constructor() {
super();
this.attachShadow({ mode: 'open' });
// Optionally show something in the DOM
this.shadowRoot.innerHTML = `<slot></slot>`;
this._utterance = new SpeechSynthesisUtterance();
this._selectVoice();
}
toggle() {
if (window.speechSynthesis.speaking) {
window.speechSynthesis.pause();
} else {
window.speechSynthesis.resume();
}
}
stop() {
window.speechSynthesis.cancel();
}
disable() {
this._enabled = false
}
enable() {
this._enabled = true
}
set enabled(val) {
if (val) {
this.enable()
} else {
this.disable()
}
}
get enabled() {
return this._enabled
}
_selectVoice() {
const updateVoice = () => {
const voices = window.speechSynthesis.getVoices();
const maleEnglishVoices = voices.filter(voice =>
voice.lang.startsWith('en') && voice.name.toLowerCase().includes('male')
);
if (maleEnglishVoices.length > 0) {
this._utterance.voice = maleEnglishVoices[0];
}
};
updateVoice();
// Some browsers load voices asynchronously
window.speechSynthesis.onvoiceschanged = updateVoice;
}
speak(text) {
if(!this._enabled) return
if (!text) return;
this._utterance.text = text;
window.speechSynthesis.speak(this._utterance);
}
}
// Define the element
customElements.define('snek-speaker', SnekSpeaker);