yuppity / unifi-video-api

Python API for UniFi Video
MIT License
58 stars 11 forks source link

Add option to download a motion image #18

Closed donaldrs closed 4 years ago

donaldrs commented 4 years ago

In addition to the video and the snapshot, a "motion" image is also generated by the server. This is the "red" image that is shown in the UI over the video.

I created a pull request to add a method to recording to download that image. I need that for my own application, but I think more people might find it useful.

Otherwise, thanks for all the great work! I really appreciate it!

yuppity commented 4 years ago

Thank you! This seems like a great addition.

(Please check the PR comments when you have time.)

donaldrs commented 4 years ago

Looks great! I should have checked for fullTimeRecording myself; great addition.

donaldrs commented 3 years ago

Hi,

I noticed in a Unifi Protect library that it had support for a websocket connection from the server. And after some investigation (looking at the web client) it turns out Unifi Video does too. After a lot of experimentation on my own, I managed to hack a websocket connection into your Unifi Video API library. There are a few issues:

It seems the websocket connection only works if you authenticate with username/password, not with the API Key (or I made an error somewhere…) My Python skills are rudimentary at best; give me Java or C++ and I can write great code, but my Python is limited to just trying and trying and getting something to work in a  non-elegant but functional way

So far, the code works by the client registering a callback function which gets called with the raw (json) message from the server as soon as it arrives. I have not yet spent time decoding the messages but the Json is readable so that should not be very hard to do.

As an example, I now get these in my callback:

[recording started, but still in progress (action=UPDATE, dataType=recording, data.inProgress=True)]

{"action":"UPDATE","data":{"eventType":"motionRecording","eventType":"motionRecording","startTime":1607780036336,"endTime":1607780068386,"cameras":["5fc0e4412f90140075312c89"],"locked":false,"inProgress":true,"markedForDeletion":false,"meta":{"cameraName":"VoordeurG4","key":"ejQMJbnm","recordingPathId":"5eb16b616b05a6c8d1aa43e2"},"_id":"5fd4c6d52f9057dd5a80172f"},"dataType":"recording"}

[same recording started, now finished (action=UPDATE, dataType=recording, data.inProgress=False)]]

{"action":"UPDATE","data":{"eventType":"motionRecording","eventType":"motionRecording","startTime":1607780036336,"endTime":1607780070335,"cameras":["5fc0e4412f90140075312c89"],"locked":false,"inProgress":false,"markedForDeletion":false,"meta":{"cameraName":"VoordeurG4","key":"ejQMJbnm","recordingPathId":"5eb16b616b05a6c8d1aa43e2"},"_id":"5fd4c6d52f9057dd5a80172f"},"dataType":"recording"}

At the moment, the client just gets these messages, it would be nicer if the events were handled internally in the library and the client gets notified of a new recording, a completed recording, … but that is a lot harder to do.

I primary am interested in this because I do not want to poll the server for new recordings every few seconds.

Would you be interested in adding something like this to the library? If so, I could send you my (ugly) code and maybe you can incorporate it?

Greeting,

Richard

From: yuppity notifications@github.com Reply to: yuppity/unifi-video-api reply@reply.github.com Date: Friday, 31 July 2020 at 17:03 To: yuppity/unifi-video-api unifi-video-api@noreply.github.com Cc: donaldrs reg@hierzo.com, Author author@noreply.github.com Subject: Re: [yuppity/unifi-video-api] Add option to download a motion image (#18)

Thank you! This seems like a great addition.

(Please check the PR comments when you have time.)

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.

yuppity commented 3 years ago

I might be interested in incorporating this as a some sort of an alternate operating mode. Meaning users would have to init UnifiVideoAPI into a separate WS mode. There's also a couple of things I'd be looking to avoid if I did implement this:

As such, I'd likely end up using a synchronous WS lib, maintaining a separate thread for it, and pushing messages to an output queue which users could then do what they liked with. At this point, I'm not sure if I would even want to classify the incoming JSON messages in anyway; I would likely just parse the JSON and queue it as a Python dict. Users would then have to write their own logic based on message['action'] and message['dataType'].

That is my thinking atm, though it is tempting to take it a step further and reflect the incoming updates in the recordings collection on the existing UnifiVideoAPI instance. I'll play around with this for awhile and hopefully form a better picture on whether the above makes sense. Any code you can send is welcome.

donaldrs commented 3 years ago

I can see your point. Here is the code that is working for me at the moment. Again, do not look for elegance 😊

Richard

From: yuppity notifications@github.com Reply to: yuppity/unifi-video-api reply@reply.github.com Date: Saturday, 12 December 2020 at 17:26 To: yuppity/unifi-video-api unifi-video-api@noreply.github.com Cc: donaldrs reg@hierzo.com, Author author@noreply.github.com Subject: Re: [yuppity/unifi-video-api] Add option to download a motion image (#18)

I might be interested in incorporating this as a some sort of an alternate operating mode. Meaning users would have to init UnifiVideoAPI into a separate WS mode. There's also a couple of things I'd be looking to avoid if I did implement this: non-WS use cases being dependant on an external WS lib, and having to deal with asyncio or depending on a third party async library. As such, I'd likely end up using a synchronous WS lib, maintaining a separate thread for it, and pushing messages to an output queue which users could then do what they liked with. At this point, I'm not sure if I would even want to classify the incoming JSON messages in anyway; I would likely just parse the JSON and queue it as a Python dict. Users would then have to write their own logic based on message['action'] and message['dataType'].

That is my thinking atm, though it is tempting to take it a step further and reflect the incoming updates in the recordings collection on the existing UnifiVideoAPI instance. I'll play around with this for awhile and hopefully form a better picture on whether the above makes sense. Any code you can send is welcome.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.

donaldrs commented 3 years ago

I now changed the implementation to use a queue.Queue instead of a callback. Pretty simple change, but I think that makes it a bit nicer (as you suggested). The issue is that is nobody is emptying the queue memory will run out at some point. So that would argue for some on/off switch for this functionality.

Richard

From: yuppity notifications@github.com Reply to: yuppity/unifi-video-api reply@reply.github.com Date: Saturday, 12 December 2020 at 17:26 To: yuppity/unifi-video-api unifi-video-api@noreply.github.com Cc: donaldrs reg@hierzo.com, Author author@noreply.github.com Subject: Re: [yuppity/unifi-video-api] Add option to download a motion image (#18)

I might be interested in incorporating this as a some sort of an alternate operating mode. Meaning users would have to init UnifiVideoAPI into a separate WS mode. There's also a couple of things I'd be looking to avoid if I did implement this: non-WS use cases being dependant on an external WS lib, and having to deal with asyncio or depending on a third party async library. As such, I'd likely end up using a synchronous WS lib, maintaining a separate thread for it, and pushing messages to an output queue which users could then do what they liked with. At this point, I'm not sure if I would even want to classify the incoming JSON messages in anyway; I would likely just parse the JSON and queue it as a Python dict. Users would then have to write their own logic based on message['action'] and message['dataType'].

That is my thinking atm, though it is tempting to take it a step further and reflect the incoming updates in the recordings collection on the existing UnifiVideoAPI instance. I'll play around with this for awhile and hopefully form a better picture on whether the above makes sense. Any code you can send is welcome.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.