fix: 중국어 TTS → Google Translate TTS로 변경 (고품질 발음)
This commit is contained in:
부모
2c4535e57e
커밋
4ab7990e5d
@ -143,32 +143,19 @@ export function OpsGuideModal({ ships, onClose, onFlyTo, onRouteSelect }: Props)
|
||||
navigator.clipboard.writeText(text).then(() => { setCopiedIdx(idx); setTimeout(() => setCopiedIdx(null), 1500); });
|
||||
};
|
||||
|
||||
const audioRef = useRef<HTMLAudioElement | null>(null);
|
||||
|
||||
const speakChinese = useCallback((text: string, idx: number) => {
|
||||
if (typeof window === 'undefined' || !window.speechSynthesis) return;
|
||||
window.speechSynthesis.cancel();
|
||||
const utter = new SpeechSynthesisUtterance(text);
|
||||
utter.lang = 'zh-CN';
|
||||
utter.rate = 0.8;
|
||||
utter.pitch = 1.0;
|
||||
utter.volume = 1;
|
||||
const voices = window.speechSynthesis.getVoices();
|
||||
const zhVoice = voices.find(v => v.lang === 'zh-CN') || voices.find(v => v.lang.startsWith('zh'));
|
||||
if (zhVoice) utter.voice = zhVoice;
|
||||
// Chrome bug workaround: pause/resume keepalive to prevent cutoff
|
||||
let keepAlive: ReturnType<typeof setInterval> | null = null;
|
||||
utter.onstart = () => {
|
||||
setSpeakingIdx(idx);
|
||||
keepAlive = setInterval(() => {
|
||||
if (window.speechSynthesis.speaking && !window.speechSynthesis.paused) {
|
||||
window.speechSynthesis.pause();
|
||||
window.speechSynthesis.resume();
|
||||
}
|
||||
}, 5000);
|
||||
};
|
||||
const cleanup = () => { setSpeakingIdx(null); if (keepAlive) clearInterval(keepAlive); };
|
||||
utter.onend = cleanup;
|
||||
utter.onerror = cleanup;
|
||||
window.speechSynthesis.speak(utter);
|
||||
// Stop previous
|
||||
if (audioRef.current) { audioRef.current.pause(); audioRef.current = null; }
|
||||
setSpeakingIdx(idx);
|
||||
const encoded = encodeURIComponent(text);
|
||||
const url = `https://translate.google.com/translate_tts?ie=UTF-8&client=tw-ob&tl=zh-CN&q=${encoded}`;
|
||||
const audio = new Audio(url);
|
||||
audioRef.current = audio;
|
||||
audio.onended = () => setSpeakingIdx(null);
|
||||
audio.onerror = () => setSpeakingIdx(null);
|
||||
audio.play().catch(() => setSpeakingIdx(null));
|
||||
}, []);
|
||||
|
||||
const handleSuspectClick = (s: SuspectVessel) => {
|
||||
|
||||
불러오는 중...
Reference in New Issue
Block a user