Untitled
unknown
javascript
2 years ago
17 kB
22
Indexable
/* eslint-disable react/jsx-no-target-blank */
/* eslint-disable react-hooks/exhaustive-deps */
/* eslint-disable no-unused-vars */
import { Col, Input, Row } from 'antd';
import React, { useEffect, useRef, useState } from 'react';
import { Form } from 'react-bootstrap';
import { microphone, microphone2 } from '../icons/icon';
const Translater = () => {
const [microphones, setMicrophones] = useState([]);
const [speakers, setSpeakers] = useState([]);
const [output1, setOutput1] = useState('');
const [output2, setOutput2] = useState('');
const [originalText1, setOriginalText1] = useState('');
const [originalText2, setOriginalText2] = useState('');
const [webSocket, setWebSocket] = useState(null);
const [recording, setRecording] = useState(false);
const [formData, setFormData] = useState({
microphone: '',
target_output_1: '',
target_output_2: ''
});
const mediaRecorderRef = useRef(null);
const audioPlayerRef1 = useRef(null);
const audioPlayerRef2 = useRef(null);
useEffect(() => {
const getMediaDevices = async () => {
let stream = null;
try {
stream = await navigator.mediaDevices.getUserMedia({ audio: true, video: false });
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);
} catch (error) {
console.error('Error getting media devices:', error);
} finally {
if (stream) {
stream.getTracks().forEach(track => track.stop());
}
}
};
getMediaDevices();
}, []);
const handleChange = (e) => {
const { name, value } = e.target;
setFormData(prevData => ({
...prevData,
[name]: value
}));
};
// Function to play audio
const playAudio = async (audioDataUrl, outputRef, speakerId) => {
if (outputRef.current) {
try {
await outputRef.current.setSinkId(speakerId);
} catch (error) {
console.error('Error setting sink ID:', error);
}
outputRef.current.src = audioDataUrl;
outputRef.current.play();
}
};
// Function to setup WebSocket connection
const setupWebSocket = () => {
return new Promise((resolve, reject) => {
const ws = new WebSocket('wss://apex-bff.azurewebsites.net/Translation/ws');
ws.onopen = () => {
resolve(ws);
};
ws.onclose = (event) => {
setWebSocket(null);
};
ws.onerror = (error) => {
reject(error);
};
ws.onmessage = (event) => {
try {
console.log(event.data);
const message = JSON.parse(event.data);
const mimeType = 'audio/wav';
const audioDataUrl = `data:${mimeType};base64,${message.TranslatedAudio}`;
console.log(message);
if (message.TranslateLanguage === 'en') {
setOutput1(prevText => `${prevText} ${message.TranslatedText}`);
setOriginalText1(prevText => `${prevText} ${message.Originaltext}`);
playAudio(audioDataUrl, audioPlayerRef1, formData.target_output_1);
} else if (message.TranslateLanguage === 'es') {
setOutput2(prevText => `${prevText} ${message.TranslatedText}`);
setOriginalText2(prevText => `${prevText} ${message.Originaltext}`);
playAudio(audioDataUrl, audioPlayerRef2, formData.target_output_2);
}
} catch (e) {
console.error('Error processing WebSocket message:', e);
}
};
setWebSocket(ws);
});
};
// PCM16 conversion function
const floatTo16BitPCM = (input) => {
const buffer = new ArrayBuffer(input.length * 2);
const view = new DataView(buffer);
for (let i = 0; i < input.length; i++) {
let s = Math.max(-1, Math.min(1, input[i]));
s = s < 0 ? s * 0x8000 : s * 0x7FFF;
view.setInt16(i * 2, s, true);
}
return buffer;
};
// Function to start recording
const startRecording = async () => {
if (mediaRecorderRef.current && mediaRecorderRef.current.state === 'recording') {
return;
}
try {
const ws = await setupWebSocket();
const stream = await navigator.mediaDevices.getUserMedia({
audio: { deviceId: formData.microphone ? { exact: formData.microphone } : undefined }
});
const audioContext = new (window.AudioContext || window.webkitAudioContext)();
const source = audioContext.createMediaStreamSource(stream);
const processor = audioContext.createScriptProcessor(4096, 1, 1);
processor.onaudioprocess = (event) => {
if (ws && ws.readyState === WebSocket.OPEN) {
const inputData = event.inputBuffer.getChannelData(0);
const pcm16Data = floatTo16BitPCM(inputData);
ws.send(pcm16Data);
}
};
source.connect(processor);
processor.connect(audioContext.destination);
mediaRecorderRef.current = processor;
setRecording(true);
} catch (error) {
console.error('Error starting recording:', error);
}
};
const stopRecording = () => {
if (mediaRecorderRef.current) {
mediaRecorderRef.current.disconnect();
}
if (webSocket) {
webSocket.close();
}
setRecording(false);
};
const handleSubmit = (e) => {
e.preventDefault();
if (recording) {
stopRecording();
} else {
startRecording();
}
};
return (
<main className='lg:container py-3 px-3 px-md-5 mx-auto' style={{ minHeight: '88vh' }}>
<h2 className='roboto_regular text_black'>Translator</h2>
<div className="bg_white shadow-sm rounded-3 px-3 px-md-5 py-4">
<Form onSubmit={handleSubmit} className="mx-auto w-100 my-4">
<div className="flex flex-col w-full">
<div className="flex flex-col mb-3 gap-2 w-full justify-center items-center">
<button type="submit">
<img src={recording ? microphone : microphone2} style={{ width: '140px', height: '140px' }} alt="Microphone" />
</button>
<span className="roboto_regular mb-3 text_dark text-lg">{recording ? 'Microphone capturing....' : 'Initiate Translation Session'}</span>
<div className="flex flex-col items-start" style={{ width: '100%', maxWidth: '500px' }}>
<span className='roboto_regular mb-1 text_secondary w-full'>Choose Input Microphone</span>
<Form.Select name='microphone'
size='large'
className="custom_control rounded-3 manrope_regular text_secondarydark bg_white border"
onChange={handleChange}
>
<option value=''>Default Microphone</option>
{microphones.length > 0 ? microphones.map((mic) => (
<option key={mic.deviceId} value={mic.deviceId}>
{mic.label || 'Unnamed Microphone'}
</option>
)) : <option value="">No Microphones Found</option>}
</Form.Select>
</div>
</div>
<Row gutter={16}>
<Col xs={24} md={12}>
<div className="flex flex-col mb-3 w-full">
<span className='roboto_regular mb-1 text_secondary w-full'>Choose a Target Language 1*</span>
<Form.Group name='target_language_1'>
<Form.Control
size='large'
value='English'
readOnly
className="custom_control rounded-3 manrope_regular text_secondarydark bg_white border"
/>
</Form.Group>
</div>
</Col>
<Col xs={24} md={12}>
<div className="flex flex-col mb-3 w-full">
<span className='roboto_regular mb-1 text_secondary w-full'>Choose a Target Language 2</span>
<Form.Group name='target_language_2'>
<Form.Control
size='large'
value='Spanish'
readOnly
className="custom_control rounded-3 manrope_regular text_secondarydark bg_white border"
/>
</Form.Group>
</div>
</Col>
</Row>
<Row gutter={16}>
<Col xs={24} md={12}>
<div className="flex flex-col mb-3 w-full">
<span className='roboto_regular mb-1 text_secondary w-full'>Choose a Target Output 1*</span>
<Form.Select
size="large"
required={!recording}
name='target_output_1'
className="custom_control rounded-3 manrope_regular text_secondarydark bg_white border"
onChange={handleChange}
>
<option value="">Select Speaker</option>
{speakers.length > 0 ? speakers.map((speaker) => (
<option key={speaker.deviceId} value={speaker.deviceId}>
{speaker.label || 'Unnamed Speaker'}
</option>
)) : <option value="">No Speakers Found</option>}
</Form.Select>
</div>
</Col>
<Col xs={24} md={12}>
<div className="flex flex-col mb-3 w-full">
<span className='roboto_regular mb-1 text_secondary w-full'>Choose a Target Output 2</span>
<Form.Select
size="large"
required={!recording}
name='target_output_2'
className="custom_control rounded-3 manrope_regular text_secondarydark bg_white border"
onChange={handleChange}
>
<option value="">Select Speaker</option>
{speakers.length > 0 ? speakers.map((speaker) => (
<option key={speaker.deviceId} value={speaker.deviceId}>
{speaker.label || 'Unnamed Speaker'}
</option>
)) : <option value="">No Speakers Found</option>}
</Form.Select>
</div>
</Col>
</Row>
<Row gutter={16}>
<Col xs={24} md={12}>
<div className="flex flex-col mb-3 w-full">
<span className='roboto_regular mb-1 text_secondary w-full'>Translated Output 1</span>
<Input.TextArea
rows={4}
className="custom_control rounded-3 manrope_regular text_secondarydark bg_white border"
value={output1}
readOnly
/>
<audio ref={audioPlayerRef1} controls style={{ display: 'none' }}>
Your browser does not support the audio element.
</audio>
{/* <button
onClick={() => alert(originalText1)}
className="custom_control rounded-3 manrope_regular text_secondarydark bg_white border"
style={{ marginTop: '10px' }}>
Show Original Text
</button> */}
</div>
<div className="flex flex-col mb-3 w-full">
<span className='roboto_regular mb-1 text_secondary w-full'>Orignal Text 1</span>
<Input.TextArea
rows={4}
className="custom_control rounded-3 manrope_regular text_secondarydark bg_white border"
value={originalText1}
readOnly
/>
</div>
</Col>
<Col xs={24} md={12}>
<div className="flex flex-col mb-3 w-full">
<span className='roboto_regular mb-1 text_secondary w-full'>Translated Output 2</span>
<Input.TextArea
rows={4}
className="custom_control rounded-3 manrope_regular text_secondarydark bg_white border"
value={output2}
readOnly
/>
<audio ref={audioPlayerRef2} style={{ display: 'none' }} controls>
Your browser does not support the audio element.
</audio>
{/* <button
onClick={() => alert(originalText2)}
className="custom_control rounded-3 manrope_regular text_secondarydark bg_white border"
style={{ marginTop: '10px' }}>
Show Original Text
</button> */}
</div>
<div className="flex flex-col mb-3 w-full">
<span className='roboto_regular mb-1 text_secondary w-full'>Orignal Text 2</span>
<Input.TextArea
rows={4}
className="custom_control rounded-3 manrope_regular text_secondarydark bg_white border"
value={originalText2}
readOnly
/>
</div>
</Col>
</Row>
</div>
</Form>
</div>
</main>
);
};
export default Translater;Editor is loading...
Leave a Comment