@lobehub/tts
Version:
A high-quality & reliable TTS React Hooks library
49 lines (47 loc) • 1.53 kB
JavaScript
import { SpeechSynthesis, SpeechSynthesisUtterance } from "../../core/const/polyfill.mjs";
import { useCallback, useEffect, useMemo, useState } from "react";
//#region src/react/useSpeechSynthes/index.ts
const useSpeechSynthes = (defaultText, { voice, rate, pitch, ...options }) => {
const [voiceList, setVoiceList] = useState(SpeechSynthesis?.getVoices());
const [text, setText] = useState(defaultText);
const [isLoading, setIsLoading] = useState(false);
const speechSynthesisUtterance = useMemo(() => {
if (!SpeechSynthesisUtterance) return;
const utterance = new SpeechSynthesisUtterance(text);
utterance.voice = voiceList.find((item) => item.name === voice);
utterance.onstart = () => setIsLoading(true);
utterance.onend = () => setIsLoading(false);
if (pitch) utterance.pitch = pitch * 10;
if (rate) utterance.rate = rate * 10;
return utterance;
}, [
text,
voiceList,
rate,
pitch,
voice
]);
useEffect(() => {
if (!SpeechSynthesis) return;
SpeechSynthesis.onvoiceschanged = () => {
setVoiceList(SpeechSynthesis?.getVoices());
};
SpeechSynthesis.onstart = () => setIsLoading(true);
SpeechSynthesis.onend = () => setIsLoading(false);
}, []);
return {
isLoading,
setText,
start: useCallback(() => {
options?.onStart?.();
SpeechSynthesis?.speak(speechSynthesisUtterance);
}, [speechSynthesisUtterance]),
stop: useCallback(() => {
options?.onStop?.();
speechSynthesis?.cancel();
setIsLoading(false);
}, [])
};
};
//#endregion
export { useSpeechSynthes };