Copyright © 2015-2025 World Wide Web Consortium. W3C® liability, trademark and permissive document license rules apply.
某些用户代理有音乐设备,例如合成器、键盘和 其他控制器,以及连接到其宿主计算机或设备的鼓机。 广泛采用的乐器数字接口(MIDI)协议使电子乐器、 控制器和计算机能够相互通信并同步。MIDI 不传输 音频信号:相反,它发送关于音符的事件消息、 用于音量、颤音和声像等参数的控制器信号、 用于设置速度的提示和时钟信号,以及系统特定的 MIDI 通信(例如远程存储合成器特定的音色数据)。 同一协议也已成为非音乐用途的标准,例如演出控制、 灯光和特效控制。
本规范定义了一个支持 MIDI 协议的 API,使 Web 应用程序 能够枚举并选择客户端系统上的 MIDI 输入和输出设备,并发送和接收 MIDI 消息。它旨在 通过提供对用户系统上可用的 MIDI 设备的低级访问, 同时支持非音乐 MIDI 应用和音乐 MIDI 应用。Web MIDI API 并非旨在 从语义上描述音乐或控制器输入;它被设计为暴露 MIDI 输入和输出接口的机制, 以及发送和接收 MIDI 消息的实际方面,而不标识这些 操作在语义上可能意味着什么(例如,根据“以 20Hz 调制颤音” 或“演奏一个 G#7 和弦”来理解,除了根据改变一个 控制器值或发送一组恰好表示 G#7 和弦的 note-on 消息来理解之外)。
对某些用户来说,“MIDI”已经成为标准 MIDI 文件
和 General MIDI 的同义词。这并不是此 API 的意图;仅仅播放
.SMF 文件的用例不在本规范的范围内(例如,它可以被视为一种
由 HTML
audio
元素支持的不同格式)。Web MIDI API
旨在支持对响应 MIDI 的设备的直接访问 -
例如控制器、外部合成器或照明系统。
Web MIDI API 也明确设计用于支持 Web 上一类新的
应用程序,这类应用程序可以响应 MIDI 控制器输入 -
使用带有物理按钮、旋钮和滑块的外部硬件控制器
(以及键盘、吉他或管乐器控制器等音乐控制器)
来控制 Web 应用程序。
Web MIDI API 还预期与 Web 平台的其他 API 和元素结合使用, 尤其是 Web Audio API。此 API 还旨在让 其他系统上的 MIDI API 用户感到熟悉,例如 Apple 的 CoreMIDI 和 Microsoft 的 Windows MIDI API。
本节描述本文档在发布时的状态。当前 W3C 发布物列表以及本技术报告的最新修订版,可以在 W3C 技术 报告索引中找到,地址为 https://www.w3.org/TR/。
本文档由 Audio Working Group 作为 Working Draft 发布,并使用 Recommendation track。
作为 Working Draft 发布并不 意味着 W3C 及其成员的认可。
这是一份草案文档,可能随时被其他文档更新、替换或废弃。 除作为进行中的工作外,不适合引用本文档。
本文档由一个根据 W3C 专利 政策 运作的团体制作。 W3C 维护一个 与该团体交付物相关的任何专利披露公开列表; 该页面还包含披露专利的说明。任何实际知晓某项专利, 且该个人认为该专利包含 基本权利要求 的个人,必须依照 W3C 专利政策第 6 节 披露该信息。
本文档受 2023 年 11 月 03 日 W3C 流程文档管辖。
本节是非规范性的。
Web MIDI API 规范为 Web 开发者定义了一种方式,用于 枚举、操作和访问 MIDI 设备 - 例如, 可能提供硬件 MIDI 端口的接口,其他设备插入这些端口, 以及支持 USB-MIDI 规范的 USB 设备。有了用于 MIDI 的 Web API, Web 应用程序就可以使用现有的软件和硬件合成器、 硬件音乐控制器、灯光系统以及其他由 MIDI 控制的机械装置。 定义此 API 时已考虑到这种广泛的用例。
此 API 采用的方法类似于 Apple 的 CoreMIDI API 和 Microsoft 的 Windows MIDI API;也就是说,该 API 被设计为表示 MIDI 的低级软件协议,以使开发者能够在其之上 构建强大的 MIDI 软件。该 API 使开发者能够枚举输入和输出接口, 并发送和接收 MIDI 消息,但(类似于上述 API) 除了为了稳健支持当前设备所必需的内容之外, 它并不试图从语义上定义或解释 MIDI 消息。
Web MIDI API 并不旨在直接实现排序等高级概念; 例如,它不直接支持标准 MIDI 文件,尽管可以在 Web MIDI API 之上构建标准 MIDI 文件播放器。它也不旨在像 General MIDI 那样 从语义上捕获音色或控制器分配;这种解释超出了 Web MIDI API 的范围(不过同样,General MIDI 可以很容易地通过 Web MIDI API 使用)。
除标记为非规范性的章节外,本规范中的所有编写指南、图表、示例和注释均为非规范性的。 本规范中的其他所有内容均为规范性的。
本文档中的关键词 MUST 和 SHOULD 应按 BCP 14 [RFC2119] [RFC8174] 中的描述解释,且仅当它们如这里所示以全大写形式出现时才如此解释。
本规范定义了适用于单一产品的一致性标准:即实现其中所含接口的 用户代理。
使用 ECMAScript 来实现本规范所定义 API 的实现,MUST 以与 Web IDL 规范 [WEBIDL] 中定义的 ECMAScript 绑定一致的方式实现这些 API,因为 本规范使用了该规范及其术语。
Web Audio API 及其相关接口和概念在 [webaudio] 中定义。
术语 MIDI、MIDI 设备、MIDI 输入 端口、MIDI 输出端口、MIDI 接口、 MIDI 消息、System Real Time 和 System Exclusive 在 [MIDI] 中定义。
8、9、
A、B 或 E,则消息总长度应为 3
字节
C 或 D,则
消息总长度应为 2 字节F1 或 F3,则消息总
长度应为 2 字节F2,则消息总长度
应为 3 字节F6、F8、FA、FB、
FC、FE
或 FF,则消息总长度应为 1 字节(仅
状态字节)
F0,则这是一个没有长度限制的
System
Exclusive 消息,且最后一个
字节应为 F7
F4、F5、F7、F9 或
FD,则
该消息无效
Web Midi API 是一个由 强大功能, 其 名称为 "midi"。它 通过定义以下与权限相关的标志,与 Permissions 集成:
WebIDLdictionary MidiPermissionDescriptor : PermissionDescriptor {
boolean sysex = false;
};
{name: "midi", sysex: true} 强于 {name:
"midi", sysex: false}。
WebIDL[SecureContext, Exposed=(Window,Worker)] interface MIDIInputMap {
readonly maplike <DOMString, MIDIInput>;
};
MIDIInputMap 是一个 maplike 接口,其值为
MIDIInput 实例,键为其 ID。
此类型用于表示所有当前可用的 MIDI 输入 端口。
WebIDL[SecureContext, Exposed=(Window,Worker)] interface MIDIOutputMap {
readonly maplike <DOMString, MIDIOutput>;
};
MIDIOutputMap 是一个 maplike 接口,其值为
MIDIOutput 实例,键为其 ID。
此类型用于表示所有当前可用的 MIDI 输出 端口。
此接口提供用于列出 MIDI 输入和输出设备,并获取对单个设备的访问权限的方法。
WebIDL[SecureContext, Exposed=(Window,Worker), Transferable] interface MIDIAccess: EventTarget {
readonly attribute MIDIInputMap inputs;
readonly attribute MIDIOutputMap outputs;
attribute EventHandler onstatechange;
readonly attribute boolean sysexEnabled;
};
inputs
outputs
onstatechange
当新端口连接,或现有端口更改 state 属性时调用的处理程序。
此 事件
处理程序,类型为 MIDIConnectionEvent,MUST 由所有实现
MIDIAccess
接口的对象支持。
必须理解,将 EventHandler
留在此对象上会阻止该对象被垃圾回收;当使用完
MIDIAccess 后,应移除任何
onstatechange 监听器。
每当先前不可用的 MIDI 端口变为可用,或现有端口更改 state 属性时,用户代理 SHOULD 运行以下步骤:
MIDIPort。
MIDIAccess 上
触发一个
名为 "statechange" 的事件,
使用 MIDIConnectionEvent,并将
port 设置为 port。
sysexEnabled
此接口表示 MIDI 输入或输出端口。
WebIDL[SecureContext, Exposed=(Window,Worker)] interface MIDIPort: EventTarget {
readonly attribute DOMString id;
readonly attribute DOMString? manufacturer;
readonly attribute DOMString? name;
readonly attribute MIDIPortType type;
readonly attribute DOMString? version;
readonly attribute MIDIPortDeviceState state;
readonly attribute MIDIPortConnectionState connection;
attribute EventHandler onstatechange;
Promise <MIDIPort> open();
Promise <MIDIPort> close();
};
id
端口的唯一 ID。开发者可用它记住用户为其应用程序选择的端口。
用户代理 MUST 确保
id 仅对该端口唯一。
用户代理 SHOULD 确保该 id 在应用程序的多个实例之间保持不变 -
例如,当系统重新启动时 - 以及当设备从系统中移除时保持不变。
应用程序可能希望在本地缓存这些 id,以重新创建 MIDI 设置。
某些系统可能不支持完全唯一的持久标识符;在这种情况下,当另一个接口
被添加到系统或从系统移除时,维护标识符会更具挑战性。
(这可能会打乱所请求端口的索引。)预期系统会尽其所能,
在 MIDI API 的多个实例之间匹配端口:例如,实现可以不透明地
使用端口接口制造商、名称和索引的某种哈希作为 id,
这样对该端口 id 的引用在插入时很可能匹配该端口。
应用程序可以使用 MIDIPort 的 id 比较来测试相等性。
manufacturer
端口的制造商。
name
端口的系统名称。
type
用于区分端口是输入端口还是输出端口的描述符属性。对于
MIDIOutput,此属性
MUST 为
"output"。对于 MIDIInput,此属性
MUST 为
"input"。
version
端口的版本。
state
connection
onstatechange
当现有端口更改其 state 或 connection 属性时调用的处理程序。
此 事件
处理程序,类型为 "statechange",MUST 由所有实现
MIDIPort 接口的对象支持。
必须理解,将 EventHandler
留在此对象上会阻止该对象被垃圾回收;当使用完
MIDIPort 后,应移除任何
onstatechange 监听器。
open
使与 MIDIPort
相对应的 MIDI 设备显式可用。请注意,为了使用
MIDIPort,并不要求调用此方法 -
在 MIDIOutput 上调用 send(),
在 MIDIInput 上附加 MIDIMessageEvent
EventHandler,
或在
MIDIInput 上添加 MIDIMessageEvent
EventListener
都会导致隐式 open()。底层实现可能无需响应此调用执行任何操作。
然而,某些底层实现可能无法支持对 MIDI 设备的共享访问,
因此使用显式 open() 和 close() 调用将使 MIDI 应用程序能够
可预测地控制对设备的这种独占访问。
调用时,此方法返回一个 Promise 对象,表示对用户系统上给定 MIDI 端口 访问权限的请求。
如果端口设备的状态为 "connected",当已获得对该端口的访问权限 (并且该端口已准备好进行输入或输出)时,所给出的 Promise 会被解决。
如果无法访问已连接的端口(例如,该端口已在仅允许独占访问的平台中被使用), 则 Promise 会被拒绝(如果有)。
如果在 "disconnected" 的端口上调用
open(),该端口的
.connection 将转换为
"pending",
直到该端口变为
"connected",或对它的所有引用都被丢弃。
即使并非所有给出的 Promise 都已敲定,也允许多次调用
open()。
当调用此方法时,用户代理 MUST 运行 打开 MIDIPort 的算法:
令 promise 为一个新的 Promise 对象,并令 resolver 为其关联的 resolver。
返回 promise,并异步运行以下步骤。
令 port 为给定的
MIDIPort 对象。
如果设备的 connection 已经是
"open"(例如,已在此
MIDIPort 上调用 open(),
或端口已被隐式打开),则跳转到下面标记为
success 的步骤。
如果设备的 connection 为 "pending"(即连接已被打开, 而设备随后断开连接),则跳转到下面标记为 success 的步骤。
如果设备的 state 为
"disconnected",则将
connection 属性更改为
"pending",并将一个新的
MIDIConnectionEvent 加入
MIDIAccess 的
statechange 处理程序队列,以及
MIDIPort 的
statechange 处理程序队列,
然后跳转到下面标记为 success
的步骤。
尝试在系统中获取对给定 MIDI 设备的访问权限。如果设备不可用(例如已被另一个进程使用且无法打开, 或已断开连接),则跳转到下面标记为 failure 的步骤。 如果设备可用且已获得访问权限,则继续以下步骤。
将 MIDIPort 的 connection 属性更改为 "open",
并将一个新的
MIDIConnectionEvent 加入
MIDIAccess 的
statechange 处理程序队列,以及
MIDIPort 的
statechange 处理程序队列。
如果此端口是输出端口,并且存在任何带有未来时间戳的已排队发送数据, 则异步开始发送这些数据。
success:调用 resolver 的
accept(value) 方法,并以 port 作为
value 实参。
终止这些步骤。
failure:令 error 为一个新的
DOMException。
如果端口不可用,则此异常的 .name 应为
"InvalidAccessError"。
调用 resolver 的 reject(value) 方法,
并以 error 作为 value 实参。
close
使与 MIDIPort
相对应的 MIDI 设备显式不可用(随后将状态从
"open" 更改为 "closed")。请注意,成功调用此方法将导致
MIDI 消息不再被传递给
MIDIInput 上的 MIDIMessageEvent 处理程序
(尽管设置新的处理程序会导致隐式 open())。
底层实现可能无需响应此调用执行任何操作。然而,某些底层实现 可能无法支持对 MIDI 设备的共享访问,而显式 close() 调用使 MIDI 应用程序能够确保 其他应用程序可以获得对设备的访问权限。
调用时,此方法返回一个 Promise 对象,表示对用户系统上给定 MIDI 端口 访问权限的请求。当端口已关闭(因此,在独占访问系统中,该端口可供 其他应用程序使用)时,所给出的 Promise 会被解决。如果端口断开连接, 则 Promise 会被拒绝。
即使并非所有给出的 Promise 都已敲定,也允许多次调用
close()。
当调用 close() 方法时,用户代理
MUST 运行以下步骤:
令 promise 为一个新的 Promise 对象,并令 resolver 为其关联的 resolver。
返回 promise,并异步运行以下步骤。
令 port 为给定的
MIDIPort 对象。
如果端口已关闭(其
.connection 为
"closed" - 例如,端口尚未被
隐式或显式打开,或已在此
MIDIPort 上调用
close()),
则跳转到下面标记为
closed 的步骤。
如果端口是输入端口,则跳到下一步。如果输出端口的 .state 不是 "connected", 或其 .connection 为 "pending",则清除所有已排队发送数据,并跳到下一步。 清除系统中任何带有未来时间戳的已排队发送数据,然后在继续下一步之前, 完成发送任何没有时间戳或时间戳位于过去或现在的发送消息。
如果底层系统中对端口的访问已打开,则关闭该访问,并释放底层系统中的 任何阻塞资源。
将 MIDIPort 的 connection 属性更改为 "closed",
并将一个新的
MIDIConnectionEvent 加入
MIDIAccess 的
statechange 处理程序队列,以及
MIDIPort 的
statechange 处理程序队列。
closed:调用 resolver 的
accept(value) 方法,并以 port 作为
value 实参。
每当与 MIDIPort
相对应的 MIDI 端口更改 state 属性时,用户代理
SHOULD 运行以下步骤:
令 port 为该
MIDIPort。
在 MIDIPort 上
触发一个事件,
其名称为 statechange,并在
MIDIAccess 上触发
statechange,
使用 MIDIConnectionEvent,并将
port 属性设置为
port。
WebIDL[SecureContext, Exposed=(Window,Worker)] interface MIDIInput: MIDIPort {
attribute EventHandler onmidimessage;
};
onmidimessage
此 事件
处理程序,类型为 "midimessage",MUST 由所有实现
MIDIInput 接口的对象支持。
如果设置了处理程序且 state 属性不是 "opened",
底层实现会尝试使该端口可用,并将 state 属性更改为
"opened"。如果成功,则会将
MIDIConnectionEvent
传递给相应的 MIDIPort 和
MIDIAccess。
每当与 MIDIInput 相对应的 MIDI 端口完成接收一个或多个
MIDI 消息时,用户代理
MUST 运行以下步骤:
令 port 为该
MIDIInput。
如果 MIDIAccess
未启用 System Exclusive
访问权限,且该消息是
System Exclusive 消息,则中止此过程。
在 port 上
触发一个
名为 "midimessage" 的事件,使用
MIDIMessageEvent,并将
timeStamp
属性设置为系统接收到该消息的时间,并将
data 属性设置为
一个表示单个 MIDI
消息的 MIDI 数据字节
Uint8Array。
特别指出,MIDI System Real Time 消息实际上可能 出现在输入流中其他消息的中间;在这种情况下, System Real Time 消息会在其出现时被派发, 而普通消息会被缓冲,直到它们完整(然后再派发)。
WebIDL[SecureContext, Exposed=(Window,Worker)] interface MIDIOutput : MIDIPort {
undefined send(sequence<octet> data, optional DOMHighResTimeStamp timestamp = 0);
undefined clear();
};
send
将要发送到相应 MIDI 端口的消息入队。底层实现将(如有必要)
将序列的每个成员强制转换为无符号 8 位整数。使用 sequence
而不是 Uint8Array,使开发者能够利用
output.send( [ 0x90, 0x45, 0x7f ]
); 的便利,而不必创建 Uint8Array,例如
output.send( new Uint8Array( [ 0x90, 0x45, 0x7f ] )
);
数据包含一个或多个完整的 有效 MIDI 消息。 数据中不允许使用 running status,因为底层系统可能不支持它。
如果 data 不是有效序列,或不包含
有效 MIDI 消息,则抛出
TypeError 异常。
如果 data 是
System Exclusive 消息,
且
MIDIAccess 未启用
System Exclusive 访问权限,则抛出
InvalidAccessError 异常。
如果端口为 "disconnected",则抛出
InvalidStateError 异常。
如果端口为 "connected",但 connection 为 "closed",则异步尝试 打开端口。
DOMHighResTimeStamp
- 相对于文档导航开始测量的毫秒数)。如果
timestamp 被设置为零(或过去的另一个时间),则应尽快发送数据。
多次以相同 timestamp 调用 send() 必须导致数据按调用顺序发送。
clear
清除 MIDIOutput 队列中任何尚未发送的
已排队发送数据。实现需要确保 MIDI 流保持良好状态,因此如果输出端口
正处于 sysex 消息中间,则应发送 sysex 终止字节(0xf7)。
WebIDLenum MIDIPortType {
"input",
"output",
};
input
MIDIPort 是输入端口,则 type 成员
MUST 为此值。
output
MIDIPort 是输出端口,则 type 成员
MUST 为此值。
WebIDLenum MIDIPortDeviceState {
"disconnected",
"connected",
};
disconnected
MIDIPort 所表示的设备
已从系统断开连接。当设备从系统断开连接时,它不应出现在相关的输入和输出端口映射中。
connected
MIDIPort 所表示的设备
已连接,并应出现在输入和输出端口映射中。
WebIDLenum MIDIPortConnectionState {
"open",
"closed",
"pending",
};
open
MIDIPort 所表示的设备
已被打开(无论是
隐式还是显式),并且可供使用。
closed
MIDIPort 所表示的设备
未被打开,或已被显式关闭。在
MIDIPort 被显式打开
(通过 MIDIPort.open())或隐式打开
(通过在输入端口上添加
midimessage
事件处理程序,或在输出端口上调用
MIDIOutput.send())之前,
这应为设备的默认状态。
pending
MIDIPort 所表示的设备
已被打开(无论是
隐式还是
显式),但设备随后已断开连接且不可用。如果设备重新连接,
在发送 statechange
事件之前,系统应尝试重新打开设备(遵循
打开 MIDIPort 的算法);这将导致
connection 状态转换为 "open" 或 "closed"。
当收到 MIDI 消息时,实现此接口的事件对象会被传递给
MIDIInput 的 onmidimessage 处理程序。
请注意,DOM Event 的
timeStamp 属性被定义为
DOMHighResTimeStamp,
并表示事件被接收或将被发送时的高精度时间。
WebIDL[SecureContext, Exposed=(Window,Worker)]
interface MIDIMessageEvent : Event {
constructor(DOMString type, optional MIDIMessageEventInit eventInitDict = {});
readonly attribute Uint8Array? data;
};
data
一个包含单个 MIDI 消息的 MIDI 数据字节的 Uint8Array。
WebIDLdictionary MIDIMessageEventInit: EventInit {
Uint8Array data;
};
data
一个包含单个 MIDI 消息的 MIDI 数据字节的 Uint8Array。
当新端口变为可用(例如,当
MIDI 设备首次插入计算机时),
当先前可用的端口变为不可用,或再次变为可用(例如,当
MIDI 接口
断开连接后又重新连接时),实现此接口的事件对象会被传递给
MIDIAccess 的
onstatechange
处理程序,
并且(如果存在)也会被传递给任何引用该端口的
MIDIPort 的
onstatechange 处理程序。
当 MIDIPort 处于
"pending" 状态且设备重新连接到宿主系统时,
在触发 statechange 事件之前,会在其上运行
打开 MIDIPort 的算法,以尝试重新打开端口。如果此转换失败
(例如,端口被底层系统中的其他事物保留,因此不可用),connection
状态会变为 "closed",否则会转换回 "open"。这是在设备 state 变化的
statechange
事件之前完成的,以便该事件既反映最终的 connection 状态,也反映设备 state。
某些底层系统可能不提供设备连接状态的通知事件;这类系统可能因不频繁轮询 新设备而出现较长延迟。因此,建议不要过度依赖连接事件。
WebIDL[SecureContext, Exposed=(Window,Worker)]
interface MIDIConnectionEvent : Event {
constructor(DOMString type, optional MIDIConnectionEventInit eventInitDict = {});
readonly attribute MIDIPort? port;
};
port
已连接或断开连接的端口。
WebIDLdictionary MIDIConnectionEventInit: EventInit {
MIDIPort port;
};
port
已连接或断开连接的端口。
允许枚举用户的 MIDI 接口 是指纹识别的潜在目标;也就是说,通过用户连接的特定 MIDI 接口来唯一 标识用户。
注意,在此上下文中,可枚举的是 MIDI 接口。这包括大多数通过 USB 连接到 宿主计算机的设备,因为 USB-MIDI 设备 通常拥有自己的 MIDI 接口,因此会被枚举。通过 5 针 DIN 线缆插入 MIDI 接口的单个采样器或合成器 MIDI 设备不会被枚举。 可被指纹识别的接口等同于 MIDI “端口”,并且对于每个 MIDI 接口,API 将暴露该 设备的名称、制造商以及该 MIDI 接口的不透明标识符。
大多数系统没有连接 MIDI 接口。只有少数 系统会连接大量 MIDI 接口。 因此,枚举 MIDI 设备所带来的额外指纹识别暴露 类似于 Gamepad API 通过枚举游戏手柄所带来的 额外指纹识别暴露:典型用户最多只会连接少量设备, 其配置可能会变化,并且所暴露的信息是关于接口本身的 (即没有用户配置的数据)。
第一批 MIDI 设备于 1983 年发布,当时 Web 平台及其安全风险尚不存在。许多 MIDI 设备在其制造商 停止支持很久之后仍在使用。MIDI 已经适应了 原始串行连接之外的传输方式,例如 FireWire、 USB 和 Bluetooth。这带来了安全挑战,因为来自不同时代的大量设备 没有官方支持却仍在积极使用,并以其设计者未曾 预期的方式连接到计算机和 Web。
一种令人担忧的理论攻击涉及对 USB-MIDI 设备进行恶意 固件更新。一般来说,USB 设备可以根据其设备描述符 执行操作,而该描述符由 USB 设备本身发送。如果 USB-MIDI 设备的 固件可以修改所发送的描述符,它 就可以让自己表现为人机接口设备。这 可能允许恶意网站读取或注入宿主计算机上的 按键或其他事件,从而可能导致系统被完全攻陷。
攻击将按如下方式进行:
为了促成上述攻击,一个 MIDI 设备 需要满足以下所有条件:
容易受到恶意固件更新影响但不满足其他条件的 MIDI 设备,不能被此攻击用于攻陷 宿主系统。恶意固件更新仍然可能导致这些 MIDI 设备停止 工作或以不期望的方式运行。
为缓解此风险,实现者应在其实现中强调以下事项:
requestMIDIAccess(),
例如通过权限提示中的文本说明。
显式允许或阻止已知 MIDI 设备列表也可能有助于缓解此特定攻击, 但许多小公司和个人会构建 MIDI 设备,并且许多 MIDI 设备 已不再受支持,因此这样做会显著降低 Web MIDI API 的可用性。
除了识别可用端口所带来的指纹识别问题之外,还存在 发送和接收 MIDI 消息方面的问题。这些问题将在 下文更深入地探讨。
MIDI 消息可分为 System Exclusive 消息和短消息(非 System Exclusive 消息)。 System Exclusive 消息还可进一步细分为 Universal System Exclusive 消息,例如常见的 MIDI Time Code 和 MIDI Sample Dump Standard,以及设备特定的消息,例如“Roland Jupiter-80 合成器的音色控制数据”,这类消息不适用于其他设备。
在讨论安全问题之前,先考察 MIDI 使用这些 功能所支持的场景会很有帮助:
这些场景各自的潜在安全影响如下:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in: