探求室の@junya108です。
HameeAdventCalendar2016の21日目です。
AmazonDashButtonを買ったのでボタンを押したら電気、エアコン、テレビetc.が全部つくボタンの記事にしようと思ってたけど、変更。
先日、リリースされたAmazon Pollyを試して感じた問題点を解決してみたいと思います。
#Amazon Pollyの問題点
喋りも滑らかで日本語にも対応している点は非常に良いのですが、声色がイマイチ。
#解決策
lambda上で音声合成やエンコードをやって声色の自由度を増やしてみようと思います。
#やることのまとめ
今回は音声合成にはopenjtalk、エンコードにはffmpegを利用します。
これをamazon linuxでコンパイルしてlambdaにアップロードしてテスト実行。という感じです。
#音声合成
macを新調したばかりでdockerが入ってなかったので、まずは、docker for macをインストール。
amazonlinuxのイメージをpullしてrun。
lambdaの実行環境よりもdockerイメージが新しいけど大丈夫かな。
$ docker pull amazonlinux:2016.09
$ docker run -i -t amazonlinux:2016.09 /bin/bash
パッケージをupdateして、必要なライブラリをinstall。
bash-4.2# yum update -y
bash-4.2# yum install gcc44 gcc-c++ libgcc44 cmake wget git aws-cli autoconf automake libtool npm epel-release yasm -y
hts_engine_APIをコンパイル&インストール
bash-4.2# cd /tmp
bash-4.2# wget http://downloads.sourceforge.net/hts-engine/hts_engine_API-1.08.tar.gz
bash-4.2# tar zxvf hts_engine_API-1.08.tar.gz
bash-4.2# cd hts_engine_API-1.08
bash-4.2# ./configure
bash-4.2# make
bash-4.2# make install
OpenJTalkをコンパイル&インストール
bash-4.2# wget http://downloads.sourceforge.net/open-jtalk/open_jtalk-1.07.tar.gz
bash-4.2# tar zxvf open_jtalk-1.07.tar.gz
bash-4.2# cd open_jtalk-1.07
bash-4.2# ./configure --with-charset=UTF-8
bash-4.2# make
bash-4.2# make install
#エンコード
必要なコーデックをinstall
bash-4.2# mkdir /usr/local/src/ffmpeg_sources
bash-4.2# cd /usr/local/src/ffmpeg_sources
bash-4.2# git clone --depth 1 git://git.code.sf.net/p/opencore-amr/fdk-aac
bash-4.2# cd fdk-aac
bash-4.2# autoreconf -fiv
bash-4.2# ./configure --prefix="/usr/local/src/ffmpeg_build" --disable-shared
bash-4.2# make
bash-4.2# make install
ffmpegをコンパイル&インストール
bash-4.2# cd /usr/local/src/ffmpeg_sources
bash-4.2# git clone --depth 1 git://source.ffmpeg.org/ffmpeg
bash-4.2# cd ffmpeg
bash-4.2# PKG_CONFIG_PATH="/usr/local/src/ffmpeg_build/lib/pkgconfig" ./configure --enable-static --disable-shared --prefix="/usr/local/src/ffmpeg_build" --extra-cflags="-I/usr/local/src/ffmpeg_build/include" --extra-ldflags="-L/usr/local/src/ffmpeg_build/lib" --bindir="/usr/local/src/bin" --enable-gpl --enable-nonfree --enable-libfdk_aac
bash-4.2# make
bash-4.2# make install
#lambdaで動かしてみる
テストでテキストを音声変換して、aacにエンコードしてS3に保存して見る。
var AWS = require('aws-sdk');
var s3 = new AWS.S3({apiVersion: '2006-03-01'});
var https = require('https');
var fs = require('fs');
var OpenJTalk = require('openjtalk');
exports.myHandler = function(event, context, callback) {
var voice = new OpenJTalk({htsvoice: './node_modules/openjtalk/voice/mei/mei_happy.htsvoice'});
voice._makeWav('未来はいつも面白い。',0,function(err,result){
var cmd = './ffmpeg -i "' + '/tmp/'+result.wav + '" -vn -ac 2 -ar 44100 -ab 128k -acodec libfdk_aac -f mp4 "'+ '/tmp/'+result.wav +'.m4a"';
var exec = require('child_process').exec;
var child = exec(cmd, function(error, stdout, stderr) {
var audioFileName=result.wav + '.m4a';
var s3Params = {
ACL: 'public-read',
Bucket: {BUCKET_NAME},
Key: audioFileName,
Body: new Buffer(fs.readFileSync('/tmp/'+audioFileName))
};
s3.putObject(s3Params, function(err, data) {
callback(null, 'Success!');
};
});
});
};
これと、node_modulesとコンパイルしたopenjtalk,ffmpegをzipでまとめる。
ここで問題発生。。ファイルサイズが60M超。。
lambdaの制限によると、lambdaで動かせるのはzipのサイズは50Mまで。
削減できそうなファイルを整理してもまだ50M超えてる。。
とりあえず、制限超えてるけど、S3にアップロードしてlambdaに登録して見る。
なんと!
怒られない、登録できちゃう。
テストしてみてちゃんとS3にファイルが作成されることを確認。
#まとめ
- ちゃんと動いた。
- メモリが128Mのlambda環境で50文字(150byte)を変換して音声合成で5000msec,エンコードで1200msecぐらい。
- 計算上はAmazon Pollyよりも安い。
- zipサイズが50M超えてもアップロード出来ちゃう。