refac
This commit is contained in:
@@ -185,6 +185,7 @@
|
||||
let speakingIdx: number | undefined;
|
||||
|
||||
let loadingSpeech = false;
|
||||
let speakAbort: AbortController | null = null;
|
||||
|
||||
let showRateComment = false;
|
||||
|
||||
@@ -202,39 +203,39 @@
|
||||
};
|
||||
|
||||
const stopAudio = () => {
|
||||
speakAbort?.abort();
|
||||
speakAbort = null;
|
||||
|
||||
try {
|
||||
speechSynthesis.cancel();
|
||||
$audioQueue?.stop();
|
||||
} catch {}
|
||||
|
||||
if (speaking) {
|
||||
speaking = false;
|
||||
speakingIdx = undefined;
|
||||
}
|
||||
speaking = false;
|
||||
speakingIdx = undefined;
|
||||
loadingSpeech = false;
|
||||
};
|
||||
|
||||
// Resolve voice: model-specific > user settings > config default
|
||||
const getVoiceId = () =>
|
||||
model?.info?.meta?.tts?.voice ??
|
||||
($settings?.audio?.tts?.defaultVoice === $config.audio.tts.voice
|
||||
? $settings?.audio?.tts?.voice ?? $config?.audio?.tts?.voice
|
||||
: $config?.audio?.tts?.voice);
|
||||
|
||||
const speak = async () => {
|
||||
if (!(message?.content ?? '').trim().length) {
|
||||
toast.info($i18n.t('No content to speak'));
|
||||
return;
|
||||
}
|
||||
|
||||
stopAudio();
|
||||
speakAbort = new AbortController();
|
||||
const { signal } = speakAbort;
|
||||
|
||||
speaking = true;
|
||||
const content = removeAllDetails(message.content);
|
||||
|
||||
// Get voice: model-specific > user settings > config default
|
||||
const getVoiceId = () => {
|
||||
// Check for model-specific TTS voice first
|
||||
if (model?.info?.meta?.tts?.voice) {
|
||||
return model.info.meta.tts.voice;
|
||||
}
|
||||
// Fall back to user settings or config default
|
||||
if ($settings?.audio?.tts?.defaultVoice === $config.audio.tts.voice) {
|
||||
return $settings?.audio?.tts?.voice ?? $config?.audio?.tts?.voice;
|
||||
}
|
||||
return $config?.audio?.tts?.voice;
|
||||
};
|
||||
|
||||
if ($config.audio.tts.engine === '') {
|
||||
let voices = [];
|
||||
const getVoicesLoop = setInterval(() => {
|
||||
@@ -242,16 +243,10 @@
|
||||
if (voices.length > 0) {
|
||||
clearInterval(getVoicesLoop);
|
||||
|
||||
const voiceId = getVoiceId();
|
||||
const voice = voices?.filter((v) => v.voiceURI === voiceId)?.at(0) ?? undefined;
|
||||
|
||||
console.log(voice);
|
||||
|
||||
const voice = voices.find((v) => v.voiceURI === getVoiceId());
|
||||
const speech = new SpeechSynthesisUtterance(content);
|
||||
speech.rate = $settings.audio?.tts?.playbackRate ?? 1;
|
||||
|
||||
console.log(speech);
|
||||
|
||||
speech.onend = () => {
|
||||
speaking = false;
|
||||
if ($settings.conversationMode) {
|
||||
@@ -281,9 +276,7 @@
|
||||
);
|
||||
|
||||
if (!messageContentParts.length) {
|
||||
console.log('No content to speak');
|
||||
toast.info($i18n.t('No content to speak'));
|
||||
|
||||
speaking = false;
|
||||
loadingSpeech = false;
|
||||
return;
|
||||
@@ -303,41 +296,43 @@
|
||||
await $TTSWorker.init();
|
||||
}
|
||||
|
||||
for (const [idx, sentence] of messageContentParts.entries()) {
|
||||
for (const [, sentence] of messageContentParts.entries()) {
|
||||
if (signal.aborted) return;
|
||||
|
||||
const url = await $TTSWorker
|
||||
.generate({
|
||||
text: sentence,
|
||||
voice: voiceId
|
||||
})
|
||||
.generate({ text: sentence, voice: voiceId })
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
toast.error(`${error}`);
|
||||
|
||||
speaking = false;
|
||||
loadingSpeech = false;
|
||||
});
|
||||
|
||||
if (signal.aborted) return;
|
||||
|
||||
if (url && speaking) {
|
||||
$audioQueue.enqueue(url);
|
||||
loadingSpeech = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (const [idx, sentence] of messageContentParts.entries()) {
|
||||
for (const [, sentence] of messageContentParts.entries()) {
|
||||
if (signal.aborted) return;
|
||||
|
||||
const res = await synthesizeOpenAISpeech(localStorage.token, voiceId, sentence).catch(
|
||||
(error) => {
|
||||
console.error(error);
|
||||
toast.error(`${error}`);
|
||||
|
||||
speaking = false;
|
||||
loadingSpeech = false;
|
||||
}
|
||||
);
|
||||
|
||||
if (signal.aborted) return;
|
||||
|
||||
if (res && speaking) {
|
||||
const blob = await res.blob();
|
||||
const url = URL.createObjectURL(blob);
|
||||
|
||||
$audioQueue.enqueue(url);
|
||||
loadingSpeech = false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user