UNPKG

camstreamerlib

Version:

Helper library for CamStreamer ACAP applications.

442 lines (441 loc) 18 kB
"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;