Ponz Dev Log

ゆるくてマイペースな開発日記

AR Studioでサンシャイン池崎になってクラウドとくっつけた話

なぜサンシャイン池崎に?

Facebook AR Studioワークショップ&ハッカソンに行ってきました。
お題として提示されたのが、今回の話題のfacebook AR Studio! ARを使ったエフェクトや表現を作成できるツールです!

本当はイケメンになるつもりだったのですが、"イケメンとは..." を突き詰めている間に池崎がフィットした次第です。 ARとあって、顔の表面にオブジェクトを貼り付けた上で動きを追従する優れもの。。。こんな感じ↓で貼り付けられます。

f:id:accelerk:20171114222044p:plain

たまたま貼り付けたサンシャイン池崎の顔の比率がぴったりでしたねw 顔のフィット具合の検証に関しては、以下リンクに譲ります。

hiroga.hatenablog.com

池崎とクラウドをくっつけて通信する

さて、本題です。ソーシャル要素を考えると、サーバー側と通信してデータを取ってきたいという欲が出てきます。 AR Studioは動きをつけたり、エフェクトを細かく制御するのは Javascriptを使うことになります。

ただし、制約事項としては以下2点を気に留めておきましょう。 1. Node.jsやブラウザのJSのような XMLHttpRequestやNPMを直接使えるわけではない 2. モジュール分割しづらい

データを取得する場合は、Networking Classの fetch メソッドを使えばOK。(中身は JSのfetch APIを呼んでいるみたいです)

[Networking Class]
https://developers.facebook.com/docs/camera-effects/reference/networking_module/networking_class

今回のハッカソンでは、以下のようにDB(今回はIBM CloudのCloudant NoSQL DB)からデータを引っ張る形にしました。 バックエンドはNode-REDサーバーを立ててCloudantにアクセスするAPIを叩く構成です。(Node-REDやCloudantの話は今回は割愛します)

// 表情のオブジェクトを取得する
const yeah = Scene.root.find('ikevoice');

// get neta serif url of Cloudant searching by id
function getNetaUrl(_id) {
    return "https://${bluemix-app-name}.mybluemix.net/neta?_id=" + _id;
}

// DBから取得したネタセリフをオブジェクトに書き込む
function fetch_neta(url) {
    Networking.fetch(url)
    .then(function (result) {
        if (result.status >= 200 && result.status < 300) {
            const neta_serifu = result.data.neta;
            yeah.text = neta_serifu;  // ここでセリフを yeah というテキストオブジェクトにテキストを書き込む
            D.log("Fetch succeeded!!");
        } else {
            D.log('There was an error: ' + result.status);
            yeah.text = 'Error retrieving data';
        }
    });
}

// 顔を後ろに倒した時のイベントを登録
// すごく直感的なメソッド!!
FaceGestures.isLeanedBack(face).monitor().subscribe((e) => {
    if (e.newValue) {
        if (judgeOrder(3)){
            ikezakiSwitch[3] = true
            saaaay('warai2');
        } else {
            allReset()
        }
        yeah.hidden = false;
        fetch_neta(getNetaUrl('0004'));  // '0004'のセリフをDBから取ってくる
        // driver.start();
    } else {
        // driver.end();
        yeah.hidden = true;
    }
});

注意すべきは、2017/11/12現在で HTTPのGETしか使えないこと。本格的に通信するならば、websocket使えるといいんだどなー...
今回はこっちから値を渡してDBに格納するフローもあったので、ハッカソンでは GET でAPIを叩く→ 叩いたAPIでパラメータを渡すPOSTのAPI叩く→ 結果を返す という手段をとりました。こうすればCRUD処理を実装できますね(๑ᴖ◡ᴖ๑)

[Node-RED側の実装例] f:id:accelerk:20171114224318p:plain

まとめ以上!