fix: add audio unlock overlay for browser autoplay policy

- Add click-to-unlock overlay on big screen
- Play silent audio to unlock browser audio context
- Show unlock prompt before allowing audio playback

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
empty
2026-01-25 22:35:50 +08:00
parent 4eb2814391
commit 7ba92c81e9

View File

@@ -7,6 +7,7 @@ const router = useRouter();
const route = useRoute();
const displayStore = useDisplayStore();
const isFullscreen = ref(false);
const audioUnlocked = ref(false);
// Mode to route mapping
const modeRoutes: Record<string, string> = {
@@ -16,6 +17,20 @@ const modeRoutes: Record<string, string> = {
'results': '/screen/results',
};
// Unlock audio playback (required by browser autoplay policy)
function unlockAudio() {
// Create and play a silent audio to unlock
const silentAudio = new Audio('data:audio/mp3;base64,SUQzBAAAAAAAI1RTU0UAAAAPAAADTGF2ZjU4Ljc2LjEwMAAAAAAAAAAAAAAA//tQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWGluZwAAAA8AAAACAAABhgC7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7//////////////////////////////////////////////////////////////////8AAAAATGF2YzU4LjEzAAAAAAAAAAAAAAAAJAAAAAAAAAAAAYYoRwmHAAAAAAD/+1DEAAAGAAGn9AAAIgAANP8AAABM');
silentAudio.play().then(() => {
audioUnlocked.value = true;
console.log('[App] Audio unlocked');
}).catch(() => {
// Still mark as unlocked - user interaction happened
audioUnlocked.value = true;
console.log('[App] Audio unlock attempted');
});
}
function toggleFullscreen() {
if (!document.fullscreenElement) {
document.documentElement.requestFullscreen();
@@ -58,6 +73,14 @@ onUnmounted(() => {
<template>
<div class="screen-app" @dblclick="toggleFullscreen">
<!-- Audio unlock overlay -->
<div v-if="!audioUnlocked" class="audio-unlock-overlay" @click="unlockAudio">
<div class="unlock-content">
<div class="unlock-icon">🔊</div>
<div class="unlock-text">点击屏幕启用音频</div>
</div>
</div>
<router-view />
<!-- Fullscreen hint -->
@@ -135,4 +158,31 @@ onUnmounted(() => {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
.audio-unlock-overlay {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.8);
display: flex;
align-items: center;
justify-content: center;
z-index: 9999;
cursor: pointer;
}
.unlock-content {
text-align: center;
color: white;
}
.unlock-icon {
font-size: 64px;
margin-bottom: 20px;
animation: pulse 2s infinite;
}
.unlock-text {
font-size: 24px;
color: rgba(255, 255, 255, 0.8);
}
</style>