Signatur
Beschreibung
Die Methode open() der Schnittstelle MIDIPort öffnet die Verbindung zum physischen oder virtuellen MIDI-Gerät hinter dem Port. Danach hat MIDIPort.connection den Wert "open". Ist der Port schon offen, wird das Promise sofort erfüllt und es passiert sonst nichts.
Normalerweise muss man open() gar nicht selbst aufrufen: Der Port wird implizit geöffnet, sobald man bei einem MIDIInput einen midimessage-Handler setzt oder bei einem MIDIOutput die Methode send() aufruft. Ein expliziter Aufruf lohnt sich in folgenden Fällen:
- Man will ein Gerät reservieren, bevor die erste Nachricht gesendet wird. So entfällt die Verzögerung beim ersten
send(). - Die Anwendung soll Fehler beim Öffnen gezielt abfangen können, etwa wenn ein anderes Programm das Gerät exklusiv belegt.
- Die Oberfläche soll den Verbindungszustand verlässlich anzeigen, zum Beispiel über das Ereignis
statechange.
Wenn das Gerät nicht geöffnet werden kann, wird das Promise mit einer DOMException vom Typ InvalidAccessError abgelehnt. Ist das Gerät getrennt (state === "disconnected"), wechselt connection auf "pending". Der Port wird dann automatisch geöffnet, sobald das Gerät wieder angeschlossen ist.
Rückgabewert
Promise, das mit demselben MIDIPort erfüllt wird, sobald der Port offen ist (bzw. auf "pending" steht). Kann der Port nicht geöffnet werden, wird es mit einer DOMException (InvalidAccessError) abgelehnt.Beispiele
Ersten MIDI-Ausgang explizit öffnen
const midi = await navigator.requestMIDIAccess();
const output = [...midi.outputs.values()][0];
if (!output) {
console.log('Kein MIDI-Ausgang gefunden');
} else {
console.log('Vorher:', output.connection);
await output.open();
console.log('Nachher:', output.connection);
// Note-On C4, Anschlagstärke 100 – ohne Verzögerung beim ersten Senden
output.send([0x90, 60, 100]);
}
Fehler beim Öffnen abfangen
const openPort = async (port) => {
try {
const p = await port.open();
console.log(`${p.name} (${p.type}) ist ${p.connection}`);
return true;
} catch (err) {
// z. B. Gerät von anderer Anwendung exklusiv belegt
console.error(`Konnte ${port.name} nicht öffnen:`, err.name);
return false;
}
};
const access = await navigator.requestMIDIAccess();
for (const input of access.inputs.values()) {
await openPort(input);
}
Alle Eingänge öffnen und auf Zustandswechsel reagieren
const access = await navigator.requestMIDIAccess();
access.addEventListener('statechange', (event) => {
const { name, state, connection } = event.port;
console.log(`${name}: state=${state}, connection=${connection}`);
});
const ports = [...access.inputs.values()];
await Promise.all(ports.map((port) => port.open()));
ports.forEach((port) => {
port.onmidimessage = ({ data }) => console.log('MIDI:', [...data]);
});
// Wichtig · Fallstricke
- Browser-Unterstützung: Die Web MIDI API gibt es in Chromium-Browsern und in Firefox (ab Version 108, dort teils über ein Site-Permission-Add-on). Safari unterstützt sie nicht. Vor der Nutzung sollte man deshalb mit
'requestMIDIAccess' in navigatorprüfen, ob sie vorhanden ist. - Sicherer Kontext: Die API funktioniert nur über HTTPS (bzw.
localhost) und braucht die Zustimmung der Nutzerin oder des Nutzers. Für SysEx-Nachrichten muss man zusätzlich{ sysex: true }anfordern. - Implizites Öffnen: Das Setzen von
onmidimessageoder der Aufruf vonsend()öffnet den Port automatisch. Ein Listener überaddEventListener('midimessage', …)öffnet den Port dagegen nicht – dann muss manopen()selbst aufrufen. - Exklusiver Zugriff: Unter Windows können viele Treiber ein Gerät nur von einer Anwendung gleichzeitig nutzen lassen.
open()schlägt dann mitInvalidAccessErrorfehl. - Geöffnete Ports sollte man mit
close()wieder freigeben, wenn man sie nicht mehr braucht, damit andere Anwendungen auf das Gerät zugreifen können.