let socket = new WebSocket("ws://localhost:9001"); socket.onmessage = function(event) { let data = JSON.parse(event.data); if (data.type === 'realtime') { document.getElementById('realtimeText').value = data.text; } else if (data.type === 'fullSentence') { document.getElementById('fullSentenceText').value = data.text; } }; // Request access to the microphone navigator.mediaDevices.getUserMedia({ audio: true }) .then(stream => { let audioContext = new AudioContext(); let source = audioContext.createMediaStreamSource(stream); let processor = audioContext.createScriptProcessor(256, 1, 1); source.connect(processor); processor.connect(audioContext.destination); processor.onaudioprocess = function(e) { let inputData = e.inputBuffer.getChannelData(0); let outputData = new Int16Array(inputData.length); // Convert to 16-bit PCM for (let i = 0; i < inputData.length; i++) { outputData[i] = Math.max(-32768, Math.min(32767, inputData[i] * 32768)); } // Send the 16-bit PCM data to the server if (socket.readyState === WebSocket.OPEN) { // Create a JSON string with metadata let metadata = JSON.stringify({ sampleRate: audioContext.sampleRate }); // Convert metadata to a byte array let metadataBytes = new TextEncoder().encode(metadata); // Create a buffer for metadata length (4 bytes for 32-bit integer) let metadataLength = new ArrayBuffer(4); let metadataLengthView = new DataView(metadataLength); // Set the length of the metadata in the first 4 bytes metadataLengthView.setInt32(0, metadataBytes.byteLength, true); // true for little-endian // Combine metadata length, metadata, and audio data into a single message let combinedData = new Blob([metadataLength, metadataBytes, outputData.buffer]); socket.send(combinedData); } }; }) .catch(e => console.error(e));