elevenlabs_field-1.0.0-beta7/js/elevenlabs-widget.js
js/elevenlabs-widget.js
(function (Drupal) { Drupal.behaviors.elevenlabsJsPlayer = { players: {}, intervals: {}, timings: {}, currentCandidate: {}, nextCandidate: {}, attach: function (context, settings) { // We always take over the play buttons click. context.querySelectorAll('.elevenlabs-global-play').forEach((item) => { let id = item.id; let playerData = drupalSettings.elevenlabs[id]; // Wait until all audios are loaded, before allowing to play them. let counter = 0; if (playerData.state == 'loading') { playerData.state = 'stopped'; for (let a of playerData.items) { document.getElementById(a.id).addEventListener('canplaythrough', () => { counter++; if (counter == playerData.totalItems) { document.getElementById(id).removeAttribute('disabled'); this.calculateTimings(id); drupalSettings.elevenlabs[id]['item'] = item; this.setEvents(id, item, playerData); } }); } } }) }, setEvents(id, item, playerData) { // Play button. if (!item.getAttribute('listener')) { item.setAttribute('listener', 'true'); item.addEventListener('click', (e) => { if (playerData.state == 'stopped') { this.startPlaying(id, item, playerData); } else { this.pausePlaying(id, item, playerData); } return false; }); } // Seeker. let seeker = document.querySelector('#' + id).parentElement.querySelector('#seek-slider'); if (!seeker.getAttribute('listener')) { seeker.setAttribute('listener', 'true'); seeker.addEventListener('input', (e) => { this.pauseAllPlayers(id, true); clearInterval(this.intervals[id]); playerData.currentTime = seeker.value * (playerData.totalTime / 1000); this.updateTimings(id, true); this.resetCandidates(id); if (playerData.state == 'started') { this.playTrack(id); } }); } }, startPlaying(id, item, playerData) { item.classList.add('pause'); playerData.state = 'started'; if ('id' in this.currentCandidate) { document.getElementById(this.currentCandidate.id).play(); } this.playTrack(id); }, pausePlaying(id, item, playerData) { playerData.state = 'stopped'; this.stopTrack(id); item.classList.remove('pause'); }, playTrack(id) { if (!('startTime' in this.currentCandidate)) { this.getNextCandidate(id); this.currentCandidate = this.nextCandidate; } this.intervals[id] = setInterval(() => { Drupal.behaviors.elevenlabsJsPlayer.updateTimings(id, false); }, 10); this.updateTimings(id, false) }, resetCandidates(id) { this.resetCurrentCandidate(id); this.getNextCandidate(id); }, stopTrack(id) { clearInterval(this.intervals[id]); this.pauseAllPlayers(id, false); }, updateTimings(id, force) { let playerData = drupalSettings.elevenlabs[id]; if (!force && 'startTime' in this.nextCandidate && playerData.currentTime >= this.nextCandidate.startTime) { this.currentCandidate = this.nextCandidate; } if (!force && 'startTime' in this.nextCandidate && playerData.currentTime >= this.currentCandidate.startTime && playerData.currentTime <= (this.currentCandidate.startTime + this.currentCandidate.duration)) { document.getElementById(this.currentCandidate.id).play(); this.getNextCandidate(id); } playerData.currentTime = (Math.round(playerData.currentTime / 10) * 10) + 10; if (playerData.currentTime >= playerData.totalTime) { this.resetPlayer(id); } if ((playerData.currentTime % 1000 === 0) || force) { document.querySelector('#audio-player-container #current-time').innerHTML = (this.calculateTime((playerData.currentTime / 1000))); } if ((playerData.currentTime % 10 === 0) || force) { document.getElementById('audio-player-container').style.setProperty('--seek-before-width', playerData.currentTime / playerData.totalTime * 100 + '%'); document.getElementById('seek-slider').value = (playerData.currentTime / playerData.totalTime * 1000); } }, calculateTimings(id) { let playerData = drupalSettings.elevenlabs[id]; if (!(id in this.timings)) { this.timings[id] = {}; let startTime = 0; for (let a of playerData.items) { let audio = document.getElementById(a.id); a.duration = audio.duration*1000; a.startTime = startTime + parseInt(a.timePadding); startTime += a.duration + parseInt(a.timePadding); } playerData.totalTime = startTime; document.querySelector('#audio-player-container #duration').innerHTML = (this.calculateTime((startTime/1000))); } }, getNextCandidate(id) { let playerData = drupalSettings.elevenlabs[id]; for (let a of playerData.items) { if (playerData.currentTime <= a.startTime && this.currentCandidate != a) { this.nextCandidate = a; return; } } }, resetCurrentCandidate(id) { let playerData = drupalSettings.elevenlabs[id]; for (let a of playerData.items) { if (playerData.currentTime <= (a.startTime + a.duration) && playerData.currentTime >= a.startTime) { this.currentCandidate = a; // Also scrub to correct place. let time = (playerData.currentTime - a.startTime) / 1000; document.getElementById(a.id).currentTime = time; return; } } }, pauseAllPlayers(id, reset) { let playerData = drupalSettings.elevenlabs[id]; for (let x of playerData.items) { let player = document.getElementById(x.id); player.pause(); if (reset) { player.currentTime = 0; } } }, resetPlayer(id) { let playerData = drupalSettings.elevenlabs[id]; playerData.item.classList.remove('pause'); clearInterval(this.intervals[id]); playerData.currentTime = 0; this.nextCandidate = {}; this.currentCandidate = {}; playerData.state = 'stopped' }, calculateTime(secs) { const minutes = Math.floor(secs / 60); const seconds = Math.floor(secs % 60); const returnedSeconds = seconds < 10 ? `0${seconds}` : `${seconds}`; return `${minutes}:${returnedSeconds}`; } }; })(Drupal);