前回の続き。タイトル変わったけど。期間がだいぶ空いたけど。
振り返り
前回の記事はこれです。
ラズパイ Zero W に motion 入れて、動画ファイルをクラウドへ保存してみた件。
しかし課題がいろいろ。
- 画像サイズを大きくすると、動画ファイルがクラウドへ保存されない
- 保存されていても、ファイルが壊れていることが多い
- そもそもクラウドのディレクトリがマウントされないことがある
- motion の起動が手動
マウントをどうにかする
fstab で InfiniCloud をマウントする設定にしたんだけど、どうにも安定しないです。
そこで、スクリプトを組んでみました。
マウントできていなければ指定回数(ここでは 3回)だけマウントを繰り返す感じです。
▶ mount_retry.sh(クリックすると展開されます)
#!/bin/bash mount_point="/mnt/infinicloud" max_retries=3 retries=0 until [ $retries -ge $max_retries ] do mount -a -t davfs if mountpoint -q "$mount_point"; then echo "Mount successful!" break else echo "Mount failed. Retrying..." retries=$((retries+1)) sleep 5 fi done if [ $retries -eq $max_retries ]; then echo "Mount failed after $max_retries retries. Exiting." fi
動画ファイルを一時置きする
motion.conf の設定で /mnt/infinicloud
を動画ファイルの出力先にしていたのを /tmp
に変更しました。
そして、/tmp
へ保存されるファイルがクローズされるのを待ち、
クローズされていればそのファイルを /mnt/infinicloud
へコピー、
つまりクラウドへアップロードする処理をスクリプトで書いてみました。
これでアップロードした動画ファイルが壊れなくなることを期待。
▶ upload_mp4.sh(クリックすると展開されます)
#!/bin/bash while true; do # /tmp/motionディレクトリ内のmp4ファイルの中で、最も古いファイルを選択する selected_file=$(ls -t /tmp/motion/*.mp4 | tail -1) if [[ -f "$selected_file" ]]; then echo "選択したファイル: $selected_file" # 選択したmp4ファイルがクローズされているか確認する if lsof "$selected_file" >/dev/null; then echo "ファイルはまだ開かれています" else echo "ファイルはクローズされています" # 別のディレクトリにmp4ファイルをコピーする cp "$selected_file" /mnt/infinicloud/motion/ # コピー後、mp4ファイルを削除する rm "$selected_file" echo "ファイルをコピーして削除しました" fi fi # 10秒間処理を停止する sleep 10 done
追記
アップロードしたら LINE Notify に通知を飛ばすようにしてみました。
echo "ファイルをコピーして削除しました" + filename=$(basename "$selected_file") # ファイル名のみを抽出 + curl -X POST -H "Authorization: Bearer {アクセストークン}" -F "message=$filename" https://notify-api.line.me/api/notify fi
motion を起動させる
スクリプト 3つ目。
motion を設定ファイル指定で起動するスクリプト。
念のため起動前 10秒待ち。いらないかもしれないけど。
▶ motion_startup.sh(クリックすると展開されます)
#!/bin/bash sleep 10 motion -c /root/motion/motion.conf
仕上げ。自動起動
systemd で起動させるため、service ファイルを記述しました。
有効化します。
systemctl enable motion.service
▶ /etc/systemd/system/motion.service(クリックすると展開されます)
[Unit] Description=Motion Service After=network.target RequiresMountsFor=/mnt/infinicloud [Service] ExecStartPre=/bin/sleep 10 ExecStart=/bin/bash -c '/root/mount_retry.sh && /root/motion_startup.sh && /root/upload_mp4.sh' Restart=always User=root [Install] WantedBy=multi-user.target
動作確認
ラズパイの電源を入れ直し、しばらく待ちました。
カメラ前で手を振ってみて、しばらく待ちました。
しばらく待って、InfiniCloud のディレクトリを見てみました。
うまくいきました。
起動時間、画質、動体検知設定 などいろいろ調整することはありそうですが、これで当初の目的は達成できました。
おまけ
InfiniCLOUD の 紹介コード: 8E2Q5