Untitled

mail@pastecode.io avatar
unknown
javascript
a month ago
17 kB
3
Indexable
Never
/* 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;
Leave a Comment