视频时长过滤器必须用秒数而非毫秒,uni-app中video组件返回的duration单位为秒(浮点数),直接传入Date会误解析为时间戳;应先转整数秒Math.floor(Number(value)),再独立封装时长格式化逻辑,支持00:00至99:59:59动态分级显示。

视频时长过滤器必须用秒数,不是毫秒
uni-app 里视频时长通常来自 video 组件的 @timeupdate 或 duration 事件,返回值单位是**秒(浮点数)**,不是毫秒。直接传给日期格式化函数会错——比如 new Date(123) 是解析时间戳,结果是 1970 年某个毫秒时刻,完全不是 2 分 3 秒。
常见错误现象:{{ duration | formatDuration }} 显示 “1970-01-01 08:00:00” 或 NaN;原因是把秒当毫秒用了。
- 所有视频时长输入必须先转为整数秒:
Math.floor(Number(value)) - 不要用
Date构造:它不适用于时长,只适用于时间点 - 时长格式化逻辑要独立封装,和日期格式化彻底分离
格式化逻辑要支持 00:00 到 99:59:59 三级结构
用户看到的视频时长可能是几十秒、几分钟、几小时,得按实际长度自动补零并省略高位。不能硬写成 HH:mm:ss 固定三位,否则 90 秒会显示成 00:01:30,而用户更习惯 1:30。
推荐做法:根据总秒数动态决定输出层级:
- ss 格式(如
45) - mm:ss 格式(如
12:05) - ≥ 3600 秒 →
HH:mm:ss格式(如01:23:45) - 所有数字都用
String(num).padStart(2, '0')补零,避免9:5这种非法格式
全局过滤器注册时注意作用域和类型校验
在 main.js 中用 Vuex.filter 注册时,容易忽略字符串输入(比如后端返回 "123.45")或 null/undefined 场景,导致 NaN 或崩溃。
实操建议:
- 第一行加类型判断:
if (value == null || value === '') return '--' - 统一转数字:
const sec = Math.floor(Number(value)),Number("123.45")得到123.45,再floor才安全 - 避免在过滤器里做副作用操作(如 console.log),它可能被频繁调用影响性能
- 微信小程序端过滤器执行环境受限,复杂逻辑建议改用计算属性或
methods
uni-dateformat 不适用,别混用
是专为「时间点」设计的组件,内部依赖 Date.now() 和阈值数组处理相对时间(如“刚刚”),它**无法解析纯秒数**。传 :date="123" 会当作时间戳解析,结果永远是 1970 年。
如果你已经用了 uni-dateformat,切记:
- 视频时长绝对不要塞进
的date属性 - 它的
threshold是毫秒数组,和秒数无关,传[60000, 3600000]没意义 - 需要“剩余时长”或“播放进度百分比”,应单独封装
formatRemain(sec)函数,而非复用日期组件
真正难的不是算分钟和秒,而是让不同长度的时长都自然可读——比如 59 秒显示 59,61 秒立刻变成 1:01,中间没有过渡态。这个边界判断必须精确,且所有平台表现一致,iOS 和安卓都不能出错。











