UNPKG

onvif-cli

Version:

onvif cli to interact with ONVIF devices

212 lines (170 loc) 7.21 kB
import { OnvifDevice } from "node-onvif-ts-extended"; import { OnvifProfile } from "../interfaces/onvif/onvifProfile.interface"; import Capabalities from "../interfaces/onvif/capabilities.interface"; import { Scopes } from "../interfaces/onvif/scopes.interface"; import { CapabalitiesFields } from "../enum/capabalities.enum"; import flattenObject from "../helpers/flattenObject"; interface ReplayUriList { name: string, uri: string } class OnvifServiceCLI { device: OnvifDevice; constructor(device: OnvifDevice) { this.device = device; } public async getCapabilities(): Promise<Capabalities> { try { const capsResponse = await this.device.services.device?.getCapabilities(); const data = capsResponse?.data; const capabilites: Capabalities = data["GetCapabilitiesResponse"]["Capabilities"]; return capabilites; } catch (error) { throw error; } } public async getOnvifProfiles(): Promise<Array<OnvifProfile>> { try { const scopesResponse = await this.device.services.device?.getScopes() const data = scopesResponse?.data; const scopes: Scopes | Array<Scopes> = data["GetScopesResponse"]["Scopes"]; let profiles: Array<OnvifProfile> = []; if (Array.isArray(scopes)) { const rawProfiles = scopes.filter((s: Scopes) => { return s.ScopeItem.indexOf("Profile") !== -1; }) profiles = rawProfiles.map((s: Scopes) => { return this.extractProfile(s) }) } else { profiles = [this.extractProfile(scopes)] } return profiles; } catch (error) { throw error; } } public async getStreamingUri(): Promise<string> { try { let response = await this.device.services.media?.getProfiles(); let data = response?.data; const profiles = data["GetProfilesResponse"]["Profiles"]; if (profiles.length) { const uris = await Promise.all(profiles.map(async (profile: any) => { const profileToken = profile["$"]["token"]; // get streaming uri using profile token response = await this.device.services.media?.getStreamUri({ ProfileToken: profileToken, Protocol: "RTSP" }); data = response?.data; const streamingUri = data["GetStreamUriResponse"]["MediaUri"]["Uri"]; return streamingUri; })) console.table(uris); if (uris.length) return uris[0]; else return ""; } else { return ""; } } catch (error) { throw error; } } // Search for replay URI public async getReplayUriList(): Promise<Array<ReplayUriList>> { try { if (!this.device.services["search"] || !this.device.services["replay"]) { throw new Error("This device does not support Search or Replay or both capabilities") } let list: Array<ReplayUriList> = [] // Request the available recordings let onvifResult = await this.device.services.search.findRecordings({ Scope: {}, KeepAliveTime: 5 }) if (onvifResult) { // GET RECORDINGS SEARCH RESULTS const SearchToken = onvifResult["data"]["FindRecordingsResponse"]["SearchToken"] onvifResult = await this.device.services.search.getRecordingSearchResults({ SearchToken }); let recordings = onvifResult["data"]["GetRecordingSearchResultsResponse"]["ResultList"]["RecordingInformation"] // GET RECORDINGS TOKENs recordings = recordings.map((record: any, i: Number) => { return { recordingToken: record["RecordingToken"], name: record["Source"]["Name"] } }) // GET RECORDINGS RTSP URIs list = await Promise.all(recordings.map(async (record: {recordingToken: string, name: string}, i: Number)=>{ const result = await this.device.services?.replay?.getReplayUri({ 'StreamSetup': { 'Stream': 'RTP-Unicast', 'Transport': { 'Protocol': 'RTSP', }, }, 'RecordingToken': record.recordingToken, }); if(result){ const replayUri = result["data"]["GetReplayUriResponse"]["Uri"]; return { name: record.name, uri: replayUri } } })) } return list; } catch (error) { throw error } } public static getCapabilityField(capabalities: Capabalities, field?: CapabalitiesFields) { switch (field) { case CapabalitiesFields.All: return flattenObject(capabalities) case CapabalitiesFields.Analytics: return flattenObject(capabalities.Analytics) case CapabalitiesFields.Device: return flattenObject(capabalities.Device) case CapabalitiesFields.Events: return flattenObject(capabalities.Events) case CapabalitiesFields.Imaging: return flattenObject(capabalities.Imaging) case CapabalitiesFields.Media: return flattenObject(capabalities.Media) case CapabalitiesFields.PTZ: return flattenObject(capabalities.PTZ) case CapabalitiesFields.Extension: return flattenObject(capabalities.Extension) default: return flattenObject(capabalities) } } // SETUP RTSP URL public static setupRtspUrl(url: string, user: string, pass: string): string { let uri = url; let uriPart1, uriPart2; if (url.indexOf("rtsp://") != -1) { uriPart1 = uri.substring(0, uri.indexOf("//") + 2); uriPart2 = uri.substring(uri.indexOf("//") + 2); } else { uriPart1 = "rtsp://"; uriPart2 = url.replace("//", "/"); // if has // replace them by / } uri = uriPart1 + user + ":" + pass + "@" + uriPart2; return uri; } private extractProfile(s: Scopes): OnvifProfile { const startIndex = s.ScopeItem.lastIndexOf("/") + 1; return { profile: s.ScopeItem.slice(startIndex) } } } export default OnvifServiceCLI;