Untitled
unknown
plain_text
a year ago
4.9 kB
9
Indexable
import React, { useState, useEffect, useRef } from 'react';
function App() {
const [microphones, setMicrophones] = useState([]);
const [speakers, setSpeakers] = useState([]);
const [selectedMicrophone, setSelectedMicrophone] = useState('');
const [selectedSpeaker, setSelectedSpeaker] = useState('');
const [recording, setRecording] = useState(false);
const [receivedText, setReceivedText] = useState('');
const [webSocket, setWebSocket] = useState(null);
const mediaRecorderRef = useRef(null);
const audioPlayerRef = useRef(null);
useEffect(() => {
getMediaDevices();
}, []);
const getMediaDevices = async () => {
const devices = await navigator.mediaDevices.enumerateDevices();
const microphones = devices.filter(device => device.kind === 'audioinput');
const speakers = devices.filter(device => device.kind === 'audiooutput');
setMicrophones(microphones);
setSpeakers(speakers);
};
const startRecording = async () => {
const stream = await navigator.mediaDevices.getUserMedia({
audio: { deviceId: selectedMicrophone ? { exact: selectedMicrophone } : undefined }
});
const mediaRecorder = new MediaRecorder(stream);
mediaRecorderRef.current = mediaRecorder;
mediaRecorder.ondataavailable = (event) => {
if (event.data.size > 0 && webSocket && webSocket.readyState === WebSocket.OPEN) {
webSocket.send(event.data);
}
};
mediaRecorder.start(100);
setupWebSocket();
setRecording(true);
};
const stopRecording = () => {
if (mediaRecorderRef.current) {
mediaRecorderRef.current.stop();
setRecording(false);
}
if (webSocket) {
webSocket.close();
}
};
const setupWebSocket = () => {
const ws = new WebSocket('ws://apex-bff.azurewebsites.net/Translation/ws'); // Adjust WebSocket URL if needed
ws.onopen = () => {
console.log('WebSocket connection opened.');
};
ws.onclose = () => {
console.log('WebSocket connection closed.');
};
ws.onerror = (error) => {
console.error('WebSocket error:', error);
};
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
if (message.Audio) {
const mimeType = 'audio/wav';
const audioDataUrl = `data:${mimeType};base64,${message.Audio}`;
playAudio(audioDataUrl);
}
if (message.Text) {
setReceivedText(prevText => `${prevText}\n${message.Text}`);
}
};
setWebSocket(ws);
};
const playAudio = (audioDataUrl) => {
const audio = new Audio(audioDataUrl);
audio.onended = () => {
audioPlayerRef.current.src = audioDataUrl;
audioPlayerRef.current.play();
};
audio.play();
};
return (
<div>
<h1>Continuous Microphone Audio to WebSocket Server</h1>
<div>
<label htmlFor="microphoneSelect">Select Microphone: </label>
<select
id="microphoneSelect"
onChange={(e) => setSelectedMicrophone(e.target.value)}
value={selectedMicrophone}
>
<option value="">Default Microphone</option>
{microphones.map((mic) => (
<option key={mic.deviceId} value={mic.deviceId}>
{mic.label}
</option>
))}
</select>
</div>
<div>
<label htmlFor="speakerSelect">Select Speaker: </label>
<select
id="speakerSelect"
onChange={(e) => setSelectedSpeaker(e.target.value)}
value={selectedSpeaker}
>
<option value="">Default Speaker</option>
{speakers.map((speaker) => (
<option key={speaker.deviceId} value={speaker.deviceId}>
{speaker.label}
</option>
))}
</select>
</div>
<button onClick={startRecording} disabled={recording}>Start Recording</button>
<button onClick={stopRecording} disabled={!recording}>Stop Recording</button>
<div id="status">Status: {recording ? 'Recording' : 'Not Recording'}</div>
<div id="receivedText" style={{ marginTop: '20px', border: '1px solid #ddd', padding: '10px', width: '400px', height: '200px', overflowY: 'scroll' }}>
{receivedText.split('\n').map((text, idx) => (
<div key={idx}>{text}</div>
))}
</div>
<audio id="audioPlayer" ref={audioPlayerRef} controls></audio>
</div>
);
}
export default App;
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import './index.css';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
body {
font-family: Arial, sans-serif;
}
#status {
margin-top: 10px;
}
#receivedText {
margin-top: 20px;
border: 1px solid #ddd;
padding: 10px;
width: 400px;
height: 200px;
overflow-y: scroll;
}
Editor is loading...
Leave a Comment