Zyaan
Zyaan

Reputation: 109

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

First thing first, I am trying to extract the video duration from the file and then display it without having to actually upload the file.

When a user selected a video - the information will be displayed below it includes file name, file size, file type. However much to my terrible skills - I cannot get the duration to display. I tried some code snippets i found from other sites as well as here but none of them seems to work. Just trying to find a simple code that would do the task.

I tried onloadedmetadata but I don't think that would even work.

Please note : I'm still learning javascript.

I also tried some sites tutorial & some code snippet I found via stackoverflow


           function uploadFunction(){
                //Variables
                var cVideo = document.getElementById("fileUp");
                var txtInfo = "";

               //function 
                if ('files' in cVideo){
                    if(cVideo.files.length == 0){
                    txtInfo = "Please select a video";
                } else {
                    for (var v = 0; v < cVideo.files.length; v++){
                        txtInfo += "<br><strong>#" + (v+1) + " File Information:</strong> <br>";         
                        var infoFile = cVideo.files[v];
                        if('name' in infoFile){
                            txtInfo += "File name: " +infoFile.name +"<br>";
                        }
                        if('size' in infoFile){
                           txtInfo += "File size: " +infoFile.size +" Bytes <br>"; 
                        }
                        if('type' in infoFile){
                            txtInfo += "File Type: "+infoFile.type +" <br>";
                        }
                        if('duration' in infoFile){
                            txtInfo += "Duration : "+infoFile.duration +"<br>";
                        }

                    }
                }

                }
                document.getElementById("information").innerHTML = txtInfo ;
 }

HTML


           <input type="file" id="fileUp" name="fileUpload" multiple size="50" onchange="uploadFunction()">
           <p id="information"></p>

Can't get the duration to appear at all.

Upvotes: 3

Views: 5124

Answers (1)

somethinghere
somethinghere

Reputation: 17340

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>

Upvotes: 7

Related Questions