52 lines
1.2 KiB
TypeScript
52 lines
1.2 KiB
TypeScript
declare global {
|
|
interface Window {
|
|
speak(s: string, lang?: string): void
|
|
}
|
|
}
|
|
|
|
export function speak (s: string, lang?: string) {
|
|
lang = lang || 'zh-CN'
|
|
|
|
if (process.client) {
|
|
let trueLang = ''
|
|
|
|
const voices = speechSynthesis.getVoices()
|
|
const [la1, la2] = lang.split(/-_/)
|
|
if (la2) {
|
|
const langRegex = new RegExp(`${la1}[-_]${la2}`, 'i')
|
|
const matchedLang = voices.filter((v) => langRegex.test(v.lang))
|
|
if (matchedLang.length > 0) {
|
|
trueLang = matchedLang.sort((v1, v2) => v1.localService
|
|
? -1 : v2.localService ? 1 : 0)[0].lang
|
|
}
|
|
}
|
|
if (!trueLang) {
|
|
const langRegex = new RegExp(`^${la1}`, 'i')
|
|
const matchedLang = voices.filter((v) => langRegex.test(v.lang))
|
|
if (matchedLang.length > 0) {
|
|
trueLang = matchedLang.sort((v1, v2) => v1.localService
|
|
? -1 : v2.localService ? 1 : 0)[0].lang
|
|
}
|
|
}
|
|
|
|
if (trueLang) {
|
|
const u = new SpeechSynthesisUtterance(s)
|
|
u.lang = trueLang
|
|
speechSynthesis.speak(u)
|
|
}
|
|
}
|
|
}
|
|
|
|
if (process.client) {
|
|
window.speak = speak
|
|
|
|
document.body.addEventListener('keydown', (evt) => {
|
|
if (evt.code === 'KeyS') {
|
|
const s = getSelection()
|
|
if (s) {
|
|
speak(s.toString())
|
|
}
|
|
}
|
|
})
|
|
}
|