LoginSignup
9
8

More than 5 years have passed since last update.

AWS Lambdaで音声合成(OpenJTalk)&エンコード(ffmpeg)

Last updated at Posted at 2016-12-20

探求室の@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に保存して見る。

exports.js
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にファイルが作成されることを確認。

スクリーンショット 2016-12-21 7.54.33.jpg

まとめ

  • ちゃんと動いた。
  • メモリが128Mのlambda環境で50文字(150byte)を変換して音声合成で5000msec,エンコードで1200msecぐらい。
  • 計算上はAmazon Pollyよりも安い。
  • zipサイズが50M超えてもアップロード出来ちゃう。
9
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
8