Pixi.jsとgetUserMediaとneume.jsを使って簡単なFirefox OSアプリを作ってみた。

# Pixi.jsとgetUserMediaとneume.jsを使って簡単なFirefox OSアプリを作ってみた。

![image](http://img.dfm.lrv.jp/camsounder/camsounder.png)

[以前、Open Web Boardを使ってFirefox OSアプリを作ってみた](http://qiita.com/tadfmac/items/eaf2d1b31f18936532b9)のですが、さすがに3ヶ月も触ってないとすっかり忘れましたw

が、今度は[flame](http://www.mozilla.jp/firefox/os/devices/flame/)が手に入ったので、またちょっとやってみることに。

で、ただHello World作るだけでは面白くないので、他にやりたいと思ってたことと混ぜこぜで、

1. getUserMediaを使ってみる（特権必要だと！？）
2. Pixi.jsのv2を使ってみる（Retina対応簡単になったと言うので！）
3. neume.jsで音を出してみる（ついにWeb Audioだぁ！）

という実験をやってみました。

## カメラ入力から音出すやつ

いろいろテキトーですが、こんな感じのになりました。

![cam1](http://img.dfm.lrv.jp/camsounder/img1.png)

コードは↓

[tadfmac/camsounder(github)](https://github.com/tadfmac/camsounder)

処理の流れはこんな感じ。

![flow](http://img.dfm.lrv.jp/camsounder/img2.png)

ここでは、これを作ってみて気づいたことなどを書いてみたいと思います。

## 1. getUserMediaを使ってみる

Firefox OSでは、[Camera API](https://developer.mozilla.org/ja/docs/Web/API/Camera_API)も利用可能なので、使ってみたい気もしたのですが、今回はWebアプリからの移植が簡単な`getUserMedia`を使うことにしました。まー簡単だし。

で、`getUserMedia`なんて、今までに何度か書いたのでコピペで動くだろうとお思ったら動かない。
`Camera Error`とか表示される。なにごと！？と思い調べてみると、

[](https://developer.mozilla.org/ja/docs/Web/API/Navigator/getUserMedia)に、下記説明があります。

> パーミッション
> getUserMedia をインストール型のアプリ (Firefox OS アプリなど) で利用する場合には、マニフェストファイルへ以下のように記述する必要があります。

なんてコト！w

というわけで、`manifest.webapp`に、パーミッションを追加する必要があるようです。

```
"permissions": {
  "video-capture": {
    "description": "Required to capture video via getUserMedia"
  }
}
```

こんな感じで。（MDNの例は"audio-capture"になってますが、今回はカメラなので"video-capture"にします）


### 余談：パフォーマンスチューニングしたいが。。。

パーミッション設定することでgetUserMediaでビデオキャプチャできるようになったのですが、flameだと正直遅い！
今回、たった8×8のピクセルしか要らないのに！サイズとフレームレート落としたい！

。。。。というのが、ChromeだとgetUserMedia()のパラメータ指定で出来るのですが、、、

[getUserMedia() video size in Firefox & Chrome differs](http://stackoverflow.com/questions/26415778/getusermedia-video-size-in-firefox-chrome-differs)

```js
var vid_constraints = {
    mandatory: {
        maxHeight: 180,
        maxWidth: 320
    }
}
var constraints = { audio: false, video: vid_constraints };
navigator.getUserMedia(constraints, successCallback, errorCallback);
```

こんな感じで。

しかしコレ、残念ながらFirefoxだとできない！

というわけで、他のところで妥協するしかありません。。。
Firefox早く対応して欲しい。。。。

## 2. Pixi.js v2のRetina対応

次はPixi.jsを使ったRetina対応です。

2倍固定でちょっと乱雑ですが、flameでは下記のように書けば問題なかったです。
最初にレンダラーを作る部分で、`resolution`オプションを指定するだけです。

```.js
var width = window.innerWidth;
var height = window.innerHeight;
var renderer = PIXI.autoDetectRenderer(width, height,{resolution:2});
```

これは簡単でした！

## 3. neume.jsでWeb Audioに対応してみる

実は、ここで少しハマりました。
neume.jsの使い方自体は、ちょっと音だすくらいなら非常によくできていて簡単なんですが！
（というか、今回は[ココ](http://qiita.com/tadfmac/items/3f0ca0d0ce021a75fd67)にも書いた[一番簡単そうなサンプル「metronome.html」](https://github.com/mohayonao/neume.js/blob/master/examples/metronome.html)をほとんどそのまま使ってるので間違えようがないw！）

しかし最初、パッケージアプリを作ってflameに入れるとなぜか`neume.js`が鳴ってくれないのです。
Webサイトに置くと鳴ります。ここでしばらく悩みました。

どうやら、`manifest.webapp` を下記のように書いてるとダメなようです。

```manifest.webapp
	:
  "type":"privileged",
  	:
```

今回、`getUserMedia`を使う関係で、`"permissions"`を指定する必要があったので、`"type":"privileged"`にしないと駄目と勘違いしてました。
(実際は`getUserMedia`を使うだけなら、`"type":"privileged"`にする必要はない)

どうやら、`"type":"priviledged"`にすると、アプリのCSP(Content Security Policy)が厳しくなるようです。

> 参考：[アプリの CSP (MDN)](https://developer.mozilla.org/ja/Apps/CSP)

結果としては、下記のように修正して動きました。

```manifest.webapp
	:
  "type":"web",
  	:
```

> 本当に`"type":"priviledged"`が必要な機能と併用したい時は、どーすればいいんでしょうね。。。というのは謎のままです。

# 思ったより動くじゃん。という印象。

Flameって最近のiPhoneやAndroidと比べると世代前感なスペックではあるのですが、思ったよりOS軽くて、やってみると結構動くもんですね。

BluetoothなどプラットフォームAPIが沢山使えるのも面白そうだし。
今後も時間を見て触ってみようと思います。flameいいオモチャw