Layui upload 不支持直接校验视频时长或分辨率,需前端用 video 标签预检(有兼容性与性能限制)和服务端强制校验(如 ffprobe),二者结合才可靠。
layui upload 本身不支持校验视频时长或分辨率
layui 的 upload 组件只提供基础的文件类型(accept)、大小(size)和后缀(exts)限制,无法直接读取视频元信息。所谓“限制时长/分辨率”,必须在客户端预检或服务端二次校验,否则用户随便改个后缀就能绕过。
前端预检需用 FileReader + video 标签 + canvas(仅 Chrome/Firefox 支持)
可行但有严重限制:浏览器必须能解码该视频格式,且只适用于小文件(大视频 load 太慢甚至卡死)。关键步骤如下:
- 监听
choose回调,拿到files[0] - 用
URL.createObjectURL(file)创建临时地址 - 动态创建
<video></video>元素,onloadedmetadata触发后读取video.duration和video.videoWidth/video.videoHeight - 校验不通过就调用
upload.abort()并提示用户
示例片段:
upload.render({
elem: '#upload-video',
url: '/api/upload',
accept: 'video',
exts: 'mp4|avi|mov',
size: 1024 * 1024 * 500, // 500MB
choose: function(obj) {
const file = obj.files[0];
if (!file || !/video\/.*/.test(file.type)) return;
<pre class="brush:php;toolbar:false;">const video = document.createElement('video');
video.preload = 'metadata';
video.onloadedmetadata = function() {
if (video.duration > 600) { // 超过 10 分钟
layer.msg('视频不能超过 10 分钟');
obj.clear(); // 清空选择
URL.revokeObjectURL(video.src);
return;
}
if (video.videoWidth {
layer.msg('无法读取视频信息,请检查格式');
obj.clear();
};
video.src = URL.createObjectURL(file);} });
服务端必须做最终校验(强烈推荐)
前端校验可被跳过,所有关键规则必须在服务端落地。常见做法:
- Node.js 可用
ffprobe(来自 ffmpeg)解析:ffprobe -v quiet -show_entries format=duration:stream=width,height -of default=nw=1 input.mp4 - Python 推荐
moviepy或ffmpeg-python,避免依赖系统 ffmpeg 安装 - Java 可用
javacv或调用ffprobe子进程 - 校验失败立即返回 HTTP 400,并附带明确错误字段(如
"duration_too_long"),前端用done回调捕获并提示
注意兼容性与体验断点
用户上传超长视频时,前端预检可能卡住几秒甚至几十秒(尤其移动端),而服务端校验又得等完整上传完——这中间没有进度反馈,容易误以为卡死。建议:
- 前端预检加 loading 提示,超时(如 8 秒)自动跳过,仅靠服务端兜底
- 服务端开启分块上传(
chunk)支持,配合upload.setUploadOption配置,实现断点续传和更早的元信息校验(比如首块上传后就 probe) - 不要信任
file.size判断清晰度,MP4 可以是 1KB 却声明 4K 分辨率;必须实际解析流
真正可靠的方案永远是「前端轻量提示 + 服务端强制拦截」,任何只靠前端的限制都形同虚设。











