クラウドインテグレーションサービス「雲斗」のブログ

芝公園にある創研情報株式会社がAWS を 中心にクラウドの基本から便利な使いかたまでをお伝えしていきます。

Amazon Polly Amazon S3 AWS CLI AWS IAM AWS Lambda

カスタムAWS Lambdaランタイムで音声ファイルを生成・変換させてみる

2019/02/12

はじめに

ほぼ1年ぶりにブログ記事を書こうとAWSシンプルアイコン素材をダウンロードしたつもりがアーキテクチャアイコンに変更されていて、時の移り変わりを感じているプログラマA(50歳)です。

ローカルな話ですが、私の地元では各家庭に告知端末(IP-TV電話)が配布されており、自治会行事の告知をしたい場合など役場に画像/音声ファイルを持ち込むと地域限定で配信してくれたりします。

で、自治会の書記(小間使いの別名)である私はいつもAWSコンソールにログインして、AWS Pollyでテキストを音声に変換・ダウンロードして、音楽(フリー素材)をAudacityでくっつけて、音声レベルをノーマライズして...とかチマチマ音声ファイルを作ってたりする訳ですが、そろそろ自動化しないとなぁと考えておりました。

最初Amazon Elastic Transcoderを使えば楽勝かなと考えていたのですが、参考記事をひととおり読み、気が変わりました!!

せいぜい30秒かそこらの短い音声だし、(多分)Amazon Elastic Transcoderを使うまでもないのではないかと。まずはテキストから音声ファイルを生成し、WAV形式に変換するまでをカスタムAWS Lambdaランタイム/AWS CLI/FFmpegで実装する事にしました。

システムイメージ

システムイメージ

謝辞

この記事はカスタムAWS Lambdaランタイム(Lambda Layer)の作成手順について参考1.2の記事、AWS CLI Layer For AWS Lambda(以下awscli-lambda-layer)リポジトリのリソースを使用させていただきました。

利用するサービス、コマンド

AWS Lambda、Polly、IAM、S3、CLI、FFmpeg

全体の作業の流れ

  1. AWS CLIを実行するカスタムAWS Lambdaランタイム(Lambda Layer)を作成
  2. Lambda Layer上で動作するLambda関数(bashスクリプト)を作成

1. Lambda Layer作成

awscli-lambda-layerリポジトリのスクリプトを実行する環境としてWindows 10上のWindows Subsystem for Linux(以下WSL)/Ubuntu18.04を使用しました。

ローカル環境準備

WSL/Ubuntuで使用したコマンド・バージョン

コマンド バージョン 確認コマンド
git 2.17.1 git version
AWS CLI 1.16.90※ aws --version
soxi 14.4.2 soxi

※ AWS CLIは"aws lambda publish-layer-version"に対応したバージョンが必要です。

AWS CLIセットアップ後のaws configureはプロファイル指定なし(default)で実行します。

項目
AWS CLIプロファイル default
AWS環境準備

AWS環境を設定します。(後でスクリプトを実行する際、これらの値を引数として指定します。)以降の作業は全てWSL/Ubuntuコンソール上で実行します。

項目
IAMロール lambdaLayerBuilder
S3バケット pg-a-temp-kumoto

IAMロールlambdaLayerBuilderを作成し、 AmazonS3FullAccess、AWSLambdaBasicExecutionRoleポリシーをアタッチします。


[pg-a@kumoto]$ vi ./AssumeRoleLambda.json
[pg-a@kumoto]$ cat AssumeRoleLambda.json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "lambda.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
[pg-a@kumoto]$ aws iam create-role --role-name lambdaLayerBuilder --assume-role-policy-document file://./AssumeRoleLambda.json
{
    "Role": {
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Action": "sts:AssumeRole",
                    "Effect": "Allow",
                    "Principal": {
                        "Service": "lambda.amazonaws.com"
                    }
                }
            ]
        },
        "RoleId": "*********************",
        "CreateDate": "2019-01-**T**:**:**Z",
        "RoleName": "lambdaLayerBuilder",
        "Path": "/",
        "Arn": "arn:aws:iam::************:role/lambdaLayerBuilder"
    }
}
[pg-a@kumoto]$ for ARN in $(aws iam list-policies --query "Policies[?PolicyName==\`AmazonS3FullAccess\`||PolicyName==\`AWSLambdaBasicExecutionRole\`].Arn" --output text)
> do
>   aws iam attach-role-policy --role-name lambdaLayerBuilder --policy-arn $ARN
> done
[pg-a@kumoto]$ aws iam list-attached-role-policies --role-name lambdaLayerBuilder
{
    "AttachedPolicies": [
        {
            "PolicyName": "AmazonS3FullAccess",
            "PolicyArn": "arn:aws:iam::aws:policy/AmazonS3FullAccess"
        },
        {
            "PolicyName": "AWSLambdaBasicExecutionRole",
            "PolicyArn": "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
        }
    ]
}

S3バケットpg-a-temp-kumotoを作成します。
アクセスのステータスは"バケットとオブジェクトは非公開"としました。


[pg-a@kumoto]$ aws s3api create-bucket --bucket pg-a-temp-kumoto --create-bucket-configuration LocationConstraint=ap-northeast-1
{
    "Location": "http://pg-a-temp-kumoto.s3.amazonaws.com/"
}
[pg-a@kumoto]$ vi s3pubAccBlock.json
[pg-a@kumoto]$ cat s3pubAccBlock.json
{
    "IgnorePublicAcls": true,
    "BlockPublicPolicy": true,
    "BlockPublicAcls": true,
    "RestrictPublicBuckets": true
}
[pg-a@kumoto]$ aws s3api put-public-access-block --bucket pg-a-temp-kumoto --public-access-block-configuration file://./s3pubAccBlock.json
Lambda Layer作成スクリプト実行

awscli-lambda-layerの以下のスクリプトを実行し、AWS CLIを実行するためのLambda Layerを作成します。

  • 01.build_deploy.sh
  • 02.create_aws_layer.sh

本来は利用したいAWS CLIコマンドだけ抽出してLambda Layer化する使い方が想定されているようですが、今回は全コマンドを対象にします。
01.build_deploy.shはLambda環境にAWS CLIをインストール、展開後のコマンドをアーカイブしてS3にアップします。


[pg-a@kumoto]$ cd /mnt/c/temp
[pg-a@kumoto]$ git clone https://github.com/CM-Kajiwara/awscli-lambda-layer.git
...
[pg-a@kumoto]$ cd /mnt/c/temp/awscli-lambda-layer
[pg-a@kumoto]$ cp bootstrap bootstrap_org
[pg-a@kumoto]$ vi bootstrap
[pg-a@kumoto]$ diff bootstrap bootstrap_org
30c30
< aws s3 cp /tmp/provided${date}.tgz s3://${S3_BUCKET}/provided.tgz
---
>   aws s3 cp /tmp/provided${date}.tgz s3://${Bucket}/provided.tgz
[pg-a@kumoto]$ ./shell/01.build_deploy.sh lambdaLayerBuilder pg-a-temp-kumoto default
rm: cannot remove 'function.zip': No such file or directory
  adding: function.sh (stored 0%)
  adding: bootstrap (deflated 42%)
delete: s3://pg-a-temp-kumoto/provided.tgz
{
    "FunctionName": "layer-creater",
    "LastModified": "2019-01-**T**:**:**.038+0000",
    "RevisionId": "c8994255-3bd7-40a3-95ca-3cbebec3a4f9",
    "MemorySize": 256,
    "Environment": {
        "Variables": {
            "S3_BUCKET": "pg-a-temp-kumoto"
        }
    },
    "Version": "$LATEST",
    "Role": "arn:aws:iam::************:role/lambdaLayerBuilder",
    "Timeout": 900,
    "Runtime": "provided",
    "TracingConfig": {
        "Mode": "PassThrough"
    },
    "CodeSha256": "p9HuJ1RxoTS8yX4k9Jpyg57SD1du6X4+kwIQMlcbPP4=",
    "Description": "",
    "CodeSize": 1043,
    "FunctionArn": "arn:aws:lambda:ap-northeast-1:************:function:layer-creater",
    "Handler": "function.handler"
}
{
    "StatusCode": 202
}
[pg-a@kumoto]$ aws s3 ls s3://pg-a-temp-kumoto/provided.tgz
2019-01-** **:**:**    8696675 provided.tgz

02.create_aws_layer.shはアーカイブしたAWS CLIコマンドとbootstrapをマージしてLambda Layerとして登録します。(すでにVersionが4になってますが気にしないでください。)


[pg-a@kumoto]$ ./shell/02.create_aws_layer.sh pg-a-temp-kumoto default
Completed 256.0 KiB/8.3 MiB (195.3 KiB/s) with 1 file(s) remaining
...
  adding: bootstrap (deflated 39%)
{
    "Content": {
        "CodeSize": 10356445,
        "CodeSha256": "71hWnVS2I4znp0g2bdnFU1ILqSTpfVecH++J3snPdbs=",
        "Location": "https://awslambda-ap-ne-1-layers.s3.ap-northeast-1.amazonaws.com/snapshots/************/aws-cli-layer-..."
    },
    "LayerVersionArn": "arn:aws:lambda:ap-northeast-1:************:layer:aws-cli-layer:4",
    "Version": 4,
    "Description": "",
    "CreatedDate": "2019-01-**T**:**:**.428+0000",
    "LayerArn": "arn:aws:lambda:ap-northeast-1:************:layer:aws-cli-layer"
}
[pg-a@kumoto]$ aws lambda list-layer-versions --layer-name aws-cli-layer
{
    "LayerVersions": [
        {
            "LayerVersionArn": "arn:aws:lambda:ap-northeast-1:************:layer:aws-cli-layer:4",
            "Version": 4,
            "CreatedDate": "2019-01-**T**:**:**.428+0000"
        }
    ]
}
事後作業

Lambda Layerが正常に登録されたら04.delete_layer_creater.shでLambda関数を削除します。あわせてS3上のAWS CLIコマンドのアーカイブファイル、バケットを削除します。


[pg-a@kumoto]$ ./shell/04.delete_layer_creater.sh default
[pg-a@kumoto]$ aws s3 rm s3://pg-a-temp-kumoto --recursive
delete: s3://pg-a-temp-kumoto/provided.tgz
[pg-a@kumoto]$ aws s3api delete-bucket --bucket pg-a-temp-kumoto

2. Lambda関数作成

さて、ようやく本論のLambda関数です。。。面倒な処理はしていません。

  1. S3バケットへのテキストファイルPUTイベントにより起動
  2. Pollyを呼び出し、テキストファイルをPCM音声ファイルに変換
  3. FFmpegでPCM音声ファイルを読取り、変換してWAV音声ファイルを生成
  4. WAV音声ファイルをS3バケットにPUT

Lambda、S3、IAMの設定です。

項目
Lambda関数 tts-function
S3バケット g-a-tts-kumoto
テキストファイル格納先 src/
WAVファイル格納先 dst/
中間(PCM)ファイル格納先 tmp/
IAMロール lambdaTTS
AWS環境準備

まずはお約束のIAMロール、S3バケットの作成です。IAMロールlambdaTTSに、AmazonS3FullAccess、AWSLambdaBasicExecutionRole、AmazonPollyFullAccessポリシーをアタッチします。


[pg-a@kumoto]$ cd /mnt/c/temp
[pg-a@kumoto]$ aws iam create-role --role-name lambdaTTS --assume-role-policy-document file://./AssumeRoleLambda.json
{
    "Role": {
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Action": "sts:AssumeRole",
                    "Effect": "Allow",
                    "Principal": {
                        "Service": "lambda.amazonaws.com"
                    }
                }
            ]
        },
        "RoleId": "*********************",
        "CreateDate": "2019-01-**T**:**:**Z",
        "RoleName": "lambdaTTS",
        "Path": "/",
        "Arn": "arn:aws:iam::************:role/lambdaTTS"
    }
}
[pg-a@kumoto]$ for ARN in $(aws iam list-policies --query "Policies[?PolicyName==\`AmazonS3FullAccess\`||PolicyName==\`AWSLambdaBasicExecutionRole\`||PolicyName==\`AmazonPollyFullAccess\`].Arn" --output text)
> do
>   aws iam attach-role-policy --role-name lambdaTTS --policy-arn $ARN
> done
[pg-a@kumoto]$ aws iam list-attached-role-policies --role-name lambdaTTS
{
    "AttachedPolicies": [
        {
            "PolicyName": "AmazonS3FullAccess",
            "PolicyArn": "arn:aws:iam::aws:policy/AmazonS3FullAccess"
        },
        {
            "PolicyName": "AWSLambdaBasicExecutionRole",
            "PolicyArn": "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
        },
        {
            "PolicyName": "AmazonPollyFullAccess",
            "PolicyArn": "arn:aws:iam::aws:policy/AmazonPollyFullAccess"
        }
    ]
}

S3バケットpg-a-tts-kumotoを作成し、バケットの下にsrc/dst/tmpフォルダを作成します。アクセスのステータスは"バケットとオブジェクトは非公開"としました。


[pg-a@kumoto]$ aws s3api create-bucket --bucket pg-a-tts-kumoto --create-bucket-configuration LocationConstraint=ap-northeast-1
{
    "Location": "http://pg-a-tts-kumoto.s3.amazonaws.com/"
}
[pg-a@kumoto]$ aws s3api put-public-access-block --bucket pg-a-tts-kumoto --public-access-block-configuration file://./s3pubAccBlock.json
...

[pg-a@kumoto]$ aws s3api put-object --bucket pg-a-tts-kumoto --key src/
[pg-a@kumoto]$ aws s3api put-object --bucket pg-a-tts-kumoto --key dst/
[pg-a@kumoto]$ aws s3api put-object --bucket pg-a-tts-kumoto --key tmp/
FFmpegダウンロード

FFmpegを用意します。依存ファイルをケアするのが大変なので今回はStaticリンクバージョンのFFmpegをダウンロードしてきます。


[pg-a@kumoto]$ cd /mnt/c/temp
[pg-a@kumoto]$ wget https://johnvansickle.com/ffmpeg/builds/ffmpeg-git-amd64-static.tar.xz
--2019-01-** **:**:**--  https://johnvansickle.com/ffmpeg/builds/ffmpeg-git-amd64-static.tar.xz
...
2019-01-** **:**:** (393 KB/s) - ‘ffmpeg-git-amd64-static.tar.xz’ saved [33512956/33512956]

[pg-a@kumoto]$ openssl dgst -md5 ffmpeg-git-amd64-static.tar.xz
MD5(ffmpeg-git-amd64-static.tar.xz)= a06edad9ed3ac1138fe15e6b39ab7c51

[pg-a@kumoto]$ curl https://johnvansickle.com/ffmpeg/builds/ffmpeg-git-amd64-static.tar.xz.md5
a06edad9ed3ac1138fe15e6b39ab7c51  ffmpeg-git-amd64-static.tar.xz
[pg-a@kumoto]$ tar Jxfv ffmpeg-git-amd64-static.tar.xz
ffmpeg-git-20190114-amd64-static/
...

[pg-a@kumoto]$ ffmpeg-git-20190114-amd64-static/ffmpeg -version
ffmpeg version N-47984-g301cee61fa-static https://johnvansickle.com/ffmpeg/  Copyright (c) 2000-2019 the FFmpeg developers
built with gcc 6.3.0 (Debian 6.3.0-18+deb9u1) 20170516
configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --disable-ffplay --disable-indev=sndio --disable-outdev=sndio --cc=gcc-6 --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gmp --enable-gray --enable-libaom --enable-libfribidi --enable-libass --enable-libvmaf --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librubberband --enable-libsoxr --enable-libspeex --enable-libvorbis --enable-libopus --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libdav1d --enable-libxvid --enable-libzvbi --enable-libzimg
libavutil      56. 25.100 / 56. 25.100
libavcodec     58. 43.101 / 58. 43.101
libavformat    58. 25.100 / 58. 25.100
libavdevice    58.  6.101 / 58.  6.101
libavfilter     7. 48.100 /  7. 48.100
libswscale      5.  4.100 /  5.  4.100
libswresample   3.  4.100 /  3.  4.100
libpostproc    55.  4.100 / 55.  4.100
デプロイパッケージ準備

03.deploy_lambda.shはデプロイパッケージを生成し、Lambda関数を作成するためのスクリプトです。デプロイパッケージ生成元フォルダに関数本体やFFmpeg等を配置します。

デプロイパッケージファイル構成

├──function.sh・・・Lambda関数本体
├──argparser.js・・・パラメータ(S3からのイベントデータ)のパーサ
├──ffmpeg・・・FFmpegコマンド

■ PCM->WAV変換仕様 ■

形式 Sample Rate Bit Depth channel エンディアン
PCM 16000 符号付き16 1 リトル
WAV 44100 符号付き16 2 リトル

[pg-a@kumoto]$ cd /mnt/c/temp/awscli-lambda-layer/include-aws-cli
[pg-a@kumoto]$ vi function.sh
[pg-a@kumoto]$ cat function.sh
function handler () {
        EVENT_DATA=$1

        S3_EVENT=$(node $LAMBDA_TASK_ROOT/argparser.js "$EVENT_DATA")
        S3_BUCKET=$(echo $S3_EVENT | cut -d' ' -f1)
        S3_SRC_PATH=$(echo $S3_EVENT | cut -d' ' -f2)
        FILE_NAME=$(echo $S3_SRC_PATH | cut -d/ -f2)

        LAMBDA_TEXT_FILE="$(mktemp)"
        aws s3 cp s3://${S3_BUCKET}/${S3_SRC_PATH} ${LAMBDA_TEXT_FILE}

        LAMBDA_PCM_FILE="$(mktemp)"
        aws polly synthesize-speech --output-format pcm --sample-rate 16000 --text-type text --text "$(cat ${LAMBDA_TEXT_FILE})" --voice-id Mizuki --language-code ja-JP ${LAMBDA_PCM_FILE}
        S3_PCM_FILE=s3://${S3_BUCKET}/tmp/${FILE_NAME}.pcm
        aws s3 cp ${LAMBDA_PCM_FILE} ${S3_PCM_FILE}

        LAMBDA_WAV_FILE="$(mktemp).wav"
        $LAMBDA_TASK_ROOT/ffmpeg -y -f s16le -ar 16000 -ac 1 -i ${LAMBDA_PCM_FILE} -ar 44100 -ac 2 ${LAMBDA_WAV_FILE}

        S3_WAV_FILE=s3://${S3_BUCKET}/dst/${FILE_NAME}.wav
        aws s3 cp ${LAMBDA_WAV_FILE} ${S3_WAV_FILE}

        RESPONSE="upload: '$S3_WAV_FILE'"

        echo $RESPONSE
}

[pg-a@kumoto]$ vi argparser.js
[pg-a@kumoto]$ cat argparser.js
var obj = JSON.parse(process.argv[2]);
process.stdout.write(obj.Records[0].s3.bucket.name+" "+obj.Records[0].s3.object.key);

[pg-a@kumoto]$ mv ../../ffmpeg-git-20190114-amd64-static/ffmpeg .

関数コードの説明

S3からのイベントデータはJSON形式ですが、Lambda環境にはデフォルトでNode.jsランタイムが用意されているのでjsコードで手っ取り早くパースして、バケット・キーを取り出します。

FFmpegの出力先WAVファイル名は".wav"で終わる必要があるらしいです。mktempで作成した拡張子のままだと"Unable to find a suitable output format for '/tmp/tmp.hzosA2AYdb'"のようなエラーが出て変換してくれませんでした。(要調査)

デプロイパッケージアップロード

03.deploy_lambda.shによりLambda関数を作成します。以下2点についてスクリプトをカスタマイズ後に実行します。

  • デプロイパッケージにモジュール追加
  • タイムアウト時間を延長(30秒だとギリギリ)

[pg-a@kumoto]$ cd /mnt/c/temp/awscli-lambda-layer/shell
[pg-a@kumoto]$ cp 03.deploy_lambda.sh 03.deploy_lambda.sh.org
[pg-a@kumoto]$ vi 03.deploy_lambda.sh
[pg-a@kumoto]$ diff 03.deploy_lambda.sh 03.deploy_lambda.sh.org
14c14
< zip function.zip -j ./include-aws-cli/ffmpeg ./include-aws-cli/function.sh ./include-aws-cli/argparser.js
---
> zip function.zip -j ./include-aws-cli/function.sh
22c22
< --timeout 900 \
---
> --timeout 30 \

[pg-a@kumoto]$ cd /mnt/c/temp/awscli-lambda-layer
[pg-a@kumoto]$ ./shell/03.deploy_lambda.sh tts-function lambdaTTS default
  adding: ffmpeg (deflated 66%)
  adding: function.sh (deflated 53%)
  adding: argparser.js (deflated 18%)
{
    "Layers": [
        {
            "CodeSize": 10356445, 
            "Arn": "arn:aws:lambda:ap-northeast-1:************:layer:aws-cli-layer:4"
        }
    ], 
    "FunctionName": "tts-function", 
    "LastModified": "2019-01-**T**:**:**.875+0000",
    "RevisionId": "d2f99d89-19df-447a-9952-485ff80e7afa", 
    "MemorySize": 128, 
    "Version": "$LATEST", 
    "Role": "arn:aws:iam::************:role/lambdaTTS", 
    "Timeout": 900, 
    "Runtime": "provided", 
    "TracingConfig": {
        "Mode": "PassThrough"
    }, 
    "CodeSha256": "pEQux/F1dHDJw2xKoUmiE7SJkYvTfHyx4d++yT11uwM=", 
    "Description": "", 
    "CodeSize": 24338621, 
    "FunctionArn": "arn:aws:lambda:ap-northeast-1:************:function:tts-function",
    "Handler": "function.handler"
}

S3バケットへのファイルPUTイベントによるLambda関数の起動を設定します。srcフォルダのみを対象とするようプレフィックスを指定します。


[pg-a@kumoto]$ aws lambda add-permission --function-name tts-function --statement-id "s3-put-event" --action "lambda:InvokeFunction" --principal "s3.amazonaws.com" --source-arn "arn:aws:s3:::pg-a-tts-kumoto"
{
    "Statement": "{\"Sid\":\"s3-put-event\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"s3.amazonaws.com\"},\"Action\":\"lambda:InvokeFunction\",\"Resource\":\"arn:aws:lambda:ap-northeast-1:************:function:tts-function\",\"Condition\":{\"ArnLike\":{\"AWS:SourceArn\":\"arn:aws:s3:::pg-a-tts-kumoto\"}}}"
}
[pg-a@kumoto]$ vi notification.json
[pg-a@kumoto]$ cat notification.json
{
  "LambdaFunctionConfigurations": [
    {
      "LambdaFunctionArn": "arn:aws:lambda:ap-northeast-1:************:function:tts-function",
      "Filter": {
        "Key": {
          "FilterRules": [
            {
              "Name": "Prefix",
              "Value": "src/"
            }
          ]
        }
      },
      "Events": [
        "s3:ObjectCreated:Put"
      ]
    }
  ]
}
[pg-a@kumoto]$ aws s3api put-bucket-notification-configuration --bucket "pg-a-tts-kumoto" --notification-configuration file://./notification.json

検証

srcフォルダにテキストファイルをPUTし、dstフォルダにWAVファイルができあがるのを待ちます。所要時間は文字数が8文字でも1000文字でもそれほど変わらず、30秒前後でした。


[pg-a@kumoto]$ cd /mnt/c/temp
[pg-a@kumoto]$ echo "日本語メッセージ" > msg.txt
[pg-a@kumoto]$ aws s3 cp msg.txt s3://pg-a-tts-kumoto/src/msg.txt
upload: ./msg.txt to s3://pg-a-tts-kumoto/src/msg.txt
[pg-a@kumoto]$ aws s3 ls s3://pg-a-tts-kumoto/dst/msg.txt.wav
2019-01-** **:**:**     214242 msg.txt.wav

WAVファイルが期待する形式になっていることを確認します。


[pg-a@kumoto]$ aws s3 cp s3://pg-a-tts-kumoto/dst/msg.txt.wav msg.wav
download: s3://pg-a-tts-kumoto/dst/msg.txt.wav to ./msg.wav
[pg-a@kumoto]$ soxi msg.wav

Input File     : 'msg.wav'
Channels       : 2
Sample Rate    : 44100
Precision      : 16-bit
Duration       : 00:00:01.21 = 53541 samples = 91.0561 CDDA sectors
File Size      : 214k
Bit Rate       : 1.41M
Sample Encoding: 16-bit Signed Integer PCM

まとめ

「カスタムAWS Lambdaランタイム」便利です。これまでであれば、Lambdaが対応していないランタイムがあればEC2で対応、という流れだったと思うのですが、(Amazon)Linuxについてはそれが不要になってしまいました。15分以内に完結する処理であればLambda「が」良いです。

依存する共有ライブラリを意識しなければならず、どんなコマンドでも簡単にLambdaに持ち込める訳ではないですが、発表されたばかりの技術ですので、今後出てくるであろうベストプラクティスに期待です。

(いちばん最初の話に戻ると、サービスを考える立場の人間から言わせれば、ホントは役場の配信システムがAPI公開してくれればLambdaと連携するシステムも簡単に作れそうなのですが、なかなかそこまで一足飛びには行かないものです...。)



参考

  1. AWS Lambda Custom RuntimesでAWS CLIを動かした。#reinvent
  2. AWS CLI Layer For AWS Lambda(awscli-lambda-layer)
  3. RUNNING FFMPEG ON AWS LAMBDA FOR 1.9% THE COST OF AWS ELASTIC TRANSCODER

-Amazon Polly, Amazon S3, AWS CLI, AWS IAM, AWS Lambda

Bitnami