続 ネットワークカメラの映像をラズパイでモニタする

IT・DX

6月のブログ「ネットワークカメラの映像をラズパイでモニタする」の後、ChatGPTがGPT5になり、さらに相談し、検討しました。
結論としては、pythonのスクリプトにすることで、遅延せず、軽く落ちないシステムになりました。
Raspberry Pi zero Wでも問題なく動いたので備忘録として残します。

1.Pi zero Wの初期設定

①Pi OSの通常版(Bookworm)をインストールし、GUIでWiFiや各初期設定をしておきます。Desktopが普通に使える設定にできた後、raspi-configでCUIにします。

②CUIでHDMIから音が出るか確認します。GUIで音がでてもCUIでは設定が別なようです。

speaker-test -c1 -twav

音が出ない場合はalsaやpulseaudioの設定を確認してください。(ChatGPTに聞けば教えてくれます)

2.pythonのgstライブラリを追加

下記でライブラリを追加してください。

sudo apt install -y \
    gstreamer1.0-plugins-base \
    gstreamer1.0-plugins-good \
    gstreamer1.0-plugins-bad \
    gstreamer1.0-plugins-ugly \
    gstreamer1.0-libav

3.pythonスクリプト

下記のrtsp-tee.pyファイルをつくります。カメラのadminパスワード、ip address、rtsp番号(26112)は適宜修正してください。

import gi
gi.require_version('Gst', '1.0')
from gi.repository import Gst, GLib

def on_message(bus, message, loop):
    msg_type = message.type
    if msg_type == Gst.MessageType.EOS:
        print("End-of-Stream")
        loop.quit()
    elif msg_type == Gst.MessageType.ERROR:
        err, debug = message.parse_error()
        print(f"Error: {err}: {debug}")
        loop.quit()

Gst.init(None)

pipeline = Gst.parse_launch(
    'rtspsrc location=rtsp://admin:xxxx@192.168.xxx.xxx:26112/ipcam_h264.sdp '
    'latency=0 protocols=tcp name=src '
    # 映像パイプライン
    'src. ! rtph264depay ! avdec_h264 ! queue max-size-buffers=0 max-size-bytes=0 max-size-time=0 '
    '! videoconvert ! autovideosink sync=false '
    # 音声パイプライン
    'src. ! rtpmp4gdepay ! avdec_aac ! queue max-size-buffers=0 max-size-bytes=0 max-size-time=0 '
    '! audioconvert ! audioresample ! alsasink sync=false'
)

bus = pipeline.get_bus()
loop = GLib.MainLoop()
bus.add_signal_watch()
bus.connect("message", on_message, loop)

pipeline.set_state(Gst.State.PLAYING)

try:
    loop.run()
except KeyboardInterrupt:
    print("Stopping...")

pipeline.set_state(Gst.State.NULL)

下記の実行でカメラのモニタ画像がTVにうつるはずです。

$python3 rtsp-tee.py 

4.shellスクリプト

それでも、ネットワークが切れたり、カメラ遅延の理由でpythonが落ちることがあります。
shellのスクリプトでretryやrebootでカバーします。
ファイル名は適宜修正してください。

#!/bin/bash

# ログ保存先
LOGDIR="/home/xxx/log/rtsp"
mkdir -p "$LOGDIR"

cd /home/xxx
export GST_PLUGIN_FEATURE_RANK=avdec_h264:MAX,v4l2h264dec:NONE
export GST_DEBUG=rtsp*:3,uridecodebin*:3

# ログファイル名
LOGFILE="$LOGDIR/tee.log"

# 古いログをローテーション(任意)
[ -f "$LOGFILE" ] && mv "$LOGFILE" "$LOGFILE.$(date +%Y%m%d%H%M%S)"

echo "$(date) shell start" | tee -a "$LOGFILE"

# ネットワーク接続確認(初回)
until ping -c1 192.168.24.1 >/dev/null 2>&1; do
    sleep 1
done

# 監視対象のエラーパターン
ERROR_PATTERNS=("Streaming stopped" "Internal data stream error" "GLib-GObject-CRITICAL" "GStreamer-CRITICAL" "gst-resource-error")

# メインループ
while true; do
  echo "$(date) gstl start" | tee -a "$LOGFILE"

  # ---- Ping 遅延のログ記録部分(6ms以上)----
  PING_RESULT=$(ping -c1 -W1 192.168.24.xxx | grep 'time=')
  if [[ $PING_RESULT =~ time=([0-9.]+) ]]; then
    RTT=${BASH_REMATCH[1]}
    if (( $(echo "$RTT > 6" | bc -l) )); then
      echo "$(date) [WARN] Ping delay: ${RTT} ms" | tee -a "$LOGFILE"
    fi
  else
    echo "$(date) [ERROR] No ping reply from 192.168.24.xxx" | tee -a "$LOGFILE"
  fi
  # ----------------------------------------------

  python3 rtsp-tee.py >> "$LOGFILE"

  echo "$(date) tee exited with status $?" | tee -a "$LOGFILE"

  # エラーパターン検出で再起動
  for pattern in "${ERROR_PATTERNS[@]}"; do
    if tail -n 100 "$LOGFILE" | grep -q "$pattern"; then
      echo "$(date) [FATAL] Detected critical error: '$pattern' ? Rebooting..." | tee -a "$LOGFILE"
      sudo reboot
    fi
  done

  sleep 3
done

echo "$(date) tee stop" | tee -a "$LOGFILE"

シェルの自動起動はsystemctlに登録しました。
登録の仕方もChatGPTに聞けば教えてくれます。

1. サービスファイルを作成

サービスは通常 /etc/systemd/system/ に置きます。
例:/etc/systemd/system/myapp.service

[Unit]
Description=My Python App
After=network.target

[Service]
ExecStart=/usr/bin/python3 /home/pi/myapp.py
WorkingDirectory=/home/pi
Restart=always
User=pi

[Install]
WantedBy=multi-user.target


ポイント:
ExecStart= に実行するコマンド(フルパス)を書く
User= に実行ユーザー(例: pi)を書く
Restart=always で落ちても再起動する

2. systemd に認識させる
sudo systemctl daemon-reload

3. サービスを有効化
起動テスト:
sudo systemctl start myapp.service

状態確認:
systemctl status myapp.service

自動起動設定:
sudo systemctl enable myapp.service

アイオーのネットワークカメラでは、HD画質でのweb再生(常時モニタ)は2台までですが、ラズパイの場合はそのような制限はないようです(多数接続すると遅延がおきるかも)

コメントお待ちしております。

コメントを残す

コメント