camstreamerlib
Version:
Helper library for CamStreamer ACAP applications.
211 lines (210 loc) • 9.61 kB
JavaScript
;
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;