Retrieving Html5 Video Duration Separately from the File

Retrieving HTML5 video duration separately from the file

The issue is in WebKit browsers; the video metadata is loaded after the video so is not available when the JS runs. You need to query the readyState attribute; this has a series of values from 0 to 4, letting you know what state the video is in; when the metadata has loaded you'll get a value of 1.

So you need to do something like:

window.setInterval(function(t){
if (video.readyState > 0) {
var duration = $('#duration').get(0);
var vid_duration = Math.round(video.duration);
duration.firstChild.nodeValue = vid_duration;
clearInterval(t);
}
},500);

I haven't tested that code, but it (or something like it) should work.

There's more information about media element attributes on developer.mozilla.org.

Get video duration when input a video file

In modern browsers, You can use the URL API's URL.createObjectURL() with an non appended video element to load the content of your file.

var myVideos = [];
window.URL = window.URL || window.webkitURL;
document.getElementById('fileUp').onchange = setFileInfo;
function setFileInfo() { var files = this.files; myVideos.push(files[0]); var video = document.createElement('video'); video.preload = 'metadata';
video.onloadedmetadata = function() { window.URL.revokeObjectURL(video.src); var duration = video.duration; myVideos[myVideos.length - 1].duration = duration; updateInfos(); }
video.src = URL.createObjectURL(files[0]);;}

function updateInfos() { var infos = document.getElementById('infos'); infos.textContent = ""; for (var i = 0; i < myVideos.length; i++) { infos.textContent += myVideos[i].name + " duration: " + myVideos[i].duration + '\n'; }}
<div id="input-upload-file" class="box-shadow">  <span>upload! (ღ˘⌣˘ღ)</span>  <input type="file" class="upload" id="fileUp" name="fileUpload"></div><pre id="infos"></pre>

Trying to get full video duration but returning as Nan

Wait for onloadedmetadata event, The loadedmetadata event is fired when the metadata has been loaded.

var myVideo = document.getElementById("videoPlayerNew");myVideo.onloadedmetadata = function() {  console.log('metadata loaded!');  console.log(this.duration);//this refers to myVideo};
<video id="videoPlayerNew" class="video-js vjs-default-skin vjs-controls-enabled" poster="http://camendesign.com/code/video_for_everybody/poster.jpg" data-setup="{}" controls="">  <source src="http://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4">    <p class="vjs-no-js">Javascript was disabled or not supported</p></video>

How to get video's metadata (length) before uploading?

It's actually reasonably simple, but since this requires turning the file into a blob and then checking its duration with a video element, uploading a video longer than a couple of minutes will take a lot of processing and slow down your page immensly. I have added a filesize restriction (which is a reasonable start in my opinion). Here's a snippet (which will not work on Stack Overflow due to sandbox restrictions, but I did test it on a local server). I obviously also don't check MIME types or whether its a video at all, although loadedmetadata will not trigger if you upload anything that is not a video.

const fileInput = document.querySelector( 'input[type=file]' );const fileDuration = document.getElementById( 'file-duration' )
// Listen for any change to the value of the file input
fileInput.addEventListener( 'change', event => {
fileDuration.textContent = 'Fetching video duration...';
// When the file selected by the user changes: // - create a fresh <video> element that has not yet fired any events // - create a file reader to safely retrieve and manipulate the file
const file = event.target.files[0]; const video = document.createElement( 'video' ); const reader = new FileReader();
// Cancel if the initial filesize just seems too large. // If the maximum allowed is 30 seconds, then a Gigabyte of file seems too much.
if( file.size > 10000000 ){
fileDuration.textContent = `File is too large (${file.size}). Refused to read duration.`; return;
}
// Before setting any source to the <video> element, // add a listener for `loadedmetadata` - the event that fires // when metadata such as duration is available. // As well as an error event is case something goes wrong.
video.addEventListener( 'loadedmetadata', event => {
// When the metadata is loaded, duration can be read.
fileDuration.textContent = `Video is ${video.duration} seconds long.`;
});
video.addEventListener( 'error', event => {
// If the file isn't a video or something went wrong, print out an error message.
fileDuration.textContent = `Could not get duration of video, an error has occurred.`;
});
// Before reading any file, attach an event listener for // when the file is fully read by the reader. // After that we can use this read result as a source for the <video>
reader.addEventListener( 'loadend', function(){
// reader.result now contains a `blob:` url. This seems like a // nonsensical collection of characters, but the <video> element // should be able to play it.
video.src = reader.result;
// After we assigned it to the `src` of the <video>, it will be // act like any other video source, and will trigger the related // events such as `loadedmetadata`, `canplay`, etc...
});
// Instruct the reader to read the file as a url. When its done // it will trigger the `loadend` event handler above.
reader.readAsDataURL( file );
});
<input type="file" /><p id="file-duration">No video file</p>


Related Topics



Leave a reply



Submit