| |
|
| | const recordButton = document.getElementById('recordButton'); |
| | const audioPlayback = document.getElementById('audioPlayback'); |
| | const resetButton = document.getElementById('resetButton'); |
| |
|
| | let mediaRecorder; |
| | let audioChunks = []; |
| | let isRecording = false; |
| | let conversationHistory = []; |
| | let resetTimer; |
| |
|
| | function getModel() { |
| | return document.getElementById('modelSelect').value; |
| | } |
| |
|
| | function getWhisperModel() { |
| | return document.getElementById('whisperModelSelect').value; |
| | } |
| |
|
| | function getTTSModel() { |
| | return document.getElementById('ttsModelSelect').value; |
| | } |
| |
|
| | function resetConversation() { |
| | conversationHistory = []; |
| | console.log("Conversation has been reset."); |
| | clearTimeout(resetTimer); |
| | } |
| |
|
| | function setResetTimer() { |
| | clearTimeout(resetTimer); |
| | resetTimer = setTimeout(resetConversation, 300000); |
| | } |
| |
|
| | recordButton.addEventListener('click', toggleRecording); |
| | resetButton.addEventListener('click', resetConversation); |
| |
|
| | function toggleRecording() { |
| | if (!isRecording) { |
| | startRecording(); |
| | } else { |
| | stopRecording(); |
| | } |
| | } |
| |
|
| | async function startRecording() { |
| | document.getElementById("recording").style.display = "block"; |
| | document.getElementById("resetButton").style.display = "none"; |
| | if (!navigator.mediaDevices) { |
| | alert('MediaDevices API not supported!'); |
| | return; |
| | } |
| | const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); |
| | mediaRecorder = new MediaRecorder(stream); |
| | audioChunks = []; |
| | mediaRecorder.ondataavailable = (event) => { |
| | audioChunks.push(event.data); |
| | }; |
| | mediaRecorder.start(); |
| | recordButton.textContent = 'Stop Recording'; |
| | |
| | recordButton.classList.add("bg-gray-500"); |
| | |
| | isRecording = true; |
| | } |
| |
|
| | function stopRecording() { |
| | mediaRecorder.stop(); |
| | mediaRecorder.onstop = async () => { |
| | document.getElementById("recording").style.display = "none"; |
| | document.getElementById("recordButton").style.display = "none"; |
| |
|
| | document.getElementById("loader").style.display = "block"; |
| | const audioBlob = new Blob(audioChunks, { type: 'audio/webm' }); |
| | document.getElementById("statustext").textContent = "Processing audio..."; |
| | const transcript = await sendAudioToWhisper(audioBlob); |
| | console.log("Transcript:", transcript); |
| | document.getElementById("statustext").textContent = "Seems you said: " + transcript+ ". Generating response..."; |
| | const responseText = await sendTextToChatGPT(transcript); |
| |
|
| | console.log("Response:", responseText); |
| | document.getElementById("statustext").textContent = "Response generated: '" + responseText + "'. Generating audio response..."; |
| |
|
| | const ttsAudio = await getTextToSpeechAudio(responseText); |
| | playAudioResponse(ttsAudio); |
| |
|
| | recordButton.textContent = 'Record'; |
| | |
| | recordButton.classList.remove("bg-gray-500"); |
| | isRecording = false; |
| | document.getElementById("loader").style.display = "none"; |
| | document.getElementById("recordButton").style.display = "block"; |
| | document.getElementById("resetButton").style.display = "block"; |
| | document.getElementById("statustext").textContent = "Press the record button to start recording."; |
| | }; |
| | } |
| |
|
| | async function sendAudioToWhisper(audioBlob) { |
| | const formData = new FormData(); |
| | formData.append('file', audioBlob); |
| | formData.append('model', getWhisperModel()); |
| |
|
| | const response = await fetch('v1/audio/transcriptions', { |
| | method: 'POST', |
| | body: formData |
| | }); |
| |
|
| | const result = await response.json(); |
| | console.log("Whisper result:", result) |
| | return result.text; |
| | } |
| |
|
| | async function sendTextToChatGPT(text) { |
| | conversationHistory.push({ role: "user", content: text }); |
| |
|
| | const response = await fetch('v1/chat/completions', { |
| | method: 'POST', |
| | headers: { "Content-Type": "application/json" }, |
| | body: JSON.stringify({ |
| | model: getModel(), |
| | messages: conversationHistory |
| | }) |
| | }); |
| |
|
| | const result = await response.json(); |
| | const responseText = result.choices[0].message.content; |
| | conversationHistory.push({ role: "assistant", content: responseText }); |
| |
|
| | setResetTimer(); |
| |
|
| | return responseText; |
| | } |
| |
|
| | async function getTextToSpeechAudio(text) { |
| | const response = await fetch('v1/audio/speech', { |
| | |
| | method: 'POST', |
| | headers: { |
| | 'Content-Type': 'application/json' |
| | }, |
| | body: JSON.stringify({ |
| | |
| | input: text, |
| | model: getTTSModel(), |
| | |
| | }) |
| | }); |
| |
|
| | const audioBlob = await response.blob(); |
| | return audioBlob; |
| | } |
| |
|
| | function playAudioResponse(audioBlob) { |
| | const audioUrl = URL.createObjectURL(audioBlob); |
| | audioPlayback.src = audioUrl; |
| | audioPlayback.hidden = false; |
| | audioPlayback.play(); |
| | } |
| |
|
| |
|