Get video duration when input a video file

I'm doing a project with HTML and Javascript that will run local with local files. I need to select a file by input, get it information and then decide if I'll add to my list and reproduce or not. And if i decide to use it I'll have to put it on a queue to use later. Otherwise I'll just discard and select another file.

The problem that I'm facing is that I cant't find a way to get the vídeo duration just by selecting it on input.

I've searched a lot and I didn't find any method to get the duration. In this code below I tried to use 'file.duration' but didn't work, it just returns 'undefined'.

That's my input, normal as you can see.

<div id="input-upload-file" class="box-shadow">
   <span>upload! (?????)</span> <!--ignore the text face lol -->
   <input type="file" class="upload" id="fileUp" name="fileUpload" onchange="setFileInfo()">
</div>

And that's the function that I'm using to get all the information.

function setFileInfo(){
  showInfo(); //change div content
  var file = document.getElementById("fileUp").files[0];
  var pid =  1;
  var Pname = file.name;
  Pname = Pname.slice(0, Pname.indexOf(".")); //get filename without extension
  var Ptype = file.type;
  var Psize = bytesToSize(file.size); //turns into KB,MB, etc...
  var Pprior = setPriority(Ptype); //returns 1, 2 or 3 
  var Pdur = file.duration;
  var Pmem = getMemory(Psize); //returns size * (100 || 10 || 1)
  var Pown = 'user';
  /* a lot of stuff throwing this info to the HTML */
  console.log(Pdur);
}

Is there way to do this? If not, what are the alternatives that can help me?

Answers:

Answer

I needed to validate a single file before continuing to execute more code, here is my method with the help of Kaiido's answer!

onchange event when a user uploads a file:

$("input[type=file]").on("change", function(e) {

    var file = this.files[0]; // Get uploaded file

    validateFile(file) // Validate Duration

    e.target.value = ''; // Clear value to allow new uploads
})

Now validate duration:

function validateFile(file) {

    var video = document.createElement('video');
    video.preload = 'metadata';

    video.onloadedmetadata = function() {

        window.URL.revokeObjectURL(video.src);

        if (video.duration < 1) {

            console.log("Invalid Video! video is less than 1 second");
            return;
        }

        methodToCallIfValid();
    }

    video.src = URL.createObjectURL(file);
}
Answer

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>

Answer

Here is async/await Promise version:

const loadVideo = file => new Promise((resolve, reject) => {
    try {
        let video = document.createElement('video')
        video.preload = 'metadata'

        video.onloadedmetadata = function () {
            resolve(this)
        }

        video.onerror = function () {
            reject("Invalid video. Please select a video file.")
        }

        video.src = window.URL.createObjectURL(file)
    } catch (e) {
        reject(e)
    }
})

Can be used as follows:

const video = await loadVideo(e.currentTarget.files[0])
console.log(video.duration)

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.