Created
December 15, 2017 13:51
-
-
Save hawkeye64/a30e43c8301626f7687b985b5e7b04bd to your computer and use it in GitHub Desktop.
How to get snapshoutUri and finally snapshot from ONVIF camera
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* this is a partial gist */ | |
const Promise = require('bluebird') | |
const axios = require('axios') | |
const Camera = require('onvif').Cam | |
class OnvifManager { | |
//... | |
this.cameras = {} | |
//... | |
readCamerasFromDatabase () { | |
//... | |
let onvif = // code to read from database | |
let options = {} | |
options.hostname = onvif.address | |
options.username = onvif.login | |
options.password = onvif.password | |
if (onvif.port && onvif.port !== 80) { | |
options.port = onvif.port | |
} | |
let camera = new Camera(options, error => { | |
camera.onvif = onvif | |
// assign to list of cameras | |
this.cameras[onvif.id] = camera | |
if (error === null) { | |
camera.getSnapshotUri({}, (error, data, xml) => { | |
if (error) { | |
console.error(`Cannot get snapshot URI for ${camera.onvif.name}/${camera.onvif.address}`) | |
} | |
else { | |
camera.snapshotUri = data | |
} | |
}) | |
} | |
} | |
// call this function whenever a snapshot from the onvif camera is desired | |
commandFetchSnapshot (id) { | |
return new Promise((resolve, reject) => { | |
let camera = this.cameras[id] | |
if (!camera) { | |
let results = { | |
message: 'Not Found', | |
status: 404 | |
} | |
reject(new Error(results)) | |
} | |
else { | |
// check that we have a snapshotUri attached to this camera | |
if ('snapshotUri' in camera) { | |
let snapshotUri = camera.snapshotUri.uri | |
// using axios.get with options { responseType: 'arraybuffer' } | |
// did not work at all. The data returned was transformed somehow. | |
// This way works! | |
axios.request({ | |
responseType: 'arraybuffer', | |
url: snapshotUri, | |
method: 'get', | |
headers: { | |
'Content-Type': 'image/*' | |
}, | |
auth: { | |
username: camera.username, | |
password: camera.password | |
} | |
}) | |
.then((results) => { | |
let mimeType = results.headers['content-type'] | |
// using nodejs Buffer to encode the inary to base64 | |
let b64encoded = Buffer.from(results.data, 'binary').toString('base64') | |
let image = 'data:' + mimeType + ';base64,' + b64encoded | |
let data = { | |
mimeType: mimeType, | |
image: image | |
} | |
// uncomment to write image to disk for testing | |
// const outputFilename = '/tmp/testfile.jpg' | |
// fs.writeFileSync(outputFilename, results.data) | |
resolve(data) | |
}) | |
.catch(error => { | |
console.error('commandFetchSnapshot error', error) | |
let results = { | |
message: 'fetchSnapshot error', | |
status: 250, | |
error: error | |
} | |
reject(new Error(results)) | |
}) | |
} | |
else { | |
let results = { | |
message: 'Unknown in commandFetchSnapshot', | |
status: 250 | |
} | |
reject(new Error(results)) | |
} | |
} | |
}) | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Axios couldn't handle working with Axis camera authentication because it uses Realm Digest. I have since changed my code to use the 'request' package.
New gist here: https://gist.github.com/hawkeye64/e67cb5aae8f46d9c94ea2c9a4bb9247b