Start · Sprachen · JavaScript · Referenz · MIDIAccess

MIDIAccess

Schnittstelle

Das <code>MIDIAccess</code>-Interface der Web MIDI API listet angeschlossene MIDI-Ein- und -Ausgabegeräte auf und meldet, wenn Geräte angeschlossen oder getrennt werden.

seit JavaScript Web MIDI API — Chromium-Browser (Chrome/Edge/Opera Kategorie: webapi

Signatur

interface MIDIAccess extends EventTarget

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 — eine MIDIInputMap (Map-ähnlich, nur lesbar) mit allen verfügbaren MIDIInput-Ports. Schlüssel ist die Port-ID.
  • outputs — eine MIDIOutputMap mit allen verfügbaren MIDIOutput-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 / Ereignis statechange — wird ausgelöst, wenn ein Port hinzukommt, wegfällt oder seinen Verbindungsstatus ändert. Das Ereignis ist ein MIDIConnectionEvent mit der Eigenschaft port.

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

Typ
MIDIAccess
Beschreibung
Wird nicht direkt konstruiert, sondern von 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();
Eingang: Launchkey Mini (Novation) – ID input-0 Ausgang: Launchkey Mini – Status connected SysEx erlaubt: false

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);
});
Note an: 60, Anschlag 100 Note aus: 60

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);
input "Launchkey Mini": connected / closed output "Launchkey Mini": disconnected / closed

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 einem SecurityError bzw. NotAllowedError abgewiesen.
  • SysEx: sysexEnabled ist nur true, wenn du requestMIDIAccess({ 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/outputs sind Live-Maps: Speichere Port-Referenzen nicht dauerhaft, ohne statechange zu beobachten. Ein getrennter Port hat state === 'disconnected'.
  • Wenn du einen midimessage-Listener registrierst, wird der Port automatisch geöffnet (connection: 'open'). Mit port.close() gibst du das Gerät wieder frei.