大魔王手头有条相机推流链路,想知道画面到底慢了多少:肉眼看到的和相机推出来的之间差的那一截,就是链路延迟。量的思路不复杂——屏幕上放一块不断变化的读数,相机对着屏幕拍,同一瞬间两边各读一次数,差值就是延迟。缺的只是一块合适的"表",于是我写了个静态页面:gxmatmars.com/tools/latency.html。
表盘长什么样
黑色全屏,正中一块圆角矩形屏,两位大数字每秒跳一格,00 到 99 循环;下面一排 10 个方块,每 0.1 秒跳一格,一圈正好一秒。屏幕右上角有个"反色"按钮,黑底白字和白底黑字一键互换,亮环境下换成白底更清楚。
测法:让相机对着这块屏,在推流画面(或截图)里读一组"秒 + 格数",肉眼同时读一组,两者相减就是延迟。比如相机画面停在 03 + 40%,肉眼看到的是 04 + 50%,延迟就是 1.1 秒。秒位负责粗对齐,格位负责细读,进位绕圈也不会读错。
设计上绕的几个弯
第一版进度条每 50ms 走 1%,肉眼看着挺顺,相机里完全是糊的。原因想通之后很简单:普通相机 25~30 帧,一帧就是 33ms 往上,任何比帧间隔更细的刻度在画面里都是噪声。后来刻度改成 100ms 一格,肉眼和相机就都读得稳了——刻度粒度不该比测量工具的帧间隔还细。
中间还折腾过三轮七段码(数码管那种日字形),纯为了把数字做得够气派。最后想明白了:要的其实不是七段码,是"又大又粗"——普通等宽字体加大加粗、纵向拉一拉,气场一样,代码还省掉一整套绘制。需求探索绕的弯,最后往往收敛成一句大实话。
几个实现细节
- 读数不靠累加:所有数字都从按下那一刻的 t0 推算,切后台再回来也不漂。顺手还堵了个怪坑——rAF 的时间戳可能早于按下时刻,差值出负数会把渲染循环打崩,钳零了事,本地测不出来,上线才现形。
- 运行中申请 Wake Lock,屏幕不会中途睡掉;双击缩放、长按选中全部禁掉,免得测一半误触。
- 纯静态单文件,挂在博客域名下,手机打开即用,反色偏好会记住。
这页面就常驻在 tools/latency.html。哪天想量量家里摄像头、监控或者无线图传的延迟,手机打开它对着屏幕拍一张,答案就在两次读数的差里。