// Store path to audio file in a variable
var xFile = 'https://storage04.dropshots.com/photos7000/photos/1381926/20180318/175955.mp4'
// Store cues of each start time of each clip in an array
var xMap = [0, 1.266, 2.664, 3.409, 4.259,4.682, 5.311, 7.169, 7.777, 9.575, 10.88,11.883,13.64, 15.883, 16.75, 17, 17.58];
/* Register doc to act when the DOM is ready but before the images
|| are fully loaded. When that occurs, call loadAudio()
*/
document.addEventListener('DOMContentLoaded', function(e) {
loadAudio(e, xFile, xMap);
});
/* Pass the Event Object, file, and array through
|| Make a Template Literal of the HTML layout and the hidden
|| <audio> tag. Interpolate the ${file} into the <audio> tag.
|| Insert the TL into the <body> and parse it into HTML.
== Call generateBtn() function...
*/
function loadAudio(e, file, map) {
var template = `
<fieldset class='set'>
<legend>Sound FX Test Panel</legend>
</fieldset>
<audio id='sndFX' hidden>
<source src='${file}' type='audio/wav'>
</audio>`;
document.body.insertAdjacentHTML('beforeend', template);
generateBtn(e, map);
}
/* Pass the Event Object and the array through
|| Reference fieldset.set
|| create a documentFragment in order to speedup appending
|| map() the array...
|| create a <button>
|| Set btn class to .btn
|| Set button.btn data-idx to the corresponding index value of
|| map array.
|| Set button.btn text to its index number.
|| Add button.btn to the documentFragment...
|| return an array of .btn (not used in this demo)
== Call the eventBinder() function...
*/
function generateBtn(e, map) {
var set = document.querySelector('.set');
var frag = document.createDocumentFragment();
map.map(function(mark, index, map) {
var btn = document.createElement('button');
btn.className = 'btn';
btn.dataset.idx = map[index];
btn.textContent = index;
frag.appendChild(btn);
return btn;
});
set.appendChild(frag);
eventBinder(e, set, map);
}
/* Pass EventObject, fieldset.set, and map array through
|| Reference the <audio> tag.
|| Register fieldset.set to the click event
|| if the clicked node (e.target) class is .btn...
|| Determine the start and end time of the audio clip.
== Call playClip() function
*/
function eventBinder(e, set, map) {
var sFX = document.getElementById('sndFX');
set.addEventListener('click', function(e) {
if (e.target.className === 'btn') {
var cue = parseFloat(e.target.textContent);
var start = parseFloat(e.target.dataset.idx);
if (cue !== (map.length - 1)) {
var end = parseFloat(e.target.nextElementSibling.dataset.idx);
} else {
var end = parseFloat(sFX.duration);
}
playClip.call(this, sFX, start, end);
} else {
return false;
}
});
}
/* Pass the reference to the <audio> tag, start and end of clip
|| pause audio
|| Set the currentTime to the start parameter
|| Listen for timeupdate event...
|| should currentTime meet or exceed the end parameter...
|| pause <audio> tag.
*/
function playClip(sFX, start, end) {
sFX.pause();
sFX.currentTime = start;
sFX.play();
sFX.ontimeupdate = function() {
if (sFX.currentTime >= end) {
sFX.pause();
}
}
return false;
}