audiojs
audiojs copied to clipboard
loading timer cannot clearinterval(fixed)
I found timer-probrem, and fix it.
For example, When HTTP-Header's failure, audio.js element's "loadTimer" cannot clearInterval.
sample: http://dobes.jp/timer_cannot_clear/error ↓ http://dobes.jp/timer_cannot_clear/fixed/
trackLoadProgress: function(audio) {
// If `preload` has been set to `none`, then we don't want to start loading the track yet.
if (!audio.settings.preload) return;
var readyTimer,
loadTimer,
audio = audio,
ios = (/(ipod|iphone|ipad)/i).test(navigator.userAgent);
// Use timers here rather than the official `progress` event, as Chrome has issues calling `progress` when loading mp3 files from cache.
readyTimer = setInterval(function() {
if (audio.element.readyState > -1) {
// iOS doesn't start preloading the mp3 until the user interacts manually, so this stops the loader being displayed prematurely.
if (!ios) audio.init.apply(audio);
}
if (audio.element.readyState > 1) {
if (audio.settings.autoplay) audio.play.apply(audio);
clearInterval(readyTimer);
// Once we have data, start tracking the load progress.
loadTimer = setInterval(function() {
// ########## add console out ##########
app.log("waiting load complete.");
audio.loadProgress.apply(audio);
if (audio.loadedPercent >= 1) clearInterval(loadTimer);
}, 200);
}
}, 200);
audio.readyTimer = readyTimer;
audio.loadTimer = loadTimer;
},
trackLoadProgress: function(audio) {
// If `preload` has been set to `none`, then we don't want to start loading the track yet.
if (!audio.settings.preload) return;
var // readyTimer, // ########## remove.
// loadTimer, // ########## remove.
audio = audio,
ios = (/(ipod|iphone|ipad)/i).test(navigator.userAgent);
// Use timers here rather than the official `progress` event, as Chrome has issues calling `progress` when loading mp3 files from cache.
// ########## set timer handle to audio's member direct. ##########
audio.readyTimer = setInterval(function() {
if (audio.element.readyState > -1) {
// iOS doesn't start preloading the mp3 until the user interacts manually, so this stops the loader being displayed prematurely.
if (!ios) audio.init.apply(audio);
}
if (audio.element.readyState > 1) {
if (audio.settings.autoplay) audio.play.apply(audio);
clearInterval(audio.readyTimer); // handle -> audio's member
// Once we have data, start tracking the load progress.
// ########## set timer handle to audio's member direct. ##########
audio.loadTimer = setInterval(function() {
// ########## add logging ##########
app.log("waiting load complete.");
audio.loadProgress.apply(audio);
if (audio.loadedPercent >= 1) clearInterval(loadTimer);
}, 200);
}
}, 200);
//audio.readyTimer = readyTimer; // ########## remove.
//audio.loadTimer = loadTimer; // ########## remove.
},
Freaky timing, thanks for picking up on this too. I'm in the process of adding support for event cleanup for instance destruction, and I notice that this timer isn't clearing either.
For the loadtimer, you also need to change the reference to: if (audio.loadedPercent >= 1) clearInterval(audio.loadTimer);
However, for me this condition is never met for some reason, and so the interval is never cleared, in my destroy() method, I'm trying to clear both audio.readyTimer and audio.loadTimer - but neither are clearing still.
EDIT: looking more closely at audio.loadTimer issue, it looks like audio.loadedPercent never reaches a value of 1 in Chrome, where it does in FF, so the interval is never cleared :(
FURTHER EDIT: It also looks like there can be multiple intervals running, so at least one never gets cleaned up. This can be a result of multiple calls to trackLoadProgress: container[audiojs].events.trackLoadProgress(audio);
Advisable to add in a check inside trackLoadProgress to only create audio.readyTimer and audio.loadTimer if they are not already created.
I'm sorry, can't understand English well. Japanese study english six years, but...(- -;
I can show you my dispose method, add to container[audiojsInstance].prototype(line-598)
dispose: function(){
//in play, stop it.
if (this.playing){
this.pause();
}
//in loading, clear timer.
if (this.loadedPercent < 1) {
if (!!this.loadTimer){
clearInterval(this.loadTimer);
}
if (!!this.readyTimer){
clearInterval(this.readyTimer);
}
}
if (this.detachEvents){
this.detachEvents();
}
//remove all <audio>tag.
$(this.wrapper).find("audio").remove();
_.each(this, function(v, k){
delete this[k];
}, this);
}