ラズパイで簡易的なドライブレコーダーを作る方法として、先日カメラモジュールを使用してraspividコマンドで動画を録画する方法を紹介しました。
raspividコマンドを実行すれば、性能が低いRaspberry Pi Zeroでもそれなりのフレームレートで高画質な動画を撮ることができます。

ただし普通にraspividコマンドを実行すると、動画の拡張子がH.264の扱いにくい形式で保存されしまうのがややネック。H.264のままでも再生できる動画プレーヤーはありますが、解像度やフレームレートなどの情報を確認できなかったりするので、可能なら扱いやすいMP4形式で保存したいところです。
ラズパイでH.264からMP4へ変換する方法としてはGPACのMP4Boxを利用する方法がよく紹介されていますが、私は諸々の利便性を考慮してFFmpegを利用して自動的に変換することにしました。
そこで今回はラズパイのraspividコマンドで動画を録画する際にFFmpegでH.264からMP4に変換するメリットと、その方法について解説します。
raspividコマンドで動画を録画する際の問題点と解決策
単純に運転中の様子を録画しておきたいだけなら、カメラモジュールを接続したラズパイで普通にraspividコマンドを実行するだけでも良いのですが、この単純な実装方法だといくつかの問題があります。
拡張子が扱いにくいH.264で保存される
まず拡張子がH.264で保存されてしまうため、ファイル自体が扱いにくいです。環境によっては再生できなかったり、動画情報を確認できない場合があったりします。
拡張子がMP4の動画もコーデックは同じH.264ですが、こちらのほうが圧倒的に扱いやすいです。ただし単純に拡張子を書き換えればMP4として扱えるわけではなく、GPACなどのソフトを利用する必要があります。
録画した動画を分割して保存しないと取り出しにくい
また録画した動画を1つの巨大なファイルとして保存してしまうと、再生して目的の場面を探したり、他の記録媒体へコピーするのに時間がかかるといったデメリットもあります。
前者については映像にタイムスタンプを記録することで解決できなくもないですが、最初から分割して保存しておけば取り出したいデータだけを素早く転送することが可能です。
raspividコマンドには動画を分割して保存するためのオプション、segmentが用意されています。これを利用すれば一定時間毎に動画を分割して保存できるので、1つ1つのファイルはそれほど大きくなりません。
ただしraspividコマンドのsegmentオプションで分割すると別の問題が発生します。
分割した動画のファイル名をそれぞれの録画開始時間で保存することができない?
先日の記事では出力ファイル名を録画開始時間で保存するためにDATEコマンドを紹介しました。これを利用することで、録画開始した日時を出力ファイル名に使用することが可能になります。
しかしsegmentオプションを利用すると、分割したファイルの名前に適用される日時がすべて最初の録画開始時間になってしまいました。
連番化すれば出力ファイル名の重複は避けられるものの、分割したファイルはそれぞれの録画開始時間、つまり分割した時間で保存したいです。そのほうが絶対に確認しやすいでしょう。
ところが、あれこれ試行錯誤してみたものの私が望むようなものは作れず。Python等でプログラムを組めば作れないことはないでしょうけれども、簡単なスクリプトでは実現できそうにありませんでした。
そこでFFmpegの出番です。raspividからFFmpegへパイプ入力してFFmpegのsegmentオプションで分割すれば、これらの問題がすべて簡単に解決できます。
raspividからFFmpegへパイプ入力すれば簡単に解決できる
raspividコマンドで取得した動画をFFmpegへパイプ入力することで、これらの問題はすべて解決できました。
この方法なら録画した動画を一定時間毎に分割することも、ファイルの名前をそれぞれの録画を開始した時間にすることも、さらに拡張子をH.264からMP4に変換するのもすべて自動的に実行することが可能です。
例えば解像度1280×720、ビットレート2000kbps、フレームレート30fpsで録画して1分単位で分割すればファイルサイズは1つあたり約15MBなので、ピンポイントで転送すればWi-Fiでもそれほど時間をかけずに取り出せます。
raspividからFFmpegへパイプ入力するスクリプトを実装する
前置きが長くなりましたが、ようやく実際に手を動かしてraspividからFFmpegへパイプ入力するスクリプトを実装していきます。
といっても既にドラレコとしてraspividコマンドを実行するスクリプトを組んであるなら、それを書き換えるだけなのですごく簡単です。
raspividからFFmpegへパイプ入力するスクリプト
#!/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とFFmpegでそれぞれ利用したオプションについて簡単に説明しておきましょう。
raspividのオプション
オプション | 説明 |
---|---|
-o | 出力ファイル名 |
-w,-h | 解像度 |
-t | 録画時間 |
-fps | フレームレート |
-b | ビットレート |
まず3行目でraspividコマンドとそのオプションについて記述します。
取得した動画データは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コマンドではないので書式が異なることに注意してください。-や_の区切り方などについては自由に書き換えて大丈夫です。
スクリプトが完成したら実行&終了してみましょう。拡張子がH.264ではなくMP4の動画ファイルが生成されているはずです。
スクリプトを自動実行させるためにsystemdに登録する
問題がなければ、ラズパイの起動と同時に録画を開始するためにスクリプトをサービスとして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です。
さらにラズパイを再起動してみて自動実行されていれば成功、完成です。
これで単純にraspividコマンドを自動実行させるよりも、録画した動画ファイルが扱いやすくなりました。
あまり短い時間で分割するとファイル数が多くなり過ぎてそれはそれで面倒ですが、不意にラズパイが停止して録画中のファイルが正常に保存されなかったりしても困るので、せいぜい5分程度で区切っておくのが無難な気もします。
あとは録画したファイルをクラウドやNASに自動転送したり、一定時間が経過したファイルを自動的に削除する仕組みを作っておきたいところですが、それはまた別の記事でということで。
まとめ
raspividコマンドで録画する時、FFmpegへパイプ入力すればH.264からMP4へ自動的に変換することが可能です。
またFFmpeg側で録画ファイルを分割して、ファイル名をそれぞれの録画開始時間で保存しておけば、目当てのデータを取り出しやすくなるメリットもあります。
ラズパイでドラレコを作ろうとしている方の参考になれば幸いです。
コメント