EmpathAPI × Reactで簡易実装

[Empath](https://webempath.com/jpn/)でApplication Engineerをしています。
Android Engineerと言っていたのですが、ここ最近Android以外をやることのほうが多く、Application Engineerと言うようにしてみました。

[Empath](https://webempath.com/jpn/)は音声感情解析AIというものを作っていて、詳しくはWebサイトから確認できます。

Reactとは書きましたが、そこまで深く触れないのであしからず。

#Empath APIとは
[Empath](https://webempath.com/jpn/)ではSDKとAPIを提供しており、そのうちのAPIはフリーで月300コールまで無料で使える手軽に試せるようになっています。
[(登録ページ)](https://webempath.net/lp-jpn/)

仕様に則ったwavファイルを投げると、感情解析結果がすぐに返ってくるという便利なものです。

仕様書は登録するとダウンロードできるので詳しくはそちらを確認してもらえるとよいです。
ざっくりとした仕様だけ書くと、下記のようになっています。

```
・ PCM WAVE形式、16bitであること
・ データサイズが1.9MB以下であること
・ フォーマットがPCM_FLOAT、PCM_SIGNED、PCM_UNSIGNED のいずれかであること
・ 録音時間が5.0秒未満であること
・ サンプリング周波数が11025Hzであること
・ チャンネル数が1(モノラル)であること 
```

#使用したもの
- Empath API(音声感情解析)
- React(JavaScript Library)
- axios(HTTPクライアント)
- Audacity(録音用)

##React
もはや説明のいらないほどのものとなりました。
Facebookが作ったJavaScriptのView Libraryです。
弊社でも取り入れているところもあります。
一応リンクだけ載せておきます。[React公式ページ](https://reactjs.org/)

今回はReactである必要は全くありませんが、自分自身が直近で使っていたので、そのまま環境等を使うためにReactにしただけです。
`とりあえずAPIの動作を見るだけ`であれば、環境設定は簡単なのでよい部分もあります。

##axios
PromiseベースのHTTPクライアントです。
[axios github](https://github.com/axios/axios)

##Audacity
弊社の音響エンジニアに教えてもらったソフトです。
今回API仕様に則った音声を録音するのに便利です。
[Audacity公式ページ](https://www.audacityteam.org/)

#セットアップ
##EmpathAPI
[登録ページ](https://webempath.net/lp-jpn/)にアクセスし、画面下部の[お申込みはこちら](https://webempath.net/sign_in)から新規登録をします。

利用規約や
<img width="983" alt="スクリーンショット 2019-04-11 11.41.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/396104/741ed6a7-a9d0-288d-c501-255505afed71.png">
個人情報取り扱い同意書をよく読み同意し
<img width="984" alt="スクリーンショット 2019-04-11 11.41.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/396104/23bfcf11-2505-ccee-fb8d-053ad4b65861.png">
次へ
メールとパスワードを設定します。
<img width="990" alt="スクリーンショット 2019-04-11 11.42.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/396104/8d6837db-7f50-34f9-3974-3a9e2cb3c387.png">
メールが届いたら、本登録をします。
先程設定したパスワードを入力します。
<img width="982" alt="スクリーンショット 2019-04-11 11.44.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/396104/381b3265-fea5-4c34-bcf1-c9a1d9d6e281.png">
必要情報を入力します。
<img width="984" alt="スクリーンショット 2019-04-11 11.45.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/396104/c65b58b5-0e2f-95eb-e5a1-31d1ff43a616.png">
プランを選びます。今回はフリープランの音声ファイルを保存するプランでいきます。
<img width="997" alt="スクリーンショット 2019-04-11 11.48.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/396104/4cfc398b-8b63-6de6-2126-9a1912fd5da8.png">
マイページが作成されるので、画面上からAPI Keyを発行します。
<img width="1013" alt="スクリーンショット 2019-04-11 12.30.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/396104/1e384d55-44bd-5ae9-0953-3328200aea0f.png">

APIの準備はこれで整いました。

##Audacity
アプリを使ってEmpathAPIに則ったwav形式で録音します。
本来はこの録音あたりも記事に書ければいいんですが、長くなるのでまたの機会にします。

アプリ起動後、このような画面になります。
画面左端に `音声トラック▼` とプルダウンであるので、こちらから仕様通りの録音フォーマット（11025Hz, PCM 16bit, モノラル）に変更します。
<img width="933" alt="スクリーンショット 2019-04-11 12.41.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/396104/a984c15a-0d2b-57bc-0304-ce7a6ccafac6.png">

この設定で5秒以下の音声を録音し、メニューからwavで書き出します。
解析用の音声はこちらを使います。

##React
公式が提供している簡易セットアップを使っていきます。Node.jsがインストール前提です。

###create-react-appをInstall
`npm install -g create-react-app`
このコマンドのみです。

###PJ作成
empath-testという名前でPJを作成します。`
create-react-app empath-test`
作成したディレクトリに移動し
`cd empath-test`
起動する
`npm start`
下記のようにお手軽に作成できます。
<img width="1440" alt="スクリーンショット 2019-04-11 10.37.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/396104/45913a2e-42a1-0fae-3037-c3931b42a136.png">

###Httpクライアントのインストール
axiosをインストールしておきます。
`npm install axios`
だけでOKです。

#実装
諸々準備が整いましたので、いよいよ実装していきます。
簡易版ですので、App.jsを書き換えていきます。

まずは取得したEmpathAPI keyと、URLをconstに置いておきます。

```js
const server = 'https://api.webempath.net/v2/analyzeWav';
const key = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
```

constractorにローカルStateを初期化します。
今回は保持するのはUploadするFileのみです。

```js
this.state = {
  file: undefined,
};
```

View周りはシンプルにします。
Fileを開くinputとAnalyzeを開始するButtonのみの配置です。

```html
  <input id="file"
    type="file"
    onChange={(e) => this.onChangeFile(e)} />

  <button onClick={this.handleClick.bind(this)}>
    Analyze
  </button>
```

実行すると下記のようにボタンが表示されました。
<img width="1440" alt="スクリーンショット 2019-04-11 14.03.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/396104/ae771c58-8d7a-f5a4-262d-989afd8cd24c.png">



ファイルを読み込まれたときのイベントは下記の様に処理し、ファイルをstateに保持します。

```js
  onChangeFile(e) {
    e.stopPropagation();
    e.preventDefault();
    var tmp = e.target.files[0];
    this.setState({ file: tmp });
  }
```

Analyzeボタンをクリックしたときのイベントにparam用のFormDataをセットします。

```js
var formData = new FormData(form);
    formData.append('apikey', key);
    formData.append('wav', this.state.file);
```

あとはaxiosで送るだけです。
結果はAlertで表示するだけです。

```js
   axios.post(server, formData, {
      headers: {
        'content-type': 'multipart/form-data',
      },
    }).then((res) => {
      var data = res.data;
      alert("(error" + data.error + ", calm:" + data.calm + ", anger:"
      + data.anger + ", joy:" + data.joy + ", sorrow:" + data.sorrow
      + ", energy" + data.energy + ")");
    }).catch(console.error);
```

実行します。
ファイル選択し、Analyzeボタンをクリックすると・・・

<img width="1440" alt="スクリーンショット 2019-04-11 14.03.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/396104/10d4de4e-d96f-cf73-2752-0f3c3fb97561.png">

結果が出ました。

>calm=>平常
>anger=>怒り
>joy=>喜び
>sorrow=>悲しみ
>energy=>元気度

が数値化されます。

元気度低いですね・・・
記事書き終わったところで休憩にしたほうがよさそうですね。。。