UPTools UPTools
生活 主笔:工具匠

浏览器能当硬件检测仪:键盘、麦克风、摄像头测试原理

上周帮同事验一把新到的机械键盘,他纠结半天要不要去网上下一个检测软件。我拦住他:那种来路不明的 exe 别装,装完大概率弹广告,键盘有没有坏键浏览器就能测。打开 键盘按键测试,让他从 Q 敲到 P、从 A 敲到 L,每个键亮不亮一目了然。

类似的事最近遇到三次。另一个同事开会前说对方听不见他说话,第三个抱怨笔记本摄像头打不开。我都用同一个套路:打开浏览器,几行 Web API 就把硬件扒清楚。下面讲清浏览器凭什么能测这三类硬件,各靠什么 API,以及最常见的「检测不到」要怎么排。

浏览器凭什么能测硬件

打开 F12 你就明白,浏览器不是个只能显示网页的壳,它背后是一整套 Web API,能直接跟操作系统的输入输出层打交道。键盘事件走 KeyboardEvent,麦克风和摄像头走 navigator.mediaDevices.getUserMedia,音频数据再交给 Web Audio API 的 AnalyserNode 处理。这些 API 本来是为网页里的富交互准备的(在线会议、网页游戏、表单输入),刚好也能拿来当检测仪用。

好处是双重的。一是不装软件,一个网址打开就能测;二是数据全在本地处理,按键流水、音频波形、视频帧都不会上传服务器,没有隐私顾虑。下面三节按硬件类型展开。

键盘:监听 keydown/keyup,分清 key 和 code

键盘是最好测的一个。每次按下松开,浏览器都会派发 KeyboardEvent,事件对象上有两个最容易混的字段:keycode

key 是逻辑键名,告诉你「这个键现在代表什么字符」。单独按 A,keya;按住 Shift 再按 A,key 变成 A;开了中文输入法再按,key 可能是 Process,因为按键被输入法接管了。

code 是物理位置,跟当前按了什么修饰键、开了什么输入法都没关系。A 键的 code 永远是 KeyA,不管大写小写、不管中英文。前端做快捷键绑定时常用 code 而不是 key,就是因为 code 在不同键盘布局下稳定。检测坏键也看 code,因为你关心的是「这个物理位置的键通不通电」,不是「它现在输出什么字符」。

键盘按键测试 打开,挨个按一遍,虚拟键盘对应位置亮起来就说明键触发了。不亮的键要么坏了,要么被系统拦截了。

排障时几个常踩的点:

第一,Fn 键、Power 键、音量加减这种媒体键经常测不到。这些键在键盘固件或系统驱动层就被拦下来,根本没传到浏览器,不是坏了,别送修。

第二,同时按下多个键,有几个键死活不响应。这是薄膜键盘的「键位冲突」,行话叫幽灵键(ghosting)。原因是薄膜键盘用矩阵扫描电路,特定组合的按键会互相干扰,电路识别不出来。要同时识别任意多键,得换 NKRO(N-Key Rollover,全键无冲)键盘,多数机械键盘标了 NKRO 就能做到。游戏玩家发现「我同时按 W A Shift 空格有时候有一个不响应」,多半就是键位冲突,不是手速问题。

第三,浏览器对按键完全没反应。先在页面上点一下让它拿到焦点,输入框、按钮、地址栏都可能把焦点抢走。

麦克风:申请权限,再画波形

麦克风稍微复杂。先调 navigator.mediaDevices.getUserMedia({ audio: true }),浏览器弹个权限框问「是否允许使用麦克风」,用户同意后才返回一路音频流。拿到流之后接到 Web Audio API 的 AnalyserNode 上,节点会持续把音频数据算成频域和时域,我们取其中一段算 RMS(均方根)就能得到当前音量,画成跳动的条或波形。

麦克风测试 走的就是这条路子。对着说话,音量条起伏、波形跳动,说明从硬件到浏览器这条路通着。

回到开头那位「对方听不见」的同事。我让他打开测试页,波形一条直线。权限给了,硬件应该没坏。点开系统设置一看,默认输入设备选成了早就拔掉的蓝牙耳机,当前用的 USB 耳机麦被晾在一边。把默认输入切回 USB 耳机,波形立刻跳起来。这种「设备选错」比硬件故障常见得多。

「检测不到声音」的排查顺序我背下来了:

先看浏览器权限。地址栏左边那个小图标点开,麦克风是不是允许。如果曾被永久拒绝,权限框不会再弹,得去站点设置里把权限重置。

再看系统默认输入设备对不对。Windows 右下角小喇叭右键进声音设置,macOS 在系统设置的声音里,确认当前用的麦克风是被选中的那个。

接着看物理静音开关。有的耳机麦上有个硬开关,或者笔记本有 Fn 组合键静音,硬件层关了再怎么调软件都没用。

最后看是不是被别的程序独占。某些会议软件开着会的时候,会把麦克风占住,其他程序拿不到。关掉那软件再测。

音量小但不是没声,多半是输入增益(灵敏度)调低了,系统设置里拉高一点,或者人离麦近一点。波形里有持续底噪,多半是麦克风本身或环境问题,换设备或开降噪。

摄像头:拿到视频流,绑到 video 元素

摄像头的套路跟麦克风几乎一样,只是参数换成 getUserMedia({ video: true })。返回的视频流直接赋给一个 <video> 元素的 srcObject,浏览器就会把画面渲染出来。从流的 track 上能读到实际分辨率(width × height)和帧率(frameRate),不用自己估算。

摄像头测试 的核心就这些。打开授权,看画面、读规格,必要时把当前帧画到 Canvas 上导出 PNG 当截图。

要切换前后置摄像头,先调 navigator.mediaDevices.enumerateDevices() 列出所有摄像头,每个带一个 deviceId,再请求时把这个 id 传进去就行。手机上更简单,请求时加 facingMode: 'user'(前置)或 facingMode: 'environment'(后置)。

摄像头打不开,原因就那几类:

权限被拒。同麦克风,看站点权限设置,曾被永久拒绝的不会重弹。

被其他程序独占。这个最常见。腾讯会议、Zoom、OBS 开着的时候占着摄像头,浏览器再请求就失败,错误信息一般是 NotReadableError。关掉那些软件再试。

不是 HTTPS 环境。getUserMedia 出于安全只在学校 localhost 和 HTTPS 网站上工作,HTTP 站点直接禁用。本地 file 打开的网页也不行。

画面卡、帧率低。光线不足时摄像头会自适应降低帧率延长曝光来换取亮度,所以晚上不开灯画面会卡。补光比换摄像头管用。分辨率比标称值低也是同理,光线够的时候它才跑满。

三类检测,一个共同点

回头看:键盘靠 KeyboardEventkeydown/keyup,麦克风和摄像头都靠 getUserMedia 拿流,音频再走 Web Audio API 算音量。三类硬件各有各的入口,但都不需要装任何软件,打开网址就能测。

更关键的一点是,这些检测全程在浏览器本地跑。你按了哪些键、说了什么话、长什么样子,都不会上传到任何服务器。比起那些要装 exe 还要注册账号的「检测软件」,这个差别不是一点半点。出问题的时候优先怀疑权限、设备、占用、HTTPS 这几个常规项,硬件本身的故障其实排到最后。

相关文章