ラズパイドラレコ作成
ssh
でアクセスし
sudo apt-get update
sudo apt-get upgrade
のあと
sudo raspi-config
で
最初のメニューの5番目の項目、Interfacing Optionsを開くと1番上にカメラの項目があるのでこれを有効化
ここまでできたら
v4l2-ctl --list-devices
使用するカメラのデバイスファイルを調べる
通常は
/dev/video0
となる
デバイスファイルを特定しておくと、下記のコマンドでサポートしている動画のフォーマットを表示することが可能
v4l2-ctl -d /dev/video0 --list-formats
ラズパイで動画を撮影する方法として、FFmpegを使用してリアルタイムでハードウェアエンコードする方法がよく紹介されていますが、特にRaspberry Pi Zeroだとフレームレートがあまり出ないのでドラレコには不向き
しかしハードウェアエンコードなんてしなくても、H.264をサポートしているカメラモジュールを使用すれば、専用の動画撮影コマンドraspividを実行することで簡単にH.264動画を撮影することが可能
安価なUSB接続のWebカメラだとH.264をサポートしていなかったりしますが、私が確認した限りではラズパイ向けのカメラモジュールはどれもH.264をサポートしているので、基本的にraspividで録画することをおすすめ
raspividで動画を撮影するには
もっともシンプルに書くなら、-oで出力ファイル名のみを指定してこのように記述
なお指定した名前のファイルが既に存在する場合は実行に失敗するので注意
raspivid -o test.h264
このように何も指定せずに実行すると5秒の動画ファイルが生成される
拡張子がH.264と扱いにくい形式ですが、一応このままでもVLCなどの動画プレーヤーで再生することが可能
撮影してみてカメラの向きが上下反転していた場合は-vf、左右反転していた場合は-hfを付け加えることで正常な向きに補正されるはず
また-rotで角度を指定して回転させることもできる
raspivid -o test.h264 -rot 180
正しい方向で撮影できるようになったら-wと-hで解像度、-tで撮影時間、-fpsでフレームレート、-bでビットレートを指定
raspivid -o test.h264 -rot 180 -w 1280 -h 720 -t 10000 -fps 30 -b 2000000
撮影時間はミリ秒で指定するため、-t 10000だと10秒の動画を生成
ただし-t 0で時間を指定しなければずっと録画し続けることが可能
Ctrl+Cで録画を停止
解像度やビットレートを上げれば高画質な動画を撮影できますが、それに比例してファイルサイズも大きくなるので注意
raspividの実行中にWi-Fiから切断されるとコマンドラインが閉じられるために録画も停止してしまう
車内にWi-Fi環境が整っている場合はともかく、そうでないならもう一工夫が必要
Raspberry Pi Zeroがネットワークから切断されてもraspividを停止しないようにするために、まずコマンドを実行するシェルスクリプトを作成
sudo nano test.sh
中身は
#!/bin/sh
raspivid -o `date '+%Y%m%d-%H%M'`.h264 \
-rot 180 -w 1280 -h 720 -t 10000 -fps 30 -b 2000000
あとは
sh test.sh
で録画できればok
次は
作成したスクリプトをサービスとしてシステム管理デーモンのsystemdに登録
まずは自動実行させたいスクリプトを/optに作成
sudo nano /opt/test.sh
今回は録画時間を指定しない
#!/bin/sh
raspivid -o `date '+%Y%m%d-%H%M'`.h264 \
-rot 180 -w 1280 -h 720 -t 0 -fps 30 -b 2000000
次は
sudo chmod 0755 /opt/test.sh
で実行権限付与
このスクリプトをサービスとしてsystemdに登録するため、ユニットファイルを作成
sudo nano /etc/systemd/system/test.service
中身は
[Unit]
Description = test
[Service]
ExecStart = /opt/test.sh
Restart = always
Type = simple
[Install]
WantedBy = multi-user.target
解説
Descriptionはユニットファイルの説明です。これは自由に記述
ExecStartに登録したいスクリプトを記述
Restartはalwaysを設定しておくことで、プロセスが不意に終了しても再起動させることが可能です。再起動する条件として異常終了した場合のみ、あるいは逆に正常終了した場合のみなどを設定することも可能ですが、通常はalwaysで良い
例外として後述するsystemctlコマンドで停止した場合のみ再起動されない
Typeはプロセスの起動タイプを設定するオプションです。simpleがデフォルトで、メインプロセスとして登録
WantedByは弱く依存するユニットを記述します。噛み砕いて説明すると、multi-user.targetの起動時にtest.serviceの起動も試みてほしい、ということです。多くのサービスがmulti-user.targetに紐付いていて、OS起動時にまとめて実行されます。
ユニットを定義できたら、サービスを有効化するために下記のコマンドを実行
sudo systemctl enable test.service
正常に有効化されていれば、下記のコマンドを入力するとバックグラウンドでサービスが実行されます。
サービスの状態は下記のコマンドで確認
sudo systemctl status test.service
しかし
Loaded: loaded (/etc/systemd/system/test.service; enabled; vendor preset: > Active: inactive (dead)
と表示されて固まる
Systemd を利用してサービスを追加・登録する
を参考に
systemctl list-unit-files --type=service |grep test
を実行し
glamor-test.service enabled enabled
gldriver-test.service enabled enabled
test.service enabled enabled
で稼働しているのを確認
またサービスを手動で停止したい場合は下記のコマンドを実行
sudo systemctl stop test.service
とりあえず止めておく
理由は
ただし普通にraspividコマンドを実行すると1つの巨大な動画ファイルが生成されてしまうので、特にWi-Fi経由でデータを取り出そうとするとかなり時間がかかります
解決策として
FFmpegへパイプ入力して動画ファイルの分割&変換処理を自動的に実行させることで対策
https://gadget-live.net/raspberry-pi-raspivid-ffmpeg-pipe-input/
を参考に
あとは
Raspberry Pi Zeroをシャットダウンして安全に電源を切る方法
スマートフォンのテザリングでSSH接続
これだと
Bluetoothテザリング
があるが
問題は複数のペアリングが可能かということ
Alexaを利用してハンズフリーで操作
これもありだけど
スマホでテザリングしてる状態で
Alexaが使えるのか?
とりあえずSSHでログインしてシャットダウンがベスト
あとはBluetoothボタンが候補
あとは人感センサーか音声でシャットダウンが候補
動画については
raspividからFFmpegへパイプ入力してFFmpegのsegmentオプションで分割すれば、これらの問題がすべて簡単に解決
この方法なら録画した動画を一定時間毎に分割することも、ファイルの名前をそれぞれの録画を開始した時間にすることも、さらに拡張子をH.264からMP4に変換するのもすべて自動的に実行することが可能
例えば解像度1280×720、ビットレート2000kbps、フレームレート30fpsで録画して1分単位で分割すればファイルサイズは1つあたり約15MBなので、ピンポイントで転送すればWi-Fiでもそれほど時間をかけずに取り出せます。
ようやく実際に手を動かしてraspividからFFmpegへパイプ入力するスクリプトを実装
既にドラレコとしてraspividコマンドを実行するスクリプトを組んであるなら、それを書き換えるだけなのですごく簡単
#!/bin/sh
raspivid -o - -w 1280 -h 720 -t 0 -fps 30 -b 2000000 |
ffmpeg -r 30 -i - -vcodec copy \
-f segment -strftime 1 -segment_time 60 \
-segment_format_options movflags=+faststart -segment_format mp4 \
-reset_timestamps 1 \
/home/pi/%Y-%m-%d_%H-%M.mp4
スクリプトの完成系はこんな感じです。これをサービスとしてsystemdに登録しておけば、ラズパイが起動すると自動的に録画を開始
raspividのオプション
オプション 説明
-o 出力ファイル名
-w,-h 解像度
-t 録画時間
-fps フレームレート
-b ビットレート
取得した動画データはFFmpegに渡すので-oでは出力ファイル名を指定しません。録画時間に上限を設けないなら0で良いでしょう。解像度やビットレート等はお好みで。
必要なオプションを記述したら、|でFFmpegにパイプ入力
FFmpegのオプション
オプション 説明
-r フレームレート
-i 入力ファイル
-vcodec 動画のコーデック
-strftime 出力ファイル名に日時を使用するためのオプション
-segment_time 分割時間
-segment_format_options movflags=+faststart 動画のメタデータ情報を先頭に付与する
-segment_format 分割する動画のフォーマット
-reset_timestamps セグメントのタイムスタンプのリセット
4行目以降はFFmpegについての記述になります。見やすくするために適宜改行してありますが、もちろん不要なら改行しなくてもOKです。
フレームレートはraspividコマンドで指定した数字に合わせましょう。入力ファイルについては、今回はパイプ入力するので指定しません。動画の拡張子は変換しますがコーデックは変わらないのでcopyです。
-strftimeは出力ファイル名に日時を使用するためのオプションです。-segment_timeで何秒毎に分割するのか時間を指定します。
-segment_format_options movflags=+faststartを記述しておくと、動画の読み込みにかかる時間が短縮されて再生開始が早くなります。-segment_formatはそのままです
タイムスタンプをリセットせずにセグメントファイルとして保存すると、再生時に早送りやシークができなかったり何かと不便なことになります。リセットしておけば普通の独立した動画として再生することが可能なので、リセットしておきました。
最後に出力ファイル名の指定についてですが、今回使用しているのはDATEコマンドではないので書式が異なることに注意してください。-や_の区切り方などについては自由に書き換えて大丈夫
これをもとにファイルパスを変更し
角度を調整したのが以下のスクリプト
raspivid -o - -rot 270 -w 1280 -h 720 -t 0 -fps 30 -b 2000000 | ffmpeg -r 30 -i - -vcodec copy -f segment -strftime 1 -segment_time 60 -segment_format_options movflags=+faststart -segment_format mp4 -reset_timestamps 1 /home/snowpool/Videos/%Y-%m-%d_%H-%M.mp4
これで Videosディレクトリに1分ごとの動画が保存される
あとはこれを
sudo nano /opt/record.sh
へ記述して
問題がなければ、ラズパイの起動と同時に録画を開始するためにスクリプトをサービスとしてsystemdに登録
sudo nano /etc/systemd/system/record.service
中身は
[Unit]
Description = Drive Recorder
[Service]
ExecStart = /opt/record.sh #スクリプトのパス
Restart = always
Type = simple
[Install]
WantedBy = multi-user.target
登録が完了したらサービスを有効化、起動
sudo systemctl enable record.service
sudo systemctl start record.service
サービスが正常に起動してスクリプトが実行されたらひとまずOK