概要
- Amazon Connectには留守番電話機能は無いため個別に作成する。
- 基本の考え方等は『[Amazon Connect]営業時間外に着信したビジネスチャンスを失わないように留守番電話機能をつけてみた』をもとにしています。
- ここまで作成すると、留守番電話で受け付けた音声がWAV形式でS3に保存されます。
使用ユーザー
- IAMユーザー
手順
WAVデータを保存するS3の作成
AWSにサインインします。
- アカウント、ユーザー名、パスワードを入力してサインインします。
アカウント内(IAM)で作成したユーザーを使用してコンソールにサインインする
- アカウント、ユーザー名、パスワードを入力してサインインします。
『AWSマネジメントコンソール』画面にある「サービスを検索」にS3と入力し、検索結果から《S3》をクリックし、Amazon S3 コンソール(https://console.aws.amazon.com/s3/)を開きます。
![image.png]()
S3のバケット一覧が表示されるので、営業時間の判断で作成したバケットをクリックします。
![image.png]()
- フォルダ名:フォルダの名前
- 暗号化:適宜必要な暗号化設定を選択
Lambdaでebmlを利用するための準備
Node.jsをインストールする
- 詳細は、Windows 10へNode.jsをインストールするを参照してください。
ebmlをダウンロードするため「nodejs」フォルダを作成するためコマンドを入力して実行します。
![image.png]()
md nodejs
nodejsフォルダに移動するためコマンドを入力して実行します。
![image.png]()
cd nodejs
ebmlをダウンロードするためコマンドを入力して実行します。
![image.png]()
npm install ebml
- 作成したnodejsフォルダの中身ではなくフォルダ自体を圧縮します。
AWSにサインインします。
- アカウント、ユーザー名、パスワードを入力してサインインします。
アカウント内(IAM)で作成したユーザーを使用してコンソールにサインインする
- アカウント、ユーザー名、パスワードを入力してサインインします。
『AWSマネジメントコンソール』画面にある「サービスを検索」にLambdaと入力し、検索結果から《Lambda》をクリックし、Amazon Lambda コンソール(https://console.aws.amazon.com/lambda/)を開きます。
![image.png]()
- 名前:ebml
- アップロード:先ほど作成したZipファイル
- ランタイム:Node.js 12.x
WAV形式に変換してS3に保存するLambdaの作成
- 以下のコードで各自で変える部分
- region変数:バケットを作成したリージョン名
- bucketName変数:作成したバケット名
- putKey変数:作成したフォルダ名(終わりに『/』を入れる)
constAWS=require("aws-sdk");constregion='XXXXXXXXX';constbucketName='my-baseXXXXXXXXX';constputKey='my-voicemessageXXXXXXXXX/wav/';exports.handler=async(event)=>{console.log(JSON.stringify(event));consts3=newS3(AWS,region);console.log(event.Records);for(letrecordofevent.Records){constgetKey=record.s3.object.key;varindex=getKey.lastIndexOf("/");varfileName="noname";if(index>=0){fileName=getKey.substr(index+1);};// S3から録音データに関する情報を取得constdata=awaits3.get(record.s3.bucket.name,getKey);constinfo=JSON.parse(data.Body);conststreamName=info.streamARN.split('stream/')[1].split('/')[0];constfragmentNumber=info.startFragmentNumber;console.log(info)// Kinesis Video Streamsから当該RAWデータの取得constraw=awaitgetMedia(streamName,fragmentNumber);// RAWデータからWAVファイルを作成constwav=Converter.createWav(raw,8000);// WAVファイルをS3に保存するlettagging='';// 付加情報をタグに追加するtagging+="customerEndpoint="+info.customerEndpoint+'&';tagging+="systemEndpoint="+info.systemEndpoint+'&';tagging+="startTimestamp="+info.startTimestamp;awaits3.put(bucketName,putKey+fileName+'.wav',Buffer.from(wav.buffer),tagging)}return{};};classS3{constructor(AWS,region){this._s3=newAWS.S3({region:region});}asyncget(bucketName,key){constparams={Bucket:bucketName,Key:key};returnawaitthis._s3.getObject(params).promise();}asyncput(bucketName,key,body,tagging){constparams={Bucket:bucketName,Key:key,Body:body,Tagging:tagging};returnawaitthis._s3.putObject(params).promise();}}constebml=require('ebml');asyncfunctiongetMedia(streamName,fragmentNumber){// Endpointの取得constkinesisvideo=newAWS.KinesisVideo({region:region});varparams={APIName:"GET_MEDIA",StreamName:streamName};constend=awaitkinesisvideo.getDataEndpoint(params).promise();// RAWデータの取得constkinesisvideomedia=newAWS.KinesisVideoMedia({endpoint:end.DataEndpoint,region:region});varparams={StartSelector:{StartSelectorType:"FRAGMENT_NUMBER",AfterFragmentNumber:fragmentNumber,},StreamName:streamName};constdata=awaitkinesisvideomedia.getMedia(params).promise();constdecoder=newebml.Decoder();letchunks=[];decoder.on('data',chunk=>{if(chunk[1].name=='SimpleBlock'){chunks.push(chunk[1].data);}});decoder.write(data["Payload"]);// chunksの結合constmargin=4;// 各chunkの先頭4バイトを破棄するvarsumLength=0;chunks.forEach(chunk=>{sumLength+=chunk.byteLength-margin;})varsample=newUint8Array(sumLength);varpos=0;chunks.forEach(chunk=>{lettmp=newUint8Array(chunk.byteLength-margin);for(vare=0;e<chunk.byteLength-margin;e++){tmp[e]=chunk[e+margin];}sample.set(tmp,pos);pos+=chunk.byteLength-margin;})returnsample.buffer;}classConverter{// WAVファイルの生成staticcreateWav(samples,sampleRate){constlen=samples.byteLength;constview=newDataView(newArrayBuffer(44+len));this._writeString(view,0,'RIFF');view.setUint32(4,32+len,true);this._writeString(view,8,'WAVE');this._writeString(view,12,'fmt ');view.setUint32(16,16,true);view.setUint16(20,1,true);// リニアPCMview.setUint16(22,1,true);// モノラルview.setUint32(24,sampleRate,true);view.setUint32(28,sampleRate*2,true);view.setUint16(32,2,true);view.setUint16(34,16,true);this._writeString(view,36,'data');view.setUint32(40,len,true);letoffset=44;constsrcView=newDataView(samples);for(vari=0;i<len;i+=4,offset+=4){view.setInt32(offset,srcView.getUint32(i));}returnview;}static_writeString(view,offset,string){for(vari=0;i<string.length;i++){view.setUint8(offset+i,string.charCodeAt(i));}}}AWSにサインインします。
- アカウント、ユーザー名、パスワードを入力してサインインします。
アカウント内(IAM)で作成したユーザーを使用してコンソールにサインインする
- アカウント、ユーザー名、パスワードを入力してサインインします。
『AWSマネジメントコンソール』画面にある「サービスを検索」にLambdaと入力し、検索結果から《Lambda》をクリックし、Amazon Lambda コンソール(https://console.aws.amazon.com/lambda/)を開きます。
![image.png]()
- voice-message-createwav
「関数コード」に初期で登録されているコードを削除して、上記voice-message-createwavをコピー&ペーストします。
![image.png]()
日本時間に対応させるため、画面を下にスクロールして「環境変数」に以下の値を入力し《保存》ボタンをクリックします。
![image.png]()
- キー:TZ、値:Asia/Tokyo
このLambdaは実行時間がかかるため、デフォルトの設定ではTimeOutエラー発生するためタイムアウトの設定を以下の内容に変更します。
![image.png]()
- タイムアウト:10秒
Lambdaにサービスへのアクセス権を設定するため下にスクロールして「実行ロール」を表示し、《XXXXXXXXロールを表示》をクリックします。
![image.png]()
- Lambdaを作成する毎に自動的にLambda名の付いたロールが一つ作成されます。
- Lambdaで利用しているAPIのアクセス権を付与します。
- kinesis Video Streamsデータ取得用情報(voice-message-infomationで作成したもの)をS3から取得するための権限
- GetObject
- kinesis Video Streamsからデータを読み込むための権限
- GetMedia
- GetDataEndpoint
- kinesis Video StreamsデータをWAV形式に変換したものをS3に保存するための権限
- PutObjectTagging
- PutObject
- kinesis Video Streamsデータ取得用情報(voice-message-infomationで作成したもの)をS3から取得するための権限
ビジュアルエディタが表示されるので《さらにアクセス許可を追加する》をクリックします。
![image.png]()
- Lambdaの実行ログを記録するため、デフォルトでCloudWatch Logsの権限が付与されます。
- Bucket name:kinesis Video Streamsデータ取得用情報が保存されているS3のバケット名+フォルダ名(バケット名とフォルダ名やフォルダ名とフォルダ名の間は『/』で連結する)
- Bucket name:my-baseXXXXXXXXX/my-voicemessageXXXXXXX/infomation
- Object name:すべてにチェックを付ける(テキストボックスには*が入力される)
- Bucket name:kinesis Video Streamsデータ取得用情報が保存されているS3のバケット名+フォルダ名(バケット名とフォルダ名やフォルダ名とフォルダ名の間は『/』で連結する)
「アクション」に今回利用するPutObjectTaggingを上書き入力し、《PutObjectTagging》をクリックし、選択状態にします。
![image.png]()
- Bucket name:kinesis Video StreamsデータをWAVに変換したデータを保存するS3のバケット名+フォルダ名(バケット名とフォルダ名やフォルダ名とフォルダ名の間は『/』で連結する)
- Bucket name:my-baseXXXXXXXXX/my-voicemessageXXXXXXX/wav
- Object name:すべてにチェックを付ける(テキストボックスには*が入力される)
- Bucket name:kinesis Video StreamsデータをWAVに変換したデータを保存するS3のバケット名+フォルダ名(バケット名とフォルダ名やフォルダ名とフォルダ名の間は『/』で連結する)
「サービス」にKinesis Video Streamsと入力し、検索結果から《Kinesis Video Streams》をクリックします。
![image.png]()
「アクション」に今回利用するGetDAtaEndpointを入力し、《GetDAtaEndpoint》をクリックし、選択状態にします。
![image.png]()
- Reagion:kinesis Video Streamsを作成したリージョン名
- Reagion : aap-northeast-1(Kinesis Video Streamsを作成したリージョン)
- Account:自分のアカウント名(デフォルトで入力される)
- Stream name:すべて
- Creation time:すべて
- Reagion:kinesis Video Streamsを作成したリージョン名
- 名前:ebml
- バージョン:先ほど作成したebmlで利用するバージョン番号
kinesis Video Streamsデータ取得用情報がS3に作成された場合に動かしたいので《トリガーを追加》をクリックします。
![image.png]()
- バケット:kinesis Video Streamsデータ取得用情報を作成したバケット
- イベントタイプ:PUT
- プレフィックス:kinesis Video Streamsデータ取得用情報を作成したフォルダ
参考サイト
- [Amazon Connect]営業時間外に着信したビジネスチャンスを失わないように留守番電話機能をつけてみた
- AWS Lambda Layersでnode_modulesを使う
- Kinesis ビデオストリーム API およびプロデューサーライブラリのサポート
- Kinesis ビデオストリーム データにアクセスする方法
- GitHub amazon-connect/amazon-connect-realtime-transcription
- サンプリング周波数とビットレート
- 音ファイル(拡張子:WAVファイル)のデータ構造について
- Windows 10へNode.jsをインストールする























































