Javascript returns NaN for audio duration depending on request sequence

北城以北 提交于 2019-12-06 06:50:13

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!