feat: 添加语音 AI 主动问候功能,优化问候文本发送逻辑和音频处理参数

This commit is contained in:
Pine
2026-08-18 08:20:44 +08:00
parent 49c0975fdc
commit f75fe7b9b3
7 changed files with 97 additions and 12 deletions
+27 -9
View File
@@ -139,17 +139,20 @@ export default function VoiceAssistant() {
const voiceStateRef = useRef(state);
voiceStateRef.current = state;
const pendingGreetingRef = useRef(false); // 连接成功后待发送的问候
const pendingGreetingTextRef = useRef(''); // 待发送的自定义问候文本(admin 测试)
const greetingSentRef = useRef(false); // 问候已发出,等回复完成启动倒计时
const greetingTimerRef = useRef(null); // 等待回答的倒计时句柄
// 主动发送问候(sendUserText → 后端 LLM 生成 → TTS 语音播放)
const sendGreeting = useCallback(() => {
const sendGreeting = useCallback((text) => {
const c = clientRef.current;
if (!c) return;
pendingGreetingRef.current = false;
pendingGreetingTextRef.current = '';
greetingSentRef.current = true;
c.sendUserText(GREETING_TEXT);
console.warn('[vision] 自动问候已发送:', GREETING_TEXT);
const msg = (text && String(text).trim()) || GREETING_TEXT;
c.sendUserText(msg);
console.warn('[vision] 主动问候已发送:', msg);
}, []);
// ── 右下角气泡渲染(复刻原版 ui/chat.js)───────────────────────────────
@@ -336,7 +339,14 @@ export default function VoiceAssistant() {
console.warn('[vision] 用户已回答,取消挂断倒计时');
}
});
client.addEventListener('input-level', (e) => paintInputLevel(e.detail?.rms));
client.addEventListener('input-level', (e) => {
// 诊断:麦克风电平(噪声门阈值 -50dB≈0.00316 线性值,说话时应显著高于它)
const rms = e.detail?.rms;
if (typeof rms === 'number' && !this?._rmsLog) {
console.info(`[mic] 麦克风电平 rms=${rms.toFixed(4)}(说话时应 > 0.01,若长期接近 0 说明麦克风被静音/无输入)`);
}
paintInputLevel(rms);
});
client.addEventListener('toolcall', (e) => void onToolCall(e));
client.addEventListener('response-finished', () => {
setState('listening');
@@ -355,8 +365,8 @@ export default function VoiceAssistant() {
clientRef.current = client;
await client.connect();
setState('listening');
// 自动问候:连接成功后发送问候(语音)
if (pendingGreetingRef.current) sendGreeting();
// 自动问候:连接成功后发送问候(语音;支持 admin 自定义文本
if (pendingGreetingRef.current) sendGreeting(pendingGreetingTextRef.current);
} catch (err) {
setErrorMsg(err?.message || String(err));
setState('error');
@@ -401,9 +411,17 @@ export default function VoiceAssistant() {
// MQTT 调度器 → 语音页操作:启动/关闭对话、刷新页面
useEffect(() => {
const onVoice = (e) => {
const { action } = e.detail || {};
const { action, text } = e.detail || {};
if (action === 'start') {
if (!clientRef.current) void start();
const greetText = (text && String(text).trim()) || sessionStorage.getItem('dpm_voice_greet') || '';
if (greetText) sessionStorage.removeItem('dpm_voice_greet');
if (clientRef.current) {
sendGreeting(greetText);
} else {
pendingGreetingTextRef.current = greetText;
pendingGreetingRef.current = true;
void start();
}
} else if (action === 'stop') {
void stop();
} else if (action === 'refresh') {
@@ -449,7 +467,7 @@ export default function VoiceAssistant() {
}
pendingGreetingRef.current = true;
if (clientRef.current) {
sendGreeting();
sendGreeting('');
} else {
void start(); // start 连接成功后检查 pendingGreetingRef 再发问候
}