我正在用HTML和Javascript做一个项目,它将使用本地文件运行本地.我需要通过输入选择一个文件,获取它的信息然后决定我是否会添加到我的列表中并重现.如果我决定使用它,我将不得不把它放在队列中以便以后使用.否则我只会丢弃并选择另一个文件.
我面临的问题是,我无法通过在输入上选择它来找到获得vídeo持续时间的方法.
我搜索了很多,但没有找到任何方法来获得持续时间.在下面的代码中,我尝试使用' file.duration '但不起作用,它只返回' undefined '.
这是我的意见,你可以看到正常.
<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>
Run Code Online (Sandbox Code Playgroud)
这就是我用来获取所有信息的功能.
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);
}
Run Code Online (Sandbox Code Playgroud)
有办法做到这一点吗?如果没有,有哪些替代方案可以帮助我?
Kai*_*ido 39
在现代浏览器中,您可以使用URL.createObjectURL()带有非附加视频元素的URL API 来加载文件的内容.
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';
}
}Run Code Online (Sandbox Code Playgroud)
<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>Run Code Online (Sandbox Code Playgroud)
Nis*_*hah 18
从中获取视频时长很简单,FileReader并且在 中管理也很容易async/await。
const getVideoDuration = file =>
new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => {
const media = new Audio(reader.result);
media.onloadedmetadata = () => resolve(media.duration);
};
reader.readAsDataURL(file);
reader.onerror = error => reject(error);
});
Run Code Online (Sandbox Code Playgroud)
const duration = await getVideoDuraion(file);
Run Code Online (Sandbox Code Playgroud)
对象file在哪里File
实例
const duration = await getVideoDuraion(file);
Run Code Online (Sandbox Code Playgroud)
const getVideoDuration = (file) =>
new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => {
const media = new Audio(reader.result);
media.onloadedmetadata = () => resolve(media.duration);
};
reader.readAsDataURL(file);
reader.onerror = (error) => reject(error);
});
const handleChange = async (e) => {
const duration = await getVideoDuration(e.target.files[0]);
document.querySelector("#duration").innerText = `Duration: ${duration}`;
};Run Code Online (Sandbox Code Playgroud)
Ada*_*dam 11
这是 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)
}
})
Run Code Online (Sandbox Code Playgroud)
可以如下使用:
const video = await loadVideo(e.currentTarget.files[0])
console.log(video.duration)
Run Code Online (Sandbox Code Playgroud)
在继续执行更多代码之前,我需要验证单个文件,这是在Kaiido的帮助下的方法!
用户上传文件时的onchange事件:
$("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
})
Run Code Online (Sandbox Code Playgroud)
现在验证持续时间:
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);
}
Run Code Online (Sandbox Code Playgroud)
这就是我在将视频推送到 S3 之前设法获取视频持续时间的方法。我正在使用此代码上传 4+ GB 的视频文件。
注意 - 对于 .avi、.flv、.vob、.mpeg 等格式,将找不到持续时间,因此请通过向用户发送简单消息来处理它
//same method can be used for images/audio too, making some little changes
getVideoDuration = async (f) => {
const fileCallbackToPromise = (fileObj) => {
return Promise.race([
new Promise((resolve) => {
if (fileObj instanceof HTMLImageElement) fileObj.onload = resolve;
else fileObj.onloadedmetadata = resolve;
}),
new Promise((_, reject) => {
setTimeout(reject, 1000);
}),
]);
};
const objectUrl = URL.createObjectURL(f);
// const isVideo = type.startsWith('video/');
const video = document.createElement("video");
video.src = objectUrl;
await fileCallbackToPromise(video);
return {
duration: video.duration,
width: video.videoWidth,
height: video.videoHeight,
};
}
//call the function
//removing unwanted code for clarity
const meta = await this.getVideoDuration(file);
//meta.width, meta.height, meta.duration is ready for you to use
Run Code Online (Sandbox Code Playgroud)