プログラムを中心とした個人的なメモ用のブログです。 タイトルは迷走中。
内容の保証はできませんのであしからずご了承ください。

2024/02/15

[python] ONVIF 対応カメラの RTSP 接続文字列を取得する

event_note2024/02/15 8:52

ネットワークカメラの映像を取得するためにまず RTSP の接続文字列を取得する必要があったので、ONVIF の Profile S から取得してみました。

ONVIF Profile S の仕様は以下にあります。

尚、単純に RTSP の接続文字列を取得したいだけなら ONVIF Device Manager というツールがあるので、それを使ったほうが楽です。

環境

  • python 3.11
  • onvif-zeep 0.2.12
  • onvif2-zeep 0.3.4

ONVIF クライアントの python 実装である onvif-zeep onvif2-zeep を使ってみました。
この2つの違いですが、以下のページによれば、onvif2-zeep のほうは WSDL と H.265 に対応しているようです。

以下、onvif-zeep onvif2-zeep それぞれのサンプルコードです。

onvif-zeep でのサンプル

準備

pip install onvif-zeep

サンプルコード

from onvif import ONVIFCamera

def get_all_rtsp_urls(camera_ip, username, password):
    # ONVIFデバイスに接続
    camera = ONVIFCamera(camera_ip, 80, username, password)

    # プロファイルを取得
    media = camera.create_media_service()
    profiles = media.GetProfiles()
    #print(profiles)

    # すべてのプロファイルに対して RTSP URL を取得
    for profile in profiles:
        name = profile['Name']
        try:
            token = profile['token']
            stream_uri = media.GetStreamUri({
                'StreamSetup': {
                    'Stream': 'RTP-Unicast',
                    'Transport': {
                        'Protocol': 'RTSP'
                    }
                },
                'ProfileToken': token
            })
            uri = stream_uri.Uri
            print(f'{name}: {uri}')
        except Exception as e:
            print(f'{name}: {e}')

if __name__ == "__main__":
    camera_ip = "192.168.0.1"
    username = "username"
    password = "password"

    get_all_rtsp_urls(camera_ip, username, password)

onvif2-zeep のサンプル

準備

pip install onvif2-zeep

WSDL のダウンロード

onvif2-zeep を使用する場合、WSDL のファイル一式が必要なようです。
以下のリポジトリからダウンロードできます。

サンプルコード

上記のコードから以下の2箇所を変更するだけです。

from onvif2 import ONVIFCamera

...

camera = ONVIFCamera(camera_ip, 80, username, password, './wsdl')

ONVIFCamera の引数の最後で、WSDL ファイルのあるパスを指定します。

実行結果

Panasonic のカメラで試した結果が以下となります。

H264_1280x960: rtsp://192.168.0.1/ONVIF/MediaInput?profile=1_def_profile8
H264_800x600: rtsp://192.168.0.1/ONVIF/MediaInput?profile=1_def_profile7
H264_640x480: rtsp://192.168.0.1/ONVIF/MediaInput?profile=1_def_profile6
H264_320x240: rtsp://192.168.0.1/ONVIF/MediaInput?profile=1_def_profile5
JPEG_1280x960: rtsp://192.168.0.1/ONVIF/MediaInput?profile=1_def_profile4
JPEG_800x600: rtsp://192.168.0.1/ONVIF/MediaInput?profile=1_def_profile3
JPEG_640x480: rtsp://192.168.0.1/ONVIF/MediaInput?profile=1_def_profile2
JPEG_320x240: rtsp://192.168.0.1/ONVIF/MediaInput?profile=1_def_profile1

ただ、H.265 のストリームがあるカメラ場合、onvif-zeep onvif2-zeep のどちらで試しても以下のように Unknown error: Configuration not complete のエラーが出て取得することができませんでした。

H26x_1: Unknown error: Configuration not complete
H26x_2: Unknown error: Configuration not complete
JPEG_1: rtsp://192.168.0.1/ONVIF/MediaInput?profile=def_profile5
JPEG_2: rtsp://192.168.0.1/ONVIF/MediaInput?profile=def_profile6

カメラ側のプロファイル設定の問題のような気がしますが、よくわかりませんでした。

ちなみに、他に TOA のカメラも試しましたが、こちらは H.265 の場合でも問題なく取得することができました。