[node.js]WebsocketとAquesTalkでゆっくりボイスのチャットをつくろう[AWS]

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

EC2でゆっくりさせる

定期的にポストされるゆっくりネタです。

以前、node.jsからゆっくろいどにアクセスしてしゃべらせるという記事を書きました。
node.jsから指定した文言をゆっくりさせることができるのですが、ローカルでしゃべるだけなので自分しかゆっくりできません。
せっかくならWebアプリで誰でもつかえるようにできないかなぁと思っていたら、それに近いことをやってる人がいました。
これはすごい。便乗するしかありません。
今回はEC2でnodeサーバをたてて、誰でもゆっくりできるようなアプリを作ってみましょう。

環境構築方法

今回使用した動作環境は以下のとおりです。

  • OS : MacOS X 10.7.5
  • EC2 : Amazon Linux
  • ブラウザ : Chrome26

ゆっくりサーバはEC2上で作成します。EC2インスタンスを起動し、sshポートと3000番ポートを開けておきましょう。

作成するアプリの機能

EC2上で動くチャットアプリをnode.jsで作成します。
アプリ画面でテキスト入力を行うと、その文言をAquesTalkでwav化して再生します。
また、Websocketでその画面を見ている人全員にwavを再生させるようにします。
チャットで入力した文字、誰かが入力した文字がゆっくりボイスで全部再生されるわけですね。
yukkurichat1

1.ゆっくりボイス出力モジュールを作成する

まずはEC2上に、AquesTalk2を使って、任意の文字をゆっくりボイスでwavファイルとして出力するプログラムを作成しましょう。
作成するための手順が全部ここにあります。
ここを参考にして(というかほぼそのまま)、wav出力モジュールを作成します。

AquestTalkの設定

まずはゆっくりボイスを作成するためのAquesTalk2(評価版)を取得し、所定の場所にライブラリをコピーします。
ldconfigでライブラリを参照できるようにするのを忘れないようにしましょう。

% wget http://www.a-quest.com/download/package/aqtk2-lnx-eva_230.zip
% unzip aqtk2-lnx-eva_230.zip
% cd aqtk2-lnx-eva_230
% sudo cp lib64/libAquesTalk2Eva.so.2.3 /usr/lib64/
% sudo ln -sf /usr/lib64/libAquesTalk2Eva.so.2.3 /usr/lib64/libAquesTalk2Eva.so.2
% sudo ln -sf /usr/lib64/libAquesTalk2Eva.so.2 /usr/lib64/libAquesTalk2Eva.so
% sudo /sbin/ldconfig -n /usr/lib64

本記事では、AquesTalk2の評価版を使用しています。
※評価版は「ナ行、マ行」の音韻がすべて「ヌ」になるという制限があります
ライセンスや使用方法等の詳細はパッケージ付属のソフトウェア利用許諾契約書をご確認の上で使用してください。

wav出力モジュールはAquesTalk2ライブラリを参照し、C言語で作成する必要があります。
g++とかでコンパイルするので、必要パッケージをyumでインストールしておきましょう。
次のようにyumを実行すれば、必要なソフトウェアが全てインストールされます。

% sudo yum groupinstall "Development Tools"

wav出力モジュール作成

ダウンロードしたAquestTalk2のパッケージには、そのまま動作するサンプルが附属しています。
今回はそのサンプルをベースにします。aqtk2-lnx-eva/samplesディレクトリにあるサンプルファイルをコピーし、それを少し修正して使用しましょう。
※MyTalk.cというファイル名にして使用
ここにあるモジュールと同じように、下記のようにプログラムに修正します。

#include #include #include #include #include #include "AquesTalk2.h"

void * file_load(const char * file, int * psize);

//まんま参考サイトのプログラムです int main(int argc, char **argv){ int size; char message[1024];

// 音声記号列を入力 if(fgets(message, 1024-1, stdin) == 0) return 0;

// Phont ファイルの読み込み void *pPhont = file_load("aq_yukkuri.phont", &size); if(pPhont == 0) return -2;

// メモリ上に音声データを生成 unsigned char *wav = AquesTalk2_Synthe_Utf8(message, 100, &size, pPhont); if(wav == 0) { fprintf(stderr, "ERR %d", size); return -1; }

// Phont データの開放(音声合成が終わったら開放できる) free(pPhont);

// 生成した音声データを保存 fwrite(wav, 1, size, stdout);

// Synthe()で生成した音声データは、使用後に呼び出し側で解放する AquesTalk2_FreeWave(wav); return 0; }

// ファイルの読み込み void * file_load(const char * file, int * psize){ FILE *fp; char *data; struct stat st; *psize = 0;

if(stat(file, &st) != 0) return NULL;

if((data = (char *)malloc(st.st_size)) == NULL){ fprintf(stderr, "can not alloc memory(file_load)\n"); return NULL; }

if((fp = fopen(file, "rb")) == NULL) { free(data); perror(file); return NULL; }

if(fread(data, 1, st.st_size, fp) < (unsigned)st.st_size) { fprintf(stderr, "can not read data (file_load)\n"); free(data); fclose(fp); return NULL; } fclose(fp); *psize = st.st_size; return data; } [/c]

ソースファイルを記述したら、ヘッダファイルをsamplesディレクトリへコピーし、g++でコンパイルします。
コンパイルするときはAquesTalk2Evaライブラリの指定を忘れずに。

% cd /home/ec2-user/aqtk2-lnx-eva/samples
% cp ../lib64/AquesTalk2.h ./
% g++ -o MyTalk MyTalk.c -lAquesTalk2Eva

MyTalkモジュールができたら、webアプリから使用する場所へコピーします。( /home/ec2-user/yukkuriディレクトリを使用)
ゆっくりボイスで出力させるためには、aq_yukkuri.phontファイルも必要なので、それもいっしょにコピーします。

% mkdir /home/ec2-user/yukkuri
% cp MyTalk /home/ec2-user/yukkuri/
% chmod -R 775 /home/ec2-user/yukkuri/
% cp ../phont/aq_yukkuri.phont /home/ec2-user/yukkuri

MyTalkモジュールの動作確認

モジュールは単体でも動作するので、ちゃんとゆっくりボイスwavが出力されるかためしてみましょう。
下記コマンドを実行すれば、wavファイルが生成されます。

% cd /home/ec2-user/yukkuri/
% sudo sh -c "echo 'こんにちわゆっくりです。' | sudo ./MyTalk > yukkuri.wav"

scpか何かで適当にダウンロードして確認してみてください。なんか微妙に声が違うような気がするけど気にしない。

2.nodeでチャットアプリを作成する

ゆっくりwavを出力するモジュールができたので、あとはチャットアプリを作成すればOKです。
まずはnodeをインストールしましょう。nodeのバージョンはv0.10.6を使用しました。

% wget -N http://nodejs.org/dist/node-latest.tar.gz
% tar -xzvf node-latest.tar.gz
% cd node-v0.10.6/
% make
% sudo make install

アプリの取得方法

次は、yukkuri-serverアプリを作成します。
とりあえずこのEC2サーバに配置したい場合、githubにアプリをupしてあるので、それをcloneしてください。
※やっつけで作ったのでいろいろ注意
cloneしたらnpmで必要モジュールをインストールしましょう。

% cd /home/ec2-user
% git clone https://github.com/nakamura-shuta/yukkuri-server.git
% cd yukkuri-server
% npm install 

自分のEC2環境で動かしたい場合、public/javascripts/yukkuri.ksで定義しているhost変数の値を、自分が使用するアドレスにしてください。

アプリのポイント

画面から入力された文字をMyTalkモジュールに渡してwavにする箇所も、ここにあるプログラムの応用です。
wavにしたい文言をハッシュ化してファイル名とし、child_process#execを使ってnodeからMyTalkモジュールを呼んでいます。(routes/index.js)
出力されたwavはpublic/mediaディレクトリに出力され、そのurlがWebsocketで配信された後、各クライアントがwavを再生します。

動作確認

アプリを起動し、ブラウザでEC2にアクセスしてみてください。

% node app.js

複数人でアクセスして、入力した文字がそれぞれのマシンで再生されるのを確認してみてください。(同じマシンだとわかりづらいかも)
ゆっくりボイスが入り乱れるカオスなチャットが展開されます。
なお、アプリはとりあえず動くものを作ったので、問題が多々あるかと思いますが見なかったことに。

まとめ

さて、今回はゆっくりボイスでのチャットを作ってみました。
最初はそのまま動くAMIを用意しようかと思ったんですが、AquestTalkの再配布にライセンス的問題がありそうだったのでやめました。
手順はそんなに複雑なものではないので、この記事と参考サイトを見ればできると思います。
文字をそのままwav化するAquestTalkとWebSocket、Audioを組み合わせることで、なかなかおもしろい機能ができました。
最近弊社で流行っている、Twilioと組み合わせても、いろいろとユニークなことができるかもしれませんね。

参考サイトなど