Estoy haciendo un proyecto con HTML y Javascript que se ejecutará localmente con archivos locales. Necesito seleccionar un archivo por entrada, obtener su información y luego decidir si lo agregaré a mi lista y lo reproduciré o no. Y si decido usarlo tendré que ponerlo en una cola para usarlo más tarde. De lo contrario, descartaré y seleccionaré otro archivo.
El problema al que me enfrento es que no puedo encontrar una manera de obtener la duración del video simplemente seleccionándolo en la entrada.
He buscado mucho y no encontré ningún método para obtener la duración. En este código a continuación, traté de usar ' file.duration ' pero no funcionó, simplemente devuelve ' undefined '.
Esta es mi entrada, normal como puedes ver.
<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>Y esta es la función que estoy usando para obtener toda la información.
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); }¿Hay alguna manera de hacer esto? Si no, ¿cuáles son las alternativas que me pueden ayudar?
En los navegadores modernos , puede usar URL.createObjectURL() de la API de URL con un elemento de video no agregado para cargar el contenido de su archivo.
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>Necesitaba validar un solo archivo antes de continuar ejecutando más código, ¡aquí está mi método con la ayuda de la respuesta de Kaiido!
onchange evento cuando un usuario sube un archivo:
$("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 })Ahora valide la duración:
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); }Aquí está la versión async/await Promise:
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) } })Se puede utilizar de la siguiente manera:
const video = await loadVideo(e.currentTarget.files[0]) console.log(video.duration)