camstreamerlib
Version:
Helper library for CamStreamer ACAP applications.
442 lines (441 loc) • 18 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.CameraVapix = void 0;
const prettifyXml = require("prettify-xml");
const xml2js_1 = require("xml2js");
const common_1 = require("./internal/common");
const DefaultAgent_1 = require("./DefaultAgent");
class CameraVapix {
constructor(options = {}) {
if ((0, common_1.isClient)(options)) {
this.client = options;
}
else {
this.client = new DefaultAgent_1.DefaultAgent(options);
}
}
vapixGet(path, parameters) {
return this.client.get(path, parameters);
}
vapixPost(path, data, contentType) {
let headers = {};
if (contentType !== undefined) {
headers = { 'Content-Type': contentType };
}
return this.client.post(path, data, {}, headers);
}
getCameraImage(camera, compression, resolution, outputStream) {
return __awaiter(this, void 0, void 0, function* () {
const res = yield this.vapixGet('/axis-cgi/jpg/image.cgi', { resolution, compression, camera });
if (res.body) {
void res.body.pipeTo(outputStream);
}
return outputStream;
});
}
getEventDeclarations() {
return __awaiter(this, void 0, void 0, function* () {
const data = '<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">' +
'<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' +
'xmlns:xsd="http://www.w3.org/2001/XMLSchema">' +
'<GetEventInstances xmlns="http://www.axis.com/vapix/ws/event1"/>' +
'</s:Body>' +
'</s:Envelope>';
const declarations = yield (yield this.vapixPost('/vapix/services', data, 'application/soap+xml')).text();
return prettifyXml(declarations);
});
}
getSupportedAudioSampleRate() {
var _a, _b;
return __awaiter(this, void 0, void 0, function* () {
const url = '/axis-cgi/audio/streamingcapabilities.cgi';
const formData = { apiVersion: '1.0', method: 'list' };
const res = yield this.vapixPost(url, JSON.stringify(formData));
try {
const encoders = (yield res.json()).data.encoders;
const data = (_b = (_a = encoders.aac) !== null && _a !== void 0 ? _a : encoders.AAC) !== null && _b !== void 0 ? _b : [];
return data.map((item) => {
return {
sampleRate: item.sample_rate,
bitRates: item.bit_rates,
};
});
}
catch (err) {
return [];
}
});
}
checkSdCard() {
return __awaiter(this, void 0, void 0, function* () {
const res = yield this.vapixGet('/axis-cgi/disks/list.cgi', {
diskid: 'SD_DISK',
});
const result = yield (0, xml2js_1.parseStringPromise)(yield res.text(), {
ignoreAttrs: false,
mergeAttrs: true,
explicitArray: false,
});
const data = result.root.disks.disk;
return {
available: data.status === 'OK',
totalSize: parseInt(data.totalsize),
freeSize: parseInt(data.freesize),
};
});
}
downloadCameraReport() {
return __awaiter(this, void 0, void 0, function* () {
const res = yield this.vapixGet('/axis-cgi/serverreport.cgi', { mode: 'text' });
if (res.ok) {
return res;
}
else {
throw new Error(yield (0, common_1.responseStringify)(res));
}
});
}
getMaxFps(channel) {
return __awaiter(this, void 0, void 0, function* () {
const data = JSON.stringify({ apiVersion: '1.0', method: 'getCaptureModes' });
const res = yield this.vapixPost('/axis-cgi/capturemode.cgi', data);
if (!res.ok) {
throw new Error(yield (0, common_1.responseStringify)(res));
}
const response = (yield res.json());
const channels = response.data;
if (channels === undefined) {
throw new Error(`Malformed reply from camera`);
}
const channelData = channels.find((x) => x.channel === channel);
if (channelData === undefined) {
throw new Error(`Video channel '${channel}' not found`);
}
const captureModes = channelData.captureMode;
const captureMode = captureModes.find((x) => x.enabled === true);
if (captureMode === undefined) {
throw new Error(`No enabled capture mode found.`);
}
const maxFps = parseInt(captureMode.maxFPS, 10);
if (isNaN(maxFps)) {
throw new Error(`Max fps not specified for given capture mode.`);
}
return maxFps;
});
}
getTimezone() {
var _a, _b;
return __awaiter(this, void 0, void 0, function* () {
const data = JSON.stringify({ apiVersion: '1.0', method: 'getDateTimeInfo' });
const res = yield this.vapixPost('/axis-cgi/time.cgi', data);
if (res.ok) {
return (_b = (_a = ((yield res.json()))) === null || _a === void 0 ? void 0 : _a.timeZone) !== null && _b !== void 0 ? _b : 'Europe/Prague';
}
else {
throw new Error(yield (0, common_1.responseStringify)(res));
}
});
}
getHeaders() {
var _a;
return __awaiter(this, void 0, void 0, function* () {
try {
const data = JSON.stringify({ apiVersion: '1.0', method: 'list' });
const res = yield this.vapixPost('/axis-cgi/customhttpheader.cgi', data);
if (res.ok) {
return (_a = (yield res.json()).data) !== null && _a !== void 0 ? _a : {};
}
else {
return {};
}
}
catch (e) {
return {};
}
});
}
setHeaders(headers) {
return __awaiter(this, void 0, void 0, function* () {
const data = JSON.stringify({ apiVersion: '1.0', method: 'set', params: headers });
return this.vapixPost('/axis-cgi/customhttpheader.cgi', data);
});
}
parseParameters(response) {
const params = {};
const lines = response.split(/[\r\n]/);
for (let i = 0; i < lines.length; i++) {
if (lines[i].length === 0 || lines[i].substring(0, 7) === '# Error') {
continue;
}
const delimiterPos = lines[i].indexOf('=');
if (delimiterPos !== -1) {
const paramName = lines[i].substring(0, delimiterPos);
const paramValue = lines[i].substring(delimiterPos + 1);
params[paramName] = paramValue;
}
}
return params;
}
getParameterGroup(groupNames) {
return __awaiter(this, void 0, void 0, function* () {
const response = yield this.vapixGet('/axis-cgi/param.cgi', { action: 'list', group: groupNames });
return this.parseParameters(yield response.text());
});
}
setParameter(params) {
let postData = 'action=update&';
for (const key in params) {
postData += key + '=' + params[key] + '&';
}
postData = postData.slice(0, postData.length - 1);
return this.vapixPost('/axis-cgi/param.cgi', postData);
}
getGuardTourList() {
return __awaiter(this, void 0, void 0, function* () {
const gTourList = new Array();
const response = yield this.getParameterGroup('GuardTour');
for (let i = 0; i < 20; i++) {
const gTourBaseName = 'root.GuardTour.G' + i;
if (gTourBaseName + '.CamNbr' in response) {
const gTour = {
id: gTourBaseName,
camNbr: response[gTourBaseName + '.CamNbr'],
name: response[gTourBaseName + '.Name'],
randomEnabled: response[gTourBaseName + '.RandomEnabled'],
running: response[gTourBaseName + '.Running'],
timeBetweenSequences: response[gTourBaseName + '.TimeBetweenSequences'],
tour: [],
};
for (let j = 0; j < 100; j++) {
const tourBaseName = 'root.GuardTour.G' + i + '.Tour.T' + j;
if (tourBaseName + '.MoveSpeed' in response) {
const tour = {
moveSpeed: response[tourBaseName + '.MoveSpeed'],
position: response[tourBaseName + '.Position'],
presetNbr: response[tourBaseName + '.PresetNbr'],
waitTime: response[tourBaseName + '.WaitTime'],
waitTimeViewType: response[tourBaseName + '.WaitTimeViewType'],
};
gTour.tour.push(tour);
}
}
gTourList.push(gTour);
}
else {
break;
}
}
return gTourList;
});
}
setGuardTourEnabled(guardTourID, enable) {
const options = {};
options[guardTourID + '.Running'] = enable ? 'yes' : 'no';
return this.setParameter(options);
}
parsePtz(parsed) {
const res = [];
parsed.forEach((value) => {
const delimiterPos = value.indexOf('=');
if (delimiterPos === -1) {
return;
}
if (!value.startsWith('presetposno')) {
return;
}
const id = Number(value.substring(11, delimiterPos));
if (Number.isNaN(id)) {
return;
}
const data = value.substring(delimiterPos + 1).split(':');
const getValue = (valueName) => {
for (const d of data) {
const p = d.split('=');
if (p[0] === valueName) {
return Number(p[1]);
}
}
return 0;
};
res.push({
id,
name: data[0],
data: {
pan: getValue('pan'),
tilt: getValue('tilt'),
zoom: getValue('zoom'),
},
});
});
return res;
}
parseCameraPtzResponse(response) {
const json = JSON.parse(response);
const parsed = {};
Object.keys(json).forEach((key) => {
if (!key.startsWith('Camera ')) {
return;
}
const camera = Number(key.replace('Camera ', ''));
if (json[key].presets !== undefined) {
parsed[camera] = this.parsePtz(json[key].presets);
}
});
return parsed;
}
getPTZPresetList(channel) {
return __awaiter(this, void 0, void 0, function* () {
const response = yield (yield this.vapixGet('/axis-cgi/com/ptz.cgi', { query: 'presetposcam', camera: channel.toString() })).text();
const positions = [];
const lines = response.split(/[\r\n]/);
for (const line of lines) {
if (line.indexOf('presetposno') !== -1) {
const delimiterPos = line.indexOf('=');
if (delimiterPos !== -1) {
const value = line.substring(delimiterPos + 1);
positions.push(value);
}
}
}
return positions;
});
}
listPtzVideoSourceOverview() {
return __awaiter(this, void 0, void 0, function* () {
try {
const response = yield this.vapixGet('/axis-cgi/com/ptz.cgi', {
query: 'presetposall',
format: 'json',
});
const data = this.parseCameraPtzResponse(yield response.text());
const res = {};
Object.keys(data).forEach((camera) => {
res[Number(camera) - 1] = data[Number(camera)].map((_a) => {
var { data } = _a, d = __rest(_a, ["data"]);
return d;
});
});
return res;
}
catch (err) {
return [];
}
});
}
goToPreset(channel, presetName) {
return this.vapixGet('/axis-cgi/com/ptz.cgi', { camera: channel.toString(), gotoserverpresetname: presetName });
}
getPtzPosition(camera) {
return __awaiter(this, void 0, void 0, function* () {
try {
const res = yield this.vapixGet('/axis-cgi/com/ptz.cgi', {
query: 'position',
camera: camera.toString(),
});
const params = this.parseParameters(yield res.text());
return {
pan: Number(params.pan),
tilt: Number(params.tilt),
zoom: Number(params.zoom),
};
}
catch (err) {
return { pan: 0, tilt: 0, zoom: 0 };
}
});
}
getInputState(port) {
return __awaiter(this, void 0, void 0, function* () {
const response = yield (yield this.vapixGet('/axis-cgi/io/port.cgi', { checkactive: port.toString() })).text();
return response.split('=')[1].indexOf('active') === 0;
});
}
setOutputState(port, active) {
return __awaiter(this, void 0, void 0, function* () {
return this.vapixGet('/axis-cgi/io/port.cgi', { action: active ? `${port}:/` : `${port}:\\` });
});
}
getApplicationList() {
return __awaiter(this, void 0, void 0, function* () {
const xml = yield (yield this.vapixGet('/axis-cgi/applications/list.cgi')).text();
const result = (yield (0, xml2js_1.parseStringPromise)(xml));
const apps = [];
for (let i = 0; i < result.reply.application.length; i++) {
apps.push(result.reply.application[i].$);
}
return apps;
});
}
startApplication(applicationID) {
return __awaiter(this, void 0, void 0, function* () {
const res = yield this.vapixGet('/axis-cgi/applications/control.cgi', {
package: applicationID.toLowerCase(),
action: 'start',
});
const text = (yield res.text()).trim().toLowerCase();
if (res.ok && text === 'ok') {
return;
}
else if (text.startsWith('error:') && text.substring(7) === '6') {
return;
}
else {
throw new Error(yield (0, common_1.responseStringify)(res));
}
});
}
restartApplication(applicationID) {
return __awaiter(this, void 0, void 0, function* () {
const res = yield this.vapixGet('/axis-cgi/applications/control.cgi', {
package: applicationID.toLowerCase(),
action: 'restart',
});
const text = (yield res.text()).trim().toLowerCase();
if (res.ok && text === 'ok') {
return;
}
else {
throw new Error(yield (0, common_1.responseStringify)(res));
}
});
}
stopApplication(applicationID) {
return __awaiter(this, void 0, void 0, function* () {
const res = yield this.vapixGet('/axis-cgi/applications/control.cgi', {
package: applicationID.toLowerCase(),
action: 'stop',
});
const text = (yield res.text()).trim().toLowerCase();
if (res.ok && text === 'ok') {
return;
}
else if (text.startsWith('error:') && text.substring(7) === '6') {
return;
}
else {
throw new Error(yield (0, common_1.responseStringify)(res));
}
});
}
}
exports.CameraVapix = CameraVapix;