Spaces:
Sleeping
Sleeping
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>AI Digit Recognition - Predict</title> | |
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}"> | |
</head> | |
<body> | |
<!-- Neural network background --> | |
<div class="neural-network" id="neuralNetwork"> | |
<!-- Neurons and connections will be generated by JavaScript --> | |
</div> | |
<!-- Navigation --> | |
<div class="container"> | |
<div class="flex justify-between items-center mb-4"> | |
<a href="{{ url_for('home') }}" class="btn btn-secondary"> | |
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> | |
<path d="m12 19-7-7 7-7"></path> | |
<path d="M19 12H5"></path> | |
</svg> | |
Back to Home | |
</a> | |
<h2>AI Digit Recognition</h2> | |
</div> | |
</div> | |
<!-- Layout container --> | |
<div class="container"> | |
<div class="flex flex-col items-center gap-6"> | |
<!-- Main row with recorder and prediction side by side --> | |
<div class="flex flex-wrap justify-center gap-4"> | |
<!-- Audio Recorder Container --> | |
<div class="content-container max-w-md"> | |
<h1 class="text-center mb-4">Audio Digit Predictor</h1> | |
<div class="flex flex-col items-center space-y-4"> | |
<!-- Record Button --> | |
<div class="relative"> | |
<button id="recordBtn" class="btn btn-primary"> | |
<svg id="micIcon" class="w-5 h-5" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> | |
<path d="M19 11a7 7 0 01-7 7m0 0a7 7 0 01-7-7m7 7v4m0 0H8m4 0h4m-4-8a3 3 0 01-3-3V5a3 3 0 116 0v6a3 3 0 01-3 3z"></path> | |
</svg> | |
<span id="recordBtnText">Record Digit (1s)</span> | |
</button> | |
<div id="progressRing" class="absolute inset-0 hidden"> | |
<svg class="w-full h-full" viewBox="0 0 36 36"> | |
<path class="stroke-current text-cyan-200" stroke-width="2" fill="none" | |
d="M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831"></path> | |
<path id="progressPath" class="stroke-current text-cyan-500" stroke-width="2" fill="none" | |
stroke-dasharray="100" stroke-dashoffset="100" | |
d="M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831"></path> | |
</svg> | |
</div> | |
</div> | |
<button id="submitBtn" disabled class="btn btn-secondary"> | |
Predict Digit | |
</button> | |
<!-- Custom Audio Player --> | |
<div id="audioContainer" class="audio-container w-full" style="display:none;"> | |
<div class="custom-audio-player"> | |
<button id="playPauseBtn" class="play-pause-btn"> | |
<svg id="playIcon" viewBox="0 0 24 24"> | |
<path d="M8 5v14l11-7z"/> | |
</svg> | |
<svg id="pauseIcon" viewBox="0 0 24 24" style="display:none;"> | |
<path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/> | |
</svg> | |
</button> | |
<div class="audio-progress"> | |
<div class="progress-bar" id="progressBar"> | |
<div class="progress-fill" id="progressFill"></div> | |
<div class="progress-thumb" id="progressThumb"></div> | |
</div> | |
<div class="time-display"> | |
<span id="currentTime">0:00</span> | |
<span id="duration">1</span> | |
</div> | |
</div> | |
<div class="volume-control"> | |
<button id="volumeBtn" class="volume-btn"> | |
<svg viewBox="0 0 24 24"> | |
<path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z"/> | |
</svg> | |
</button> | |
<div class="volume-slider" id="volumeSlider"> | |
<div class="volume-fill" id="volumeFill"></div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<audio id="audioPlayback" controls class="w-full mt-4" style="display:none;"></audio> | |
</div> | |
<p id="statusMessage" class="text-center mt-4">Click Record to start</p> | |
</div> | |
<!-- Prediction Display --> | |
<div id="predictionContainer" class="content-container prediction-container hidden" style="min-width: 250px;"> | |
<h3 class="text-lg font-semibold mb-3 text-cyan-200">AI Prediction:</h3> | |
<div id="wordDisplay" class="word-display">Word</div> | |
<div id="digitDisplay" class="digit-display">0</div> | |
<div id="fullDisplay" class="text-sm text-white mt-2">Full: Word (0)</div> | |
</div> | |
</div> | |
<!-- Probabilities Container --> | |
<div id="probabilitiesContainer" class="content-container max-w-xl hidden"> | |
<h2 class="text-center mb-4">All Probabilities</h2> | |
<div id="probabilitiesList" class="probability-container space-y-2"> | |
<!-- Probabilities will be inserted here --> | |
</div> | |
</div> | |
</div> | |
</div> | |
<script src="{{ url_for('static', filename='script.js') }}"></script> | |
<script> | |
// Neural network animation | |
function createNeuralNetwork() { | |
const container = document.getElementById('neuralNetwork'); | |
const neurons = []; | |
const numNeurons = 50; | |
// Create neurons | |
for (let i = 0; i < numNeurons; i++) { | |
const neuron = document.createElement('div'); | |
neuron.className = 'neuron'; | |
const x = Math.random() * window.innerWidth; | |
const y = Math.random() * window.innerHeight; | |
neuron.style.left = x + 'px'; | |
neuron.style.top = y + 'px'; | |
neuron.style.animationDelay = Math.random() * 3 + 's'; | |
container.appendChild(neuron); | |
neurons.push({ element: neuron, x, y }); | |
} | |
// Create connections between nearby neurons | |
for (let i = 0; i < neurons.length; i++) { | |
for (let j = i + 1; j < neurons.length; j++) { | |
const neuron1 = neurons[i]; | |
const neuron2 = neurons[j]; | |
const distance = Math.sqrt( | |
Math.pow(neuron1.x - neuron2.x, 2) + | |
Math.pow(neuron1.y - neuron2.y, 2) | |
); | |
// Only connect neurons that are close enough | |
if (distance < 200) { | |
const connection = document.createElement('div'); | |
connection.className = 'connection'; | |
const angle = Math.atan2(neuron2.y - neuron1.y, neuron2.x - neuron1.x); | |
const length = distance; | |
connection.style.left = neuron1.x + 'px'; | |
connection.style.top = neuron1.y + 'px'; | |
connection.style.width = length + 'px'; | |
connection.style.transform = `rotate(${angle}rad)`; | |
connection.style.animationDelay = Math.random() * 5 + 's'; | |
container.appendChild(connection); | |
} | |
} | |
} | |
} | |
// Initialize neural network on page load | |
document.addEventListener('DOMContentLoaded', createNeuralNetwork); | |
// Recreate neural network on window resize | |
window.addEventListener('resize', () => { | |
const container = document.getElementById('neuralNetwork'); | |
container.innerHTML = ''; | |
createNeuralNetwork(); | |
}); | |
</script> | |
</body> | |
</html> | |