ONVIFでネットワークカメラを操作する【PHP】
社内のIoTプロジェクトでネットワークカメラを操作することになりました。
公式のAPIが用意されていればそれを使用して操作することが出来ます。
公式APIが存在しない場合に調査していただきたいのが、ONVIFです。
まずはONVIFについて少し説明します。
ONVIF(Open Network Video Interface Forum)について
引用リンク:ONVIF公式
引用すると、
❞------------------------------
ONVIF は、 IP ベースの物理的セキュリティ製品の効果的な相互運用性のために標準化されたインターフェイスを提供および促進するオープンな業界フォーラムです。
❞------------------------------
メーカーごとにバラバラのインターフェースだとシステムのカスタマイズや組み込みをする際に、メーカーごとに対応する必要があります。
ONVIFを準拠した製品を選択することで規格として決められた機能を使用することが可能です。
結果的に機器選択の幅を広げたり、組み込みのコストを抑えるという良さがあります。
ONVIF準拠製品のデータベースが公式に存在するので、採用予定の機器が準拠しているか調べてみてください。
リンク:ONVIF準拠製品
PHPで使ってみる
ONVIFとの通信をするためにはSOAPというXMLベースの通信プロトコルを使用するようです。
今回使用するまで使ったこともない通信でした。
すこし複雑なメッセージに基づいているため、こちらのライブラリを使用していきたいと思います。
https://github.com/KuroNeko-san/ponvif
READMEに記述してある通りにクラス読み込みから機器の発見までいきます。
//ライブラリの読み込み
require 'class.ponvif.php';
$onvif = new Ponvif();
$result = $onvif->discover();
var_dump($result);
ネットワーク内に該当機器が存在する場合には配列形式で結果が返却されます。
IPAddrキーの値が機器のIPなので、操作したい機器の情報を取得しておきましょう。
次に、メディアストリームのURIを取得してみます。
//ライブラリの読み込み
require 'class.ponvif.php';
$onvif = new Ponvif();
//公式アプリ等で設定したユーザー名
$onvif->setUsername('admin');
//公式アプリ等で設定したパスワード
$onvif->setPassword('password');
//機器のIP
$onvif->setIPAddress('192.168.1.108');
try
{
//初期化
$onvif->initialize();
//機器のソースを取得
$sources = $onvif->getSources();
//トークンを取得
$profileToken = $sources[0][0]['profiletoken'];
//ストリームのURI
$mediaUri = $onvif->media_GetStreamUri($profileToken);
var_dump($mediaUri);
}
catch(Exception $e)
{
echo $e->getMessage();
}
初期化した時にライブラリにエラーが出てしまいました。
extension=soap
extension=sockets
この二つのPHP拡張が有効化されていないことが原因でした。
php.iniからコメントアウトされていた該当部分を有効化したら動きました。
動かない場合は試してみてください。
最後にパンチルト操作を行っていきます。
機器が対応している場合は使用できる機能なので注意。
//ライブラリの読み込み
require 'class.ponvif.php';
$onvif = new Ponvif();
//公式アプリ等で設定したユーザー名
$onvif->setUsername('admin');
//公式アプリ等で設定したパスワード
$onvif->setPassword('password');
//機器のIP
$onvif->setIPAddress('192.168.1.108');
try
{
//初期化
$onvif->initialize();
//機器のソースを取得
$sources = $onvif->getSources();
//トークンを取得
$profileToken = $sources[0][0]['profiletoken'];
//パンチルト操作
$onvif->ptz_RelativeMove($profileToken, x方向の回転角度, y方向の回転角度, x方向の回転速度, y方向の回転速度);
}
catch(Exception $e)
{
echo $e->getMessage();
}
profileのトークン取得後のptz_RelativeMove関数が操作を行っています。
まとめ
ONVIFのように標準化してもらえると便利ですね。
他の機能を使いたい場合、ライブラリのクラスがシンプルで読みやすいので探してみてください。
以上になります、ありがとうございました。
プログラマー/K.D