月初のスクリプト
はじめに
Raspberry Piに接続したカメラとmotionを使用して、動体検出、その画像をファイル共有先のUbuntu PCに保存するようにしている。これを月初にffmpegを利用して、動画化して年度ごとのフォルダに保存する。これをシェルスクリプトで自動化している。長いもので、2020年末〜2021年から運用しているものもある。(途中、カメラの故障で交換したものもあったと思う。)
2023年10月分の画像ファイル数がシェルで取り扱える限界を超えたようで、動作しなかった。そこで、日毎にムービーを作成し、月初にひと月分の日毎ムービーを統合するように変更したのでその詳細をまとめてみた。
現在カメラは5台でRaspberry Pi Zeroに接続され動体を監視中。γ、η、θは停止中。ι、κを準備中である。カメラはないが、九州地方にλが稼働しており、環境データをサーバーに送信中。1年を超えて継続運用している。
また、簡単なhtmlを作成し、以下のようにリアルタイムでカメラの映像を確認することもできるようにしている。

motionについて
motionは、さまざまなカメラからのビデオ信号を監視し、動体検出されたときに設定に応じた動作を実行するプログラムです。このブログを書く際にmotionのホームページを訪れたところ、新しくmotion plusが公開されているようだ。旧motionは2000年に公開されているようで、古くなった機能、ほとんど使われない機能を削除した新しいプログラムがmotion plusのようだ。
近いうちに使ってみよう。
motionアプリケーションの機能
- Create videos or save pictures of the activity
- Passthrough recording from many IP cameras
- View live stream of cameras
- Invoke scripts when activities occur
- Log activity into multiple types of databases
- Fully customizable masks for privacy or motion detection
- Full tls(https) support with authentication for webcontrol and streams
様々なタイプのカメラが使用可能
- Network cameras via RTSP, RTMP and HTTP
- PI cameras
- V4L2 webcams
- Video capture cards
- Existing movie files
フォルダ構成
サーバー側のPicturesフォルダに各Raspberry Piのフォルダを作成してあり、各Raspberry Pi側のPicturesフォルダにマウントしてある。
$ ll
合計 46704
drwxr-xr-x 21 kimi kimi 4096 11月 30 22:19 ./
drwxr-xr-x 49 kimi kimi 4096 12月 4 16:57 ../
-rw-rw-r-- 1 kimi kimi 0 4月 5 2022 .trackerignore
drwxrwxrwx 3 kimi kimi 69632 9月 22 2021 rasp_2b_alpha/
drwxrwxrwx 2 kimi kimi 20480 10月 7 2021 rasp_2b_beta/
drwxrwxr-x 2 kimi kimi 4096 4月 16 2022 rasp_3b_alpha/
drwxrwxrwx 3 kimi kimi 1646592 12月 2 09:12 rasp_3b_beta/
drwxrwxrwx 2 kimi kimi 4096 11月 29 11:39 rasp_400_alpha/
drwxrwxrwx 2 kimi kimi 4096 11月 29 11:39 rasp_4b_alpha/
drwxrwxrwx 5 kimi kimi 3284992 12月 2 09:26 rasp_4b_beta/
drwxrwxrwx 2 kimi kimi 4096 7月 26 13:32 rasp_4b_gamma/
drwxrwxrwx 6 kimi kimi 3440640 12月 4 13:07 rasp_zero_alpha/
drwxrwxrwx 5 kimi kimi 1826816 12月 4 13:59 rasp_zero_beta/
drwxrwxrwx 5 kimi kimi 253952 12月 4 00:42 rasp_zero_delta/
drwxrwxrwx 5 kimi kimi 21622784 12月 2 09:21 rasp_zero_epsilon/
drwxrwxrwx 5 kimi kimi 3424256 12月 4 18:09 rasp_zero_eta/
drwxrwxrwx 6 kimi kimi 2617344 12月 1 07:06 rasp_zero_ganma/
drwxrwxrwx 3 kimi kimi 3186688 8月 2 2022 rasp_zero_iota/
drwxrwxrwx 2 kimi kimi 4096 6月 21 2022 rasp_zero_kappa/
drwxrwxrwx 6 kimi kimi 2015232 12月 2 09:23 rasp_zero_theta/
drwxrwxrwx 6 kimi kimi 4227072 12月 4 18:25 rasp_zero_zeta/
drwxrwxr-x 3 kimi kimi 4096 12月 2 09:25 scripts/
カメラが接続されているRaspberry Pi zero側の/etc/fstabの設定は次の通り。---は適宜必要な内容に変更。
proc /proc proc defaults 0 0
PARTUUID=331defd0-01 /boot vfat defaults 0 2
PARTUUID=331defd0-02 / ext4 defaults,noatime 0 1
# a swapfile is not a swap partition, no line here
# use dphys-swapfile swap[on|off] for that
//---.---.---.---/zero_zeta /home/-----/Pictures cifs username=-----,password=-----,uid=1000,gid=1000 0 0
日毎のシェルスクリプト
スクリプトのファイル名は”daily_script.sh”で保存。
#!/bin/bash
# Script to make time series images into video
# 対象のRaspberry Pi
rasp="zero_zeta"
# ベースディレクトリ
base_dir="/home/kimi/Pictures/rasp_${rasp}"
# カレントディレクトリを指定のディレクトリに変更
cd "$base_dir" || exit 1
# 前日を取得
file_name=date -d 'yesterday' '+%Y%m%d'
# 前日の年を取得
year=$(date -d "$file_name" '+%Y')
# テンポラリフォルダを作成しファイルをコピー、カレントディレクトリを変更
mkdir -p temp
mv ${file_name}*.jpg ./temp/ || exit 1
cd ./temp/
# 空のファイルを検索、削除
# ネットワーク状態により、画像が壊れることがある様で、容量ゼロのjpegファイルが存在するとffmpegが失敗するため。
find . -empty -delete
# 連番のつけ直し
ls | awk '{printf " mv %s pic%05d.jpg\n", $0, NR}' | bash
# 動画ファイルへの変換
ffmpeg -f image2 -r 15 -i pic%05d.jpg -r 15 -an -vcodec libx264 -pix_fmt yuv420p -loglevel quiet ${file_name}.mp4
if [ $? -eq 0 ]; then
# 動画ファイルの移動
mv "${file_name}.mp4" ../${year}/"${file_name}_${rasp}.mp4"
# tempフォルダから移動、消去
cd ..
rm -r temp
fi月初のシェルスクリプト
スクリプトのファイル名は”new_monthly_scpt.sh”で保存。
#!/bin/bash
# 日毎のムービーをひと月分まとめるスクリプト
# 対象のRaspberry Pi
rasp="zero_zeta"
# ベースディレクトリ
base_dir="/home/kimi/Pictures/rasp_${rasp}"
# カレントディレクトリを指定のディレクトリに変更
cd "$base_dir" || exit 1
# 先月の年と年月を取得
last_month=$(date -d 'last month' '+%Y-%m')
Year=$(date -d "$last_month-01" '+%Y')
YM=$(date -d "$last_month-01" '+%Y%m')
# カレントディレクトリを先月の年に変更
if [ ! -d "${Year}" ]; then
mkdir "${Year}"
fi
cd "${Year}" || exit 1
# Trashフォルダが存在しない場合は作成
trash_folder="Trash"
if [ ! -d "${trash_folder}" ]; then
mkdir "${trash_folder}" || exit 1
fi
# 日毎の動画のリストを作成
video_list="video_list.txt"
ls "${YM}"*.mp4 | awk '{printf "file %s\n", $0}' > "${video_list}" || exit 1
# 画像を動画に変換
output_file="temp.mp4"
ffmpeg -f concat -i "${video_list}" -c copy -loglevel quiet "${output_file}"
# 動画の作成が成功したかを確認
if [ $? -eq 0 ]; then
# 日毎の動画を削除用フォルダに移動
mv "${YM}"*.mp4 ./"${trash_folder}"
# 作成した動画をファイル名変更
mv temp.mp4 "${YM}_${rasp}.mp4"
# テンポラリファイルを削除
rm "${video_list}"
else
# ファイルが存在しない場合は終了
# cronに登録し、メール出力が不要な場合、
# cron ジョブの末尾に "">/dev/null 2>&1" を追加して標準出力と標準エラー出力を破棄すること
echo "Error: No files found for copying."
exit 1
fi運用
画像の保存先のPCのcrontabはこんな感じで、日毎ムービーと月毎のムービーを作成する前述のシェルスクリプトを実行する。
#月毎のムービーの作成
00 1 1 * * bash /home/kimi/Pictures/rasp_zero_zeta/new_monthly_scpt.sh
02 1 1 * * bash /home/kimi/Pictures/rasp_zero_eta/new_monthly_scpt.sh
20 0 1 * * bash /home/kimi/Pictures/rasp_zero_alpha/new_monthly_scpt.sh
30 0 1 * * bash /home/kimi/Pictures/rasp_zero_beta/new_monthly_scpt.sh
40 0 1 * * bash /home/kimi/Pictures/rasp_zero_delta/new_monthly_scpt.sh
#50 0 1 * * bash /home/kimi/Pictures/rasp_zero_ganma/monthly_scpt.sh
#10 1 1 * * bash /home/kimi/Pictures/rasp_zero_theta/monthly_scpt.sh
#0 1 1 * * bash /home/kimi/Pictures/rasp_zero_epsilon/monthly_scpt.sh
#20 1 1 * * bash /home/kimi/Pictures/rasp_4b_beta/monthly_scpt.sh
#一日分の画像が多い場所は日毎のムービーも作成
0 0 * * * bash /home/kimi/Pictures/rasp_zero_eta/daily_script.sh
10 0 * * * bash /home/kimi/Pictures/rasp_zero_zeta/daily_script.sh
15 0 * * * bash /home/kimi/Pictures/rasp_zero_alpha/daily_script.sh
20 0 * * * bash /home/kimi/Pictures/rasp_zero_beta/daily_script.sh
30 0 * * * bash /home/kimi/Pictures/rasp_zero_delta/daily_script.sh
まとめ
問題なく、日毎及び月初は処理され、画像は月毎の動画として保存された。
画像ファイルが少なくなったことで、ディスク容量が20%程減少した。以前は70%ぐらい使用していた。
09:24 午前 kimi@endeavor-na601e:~/Pictures/rasp_zero_zeta
$ df -h
Filesystem Size Used Avail Use% Mounted on
tmpfs 781M 12M 770M 2% /run
/dev/sda1 229G 99G 118G 46% /
tmpfs 3.9G 0 3.9G 0% /dev/shm
tmpfs 5.0M 4.0K 5.0M 1% /run/lock
tmpfs 781M 100K 781M 1% /run/user/121
tmpfs 781M 92K 781M 1% /run/user/1000


