I'm trying to count how many times an HTML5 Audio object(audioPlayer
) has played, by adding an 'ended
' event, and using the played
property which returns a Timesrange
Object. Nevertheless, this approach only works
ok until the 1st complete listen, ie, when it ends I get a Timesrange
object with all the partial listens. For further listens, it just "forgets" the 1st listen.
Here is my code
const audioPlayer = document.getElementById('soundPlayer');
audioPlayer.addEventListener(
'ended',
function() {
const timesPlayed = audioPlayer.played;
let totalTimePlayed = 0;
for (let i = 0; i < timesPlayed.length; i += 1) {
totalTimePlayed += timesPlayed.end(i) - timesPlayed.start(i);
}
const ratioPlayed = totalTimePlayed / audioPlayer.duration;
},
true
);
A second question is: how do I force an ended
event if the user leaves page while the audio is playing (ie, without having ended)?
(This experiment is a multi-page webapp "survey" with an HTML5 Audio Element in each page, that the user listens to, then by pressing a button goes to the next page.
I'm trying to use the onbeforeunload
, but I can't trigger the "ended" event.
function preventNavigatingAway() {
window.onbeforeunload = function() {
$('#soundPlayer').trigger('ended');
};
}
Additional comment: I'm not sure if the order for which I'm calling the events is correct, so here is my full code:
function initAudio(audioPlayer) {
audioPlayer.addEventListener(
'ended',
function() {
const ratioPlayedInput = $("input:text[name='input-ratioPlayed']").val() || '0';
let ratioPlayed = parseFloat(ratioPlayedInput);
let timesPlayed = $("input:text[name='input-timesPlayed']").val();
timesPlayed = parseInt(timesPlayed, 10) || 0;
const currTimesPlayed = audioPlayer.played;
let totalTimePlayed = 0;
for (let i = 0; i < currTimesPlayed.length; i += 1) {
totalTimePlayed += currTimesPlayed.end(i) - currTimesPlayed.start(i);
}
ratioPlayed += totalTimePlayed / audioPlayer.duration;
ratioPlayed = parseFloat(ratioPlayed.toFixed(2));
timesPlayed += currTimesPlayed.length;
$("input:text[name='input-ratioPlayed']").val(ratioPlayed);
$("input:text[name='input-timesPlayed']").val(timesPlayed);
},
true
);
return true;
}
function preventNavigatingAway() {
console.log('preventNavigatingAway');
window.onbeforeunload = function() {
$('#soundPlayer').trigger('ended');
console.log('in window.beforeunload()');
};
}
document.addEventListener('DOMContentLoaded', function() {
console.log('DOMContentLoaded!');
const audioPlayer = document.getElementById('soundPlayer');
initAudio(audioPlayer);
preventNavigatingAway();
});