I'm creating my audio element with new Audio()
, however when adding the event listener 'waiting'
, it triggers right away when I press play and does not actually trigger when it starts buffering.
Code:
var source = new Audio('some-url');
source.addEventListener('waiting', function () {
alert('Buffering');
};
source.play()
So 'waiting'
triggers right away, but it doesn't trigger again when audio starts buffering after playing, however it also triggers ONCE if I seek the track (even on localhost). How can I do this?
I'm creating my audio element with new Audio()
, however when adding the event listener 'waiting'
, it triggers right away when I press play and does not actually trigger when it starts buffering.
Code:
var source = new Audio('some-url');
source.addEventListener('waiting', function () {
alert('Buffering');
};
source.play()
So 'waiting'
triggers right away, but it doesn't trigger again when audio starts buffering after playing, however it also triggers ONCE if I seek the track (even on localhost). How can I do this?
3 Answers
Reset to default 4The behavior you're seeing from the waiting
event is as expected per Mozilla documentation (https://developer.mozilla/en-US/docs/Web/Guide/Events/Media_events):
waiting
Sent when the requested operation (such as playback) is delayed pending the pletion of another operation (such as a seek).
To get progress of media download, you'll want to listen to either loadstart
for a one-time event or progress
for a recurring event:
loadstart
Sent when loading of the media begins.
progress
Sent periodically to inform interested parties of progress downloading the media. Information about the current amount of the media that has been downloaded is available in the media element's buffered attribute.
var source = new Audio();
source.addEventListener('waiting', function () {
window.alert('Waiting');
};
source.addEventListener('loadstart', function () {
window.alert("Loading");
};
source.addEventListener('progress', function () {
// do something, eg:
var timeRanges = source.buffered;
if (timeRanges && timeRanges.length > 0) {
console.log(timeRanges);
// do something with the TimeRanges object
}
};
source.play()
I know I'm late but this should do
let slowInternetTimeout = null;
source.addEventListener('loadstart', function () {
//show buffering
alert('Buffering');
});
source.addEventListener('waiting', () => {
slowInternetTimeout = setTimeout(() => {
//show buffering
alert('Buffering');
});
});
source.addEventListener('playing', () => {
if(slowInternetTimeout != null){
clearTimeout(slowInternetTimeout);
slowInternetTimeout = null;
//continue playing
alert('Play continues');
}
});
So for me this worked:
var source, sourceTime, dateTime;
source = new Audio('some-url');
function pare() {
var difference = Math.abs(sourceTime - dateTime);
if (difference > 1000) {
alert('buffering!');
}
};
source.addEventListener('timeupdate', function () {
var date, time;
date = new Date();
time = date.getTime();
sourceTime = date;
});
function updateTime() {
var date, time;
date = new Date();
time = date.getTime();
dateTime = time;
pare();
setTimeout(updateTime(), 50);
};
source.play()
updateTime();
The reason you need to check if difference is greater than 1000 is because timeupdate
event is inconsistent and might sometimes be exactly one second differ.