camstreamerlib
Version:
Helper library for CamStreamer ACAP applications.
167 lines (166 loc) • 6.94 kB
JavaScript
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);
}
}
}