问题
I'm very new to Javascript. I haven't had much success finding an answer to my query. Here's a description of the problem.
I create an audio element and set the source to an .m4a file. The .m4a file is able to both load and play successfully.
I get strange results, however, when requesting the source audio duration. The following javascript produces 'NaN' in Chrome:
//Create audio element based on HTML audio id and modify controls accordingly
var aud = document.getElementById("storyTime");
aud.setAttribute("src",story.audioTitle);
console.log("DEBUG: Audio Duration = " + aud.duration); //Get 'NaN'
console.log("DEBUG: Audio Source = " + aud.src);
aud.controls = true;
I tried then inserting a button with an onclick callback in the HTML with a similar function. This button executing the "same code" returns the correct audio duration.
HTML:
<button onclick="checkDuration()" type="button">Get audio length</button><br>
javascript:
//Check audio duration
function checkDuration() {
var aud = document.getElementById("storyTime");
console.log("DEBUG: Audio Duration: " + aud.duration);
}
I figure the issue is with timing of said request. However, if I preface the duration request with loading events such as 'canplaythrough' I still get the 'NaN' response when using the inline code.
aud.addEventListener("canplaythrough", console.log("Audio duration = " + aud.duration));
I appreciate any tips on appropriately handing audio loading event sequence.
Thanks to Andy for the suggestions. I was able to query reliable duration with the following code.
//Create audio element based on HTML audio id and modify controls accordingly
var aud = document.getElementById("storyTime");
aud.setAttribute("src",story.audioTitle);
aud.controls = true;
aud.load();
aud.onloadeddata = function(){
var audDuration = aud.duration;
console.log("aud.duration = " + audDuration);
}
}
The solution I believe is due to invoking the load()
call before listening for loadeddata
.
Without the load()
call, the audio does eventually load, but the loadeddata
event fires before, or asynchronous, to duration available (methinks).
I made a test function to check audio duration. I try checking with two methods as follows:
//Check audio duration and disable controls if NaN
function checkDuration() {
var aud = document.getElementById("storyTime");
aud.addEventListener("loadeddata",console.log("DEBUG (loadeddata version): Audio Duration: " + aud.duration));
aud.onloadeddata = function(){
var audDuration = aud.duration;
console.log("DEBUG (onloadeddata version): Audio Duration: " + audDuration);
}
}
The results:
DEBUG (loadeddata version): Audio Duration: NaN DEBUG (onloadeddata version): Audio Duration: 1601.991111
I'm not sure I understand the difference, or why there would be a difference.
回答1:
The event loadeddata
should be your friend here:
aud.addEventListener("loadeddata", function() {
console.log("Audio data loaded");
console.log("Audio duration: " + this.duration);
});
来源:https://stackoverflow.com/questions/29019672/javascript-returns-nan-for-audio-duration-depending-on-request-sequence