sp/src/pages/web-tools/deep-speech.astro

73 lines
2.7 KiB
Plaintext

---
import Layout from "../../layouts/Layout.astro";
---
<Layout title="DeepSpeech Streaming STT">
<h1>DeepSpeech Real-Time Transcription</h1>
<button id="startBtn">Start Listening</button>
<button id="stopBtn" disabled>Stop</button>
<div id="transcript"></div>
</Layout>
<script is:inline>
const startBtn = document.getElementById('startBtn');
const stopBtn = document.getElementById('stopBtn');
const transcriptDiv = document.getElementById('transcript');
let mediaStream;
let audioContext;
let processor;
let websocket;
startBtn.addEventListener('click', async () => {
try {
// Initialize WebSocket
websocket = new WebSocket('ws://localhost:3000');
websocket.onmessage = (event) => {
const data = JSON.parse(event.data);
transcriptDiv.innerHTML += data.transcript + (data.isFinal ? '<br>' : ' ');
};
// Get microphone
mediaStream = await navigator.mediaDevices.getUserMedia({ audio: true });
// Set up audio processing (16kHz, mono for DeepSpeech)
audioContext = new (window.AudioContext || window.webkitAudioContext)();
const source = audioContext.createMediaStreamSource(mediaStream);
// Resample to 16kHz (DeepSpeech requirement)
const downsampler = audioContext.createScriptProcessor(4096, 1, 1);
downsampler.onaudioprocess = (e) => {
const inputData = e.inputBuffer.getChannelData(0);
const pcm16 = new Int16Array(inputData.length);
for (let i = 0; i < inputData.length; i++) {
pcm16[i] = Math.max(-32768, Math.min(32767, inputData[i] * 32768));
}
if (websocket.readyState === WebSocket.OPEN) {
websocket.send(pcm16.buffer);
}
};
source.connect(downsampler);
downsampler.connect(audioContext.destination);
// Notify server to start processing
websocket.onopen = () => {
websocket.send('start');
startBtn.disabled = true;
stopBtn.disabled = false;
};
} catch (err) {
console.error('Error:', err);
}
});
stopBtn.addEventListener('click', () => {
if (mediaStream) mediaStream.getTracks().forEach(track => track.stop());
if (websocket) websocket.send('end');
startBtn.disabled = false;
stopBtn.disabled = true;
});
</script>