LoginSignup
7
5

More than 5 years have passed since last update.

Eagle Eye Networks APIで簡単ビデオ連携 その1 静止画取得

Last updated at Posted at 2016-10-03

Eagle Eye Networks APIで簡単ビデオ連携 その1 静止画取得

昨今色々と話題の豊富なクラウド型の動画管理システム(VMS)ですが、あまり連携事例も情報量が無く、Qiitaでもあまり例が無さそうですので、ここで「Eagle Eye Networks」(以下EEN)という完全クラウド型のVMSを使用した連携例を紹介してみたいと思います。

EENで静止画を取得できると何かいいのか??

今までのオンプレ型のVMSでも、静止画のエクスポートを行えばシステム間連携はできるし、保存もできます。じゃあなんでEENで取得して連携するのか?それは端的に言えば「元々クラウドにデータがあれば、クラウドシステムとの連携って簡単でしょ?」ということです。しかもリトリーブするために新たにシステムを組むなど、非生産的なことをせずに簡単にRESTで取得できる、ということで一番のメリットだと思います。
この仕組を使えば、

  • 入退室管理のタイムスタンプだけで、簡単にその時の静止画が取れる
  • 動画だと回線的に厳しい環境でも、静止画の連続gifならなんとかなるようなもの

にも簡単にシステムが適用できます。

環境

EENはIPカメラとそれに電源を供給しながら通信を行うPoEスイッチ、そしてEENのクラウドデータセンターと接続するためのブリッジという構成で実装します。
EENが実際にどのように動作するかは以下のサイトを御覧ください。
EEN製品サイト(日本語)

またEENのAPIについてはネットで公開されているので、こちらもご参照下さい(全然途中までですが)。
EEN APIサイト(日本語)

必要なもの
- EENのアカウント
- EENに対応しているIPカメラ
- PoEスイッチ
- IBM Bluemixのアカウント
- Bluemix上のnode.jsのランタイム
- 上記ランタイム上で動くNode-RED
- node-red-contrib-json(package.jsonで事前に読み込みすること)

前提条件
- EENのサブスクリプション契約があること
 試用版については上記サイトを参照
- Bluemixのサブスクリプション契約があること
 試用版についてはBluemixのサイトを参照

事前確認

実際に接続を行う前に、2点確認事項があります。
まずは、

  1. API連携を行うユーザーID、パスワードを確認
  2. EENのWeb画面でカメラが認識されていることを確認

以下のような感じでWeb画面に表示されていればOKです。
Layout.png

Node-REDでインポート

下記のJSON DocをデプロイしたNode-RED上にインポートしてみてください。

  • 認証、認可用ノード
[{"id":"977ab801.29e488","type":"inject","z":"ba43e00b.410be","name":"","topic":"","payload":"","payloadType":"str","repeat":"3600","crontab":"","once":true,"x":110,"y":400,"wires":[["dc2123d7.9639d"]]},{"id":"dc2123d7.9639d","type":"function","z":"ba43e00b.410be","name":"Get Auth Head","func":"var user = \"<User ID>\";\nvar password = \"<Password>\";\nmsg.payload = 'username=' + user + '&password=' + password;\nreturn msg;","outputs":1,"noerr":0,"x":340,"y":400,"wires":[["a175b66d.8cb478"]]},{"id":"a175b66d.8cb478","type":"http request","z":"ba43e00b.410be","name":"","method":"POST","ret":"obj","url":"https://login.eagleeyenetworks.com/g/aaa/authenticate","x":330,"y":460,"wires":[["df64b846.5dc978"]]},{"id":"df64b846.5dc978","type":"http request","z":"ba43e00b.410be","name":"","method":"POST","ret":"obj","url":"https://login.eagleeyenetworks.com/g/aaa/authorize","x":330,"y":520,"wires":[["73b7e889.bc36f8"]]},{"id":"73b7e889.bc36f8","type":"contrib-json","z":"ba43e00b.410be","engine":"JSONPath","command":"jq","expr":"$.headers.set-cookie[1]","complete":"complete","prop":"payload","name":"Put Cookie","x":650,"y":400,"wires":[["e994bf64.d51cb"]]},{"id":"e994bf64.d51cb","type":"function","z":"ba43e00b.410be","name":"Form Auth Key2","func":"var cookies = msg.payload[0].split(\"; \");\nfor (var i = 0; i < cookies.length; i++) {\n\tvar str = cookies[i].split(\"=\");\n\tif (str[0] === \"auth_key\") {\n\t\tglobal.set(\"auth_key2\", unescape(str[1]));\n\t\tbreak;\n\t}\n}\nmsg.payload = global.get(\"auth_key2\");\nreturn msg;","outputs":1,"noerr":0,"x":660,"y":460,"wires":[["cf84a0d5.fefc5"]]},{"id":"173b1941.36c997","type":"comment","z":"ba43e00b.410be","name":"Generate EEN Auth Key loop #2","info":"","x":190,"y":340,"wires":[]},{"id":"cf84a0d5.fefc5","type":"debug","z":"ba43e00b.410be","name":"","active":false,"console":"false","complete":"false","x":650,"y":520,"wires":[]}]
  • 静止画表示用ノード
[{"id":"7bddddbf.fd52a4","type":"http in","z":"13af9bb0.48d9b4","name":"GetLivePreview","url":"/eengetprev","method":"get","swaggerDoc":"","x":140,"y":620,"wires":[["ecd24ef4.d8883"]]},{"id":"fbe621e.5f684e","type":"change","z":"13af9bb0.48d9b4","name":"Restore Header","rules":[{"t":"delete","p":"headers","pt":"msg"},{"t":"set","p":"headers","pt":"msg","to":"orgheaders","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":680,"y":740,"wires":[["9b4dd731.f54048"]]},{"id":"9b4dd731.f54048","type":"http response","z":"13af9bb0.48d9b4","name":"","x":890,"y":740,"wires":[]},{"id":"6df3c0.309e5c4","type":"comment","z":"13af9bb0.48d9b4","name":"Get EEN Live Preview","info":"### Usage\nhttp://<My Bluemix Site>.mybluemix.net/eengetprev?camName=<Camera Name>&test=<0 or 1>\n\n- camName\n    - Camera Display Name\n\n- test\n  If 'test' parameter specify to '1', Live video is not shown and return only 'Return code'.\n  This parameter is option .\n\n### Example\nhttp://<My Bluemix Site>.mybluemix.net/eengetprev?camName=EN-CDUM-002a&test=1\n","x":160,"y":560,"wires":[]},{"id":"ecd24ef4.d8883","type":"function","z":"13af9bb0.48d9b4","name":"Get Auth & Set EENTS","func":"msg.orgheaders=msg.req.headers;\n\nif (msg.payload.auth_key) {\n    msg.auth_key = msg.payload.auth_key;\n} else {\n    msg.auth_key = global.get(\"auth_key2\");\n}\n\nif (msg.payload.camName) {\n    msg.camName = msg.payload.camName;\n}\n\nif (msg.payload.test) {\n    msg.test = msg.payload.test;\n}\n\nvar st_UTC_do = new Date();\nmsg.st_UTC = [st_UTC_do.getFullYear(),\n                ( '0' + (st_UTC_do.getMonth() + 1)).slice(-2),\n                ( '0' + st_UTC_do.getDate() ).slice(-2),\n                ( '0' + st_UTC_do.getHours() ).slice( -2 ),\n                ( '0' + st_UTC_do.getMinutes() ).slice( -2 ),\n                ( '0' + st_UTC_do.getSeconds() ).slice( -2 )\n                ].join(\"\");\n\nvar st_JST_do = new Date(st_UTC_do.getTime() + 32400000);\nmsg.st_JST = [st_JST_do.getFullYear(),\n                ( '0' + (st_JST_do.getMonth() + 1)).slice(-2),\n                ( '0' + st_JST_do.getDate() ).slice(-2),\n                ( '0' + st_JST_do.getHours() ).slice( -2 ),\n                ( '0' + st_JST_do.getMinutes() ).slice( -2 ),\n                ( '0' + st_JST_do.getSeconds() ).slice( -2 )\n                ].join(\"\");\n\nreturn msg;","outputs":1,"noerr":0,"x":390,"y":620,"wires":[["c9075a91.0664e8"]]},{"id":"c9075a91.0664e8","type":"http request","z":"13af9bb0.48d9b4","name":"Get Camera ID","method":"GET","ret":"obj","url":"https://login.eagleeyenetworks.com/g/device/list?A={{auth_key}}&t=camera","tls":"","x":360,"y":680,"wires":[["29278254.814d5e"]]},{"id":"29278254.814d5e","type":"function","z":"13af9bb0.48d9b4","name":"Pull CamID","func":"var camLength = msg.payload.length;\n\nfor (itr = 0; itr < camLength; itr++){\n    var camIdx = msg.payload[itr].indexOf(msg.camName);\n    if ( camIdx > 0 ) {\n        msg.camID = msg.payload[itr][camIdx - 1];\n    }\n}\n\nreturn msg;","outputs":1,"noerr":0,"x":350,"y":740,"wires":[["e016f2f3.68a15"]]},{"id":"e016f2f3.68a15","type":"http request","z":"13af9bb0.48d9b4","name":"Get Imge","method":"GET","ret":"bin","url":"https://login.eagleeyenetworks.com/asset/after/image.jpeg?timestamp={{st_UTC}}.000;id={{camID}};A={{auth_key}};asset_class=pre","x":660,"y":620,"wires":[["d875e65e.8fbf48"]]},{"id":"d875e65e.8fbf48","type":"function","z":"13af9bb0.48d9b4","name":"Set Img File Name","func":"msg.jpgfilename = msg.camID + \"_\" + msg.st_JST + \".jpg\";\nmsg.orgheaders['Content-Disposition'] = \"inline; filename=\" + msg.jpgfilename;\nmsg.orgheaders['Content-Type'] = \"image/jpeg\";\n\nreturn msg;","outputs":1,"noerr":0,"x":690,"y":680,"wires":[["fbe621e.5f684e"]]}]

インポートが完了すると、それぞれ下記のように表示されるはずです。
auth.png
prev.png

ノードのカスタマイズ

このままではユーザーID、パスワードが使えませんので、それぞれの内容を定義しているノードに記載します。

先ほどインポートした「Get Auth Head」というノードを開いて下さい。
auth2.png

Functionの編集モードになるので、、の部分をそれぞれご自身のユーザーID、パスワードに変更し下さい。
editfunc.png

繋げてみよう

これで準備は完了です。
実際にURLにアクセスして確認してみましょう。
接続先のURLは、

です。

この仕組はカメラ名が必要ですので、
?camName=カメラ名
というパラメータを上記のURLに付加します。最終的には、

となります。
このURLでアクセスを行うと、以下のような静止画が表示されます。

result.png

最後に

いかがでしたか?かなり簡単に静止画を取得できたかと思います。
今回はビジュアル的にわかりやすくするためにBluemix + Node-REDを使っているので多少冗長なところがあったかと思いますが、素直にnode.jsで書いてしまえばもっと行数も少なくいけたかと思います。
EENはこんな感じで静止画や動画を簡単に取得できるので、色々と連携可能な仕組みができると思います。
次回は動画の取得!です。その後は動画の保存なんかも書いてみたいと思います(OKであれば)。

ライセンス、著作権等

本スクリプト、ノード構成、エクスポート内容についてはMIT Licenseを適用します。
Eagle Eye Networksの商標およびロゴについてはEagle Eye Networks, Inc.に帰属します。
IBMおよびIBM Bluemix、Node-Redの商標およびロゴについてはInternational Business Machines Corporationに帰属します。
node.jsの商標およびロゴについてはNode.js contributorsに帰属します。

7
5
2

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
7
5