AWS Lambda에서 음성 합성(OpenJTalk) 및 인코딩(ffmpeg)

탐구실 @junya108 입니다.
HameeAdventCalendar2016 의 21일째입니다.
AmazonDashButton을 샀기 때문에 버튼을 누르면 전기, 에어컨, TV 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

패키지를 업데이트하고 필요한 라이브러리를 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에 파일이 작성되는 것을 확인.



요약


  • 제대로 움직였다.
  • 메모리가 128M인 lambda 환경에서 50자(150byte)를 변환해 음성 합성으로 5000msec, 인코딩으로 1200msec 정도.
  • 계산상은 Amazon Polly보다 싸다.
  • zip 사이즈가 50M 넘어도 업로드 할 수 버린다.
  • 좋은 웹페이지 즐겨찾기