jaykishan-b's picture
Updated: API url in template
d119ffb
raw
history blame
14.2 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Speech Analysis</title>
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
body {
background-color: #f4f7f8;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}
.container {
margin-top: 50px;
padding: 20px;
background: #fff;
box-shadow: 0 0 15px rgba(0, 0, 0, 0.1);
border-radius: 10px;
}
.progress-bar-inner {
width: 0%;
transition: width 1s ease-in-out;
}
.audio-player {
margin-top: 20px;
}
.btn-analyze {
background-color: #007bff;
color: white;
border-radius: 5px;
padding: 10px 20px;
}
.btn-analyze:hover {
background-color: #0056b3;
}
.score-label {
display: flex;
justify-content: space-between;
font-weight: 600;
}
.feedback-section {
margin-top: 30px;
}
.highlight-mispronounced {
background-color: yellow;
font-weight: bold;
}
.highlight {
background-color: yellow;
font-weight: bold;
}
.highlight-grammar {
background-color: lightpink;
/* or any other color */
font-weight: bold;
}
</style>
</head>
<body>
<div class="container">
<h1 class="text-center mb-4">Speech Analysis</h1>
<div class="mb-3">
<label for="audio-file" class="form-label">Upload your audio file:</label>
<input type="file" class="form-control" id="audio-file" accept="audio/*">
</div>
<!-- Language Dropdown -->
<div class="mb-3">
<label for="language-select" class="form-label">Select Language:</label>
<select class="form-select" id="language-select">
<option value="en-GB">English (United Kingdom)</option>
<option value="nb-NO">Norwegian</option>
</select>
</div>
<div class="text-center mb-4">
<button class="btn btn-analyze" onclick="analyzeAudio()">Analyze Speech</button>
</div>
<div class="audio-player text-center" id="audio-player-container" style="display: none;">
<audio id="audio-player" controls></audio>
</div>
<h3 class="mt-5">Speech Scores</h3>
<!-- Scores with Progress Bars -->
<div id="scores-container">
<div class="mb-3">
<div class="score-label">
<span>Fluency Score</span>
<span id="fluency-score">0%</span>
</div>
<div class="progress">
<div class="progress-bar progress-bar-inner bg-success" id="fluency-progress" role="progressbar"
aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
<div class="mb-3">
<div class="score-label">
<span>Pronunciation Score</span>
<span id="pronunciation-score">0%</span>
</div>
<div class="progress">
<div class="progress-bar progress-bar-inner bg-primary" id="pronunciation-progress"
role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
<div class="mb-3">
<div class="score-label">
<span>Completeness Score</span>
<span id="completeness-score">0%</span>
</div>
<div class="progress">
<div class="progress-bar progress-bar-inner bg-warning" id="completeness-progress"
role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
<div class="mb-3">
<div class="score-label">
<span>Accuracy Score</span>
<span id="accuracy-score">0%</span>
</div>
<div class="progress">
<div class="progress-bar progress-bar-inner bg-danger" id="accuracy-progress" role="progressbar"
aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
<div class="mb-3">
<div class="score-label">
<span>Grammar Score</span>
<span id="grammar-score">0%</span>
</div>
<div class="progress">
<div class="progress-bar progress-bar-inner bg-info" id="grammar-progress" role="progressbar"
aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
<div class="mb-3">
<div class="score-label">
<span>Comprehension Score</span>
<span id="comprehension-score">0%</span>
</div>
<div class="progress">
<div class="progress-bar progress-bar-inner bg-dark" id="comprehension-progress" role="progressbar"
aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
<div class="mb-3">
<div class="score-label">
<span>Intonation Score</span>
<span id="intonation-score">0%</span>
</div>
<div class="progress">
<div class="progress-bar progress-bar-inner bg-secondary" id="intonation-progress"
role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
</div>
<div class="feedback-section">
<h4>Speech Analysis Feedback</h4>
<p><strong>Identified Text:</strong> <span id="identified-text"></span></p>
<div id="feedback-container">
<!-- <p><strong>Pronunciation Feedback:</strong> <span id="pronunciation-feedback"></span></p> -->
<!-- <p><strong>Fluency Feedback:</strong> <span id="fluency-feedback"></span></p> -->
<!-- <p><strong>Accuracy Feedback:</strong> <span id="accuracy-feedback"></span></p> -->
<!-- <p><strong>Grammar Feedback:</strong> <span id="grammar-feedback"></span></p> -->
<!-- <p><strong>Intonation Feedback:</strong> <span id="intonation-feedback"></span></p>
<p><strong>Comprehension Feedback:</strong> <span id="comprehension-feedback"></span></p> -->
</div>
</div>
</div>
<!-- Bootstrap JS and Popper.js -->
<script src="https://cdn.jsdelivr.net/npm/@popperjs/[email protected]/dist/umd/popper.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js"></script>
<script>
function analyzeAudio() {
const audioFile = document.getElementById("audio-file").files[0];
const language = document.getElementById("language-select").value;
if (!audioFile) {
alert("Please upload an audio file.");
return;
}
const formData = new FormData();
formData.append("audio_file", audioFile);
formData.append("language", language)
fetch("/api/v1/analyze", {
method: "POST",
body: formData
})
.then(response => response.json())
.then(data => {
updateProgress('fluency', data.fluency_score);
updateProgress('pronunciation', data.pronunciation_score);
updateProgress('completeness', data.completeness_score);
updateProgress('accuracy', data.accuracy_score);
updateProgress('grammar', data.grammar_score);
updateProgress('comprehension', data.comprehension_score);
updateProgress('intonation', data.intonation_score);
const audioPlayer = document.getElementById("audio-player");
const audioURL = URL.createObjectURL(audioFile);
audioPlayer.src = audioURL;
document.getElementById("audio-player-container").style.display = "block";
// Example data to simulate the transcript and errors from the backend
// const grammar_errors = [{ 'word': 'dismissal', 'position_in_text': 2, 'error': 'Subject without a verb', 'suggestion': 'Ensure the subject is followed by a verb.' }, { 'word': 'college', 'position_in_text': 4, 'error': 'Missing article', 'suggestion': "Add an article ('a', 'an', 'the') before this noun." }, { 'word': 'he', 'position_in_text': 10, 'error': 'Subject without a verb', 'suggestion': 'Ensure the subject is followed by a verb.' }, { 'word': 'reaction', 'position_in_text': 13, 'error': 'Missing article', 'suggestion': "Add an article ('a', 'an', 'the') before this noun." }, { 'word': 'experiences', 'position_in_text': 24, 'error': 'Subject without a verb', 'suggestion': 'Ensure the subject is followed by a verb.' }, { 'word': 'experiences', 'position_in_text': 24, 'error': 'Missing article', 'suggestion': "Add an article ('a', 'an', 'the') before this noun." }, { 'word': 'factory', 'position_in_text': 32, 'error': 'Missing article', 'suggestion': "Add an article ('a', 'an', 'the') before this noun." }, { 'word': 'success', 'position_in_text': 38, 'error': 'Missing article', 'suggestion': "Add an article ('a', 'an', 'the') before this noun." }, { 'word': 'leader', 'position_in_text': 42, 'error': 'Subject without a verb', 'suggestion': 'Ensure the subject is followed by a verb.' }, { 'word': 'environment', 'position_in_text': 52, 'error': 'Missing article', 'suggestion': "Add an article ('a', 'an', 'the') before this noun." }, { 'word': 'clashes', 'position_in_text': 61, 'error': 'Missing article', 'suggestion': "Add an article ('a', 'an', 'the') before this noun." }, { 'word': 'Illusion', 'position_in_text': 64, 'error': 'Missing article', 'suggestion': "Add an article ('a', 'an', 'the') before this noun." }, { 'word': 'incense', 'position_in_text': 73, 'error': 'Missing article', 'suggestion': "Add an article ('a', 'an', 'the') before this noun." }, { 'word': 'violence', 'position_in_text': 75, 'error': 'Missing article', 'suggestion': "Add an article ('a', 'an', 'the') before this noun." }, { 'word': 'write', 'position_in_text': 77, 'error': 'Missing article', 'suggestion': "Add an article ('a', 'an', 'the') before this noun." }, { 'word': 'which', 'position_in_text': 82, 'error': 'Subject without a verb', 'suggestion': 'Ensure the subject is followed by a verb.' }]
// Function to highlight mispronounced words and grammar errors
function highlightErrors(text, mispronouncedWords, grammarErrors) {
const textArray = text.split(" ");
const highlightedTextArray = textArray.map((word, index) => {
// Check for mispronounced words
const mispronounced = mispronouncedWords.find(mw => mw.word === word && mw.position_in_text === index);
if (mispronounced) {
return `<span class="highlight-mispronounced">${word}</span>`;
}
// Check for grammar errors
const grammarError = grammarErrors.find(ge => ge.word === word && ge.position_in_text === index);
console.log("GRAMMAR ERROR: ", grammarError)
if (grammarError) {
return `<span class="highlight-grammar">${word}</span>`;
}
return word; // Return unmodified if no errors
});
return highlightedTextArray.join(" ");
}
// Apply the highlighting function to the DisplayText
const highlightedText = highlightErrors(data.display_text, data.mispronunced_words, data.grammar_errors);
// Inject the highlighted text into an HTML element
document.getElementById("identified-text").innerHTML = highlightedText;
// Update feedback
document.getElementById("pronunciation-feedback").textContent = data.pronunciation_feedback;
document.getElementById("fluency-feedback").textContent = data.fluency_feedback;
document.getElementById("accuracy-feedback").textContent = data.accuracy_feedback;
document.getElementById("grammar-feedback").textContent = data.grammar_feedback;
document.getElementById("intonation-feedback").textContent = data.intonation_feedback;
document.getElementById("comprehension-feedback").textContent = data.comprehension_feedback;
})
.catch(error => console.error('Error:', error));
}
function updateProgress(scoreType, score) {
const progressBar = document.getElementById(`${scoreType}-progress`);
const scoreLabel = document.getElementById(`${scoreType}-score`);
progressBar.style.width = `${score}%`;
progressBar.setAttribute('aria-valuenow', score);
scoreLabel.textContent = `${score}%`;
}
</script>
</body>
</html>