Overview
onvif
client protocol Profile S (Live Streaming) and Profile G (Replay) implementation.
This is a wrapper to ONVIF protocol which allows you to get information about your NVT (network video transmitter) device, its media sources, control PTZ (pan-tilt-zoom) movements and manage presets, detect devices in your network and control its events. It will also allow you to get information about your NVR (network video recorder) Profile G device and obtain a list of recordings.
User can use the following code to import the onvif
module .
var onvif = require('@edgeros/jsre-onvif');
Support
The following shows onvif
module APIs avaliable for each permissions.
User Mode | Privilege Mode | |
---|---|---|
Discovery | ● | ● |
discovery.start | ● | ● |
discovery.stop | ● | ● |
discovery.discovery | ● | ● |
discovery.search | ● | ● |
discovery.lookup | ● | ● |
Cam | ● | ● |
cam.connect | ● | ● |
cam.getSystemDateAndTime | ● | ● |
cam.getDeviceInformation | ● | ● |
cam.getServices | ● | ● |
cam.getServiceCapabilities | ● | ● |
cam.getStreamUri | ● | ● |
cam.getSnapshotUri | ● | ● |
cam.getPresets | ● | ● |
cam.gotoPreset | ● | ● |
cam.setPreset | ● | ● |
cam.removePreset | ● | ● |
cam.gotoHomePosition | ● | ● |
cam.setHomePosition | ● | ● |
cam.getNodes | ● | ● |
cam.relativeMove | ● | ● |
cam.absoluteMove | ● | ● |
cam.continuousMove | ● | ● |
cam.stop | ● | ● |
cam.getStatus | ● | ● |
cam.getConfigurations | ● | ● |
cam.getConfigurationOptions | ● | ● |
Discovery Class
onvif.Discovery(serOpts[, searchOpts])
-
serOpts
{Array | Object} The server options or server optoins array. Options:-
ifname
{String | Null} Specify the network interface. -
localPort
{Integer} Local port. 0 - Automatic port allocation.
-
-
searchOpts
{Object} Has the following properties:-
localAddr
{String} The local address of udp broadcast. Network interface is usually specified byifname
, and thislocalAddr
does not need to be set generally . default: Udp.INADDR_ANY -
remotePort
{Integer} Device port. default: 3702 -
searchCycle
{Integer} Search cycles. default: 10000 -
resolve
{Boolean} Auto create camera object. default: true
-
- Returns: {Object} Device discovery object.
Example
var onvif = require('@edgeros/jsre-onvif');
var discovery = new onvif.Discovery({ifname: 'en2', localPort: 0}, {
searchCycle: 30000,
resolve: false
});
Discovery Object
discovery.start()
Start discovery service. A 'start' event will be emited after discovery object initialization.
discovery.stop()
Stop discovery service. A 'stop' event will be emited when discovery stoped. discovery.search()
can't be call after stop.
discovery.discovery()
Periodically search for camera devices. This method can only be called once. The search period is set when the discovery object is created. The 'find' event will be emited and a camera object will be created when discovery object searches for a device.
discovery.search()
Search camera devices. The method can be called Several times. The 'find' event will be emited and a camera object will be created when discovery object searches for a device.
Discovery Events
start
An open
event is emitted when the device handshake success. This event parameter is:
-
err
{Error} If the device fails to handshake, the error object is returned. -
device
{Object} This device object.
If the device fails to open, the device object is automatically released, the close
event is not triggered, and messages are not allowed to be sent.
stop
This event is triggered when the device close or times out, and messages are not allowed to be sent to the device after this event. This event parameter is:
-
device
{Object} This device object.
find
This event is emited when a device is searched. If the 'resolve' option is set to true, when the discovery object is created, the camera object is created and returned to the event, otherwise the original data is returned. This event parameter is:
-
cam
{Cam} Cam object. -
saddr
{Object} Remote saddr object. -
xml
{String} Original reply data.
lost
Each time you search for a device, the last discovered device is checked, and if the last discovered device does not appear in the current search, the device is invalid, it is removed from the device records, and the 'lost' event is emited. This event parameter is:
-
cam
{Cam} Cam object.
'After the camera object is moved, nothing can be done on it.
error
An error event is emited when the result returned by the search device cannot be parsed. This event parameter is:
-
msg
{String} Error message.
Cam Class
onvif.Cam(options[, callback])
-
options
{Object} Options are:-
hostname
{String} Camera host. -
username
{String} User name, default: undefined. -
password
Password, default: undefined. -
port
{Integer} default: 80. -
path
{String} Camera media path, default: /onvif/device_service. -
timeout
{Integer} The connections timeout, default: 120000.
-
-
callback
{Function} As the 'connect' event callback. Arguments:-
err
{Error} Error object if error. -
xml
{String} Xml result.
-
The library calls connect() automatically which executes the getSystemDateAndTime
, getCapabilities
and other methods.
The device object discovered by the Discovery
object can be used as the create camera options
.
Note on username and password:
- Some cameras do not require username : password credentials.
- If a camera does require a username : password but you do not provide them, you will be limited to executing a few ONVIF methods that can operate without credentials, for example you can execute only
getSystemDateAndTime
method.
Callback (optional) executes when the cam is initialised. Single argument for this function is possible error.
Example
This example asks your camera to look up and starts a web server at port 3030 that distributes a web page with vlc-plugin container which translates video from the camera.
var http = require('http');
var Cam = require('onvif').Cam;
new Cam({
hostname: <CAMERA_HOST>,
username: <USERNAME>,
password: <PASSWORD>
}, function(err) {
this.absoluteMove({x: 1, y: 1, zoom: 1});
this.getStreamUri({protocol:'RTSP'}, function(err, stream) {
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.end('<html><body>' +
'<embed type="application/x-vlc-plugin" target="' + stream.uri + '"></embed>' +
'</body></html>');
}).listen(3030);
});
});
Technical Description
When the cam object is created it automatically sends a getCapabilities
command to the ONVIF device. If the device is a camera or encoder (NVT) it sends two commands to the ONVIF device:
getVideoSources
and getProfiles
. It fills corresponding properties of an object:
- capabilities:
- device
- events
- imaging
- media
- PTZ
- extension
- uri (this is a links to different NVT services)
- videoSources:
- $.token
- framerate
- resolution
- profiles, array of profile object
- name
- videoSourceConfiguration
- videoEncoderConfiguration
- PTZConfiguration
After that it runs getActiveSources
method. It iterates over all video sources and tries to find out proper configuration for profile and videosource. First matching profile becomes a member of defaultProfiles array and video source configuration with ptz configuration becomes a member of activeSources array.
Configuration for the first or the only one video source becomes defaultProfile and activeSource properties. All methods without passing options object use it. You can change it manually at any time.
- defaultProfile (link to the first profile in profiles)
- activeSource (based on the default profile)
- sourceToken
- profileToken
- encoding
- width
- height
- fps
- bitrate
- ptz
Cam Object
cam.connect(callback)
-
callback
{Function} Arguments:-
err
{Error} Error object if error. -
xml
{String} Xml result.
-
Connect to the camera and fill device information properties with getSystemDateAndTime
, getCapabilities
, getVideoSources
, getProfiles
methods
See more detailed information at http://www.onvif.org/ver10/media/wsdl/media.wsdl
After cam initialisation we can run several ONVIF commands.
There are several common methods that work without credentials. Here are they: getSystemDateAndTime
.
Example
var http = require('http');
var Cam = require('@edgeros/jsre-onvif').Cam;
new Cam({
hostname: '10.4.0.181',
username: 'admin',
password: 'admin'
}, function (err) {
this.absoluteMove({ x: 1, y: 1, zoom: 1 });
this.getStreamUri({ protocol: 'RTSP' }, function (err, stream) {
var server = http.createServer('ser', function (req, res) {
res.statusCode(200);
res.setHeader('Content-Type', 'text/html');
res.end('<html><body>' +
'<embed type="application/x-vlc-plugin" target="' + stream.uri + '"></embed>' +
'</body></html>');
}, 0, addr);
server.start();
});
});
cam.getSystemDateAndTime(callback)
-
callback
{Function} Arguments:-
err
{Error} Error object if error occur. -
date
{Object} Date object. -
xml
{String} Xml result.
-
Returns a Date object with current camera datetime in the callback.
Works without credentials (passed username
and password
arguments).
cam.getDeviceInformation(callback)
-
callback
{Function} Arguments:-
err
{Error} Error object if error occur. -
device
{Object} Device information. -
xml
{String} Xml result.
-
Device. Returns a device information, such as manufacturer, model and firmware version in the callback
Works without credentials (passed username
and password
arguments).
cam.getServices(callback)
-
callback
{Function} Arguments:-
err
{Error} Error object if error occur. -
services
{Array} Service object array. -
xml
{String} Xml result.
-
Device. Returns in callback and assigns to #services
property an array consists of objects with properties: namespace
, XAddr
, version
cam.getServiceCapabilities(callback)
-
callback
{Function} Arguments:-
err
{Error} Error object if error occur. -
capabilities
{Object} Device service capabilities information.. -
xml
{String} Xml result.
-
Device. Returns in callback and assigns to #serviceCapabilities
property the capabilities of the device service (not media):
network, security and system. If your device supports some auxiliary capabilities they will be there too.
cam.getStreamUri([options, ]callback)
-
options
{Object} The options are:-
stream
{String} (optional) - defines if a multicast or unicast stream is requested. Possible values are: 'RTP-Unicast', 'RTP-Multicast', default: 'RTP-Unicast'. -
protocol
{String} (optional) - defines the network protocol for streaming. Possible values are: 'UDP', 'TCP', 'RTSP', 'HTTP', default: 'RTSP'. -
profileToken
{String (optional) - defines media profile to use and will define the configuration of the content of the stream. default:#activeSource.profileToken
.
-
-
callback
[Function] Arguments:-
err
{Error} Error object if error occur. -
mediaUri
{Object} Object result. Get media uri from stream.uri.-
uri
{String} Media stream uri.
-
-
xml
{String} Xml result.
-
Media. Returns a URI that can be used to initiate a live media stream using RTSP as the control protocol
cam.getSnapshotUri([options, ]callback)
-
options
{Object} The options are:-
profileToken
{String (optional) - defines media profile to use and will define the configuration of the content of the stream. default:#activeSource.profileToken
.
-
-
callback
[Function] Arguments:-
err
{Error} Error object if error occur. -
MediaUri
{Object} Object result .-
uri
{String} Snapshot uri.
-
-
xml
{String} Xml result.
-
Media. Obtain a JPEG snapshot URI from the device.
cam.getPresets([options, ]callback)
-
options
{Object} The options are:-
profileToken
{String (optional) - defines media profile to use and will define the configuration of the content of the stream. default:#activeSource.profileToken
.
-
-
callback
[Function] Arguments:-
err
{Error} Error object if error occur. -
presets
{Object} Presets object. -
xml
{String} Xml result.
-
Returns the saved presets as an a key-value object where the key is the name of a preset and a value is a preset token.
This method also stores the presets information in a #presets
property of an object.
cam.gotoPreset(options, callback)
-
options
{Object} The options are:-
profileToken
{String (optional) - defines media profile to use and will define the configuration of the content of the stream. default:#activeSource.profileToken
. -
presetName
{String} the name of preset. List of presets you can get by#getPresets
method or in#presets
property. -
speed
{Integer}
-
-
callback
[Function] Arguments:-
err
{Error} Error object if error occur.
-
PTZ. Operation to go to a saved preset position for the PTZ node in the selected profile.
cam.setPreset(options, callback)
-
options
{Object} The options are:-
profileToken
{String (optional) - defines media profile to use and will define the configuration of the content of the stream. default:#activeSource.profileToken
. -
presetName
{String} the name to give to the preset. (optional) is this is a preset update.
-
-
callback
[Function] Arguments:-
err
{Error} Error object if error occur.
-
PTZ. Operation to set the current position as a preset for the PTZ node in the selected profile. If presetToken
is passed as an option, then the preset for which that token is attached will be replaced. After success, you should re-fetch the presets with #getPresets
method.
cam.removePreset(options, callback)
-
options
{Object} The options are:-
profileToken
{String (optional) - defines media profile to use and will define the configuration of the content of the stream. default:#activeSource.profileToken
. -
presetToken
{String} the preset token to use for preset removal (this will be thevalue
of a preset object found in#presets
after calling the#getPresets
method.
-
-
callback
[Function] Arguments:-
err
{Error} Error object if error occur.
-
PTZ. Operation to remove a preset specified by the preset token. After success, you should re-fetch the presets with #getPresets
method.
cam.gotoHomePosition(options, callback)
-
options
{Object} The options are:-
profileToken
{String (optional) - defines media profile to use and will define the configuration of the content of the stream. default:#activeSource.profileToken
. -
speed
{Object} An object with properties:-
x
{Float} Pan speed. -
y
{Float} Tilt speed. -
zoom
{Float} Zoom speed.
-
-
-
callback
[Function] Arguments:-
err
{Error} Error object if error occur.
-
PTZ. Operation to go to the saved home
position for the PTZ node in the selected profile. If no home
position has been saved, the ONVIF camera will do nothing.
If the speed option is omitted, the default speed set by the PTZConfiguration will be used.
cam.setHomePosition(options, callback)
-
options
{Object} The options are:-
profileToken
{String (optional) - defines media profile to use and will define the configuration of the content of the stream. default:#activeSource.profileToken
.
-
-
callback
[Function] Arguments:-
err
{Error} Error object if error occur.
-
PTZ. Operation to set the current position as the home
position for the PTZ node in the selected profile.
cam.getNodes(callback)
-
callback
[Function] Arguments:-
err
{Error} Error object if error occur. -
nodes
{Object} nodes['ptzNodeToken'] - the current PTZ node. PTZ node properties to see: http://www.onvif.org/onvif/ver20/ptz/wsdl/ptz.wsdl#op.SetPreset. -
xml
*{String} Xml result.
-
PTZ. Returns the properties of the current PTZ node, if it exists.
Use this function to get maximum number of presets, ranges of admitted values for x, y, zoom, iris, focus.
Sets all information into #nodes
property.
cam.relativeMove(options, callback)
-
options
{Object} The options are:-
profileToken
{String (optional) - defines media profile to use and will define the configuration of the content of the stream. default:#activeSource.profileToken
. -
x
{Float} Pan, number or a string within -1 to 1, optional, default: 0 -
y
{Float} Tilt, number or a string within -1 to 1, optional, default: 0 -
zoom
{Float} Zoom, number or a string within -1 to 1, optional, default: 0 -
speed
{Float} An object with properties. If the speed argument is omitted, the default speed set by the PTZConfiguration will be used.-
x
{Float} Pan speed -
y
{Float} Tilt speed -
zoom
{Float} Zoom speed
-
-
-
callback
[Function] Arguments:-
err
{Error} Error object if error occur.
-
PTZ. This is a relative pan-tilt-zoom method. Options for this method is a delta between desired and current position of the camera.
Callback is optional and means essentially nothing.
cam.absoluteMove(options, callback)
-
options
{Object} The options are:-
profileToken
{String (optional) - defines media profile to use and will define the configuration of the content of the stream. default:#activeSource.profileToken
. -
x
{Float} Pan, number or a string within -1 to 1, optional, default: 0 -
y
{Float} Tilt, number or a string within -1 to 1, optional, default: 0 -
zoom
{Float} Zoom, number or a string within -1 to 1, optional, default: 0 -
speed
{Float} An object with properties. If the speed argument is omitted, the default speed set by the PTZConfiguration will be used.-
x
{Float} Pan speed -
y
{Float} Tilt speed -
zoom
{Float} Zoom speed
-
-
-
callback
[Function] Arguments:-
err
{Error} Error object if error occur.
-
PTZ. This is an absolute pan-tilt-zoom method. Options for this method is an absolute position of the camera.
Callback is optional and means essentially nothing
cam.continuousMove(options, callback)
-
options
{Object} The options are:-
profileToken
{String (optional) - defines media profile to use and will define the configuration of the content of the stream. default:#activeSource.profileToken
. -
x
{Float} Pan velocity, number or a string within -1 to 1, optional, default: 0 -
y
{Float} Tilt velocity, number or a string within -1 to 1, optional, default: 0 -
zoom
{Float} Zoom velocity, number or a string within -1 to 1, optional, default: 0 -
timeout
{Integer} Timeout in milliseconds, number. If timeout is omitted, movement will continue untilstop
command. default: Infinity
-
-
callback
[Function] Arguments:-
err
{Error} Error object if error occur.
-
PTZ. Operation for continuous Pan/Tilt and Zoom movements.
cam.stop([[options, ]callback])
-
options
{Object} The options are:-
profileToken
{String} (optional) - defines media profile to use and will define the configuration of the content of the stream. Default is#activeSource.profileToken
-
panTilt
{Boolean | String} (optional) - set true when we want to stop ongoing pan and tilt movements. IfpanTilt
arguments are not present, this command stops these movements. -
zoom
{Boolean | String} (optional) - set true when we want to stop ongoing zoom movement. Ifzoom
arguments are not present, this command stops ongoing zoom movement.
-
-
callback
[Function] Arguments:-
err
{Error} Error object if error occur.
-
PTZ. Stop ongoing pan, tilt and zoom movements of absolute, relative and continuous type.
cam.getStatus([options, ]callback)
-
options
{Object} The options are:-
profileToken
{String} (optional) - defines media profile to use and will define the configuration of the content of the stream. Default is#activeSource.profileToken
-
-
callback
[Function] Arguments:-
err
{Error} Error object if error occur. -
status
{Object} PTZ status.
-
PTZ. Returns an object with the current PTZ values.
Example
{
position: {
x: 'pan position',
y: 'tilt position',
zoom: 'zoom'
},
moveStatus: {}, // camera moving
utcTime: 'current camera datetime'
}
cam.getConfigurations(callback)
-
callback
[Function] Arguments:-
err
{Error} Error object if error occur. -
configurations
{Object} configurations object. The configuration object to see: http://www.onvif.org/onvif/ver20/ptz/wsdl/ptz.wsdl#op.SetPreset. -
xml
*{String} Xml result.
-
PTZ. Get all the existing PTZConfigurations from the device. Configurations saved into #configurations
property.
cam.getConfigurationOptions(configurationToken, callback)
-
options
{Object} The options are:-
configurationToken
{String} configuration token.
-
-
callback
[Function] Arguments:-
err
{Error} Error object if error occur. -
configurations
{Object} configurations object. The configuration object to see: http://www.onvif.org/onvif/ver20/ptz/wsdl/ptz.wsdl#op.SetPreset. -
xml
*{String} Xml result.
-
PTZ. Get supported coordinate systems including their range limitations for selected configuration. Extends corresponding
Cam Events
connect
Emit when camera object initialled. This event parameter is:
-
err
{Error} Error object if error occur.-
typeError
{Boolean} true - Not Profile S device.
-
-
xml
*{String} Xml result.
rawResponse
Emit after received the response of command. This event parameter is:
-
xml
{String} Indicates raw xml response from device.
rawRequest
Emit before the command is sent. This event parameter is:
-
body
{Object} Indicates raw xml request to device.
Example
Discovery Camera
var iosched = require('iosched');
var onvif = require('@edgeros/jsre-onvif');
var discovery = new onvif.Discovery({ifname: 'en2', localPort: 0});
discovery.on('find', (cam, addr) => {
console.info('find camera:', addr);
cam.on('connect', (err) => {
if (err) {
console.log('Connection Failed:', err);
return;
}
cam.getStreamUri({protocol:'RTSP'}, function(err, stream) {
if (err) {
console.log('getStreamUri failed:', err);
return;
}
console.info('get stream:', stream.uri);
});
});
});
discovery.on('error', (err) => {
console.error(err);
});
discovery.on('start', () => {
discovery.search();
});
discovery.start();
iosched.forever();
Discovery And Create Camera
var iosched = require('iosched');
var onvif = require('@edgeros/jsre-onvif');
var discovery = new onvif.Discovery({ifname: 'en2', localPort: 0}, {resolve: false});
discovery.on('find', (dev, addr) => {
dev.username = 'admin';
dev.password = 'admin';
var cam = new onvif.Cam(dev);
cam.on('connect', (err) => {
if (err && err.typeError) { /* Not Profile S. */
return;
} else if (err) {
console.warn(`Camera(${cam.urn}) connection fail, may need password:`, err);
return;
}
cam.getStreamUri({protocol:'RTSP'}, function(err, stream) {
if (err) {
console.warn(`Camera(${cam.urn}) get uri fail:`, err);
} else {
console.info(`Camera(${cam.urn}) get uri:`, stream.uri);
}
});
});
});
discovery.on('error', (err) => {
console.error(err);
});
discovery.on('start', () => {
discovery.search();
});
discovery.start();
iosched.forever();