node.jsでRICOH THETAを操作できるnpmを作った。nodeが入ってるMacやLinuxをWiFiでTHETAに接続して使う。

https://github.com/shokai/node-ricoh-theta
https://www.npmjs.com/package/ricoh-theta

不具合・質問などはtwittergithubのissueにお願いします。


ネットを探した感じだと、thetaのシャッターを切るコード片は色々な言語で実装されてた。
でもそれらはちゃんとPTP-IPのコネクションやセッションを管理せず撮影命令のパケットを送るだけなので、撮影した写真を吸い出したり、リスト取得、削除はできない。
そこでptp.jsにそれらの機能を追加して、それをさらにラップしてricoh-theta npmを作った。


インストール

グローバルにインストールするとthetaというコマンドが使える。
% npm install ricoh-theta -g
% theta --help


crontabに
* * * * * theta --capture tmp.jpg && open tmp.jpg
とか書いて大きいモニタに表示しておくだけで結構おもしろい。


ライブラリとして使う


もちろんライブラリとしてもこんな感じで使える。
var Theta = require('ricoh-theta');

var theta = new Theta();
theta.connect('192.168.1.1');

// capture
theta.on('connect', function(){
theta.capture(function(err){
if(err) return console.error(err);
console.log('capture success');
});
});

// get picture
theta.on('objectAdded', function(object_id){
theta.getPicture(object_id, function(err, picture){
fs.writeFile('tmp.jpg', picture, function(err){
console.log('picture saved => tmp.jpg');
theta.disconnect();
});
});
});
取得した写真はbufferなので、ファイルに書き出さずにそのままhttpで配信するとかも容易。

captureからのコールバックで撮影したオブジェクトのIDを受け取るのではなく、objectAddedという別イベントにしてある。PTP-IPがそれらを別に扱っているのでそうした(今後のTHETAでどっちが先に発火するか、逆になる可能性あるし)
この書き方だと、APIに接続していればリモートシャッターではなく本体の撮影ボタンを自分で押して撮って、オブジェクト追加通知をnodeで受けて写真を吸い取るという事もできる。

そんなわけで、最初は接続→撮影→取得っていう手続きすればいいんだからPromiseでやろうと思ったけど、socket.io風のインタフェースに落ち着いた。

PTPではオブジェクトIDのほかにストレージIDというのもあって、これは例えばデジカメで内蔵メモリとSDカードとを切り替えて使う時に指定するためのIDなんだけど、thetaは内蔵メモリしかないから常にID:1が使われている。
もし今後マイクロSDを追加できるTHETAがでてきたら、APIを変えると思う。




ptp.jsへの追加分はプルリクしておいたんだけど、今のところricoh-theta npmがインストールするptp.jsは俺のgithubのread_dataブランチからインストールするようになっている。
(2015年1月31日:mergeされたのでnpmjs.orgから普通にインストールするようにした)

nodeって、マイナーなプロトコルの基本実装がnpmになっている事が多かったり、変更が本家にmergeされていなくても言語のパッケージマネージャがgithubから依存解決できたりというのがすごい良いと思う。