UNPKG

camstreamerlib

Version:

Helper library for CamStreamer ACAP applications.

167 lines (166 loc) 6.94 kB
import { ErrorWithResponse, ServiceNotFoundError, StorageDataFetchError } from './errors/errors'; import { networkCameraListSchema } from './types/common'; import { z } from 'zod'; import { ImageType, serviceListSchema, servicesSchema, wsResponseSchema, getStorageDataListSchema, getFileListSchema, } from './types/CamOverlayAPI'; import { BasicAPI } from './internal/BasicAPI'; const BASE_PATH = '/local/camoverlay/api'; export class CamOverlayAPI extends BasicAPI { static getBasePath = () => BASE_PATH; static getProxyPath = () => `${BASE_PATH}/proxy.cgi`; static getFilePreviewPath = (path) => `${BASE_PATH}/image.cgi?path=${encodeURIComponent(path)}`; async checkAPIAvailable(options) { await this._getJson(`${BASE_PATH}/api_check.cgi`, undefined, options); } async checkCameraTime(options) { const res = await this._getJson(`${BASE_PATH}/camera_time.cgi`, undefined, options); return z.boolean().parse(res.state); } async getNetworkCameraList(options) { const res = await this._getJson(`${BASE_PATH}/network_camera_list.cgi`, undefined, options); return networkCameraListSchema.parse(res.camera_list); } async wsAuthorization(options) { const res = await this._getJson(`${BASE_PATH}/ws_authorization.cgi`, undefined, options); return wsResponseSchema.parse(res).message; } async getMjpegStreamImage(mjpegUrl, options) { return await this._getBlob(`${BASE_PATH}/fetch_mjpeg_image.cgi`, { mjpeg_url: decodeURIComponent(mjpegUrl) }, options); } async listFiles(fileType, options) { const res = await this._getJson(`${BASE_PATH}/upload_${fileType}.cgi`, { action: 'list' }, options); return getFileListSchema(fileType).parse(res.list); } async uploadFile(fileType, formData, storage, options) { await this._post(`${BASE_PATH}/upload_${fileType}.cgi`, formData, { action: 'upload', storage: storage, }, options); } async removeFile(fileType, fileParams, options) { await this._postUrlEncoded(`${BASE_PATH}/upload_${fileType}.cgi`, { action: 'remove', ...fileParams, }, options); } async getFileStorage(fileType, options) { const res = await this._getJson(`${BASE_PATH}/upload_${fileType}.cgi`, { action: 'get_storage' }, options); if (res.code !== 200) { throw new StorageDataFetchError(res); } return getStorageDataListSchema(fileType).parse(res.list); } async getFilePreviewFromCamera(path, options) { return await this._getBlob(CamOverlayAPI.getFilePreviewPath(path), undefined, options); } async updateInfoticker(serviceId, text, options) { await this._getJson(`${BASE_PATH}/infoticker.cgi`, { service_id: serviceId, text: text }, options); } async setEnabled(serviceId, enabled, options) { await this._post(`${BASE_PATH}/enabled.cgi`, '', { [`id_${serviceId}`]: enabled ? 1 : 0 }, options); } async isEnabled(serviceId, options) { const agent = this.getClient(options?.proxyParams); const res = await agent.get({ path: `${BASE_PATH}/services.cgi`, parameters: { action: 'get' }, timeout: options?.timeout, }); if (res.ok) { const data = JSON.parse(await res.text()); for (const service of data.services) { if (service.id === serviceId) { return service.enabled === 1; } } throw new ServiceNotFoundError(); } else { throw new ErrorWithResponse(res); } } async getSingleService(serviceId, options) { const res = await this._getJson(`${BASE_PATH}/services.cgi`, { action: 'get', service_id: serviceId, }, options); return servicesSchema.parse(res); } async getServices(options) { const res = await this._getJson(`${BASE_PATH}/services.cgi`, { action: 'get' }, options); const services = serviceListSchema.parse(res).services; return services; } async updateSingleService(service, options) { await this._postJsonEncoded(`${BASE_PATH}/services.cgi`, service, { action: 'set', service_id: service.id, }, options); } async updateServices(services, options) { await this._postJsonEncoded(`${BASE_PATH}/services.cgi`, { services: services }, { action: 'set', }, options); } updateCGText(serviceId, fields, options) { const params = {}; for (const field of fields) { const name = field.field_name; params[name] = field.text; if (field.color !== undefined) { params[`${name}_color`] = field.color; } } return this.promiseCGUpdate(serviceId, 'update_text', params, undefined, undefined, options); } updateCGImagePos(serviceId, coordinates = '', x = 0, y = 0, options) { const params = { coord_system: coordinates, pos_x: x, pos_y: y, }; return this.promiseCGUpdate(serviceId, 'update_image', params, undefined, undefined, options); } updateCGImage(serviceId, path, coordinates = '', x = 0, y = 0, options) { const params = { coord_system: coordinates, pos_x: x, pos_y: y, image: path, }; return this.promiseCGUpdate(serviceId, 'update_image', params, undefined, undefined, options); } updateCGImageFromData(serviceId, imageType, imageData, coordinates = '', x = 0, y = 0, options) { const contentType = imageType === ImageType.PNG ? 'image/png' : 'image/jpeg'; const params = { coord_system: coordinates, pos_x: x, pos_y: y, }; return this.promiseCGUpdate(serviceId, 'update_image', params, contentType, imageData, options); } downloadReport(options) { return this._getText(`${BASE_PATH}/report.cgi`, undefined, options); } async promiseCGUpdate(serviceId, action, params = {}, contentType, data, options) { const path = `${BASE_PATH}/customGraphics.cgi`; let headers = {}; if (contentType !== undefined && data !== undefined) { headers = { 'Content-Type': contentType }; } const agent = this.getClient(options?.proxyParams); const res = await agent.post({ path, data: data ?? '', parameters: { action: action, service_id: serviceId.toString(), ...params, }, headers, timeout: options?.timeout, }); if (!res.ok) { throw new ErrorWithResponse(res); } } }