Signatur
Beschreibung
Ein MIDIAccess-Objekt ist der Einstieg in die Web MIDI API. Du erzeugst es nicht selbst, sondern erhältst es als Ergebnis des Promise von navigator.requestMIDIAccess(). Über das Objekt kommst du an alle MIDI-Geräte, die das System erkennt, zum Beispiel USB-Keyboards, Controller, Synthesizer oder virtuelle MIDI-Ports.
Die wichtigsten Mitglieder:
inputs— eineMIDIInputMap(Map-ähnlich, nur lesbar) mit allen verfügbarenMIDIInput-Ports. Schlüssel ist die Port-ID.outputs— eineMIDIOutputMapmit allen verfügbarenMIDIOutput-Ports.sysexEnabled—boolean. Gibt an, ob der Zugriff mit{ sysex: true }angefordert und erlaubt wurde. Nur dann darfst du System-Exclusive-Nachrichten senden und empfangen.onstatechange/ Ereignisstatechange— wird ausgelöst, wenn ein Port hinzukommt, wegfällt oder seinen Verbindungsstatus ändert. Das Ereignis ist einMIDIConnectionEventmit der Eigenschaftport.
Typischer Ablauf: Zugriff anfordern, über inputs iterieren und an jedem Eingang einen midimessage-Listener registrieren. Mit outputs sendest du über MIDIOutput.send() Nachrichten an Geräte. Weil Geräte zur Laufzeit an- und abgesteckt werden können, solltest du auf statechange reagieren und deine Gerätelisten bzw. die Oberfläche aktualisieren.
Rückgabewert
navigator.requestMIDIAccess(options) als erfülltes Promise<MIDIAccess> geliefert.Beispiele
Zugriff anfordern und Geräte auflisten
const listMidiDevices = async () => {
if (!navigator.requestMIDIAccess) {
console.warn('Web MIDI wird von diesem Browser nicht unterstützt.');
return;
}
try {
const midi = await navigator.requestMIDIAccess();
for (const input of midi.inputs.values()) {
console.log(`Eingang: ${input.name} (${input.manufacturer}) – ID ${input.id}`);
}
for (const output of midi.outputs.values()) {
console.log(`Ausgang: ${output.name} – Status ${output.state}`);
}
console.log('SysEx erlaubt:', midi.sysexEnabled);
} catch (err) {
console.error('MIDI-Zugriff verweigert:', err.name);
}
};
listMidiDevices();
Noten von allen Eingängen empfangen
const midi = await navigator.requestMIDIAccess();
const handleMessage = (event) => {
const [status, note, velocity] = event.data;
const command = status & 0xf0;
if (command === 0x90 && velocity > 0) {
console.log(`Note an: ${note}, Anschlag ${velocity}`);
} else if (command === 0x80 || (command === 0x90 && velocity === 0)) {
console.log(`Note aus: ${note}`);
}
};
midi.inputs.forEach((input) => {
input.addEventListener('midimessage', handleMessage);
});
Auf An- und Abstecken reagieren (statechange)
const midi = await navigator.requestMIDIAccess();
const onStateChange = (event) => {
const { port } = event;
console.log(`${port.type} "${port.name}": ${port.state} / ${port.connection}`);
};
midi.addEventListener('statechange', onStateChange);
// Alternativ: midi.onstatechange = onStateChange;
// Später wieder abmelden:
// midi.removeEventListener('statechange', onStateChange);
Note an einen Ausgang senden
const midi = await navigator.requestMIDIAccess();
const [output] = midi.outputs.values();
if (output) {
output.send([0x90, 60, 0x7f]); // Note an: C4, volle Lautstärke
output.send([0x80, 60, 0x00], performance.now() + 500); // Note aus nach 500 ms
} else {
console.log('Kein MIDI-Ausgang gefunden.');
}
// Wichtig · Fallstricke
- Browser-Unterstützung: Die API gibt es in Chromium-Browsern und in Firefox ab Version 108. Safari unterstützt sie nicht. Prüfe vor der Nutzung immer mit
'requestMIDIAccess' in navigator, ob sie vorhanden ist. - Sicherer Kontext und Berechtigung: Die API funktioniert nur über HTTPS oder
localhost. Aktuelle Browser fragen bei jedem MIDI-Zugriff um Erlaubnis, nicht nur bei SysEx. Firefox verlangt außerdem ein installiertes „Site Permission Add-on“. Bei Ablehnung wird das Promise mit einemSecurityErrorbzw.NotAllowedErrorabgewiesen. - SysEx:
sysexEnabledist nurtrue, wenn durequestMIDIAccess({ sysex: true })aufrufst und der Nutzer zustimmt. Über SysEx lässt sich die Firmware mancher Geräte ändern. Fordere diesen Zugriff deshalb nur an, wenn du ihn wirklich brauchst. - Permissions Policy: In iframes muss der Zugriff mit
allow="midi"freigegeben werden. inputs/outputssind Live-Maps: Speichere Port-Referenzen nicht dauerhaft, ohnestatechangezu beobachten. Ein getrennter Port hatstate === 'disconnected'.- Wenn du einen
midimessage-Listener registrierst, wird der Port automatisch geöffnet (connection: 'open'). Mitport.close()gibst du das Gerät wieder frei.