← back to Dear Bubbe Nextjs
public/test-microphone.html
247 lines
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Microphone Test</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 50px auto;
padding: 20px;
background: linear-gradient(to bottom, #667eea, #764ba2);
color: white;
min-height: 100vh;
}
.container {
background: rgba(255, 255, 255, 0.1);
border-radius: 10px;
padding: 30px;
}
h1 {
text-align: center;
margin-bottom: 30px;
}
.button-container {
display: flex;
gap: 20px;
justify-content: center;
margin-bottom: 30px;
}
button {
padding: 15px 30px;
font-size: 18px;
border: none;
border-radius: 5px;
cursor: pointer;
transition: all 0.3s;
}
button:hover:not(:disabled) {
transform: scale(1.05);
}
button:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.start-btn {
background: #10b981;
color: white;
}
.stop-btn {
background: #ef4444;
color: white;
}
.status {
text-align: center;
font-size: 20px;
margin: 20px 0;
padding: 15px;
background: rgba(0, 0, 0, 0.2);
border-radius: 5px;
}
.transcript {
background: rgba(255, 255, 255, 0.1);
padding: 20px;
border-radius: 5px;
min-height: 100px;
margin-top: 20px;
}
.error {
background: rgba(239, 68, 68, 0.2);
color: #fca5a5;
padding: 15px;
border-radius: 5px;
margin-top: 20px;
}
.success {
background: rgba(16, 185, 129, 0.2);
color: #6ee7b7;
}
.info {
background: rgba(59, 130, 246, 0.2);
color: #93c5fd;
padding: 15px;
border-radius: 5px;
margin-bottom: 20px;
}
</style>
</head>
<body>
<div class="container">
<h1>🎤 Microphone Test for Bubbe</h1>
<div class="info">
<p><strong>Instructions:</strong></p>
<ol>
<li>Click "Start Recording" to test microphone access</li>
<li>Allow microphone permissions when prompted</li>
<li>Speak into your microphone</li>
<li>Your speech will be converted to text below</li>
<li>Click "Stop Recording" when done</li>
</ol>
</div>
<div class="button-container">
<button id="startBtn" class="start-btn">Start Recording</button>
<button id="stopBtn" class="stop-btn" disabled>Stop Recording</button>
</div>
<div id="status" class="status">Ready to test microphone</div>
<div class="transcript">
<h3>Transcript:</h3>
<p id="transcript">No speech detected yet...</p>
</div>
<div id="error" class="error" style="display: none;"></div>
</div>
<script>
let recognition = null;
const startBtn = document.getElementById('startBtn');
const stopBtn = document.getElementById('stopBtn');
const status = document.getElementById('status');
const transcript = document.getElementById('transcript');
const errorDiv = document.getElementById('error');
// Check for browser support
if (!('webkitSpeechRecognition' in window) && !('SpeechRecognition' in window)) {
errorDiv.style.display = 'block';
errorDiv.innerHTML = '<strong>Error:</strong> Speech recognition is not supported in this browser. Please use Chrome, Edge, or Safari.';
startBtn.disabled = true;
} else {
// Initialize speech recognition
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
recognition = new SpeechRecognition();
recognition.continuous = true;
recognition.interimResults = true;
recognition.lang = 'en-US';
recognition.onstart = () => {
status.textContent = '🔴 Recording... Speak now!';
status.classList.add('success');
startBtn.disabled = true;
stopBtn.disabled = false;
errorDiv.style.display = 'none';
};
recognition.onend = () => {
status.textContent = 'Recording stopped';
status.classList.remove('success');
startBtn.disabled = false;
stopBtn.disabled = true;
};
recognition.onresult = (event) => {
let finalTranscript = '';
let interimTranscript = '';
for (let i = event.resultIndex; i < event.results.length; i++) {
const result = event.results[i];
if (result.isFinal) {
finalTranscript += result[0].transcript + ' ';
} else {
interimTranscript += result[0].transcript;
}
}
if (finalTranscript || interimTranscript) {
transcript.innerHTML = '<strong>Final:</strong> ' + finalTranscript +
'<br><strong>Interim:</strong> <em>' + interimTranscript + '</em>';
}
};
recognition.onerror = (event) => {
errorDiv.style.display = 'block';
let errorMessage = '';
switch(event.error) {
case 'not-allowed':
errorMessage = 'Microphone permission denied. Please allow microphone access and refresh the page.';
break;
case 'no-speech':
errorMessage = 'No speech detected. Please try speaking again.';
break;
case 'audio-capture':
errorMessage = 'No microphone found. Please check your microphone connection.';
break;
case 'network':
errorMessage = 'Network error. Please check your internet connection.';
break;
default:
errorMessage = 'Error: ' + event.error;
}
errorDiv.innerHTML = '<strong>Error:</strong> ' + errorMessage;
status.textContent = 'Error occurred';
startBtn.disabled = false;
stopBtn.disabled = true;
};
}
startBtn.addEventListener('click', async () => {
try {
// Check if mediaDevices is available before trying to access it
if (navigator && navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
try {
// First request microphone permission
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
stream.getTracks().forEach(track => track.stop()); // Stop the test stream
} catch (permErr) {
console.log('Permission request failed, continuing anyway:', permErr);
}
}
// Start recognition (it will handle permissions on its own)
recognition.start();
} catch (err) {
errorDiv.style.display = 'block';
errorDiv.innerHTML = '<strong>Error:</strong> ' + err.message;
}
});
stopBtn.addEventListener('click', () => {
if (recognition) {
recognition.stop();
}
});
// Test browser capabilities
window.addEventListener('load', () => {
const capabilities = [];
if ('mediaDevices' in navigator) capabilities.push('✅ Media Devices API');
else capabilities.push('❌ Media Devices API');
if ('getUserMedia' in navigator.mediaDevices || 'getUserMedia' in navigator) capabilities.push('✅ getUserMedia');
else capabilities.push('❌ getUserMedia');
if ('SpeechRecognition' in window || 'webkitSpeechRecognition' in window) capabilities.push('✅ Speech Recognition');
else capabilities.push('❌ Speech Recognition');
console.log('Browser Capabilities:', capabilities.join(' | '));
});
</script>
</body>
</html>