Start · Sprachen · JavaScript · Referenz · MIDIPort

MIDIPort

Schnittstelle

Das <code>MIDIPort</code>-Interface der Web MIDI API steht für einen MIDI-Eingangs- oder -Ausgangsport und ist die Basis von <code>MIDIInput</code> und <code>MIDIOutput</code>.

seit JavaScript Web MIDI API — Chrome/Edge 43+, Opera 30+, Firefox Kategorie: webapi

Signatur

interface MIDIPort extends EventTarget

Beschreibung

MIDIPort ist die gemeinsame Basisschnittstelle für alle MIDI-Ports, die über navigator.requestMIDIAccess() erreichbar sind. Direkt erzeugt wird sie nie. Du bekommst immer eine konkrete Instanz von MIDIInput (Eingang, z. B. ein Keyboard) oder MIDIOutput (Ausgang, z. B. ein Synthesizer). Diese Instanzen stehen in den Maps MIDIAccess.inputs und MIDIAccess.outputs.

Jeder Port beschreibt sein Gerät mit den schreibgeschützten Eigenschaften id, name, manufacturer, version und type ("input" oder "output"). Dazu kommen zwei Zustände:

  • state: "connected" oder "disconnected". Sagt, ob das Gerät physisch verfügbar ist.
  • connection: "open", "closed" oder "pending". Sagt, ob deine Anwendung den Port gerade benutzt.

Mit den Methoden open() und close() öffnest oder schließt du den Port ausdrücklich. Beide geben ein Promise<MIDIPort> zurück. Ändert sich state oder connection, wird das Ereignis statechange ausgelöst (über addEventListener("statechange", …) oder onstatechange). Das gleiche Ereignis kommt auch am MIDIAccess-Objekt an.

Typische Einsatzfälle: eine Geräteliste in einer Musik-App, Hot-Plugging (Geräte an- und abstecken) und das gezielte Freigeben von Ports, damit andere Programme sie nutzen können.

Rückgabewert

Typ
MIDIInput | MIDIOutput
Beschreibung
Keine direkte Instanziierung. Instanzen erhältst du über MIDIAccess.inputs und MIDIAccess.outputs.

Beispiele

Alle verfügbaren MIDI-Ports auflisten

const listPorts = async () => {
  const access = await navigator.requestMIDIAccess();
  const ports = [...access.inputs.values(), ...access.outputs.values()];
  for (const port of ports) {
    console.log(`${port.type}: ${port.name} (${port.manufacturer}) – ${port.state}/${port.connection}`);
  }
};

listPorts().catch((err) => console.error('MIDI nicht verfügbar:', err));
input: Launchkey Mini (Novation) – connected/closed output: Launchkey Mini (Novation) – connected/closed

Port ausdrücklich öffnen und schließen

const access = await navigator.requestMIDIAccess();
const [output] = access.outputs.values();

if (output) {
  await output.open();
  console.log(output.connection); // "open"
  output.send([0x90, 60, 100]); // Note On, mittleres C
  setTimeout(async () => {
    output.send([0x80, 60, 0]); // Note Off
    await output.close();
    console.log(output.connection);
  }, 500);
}
open closed

Hot-Plugging mit statechange (addEventListener und onstatechange)

const access = await navigator.requestMIDIAccess();

// Global: alle Ports überwachen
access.addEventListener('statechange', (event) => {
  const { port } = event; // MIDIPort
  console.log(`${port.name} ist jetzt ${port.state} (${port.connection})`);
});

// Einzelnen Port per on-Property überwachen
for (const input of access.inputs.values()) {
  input.onstatechange = (e) => {
    if (e.port.state === 'disconnected') {
      console.warn(`Eingang ${e.port.name} wurde getrennt`);
    }
  };
}
Launchkey Mini ist jetzt disconnected (closed) Eingang Launchkey Mini wurde getrennt

// Wichtig · Fallstricke

  • Kompatibilität: Chromium-Browser und Firefox (ab 108) unterstützen die API, Safari nicht. Die API läuft nur in sicheren Kontexten (HTTPS). Firefox verlangt außerdem ein Site-Permission-Add-on bzw. eine Nutzerbestätigung.
  • Berechtigungen: requestMIDIAccess({ sysex: true }) fragt den Nutzer ausdrücklich um Erlaubnis, weil SysEx-Nachrichten Geräte-Firmware verändern können. Frage SysEx nur an, wenn du es wirklich brauchst. Auch eine Permissions Policy (midi) kann den Zugriff in iframes sperren.
  • Implizites Öffnen: Beim Setzen von MIDIInput.onmidimessage oder beim Aufruf von MIDIOutput.send() wird der Port automatisch geöffnet. open() brauchst du nur, wenn du den Port vorher belegen willst. Achtung: addEventListener("midimessage", …) öffnet den Port nicht automatisch.
  • Exklusiver Zugriff: Unter Windows kann ein Port oft nur von einem Programm gleichzeitig genutzt werden. open() wird dann mit InvalidAccessError abgelehnt.
  • state und connection sind verschiedene Dinge: state beschreibt die Hardware, connection die Nutzung durch deine App. Wird ein offener Port abgesteckt, geht connection auf "pending". Beim erneuten Anstecken wird er automatisch wieder geöffnet.
  • Eine über Sitzungen stabile id ist nicht garantiert. Zum Wiedererkennen eines Geräts eignet sich die Kombination aus name und manufacturer.