diff --git a/README.md b/README.md
index abc30b8b..4fdf093f 100644
--- a/README.md
+++ b/README.md
@@ -1,13 +1,30 @@
# NASA Space Apps Challenge 2024 [Noida]
-#### Team Name -
-#### Problem Statement -
-#### Team Leader Email -
+#### Team Name - Supernovas
+#### Problem Statement - Community Mapping
+#### Team Leader Email - nishantpandey2004@gmail.com
## A Brief of the Prototype:
- What is your solution? and how it works.
+ The prototype is an interactive web-based map application designed to provide real-time geographic data visualization and user-controlled features. It integrates multiple layers of geographic information, including OpenStreetMap (OSM) tiles, air quality index (AQI), vegetation, highways, terrain, and satellite imagery.
+
+Key features of the prototype include:
+
+1. **Map Layer Toggling**: Users can easily toggle different map layers such as vegetation, highways, satellite view, terrain, and pollution, allowing for customized map visualization.
+
+2. **Air Quality Information**: An AQI widget can be displayed for specific cities, showing real-time air quality data with a user-friendly interface.
+
+3. **Location-based Markers**: Users can mark specific cities on the map and calculate the distance between marked locations using a routing system.
+
+4. **Rainfall Data**: The prototype allows toggling a rainfall layer to display precipitation data over the map, adding an environmental monitoring feature.
+
+5. **Voice and Text Commands**: The application supports both text-based input and voice commands to control the map’s features (e.g., zooming in/out, going to a location, toggling layers).
+
+6. **History Logging**: Each user action, such as toggling a layer or marking a city, is logged and displayed in a history list for reference.
+
+The application is designed to be user-friendly, allowing seamless interaction between the user and the map interface for visualizing geographic and environmental data.
## Code Execution Instruction:
- *[If your solution is **not** application based, you can ignore this para]
+ 1. [Run Prototype](https://nasa-space-apps-noida.vercel.app/)
+ 2. [Watch DEMO](https://www.youtube.com/watch?v=8CtPQ6vBYGo)
- *The Repository must contain your **Execution Plan PDF**.
+
diff --git a/Supernovas/index.css b/Supernovas/index.css
new file mode 100644
index 00000000..76c4bf2c
--- /dev/null
+++ b/Supernovas/index.css
@@ -0,0 +1,225 @@
+/* General reset for styling */
+* {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+}
+
+body {
+ font-family: 'Orbitron', sans-serif;
+ /* Futuristic font */
+ background: url('server/space-background.jpg') no-repeat center center fixed;
+ /* Space background */
+ background-size: cover;
+ color: white;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+header {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 20px;
+ background: rgba(0, 0, 0, 0.7);
+ border-bottom: 2px solid #fff;
+ width: 100%;
+}
+
+header img {
+ width: 80px;
+ margin-right: 20px;
+}
+
+header h1 {
+ font-size: 2.5rem;
+ color: #00bfff;
+ /* NASA-like light blue */
+ text-shadow: 0px 0px 15px #00bfff;
+}
+
+.map-container {
+ width: 90%;
+ height: 65vh;
+ margin: 20px 0;
+ position: relative;
+ display: flex;
+ /* Flexbox for positioning */
+}
+
+#map {
+ flex: 1;
+ /* Map takes remaining space */
+ height: 100%;
+ border: 3px solid #fff;
+ border-radius: 15px;
+ overflow: hidden;
+ box-shadow: 0 0 20px rgba(255, 255, 255, 0.3);
+ position: relative;
+}
+
+/* History box on the left side */
+.history-box {
+ position: absolute;
+ top: 20px;
+ left: 20px;
+ width: 250px;
+ max-height: 200px;
+ background: rgba(0, 0, 0, 0.7);
+ padding: 15px;
+ border-radius: 10px;
+ color: #fff;
+ box-shadow: 0px 0px 10px rgba(0, 0, 255, 0.5);
+ overflow-y: auto;
+ z-index: 1000;
+ /* Ensure it stays on top */
+}
+
+.history-box h2 {
+ font-size: 1.5rem;
+ margin-bottom: 10px;
+ text-align: center;
+ color: #00bfff;
+}
+
+.history-box ul {
+ list-style: none;
+ padding-left: 0;
+ margin: 0;
+ max-height: 160px;
+ /* Adjust height to fit box */
+ overflow-y: auto;
+ /* Scroll when content exceeds */
+}
+
+.history-box ul li {
+ margin-bottom: 10px;
+ padding: 8px;
+ background: rgba(255, 255, 255, 0.1);
+ border-radius: 5px;
+ font-size: 1rem;
+ color: #00bfff;
+ box-shadow: 0px 0px 5px rgba(255, 255, 255, 0.3);
+}
+
+/* Distance box on the right side */
+#distance {
+ position: absolute;
+ top: 20px;
+ right: 20px;
+ background: rgba(0, 0, 0, 0.7);
+ padding: 10px;
+ border-radius: 10px;
+ color: white;
+ font-size: 1.2rem;
+ box-shadow: 0px 0px 15px rgba(0, 191, 255, 0.7);
+ z-index: 1000;
+}
+
+/* Coordinates display (below distance) */
+#coordinates {
+ position: absolute;
+ top: 80px;
+ right: 20px;
+ background: rgba(0, 0, 0, 0.7);
+ padding: 10px;
+ border-radius: 10px;
+ color: white;
+ font-size: 1.2rem;
+ box-shadow: 0px 0px 15px rgba(0, 191, 255, 0.7);
+ z-index: 1000;
+}
+
+
+.watermark {
+ position: absolute;
+ top: 20px;
+ right: 10px;
+ background-color: rgba(255, 255, 255, 0.7);
+ padding: 5px 10px;
+ border-radius: 5px;
+ font-size: 14px;
+ font-weight: bold;
+ color: red;
+ z-index: 1000;
+ opacity: 70%;
+}
+
+
+footer {
+ width: 100%;
+ text-align: center;
+ background: rgba(0, 0, 0, 0.7);
+ padding: 20px;
+ color: #fff;
+ border-top: 2px solid #00bfff;
+}
+
+footer p {
+ font-size: 1.2rem;
+}
+
+footer .commands {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
+}
+
+footer .command-box {
+ background: rgba(255, 255, 255, 0.2);
+ border-radius: 5px;
+ margin: 5px;
+ padding: 10px 15px;
+ font-size: 1rem;
+ color: #00bfff;
+ box-shadow: 0px 0px 10px rgba(0, 191, 255, 0.5);
+ cursor: pointer;
+ transition: all 0.3s;
+}
+
+footer .command-box:hover {
+ background: #00bfff;
+ color: #fff;
+ box-shadow: 0px 0px 15px #fff;
+}
+
+.search-bar {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ margin: 10px;
+ z-index: 1000;
+
+ position: absolute;
+ top: 20px;
+ right: 30%;
+
+
+
+ z-index: 1000;
+ /* Ensure it stays on top */
+}
+
+#search-input {
+ padding: 10px;
+ font-size: 16px;
+ width: 300px;
+ border: 1px solid #ccc;
+ border-radius: 5px;
+}
+
+#mic-button {
+ background-color: #ffffff;
+ color: white;
+ font-size: 26px;
+ border-color: #ff0000;
+ border-radius: 50%;
+
+ margin-left: 5px;
+ cursor: pointer;
+}
+
+#mic-button:hover {
+ background-color: #ff0000;
+}
\ No newline at end of file
diff --git a/Supernovas/index.html b/Supernovas/index.html
new file mode 100644
index 00000000..db909ede
--- /dev/null
+++ b/Supernovas/index.html
@@ -0,0 +1,95 @@
+
+
+
+
+
+
+ VANI - Voice Assistance for Navigation and Interaction
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ VANI
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Supernovas/script.js b/Supernovas/script.js
new file mode 100644
index 00000000..94091dec
--- /dev/null
+++ b/Supernovas/script.js
@@ -0,0 +1,336 @@
+var map = L.map("map").setView([21.82, 82.71], 5);
+L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);
+
+// AQI (Air Quality Index) layer
+var WAQI_URL = "https://tiles.waqi.info/tiles/usepa-aqi/{z}/{x}/{y}.png?token=f9a3aa393a0d9a30af06f258f0a2854e227670db"; // Replace with your actual token
+var waqiLayer = L.tileLayer(WAQI_URL, {
+ attribution: 'Air Quality Tiles © waqi.info'
+})
+
+var vegetationLayer = L.tileLayer('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png');
+var highwaysLayer = L.tileLayer('https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png');
+let pollutionLayer = null;
+let rainfallLayer = null;
+
+// Functions for handling different map layers and controls
+const goToCoords = function (city) {
+ var inurl = "https://nominatim.openstreetmap.org/search?q=" + city + "&limit=1&format=json&addressdetails=1";
+ $.when(ajax1()).done(function (data) {
+ if (data.length > 0) {
+ map.flyTo([data[0]["lat"], data[0]["lon"]], 12);
+ addToHistory('Go to ' + city);
+ } else {
+ alert('City not found!');
+ }
+ });
+ function ajax1() {
+ return $.ajax({
+ url: inurl,
+ dataType: "json"
+ });
+ }
+};
+
+const toggleVegetation = function () {
+ if (map.hasLayer(vegetationLayer)) {
+ map.removeLayer(vegetationLayer);
+ addToHistory('Hide vegetation');
+ } else {
+ map.addLayer(vegetationLayer);
+ addToHistory('Show vegetation');
+ }
+};
+
+const toggleHighways = function () {
+ if (map.hasLayer(highwaysLayer)) {
+ map.removeLayer(highwaysLayer);
+ addToHistory('Hide highways');
+ } else {
+ map.addLayer(highwaysLayer);
+ addToHistory('Show highways');
+ }
+};
+
+const toggleSatellite = function () {
+ var satelliteLayer = L.tileLayer('https://{s}.google.com/vt/lyrs=s&x={x}&y={y}&z={z}', {
+ maxZoom: 20,
+ subdomains: ['mt0', 'mt1', 'mt2', 'mt3']
+ });
+ if (map.hasLayer(satelliteLayer)) {
+ map.removeLayer(satelliteLayer);
+ addToHistory('Hide satellite');
+ } else {
+ map.addLayer(satelliteLayer);
+ addToHistory('Show satellite');
+ }
+};
+
+const toggleTerrain = function () {
+ var terrainLayer = L.tileLayer('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png');
+ if (map.hasLayer(terrainLayer)) {
+ map.removeLayer(terrainLayer);
+ addToHistory('Hide terrain');
+ } else {
+ map.addLayer(terrainLayer);
+ addToHistory('Show terrain');
+ }
+};
+
+const showPollutionMap = function () {
+ // Check if pollutionLayer already exists
+ if (pollutionLayer) {
+ map.removeLayer(pollutionLayer); // Remove the previous layer if it exists
+ pollutionLayer = null; // Reset the layer variable
+ }
+
+ // Create the pollution layer using the location
+ pollutionLayer = L.tileLayer(WAQI_URL, {
+ attribution: 'Air Quality Tiles © waqi.info',
+ opacity: 0.7
+ }).addTo(map);
+
+ // Log the action in history
+ addToHistory('Show pollution');
+};
+
+const showRainfallMap = function () {
+ // Check if rainfallLayer already exists
+ if (rainfallLayer) {
+ map.removeLayer(rainfallLayer); // Remove the previous layer if it exists
+ rainfallLayer = null; // Reset the layer variable
+ }
+
+ // Create the rainfall layer using the location
+ rainfallLayer = L.tileLayer(WAQI_URL, {
+ attribution: 'Air Quality Tiles © waqi.info',
+ opacity: 0.7
+ }).addTo(map);
+
+ // Log the action in history
+ addToHistory('Show rainfall');
+};
+
+const zoomIn = function () {
+ map.zoomIn();
+ addToHistory('Zoom in');
+};
+
+const zoomOut = function () {
+ map.zoomOut();
+ addToHistory('Zoom out');
+};
+
+const stoplistening = function () {
+ annyang.abort();
+ addToHistory('Stop listening');
+};
+
+let markersArray = [];
+let routingControl = null;
+
+const addMarker = function (city) {
+ var markerUrl = "https://nominatim.openstreetmap.org/search?q=" + city + "&format=json&limit=1";
+ $.ajax({
+ url: markerUrl,
+ dataType: "json",
+ success: function (data) {
+ if (data.length > 0) {
+ var lat = data[0].lat;
+ var lon = data[0].lon;
+ var marker = L.marker([lat, lon]).addTo(map).bindPopup(city);
+ markersArray.push(marker);
+ addToHistory('Mark ' + city);
+ } else {
+ alert('City not found!');
+ }
+ }
+ });
+};
+
+const removeMarker = function (city) {
+ markersArray = markersArray.filter(marker => {
+ if (marker.getPopup().getContent() === city) {
+ map.removeLayer(marker);
+ addToHistory('Unmark ' + city);
+ return false;
+ }
+ return true;
+ });
+};
+
+const calculateDistance = function () {
+ if (markersArray.length < 2) {
+ alert("You need at least two markers to calculate distance.");
+ return;
+ }
+
+ if (routingControl !== null) {
+ map.removeControl(routingControl);
+ }
+
+ var waypoints = markersArray.map(marker => marker.getLatLng());
+ routingControl = L.Routing.control({
+ waypoints: waypoints,
+ lineOptions: {
+ styles: [{ color: 'red', opacity: 0.6, weight: 4 }]
+ },
+ createMarker: function () { return null; },
+ routeWhileDragging: true,
+ show: false,
+ addWaypoints: false
+ }).addTo(map);
+
+ routingControl.on('routesfound', function (e) {
+ var routes = e.routes;
+ var summary = routes[0].summary;
+ var distance = (summary.totalDistance / 1000).toFixed(2); // Convert to kilometers
+ document.getElementById('distance').innerHTML = "Total distance: " + distance + " km";
+ addToHistory('Calculate distance');
+ });
+};
+
+// AQI Widget Integration
+const showAQIWidget = function(city) {
+ goToCoords(city); // Navigate to the city first
+
+ // After the navigation is successful, load the AQI data
+ $.when(ajax1(city)).done(function() {
+ const container = document.getElementById('city-aqi-container');
+ container.innerHTML = ''; // Clear previous widget
+
+ // Set CSS styles for positioning
+ container.style.position = 'absolute';
+ container.style.zIndex = '1000';
+ container.style.position = 'fixed'; // Change to fixed for viewport centering
+ container.style.top = '50%'; // Move down 50% of the viewport height
+ container.style.left = '50%'; // Move right 50% of the viewport width
+ container.style.transform = 'translate(-50%, -50%)'; // Center it perfectly
+ container.style.color = 'black';
+
+ // Load the AQI data
+ _aqiFeed({
+ container: "city-aqi-container",
+ city: city.toLowerCase(),
+
+ display: "%cityname AQI is %aqi
on %date"
+ });
+
+ addToHistory('Show AQI widget of ' + city);
+ }).fail(function() {
+ alert('Unable to load AQI data for ' + city);
+ });
+};
+
+
+// Helper function to get city coordinates
+function ajax1(city) {
+ var inurl = "https://nominatim.openstreetmap.org/search?q=" + city + "&limit=1&format=json&addressdetails=1";
+ return $.ajax({
+ url: inurl,
+ dataType: "json"
+ });
+}
+
+const closeAQIWidget = function() {
+ document.getElementById('city-aqi-container').innerHTML = ''; // Clear the widget
+ addToHistory('Close AQI widget');
+};
+
+// History Management
+const addToHistory = function (action) {
+ var historyList = document.getElementById("history-list");
+ var listItem = document.createElement("li");
+ listItem.textContent = action;
+ historyList.appendChild(listItem);
+};
+
+
+
+// Searchbar Event Listener for Text Input - Handling All Commands
+document.getElementById('search-input').addEventListener('keydown', function (e) {
+ if (e.key === 'Enter') {
+ const input = this.value.trim().toLowerCase();
+ const command = input.split(' ');
+
+ // Identify which command was entered
+ if (input.startsWith('go to ')) {
+ const city = input.replace('go to ', '');
+ goToCoords(city);
+ } else if (input === 'show vegetation') {
+ toggleVegetation();
+ } else if (input === 'show highways') {
+ toggleHighways();
+ } else if (input === 'show satellite') {
+ toggleSatellite();
+ } else if (input === 'show terrain') {
+ toggleTerrain();
+ } else if (input === 'zoom in') {
+ zoomIn();
+ } else if (input === 'zoom out') {
+ zoomOut();
+ } else if (input.startsWith('mark ')) {
+ const city = input.replace('mark ', '');
+ addMarker(city);
+ } else if (input.startsWith('unmark ')) {
+ const city = input.replace('unmark ', '');
+ removeMarker(city);
+ } else if (input === 'calculate distance') {
+ calculateDistance();
+ } else if (input === 'show pollution') {
+ showPollutionMap();
+ }else if (input.startsWith('show aqi of ')) {
+ const city = input.replace('show aqi of ', '');
+ showAQIWidget(city);
+ } else if (input === 'close widget') {
+ closeAQIWidget();}
+ else if (input === 'show rainfall') {
+ showRainfallMap();
+ }
+ else {
+ alert("Command not recognized.");
+ }
+
+
+ // Clear input field after command is executed
+ this.value = '';
+ }
+});
+
+// Microphone Button to Activate Voice Command (One-time listening)
+document.getElementById('mic-button').addEventListener('click', function () {
+ if (annyang) {
+ // Start listening, but listen for a single command only
+ annyang.start({ autoRestart: false, continuous: false });
+
+ // Automatically stop after the first recognition event
+ annyang.addCallback('result', function () {
+ annyang.abort();
+ });
+ alert("Listening for voice commands...");
+ }
+});
+
+// Voice Command Setup (Annyang)
+if (annyang) {
+ const commands = {
+ 'go to *city': goToCoords,
+ 'show vegetation': toggleVegetation,
+ 'show highways': toggleHighways,
+ 'show satellite': toggleSatellite,
+ 'show terrain': toggleTerrain,
+ 'zoom in': zoomIn,
+ 'zoom out': zoomOut,
+ 'mark *city': addMarker,
+ 'unmark *city': removeMarker,
+ 'calculate distance': calculateDistance,
+ 'stop listening': stoplistening,
+ 'show pollution': showPollutionMap,
+ 'show aqi of *city': showAQIWidget,
+ 'close aqi': closeAQIWidget,
+ };
+
+ annyang.addCommands(commands);
+ SpeechKITT.annyang();
+ SpeechKITT.setStylesheet('//cdnjs.cloudflare.com/ajax/libs/SpeechKITT/0.3.0/themes/flat-clouds.css');
+ SpeechKITT.vroom();
+}
\ No newline at end of file
diff --git a/Supernovas/server/app.py b/Supernovas/server/app.py
new file mode 100644
index 00000000..072c5570
--- /dev/null
+++ b/Supernovas/server/app.py
@@ -0,0 +1,53 @@
+from flask import Flask, request, jsonify
+import whisper
+from flask_cors import CORS
+import numpy as np
+from pydub import AudioSegment
+import os
+
+app = Flask(__name__)
+CORS(app)
+
+model = whisper.load_model("base")
+
+@app.route("/transcribe", methods=["POST"])
+def transcribe():
+ try:
+ # Check if an audio file is present in the request
+ if "audio" not in request.files:
+ return jsonify({"error": "No audio file found in the request"}), 400
+
+ # Get the audio file from the request
+ audio_file = request.files["audio"]
+
+ # Save the audio file to a temporary location
+ audio_file_path = "./temp_audio.wav"
+ audio_file.save(audio_file_path)
+
+ # Load the audio file with pydub
+ audio = AudioSegment.from_file(audio_file_path)
+
+ # Convert to mono and resample to 16 kHz
+ audio = audio.set_channels(1).set_frame_rate(16000)
+
+ # Export to a new temporary file
+ processed_audio_path = "./processed_temp_audio.wav"
+ audio.export(processed_audio_path, format="wav")
+
+ # Load the processed audio with whisper
+ result = model.transcribe(processed_audio_path)
+ print(result)
+
+ # Clean up the temporary audio files
+ os.remove(audio_file_path)
+ os.remove(processed_audio_path)
+
+ return jsonify(result)
+
+ except Exception as e:
+ print("An error occurred during transcription:")
+ print(str(e))
+ return jsonify({"error": str(e)}), 500
+
+if __name__ == "__main__":
+ app.run(debug=True)
\ No newline at end of file
diff --git a/Supernovas/server/demo.html b/Supernovas/server/demo.html
new file mode 100644
index 00000000..a28ce9ae
--- /dev/null
+++ b/Supernovas/server/demo.html
@@ -0,0 +1,19 @@
+
+
+
+
+
+ Voice-enabled Geospatial Navigation
+
+
+
+ Voice-enabled Geospatial Navigation
+
+
+
+
diff --git a/Supernovas/server/demo.js b/Supernovas/server/demo.js
new file mode 100644
index 00000000..280cefa8
--- /dev/null
+++ b/Supernovas/server/demo.js
@@ -0,0 +1,26 @@
+function sendAudioFile(file) {
+ const formData = new FormData();
+ formData.append("audio", file);
+
+ fetch("http://127.0.0.1:5000/transcribe", {
+ method: "POST",
+ body: formData
+ })
+ .then(response => response.json())
+ .then(data => {
+ const transcriptionTextElement = document.getElementById("transcriptionText");
+ console.log(data)
+ transcriptionTextElement.textContent = data.text;
+ })
+ .catch(error => {
+ console.error("Error during transcription:", error);
+ });
+}
+
+
+document.getElementById("audioInput").addEventListener("change", function(event) {
+ const file = event.target.files[0];
+ if (file) {
+ sendAudioFile(file);
+ }
+});
diff --git a/Supernovas/server/index.html b/Supernovas/server/index.html
new file mode 100644
index 00000000..eff5acd0
--- /dev/null
+++ b/Supernovas/server/index.html
@@ -0,0 +1,71 @@
+
+
+
+
+
+ Voice-enabled Geospatial Navigation
+
+
+
+ Voice-enabled Geospatial Navigation
+
+ Press the mic to start recording.
+
+
+
+
+
+
diff --git a/Supernovas/server/isro.png b/Supernovas/server/isro.png
new file mode 100644
index 00000000..88a308d0
Binary files /dev/null and b/Supernovas/server/isro.png differ
diff --git a/Supernovas/server/nasa.gif b/Supernovas/server/nasa.gif
new file mode 100644
index 00000000..5e804493
Binary files /dev/null and b/Supernovas/server/nasa.gif differ
diff --git a/Supernovas/server/requirements.txt b/Supernovas/server/requirements.txt
new file mode 100644
index 00000000..c303a1b8
--- /dev/null
+++ b/Supernovas/server/requirements.txt
@@ -0,0 +1,7 @@
+flask
+flask-cors
+torch
+openai-whisper
+pydub
+pyaudio
+numpy==1.24.1
diff --git a/Supernovas/server/script.js b/Supernovas/server/script.js
new file mode 100644
index 00000000..2055a85b
--- /dev/null
+++ b/Supernovas/server/script.js
@@ -0,0 +1,88 @@
+let mediaRecorder;
+let audioChunks = [];
+let isRecording = false;
+
+const micContainer = document.getElementById("micContainer");
+const micIcon = document.getElementById("micIcon");
+const wave = document.getElementById("wave");
+const status = document.getElementById("status");
+const textBox = document.getElementById("textBox");
+
+micContainer.addEventListener("click", () => {
+ if (!isRecording) {
+ startRecording();
+ } else {
+ stopRecording();
+ }
+});
+
+async function startRecording() {
+ console.log("Recording started.");
+ status.textContent = "Recording...";
+ isRecording = true;
+
+ try {
+ const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
+ mediaRecorder = new MediaRecorder(stream);
+ audioChunks = [];
+
+ mediaRecorder.ondataavailable = event => {
+ audioChunks.push(event.data);
+ };
+
+ mediaRecorder.onstop = () => {
+ const audioBlob = new Blob(audioChunks, { type: 'audio/wav' });
+ const audioFile = new File([audioBlob], "recording.wav", { type: 'audio/wav' });
+ sendAudioFile(audioFile);
+ status.textContent = "Recording stopped. Processing...";
+ };
+
+ mediaRecorder.start();
+ micIcon.classList.add("active");
+ wave.style.opacity = 1;
+ } catch (error) {
+ console.error("Error accessing microphone:", error);
+ status.textContent = "Error accessing microphone. Please allow microphone access.";
+ }
+}
+
+function stopRecording() {
+ console.log("Recording stopped.");
+ mediaRecorder.stop();
+ isRecording = false;
+ micIcon.classList.remove("active");
+ wave.style.opacity = 0;
+ status.textContent = "Recording stopped. Click the mic to start recording again.";
+}
+
+function sendAudioFile(file) {
+ console.log("Sending audio file...");
+ const formData = new FormData();
+ formData.append("audio", file);
+
+ // Replace with your server URL for transcription
+ fetch("http://127.0.0.1:5000/transcribe", {
+ method: "POST",
+ body: formData
+ })
+ .then(response => {
+ if (!response.ok) {
+ throw new Error("Network response was not ok");
+ }
+ console.log("Transcription response:", response);
+ return response.json();
+ })
+ .then(data => {
+ console.log("Transcription result:", data);
+ displayTranscription(data.text);
+ })
+ .catch(error => {
+ console.error("Error during transcription:", error);
+ status.textContent = "Error during transcription.";
+ });
+}
+
+function displayTranscription(text) {
+ console.log("Transcription:", text);
+ textBox.textContent = text; // Display transcription result in text box
+}
\ No newline at end of file
diff --git a/Supernovas/server/test_audio.wav b/Supernovas/server/test_audio.wav
new file mode 100644
index 00000000..3d449fb1
Binary files /dev/null and b/Supernovas/server/test_audio.wav differ