feat:语音对话优化
This commit is contained in:
@@ -15,7 +15,7 @@ import { loadConfig, saveConfig } from "../lib/storage";
|
||||
import { useI18n } from "../lib/i18n";
|
||||
import { useCamera } from "../components/CameraManager";
|
||||
import { useMicrophone } from "../components/MicManager";
|
||||
import { useVAD, sampleFrame, compareFrames } from "../components/EdgeProcessor";
|
||||
import { useVAD, sampleFrame } from "../components/EdgeProcessor";
|
||||
import { useWebSocketManager } from "../components/WebSocketManager";
|
||||
import { useObservationMode } from "./useObservationMode";
|
||||
import type { ChatMessage, SessionConfig, ServerMessage, LLMDoneMessage } from "../types";
|
||||
@@ -194,24 +194,13 @@ export function useVisionSession(accessToken?: string | null) {
|
||||
ttsPlayerRef.current?.stop();
|
||||
setIsAudioPlaying(false);
|
||||
|
||||
// 尝试捕获图像帧(允许为 null,纯语音场景无需画面)
|
||||
const frame = captureFrame();
|
||||
if (!frame) {
|
||||
console.warn("[Session] 无法捕获图像帧");
|
||||
return;
|
||||
}
|
||||
|
||||
// 关键帧检测:与上一帧对比,相似度过高则跳过
|
||||
// 更新帧参考(供观察模式使用,但不以此阻断语音请求)
|
||||
const video = videoRef.current;
|
||||
if (video) {
|
||||
const currentSample = sampleFrame(video);
|
||||
if (currentSample && prevFrameRef.current) {
|
||||
const { similarity } = compareFrames(prevFrameRef.current, currentSample);
|
||||
if (similarity > 0.9) {
|
||||
console.log(`[Session] 画面无变化 (similarity=${similarity.toFixed(2)}),跳过`);
|
||||
prevFrameRef.current = currentSample;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (currentSample) {
|
||||
prevFrameRef.current = currentSample;
|
||||
}
|
||||
@@ -221,7 +210,7 @@ export function useVisionSession(accessToken?: string | null) {
|
||||
send({
|
||||
type: "query",
|
||||
request_id: requestId,
|
||||
image: dataUrlToBase64(frame),
|
||||
image: frame ? dataUrlToBase64(frame) : "",
|
||||
audio: encodeAudioToBase64(audio),
|
||||
});
|
||||
|
||||
@@ -304,6 +293,20 @@ export function useVisionSession(accessToken?: string | null) {
|
||||
case "error":
|
||||
console.error("[Session] 服务端错误:", msg.code, msg.message);
|
||||
showToast(getErrorMessage(msg.code, t), "error");
|
||||
// STT 失败时:将"语音识别中..."占位消息替换为失败提示
|
||||
if (msg.code === "STT_ERROR") {
|
||||
setMessages((prev) => {
|
||||
const updated = [...prev];
|
||||
const lastUserIdx = updated.findLastIndex((m) => m.role === "user");
|
||||
if (lastUserIdx >= 0 && updated[lastUserIdx].content === t("session.recognizing")) {
|
||||
updated[lastUserIdx] = {
|
||||
...updated[lastUserIdx],
|
||||
content: t("session.sttFailed"),
|
||||
};
|
||||
}
|
||||
return updated;
|
||||
});
|
||||
}
|
||||
setIsProcessing(false);
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user