Untitled

 avatar
unknown
javascript
a year ago
14 kB
7
Indexable
/* eslint-disable no-unused-vars */import { Col, Row } from 'antd';
import React, { useEffect, useState, useRef } from 'react';
import { microphone, microphone2 } from '../icons/icon';
import { Form } from 'react-bootstrap';

const Translater = () => {
    const [microphones, setMicrophones] = useState([]);
    const [speakers, setSpeakers] = useState([]);
    const [output1, setOutput1] = useState('');
    const [output2, setOutput2] = 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
        }));
    };

    const playAudio = (audioDataUrl, outputRef) => {
        if (outputRef.current) {
            outputRef.current.src = audioDataUrl;
            outputRef.current.play();
        }
    };

    const setupWebSocket = () => {
        if (webSocket) {
            webSocket.close(); // Close existing WebSocket if any
        }

        const ws = new WebSocket('wss://apex-bff.azurewebsites.net/Translation/ws'); // Adjust WebSocket URL if needed

        ws.onopen = () => {
            console.log('WebSocket connection opened.');
        };

        ws.onclose = (event) => {
            console.log('WebSocket connection closed.', event.reason);
            setWebSocket(null); // Reset WebSocket state
        };

        ws.onerror = (error) => {
            console.error('WebSocket error:', error.message);
        };

        ws.onmessage = (event) => {
            console.log('WebSocket message received:', event.data);
            try {
                const message = JSON.parse(event.data);
                console.log(message);

                const mimeType = 'audio/wav'; // Adjust mimeType if needed
                const audioDataUrl = `data:${mimeType};base64,${message.TranslatedAudio}`;

                if (message.TranslateLanguage === 'en') {
                    setOutput1(prevText => `${prevText}\n${message.TranslatedText}`);
                    playAudio(audioDataUrl, audioPlayerRef1);
                } else {
                    setOutput2(prevText => `${prevText}\n${message.TranslatedText}`);
                    playAudio(audioDataUrl, audioPlayerRef2);
                }
            } catch (e) {
                console.error('Error processing WebSocket message:', e);
            }
        };

        setWebSocket(ws);
    };

    const startRecording = async () => {
        if (mediaRecorderRef.current && mediaRecorderRef.current.state === 'recording') {
            console.warn('Recording is already in progress.');
            return;
        }

        try {
            const stream = await navigator.mediaDevices.getUserMedia({
                audio: { deviceId: formData.microphone ? { exact: formData.microphone } : 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.onstart = () => {
                console.log('MediaRecorder started');
            };

            mediaRecorder.onstop = () => {
                console.log('MediaRecorder stopped');
            };

            mediaRecorder.start(100);
            setupWebSocket();

            setRecording(true);
        } catch (error) {
            console.error('Error starting recording:', error);
        }
    };

    const stopRecording = () => {
        if (mediaRecorderRef.current) {
            mediaRecorderRef.current.stop();
        }

        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"
                                        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>
                                    <textarea
                                        rows="4"
                                        className="custom_control rounded-3 manrope_regular text_secondarydark bg_white border"
                                        value={output1}
                                        readOnly
                                    />
                                    <audio ref={audioPlayerRef1} controls style={{ marginTop: '10px' }}>
                                        Your browser does not support the audio element.
                                    </audio>
                                </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>
                                    <textarea
                                        rows="4"
                                        className="custom_control rounded-3 manrope_regular text_secondarydark bg_white border"
                                        value={output2}
                                        readOnly
                                    />
                                    <audio ref={audioPlayerRef2} controls style={{ marginTop: '10px' }}>
                                        Your browser does not support the audio element.
                                    </audio>
                                </div>
                            </Col>
                        </Row>
                    </div>
                </Form>
            </div>
        </main>
    );
};

export default Translater;
Editor is loading...
Leave a Comment