Raspberry PiでMJPEG録画の遅延を最小化!決まった時間の映像をきれいに保存する方法

みなさん、こんにちは。

Raspberry Pi で mjpg-streamer や qstreamer などを使って監視カメラシステムを構築した場合、後で見返すために録画したいことがありますよね。

「毎日同じ時間帯の映像を記録しておきたい」「特定イベント発生時ではなく、決まった時間の映像を保存しておきたい」といった場合、映像がリアルタイムから大きく遅れていてガッカリ、なんて経験はありませんか?

そこで今回は、Raspberry Piで配信しているMJPEG映像を、最小限の遅延で、決まった時間の映像としてきれいに保存する方法をご紹介します。ポイントは、Raspberry PiのCPUに負担をかけず、古いフレームをどんどん捨てて常に最新の映像に追従することです。

 


 

遅延を最小化する基本方針

 

今回の方法のキモは、ffmpegというコマンドラインツールを使います。そして、以下の3つのポイントを守ることで、遅延を最小限に抑えます。

  1. 再エンコードはしない!
    • Raspberry Pi側で映像を再エンコードすると、CPUに大きな負荷がかかってしまいます。今回は-c copyオプションを使い、MJPEGストリームをそのままコピーして保存します。これならCPUの負荷はほぼゼロです。
  2. 古いフレームは捨てる!
    • 遅延が蓄積しないように、受信が遅れた古いフレームは容赦なく捨てて、常に最新の映像に追従させます。
  3. バッファを使わない!
    • 入力や書き込みのバッファを最小化し、受け取ったデータをすぐに処理します。

これらのポイントを踏まえた、具体的なffmpegコマンドを見ていきましょう。

 


 

ffmpegのバージョン別コマンド例

 

Raspberry Pi OSやインストール方法によって、ffmpegのバージョンが異なります。お使いのバージョンに合わせて、以下のコマンドを試してみてください。

ffmpeg 4系の場合

ffmpeg \
    -fflags nobuffer+genpts+discardcorrupt \
    -flags low_delay \
    -framedrop \
    -avoid_negative_ts make_zero \
    -i http://localhost:8080/?action=stream \
    -c copy \
    -f segment -segment_time 600 \
    /home/pi/videos/%Y-%m-%d_%H-%M-%S.avi

このコマンドを、例えばcronなどを使って、毎日10時に実行するように設定することで、毎日10時から10分間の映像を保存できます。

ffmpeg 5系の場合

ffmpeg \
    -fflags nobuffer+genpts+discardcorrupt \
    -flags low_delay \
    -framedrop \
    -use_wallclock_as_timestamps 1 \
    -avoid_negative_ts make_zero \
    -i http://localhost:8080/?action=stream \
    -c copy \
    -f segment -segment_time 600 \
    /home/pi/videos/%Y-%m-%d_%H-%M-%S.avi

ffmpeg 6系の場合

ffmpeg \
    -fflags nobuffer+genpts+discardcorrupt \
    -flags low_delay \
    -framedrop \
    -use_wallclock_as_timestamps 1 \
    -avoid_negative_ts make_zero \
    -thread_queue_size 128 \
    -i http://localhost:8080/?action=stream \
    -c copy \
    -f segment -segment_time 600 \
    /home/pi/videos/%Y-%m-%d_%H-%M-%S.avi

 


 

各オプションの役割をチェック!

 

コマンドに出てくるオプションの意味を簡単に解説します。特に、遅延をなくすための重要なオプションに注目してみてください。

  • -fflags nobuffer
    • 入力バッファを使わずに、すぐに処理を始めます。
  • -flags low_delay
    • 低遅延モードを有効にします。
  • -framedrop
    • 遅れて到着したフレームを破棄し、常に最新のフレームに追従します。
  • -c copy
    • 再エンコードせず、そのままコピー保存します。CPU負荷を最小限に抑える一番のポイントです。
  • -use_wallclock_as_timestamps 1
    • 受信した時刻をそのままタイムスタンプとして利用します(ffmpeg 5系以降で推奨)。
  • -f segment -segment_time 600
    • 600秒(10分)ごとにファイルを分割して保存します。これにより、必要な時間の映像だけを効率的に保存できます。
  • /home/pi/videos/%Y-%m-%d_%H-%M-%S.avi
    • 録画ファイル名に日時を自動で付与します。

実運用でのヒント

  • 保存先は?
    • 保存先がmicroSDカードだと、書き込みの負荷で寿命が短くなる可能性があります。USBメモリや外付けSSDを保存先にするのがおすすめです。
  • ネットワーク経由でもOK
    • このコマンドは、同じネットワーク上の別のPCなどからMJPEGストリームを取得して録画する場合にも使えます。

 


 

まとめ

 

いかがでしたか?

今回の設定の鍵は、再エンコードせずにmjpegをそのまま保存すること、そして、-fflags nobuffer-flags low_delay-framedropの3つのオプションで遅延を溜めないことです。

この方法なら、Raspberry Piでも軽快かつリアルタイムに近い録画が実現できますよ!

みなさんも、ぜひ試してみてください。

 

本日も最後までお読みいただきありがとうございました。

それでは、よいRaspberry Piライフを!

コメントする

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

上部へスクロール