0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

(IoT共通)ネットワークカメラをRTSPで受信し、動体検知の前後20秒分の動画を残す

Posted at

■概略

◯RTSPサーバとRTSPクライアント(ffmpeg)

最近のネットワークカメラはRTSPサーバになれる
※今回はPanasonic WV-S1536Lを使用
Linux(MA-X300を使用)でffmpegを使えばRTSPクライアントになれる
これでカメラ画像をMP4で記録することができる

◯ネットワークカメラの動体検知

最近のネットワークカメラには動体検知機能がある
 ※画像内で動きが発生したら通知してくれる
1)通知をLinuxにRESTで通知する
2)MP4を通知の前後10秒の合計20秒の動画にして保存する
これで動体検知した画像だけを残すことができる

■カメラ側

◯概略とカメラ設定

1)ネットワークカメラをRTSPサーバにして、MA-X300で常時受信する
 受信したmp4は/ramdiskに10秒ごとに別ファイルで保存する
 /ramdiskの容量は少ないので10分経過で削除する
2)RESTサーバで動体検知通知を受信する
 10秒後に最新3のmp4を1つのmp4にして/mp4に保存する

◯認証方法

rtspをID/PW認証する場合は以下のようにURLにID/PWを記載する

rtsp://{ネットワークカメラのIP}:554/Src/MediaInput/stream_1
 ↓
rtsp://{ID}:{パスワード}@{ネットワークカメラのIP}:554/Src/MediaInput/stream_1

しかしMA-X300のUbuntu22.04(ARM64)のffmpegではID/PWの指定をするとエラーになる
そのためネットワークカメラはID/PW認証を止め、IP認証にする

ネットワークカメラのWebI/Fにログインし、

ユーザ管理-ユーザ認証をoff
ユーザ管理-ホスト認証をonにして必要なIP(ここではMA-X300のIP)を追加

◯カメラ設定

歯車マークの[設定]-[詳細設定]-[カメラの詳細設定]-[映像/音声]-[映像]
以下変更点と重要点のみ

初期表示ストリーム ストリーム(1)
JPEG画像更新速度(動画時) 5fps
ストリーム配信 On
JPEG(1) 解像度 1280x720
ストリーム配信 ◎ON
圧縮方式 H.264
※H.265だとWindows Media Playerで再生
 できない
解像度 1280x720
※FD。FullHD(1920x1024)・15fpsにするかも
配信モード ベストエフォート配信
フレームレート 5fps
※6.1MB/分 ramdiskに保存できるように
 容量は少なくする
1クライアントあたりのビットレート 1024kbps

 

◯カメラ動体検知設定

歯車マークの[設定]-[詳細設定]-[カメラの詳細設定]-[アラーム]-[動作検知エリア]
 [全領域]をクリックする
歯車マークの[設定]-[詳細設定]-[カメラの詳細設定]-[アラーム]-[通知]-[HTTPアラーム通知]
通知先1 : http://{ネットワークカメラのIP}
 アラーム(左のチェックボックス) : x
 通知データ : /notice
 ※http://{ネットワークカメラのIP}/api/v1/notice にRESTサーバを用意する

 

■MA-X300側

◯処理の流れ

1) カメラからRTSP受信常駐プログラム

プログラム名 : restserver_local/batch/systemd_rtspRecording1.py
ffmpegコマンドでeth1のLAN側にあるカメラにRTSP接続し
10秒毎のmp4ファイルを/ramdiskに
{カメラ名}_yyyymmdd_HHMMSS.mp4の形式で作成しつづけている
MA-X300が複数台のカメラを受信する場合複数の常駐プログラムが必要

◯ffmpeg他インストール
# apt install -y ffmpeg
# apt install -y python3-venv
# cd /var/www
# python3 -m venv python3-venv
# source /var/www/python3-venv/bin/activate
(python3-venv) root@netcam:~# pip3 install requests
◯ffmpeg常駐スクリプト

MA-X300上のffmpegで以下のオプションで受信ができる
-c:v copy を指定しないと再度エンコードを行おうとしてCPU稼働率が激上がりする

pythonの設定はRESTサーバもcronもsystemdも全てconfg.pyで設定する

/var/www/ismscam/batch/config.py

device_name  = 'emboma-matsuyama'
camera1_url  = 'rtsp://{ネットワークカメラのIP}:554/Src/MediaInput/stream_1'
camera1_name = 'camera1'

/var/www/ismscam/batch/systemd_rtspRecording1.py

import config
…
cmd = 'ffmpeg -rtsp_transport tcp -i "{config.camera1_url}" \
    -f segment -segment_time "10" -segment_format_options movflags=+faststart \
    -c:v copy \
    -reset_timestamps "1" -strftime "1" /ramdisk/{config.camera1_name}_%Y%m%d_%H%M%S.mp4'
…
○ffmepg起動スクリプト

/etc/systemd/system

[Unit]
Description=RTSP Recording 1
After=network.target

[Service]
Type=simple
PIDFile=/var/run/systemd_rtspRecording1.pid
RemainAfterExit=no
Restart=on-failure
RestartSec=10
ExecStart=/var/www/ismscam/batch/systemd_rtspRecording1.py

[Install]
WantedBy=multi-user.target
# systemctl enable rtsprecording1
# systemctl start rtsprecording1

/ramdiskに10秒ごとにmp4が書き出されれば成功

2) 10分経った/ramdiskの古いmp4を削除するcronプログラム

プログラム名 : restserver_local/batch/cron_rmOldMP4_1.bash
cronで1分毎に起動し、10分経過した特定のカメラが受信したmp4を削除している
複数台のカメラを受信する場合は複数の削除プログラムが必要
削除は他に、以下がある
・/mp4のn日経ったmp4を削除する
・DISKが90%超で最古のMP4を1つ強制削除する

◯/ramdiskの10分以上経ったMP4を削除するcron

カメラ毎に下記cronをrootで登録し、/ramdiskの10分以上経ったmp4は自動的に削除されるように設定する
config.pyのcamera_nameを設定する

# crontab -e
*/1 * * * * /var/www/ismscam/batch/cron_rmOldMP4_1.bash > /dev/null 2>&1
---
find /ramdisk -mmin +10 -name "camera1*.mp4" | xargs rm -f
---

3) カメラのHTTP通知をWebサーバで受信しMP4を合成する

カメラで動体検知をするとWebサーバにHTTP通知する
10秒毎に分割されているMP4を必要な本数結合し/mp4に保存する

◯bottle.pyでRESTサーバを作成する

/api/v1/notice部分

### REST API
# mp4ファイルを結合し/mp4に保存する
@route('/api/v1/notice', method='GET')
@route('/api/v1/notice/<camera>', method='GET')
def notice(camera=''):
    forms = getUTF8forms(request.forms)
    result = {}

    result['camera'] = camera
    if camera == '':
        result['message'] = 'No camera name!'
        return template('notice', dict(forms=forms, result=result))

    nowtime = datetime.now().strftime('%Y%m%d%H%M%S')
    # ローカル出力ファイル
    # mp4結合ファイル:{device_name}_{camera}_yyyymmddHHMMSS.mp4
    localout_filename = '{0}_{1}_{2}.mp4'.format(config.device_name, camera, nowtime)
    localout_filepath = '/mp4/{0}'.format(localout_filename)
    # ローカル入力ファイル 呼び出しから10秒後の最新mp4を3つ取得する
    # カメラからのmp4:{camera}_yyyymmddHHMMSS.mp4
    time.sleep(10)
    files = glob.glob("/ramdisk/{0}*mp4".format(camera))
    files.sort()
    files = files[-3:]
    # 結合対象を書いたファイル
    target_file = "{0}_targets".format(localout_filepath)
    fileobj = open(target_file, "w", encoding = "utf_8")
    for i in range(3):
        fileobj.write("file {0}\n".format(files[i]))
    fileobj.close()
    # 3つのmp4を結合し結合対象を書いたファイルを削除
    cmd = 'ffmpeg -f concat -safe 0 -i {0} -c copy {1}'
    cmd = cmd.format(target_file, localout_filepath)
    ret = subprocess.run(cmd, shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
    os.remove(target_file)
    # 画面表示用にファイル名とファイルサイズを取得
    result['mp4file_name'] = localout_filename
    if os.path.exists(localout_filepath):
        result['mp4file_size'] = os.path.getsize(localout_filepath)

    return template('notice', dict(forms=forms, result=result))
◯/mp4の7日以上経ったMP4を削除するcron

カメラ毎に下記cronをrootで登録し、/mp4の7日以上経ったmp4は自動的に削除されるように設定する
config.pyのcamera_nameを設定する

---
# crontab -e
*/1 * * * * /var/www/ismscam/batch/cron_rmOldStorageMP4_1.bash
---
find /mp4 -mtime 7 -name "camera1*.mp4" | xargs rm -f
---
◯DISK90%超で最古のMP4を強制的に削除するcron(毎分)
# crontab -e
*/1 * * * * /var/www/ismscam/batch/cron_rmOldestMP4.bash > /dev/null 2>&1
---
#!/bin/bash
# DISK利用率90%を超えたら最も古いMP4を1つ削除する
use=`df -h|grep root|awk '{print $5}'|sed "s/%//"`
if [ $use -gt 90 ]; then
    mp4file=`ls -ltr /mp4| tail -n +2 | head -1|awk '{print $9}'`
    /bin/rm '/mp4/'$mp4file
fi
---

4) その他

◯ Scoreboard is Fullエラーを抑える

MX-X300でWebアプリを動かすと、半日程度稼働させると、apache2のerror_logに下記のエラーが頻発し、
Webアクセスができなくなる

AH03490: scoreboard is full, not at MaxRequestWorkers.Increase ServerLimit  .

下記のファイルの以下をコメントアウトし、apache2を再起動する
/etc/apache2/mods-available/mpm_event.conf
/etc/apache2/mods-available/mpm_prefork.conf
/etc/apache2/mods-available/mpm_worker.conf

#   MaxConnectionsPerChild   0
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?