feat: 增加流式语音合成错误处理,优化请求超时逻辑

This commit is contained in:
EvanWu 2025-08-11 10:59:17 +08:00
parent b73e65d2d0
commit 800c96c479

View File

@ -1,10 +1,5 @@
"use client"; "use client";
import { import { ApiPath, Alibaba, ALIBABA_BASE_URL } from "@/app/constant";
ApiPath,
Alibaba,
ALIBABA_BASE_URL,
REQUEST_TIMEOUT_MS,
} from "@/app/constant";
import { import {
useAccessStore, useAccessStore,
useAppConfig, useAppConfig,
@ -103,6 +98,9 @@ export class QwenApi implements LLMApi {
} }
async *streamSpeech(options: SpeechOptions): AsyncGenerator<AudioBuffer> { async *streamSpeech(options: SpeechOptions): AsyncGenerator<AudioBuffer> {
if (!options.input || !options.model) {
throw new Error("Missing required parameters: input and model");
}
const requestPayload = { const requestPayload = {
model: options.model, model: options.model,
input: { input: {
@ -129,7 +127,7 @@ export class QwenApi implements LLMApi {
// make a fetch request // make a fetch request
const requestTimeoutId = setTimeout( const requestTimeoutId = setTimeout(
() => controller.abort(), () => controller.abort(),
REQUEST_TIMEOUT_MS, getTimeoutMSByModel(options.model),
); );
const res = await fetch(speechPath, speechPayload); const res = await fetch(speechPath, speechPayload);
@ -148,12 +146,20 @@ export class QwenApi implements LLMApi {
buffer = lines.pop() || ""; buffer = lines.pop() || "";
for (const line of lines) { for (const line of lines) {
if (line.startsWith("data:")) { const data = line.slice(5);
const data = line.slice(5); try {
const json = JSON.parse(data); if (line.startsWith("data:")) {
if (json.output?.audio?.data) { const json = JSON.parse(data);
yield this.PCMBase64ToAudioBuffer(json.output.audio.data); if (json.output?.audio?.data) {
yield this.PCMBase64ToAudioBuffer(json.output.audio.data);
}
} }
} catch (parseError) {
console.warn(
"[StreamSpeech] Failed to parse SSE data:",
parseError,
);
continue;
} }
} }
} }