File size: 4,992 Bytes
0f941de
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a8e33ed
eaeaa29
 
 
0f941de
 
 
 
 
 
 
 
 
 
eaeaa29
 
eb067a7
 
 
eaeaa29
 
 
 
 
0f941de
 
 
 
eaeaa29
 
 
 
0f941de
 
 
 
 
 
 
eb067a7
0f941de
 
 
eaeaa29
0f941de
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
eaeaa29
0f941de
 
 
 
 
eaeaa29
0f941de
 
 
 
 
 
 
 
 
 
eaeaa29
0f941de
 
59d50fc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Voice Chat Bot</title>
    <script src="https://cdn.jsdelivr.net/npm/onnxruntime-web/dist/ort.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/@ricky0123/[email protected]/dist/bundle.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/@xenova/[email protected]"></script>
    <style>
        body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; }
        button { font-size: 18px; padding: 10px 20px; margin: 10px 0; }
        #conversation { border: 1px solid #ccc; padding: 10px; height: 300px; overflow-y: scroll; margin-bottom: 10px; }
    </style>
</head>
<body>
    <h1>Voice Chat Bot</h1>
    <div id="conversation"></div>
    <button id="startButton">Start Listening</button>
    <button id="stopButton" disabled>Stop Listening</button>

    <script type="module">
        import { pipeline, env } from 'https://cdn.jsdelivr.net/npm/@xenova/[email protected]';

        // Set the local directory for caching models
        env.localModelPath = './models';

        const conversationDiv = document.getElementById('conversation');
        const startButton = document.getElementById('startButton');
        const stopButton = document.getElementById('stopButton');

        let myvad;
        let sttPipeline;
        let ttsPipeline;

        async function initializePipelines() {
            try {
                sttPipeline = await pipeline('automatic-speech-recognition', 'Xenova/whisper-tiny.en');
                ttsPipeline = await pipeline('text-to-speech', 'Xenova/mms-tts-eng', {
                    quantized: false,
                });
                addMessage('System', 'Voice Chat Bot initialized. Click "Start Listening" to begin.');
            } catch (error) {
                console.error('Error initializing pipelines:', error);
                addMessage('System', 'Error initializing Voice Chat Bot. Please check the console for details.');
            }
        }

        async function processSpeech(audio) {
            try {
                if (!sttPipeline || !ttsPipeline) {
                    throw new Error('Pipelines not initialized');
                }

                const transcription = await sttPipeline(audio);
                addMessage('User', transcription.text);
                
                // Placeholder for LLM response
                const botResponse = `I heard you say: "${transcription.text}". This is a placeholder response.`;
                addMessage('Bot', botResponse);

                const speechOutput = await ttsPipeline(botResponse);
                playAudio(speechOutput.audio);
            } catch (error) {
                console.error('Error processing speech:', error);
                addMessage('System', 'Error processing speech. Please try again.');
            }
        }

        function addMessage(sender, message) {
            const messageElement = document.createElement('p');
            messageElement.innerHTML = `<strong>${sender}:</strong> ${message}`;
            conversationDiv.appendChild(messageElement);
            conversationDiv.scrollTop = conversationDiv.scrollHeight;
        }

        function playAudio(audioArray) {
            const audioContext = new (window.AudioContext || window.webkitAudioContext)();
            const audioBuffer = audioContext.createBuffer(1, audioArray.length, 16000);
            const channelData = audioBuffer.getChannelData(0);
            channelData.set(audioArray);

            const source = audioContext.createBufferSource();
            source.buffer = audioBuffer;
            source.connect(audioContext.destination);
            source.start();
        }

        async function startListening() {
            try {
                myvad = await vad.MicVAD.new({
                    onSpeechEnd: (audio) => {
                        processSpeech(audio);
                    }
                });
                await myvad.start();
                startButton.disabled = true;
                stopButton.disabled = false;
                addMessage('System', 'Listening...');
            } catch (error) {
                console.error('Error starting VAD:', error);
                addMessage('System', 'Error starting voice detection. Please check your microphone and try again.');
            }
        }

        function stopListening() {
            if (myvad) {
                myvad.pause();
                startButton.disabled = false;
                stopButton.disabled = true;
                addMessage('System', 'Stopped listening.');
            }
        }

        startButton.addEventListener('click', startListening);
        stopButton.addEventListener('click', stopListening);

        // Initialize pipelines when the page loads
        initializePipelines();
    </script>
</body>
</html>