Spaces:
Running
Running
File size: 3,660 Bytes
7fb4a00 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Smart Earbud Volume Controller</title>
<!-- ONNX Runtime Web for running Silero VAD locally in browser -->
<script src="https://cdn.jsdelivr.net/npm/onnxruntime-web/dist/ort.min.js"></script>
<!-- ONNX VAD Helper library -->
<script src="https://cdn.jsdelivr.net/npm/@vapi-ai/vads-web/dist/index.umd.js"></script>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
background-color: #0f172a;
color: #f8fafc;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
}
.card {
background-color: #1e293b;
padding: 2rem;
border-radius: 12px;
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.5);
max-width: 450px;
width: 100%;
text-align: center;
}
button {
background-color: #3b82f6;
color: white;
border: none;
padding: 0.75rem 1.5rem;
font-size: 1rem;
font-weight: 600;
border-radius: 8px;
cursor: pointer;
margin-bottom: 1rem;
transition: background-color 0.2s;
}
button:hover { background-color: #2563eb; }
button:disabled { background-color: #64748b; cursor: not-allowed; }
.status-box {
margin-top: 1.5rem;
padding: 1rem;
border-radius: 8px;
background-color: #334155;
font-weight: 500;
}
.speaking { background-color: #991b1b; color: #fca5a5; }
.silent { background-color: #065f46; color: #a7f3d0; }
audio { width: 100%; margin-top: 1rem; }
</style>
</head>
<body>
<div class="card">
<h2>Auto-Ducking Earbud Simulator</h2>
<p>Play audio below, then start the microphone. When speech is detected, audio volume will automatically drop.</p>
<audio id="audioPlayer" controls loop src="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3"></audio>
<br/><br/>
<button id="startBtn">Start Voice Detection</button>
<div id="status" class="status-box silent">Status: Inactive</div>
</div>
<script>
let vad;
const audioPlayer = document.getElementById('audioPlayer');
const startBtn = document.getElementById('startBtn');
const statusDiv = document.getElementById('status');
let restoreTimeout;
startBtn.addEventListener('click', async () => {
try {
startBtn.disabled = true;
startBtn.innerText = "Initializing VAD...";
// Initialize VAD Engine
vad = await vad.MicVAD.new({
onSpeechStart: () => {
statusDiv.innerText = "Speech Detected: Lowering Volume";
statusDiv.className = "status-box speaking";
audioPlayer.volume = 0.2; // DUCK VOLUME (20%)
if (restoreTimeout) clearTimeout(restoreTimeout);
},
onSpeechEnd: () => {
statusDiv.innerText = "Silence: Restoring Volume soon...";
// Hold lower volume for 1.5s after speech stops
restoreTimeout = setTimeout(() => {
audioPlayer.volume = 1.0; // RESTORE VOLUME (100%)
statusDiv.innerText = "Monitoring Environment...";
statusDiv.className = "status-box silent";
}, 1500);
}
});
vad.start();
startBtn.innerText = "Listening...";
statusDiv.innerText = "Monitoring Environment...";
} catch (e) {
console.error(e);
alert("Microphone access denied or error loading model.");
startBtn.disabled = false;
startBtn.innerText = "Start Voice Detection";
}
});
</script>
</body>
</html> |