-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
739cff8
commit 7effcdb
Showing
6 changed files
with
223 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
from fastapi import FastAPI, WebSocket, WebSocketDisconnect, Request | ||
from fastapi.responses import HTMLResponse | ||
from fastapi.staticfiles import StaticFiles | ||
from fastapi.templating import Jinja2Templates | ||
import uvicorn | ||
from langchain_cohere import ChatCohere | ||
from langchain_core.messages import HumanMessage | ||
|
||
app = FastAPI() | ||
|
||
llm = ChatCohere(cohere_api_key='lMQ2FCVWccphyyB10tGpZg3oinBjGOixW0D3fmPd') | ||
|
||
app.mount("/static", StaticFiles(directory="static"), name="static") | ||
templates = Jinja2Templates(directory="templates") | ||
|
||
@app.get("/", response_class=HTMLResponse) | ||
async def index(request: Request): | ||
return templates.TemplateResponse("index.html", {"request": request}) | ||
|
||
@app.websocket("/transcribe") | ||
async def transcribe(websocket: WebSocket): | ||
await websocket.accept() | ||
|
||
while True: | ||
human_input = await websocket.receive_text() | ||
if human_input: | ||
human_message = [HumanMessage(content=human_input)] | ||
response = llm.invoke(human_message, max_tokens=80) | ||
await websocket.send_text(response.content) | ||
|
||
if __name__ == "__main__": | ||
uvicorn.run(app, host="0.0.0.0", port=5000, reload=True) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/* Speech recognition output */ | ||
.output-box { | ||
background-color: rgb(248 245 245); | ||
padding: 20px; | ||
border-radius: 10px; | ||
min-height: 150px; | ||
overflow-y: auto; | ||
} | ||
|
||
/* Theme toggle button styles */ | ||
.theme-toggle { | ||
position: fixed; | ||
top: 20px; | ||
right: 20px; | ||
z-index: 9999; | ||
background-color: #9a69dc; | ||
color: white; | ||
border: none; | ||
border-radius: 50%; | ||
width: 50px; | ||
height: 50px; | ||
font-size: 24px; | ||
cursor: pointer; | ||
} | ||
|
||
/* Recording button styles */ | ||
.recording-button { | ||
font-size: 24px; | ||
border-radius: 50%; | ||
width: 90px; | ||
height: 90px; | ||
margin: 0 10px; | ||
background-color: #9a69dc; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
// Theme toggle | ||
const body = document.body; | ||
const themeToggle = document.getElementById("themeToggle"); | ||
// WebSocket | ||
var httpProtocol = 'http://'; | ||
var wsProtocol = 'ws://'; | ||
if (window.location.protocol === 'https:') { | ||
httpProtocol = 'https://'; | ||
wsProtocol = 'wss://'; | ||
} | ||
const socket = new WebSocket(wsProtocol + window.location.host + "/transcribe"); | ||
// Recording Button | ||
const recordingButton = document.getElementById("recordingButton"); | ||
// Output Box | ||
const output = document.getElementById("output"); | ||
let isRecording = false; | ||
|
||
// Theme toggle functionality | ||
themeToggle.addEventListener("click", () => { | ||
body.classList.toggle("bg-dark"); | ||
const isDarkTheme = body.classList.contains("bg-dark"); | ||
themeToggle.innerHTML = isDarkTheme | ||
? '<i class="bi bi-sun"></i>' | ||
: '<i class="bi bi-moon"></i>'; | ||
}); | ||
|
||
// Initialize speech recognition | ||
const SpeechRecognition = | ||
window.SpeechRecognition || window.webkitSpeechRecognition; | ||
const recognition = new SpeechRecognition(); | ||
|
||
recognition.interimResults = false; // Enable interim results | ||
recognition.continuous = false; | ||
recognition.lang = "en-US"; | ||
|
||
// Event listeners for start and stop buttons | ||
recordingButton.addEventListener("click", toggleRecording); | ||
function toggleRecording() { | ||
isRecording = !isRecording; | ||
recordingButton.innerHTML = isRecording | ||
? '<i class="bi bi-mic-mute-fill"></i>' | ||
: '<i class="bi bi-mic-fill"></i>'; | ||
if (isRecording) { | ||
startRecording(); | ||
} else { | ||
stopRecording(); | ||
} | ||
} | ||
|
||
// Event listener for when speech recognition starts | ||
recognition.onstart = function () { | ||
console.log("Speech recognition started..."); | ||
output.innerHTML = ""; | ||
output.innerHTML = '<p class="text-muted">Listening...</p>'; | ||
}; | ||
|
||
// Event listener for interim results | ||
recognition.onresult = function (event) { | ||
const interimTranscript = Array.from(event.results) | ||
.map((result) => result[0].transcript) | ||
.join(""); | ||
output.innerHTML = `<p>${interimTranscript}</p>`; | ||
socket.send(interimTranscript); | ||
}; | ||
|
||
// Event listener for when speech recognition ends | ||
recognition.onend = function () { | ||
console.log("Speech recognition ended."); | ||
isRecording = !isRecording; | ||
recordingButton.innerHTML = isRecording | ||
? '<i class="bi bi-mic-mute-fill"></i>' | ||
: '<i class="bi bi-mic-fill"></i>'; | ||
}; | ||
|
||
// Function to start recording | ||
function startRecording() { | ||
navigator.mediaDevices | ||
.getUserMedia({ audio: true }) | ||
.then(() => { | ||
recognition.start(); // Start recognition | ||
speechSynthesis.cancel(); | ||
isRecording = true | ||
}) | ||
.catch((error) => { | ||
// Microphone is not enabled or available | ||
console.error("Microphone is not enabled or available:", error); | ||
alert( | ||
"Microphone is not enabled or available. Please enable your microphone and refresh the page." | ||
); | ||
}); | ||
} | ||
|
||
function stopRecording() { | ||
recognition.stop(); | ||
isRecording = false | ||
output.innerHTML = '<p class="text-muted">Start Recording to begin.</p>' | ||
} | ||
|
||
// On reciveing message from socket | ||
socket.onmessage = function (event) { | ||
stopRecording(); | ||
output.innerHTML = `<p>${event.data}</p>`; | ||
textToSpeech(event.data); | ||
}; | ||
|
||
// Speak recieved text from AI | ||
function textToSpeech(phrase) { | ||
const audio = new Audio(); | ||
const speechSettings = new SpeechSynthesisUtterance(phrase); | ||
speechSynthesis.speak(speechSettings); | ||
} | ||
|
||
// Stop speaking | ||
function stopSpeaker() { | ||
speechSynthesis.cancel(); | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
|
||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title>TalkGenie</title> | ||
<link rel="icon" type="image/png" sizes="32x32" href="{{ url_for('static', path='/logo/talkgenie-icon.png') }}"> | ||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet"> | ||
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons/font/bootstrap-icons.css" rel="stylesheet"> | ||
<link href="{{ url_for('static', path='/css/style.css') }}" rel="stylesheet"> | ||
</head> | ||
|
||
<body class="bg-dark"> | ||
<!-- Theme toggle button --> | ||
<button id="themeToggle" class="theme-toggle" title="Toggle Theme"> | ||
<i class="bi bi-sun"></i> | ||
</button> | ||
|
||
<!-- Main contianer --> | ||
<div class="container text-center"> | ||
<img src="{{ url_for('static', path='/logo/talkgenie-logo.png') }}" height="500" /> | ||
<p style="color: rgb(182 146 228);">TalkGenie grant your voice wishes, utilizing advanced AI to understand your | ||
commands and provide swift and accurate responses tailored to your needs.</p> | ||
<div class="mb-4"> | ||
<button id="recordingButton" class="btn btn-dark recording-button" title="Start Recording"> | ||
<i class="bi bi-mic-fill"></i> | ||
</button> | ||
</div> | ||
<div id="output" class="output-box"> | ||
<p class="text-muted">Start Recording to begin.</p> | ||
</div> | ||
</div> | ||
|
||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script> | ||
<script src="{{ url_for('static', path='/js/index.js') }}"></script> | ||
<script> | ||
</script> | ||
</body> | ||
|
||
</html> |