月初のスクリプト
はじめに
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フォルダにマウントしてある。
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25  | 
						$ 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の設定は次の通り。---は適宜必要な内容に変更。
| 
					 1 2 3 4 5 6 7 8  | 
						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”で保存。
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40  | 
						#!/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”で保存。
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52  | 
						#!/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はこんな感じで、日毎ムービーと月毎のムービーを作成する前述のシェルスクリプトを実行する。
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18  | 
						#月毎のムービーの作成                                                                                                                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%ぐらい使用していた。
| 
					 1 2 3 4 5 6 7 8 9 10  | 
						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  | 
					


