added output image resize
added output image resize

<script type="text/x-red" data-template-name="ONVIF Snapshot"> <script type="text/x-red" data-template-name="ONVIF Snapshot">
<div class="form-row"> <div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> <label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
<input type="text" id="node-input-name" placeholder="Name"> <input type="text" id="node-input-name" placeholder="Name">
</div> </div>
<div class="form-row"> <div class="form-row">
<label for="node-input-url"><i class="fa fa-link"></i> IP Cam URL</label> <label for="node-input-url"><i class="fa fa-link"></i> IP Cam URL</label>
<input type="text" id="node-input-url" placeholder="http://192.168.0.10:8080/onvif/device_service"> <input type="text" id="node-input-url" placeholder="http://192.168.0.10:8080/onvif/device_service">
</div> </div>
<div class="form-row"> <div class="form-row">
<label for="node-input-username"><i class="fa fa-user"></i> Username</label> <label for="node-input-username"><i class="fa fa-user"></i> Username</label>
<input type="text" id="node-input-username" placeholder="Username"> <input type="text" id="node-input-username" placeholder="Username">
</div> </div>
<div class="form-row"> <div class="form-row">
<label for="node-input-password"><i class="fa fa-key"></i> Password</label> <label for="node-input-password"><i class="fa fa-key"></i> Password</label>
<input type="text" id="node-input-password" placeholder="Password"> <input type="text" id="node-input-password" placeholder="Password">
</div> </div>
  <div class="form-row">
  <label for="node-input-resize"><i class="fa fa-file-code-o"></i> Resize</label>
  <input type="text" id="node-input-resize" placeholder='{"width": 800}'>
  </div>
</script> </script>
   
<script type="text/x-red" data-help-name="ONVIF Snapshot"> <script type="text/x-red" data-help-name="ONVIF Snapshot">
<h2>Inputs</h2> <h2>Inputs</h2>
<p>You can wire inject nodes to the input of this node and send the following in <code>msg.payload</code>.</p> <p>You can wire inject nodes to the input of this node and send the following in <code>msg.payload</code>.</p>
<table> <table>
<thead> <thead>
<tr> <tr>
<th>msg.payload</th> <th>msg.payload</th>
<th></th> <th></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
  <td><code>name</code></td>
  <td>IP camera name</td>
  </tr>
  <tr>
<td><code>url</code></td> <td><code>url</code></td>
<td>IP camera URL</td> <td>IP camera URL</td>
</tr> </tr>
<tr> <tr>
<td><code>username</code></td> <td><code>username</code></td>
<td>IP camera username</td> <td>IP camera username</td>
</tr> </tr>
<tr> <tr>
<td><code>password</code></td> <td><code>password</code></td>
<td>IP camera password</td> <td>IP camera password</td>
  </tr>
  <tr>
  <td><code>resize.width</code></td>
  <td>Resize image by width</td>
  </tr>
  <tr>
  <td><code>resize.height</code></td>
  <td>Resize image by height</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
   
<h2>Output</h2> <h2>Output</h2>
<table> <table>
<thead> <thead>
<tr> <tr>
<th>msg.payload</th> <th>msg.payload</th>
<th></th> <th></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<td><code>image.base64</code></td> <td><code>image.base64</code></td>
<td>Base64 encoded image</td> <td>Base64 encoded image</td>
</tr> </tr>
<tr> <tr>
<td><code>image.binary</code></td> <td><code>image.binary</code></td>
<td>Binary image</td> <td>Binary image</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</script> </script>
   
<script type="text/javascript"> <script type="text/javascript">
RED.nodes.registerType("ONVIF Snapshot", { RED.nodes.registerType("ONVIF Snapshot", {
category: "ONVIF", category: "ONVIF",
color: "#91d2f7", color: "#91d2f7",
defaults: { defaults: {
name: {value: ""}, name: {value: ""},
url: {value: "", required: true}, url: {value: "", required: true},
username: {value: ""}, username: {value: ""},
password: {value: ""} password: {value: ""}
}, },
inputs: 1, inputs: 1,
outputs: 1, outputs: 1,
icon: "onvif-snapshot.png", icon: "onvif-snapshot.png",
label: function() { label: function() {
return this.name || this.url || this.type; return this.name || this.url || this.type;
}, },
labelStyle: function() { labelStyle: function() {
return this.name ? "node_label_italic" : ""; return this.name ? "node_label_italic" : "";
}, },
paletteLabel: "Snapshot", paletteLabel: "Snapshot",
oneditprepare: function() { oneditprepare: function() {
}, },
oneditsave: function() { oneditsave: function() {
} }
}); });
</script> </script>
   
module.exports = (RED) => { module.exports = (RED) => {
"use strict"; "use strict";
let onvif = require("node-onvif"); let onvif = require("node-onvif");
  const sharp = require('sharp');
   
function snapshot(config) { function snapshot(config) {
RED.nodes.createNode(this, config); RED.nodes.createNode(this, config);
let node = this; let node = this;
   
node.on("input", function (msg) { node.on("input", function (msg) {
try {  
let _msg = JSON.parse(msg.payload);  
if (typeof _msg === "object") {  
if(_msg.hasOwnProperty("name")) {  
msg.name = _msg.name;  
}  
if(_msg.hasOwnProperty("url")) {  
msg.url = _msg.url;  
}  
if(_msg.hasOwnProperty("username")) {  
msg.username = _msg.username;  
}  
if(_msg.hasOwnProperty("password")) {  
msg.password = _msg.password;  
}  
}  
}  
catch (ex) {}  
   
config.name = msg.name || config.name; config.name = msg.payload.name || config.name;
config.url = msg.url || config.url; config.url = msg.payload.url || config.url;
config.username = msg.username || config.username; config.username = msg.payload.username || config.username;
config.password = msg.password || config.password; config.password = msg.payload.password || config.password;
  config.resize = msg.payload.resize || config.resize;
   
if(msg.hasOwnProperty("payload")) { if(msg.hasOwnProperty("payload")) {
msg._payload = msg.payload; msg._payload = msg.payload;
} }
msg.node = this.type; msg.node = this.type;
   
  if (!config.url) {
  node.warn("No URL is specified. Please specify in node configuration.");
  return;
  }
   
run(msg, node, config); run(msg, node, config);
}); });
   
if (!config.url) {  
node.warn("No URL is specified. Please specify in node configuration.");  
return;  
}  
} }
RED.nodes.registerType("ONVIF Snapshot", snapshot); RED.nodes.registerType("ONVIF Snapshot", snapshot);
   
function run(msg, node, config) { function run(msg, node, config) {
let onvifInstance = new onvif.OnvifDevice({ let onvifInstance = new onvif.OnvifDevice({
xaddr: config.url, xaddr: config.url,
user : config.username, user : config.username,
pass : config.password pass : config.password
}); });
   
onvifInstance.init().then((info) => { onvifInstance.init().then((info) => {
node.log('Fetching snapshot from ' + config.url); node.log('Fetching snapshot from ' + config.url);
return onvifInstance.fetchSnapshot(); return onvifInstance.fetchSnapshot();
}).then((res) => { }).then((res) => {
let prefix = 'data:' + res.headers['content-type'] + ';base64,'; let prefix = 'data:' + res.headers['content-type'] + ';base64,';
let base64Image = Buffer.from(res.body, 'binary').toString('base64');  
msg.payload = { if (config.resize) {
config: config, sharp(Buffer.from(res.body, 'binary'))
image: { .resize(config.resize)
base64: (prefix + base64Image), .toFormat('png')
binary: res.body .toBuffer()
} .then( data => {
}; msg.payload = {
node.send(msg); config: config,
  image: {
  base64: (prefix + data.toString('base64')),
  binary: res.body
  }
  };
  node.send(msg);
  }).catch( err => {
   
  });
  } else {
  let base64Image = Buffer.from(res.body, 'binary').toString('base64');
  msg.payload = {
  config: config,
  image: {
  base64: (prefix + base64Image),
  binary: res.body
  }
  };
  node.send(msg);
  }
}).catch((error) => { }).catch((error) => {
msg.payload = null; msg.payload = null;
msg.error = error; msg.error = error;
node.send(msg); node.send(msg);
}); });
} }
} }
   
{ {
"name": "node-red-contrib-onvif", "name": "node-red-contrib-onvif",
"version": "0.0.3", "version": "1.0.0",
"description": "A Node-RED node that interacts with ip cameras using the ONVIF protocol", "description": "A Node-RED node that interacts with ip cameras using the ONVIF protocol",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/razvanstanga/node-red-contrib-onvif.git" "url": "https://github.com/razvanstanga/node-red-contrib-onvif.git"
}, },
"dependencies": { "dependencies": {
"node-onvif": "^0.1.7" "node-onvif": "^0.1.7",
  "sharp": "^0.26.2"
}, },
"inputs": 1, "inputs": 1,
"keywords": [ "keywords": [
"node-red", "node-red",
"node-red-contrib", "node-red-contrib",
"onvif", "onvif",
"ipcam" "ipcam"
], ],
"node-red": { "node-red": {
"nodes": { "nodes": {
"ONVIF Snapshot": "onvif/snapshot.js" "ONVIF Snapshot": "onvif/snapshot.js"
} }
}, },
"author": { "author": {
"name": "Razvan Stanga" "name": "Razvan Stanga"
}, },
"license": "Apache", "license": "Apache",
"bugs": { "bugs": {
"url": "https://github.com/razvanstanga/node-red-contrib-onvif/issues" "url": "https://github.com/razvanstanga/node-red-contrib-onvif/issues"
}, },
"homepage": "https://github.com/razvanstanga/node-red-contrib-onvif" "homepage": "https://github.com/razvanstanga/node-red-contrib-onvif"
} }
   
comments