Get MIDI Input from the Browser
Using Web-Midi in Chrome to capture Midi Input
- open a website on http://localhost:1880/webmidi to capture midi events.
- events are passed to Node-RED via websockets
[{"id":"2e9160b.e4fe9a","type":"tab","label":"WebMidi","disabled":false,"info":""},{"id":"e97da89a.80bc68","type":"inject","z":"2e9160b.e4fe9a","name":"","topic":"","payload":"{\"topic\":\"midi/test\",\"payload\":\"100\"}","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":300,"wires":[["f1f7b660.30d318"]]},{"id":"c9bcd68.6791e28","type":"http response","z":"2e9160b.e4fe9a","name":"","statusCode":"200","headers":{},"x":860,"y":400,"wires":[]},{"id":"d54b6395.9592c","type":"http in","z":"2e9160b.e4fe9a","name":"","url":"/webmidi","method":"get","upload":false,"swaggerDoc":"","x":130,"y":400,"wires":[["7ccfa9a7.99464"]],"info":"<http://localhost:1880/webmidi>"},{"id":"7ccfa9a7.99464","type":"template","z":"2e9160b.e4fe9a","name":"","field":"payload","fieldType":"msg","format":"html","syntax":"plain","template":"<html>\n <head>\n <script src=\"https://cdn.jsdelivr.net/npm/[email protected]\"></script>\n </head>\n <body>\n \n <h1>Please connect your midi device</h1>\n <ul id=\"log\"></ul>\n \n <script>\n \n var socket = new WebSocket(`ws://${document.location.host}/ws/webmidi`);\n \n function log(msg) {\n document.getElementById(\"log\").insertAdjacentHTML('afterbegin', `<li>${msg}</li>`);\n }\n \n function send(obj) {\n socket.send(JSON.stringify(obj));\n }\n \n socket.onopen = function () {\n log(\"Websocket opened\");\n };\n \n socket.onerror = function (errorEvent) {\n log(\"Error! Websocket closed\");\n };\n \n WebMidi.enable(function (err) {\n\n if (err) {\n log(\"WebMidi could not be enabled.\");\n return;\n } \n \n log(\"WebMidi enabled!\");\n console.log(WebMidi.inputs);\n console.log(WebMidi.outputs);\n \n //get the first midi input device\n let input = WebMidi.inputs[0];\n \n input.addListener('noteon', 'all',\n function(e) {\n log(`Key Down: ${e.note.name} (Octave ${e.note.octave})`);\n send({ payload: e.note, topic: 'midi/noteon' });\n }\n );\n \n input.addListener('noteoff', 'all',\n function (e) {\n log(`Key Up: ${e.note.name} (Octave ${e.note.octave})`);\n send({ payload: e.note, topic: 'midi/noteoff' });\n }\n );\n \n input.addListener('controlchange', 'all',\n function (e) {\n log(`Controller ${e.controller.number}: ${e.value} `);\n console.log(\"Received 'controlchange' message.\", e);\n send({ payload: {number: e.controller.number, value: e.value}, topic: 'midi/controlchange' });\n }\n );\n \n \n input.addListener('pitchbend', 'all',\n function (e) {\n log(\"Received Pitch Bend ...\");\n console.log(\"Pitch Bend:\", e);\n }\n );\n \n \n });\n \n </script>\n \n </body>\n</html>","output":"str","x":540,"y":400,"wires":[["c9bcd68.6791e28"]]},{"id":"f1f7b660.30d318","type":"websocket out","z":"2e9160b.e4fe9a","name":"","server":"","client":"6e66e176.fce898","x":610,"y":300,"wires":[]},{"id":"c1710c75.68d528","type":"comment","z":"2e9160b.e4fe9a","name":"test the websocket connection","info":"","x":190,"y":260,"wires":[]},{"id":"1f189d98.f7242a","type":"comment","z":"2e9160b.e4fe9a","name":"website to send midi input to server","info":"<http://localhost:1880/webmidi>","x":200,"y":360,"wires":[]},{"id":"3e940c66.56c2fc","type":"websocket in","z":"2e9160b.e4fe9a","name":"","server":"c1ead446.0e336","client":"","x":140,"y":200,"wires":[["41b78993.6020d"]]},{"id":"2f0fe21e.143206","type":"comment","z":"2e9160b.e4fe9a","name":"receive webmidi via websocket","info":"","x":190,"y":160,"wires":[]},{"id":"41b78993.6020d","type":"debug","z":"2e9160b.e4fe9a","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":830,"y":200,"wires":[]},{"id":"6e66e176.fce898","type":"websocket-client","z":"","path":"ws://localhost:1880/ws/webmidi","tls":"","wholemsg":"false"},{"id":"c1ead446.0e336","type":"websocket-listener","z":"","path":"/ws/webmidi","wholemsg":"true"}]