UNPKG

camstreamerlib

Version:

Helper library for CamStreamer ACAP applications.

211 lines (210 loc) 9.61 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.parseCameraStreamResponse = exports.CamStreamerAPI = void 0; const zod_1 = require("zod"); const ProxyClient_1 = require("./internal/ProxyClient"); const CamStreamerAPI_1 = require("./types/CamStreamerAPI/CamStreamerAPI"); const errors_1 = require("./errors/errors"); const oldStreamSchema_1 = require("./types/CamStreamerAPI/oldStreamSchema"); const utils_1 = require("./internal/utils"); const BASE_PATH = '/local/camstreamer'; class CamStreamerAPI { client; constructor(client) { this.client = client; } static getProxyPath = () => `${BASE_PATH}/proxy.cgi`; static getWsEventsPath = () => `${BASE_PATH}/events`; getClient(proxyParams) { return proxyParams ? new ProxyClient_1.ProxyClient(this.client, proxyParams) : this.client; } async checkAPIAvailable(options) { await this._getJson(`${BASE_PATH}/api_check.cgi`, undefined, options); } async wsAuthorization(options) { const res = await this._getJson(`${BASE_PATH}/ws_authorization.cgi`, undefined, options); if (res.status !== 200) { throw new errors_1.WsAuthorizationError(res.message); } return zod_1.z.string().parse(res.data); } async getUtcTime(options) { const res = await this._getJson(`${BASE_PATH}/get_utc_time.cgi`, undefined, options); if (res.status !== 200) { throw new errors_1.UtcTimeFetchError(res.message); } return zod_1.z.number().parse(res.data); } async getMaxFps(source = 0, options) { return await this._getJson(`${BASE_PATH}/get_max_framerate.cgi`, { video_source: source.toString() }, options); } async isCSPassValid(pass, options) { const res = await this._getJson(`${BASE_PATH}/check_pass.cgi`, { pass }, options); return res.data === '1'; } async getStreamList(options) { const res = await this._getJson(`${BASE_PATH}/stream_list.cgi`, { action: 'get' }, options); const oldStreamListRecord = zod_1.z.record(zod_1.z.string(), oldStreamSchema_1.oldStringStreamSchema).safeParse(res.data); if (oldStreamListRecord.success) { const data = Object.entries(oldStreamListRecord.data).map(([id, streamData]) => ({ id: parseInt(id), ...(0, exports.parseCameraStreamResponse)(streamData), })); throw new errors_1.MigrationError([], data); } const newStreamData = []; const oldStreamData = []; const invalidStreamData = []; for (const streamData of res.data.streamList) { const newStreamParse = CamStreamerAPI_1.streamSchema.safeParse(streamData); if (newStreamParse.success) { newStreamData.push(newStreamParse.data); continue; } const oldStreamParse = oldStreamSchema_1.oldStringStreamSchemaWithId.safeParse(streamData); if (oldStreamParse.success) { oldStreamData.push({ id: parseInt(oldStreamParse.data.id), ...(0, exports.parseCameraStreamResponse)(oldStreamParse.data), }); continue; } invalidStreamData.push(streamData); } if (oldStreamData.length > 0 || invalidStreamData.length > 0) { throw new errors_1.MigrationError(newStreamData, oldStreamData, invalidStreamData); } return newStreamData; } async setStreamList(streamList, options) { await this._postJsonEncoded(`${BASE_PATH}/stream_list.cgi`, JSON.stringify({ streamList }), { action: 'set', }, options); } async getStream(streamId, options) { const res = await this._getJson(`${BASE_PATH}/stream_list.cgi`, { action: 'get', stream_id: streamId }, options); const newStream = CamStreamerAPI_1.streamSchema.safeParse(res.data); if (newStream.success) { return newStream.data; } const oldStream = oldStreamSchema_1.oldStringStreamSchema.passthrough().parse(res.data); throw new errors_1.MigrationError([], [{ id: streamId, ...(0, exports.parseCameraStreamResponse)(oldStream) }]); } async setStream(streamId, streamData, options) { await this._postJsonEncoded(`${BASE_PATH}/stream_list.cgi`, JSON.stringify(streamData), { action: 'set', stream_id: streamId, }, options); } async isStreaming(streamId, options) { const res = await this._getJson(`${BASE_PATH}/get_streamstat.cgi`, { stream_id: streamId }, options); return res.data.is_streaming === 1; } async setStreamEnabled(streamId, enabled, options) { await this._postUrlEncoded(`${BASE_PATH}/set_stream_enabled.cgi`, { stream_id: streamId, enabled: enabled ? 1 : 0 }, options); } async setStreamActive(streamId, active, options) { await this._postUrlEncoded(`${BASE_PATH}/set_stream_active.cgi`, { stream_id: streamId, active: active ? 1 : 0 }, options); } async listFiles(options) { const res = await this._getJson(`${BASE_PATH}/upload_audio.cgi`, { action: 'list' }, options); return CamStreamerAPI_1.audioFileListSchema.parse(res.data); } async uploadFile(formData, storage, options) { await this._post(`${BASE_PATH}/upload_audio.cgi`, formData, { action: 'upload', storage: storage, }, options); } async removeFile(fileParams, options) { await this._postUrlEncoded(`${BASE_PATH}/upload_audio.cgi`, { action: 'remove', ...fileParams }, options, undefined); } async getFileStorage(options) { const res = await this._getJson(`${BASE_PATH}/upload_audio.cgi`, { action: 'get_storage' }, options); return CamStreamerAPI_1.storageListSchema.parse(res.data); } async getFileFromCamera(path, options) { return await this._getBlob(`${BASE_PATH}/audio.cgi`, { path }, options); } async _getJson(path, parameters, options) { const agent = this.getClient(options?.proxyParams); const res = await agent.get({ path, parameters, timeout: options?.timeout }); if (res.ok) { return await res.json(); } else { throw new errors_1.ErrorWithResponse(res); } } async _getBlob(path, parameters, options) { const agent = this.getClient(options?.proxyParams); const res = await agent.get({ path, parameters, timeout: options?.timeout }); if (res.ok) { return await this.parseBlobResponse(res); } else { throw new errors_1.ErrorWithResponse(res); } } async parseBlobResponse(response) { try { return (await response.blob()); } catch (err) { throw new errors_1.ParsingBlobError(err); } } async _postUrlEncoded(path, parameters, options, headers) { const data = (0, utils_1.paramToUrl)(parameters); const baseHeaders = { 'Content-Type': 'application/x-www-form-urlencoded' }; return this._post(path, data, undefined, options, { ...baseHeaders, ...headers }); } async _postJsonEncoded(path, data, parameters, options, headers) { const agent = this.getClient(options?.proxyParams); const baseHeaders = { 'Accept': 'application/json', 'Content-Type': 'application/json' }; return agent.post({ path, data, parameters, timeout: options?.timeout, headers: { ...baseHeaders, ...headers }, }); } async _post(path, data, parameters, options, headers) { const agent = this.getClient(options?.proxyParams); const res = await agent.post({ path, data, parameters, headers, timeout: options?.timeout }); if (res.ok) { return await res.json(); } else { throw new errors_1.ErrorWithResponse(res); } } } exports.CamStreamerAPI = CamStreamerAPI; const parseCameraStreamResponse = (cameraStreamData) => { return { enabled: parseInt(cameraStreamData.enabled), active: parseInt(cameraStreamData.active), audioSource: cameraStreamData.audioSource, avSyncMsec: parseInt(cameraStreamData.avSyncMsec), internalVapixParameters: cameraStreamData.internalVapixParameters, userVapixParameters: cameraStreamData.userVapixParameters, outputParameters: cameraStreamData.outputParameters, outputType: cameraStreamData.outputType, mediaServerUrl: cameraStreamData.mediaServerUrl, inputType: cameraStreamData.inputType, inputUrl: cameraStreamData.inputUrl, forceStereo: parseInt(cameraStreamData.forceStereo), streamDelay: isNaN(parseInt(cameraStreamData.streamDelay)) ? null : parseInt(cameraStreamData.streamDelay), statusLed: parseInt(cameraStreamData.statusLed), statusPort: cameraStreamData.statusPort, callApi: parseInt(cameraStreamData.callApi), trigger: cameraStreamData.trigger, schedule: cameraStreamData.schedule, prepareAhead: parseInt(cameraStreamData.prepareAhead), startTime: isNaN(parseInt(cameraStreamData.startTime)) ? null : parseInt(cameraStreamData.startTime), stopTime: isNaN(parseInt(cameraStreamData.stopTime)) ? null : parseInt(cameraStreamData.stopTime), }; }; exports.parseCameraStreamResponse = parseCameraStreamResponse;