Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Speed improvements? #224

Closed
rodrigograca31 opened this issue Jan 29, 2022 · 8 comments
Closed

Speed improvements? #224

rodrigograca31 opened this issue Jan 29, 2022 · 8 comments

Comments

@rodrigograca31
Copy link
Contributor

Hi!

I've noticed it takes 1-2 seconds for the commands to take effect....

Lets say thats because the video isnt instantaneous or some other performance issue.... I still would like to ask that we replace xml2js with a more up-to-date library. Its 2+ years outdated.

Here is an alternative: https://github.com/NaturalIntelligence/fast-xml-parser

is there other ways we can improve the speed of the PTZ commands? maybe some camera settings? 🤔

@chriswiggins
Copy link
Collaborator

Have you timed which commands take a while to run inside the library? I'd doubt the XML parser is the bottleneck?

@agsh
Copy link
Owner

agsh commented Jan 31, 2022

@rodrigograca31 Yes, please check your network lags to the device

@rodrigograca31
Copy link
Contributor Author

rodrigograca31 commented Feb 1, 2022

Have you timed which commands take a while to run inside the library? I'd doubt the XML parser is the bottleneck?

ok. to be honest I agree with you.
but Im using cat 5e and good routers.... but yeah sometimes the video takes 1-2 seconds to load at first....
maybe its something with the cameras themselves....

the command would be absoluteMove.

any ideas how I can improve the network?
yes I do realize thats a very relative question.... I guess I need to spend more € on cables, switches, cameras? 🤔 but im mostly just a coder.... 😂

@agsh
Copy link
Owner

agsh commented Feb 1, 2022

@rodrigograca31 Seriously I don't think that xml parsing of a small response is the bottleneck.
Do you have the same troubles with other onvif libraries?
The simpliest way to find out, just to add console.time to log the time between request to the camera and its response here: https://github.com/agsh/onvif/blob/master/lib/cam.js#L204
If the response is quick, this is your cam problem.
If the response is slow, this is the network problem.
Sample code replacement:

Cam.prototype._request = function(options, callback) {
	if (typeof callback !== 'function') {
		throw new Error('`callback` must be a function');
	}
	const _this = this;
	let callbackExecuted = false;
	let reqOptions = options.url || {
		hostname : this.hostname
		, port     : this.port
		, agent    : this.agent // Supports things like https://www.npmjs.com/package/proxy-agent which provide SOCKS5 and other connections
		, path     : options.service
			? (this.uri[options.service] ? this.uri[options.service].path : options.service)
			: this.path
		, timeout : this.timeout
	};
	reqOptions.headers = {
		'Content-Type'   : 'application/soap+xml'
		, 'Content-Length' : Buffer.byteLength(options.body, 'utf8')// options.body.length chinese will be wrong here
		, charset          : 'utf-8'
	};

	reqOptions.method = 'POST';
	const httpLib = this.useSecure ? https : http;
	reqOptions = this.useSecure ? ({ ...this.secureOpts, ...reqOptions}) : reqOptions;
	const req = httpLib.request(reqOptions, (res) => {
		const bufs = []; let length = 0;
		res.on('data', (chunk) => {
			bufs.push(chunk);
			length += chunk.length;
		});
		res.on('end', () => {
			console.timeEnd('request');
			if (callbackExecuted === true) {
				return;
			}
			callbackExecuted = true;
			const xml = Buffer.concat(bufs, length).toString('utf8');
			/**
			 * Indicates raw xml response from device.
			 * @event Cam#rawResponse
			 * @type {string}
			 */
			_this.emit('rawResponse', xml);
			parseSOAPString(xml, callback);
		});
	});

	req.setTimeout(this.timeout, () => {
		if (callbackExecuted === true) {
			return;
		}
			callbackExecuted = true;

		callback(new Error('Network timeout'));
		req.abort();
	});

	req.on('error', (err) => {
		if (callbackExecuted === true) {
			return;
		}
		callbackExecuted = true;
		/* address, port number or IPCam error */
		if (err.code === 'ECONNREFUSED' && err.errno === 'ECONNREFUSED' && err.syscall === 'connect') {
			callback(err);
			/* network error */
		} else if (err.code === 'ECONNRESET' && err.errno === 'ECONNRESET' && err.syscall === 'read') {
			callback(err);
		} else {
			callback(err);
		}
	});
	/**
	 * Indicates raw xml request to device.
	 * @event Cam#rawRequest
	 * @type {Object}
	 */
	this.emit('rawRequest', options.body);
	console.time('request');
	req.write(options.body);
	req.end();
};

@rodrigograca31
Copy link
Contributor Author

doing a simple absoluteMove seems to have a quick response.
so Im thinking its the camera video thats actually slow....

@RogerHardiman
Copy link
Collaborator

If you are viewing your video with 'ffplay' or 'vlc', then both add a large delay to the video before they show the pixels on the screen to smooth out network buffering. You can configure VLC to not use buffering and for ffplay there are some command line options to add. I forget what they are now.

The ONVIF library is fast. I use it in several commercial projects which include Pan and Tilt control, often with the Continuous Move API where you send Start and Stop commands.

@chriswiggins
Copy link
Collaborator

@rodrigograca31 if you're using ffplay, try the following command

ffplay - analyzeduration 0.2 -probesize 1000 rtsp://x.x.x.x

@RogerHardiman
Copy link
Collaborator

ffplay -fflags nobuffer rtsp://x.x.x.x is what I use

note it is double 'f', ie 'f''flags' = fflags

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants