"use client"; import { useState, useEffect, useRef } from "react"; import { Volume2, Play, Square, Settings2, Info } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Textarea } from "@/components/ui/textarea"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Slider } from "@/components/ui/slider"; import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { toast } from "sonner"; export default function TtsPage() { const [text, setText] = useState("欢迎使用信奥工具箱,这是一个基于浏览器 Web Speech API 实现的文字转语音工具。您可以自由调节语速、音调和音量。"); const [voices, setVoices] = useState([]); const [selectedVoice, setSelectedVoice] = useState(""); const [rate, setRate] = useState(1); const [pitch, setPitch] = useState(1); const [volume, setVolume] = useState(1); const [isSpeaking, setIsActive] = useState(false); const synth = useRef(null); useEffect(() => { if (typeof window !== "undefined") { synth.current = window.speechSynthesis; const loadVoices = () => { const availableVoices = synth.current?.getVoices() || []; setVoices(availableVoices); // Default to a Chinese voice if available, otherwise first one const zhVoice = availableVoices.find(v => v.lang.includes("zh")) || availableVoices[0]; if (zhVoice && !selectedVoice) { setSelectedVoice(zhVoice.name); } }; loadVoices(); if (synth.current && synth.current.onvoiceschanged !== undefined) { synth.current.onvoiceschanged = loadVoices; } } return () => { if (synth.current) { synth.current.cancel(); } }; }, []); const speak = () => { if (!synth.current || !text) return; if (synth.current.speaking) { synth.current.cancel(); } const utterance = new SpeechSynthesisUtterance(text); const voice = voices.find(v => v.name === selectedVoice); if (voice) utterance.voice = voice; utterance.rate = rate; utterance.pitch = pitch; utterance.volume = volume; utterance.onstart = () => setIsActive(true); utterance.onend = () => setIsActive(false); utterance.onerror = () => { setIsActive(false); toast.error("播放出错"); }; synth.current.speak(utterance); }; const stop = () => { if (synth.current) { synth.current.cancel(); setIsActive(false); } }; return (

文字转语音 (TTS)

基于浏览器内置 API,无需安装插件

输入文本