Skip to content

Commit cf55b78

Browse files
authored
Merge pull request #260 from hyperaudio/259-alignment
Addresses #259 Added the ability to align an existing transcript to a machine generated timed transcript, so that the timings match.
2 parents f51106e + b8a9826 commit cf55b78

File tree

2 files changed

+382
-0
lines changed

2 files changed

+382
-0
lines changed

index.html

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
<script src="js/hyperaudio-lite-editor-deepgram.js"></script>
2828
<script src="js/hyperaudio-lite-editor-whisper.js"></script>
29+
<script src="js/word-alignment.js"></script>
2930

3031
<!-- DaisyUI / Tailwind -->
3132
<link href="https://cdn.jsdelivr.net/npm/daisyui@4.4.2/dist/full.css" rel="stylesheet" type="text/css" />
@@ -266,6 +267,14 @@
266267
<li><a id="upload-transcribe-btn">Upload & Transcribe</a></li>
267268
<hr
268269
class="my-2 h-0 border border-t-0 border-solid border-neutral-700 opacity-25 dark:border-neutral-200" />
270+
<li class="menu-title">
271+
<span>
272+
Align
273+
</span>
274+
</li>
275+
<li><a id="upload-align-btn">Add Transcript</a></li>
276+
<hr
277+
class="my-2 h-0 border border-t-0 border-solid border-neutral-700 opacity-25 dark:border-neutral-200" />
269278
<li class="menu-title">
270279
<span>
271280
Download as
@@ -552,6 +561,28 @@ <h3 class="font-bold text-lg" style="margin-bottom:16px">Transcribe</h3>
552561
</div>
553562
</div>
554563

564+
<input type="checkbox" id="align-modal" class="modal-toggle" />
565+
<div class="modal">
566+
<div class="modal-box">
567+
<label id="close-modal" for="align-modal" class="btn btn-sm btn-circle absolute right-2 top-2"></label>
568+
<h3 class="font-bold text-lg" style="margin-bottom:16px">Align</h3>
569+
570+
<div class="flex flex-col gap-4 w-full">
571+
<textarea
572+
id="align-text-input"
573+
name="align-text-input"
574+
placeholder="Paste the transcript text you want to align with the media here..."
575+
class="textarea textarea-bordered w-full h-48"
576+
rows="8"></textarea>
577+
</div>
578+
579+
<div class="modal-action">
580+
<button id="align-text-btn" class="btn btn-primary">ALIGN</button>
581+
</div>
582+
583+
</div>
584+
</div>
585+
555586
<input type="checkbox" id="regenerate-captions-modal" class="modal-toggle" />
556587
<div class="modal">
557588
<div class="modal-box">
@@ -575,6 +606,9 @@ <h3 class="font-bold text-lg">Caption Regeneration </h3>
575606
<script src="js/caption-modified.js"></script>
576607
<script>
577608

609+
console.log("version 3");
610+
611+
578612
let updateCaptionsFromTranscript = true;
579613
let captionMode = false; // used to detect whether we need to sanitise amongst other things
580614
let transcriptRequiresInit = false; // to know whether a transcript has been loaded while in captionMode and so not initialised
@@ -1655,6 +1689,94 @@ <h3 class="font-bold text-lg">Load from Local Storage</h3>
16551689
// Programmatically check the transcribe-modal checkbox to open the modal
16561690
document.getElementById('transcribe-modal').checked = true;
16571691
});
1692+
1693+
document.getElementById('upload-align-btn').addEventListener('click', function() {
1694+
document.getElementById('align-modal').checked = true;
1695+
});
1696+
1697+
// Add event listener for ALIGN button
1698+
document.getElementById('align-text-btn').addEventListener('click', function() {
1699+
alignTranscriptText();
1700+
});
1701+
1702+
// Word Alignment Algorithm with Loader
1703+
function alignTranscriptText() {
1704+
console.log("aligning...");
1705+
try {
1706+
// Get the pasted text from the textarea
1707+
const plainText = document.getElementById('align-text-input').value.trim();
1708+
1709+
if (!plainText) {
1710+
alert('Please paste some text to align.');
1711+
return;
1712+
}
1713+
1714+
// Get the current timed transcript HTML
1715+
const hypertranscriptDiv = document.getElementById('hypertranscript');
1716+
if (!hypertranscriptDiv) {
1717+
alert('No timed transcript found.');
1718+
return;
1719+
}
1720+
1721+
// Store original content in case we need to restore it on error
1722+
const originalContent = hypertranscriptDiv.innerHTML;
1723+
1724+
// Close the modal first
1725+
document.getElementById('align-modal').checked = false;
1726+
1727+
// Clear the textarea
1728+
document.getElementById('align-text-input').value = '';
1729+
1730+
// Wait for modal to close, then show loader and start alignment
1731+
setTimeout(() => {
1732+
// Show loader
1733+
hypertranscriptDiv.innerHTML = '<div class="vertically-centre"><center>Aligning transcript....</center><br/><img src="'+transcribingSvg+'" width="50" alt="aligning" style="margin: auto; display: block;"></div>';
1734+
1735+
// Short delay to allow loader to render before processing
1736+
setTimeout(() => {
1737+
try {
1738+
// Extract words and timings from existing HTML
1739+
const { words: sourceWords, timings, htmlStructure } = extractTimedWords(originalContent);
1740+
1741+
if (sourceWords.length === 0) {
1742+
hypertranscriptDiv.innerHTML = originalContent;
1743+
alert('No timed words found in the current transcript.');
1744+
return;
1745+
}
1746+
1747+
// Split plain text into words, excluding speaker names
1748+
const targetWords = extractWordsWithoutSpeakers(plainText);
1749+
1750+
// Align words
1751+
const alignment = alignWords(sourceWords, targetWords);
1752+
1753+
// Generate new HTML with aligned timings and paragraph structure
1754+
const newHTML = generateAlignedHTML(alignment, sourceWords, targetWords, timings, htmlStructure, plainText);
1755+
1756+
// Update the hypertranscript div with aligned content
1757+
hypertranscriptDiv.innerHTML = newHTML;
1758+
1759+
// Reinitialize hyperaudio to recognize the new transcript
1760+
if (typeof hyperaudio === 'function') {
1761+
hyperaudio();
1762+
}
1763+
1764+
} catch (error) {
1765+
console.error('Alignment error:', error);
1766+
hypertranscriptDiv.innerHTML = originalContent;
1767+
alert('Error during alignment: ' + error.message);
1768+
}
1769+
}, 100); // Small delay to allow loader to render
1770+
}, 300); // Wait for modal close animation
1771+
1772+
} catch (error) {
1773+
console.error('Alignment error:', error);
1774+
alert('Error during alignment: ' + error.message);
1775+
}
1776+
}
1777+
1778+
// Alignment functions are now in js/word-alignment.js
1779+
16581780
</script>
16591781

16601782

0 commit comments

Comments
 (0)