必须等待 loadedmetadata 事件触发后才能准确获取 video/audio 元素的 duration,此前读取为 NaN 或 0;需用 URL.createObjectURL 创建临时 URL 并监听该事件,校验后及时 revoke;大小校验须前置,避免大文件阻塞 UI;移动端 capture 场景下 loadedmetadata 可能不触发,需设超时 fallback;服务端必须用 ffprobe 二次校验,前端限制仅作体验优化。

用 loadedmetadata 读取视频时长再校验
浏览器不提供直接读取视频时长的同步 API,必须等元数据加载完成。loadedmetadata 是唯一可靠触发点,不能用 onload 或直接读 duration——此时值常为 NaN 或 0。
常见错误是把校验逻辑写在事件外,或没等 loadedmetadata 就取 audioElement.duration,结果永远判断失败。
- 必须用
URL.createObjectURL(file)创建临时 URL,传给HTMLMediaElement(video或audio均可) - 监听
loadedmetadata,而非canplay或loadeddata,前者保证duration可用 - 校验后立即调用
URL.revokeObjectURL(url)防止内存泄漏 - 若用户选的是无音轨纯画面视频(如某些 MOV),
audioElement仍能正确解析时长,无需换videoElement
file.size 和 duration 要分开校验,顺序不能反
先读大小再读时长,否则大文件会卡住 UI:一个 500MB 的 MP4,loadedmetadata 可能要等数秒,而 file.size 是瞬间获取的。
移动端尤其明显——Safari 对大文件的 size 读取是同步且可靠的,但时长解析可能因解码器限制失败(比如某些 HEVC 视频)。
立即学习“前端免费学习笔记(深入)”;
- 先检查
file.size > 100 * 1024 * 1024(如限 100MB),超了直接拒,不走后续解析 - 再创建
video元素并监听loadedmetadata,避免无效解析 - 若
duration为Infinity或NaN,说明元数据损坏或格式异常,应视为非法文件 - 别依赖
file.type判断是否为视频——伪造type很容易,必须靠实际解析
移动端 capture="user" 场景下时长限制更难生效
用 <input type="file" accept="video/*" capture="user"> 调起摄像头直录时,iOS Safari 和部分安卓 WebView 不保证返回的 File 对象能被 URL.createObjectURL 正确解析出时长——它可能是个“流式 blob”,loadedmetadata 永远不触发。
这不是代码 bug,是系统级限制。此时唯一能做的,是退回到“录制前限制”:用 MediaRecorder + timeSlice 主动截断,或提示用户“请勿录制超过 1 分钟”。
- 真机测试必须覆盖 iOS Safari、Chrome for Android、微信内置浏览器
- 不要在
capture场景下假设loadedmetadata一定回调 - 若回调未触发,需设超时(如 3s)并 fallback 提示:“无法验证视频时长,请重试或手动剪辑”
- Android WebView 中,部分旧版本甚至不支持
capture="user"录制视频,只支持拍照
后端必须二次校验,前端限制只是用户体验层
前端时长判断可被绕过:用户禁用 JS、用 curl 上传、或用开发者工具删掉校验逻辑。真正有效的限制在服务端。
比如 FFmpeg 命令行:ffprobe -v quiet -show_entries format=duration -of csv=p=0 your_video.mp4,取结果后比对是否 ≤ 60。
- Nginx 层无法校验时长,只能靠 client_max_body_size 控制体积
- Node.js + multer 接收后,必须用
child_process调用 ffprobe,不能只信前端传来的 duration 字段 - 若后端发现时长超标,HTTP 状态码应返回
413 Payload Too Large或422 Unprocessable Entity,而非 200 + 错误消息体 - 上传过程中断或网络抖动,可能导致只收到部分文件——此时 ffprobe 会报错,需捕获异常并清理临时文件
实际限制 1 分钟的关键点不在“怎么写代码”,而在接受「前端只能尽力而为,真正防线永远在服务端」。最常被忽略的是:移动端 capture 场景下,loadedmetadata 根本不可靠,却没人测真机。



















