fix: update TTS voice mapping to only use valid Edge TTS voices

Previously the voice map referenced 10+ non-existent Edge TTS voice names
(xiaohan, xiaochen, xiaoshuang, etc.), causing NoAudioReceived errors and
fallback to browser default TTS. Now only maps to the 6 actually available
Chinese voices (xiaoxiao, xiaoyi, yunxi, yunyang, yunjian, yunxia).
Added voice speed adjustments and fixed --rate argument format for Windows.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-07-04 17:06:51 +08:00
parent fbf8dbbe86
commit 3483c6b3be
7 changed files with 307 additions and 138 deletions

View File

@@ -262,6 +262,25 @@
<el-slider v-model="chatTemperature" :min="0" :max="2" :step="0.1" size="small" show-stops />
<div style="margin:10px 0 4px;font-size:13px;font-weight:500">最大迭代</div>
<el-input-number v-model="chatMaxIterations" :min="1" :max="50" size="small" style="width:100%" />
<div style="margin:10px 0 4px;font-size:13px;font-weight:500">朗读语音</div>
<el-select v-model="chatVoice" size="small" style="width:100%">
<el-option-group label="── 教师女声 ──">
<el-option label="晓晓老师 · 温柔教导" value="teacher1" />
<el-option label="晓怡老师 · 活泼教学" value="teacher2" />
</el-option-group>
<el-option-group label="── 女声 ──">
<el-option label="晓晓 · 温柔" value="xiaoxiao" />
<el-option label="晓怡 · 活泼" value="xiaoyi" />
<el-option label="晓辰 · 温和" value="xiaochen" />
<el-option label="晓涵 · 知性" value="xiaohan" />
</el-option-group>
<el-option-group label="── 男声 ──">
<el-option label="云希 · 阳光" value="yunxi" />
<el-option label="云扬 · 专业" value="yunyang" />
<el-option label="云健 · 激情" value="yunjian" />
<el-option label="云夏 · 可爱" value="yunxia" />
</el-option-group>
</el-select>
</div>
</el-popover>
</template>
@@ -339,7 +358,7 @@ import { useTTS } from '@/composables/useTTS'
import { useSpeechRecognition } from '@/composables/useSpeechRecognition'
// Shared composables
const { renderMarkdown } = useMarkdown()
const { renderMarkdown, stripMarkdownForTTS } = useMarkdown()
const { pendingAttachments, fileInputRef, inputDragOver, uploadFiles, removeAttachment, clearAttachments, buildAttachmentContext, onDragLeave, onDrop, onFilesSelected, handleAttachFile } = useFileUpload()
const { isSpeaking, speak: ttsSpeak, stop: ttsStop } = useTTS()
const { isListening, transcript, supported: voiceSupported, start: voiceStart, stop: voiceStop } = useSpeechRecognition()
@@ -456,6 +475,7 @@ const sessionsLoading = ref(false)
const chatModel = ref('deepseek-v4-pro')
const chatTemperature = ref(0.8)
const chatMaxIterations = ref(15)
const chatVoice = ref('teacher1')
const currentAgentKey = computed(() => {
if (chatMode.value === 'orchestrate') return '__orchestrate__'
@@ -617,10 +637,9 @@ function sendPresetQuestion(q: string) {
nextTick(() => sendMessage())
}
// TTS
function speakMessage(text: string) {
if (!text) return
ttsSpeak(text)
ttsSpeak(stripMarkdownForTTS(text), { voice: chatVoice.value })
}
function stopSpeak() {
ttsStop()