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.
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