InstantASRforYouNow / index.html
awacke1's picture
Update index.html
9dc594c verified
raw
history blame
4.74 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Simple ASR Client</title>
<script type="importmap">
{
"imports": {
"@xenova/transformers": "https://cdn.jsdelivr.net/npm/@xenova/[email protected]/+esm"
}
}
</script>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 20px auto;
padding: 20px;
}
#output {
margin-top: 20px;
padding: 10px;
border: 1px solid #ccc;
min-height: 100px;
}
.ready {
color: green;
font-weight: bold;
}
.loading {
color: orange;
}
.error {
color: red;
}
</style>
</head>
<body>
<h1>Simple Speech Recognition</h1>
<div id="status" class="loading">Loading model...</div>
<button id="startBtn" disabled>Start Recording</button>
<div id="output"></div>
<script type="module">
import { pipeline } from '@xenova/transformers';
let isRecording = false;
let mediaRecorder = null;
let audioChunks = [];
const statusElement = document.getElementById('status');
const startBtn = document.getElementById('startBtn');
const output = document.getElementById('output');
// Initialize the model
async function initModel() {
try {
console.log('Starting model loading...');
statusElement.textContent = 'Loading model...';
statusElement.className = 'loading';
const model = await pipeline('automatic-speech-recognition', 'Xenova/whisper-tiny');
console.log('Model loaded successfully!');
statusElement.textContent = 'MODEL LOADED SUCCESSFULLY! Ready to record.';
statusElement.className = 'ready';
startBtn.disabled = false;
startBtn.onclick = async () => {
if (!isRecording) {
try {
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
mediaRecorder = new MediaRecorder(stream);
audioChunks = [];
mediaRecorder.ondataavailable = (event) => {
audioChunks.push(event.data);
};
mediaRecorder.onstop = async () => {
const audioBlob = new Blob(audioChunks, { type: 'audio/wav' });
try {
const result = await model(audioBlob);
output.textContent += result.text + ' ';
} catch (e) {
console.error('Transcription error:', e);
statusElement.textContent = 'Error during transcription';
statusElement.className = 'error';
}
audioChunks = [];
};
mediaRecorder.start(1000);
isRecording = true;
startBtn.textContent = 'Stop Recording';
statusElement.textContent = 'Recording...';
statusElement.className = 'loading';
} catch (e) {
console.error('Recording error:', e);
statusElement.textContent = 'Error accessing microphone';
statusElement.className = 'error';
}
} else {
mediaRecorder.stop();
mediaRecorder.stream.getTracks().forEach(track => track.stop());
isRecording = false;
startBtn.textContent = 'Start Recording';
statusElement.textContent = 'Processing...';
statusElement.className = 'loading';
}
};
} catch (e) {
console.error('Model loading error:', e);
statusElement.textContent = 'Error loading model: ' + e.message;
statusElement.className = 'error';
}
}
// Start loading the model
initModel();
</script>
</body>
</html>