小喇叭修改

This commit is contained in:
tanglong 2026-10-27 15:25:29 +08:00
parent ed1fef31be
commit e74900bcb0
3 changed files with 27 additions and 34 deletions

1
.gitattributes vendored
View File

@ -4,3 +4,4 @@
*.png -text *.png -text
*.jpg -text *.jpg -text
*.jpeg -text *.jpeg -text
*.sh text eol=lf

View File

@ -16,8 +16,7 @@ if ! docker compose version >/dev/null 2>&1; then
exit 1 exit 1
fi fi
# Do not reuse an old frontend layer: media files must always come from the # Force a fresh image so replaced media files cannot be hidden by build cache.
# currently uploaded source package.
docker compose build --no-cache shuziren docker compose build --no-cache shuziren
docker compose up -d --force-recreate --remove-orphans shuziren docker compose up -d --force-recreate --remove-orphans shuziren

View File

@ -1,6 +1,6 @@
<template> <template>
<main class="realtime-dh-wrapper"> <main class="realtime-dh-wrapper">
<section class="realtime-dh-stage" @pointerdown.capture="unlockAudioAndPlay"> <section class="realtime-dh-stage" @pointerdown.capture.once="unlockAudioAndPlay">
<div class="visual-stage"> <div class="visual-stage">
<div class="standby-scene" :class="{thinking: waitingForAnswer}"> <div class="standby-scene" :class="{thinking: waitingForAnswer}">
<video <video
@ -92,11 +92,11 @@
type="button" type="button"
class="sound-button" class="sound-button"
:class="{enabled: soundEnabled}" :class="{enabled: soundEnabled}"
:aria-label="soundEnabled ? '关闭声音' : '开启声音'" aria-label="开启并保持数字人声音"
:title="soundEnabled ? '声音已开启,点击关闭' : '声音已关闭,点击开启'" title="开启并保持声音"
@click="handleMute" @click="enableSound"
> >
<img :src="soundEnabled ? VoiceSvg : MutedSvg" class="mute-icon" alt="" /> <img :src="soundEnabled && audioUnlocked ? VoiceSvg : MutedSvg" class="mute-icon" alt="" />
</button> </button>
</div> </div>
@ -322,8 +322,10 @@ const tryPlayPendingAnswer = async () => {
const canPlayWithSound = audioUnlocked.value || await checkPlayUnMute(); const canPlayWithSound = audioUnlocked.value || await checkPlayUnMute();
if (generation !== connectionGeneration || !humanReady.value) return; if (generation !== connectionGeneration || !humanReady.value) return;
if (!canPlayWithSound) { if (!canPlayWithSound) {
if (!soundUnlockTip.value) {
ElMessage.warning('请点击一次小喇叭开启数字人声音');
}
soundUnlockTip.value = true; soundUnlockTip.value = true;
ElMessage.warning('请点击屏幕任意位置,数字人将开启声音并重新口播');
showToolbar(); showToolbar();
return; return;
} }
@ -331,7 +333,7 @@ const tryPlayPendingAnswer = async () => {
dhIframe.playVideo(true); dhIframe.playVideo(true);
dhIframe.muteAudio(false); dhIframe.muteAudio(false);
videoIsMuted.value = false; videoIsMuted.value = false;
await new Promise(resolve => setTimeout(resolve, 350)); await new Promise(resolve => window.setTimeout(resolve, 240));
} else if (!soundEnabled.value && !videoIsMuted.value) { } else if (!soundEnabled.value && !videoIsMuted.value) {
dhIframe.muteAudio(true); dhIframe.muteAudio(true);
videoIsMuted.value = true; videoIsMuted.value = true;
@ -381,32 +383,9 @@ const handleVoiceError = (message) => {
const handleVoiceStatus = (message) => { const handleVoiceStatus = (message) => {
voiceStatus.value = message; voiceStatus.value = message;
}; };
const handleMute = () => {
const nextEnabled = !soundEnabled.value;
soundEnabled.value = nextEnabled;
if (nextEnabled) {
audioUnlocked.value = true;
soundUnlockTip.value = false;
if (showHuman.value) dhIframe.playVideo(true);
} else {
soundUnlockTip.value = false;
}
if (!showHuman.value) {
showToolbar();
return;
}
dhIframe.muteAudio(!nextEnabled);
window.setTimeout(() => {
if (showHuman.value) {
videoIsMuted.value = !nextEnabled;
if (nextEnabled) void tryPlayPendingAnswer();
}
}, 300);
showToolbar();
};
const unlockAudioAndPlay = () => { const unlockAudioAndPlay = () => {
if (!soundEnabled.value) return;
if (audioUnlocked.value && !soundUnlockTip.value) return; if (audioUnlocked.value && !soundUnlockTip.value) return;
soundEnabled.value = true;
audioUnlocked.value = true; audioUnlocked.value = true;
soundUnlockTip.value = false; soundUnlockTip.value = false;
if (showHuman.value) { if (showHuman.value) {
@ -418,6 +397,20 @@ const unlockAudioAndPlay = () => {
connectHuman(); connectHuman();
} }
}; };
const enableSound = () => {
soundEnabled.value = true;
audioUnlocked.value = true;
soundUnlockTip.value = false;
if (showHuman.value) {
dhIframe.playVideo(true);
dhIframe.muteAudio(false);
videoIsMuted.value = false;
window.setTimeout(() => void tryPlayPendingAnswer(), 120);
} else if (pendingSpeechText.value) {
connectHuman();
}
showToolbar();
};
const keepConnectionAlive = () => { const keepConnectionAlive = () => {
showTimeoutTip.value = false; showTimeoutTip.value = false;
sendSpeech('我还在,很高兴继续为你服务。'); sendSpeech('我还在,很高兴继续为你服务。');
@ -439,7 +432,7 @@ const onMessage = (event) => {
humanVisualReady.value = false; humanVisualReady.value = false;
} }
if (content.action === 'localVideoMuted') { if (content.action === 'localVideoMuted') {
videoIsMuted.value = parseMutedState(content.body); if (parseMutedState(content.body)) videoIsMuted.value = true;
if (soundEnabled.value && videoIsMuted.value && !audioUnlocked.value if (soundEnabled.value && videoIsMuted.value && !audioUnlocked.value
&& (pendingSpeechText.value || speechBusy.value)) { && (pendingSpeechText.value || speechBusy.value)) {
soundUnlockTip.value = true; soundUnlockTip.value = true;