JavaScript
Node.js
websocket
Max-MSP

ブラウザからWebSocketとOSCを使ってMAXを操作してみる

More than 3 years have passed since last update.


ブラウザからWebSocketとOSCを使ってMAXを操作してみる


モチベーション


  • 久々にMax触りたいので、コントローラ募集中。うちにiPhone×2+iPod touch 5th×1がある!コレ使いたい。というか、iOSしかない!w


  • iOSCは素晴らしいし大好きだが、自分でもUI作ってみたい

  • でもiPhoneのネイティブアプリ作りたくないのでブラウザでやりたい。

  • インターネットに出て行くなんて使い方はしないので、レイテンシーなんとかなるはず!

  • ブラウザで作れるようにしとけば、iPhoneだけでなく、ブラウザ+Arduino+センサ、Web MIDIとか、WebRTCとか、いろいろと夢(妄想)が広がる!

というわけで、自分以外に誰も得な人が居ないと思われる記事ですw


レイテンシー気にせず変換作戦!

↓こんな風に途中で変換すれば、なんとかなるはず!という作戦です。

なんとかなって欲しい図

MaxをWebSocketに対応させる方が良いのかもしれませんが、応用効かないのであまりやりたくないし。

レイテンシーは仕方ありませんので、ある程度は目をつぶる方針です。速さを求めるならOSCを組み込んだNativeアプリの方が良いです。


使ったもの

こんな感じです。


1) 「WebSocketを受けてOSCで送る君」をnode.jsで作る

まず、サーバから作ります。

Node.jsとnpmは入っている前提です。

wsとomgoscを入れましょう。

> npm install ws

> npm install omgosc

あとは「WebSocketを受けてOSCで送る君」を書くだけです。

var hosturl = "0.0.0.0";

var wsport = 3100;
var oscport = 8000;

// WebSocket Serverを立ち上げる
var WebSocketServer = require('ws').Server;
var wss = new WebSocketServer({host:hosturl, port:wsport});

// OSC Senderを立ち上げる
var oscsender = require('omgosc').UdpSender;
var sender = new oscsender(hosturl, oscport);

// WebSocketのイベントハンドラ
wss.on('connection', function (ws) {
ws.on('message', function (message) {
console.log(message);
var mes = JSON.parse(message);
if(mes.osc){ // チェック甘!
// OSCで送信
sender.send(mes.path,mes.type,[mes.data]);
}
});
});

はい。できました。

これを、server.js など、適当な名前で保存して、コマンドラインから

> node server.js

と入力して実行します。


2) OSCを受け取る側(ここではMax)のパッチ

server.jsが、UDPに変換してくれるので、Max側ではOSC対応コントローラと繋ぐ時と同じ要領で普通にパッチが作れます。

念のため、server.jsに指定したOSC送信先ポート番号だけ間違わないようにしてください。

今回の例では、server.jsが8000番にOSCを送りつけてくるので、受け取るMax側もudpreceive 8000 で受けとる必要があります。

データが届いたことを確認するだけのパッチ


3) コントローラとなるWebページを作る

最後にWebページです。

WebSocketをSever.jsに送りつけるところだけ紹介します。

// server.jsは同じドメインに居る前提。

var url = window.document.location.host.replace(/:.*/, '');
var wsport = 3100; // WebSocketのPort番号

// WebSocket開始
var wsOsc = {};
wsOsc.ws = new WebSocket('ws://' + url + ':'+wsport);
wsOsc.status = 0; // 0: 送れる 1: 送れない
wsOsc.ws.onopen = function(){
wsOsc.status = 1; // 送れる
};
wsOsc.ws.onclose = function(){
wsOsc.status = 0; // 送れない
};
wsOsc.send = function(path,type,data){
var jsonobj = {"osc":"WsOscSend","path":path,"type":type,"data":data};
var json = JSON.stringify(jsonobj);

// 送れれば送る
if(wsOsc.status){
wsOsc.ws.send(json);
}
};

// 送るところ。(jQuery使ってます)
var toggle = 0;
$(function() {
// iPhone用(てぬき)
$('#bt1').bind('touchstart', function(event) {
event.preventDefault();

// ここで送信。
wsOsc.send('/osc/button1','i',[toggle]);
if(toggle == 0){
toggle = 1;
}else{
toggle = 0;
}
});
});

。。。てきと〜なコードですいませんw

やってることは下記のようなことです。


  • WebSocketのコネクションを貼る

  • OSCメッセージは、一旦JSONにシリアライズする

  • JSONシリアライズしたデータをWebSocketで送る


通信じゃないところにもレイテンシーの原因があるので注意!

今回これを作ってて気付いたのですが、onClickとかを使うと反応がメチャメチャ悪くなります。

サンプルコードでは面倒くさがってtouchstartにイベントを仕掛けましたが、クリック操作にしたい場合、fastclickとかを使った方が良いと思いました。


動かしてみた感想

確かにレイテンシーありますけど、使い道はあるんじゃないかな〜?w


まとめ

Node.js+WebSocket素晴らしいですね。

オマケ:MIDIでやってる人も居ました。


2015.02.26 追記

パッケージを公開してる人が居ました!(仕組みは同じっぽい)

osc-web

自分でいちから作るの面倒!という方は試してみよう!

さっそく試してみます!!←お前もか!!w