摘要:网页把GainNode设为零并不等于释放音频设备。本文从Web Audio实时图、浏览器音频会话、设备指纹与蓝牙Multipoint仲裁解释“听不见却占线”的机制、证据边界和复现实验。
你在手机上听歌,同时让支持 multipoint(多点连接)的耳机连着电脑。打开某购物网站后,手机音乐突然停了;关闭网页,又立刻恢复。标签页没有视频,扬声器图标也没亮,甚至把标签页、浏览器或 Windows 静音都无效——这并不一定是蓝牙坏了,而可能是网页启动了一条**听不见、却仍在运行的音频链路**。
2026 年 8 月,Laserphile 对 AliExpress 首页的一次调查记录了这个现象。作者注入代码监视 AudioContext 构造和 AudioNode.connect(),发现两个混淆过的安全脚本在页面闲置数秒后创建实时 Web Audio 图:
1 | 锯齿波 Oscillator |
“没有声音”不等于“没有播放链路”
AudioContext 是 Web Audio API 的实时处理容器,内部由振荡器、滤波器、分析器、增益等节点组成。节点接到 destination 后,浏览器通常会按声卡时钟持续拉取、计算音频块。把末端 GainNode 设为 0,只会把样本乘成零,并不等于调用 suspend()、disconnect() 或 close();MDN 也明确说明,suspend() 会暂停时间推进和音频硬件访问,close() 则释放其系统音频资源。
这解释了为什么“静音”可能无效:标签页或系统音量静音往往发生在更下游,只改变最终混音结果,不必然撤销浏览器已经建立的输出流。标签页不显示扬声器图标也不能反证“没有音频活动”:浏览器可能依据最终是否产生可听样本来显示图标,而操作系统关心的是应用是否仍持有并向输出端提交音频缓冲。两者观察的是不同层级。
至于零样本是否仍会让蓝牙链路保持活跃,取决于浏览器、操作系统音频栈、驱动和耳机固件,不能由 Web Audio 规范单独推出。原调查证明的是其特定 Firefox/Chrome、Windows 和耳机组合上的可重复关联,不是所有设备必现的通则。
它为什么像指纹,而不是播放器?
调查中的脚本没有 <audio>、<video>、play() 或 Media Session;它生成已知波形,再读取分析结果。相同信号经过不同浏览器版本、数学实现和 CPU 指令路径后,输出可能有细小差异,哈希后可成为一个“半标识符”,再与 Canvas、WebGL、屏幕尺寸、硬件并发数、性能时序和交互数据组合,用于反欺诈、机器人识别,也可能用于跟踪。
但用途与效果要分开说。客户端代码能证明它采集并上报了多类指纹式特征,却不能证明服务端如何留存、是否跨站关联。Firefox 开发者 Tom Ritter 的后续测试还指出:Firefox 118 起已把多数 Web Audio 差异归一化;其遥测样本中 99.24% 用户只落入三个主要结果,剩余差异主要与 CPU 的 FMA/NEON 路径有关。因此,这段检测“在做 Web Audio 特征采集”较有依据,“足以唯一识别某台设备”则并不成立。Brave 采用的另一思路是对 Canvas 与 Web Audio 输出做按站点、按会话的轻微随机化(farbling)。
蓝牙多点为何会被“占线”
Multipoint 的核心是耳机同时维持两个源设备连接,但多数产品并不能同时播放两路媒体;耳机必须按厂商规则选择当前 A2DP 媒体源,并通常让来电等 HFP 事件获得更高优先级。不同产品依据“是否有活动媒体流”、播放控制状态、超时或私有策略切换,标准和实现并不统一。
于是可能出现这样的副作用:电脑端浏览器持续保有实时输出会话,操作系统继续把电脑视作活动音频源;耳机也迟迟不把媒体通道让给手机。这里最关键的表述是“可能”:网页并没有直接控制耳机,更没有调用所谓“蓝牙抢占 API”,而是通过浏览器音频输出,间接触发了整条链路的仲裁行为。
可复现实验思路
准备一副支持 multipoint 的耳机,连接电脑和手机,先确认电脑无声时手机能正常播放。随后在本地测试页中,由一次按钮点击创建四组对照:
- 只创建
AudioContext,不接destination; Oscillator → Gain(0) → destination,保持state === "running";- 对第 2 组调用
suspend(); - 再调用
close(),或断开节点。
每组记录手机是否中断、恢复耗时、浏览器状态,以及系统音量混音器/浏览器媒体诊断页是否出现活动会话;再交叉测试有线输出、另一浏览器和另一副耳机。另加 OfflineAudioContext 对照:它渲染到内存缓冲区,不需要实时扬声器目的地,更适合一次性指纹测量。实验不要用“网页能否听见”代替“系统是否保持音频会话”,也不要把单一硬件结果外推到所有平台。
用户、网站与浏览器可以做什么
- 用户侧:关闭可疑标签页;按站点限制自动播放;使用可信内容拦截器阻止已确认的脚本;必要时在耳机应用中手动指定音源。拦截反欺诈脚本可能增加验证码,甚至影响登录或支付。
- 网站侧:一次性特征计算优先使用
OfflineAudioContext;实时上下文用完立即suspend()/close();页面隐藏或任务结束时释放资源;不要仅靠零增益“假装停止”。 - 浏览器侧:把“占用输出设备”与“可听见声音”分别可视化;对长时间零输出的后台上下文尝试释放硬件、改用空输出,同时保持必要的图时钟;进一步归一化或随机化可指纹化结果;在不破坏网页乐器、会议、游戏和无障碍应用的前提下,收紧无用户意图的实时音频激活。
优化并不简单:Web Audio 图可能有自动化参数、反馈连接或 AudioWorklet 副作用,浏览器不能看到增益为零就武断停算。但至少,这次案例揭示了一个产品边界:“静音”是声学结果,“不占用音频设备”才是资源状态。浏览器若只展示前者,用户就看不见后者造成的真实硬件副作用。
参考资料
- Laserphile, AliExpress webpage keeping multipoint Bluetooth headphones active with WebAudio fingerprinting, 2026-08。
- Tom Ritter, WebAudio fingerprinting on Alibaba, 2026-08-20。
- MDN, AudioContext 与 BaseAudioContext.state。
- Chrome for Developers, Autoplay policy in Chrome(Web Audio 自 Chrome 71 起纳入自动播放策略)。
- Brave, Fingerprinting defenses 2.0。
- SoundGuys, What is Bluetooth multipoint?。