Skip to content

Commit

Permalink
new captions
Browse files Browse the repository at this point in the history
  • Loading branch information
seth-shaw-asu committed Jan 28, 2025
1 parent 9ca6ba0 commit 03d2a5a
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 36 deletions.
113 changes: 78 additions & 35 deletions modules/islandora_audio/js/audio.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,44 +4,87 @@
* @file
* Displays Audio viewer.
*/
(function ($, Drupal) {
'use strict';
(function (Drupal, once) {
Drupal.behaviors.customBehavior = {
attach: function (context, settings) {

/**
* If initialized.
* @type {boolean}
*/
var initialized;
/**
* Unique HTML id.
* @type {string}
*/
var base;
once('customBehavior', 'audio', context).forEach(function (element) {
function parseTimestamp(timestamp) {
const [hours, minutes, seconds] = timestamp.split(':').map(Number);
return hours * 3600 + minutes * 60 + seconds;
}
function parseWebVTT(content) {
timeMarkerRegex = new RegExp("^\\d{2}:\\d{2}:\\d{2}\\.\\d{3} --> \\d{2}:\\d{2}:\\d{2}\\.\\d{3}$");
const lines = content.split('\n');
const cues = [];
let currentCue = null;

function init(context,settings){
if (!initialized){
initialized = true;
if ($('audio')[0].textTracks.length > 0) {
$('audio')[0].textTracks[0].oncuechange = function() {
if (this.activeCues.length > 0) {
var currentCue = this.activeCues[0].text;
$('#audioTrack').html(currentCue);
}
}
for (const line of lines) {
const trimmedLine = line.trim();
if (trimmedLine === 'WEBVTT') {
continue;
}
if (!trimmedLine) {
// Empty line indicates the end of a cue
if (currentCue) {
cues.push(currentCue);
currentCue = null;
}
continue;
}
}
}
Drupal.Audio = Drupal.Audio || {};

/**
* Initialize the Audio Viewer.
*/
Drupal.behaviors.Audio = {
attach: function (context, settings) {
init(context,settings);
},
detach: function () {
if (timeMarkerRegex.test(trimmedLine)) {
// Timing line
currentCue = { start: '', end: '', text: '' };
const [start, end] = trimmedLine.split(' --> ');
currentCue.start = parseTimestamp(start);
currentCue.end = parseTimestamp(end);
} else if (currentCue) {
// Text line
currentCue.text += (currentCue.text ? '\n' : '') + trimmedLine;
}
}
return cues;
}
};

})(jQuery, Drupal);
const vtt_source = element.querySelector("track[kind='captions']")?.getAttribute('src');
if (!vtt_source) { return; }
fetch(vtt_source).then(response => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.text();
}).then(text => {
const cues = parseWebVTT(text);

// Create a Custom Event attached to the timeupdate event to pass cues along.
element.addEventListener('timeupdate', (e) => {
const captionEvent = new CustomEvent('updateCaptions', { detail: cues })
e.target.dispatchEvent(captionEvent);
});
element.addEventListener('updateCaptions', (e) => {
if (!e.detail) {
return;
}

// Grab the caption for the current time.
const currentTime = e.target.currentTime;
let cue = e.detail.find(
(cue) =>
currentTime >= cue.start &&
currentTime <= cue.end
);

// Update the caption box.
let captionsBox = e.target.parentElement.querySelector('div.audioTrack')
if (cue?.text) {
captionsBox.innerHTML = cue.text.replace(/\n/g, "<br>");
} else {
captionsBox.innerHTML = '';
}
});
});
})
}
}
})(Drupal, once);
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* @ingroup themeable
*/
#}
<div id="audioTrack"></div>
<div class="audioTrack"></div>
<audio {{ attributes }}>
{% for file in files %}
<source {{ file.source_attributes }} />
Expand Down

0 comments on commit 03d2a5a

Please sign in to comment.