|
<!DOCTYPE html> |
|
<html lang="en"> |
|
|
|
<head> |
|
<meta charset="UTF-8"> |
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
<title>REM Waste - English Accent Analyzer</title> |
|
<script src="https://cdn.tailwindcss.com"></script> |
|
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}"> |
|
</head> |
|
|
|
<body class="flex items-center justify-center min-h-screen p-4"> |
|
<div class="container mx-auto p-6 card"> |
|
<h1 class="text-3xl font-bold text-center text-gray-800 mb-6">English Accent Analyzer</h1> |
|
<p class="text-center text-gray-600 mb-8"> |
|
Enter a public video URL (e.g., YouTube, Loom, direct MP4 link) to analyze the speaker's English accent. |
|
</p> |
|
|
|
<form id="analyzeForm" class="space-y-6"> |
|
<div> |
|
<label for="videoUrl" class="block text-sm font-medium text-gray-700 mb-2">Video URL:</label> |
|
<input type="url" id="videoUrl" name="video_url" |
|
placeholder="e.g., https://www.youtube.com/watch?v=dQw4w9WgXcQ" |
|
class="input-field focus:ring-indigo-500 focus:border-indigo-500" required> |
|
</div> |
|
<button type="submit" class="btn-primary w-full text-lg font-semibold"> |
|
Analyze Accent |
|
</button> |
|
</form> |
|
|
|
<div id="statusMessage" class="mt-8 p-4 rounded-lg text-center text-gray-800 font-medium hidden"> |
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div id="results" class="mt-8 p-6 rounded-lg border border-gray-200 hidden"> |
|
<h2 class="text-xl font-semibold text-gray-800 mb-4">Analysis Results:</h2> |
|
<p class="text-lg mb-2"><span class="result-label">Detected Accent:</span> <span id="accentResult" |
|
class="result-value"></span></p> |
|
<p class="text-lg mb-2"><span class="result-label">Confidence Score:</span> <span id="confidenceResult" |
|
class="result-value"></span></p> |
|
<h2> |
|
<p id="summaryResult" class="result-summary"></p> |
|
</h2> |
|
</div> |
|
|
|
|
|
<div id="errorMessage" class="mt-8 p-4 rounded-lg bg-red-100 border border-red-400 text-red-700 hidden"> |
|
</div> |
|
</div> |
|
|
|
<script> |
|
const analyzeForm = document.getElementById('analyzeForm'); |
|
const videoUrlInput = document.getElementById('videoUrl'); |
|
const statusMessageDiv = document.getElementById('statusMessage'); |
|
const resultsDiv = document.getElementById('results'); |
|
const accentResultSpan = document.getElementById('accentResult'); |
|
const confidenceResultSpan = document.getElementById('confidenceResult'); |
|
const summaryResultSpan = document.getElementById('summaryResult'); |
|
const errorMessageDiv = document.getElementById('errorMessage'); |
|
|
|
let pollingInterval; |
|
|
|
|
|
function showStatus(message, type = 'info') { |
|
statusMessageDiv.textContent = message; |
|
statusMessageDiv.classList.remove('hidden', 'bg-green-100', 'bg-red-100', 'text-green-700', 'text-red-700', 'bg-blue-100', 'text-blue-700'); |
|
statusMessageDiv.classList.add('block'); |
|
if (type === 'success') { |
|
statusMessageDiv.classList.add('bg-green-100', 'text-green-700'); |
|
} else if (type === 'error') { |
|
statusMessageDiv.classList.add('bg-red-100', 'text-red-700'); |
|
} else { |
|
statusMessageDiv.classList.add('bg-blue-100', 'text-blue-700'); |
|
} |
|
resultsDiv.classList.add('hidden'); |
|
errorMessageDiv.classList.add('hidden'); |
|
} |
|
|
|
|
|
function showError(message) { |
|
errorMessageDiv.textContent = `Error: ${message}`; |
|
errorMessageDiv.classList.remove('hidden'); |
|
statusMessageDiv.classList.add('hidden'); |
|
resultsDiv.classList.add('hidden'); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function showResults(accent, confidence, summary) { |
|
accentResultSpan.textContent = accent || 'N/A'; |
|
confidenceResultSpan.textContent = confidence || 'N/A'; |
|
summaryResultSpan.textContent = summary || ''; |
|
|
|
resultsDiv.classList.remove('hidden'); |
|
resultsDiv.style.display = 'block'; |
|
|
|
statusMessageDiv.classList.add('hidden'); |
|
errorMessageDiv.classList.add('hidden'); |
|
} |
|
|
|
|
|
|
|
analyzeForm.addEventListener('submit', async (event) => { |
|
event.preventDefault(); |
|
|
|
const videoUrl = videoUrlInput.value.trim(); |
|
if (!videoUrl) { |
|
showError("Please enter a video URL."); |
|
return; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
clearInterval(pollingInterval); |
|
statusMessageDiv.classList.add('hidden'); |
|
resultsDiv.classList.add('hidden'); |
|
errorMessageDiv.classList.add('hidden'); |
|
|
|
|
|
accentResultSpan.textContent = ''; |
|
confidenceResultSpan.textContent = ''; |
|
summaryResultSpan.textContent = ''; |
|
|
|
try { |
|
const response = await fetch('/analyze', { |
|
method: 'POST', |
|
headers: { |
|
'Content-Type': 'application/json', |
|
}, |
|
body: JSON.stringify({ video_url: videoUrl }), |
|
}); |
|
|
|
const data = await response.json(); |
|
|
|
if (response.ok) { |
|
if (data.status === 'processing') { |
|
showStatus(data.message); |
|
|
|
pollingInterval = setInterval(() => checkStatus(data.task_id), 3000); |
|
} else { |
|
showError(data.message || "An unexpected response was received."); |
|
} |
|
} else { |
|
showError(data.message || `Server error: ${response.status}`); |
|
} |
|
} catch (error) { |
|
console.error('Fetch error:', error); |
|
showError("Could not connect to the server or an unexpected network error occurred."); |
|
} |
|
}); |
|
|
|
|
|
async function checkStatus(taskId) { |
|
try { |
|
const response = await fetch(`/status/${taskId}`); |
|
const data = await response.json(); |
|
|
|
if (response.ok) { |
|
if (data.status === 'processing') { |
|
showStatus(data.message); |
|
} else if (data.status === 'completed') { |
|
clearInterval(pollingInterval); |
|
console.log("Received data from backend:", data); |
|
showResults(data.accent, data.confidence, data.summary); |
|
showStatus("Analysis completed successfully!", 'success'); |
|
} else if (data.status === 'error') { |
|
clearInterval(pollingInterval); |
|
showError(data.message); |
|
} |
|
} else { |
|
clearInterval(pollingInterval); |
|
showError(data.message || `Server error: ${response.status}`); |
|
} |
|
} catch (error) { |
|
console.error('Polling error:', error); |
|
clearInterval(pollingInterval); |
|
showError("Lost connection to the server while checking status."); |
|
} |
|
} |
|
</script> |
|
</body> |
|
|
|
</html> |