Start · Sprachen · JavaScript · Referenz · Navigator.requestMIDIAccess()

Navigator.requestMIDIAccess()

Methode

Fordert Zugriff auf die MIDI-Ein- und Ausgabegeräte des Systems an und liefert ein <code>Promise</code>, das mit einem <code>MIDIAccess</code>-Objekt erfüllt wird.

seit JavaScript Web MIDI API — Chrome 43+, Edge 79+, Firefox 108+, Kategorie: webapi

Signatur

Navigator.prototype.requestMIDIAccess(options)

Beschreibung

Die Methode navigator.requestMIDIAccess() ist der Einstiegspunkt der Web MIDI API. Mit ihr bittet eine Webanwendung um Zugriff auf angeschlossene MIDI-Geräte wie Keyboards, Controller, Synthesizer oder Drum-Pads. Wird die Anfrage erfüllt, erhält man ein MIDIAccess-Objekt. Über dessen Maps inputs und outputs lassen sich alle verfügbaren Ports aufzählen.

Eingehende Nachrichten, etwa Note-On, Note-Off oder Control Change, empfängt man über das Ereignis midimessage eines MIDIInput. Nachrichten an Geräte schickt man mit MIDIOutput.send(). Das Ereignis statechange auf dem MIDIAccess-Objekt meldet, wenn Geräte angeschlossen oder getrennt werden.

Mit der Option sysex: true fordert man zusätzlich System-Exclusive-Nachrichten an. Sie sind nötig für Firmware-Updates, Patch-Dumps oder herstellerspezifische Befehle. Weil SysEx sehr weitreichend in Geräte eingreifen kann, fragt der Browser dafür immer ausdrücklich nach Erlaubnis. Seit Chrome 124 wird auch für den Zugriff ohne SysEx eine Berechtigung abgefragt.

Die Methode funktioniert nur in einem sicheren Kontext (HTTPS oder localhost). Die Nutzung kann außerdem über die Permissions Policy midi eingeschränkt sein.

Parameter

Name Typ Default Beschreibung
$options object {} Optionales Konfigurationsobjekt mit folgenden Eigenschaften:
  • sysex (boolean, Standard false): Fordert zusätzlich das Senden und Empfangen von System-Exclusive-Nachrichten an.
  • software (boolean, Standard false): Erlaubt auch Software-Synthesizer bzw. virtuelle Ports. Dieser Wert wird bislang kaum ausgewertet.

Rückgabewert

Typ
Promise<MIDIAccess>
Beschreibung
Ein Promise, das mit einem MIDIAccess-Objekt erfüllt wird. Es wird mit einer DOMException abgelehnt: SecurityError oder NotAllowedError, wenn der Zugriff verweigert oder durch eine Richtlinie blockiert wird; AbortError bzw. InvalidStateError, wenn der Zugriff aus technischen Gründen scheitert; NotSupportedError, wenn die Funktion nicht verfügbar ist.

Beispiele

Zugriff anfordern und Geräte auflisten

const listMidiDevices = async () => {
  if (!('requestMIDIAccess' in navigator)) {
    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})`);
    }
    for (const output of midi.outputs.values()) {
      console.log(`Ausgang: ${output.name} (${output.manufacturer})`);
    }
  } catch (err) {
    console.error(`MIDI-Zugriff fehlgeschlagen: ${err.name}`);
  }
};

listMidiDevices();
Eingang: Launchkey Mini MK3 (Novation) Ausgang: Launchkey Mini MK3 (Novation)

Noten eines Keyboards empfangen

const midi = await navigator.requestMIDIAccess();

const handleMessage = ({ data }) => {
  const [status, note, velocity] = data;
  const command = status & 0xf0;
  if (command === 0x90 && velocity > 0) {
    console.log(`Note an: ${note}, Anschlagstärke ${velocity}`);
  } else if (command === 0x80 || (command === 0x90 && velocity === 0)) {
    console.log(`Note aus: ${note}`);
  }
};

for (const input of midi.inputs.values()) {
  input.addEventListener('midimessage', handleMessage);
}

// Neu angeschlossene Geräte erkennen
midi.addEventListener('statechange', ({ port }) => {
  console.log(`${port.type} "${port.name}": ${port.state}`);
  if (port.type === 'input' && port.state === 'connected') {
    port.addEventListener('midimessage', handleMessage);
  }
});
Note an: 60, Anschlagstärke 97 Note aus: 60

Ton an einen Synthesizer senden (mit SysEx-Anfrage)

const playNote = async (note = 60, durationMs = 500) => {
  const midi = await navigator.requestMIDIAccess({ sysex: true });
  const [output] = midi.outputs.values();
  if (!output) {
    console.log('Kein MIDI-Ausgang gefunden.');
    return;
  }
  // Note On, Kanal 1, Anschlagstärke 100
  output.send([0x90, note, 100]);
  // Note Off nach durationMs, zeitgenau über den Zeitstempel
  output.send([0x80, note, 0], performance.now() + durationMs);
  console.log(`Note ${note} an "${output.name}" gesendet.`);
};

playNote(64);
Note 64 an "USB MIDI Synth" gesendet.

// Wichtig · Fallstricke

  • Browser-Kompatibilität: Chromium-Browser unterstützen die API seit Langem, Firefox erst ab Version 108 (und nur mit zusätzlicher Freigabe über ein Site-Permission-Add-on). Safari unterstützt Web MIDI nicht. Prüfen Sie deshalb immer mit 'requestMIDIAccess' in navigator und bieten Sie eine Ausweichlösung an.
  • Sicherer Kontext: Die Methode gibt es nur unter HTTPS oder localhost. In iframes muss die Einbettung die Berechtigung ausdrücklich erlauben, z. B. mit <iframe allow="midi">.
  • Sicherheit bei SysEx: Mit SysEx-Nachrichten lässt sich Firmware überschreiben oder ein Gerät unbrauchbar machen. Fordern Sie sysex: true nur an, wenn Sie es wirklich brauchen. Verweigert der Nutzer den Zugriff, wird das Promise abgelehnt.
  • Fingerprinting: Die Liste der Gerätenamen kann Nutzer identifizierbar machen. Browser fragen daher zunehmend auch ohne SysEx nach Erlaubnis.
  • Note On mit Anschlagstärke 0 gilt nach MIDI-Standard als Note Off. Viele Geräte senden das statt 0x80.
  • Ports werden beim ersten send() oder beim Setzen eines midimessage-Listeners implizit geöffnet. Mit port.open() bzw. port.close() steuern Sie das ausdrücklich.