diff --git a/plugins/onvif/src/main.ts b/plugins/onvif/src/main.ts index cbe2123d4..e648bdf5f 100644 --- a/plugins/onvif/src/main.ts +++ b/plugins/onvif/src/main.ts @@ -6,48 +6,29 @@ import { connectCameraAPI, OnvifEvent } from "./onvif-api"; const { mediaManager } = sdk; -class OnvifCamera extends RtspSmartCamera implements Camera { +class OnvifCamera extends RtspSmartCamera { eventStream: Stream; listenEvents(): EventEmitter & Destroyable { + (async () => { + const client = await this.createClient(); + const events = client.listenEvents(); + events.on('event', event => { + if (event === OnvifEvent.MotionStart) + this.motionDetected = true; + else if (event === OnvifEvent.MotionStop) + this.motionDetected = false; + else if (event === OnvifEvent.AudioStart) + this.audioDetected = true; + else if (event === OnvifEvent.AudioStop) + this.audioDetected = false; + }) + })(); const ret: any = new EventEmitter(); ret.destroy = () => { - }; - return ret; } - constructor(nativeId: string) { - super(nativeId); - - this.createMotionStream(); - } - - async createMotionStream() { - while (true) { - try { - this.motionDetected = false; - this.audioDetected = false; - - const api = await this.createClient(); - for await (const event of api.listenEvents()) { - if (event === OnvifEvent.MotionStart) - this.motionDetected = true; - else if (event === OnvifEvent.MotionStop) - this.motionDetected = false; - else if (event === OnvifEvent.AudioStart) - this.audioDetected = true; - else if (event === OnvifEvent.AudioStop) - this.audioDetected = false; - } - } - catch (e) { - console.error('event listener failure', e); - await new Promise(resolve => setTimeout(resolve, 10000)); - } - } - } - createClient() { return connectCameraAPI(this.storage.getItem('ip'), this.getUsername(), this.getPassword()); } diff --git a/plugins/onvif/src/onvif-api.ts b/plugins/onvif/src/onvif-api.ts index c1224dfb2..9ab10f50c 100644 --- a/plugins/onvif/src/onvif-api.ts +++ b/plugins/onvif/src/onvif-api.ts @@ -1,4 +1,5 @@ import { EventEmitter, once } from 'events'; +import { Destroyable } from '../../rtsp/src/rtsp'; import DigestClient from './digest-client'; const onvif = require('onvif'); @@ -11,37 +12,31 @@ export enum OnvifEvent { AudioStop, } -export class OnvifCameraAPI extends EventEmitter { +export class OnvifCameraAPI { digestAuth: DigestClient; constructor(public cam: any, username: string, password: string) { - super(); - this.digestAuth = new DigestClient(username, password); } - async* listenEvents() { - + listenEvents() { + const ret = new EventEmitter(); this.cam.on('event', (event: any) => { const value = event.message?.message?.data?.simpleItem?.$?.Value; if (event.topic?._?.indexOf('MotionAlarm') !== -1) { if (value === true) - this.emit('event', OnvifEvent.MotionStart) + ret.emit('event', OnvifEvent.MotionStart) else if (value === false) - this.emit('event', OnvifEvent.MotionStop) + ret.emit('event', OnvifEvent.MotionStop) } else if (event.topic?._?.indexOf('DetectedSound') !== -1) { if (value === true) - this.emit('event', OnvifEvent.AudioStart) + ret.emit('event', OnvifEvent.AudioStart) if (value === false) - this.emit('event', OnvifEvent.AudioStop) + ret.emit('event', OnvifEvent.AudioStop) } }); - - while (true) { - const [event] = await once(this, 'event'); - yield event as OnvifEvent; - } + return ret; } async getStreamUrl(): Promise { @@ -51,7 +46,7 @@ export class OnvifCameraAPI extends EventEmitter { async jpegSnapshot(): Promise { const url: string = (await new Promise((resolve, reject) => this.cam.getSnapshotUri((err: Error, uri: string) => err ? reject(err) : resolve(uri))) as any).uri; - const response = await this.digestAuth.fetch( url); + const response = await this.digestAuth.fetch(url); const buffer = await response.arrayBuffer(); return Buffer.from(buffer);