(6)稿目でuploadしたmp4ファイルの表示部になります。
mp4ファイルを確認する為のweb page Projectの構成と、ラズパイでイベント録画してS3にuploadした後にmp4ファイルを処理するLambda関数を説明します。
web page Projectの構成
web page Projectのリポジトリー内格納場所は/Monitoring-system-with-Raspberry-Pi-and-AWS/templateになります。
CloudFrontオリジン(兼mp4のupload先)として構築したS3バケットのrootにはindex.htmlが配置されます。このindex.htmlがCloudFrontにDefault Rootとして登録されていてCloudFrontDomainを叩くと表示されます。
以下はset_parameters.pyでモノの名前を入力後に出力したindex.htmlの一部です。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>My Place Watching Over Site</title>
<meta name="viewport" content="width=device-width">
<link href="https://fonts.googleapis.com/earlyaccess/nicomoji.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=M+PLUS+Rounded+1c" rel="stylesheet">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="container">
<header>
<h1>My Place Watching Over Site</h1>
</header>
<section class="information">
<h1>Event records from catbed1 to catbed4</h1>
</section>
</div> <div class="box1">
<div class="section2">
<h2>catbed1</h2>
<img src="img/place1.jpg" width="500">
<ol>
<li><a href="Place1/place1-1.html" target="_blank">latest</a></li>
<li><a href="Place1/place1-2.html" target="_blank">1 time ago</a></li>
・
・
・
<li><a href="Place2/place2-11.html" target="_blank">10 times ago</a></li>
<li><a href="Place2/place2-12.html" target="_blank">11 times ago</a></li>
</ol>
</div>
</div>
webブラウザーで表示される外観は以下のようになります。
一つ階層を下がると、ラズパイ設置場所Place1からPlace4の映像を仕分けする為のプレフィクスが用意されていて、各プレフィックスにはindex.htmlに紐づいた過去12回分のmp4ファイルを表示するhtmlファイルが格納されています。
後述するmp4ファイル名変更をするLambda関数は./functionに格納されます。
ページレイアウト用のCSSは./cssに、web pageに表示する場所の写真は./imgに格納されます。
表示する場所の写真を変更する場合はフォルダー内の写真を上書きします。
/neko-mimamori
┣ index.html
┣ /Place1
┃ ┣ 01.mp4
┃ ┣ Place1.html
┃ ┣ 02.mp4
┃ ┣ Place1-2.html
・ ・
・ ・
┃ ┣ 12.mp4
┃ ┗ Place1-12.html
・ ・
┣ /Place4
・ ・
・ ・
・ ・
┣ /function
┃ ┗ app.py
┣ /img
┃ ┣ place1.jpg
┃ ┣ place2.jpg
┃ ┣ place3.jpg
┃ ┗ place4.jpg
┣ /css
Lambda関数によるmp4ファイル名変更と移動
html中のmp4ファイル名は固定(下のPlace1.htmlの場合だと01.mp4に固定)されているため、新たなファイルがuploadされた場合はファイル名をhtmlに合わせて書き換える必要があります。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>catbedNo1</title>
</head>
<body>
<h1>catbed1 latest</h1>
<video src="01.mp4" autoplay muted loop playsinline controls width=1024 height=768></video>
</body>
このファイル名更新作業をLambda関数で行います。
シーケンス図
mp4がS3のrootにuploadされるとLambda関数が発火して、まず最初に連番ファイル名になっている既存のmp4ファイルの番号を一つずつ繰り下げます。最後に、uploadされたmp4ファイルを01.mp4にリネームします。
下図のような動作になります。
Lambda関数
このmp4ファイル名変更シーケンスを実行するLambda関数です。
S3Bucket名は環境変数として読み込みます。
import boto3
import os
s3 = boto3.client('s3')
ORG_BACKET = os.environ['ORG_BACKET']
deploy_fileはmp4表示用htmlに書かれているファイル名を降順に格納したリストです。Lambdaが発火したら古い順にファイル名を更新して01.mp4をあける必要があるからです。
PLACE1 = "Place1"
PLACE2 = "Place2"
PLACE3 = "Place3"
PLACE4 = "Place4"
deploy_file = ["12.mp4",
"11.mp4",
"10.mp4",
"09.mp4",
"08.mp4",
"07.mp4",
"06.mp4",
"05.mp4",
"04.mp4",
"03.mp4",
"02.mp4",
"01.mp4"]
古い順にファイルをリネームします。バージョニング設定をしていない場合、元の12.mp4は上書きされると消えます。
def modify_fname(filename, prefix):
for i in range(len(deploy_file)):
try:
if deploy_file[i] == '01.mp4':
s3.copy_object(Bucket=ORG_BACKET,
Key=prefix+deploy_file[i],
CopySource={'Bucket': ORG_BACKET,
'Key': filename})
s3.delete_object(Bucket=ORG_BACKET,
Key=filename)
break
else:
s3.copy_object(Bucket=ORG_BACKET,
Key=prefix+deploy_file[i],
CopySource={'Bucket': ORG_BACKET,
'Key': prefix+deploy_file[i+1]})
except Exception as e:
pass
return
s3:ObjectCreatedのevent引数からuploadファイル名を抽出し、ファイル名に含まれるPlace番号が振り分け先プレフィックスになります。
def lambda_handler(event, context):
for rec in event['Records']:
filename = (rec['s3']['object']['key'])
if PLACE1 in filename: prefix = PLACE1 + "/"
if PLACE2 in filename: prefix = PLACE2 + "/"
if PLACE3 in filename: prefix = PLACE3 + "/"
if PLACE4 in filename: prefix = PLACE4 + "/"
modify_fname(filename, prefix)
return
Projectの実装
(8)template.yamlで定義するAWSリソースの説明とsam deployで説明したAWSリソースを全て実装した後に/Monitoring-system-with-Raspberry-Pi-and-AWS/templateの中身を作成したS3Bucketにuploadします。
これまでの設定例と同じくBucket名をneko-mimamoriとします。
モノの名前の登録と同様にここではawscliを利用してS3にuploadします。
BUCKET_NAME="neko-mimamori"
/usr/local/bin/aws s3 cp ./index.html s3://${BUCKET_NAME}
/usr/local/bin/aws s3 cp ./css/ s3://${BUCKET_NAME}/css --recursive
/usr/local/bin/aws s3 cp ./Place1/ s3://${BUCKET_NAME}/Place1 --recursive
/usr/local/bin/aws s3 cp ./Place2/ s3://${BUCKET_NAME}/Place2 --recursive
/usr/local/bin/aws s3 cp ./Place3/ s3://${BUCKET_NAME}/Place3 --recursive
/usr/local/bin/aws s3 cp ./Place4/ s3://${BUCKET_NAME}/Place4 --recursive
/usr/local/bin/aws s3 cp ./img/ s3://${BUCKET_NAME}/img --recursive
リポジトリー中のshellscriptではBUCKET_NAMEをiot_prov_configから読み込むので1行目だけ下記のように置き換えます。
BUCKET_NAME=$(cat ../../cert/iot_prov_config | grep S3BUCKET | awk -F'=' '{print $2}')
・
・
・
S3Bucketにuploadが完了しているのを確認できました。
次回
恐らく、本業でも趣味でもwebの仕組みを作られてる方が見たら「どうしてこうなった、、、、、」と言うかそっ閉じしたくなるような内容だったと思います。お付き合い頂きありがとうございました。
今後の課題として簡単なSPAづくりをJavaScriptのフレームワーク使って挑戦したいと思います。Amplifyも。
次回最終回、(10)cliでラズパイ環境とAWSリソースを構築に続きます。