ラズパイzero で音声つき動画の自動撮影

ラズパイzero で音声つき動画の自動撮影

ダイソーの300円で販売されているAB Shutter3 で
撮影とシャットダウンボタンを作成する予定だったが
ボタンが1つしか認識しないため
撮影については cron で行い
シャットダウンについては
AB Shutter3 で担当することに

motion の自動起動を停止

これは
insservの使い方

を参考に

insserv -r motion
で停止

sudo service motion stop
も実行

これをしないとどんどん静止画が増えてしまう

次に

nano bluebutton.sh

でファイルを作成

#!/bin/sh
command="sudo bluebutton -d="Shutter3" -c ~/.config/bluebutton"
eval $command

として保存

sudo crontab -e

でファイルを開き

以前

#*/10 * * * * /home/pi/rscamera.sh

としていたのでこれをコメントアウト

@reboot /home/pi/bluebutton.sh
を追記

これで再起動したときに
AB Shutter3 が有効化される

これを行ったため
マイクの情報が変わっていた

arecord -l

**** ハードウェアデバイス CAPTURE のリスト ****
カード 2: Device [USB PnP Sound Device], デバイス 0: USB Audio [USB Audio]
サブデバイス: 0/1
サブデバイス #0: subdevice #0

amixer -c2
Simple mixer control ‘Mic’,0
Capabilities: cvolume cvolume-joined cswitch cswitch-joined
Capture channels: Mono
Limits: Capture 0 – 16
Mono: Capture 16 [100%] [23.81dB] [on]
Simple mixer control ‘Auto Gain Control’,0
Capabilities: pswitch pswitch-joined
Playback channels: Mono
Mono: Playback [on]

このため音声つき動画撮影コマンドも変更され
timeout 15 raspivid -t 0 -w 640 -h 480 -b 10000000 -fps 30 -awb fluorescent -n -o test.h264 | arecord -D hw:2,0 -f S16_LE -r 44100 -d 0 test.wav;ffmpeg -y -i test.wav -r 30 -i test.h264 -vcodec copy /mnt/nas/test.mk
となる

このままだと同じファイルになってしまうので
dateコマンドを使って作成するファイルに日時と時間をつける

ファイル名に日時情報を追加

にdate コマンドの解説があるのでこちらを参考に

timeout 15 raspivid -t 0 -w 640 -h 480 -b 10000000 -fps 30 -awb fluorescent -n -o test.h264 |    arecord -D hw:2,0 -f S16_LE -r 44100 -d 0 test.wav;ffmpeg -y -i test.wav  -r 30 -i test.h264  -vcodec copy /mnt/nas/`date +%Y%m%d_%H-%M-%S`.mkv

とすれば
ファイル名が
20200913_21-01-32.mkv
というように
秒数まで入るので上書きされることがなくなる

%Yで西暦
%m で月
%d で日
%H が時間
%M が分
%S で秒
となっている

なお

`date +%Y%m%d_%H-%M-%S`

はバッククォートで囲っている
shift + @ でバッククォートになる

‘ と似ているので注意

あとはラズパイzero の時間がずれているので
Raspberry Pi のシステム時刻を変更する
によれば初期状態だと世界標準になっているとのこと

sudo timedatectl set-timezone Asia/Tokyo

を実行すれば再起動するまで一時的に合わせることができるので

起動時にこれを実行するようにする

cd /etc/init.d/
sudo nano autorun_date

でスクリプトファイルを作成

]
#!/bin/sh
### BEGIN INIT INFO
# Provides: mathkernel
# Required-Start: $local_fs
# Required-Stop: $local_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: mathkernel
### END INIT INFO

#システム時刻を日本に合わせる
sudo timedatectl set-timezone Asia/Tokyo

として保存

sudo chmod 755 autorun_date

で実行権限付与

本来ならこれをスクリプトとして登録するところだったけど
現在では
【CentOS7】timedatectlコマンドでタイムゾーンをJSTへ変更する

にあるように
一度コマンドを実行すれば設定はそのままになるようになっていた

なお

sudo timedatectl 

を実行すると
現在設定されているタイムゾーンを確認できる

今回は

      Local time: 金 2020-09-18 05:51:10 JST
  Universal time: 木 2020-09-17 20:51:10 UTC
        RTC time: n/a
       Time zone: Asia/Tokyo (JST, +0900)
 Network time on: yes
NTP synchronized: yes
 RTC in local TZ: no

となっていた

次に音声つき動画撮影のスクリプトを用意
とはいってもこれをスクリプトファイルにするだけ

nano homevideo.sh

でファイルを作成

#!/bin/bash
timeout 15 raspivid -t 0 -w 640 -h 480 -b 10000000 -fps 30 -awb fluorescent -n -o test.h264 |    arecord -D hw:2,0 -f S16_LE -r 44100 -d 0 test.wav;ffmpeg -y -i test.wav  -r 30 -i test.h264  -vcodec copy /mnt/nas/`date +%Y%m%d_%H-%M-%S`.mkv

として保存

chmod +x homevideo.sh

で実行権限付与

./homevideo.sh 

としたが
timeout コマンドが動作しない

タイムアウト付きのシェル関数を実行する


bashのtimeoutコマンドをshellスクリプトから実行すると終了ステータスが正しく取得できない

をみたところ

スクリプトファイルを timeout コマンドで実行すればよさそう

なおワンライナーでの書き方については
(Linux)コマンドを連結して行う「;」「&」「&&」「||」の違い

を参考に

そのままワンライナーを書き込んでも失敗するため

#!/bin/bash
raspivid -t 0 -w 640 -h 480 -b 10000000 -fps 30 -awb fluorescent -n -o test.h26$
ffmpeg -y -i test.wav  -r 30 -i test.h264  -vcodec copy /mnt/nas/`date +%Y%m%d_$

として保存

変更点は ; による1行の部分を
; を削除して2行にしている

timeout 15 ./homevideo.sh

としたが
timeout コマンドにより変換する前に停止してしまう

とりあえずcrontab に直接コマンドを書き込むことにしたが
これもダメ

タイムアウト付きのシェル関数を実行する

を元に考えてみると

timeoutはコマンドであるため
bashシェルのサブプロセスで実行される

timeoutコマンドは
タイムアウトのサブプロセス(シェルの孫プロセス)として実行さる

つまり timeout コマンドをシェルスクリプトでそのまま使うことは無理そう

timeoutをシェルスクリプトで実現する

を参考に
同じ機能をもったシェル関数を作成し
それを実行

ラズパイzero にexpect コマンドがなかったので

sudo apt-get install expect

でインストール

あとは
homevideo.sh の内容を

#!/bin/bash
limittime() {

    time=$1

    # start the command in a subshell to avoid problem with pipes
    # (spawn accepts one command)
    command="/bin/sh -c \"${@:2}\""

    expect -c "set timeout $time; spawn -noecho $command; expect timeout { exit 124 } eof; catch wait result; exit [lindex \$result 3]"
}

limittime 15 raspivid -t 0 -w 640 -h 480 -b 10000000 -fps 30 -awb fluorescent -n -o test.h264 | limittime 15 arecord -D hw:2,0 -f S16_LE -r 44100 -d 0 test.wav
ffmpeg -y -i test.wav  -r 30 -i test.h264  -vcodec copy /mnt/nas/`date +%Y%m%d_%H-%M-%S`.mkv

として
raspivid と arecord を
15秒後に終わるように指定

コマンドのときには raspivid のみ timeoutコマンドを実行すれば
成功したけど
シェルスクリプトで実行するときには
arecord コマンドも設定しないとオーバーランになってしまい
ctrl+c で止めるまで動画変換されなかった

シェルスクリプトで音声つき動画がとれるようになったので
これを cron で実行

crontab -e

を実行

最終行に

*/2 * * * * /home/pi/homevideo.sh

を追記して保存

これで2分ごとに15秒の音声つき動画が撮影されるようになる

間隔をおいてのcron 実行については

cron を10分おき 2時間おきに実行する方法

を参考に

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です