LoginSignup
0
1

More than 1 year has passed since last update.

ラズパイとAWS IoTを使った見守りシステム自作で学んだこと(9)S3にuploadした映像の確認用web page

Last updated at Posted at 2022-08-30

(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の一部です。

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に合わせて書き換える必要があります。

/Place1/place1-1.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名は環境変数として読み込みます。

app.py
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行目だけ下記のように置き換えます。

mimamori-project-deploy.sh
BUCKET_NAME=$(cat ../../cert/iot_prov_config | grep S3BUCKET | awk -F'=' '{print $2}')
                    ・
                    ・
                    ・

S3Bucketにuploadが完了しているのを確認できました。

次回

恐らく、本業でも趣味でもwebの仕組みを作られてる方が見たら「どうしてこうなった、、、、、」と言うかそっ閉じしたくなるような内容だったと思います。お付き合い頂きありがとうございました。

今後の課題として簡単なSPAづくりをJavaScriptのフレームワーク使って挑戦したいと思います。Amplifyも。

次回最終回、(10)cliでラズパイ環境とAWSリソースを構築に続きます。

0
1
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
0
1