fix(stage-ui): unspeech voiceId (#73)

Co-authored-by: Neko <11081491+nekomeowww@users.noreply.github.com>
This commit is contained in:
RainbowBird
2025-03-13 00:33:14 +08:00
committed by GitHub
co-authored by Neko
parent b753ef3302
commit 8e7e024390
3 changed files with 20 additions and 36 deletions
@@ -1,7 +1,7 @@
<script setup lang="ts">
import type { ElectronAPI } from '@electron-toolkit/preload'
import type { DuckDBWasmDrizzleDatabase } from '@proj-airi/drizzle-duckdb-wasm'
import type { SpeechProvider } from '@xsai-ext/shared-providers'
import type { SpeechProviderWithExtraOptions } from '@xsai-ext/shared-providers'
import type { Emotion } from '../../constants/emotions'
import { drizzle } from '@proj-airi/drizzle-duckdb-wasm'
@@ -80,24 +80,26 @@ async function handleSpeechGeneration(ctx: { data: string }) {
return
}
const provider = providersStore.getProviderInstance(activeSpeechProvider.value) as SpeechProvider
// TODO: UnElevenLabsOptions
const provider = providersStore.getProviderInstance(activeSpeechProvider.value) as SpeechProviderWithExtraOptions<string, any>
if (!provider) {
console.error('Failed to initialize speech provider')
return
}
const res = await generateSpeech({
...provider.speech(activeSpeechModel.value),
...provider.speech(activeSpeechModel.value, {
// Optional: Add SSML wrapping if enabled
...(ssmlEnabled.value && {
input: speechStore.generateSSML(ctx.data),
}),
voiceSettings: {
stability: 0.4,
similarityBoost: 0.5,
},
}),
input: ctx.data,
voice: voiceId.value,
// Optional: Add SSML wrapping if enabled
...(ssmlEnabled.value && {
input: speechStore.generateSSML(ctx.data),
}),
voiceSettings: {
stability: 0.4,
similarityBoost: 0.5,
},
})
// Decode the ArrayBuffer into an AudioBuffer
+3 -22
View File
@@ -12,7 +12,6 @@ export const useSpeechStore = defineStore('speech', () => {
const activeSpeechProvider = useLocalStorage('settings/speech/active-provider', '')
const activeSpeechModel = useLocalStorage('settings/speech/active-model', 'eleven_multilingual_v2')
const voiceName = useLocalStorage('settings/speech/voice-name', '')
const voiceId = useLocalStorage('settings/speech/voice-id', '')
const pitch = useLocalStorage('settings/speech/pitch', 0)
const rate = useLocalStorage('settings/speech/rate', 1)
const ssmlEnabled = useLocalStorage('settings/speech/ssml-enabled', false)
@@ -81,27 +80,11 @@ export const useSpeechStore = defineStore('speech', () => {
function setVoiceName(name: string) {
voiceName.value = name
// If this is a preset voice, also set the voiceId
for (const voiceEnum in voiceMap) {
if (voiceEnum === name) {
voiceId.value = voiceMap[voiceEnum as Voice]
break
}
}
}
function setVoiceId(id: string) {
voiceId.value = id
// Try to find the corresponding voice name
for (const voiceEnum in voiceMap) {
if (voiceMap[voiceEnum as Voice] === id) {
voiceName.value = voiceEnum
break
}
}
}
const voiceId = computed(() => {
return voiceMap[voiceName.value as Voice]
})
function setPitch(value: number) {
pitch.value = value
@@ -121,7 +104,6 @@ export const useSpeechStore = defineStore('speech', () => {
function resetVoiceSettings() {
voiceName.value = ''
voiceId.value = ''
pitch.value = 0
rate.value = 1
ssmlEnabled.value = false
@@ -286,7 +268,6 @@ export const useSpeechStore = defineStore('speech', () => {
setActiveSpeechProvider,
setActiveSpeechModel,
setVoiceName,
setVoiceId,
setPitch,
setRate,
setSSMLEnabled,
+4 -3
View File
@@ -1,5 +1,5 @@
/* eslint-disable no-case-declarations */
import type { ChatProvider, EmbedProvider, SpeechProvider, TranscriptionProvider } from '@xsai-ext/shared-providers'
import type { ChatProvider, EmbedProvider, SpeechProviderWithExtraOptions, TranscriptionProvider } from '@xsai-ext/shared-providers'
import { useLocalStorage } from '@vueuse/core'
import {
@@ -31,7 +31,7 @@ export interface ProviderMetadata {
iconColor?: string
iconImage?: string
baseUrlDefault?: string
createProvider: (config: Record<string, unknown>) => ChatProvider | EmbedProvider | SpeechProvider | TranscriptionProvider
createProvider: (config: Record<string, unknown>) => ChatProvider | EmbedProvider | SpeechProviderWithExtraOptions | TranscriptionProvider
modelSelectionType: 'dynamic' | 'manual' | 'hardcoded'
fetchModelsManually?: (config: Record<string, unknown>) => Promise<ModelInfo[]>
hardcodedModels?: ModelInfo[]
@@ -226,7 +226,8 @@ export const useProvidersStore = defineStore('providers', () => {
description: 'elevenlabs.io',
icon: 'i-simple-icons:elevenlabs',
baseUrlDefault: 'https://unspeech.hyp3r.link/v1/',
createProvider: config => createUnElevenLabs(config.apiKey as string, config.baseUrl as string),
// TODO: UnElevenLabsOptions
createProvider: config => createUnElevenLabs(config.apiKey as string, config.baseUrl as string) as SpeechProviderWithExtraOptions<string, any>,
modelSelectionType: 'hardcoded',
hardcodedModels: [
{