返回知识中心
平台

Web MIDI API:权限与设备隐私

围绕用户激活、权限、端口变化、受限消息、最小元数据和可靠回退设计 Web MIDI。

BotBrowser Team

文档中心

想直接进入 平台 文档吗?

这篇文章属于知识中心的指南库。若你要步骤化配置、参考说明和持续更新,请直接进入对应 docs 分区。

当受控浏览器暴露 navigator.requestMIDIAccess() 并由明确操作发起请求时,BotBrowser 可用于测试经过授权的 Web MIDI 流程。它不能制造物理乐器、替用户选择端口、绕过浏览器授予权限,也不能把端口名称变成所有权证明。可靠的契约是可见工作流:请求、显示结果、校验每条消息、协调端口变化,并在浏览器或硬件不可用时保留无 MIDI 路径。

用户操作请求 MIDI 访问,端口变化和受限 MIDI 消息进入安全回退

TL;DR

获得浏览器权限后,Web MIDI 可以访问输入和输出端口,但不会提供无限制的硬件清单或稳定的乐器身份。检测 navigator.requestMIDIAccess,从明确控件调用,只请求必要能力,把 MIDIAccess 当作会变化的实时视图。监听 statechange,校验 MIDIMessageEvent.data,端口消失时释放监听器。

W3C Web MIDI 规范定义了 MIDIAccess、输入输出端口、状态变化、消息事件和可选的 System Exclusive。MDN指出支持范围有限。BotBrowser 可以记录浏览器可见的权限和端口状态,但不能证明物理乐器存在、属于某人或产生了声音。

内容导航

权限是能力边界

navigator.requestMIDIAccess() 请求的是浏览器管理的能力,而不是打开所有 USB 设备。安全上下文、用户激活、权限和平台支持都可能成为条件。Promise 返回 MIDIAccess 只表示浏览器暴露了能力表面,不表示存在连接端口或某人已获授权。

请求最小范围。普通音符和控制消息可使用 { sysex: false }。System Exclusive 可能包含厂商命令和较大的不透明序列,需要单独的产品决定和说明。不要因为库支持 sysex: true 就自动开启。Web USB:设备访问与隐私边界体现同一原则:权限不是设备清单。

端口名称、厂商和版本可用于当前会话的选择器,却不是所有权证明或稳定身份。只在任务需要时保存 granted、denied、unsupported 或 no-port,不要把这些结果与网络、屏幕和 profile 组合成长久标签。

从用户操作请求访问

在使用时检测能力。没有 API 时可以禁用“连接 MIDI”按钮;用户点击或按键后再请求,不要在加载、定时器或后台网络回调中自动弹出选择器。

async function connectMidi() {
  if (!window.isSecureContext || !navigator.requestMIDIAccess) {
    return showMidiState('unsupported');
  }
  setMidiState('requesting');
  try {
    const access = await navigator.requestMIDIAccess({ sysex: false });
    attachMidiAccess(access);
    renderPorts(access);
  } catch (error) {
    setMidiState(classifyMidiError(error));
    showMidiFallback();
  }
}
connectButton.addEventListener('click', connectMidi);

requesting 可以防止重复选择并提供可访问状态。失败时只记录页面能知道的 NotAllowedError、不支持或本地超时,不要说某个命名设备拒绝了访问。恢复控件,提供新的可见重试。Web Bluetooth:权限与设备隐私展示了相似选择器,但同样应区分 API 存在、浏览器授予访问和当前有可用设备。

把端口视为变化中的会话

MIDIAccess.inputs 和 MIDIAccess.outputs 是当前暴露端口的 map。设备插入、移除或重配置时会触发 statechange;每次事件都重新绘制完整 map,不要把旧行追加到新列表。

function attachMidiAccess(access) {
  access.onstatechange = event => {
    const port = event.port;
    renderPorts(access);
    if (port.state === 'disconnected') detachInput(port.id);
    if (port.state === 'connected' && port.type === 'input') attachInput(port);
  };
  for (const input of access.inputs.values()) attachInput(input);
  for (const output of access.outputs.values()) renderOutput(output);
}

使用前检查 port.state 和 port.connection,捕获发送失败。输入断开时删除监听器并清除关联状态。port.id 只应作为短期会话键,不能写进长期 profile 或指纹。send() 也不能证明乐器产生了声音或其他应用收到了消息。输出端口必须由用户明确选择,不要因为名称相似而静默切换。

在消息进入应用状态前限制它

MIDIMessageEvent.data 是不可信字节序列。更新状态前校验长度、状态字节、通道和数据范围。应用允许的白名单可以小于完整 MIDI 协议。

const MAX_MIDI_BYTES = 3;
const allowedStatus = new Set([0x80, 0x90, 0xb0, 0xe0]);
function acceptMidiMessage(event) {
  const bytes = [...event.data];
  if (bytes.length < 2 || bytes.length > MAX_MIDI_BYTES) return;
  const status = bytes[0] & 0xf0;
  if (!allowedStatus.has(status) || bytes.slice(1).some(byte => byte > 0x7f)) return;
  updateMusicState({ status, channel: bytes[0] & 0x0f, data: bytes.slice(1) });
}

示例故意忽略 System Exclusive、realtime 和系统消息。启用它们应是有大小限制和厂商文档的独立协议变更。不要默认记录全部字节,也不要把字节序列当作设备身份。对高频事件限流,只在用户明确开启诊断时保留短时原始捕获。

最小化元数据并保留回退

虚拟键盘、文件导入、快捷键或乐谱视图可以在没有 MIDI 时保留任务。页面应说明浏览器没有暴露可用端口,不要假装正在控制乐器。把音乐模型与 MIDI 适配器分开:断开后仍可编辑,新端口出现后要求明确选择。

短记录可以包含支持结果、权限、端口类型和状态、本地标签、接收消息计数及时间。无需保存完整厂商字符串、端口清单、原始字节或无关浏览器属性。端口名可能暴露设备型号或工作室环境,应定义用途和保存期限。

使用决策表

观察结果安全动作不应声称
API 缺失或上下文不安全保留虚拟键盘或文件路径浏览器普遍支持
权限被拒绝解释并保留任务某个命名设备拒绝
已授权但无端口显示设置提示和回退不存在物理乐器
输入端口连接安装校验监听器端口属于某人
输出端口连接发送前要求明确选择已产生或听到声音
statechange 断开删除监听器并标记离线一定会自动回来
MIDI 字节无效丢弃并分类发送者身份已知
请求 SysEx要求单独决定默认数据无害

用 BotBrowser 测试可见行为

BotBrowser 受控上下文可以运行确定性连接按钮、合成回退、受限校验器和可见端口记录。记录 API 是否存在、权限结果、端口数量、statechange 事件和回退可见性。unsupported、permission-denied、no-port 都是有效结果,只要不声称播放了声音。BotBrowser 高级功能文档不保证 runner 上有 MIDI 设备。

{
  "api": "requestMIDIAccess",
  "permission": "unknown",
  "ports": { "inputs": 0, "outputs": 0 },
  "states": ["fallback"],
  "messagesAccepted": 0,
  "rawBytesRetained": false,
  "physicalInstrument": "not-asserted"
}

每次只改变一个变量重复 fixture:浏览器版本、安全上下文、权限结果、端口连接或消息类型。比较第一次可见差异,不要将单次结果扩大成所有系统和驱动的承诺。

结论

Web MIDI 是受权限控制且会变化的浏览器能力。从可见操作发起,使用最小范围,显示实时端口 map,校验每条消息,断开时释放监听器。BotBrowser 可以在授权受控上下文中重放这些可见分支;它不能制造乐器、绕过权限、保证端口或从 MIDI 元数据推断所有权。

公开来源

延伸阅读

阅读 Web Bluetooth:权限与设备隐私 和 Web USB:设备访问与隐私边界。

#Web MIDI API#权限#设备隐私#浏览器硬件#BotBrowser

本文属于指南: Web 平台能力面:一致性复核地图

让 BotBrowser 从研究走向生产

先用这些指南理解模型,再进入跨平台验证、隔离上下文和面向规模化的浏览器部署。