Audio duration returns NaN
Asked Answered
S

4

11

Accessing an HTML5 audio element (a .ogg file) with JavaScript in Chrome. The file does play properly, yet somehow it will not recognize the duration.

I just cribbed this code: https://www.w3schools.com/jsref/prop_audio_duration.asp (I know w3schools isn't great, but it seems like something else is the problem...)

var x = document.getElementById("testTone").duration;
console.log("duration:"+x);  // duration:NaN

var y = document.getElementById("testTone");
y.play();   // works!

the element...

<audio controls id="testTone">
    <source src="autoharp/tone0.ogg" type="audio/ogg">
</audio>
Superheterodyne answered 17/6, 2017 at 23:39 Comment(3)
what does your html look like?Gipsy
because audio need time to load and it is not ready when you calling .durationCommercial
@Gipsy added above...Superheterodyne
R
28

Add preload="metadata" to your tag to have it request the metadata for your audio object:

<audio controls id="testTone" preload="metadata">
    <source src="autoharp/tone0.ogg" type="audio/ogg">
</audio>

In your code, attach an event handler, to set the duration when the metadata has been loaded:

var au = document.getElementById("testTone");
au.onloadedmetadata = function() {
    console.log(au.duration)
};
Rumor answered 17/6, 2017 at 23:47 Comment(3)
REF: stevesouders.com/blog/2013/04/12/html5-video-preload preload='metadata' “Hints to the UA that the user is not expected to need the video, but that fetching its metadata (dimensions, first frame, track list, duration, and so on) is desirable.”Commercial
Thank you! I am still studying this, it helps. Page loading clearly has complexities that I need to understand better. A question: after the comment that the audio needed time to load, I tried wrapping my original code with a (jQuery) document.ready function... didn't work. Can you explain why not?Superheterodyne
Also - why the use of a function here? It works, but I feel like I'm missing something.Superheterodyne
C
0

Beside @FrankerZ's solution, you could also do the following:

<audio controls id="testTone">
  <source src="https://www.w3schools.com/jsref/horse.ogg" type="audio/ogg">
  <source src="https://www.w3schools.com/jsref/horse.mp3" type="audio/mpeg">
</audio>

<button onclick="myFunction()">Try it</button>

<script>
  function myFunction() {
    var x = document.getElementById("testTone").duration;
    console.log("duration:" + x); // duration:NaN

    var y = document.getElementById("testTone");
    y.play(); // works!
  }
</script>
Commercial answered 17/6, 2017 at 23:51 Comment(3)
Is this an obscure way of explaining the problem with w3schools? A direct approach would be better...Superheterodyne
@GregoryTippett in your code, the source is not valid as well.Commercial
@GregoryTippett preload='metadata' is a btter approch TBO :DCommercial
L
0

you can try this..hope it will work i used this in 'timeupdate' event as i was getting same NaN error.

var x = document.getElementById("testTone").duration;
if(x){
    console.log("duration:"+x);  
} 
Lodge answered 30/12, 2022 at 8:48 Comment(0)
M
0

function getDuration(){
let au = document.createElement('audio'), inp = document.getElementById('UploadInput');
  if (inp.value) {
    if (inp.files[0].type.match(/audio|video/g)) {
      au.src = URL.createObjectURL(inp.files[0])
      au.setAttribute('preload', "metadata")
      au.addEventListener('loadedmetadata', () => {
        console.log(`Duration: ~ ${au.duration.toFixed()}s`)
      })
      // document.body.appendChild(au)
    } else {
      console.log('File is not Audio/Video');
    }
  } else {
    console.log('No File Dropped!');
  }
}
<input id=UploadInput type=file onchange="getDuration();">
Marlow answered 27/3, 2023 at 18:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.