nodejsでローカルにoscを送るwebアプリケーションを作る (SocketIO, Express)

Type: Tech BlogDate: 2019 - 10 - 9Tags:
#Open Sound Control#nodejs#express

誰でも osc を通して作品に参加できるような web アプリケーションをプロトタイピングしました。リポジトリ

OSC とは: opensoundcontrol.orgwikipediaを参照。

yoppa.org のopenFramewoks – OSC (Open Sound Control) を利用したネットワーク連携が非常にためになる。

UDP 上で MIDI みたいなものを Max/MSP に送ったりできるので非常に便利。今回はこいつを LAN 上だけならずインターネット上のスマートフォンからローカルに受け付ける,展示をよりインタラクティブにするためのツールのプロトタイピングを行う。

(以下リポジトリを参照していただければローカルでアプリケーション動かせます)

https://github.com/atsukoba/osc-webapp

nodejs/express でサーバを立てて,軽くて双方向に使える websocket でユーザのアプリケーション上での動きを捉える。localhost に立てたサーバを ngrok で公開し,その URL(とローカルの IP アドレス)を QR コードに出力するところまでを実装する。

軽くフロントを書いてデモをつくり,簡単なボタンとそのボタンに対応したメッセージをローカルの osc に送れるかを確認する。

alt

express

1npm install express-generator -g
2express --view=ejs osc-webapp
3cd osc-webapp
4npm install

socket.ioを使用する。

1const app = express();
2const http = require("http").Server(app);
3const io = require("socket.io")(http);

osc

node-osc(npm: node-osc)を利用する。利用例としては以下のような感じ

1const osc_portnum = 5050;
2const client = new osc.Client("127.0.0.1", osc_portnum);
3
4io.of("osc").on("connection", (socket) => {
5  socket.on("message", (obj) => {
6    console.log("osc: " + obj);
7    obj = JSON.parse(obj);
8    let sendObj = new osc.Message(obj.address);
9    sendObj.append(obj.args);
10    client.send(sendObj);
11    let dt = new Date();
12    io.of("osc").send(
13      `${dt.toFormat("HH24:MI:SS")} : osc message received: ${obj.args}`,
14    );
15  });
16});

qrcode

os, qrcode(npm: qrcode) を用いて,ローカル IP アドレスとngrok(npm: ngrok)で生成した URL を QR にする。

1const ngrok = require("ngrok");
2const qrcode = require("qrcode");
3
4// get local ip addresses
5let interfaces = os.networkInterfaces();
6let addresses = [];
7for (let k in interfaces) {
8  for (let k2 in interfaces[k]) {
9    let address = interfaces[k][k2];
10    if (address.family === "IPv4" && !address.internal) {
11      addresses.push(address.address);
12    }
13  }
14}
15console.log(`local ip addresses: ${addresses}`);
16console.log(`FOR LOCAL NEWORK PARTICIPANTS`);
17qrcode.toString(
18  `http://${addresses[0]}:${portnum}`,
19  { type: "terminal" },
20  (err, str) => {
21    console.log(str);
22  },
23);
24
25// make ngrok tunnel
26console.log(`FOR WWW PARTICIPANTS`);
27(async () => {
28  let url = await ngrok.connect(portnum);
29  console.log("ngrok URL: " + url);
30  qrcode.toString(url, { type: "terminal" }, (err, str) => {
31    console.log(str);
32  });
33})();

つかう

1npm start

これで QR コードが生成されるので,それをシェアすれば osc を送れる。同一 LAN にいるなら,上部の QR コードでおk。config ファイルでポート番号を指定し,デモはクライアント側の main.js で(今は)送る osc メッセージをハードコードしているので,適宜それを編集して使っていただければと思う。

gif

reference