Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Facing Problem in retrieving HTML5 video duration
A common problem when working with HTML5 video is that the duration property returns NaN (Not a Number) when you try to access it before the browser has finished loading the video's metadata. This happens because the video file's metadata (which contains the duration, dimensions, etc.) is not available immediately after the page loads.
Why Does video.duration Return NaN?
The HTML5 <video> element has a readyState attribute that indicates how much data the browser has loaded. It has values from 0 to 4 −
-
0(HAVE_NOTHING) − No data available yet. -
1(HAVE_METADATA) − Metadata (duration, dimensions) is loaded. -
2(HAVE_CURRENT_DATA) − Data for current playback position is available. -
3(HAVE_FUTURE_DATA) − Enough data for the next few frames. -
4(HAVE_ENOUGH_DATA) − Enough data to play through without buffering.
The duration property is only available once readyState reaches at least 1 (metadata loaded). If you query it at readyState 0, you get NaN.
Solution: Using the loadedmetadata Event
The cleanest solution is to listen for the loadedmetadata event, which fires as soon as the browser has loaded the video's metadata ?
Example
<!DOCTYPE html>
<html>
<body>
<video id="myVideo" src="sample.mp4"></video>
<p>Duration: <span id="duration">Loading...</span> seconds</p>
<script>
var video = document.getElementById('myVideo');
video.addEventListener('loadedmetadata', function() {
var videoDuration = Math.round(video.duration);
document.getElementById('duration').textContent = videoDuration;
});
</script>
</body>
</html>
Once the metadata loads, the loadedmetadata event fires and the duration is displayed. This is the recommended approach.
Alternative: Polling with setInterval
If you need to support edge cases where the event may not fire reliably, you can poll the readyState attribute using setInterval. The interval checks every second whether the metadata is ready, retrieves the duration, and then clears itself ?
Example
<!DOCTYPE html>
<html>
<body>
<video id="myVideo" src="sample.mp4"></video>
<p>Duration: <span id="duration">Loading...</span> seconds</p>
<script>
var video = document.getElementById('myVideo');
var tm = window.setInterval(function() {
// Check if metadata is loaded
if (video.readyState > 0) {
var videoDuration = Math.round(video.duration);
document.getElementById('duration').textContent = videoDuration;
clearInterval(tm);
}
}, 1000);
</script>
</body>
</html>
This polls every 1000 milliseconds (1 second). Once readyState is greater than 0, the duration is read and the interval is cleared to stop further polling.
Conclusion
The video.duration property returns NaN if accessed before metadata is loaded. Use the loadedmetadata event as the primary solution, or fall back to polling readyState with setInterval if needed.
