ブラウザから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