Motion/Image recording action - handoff movie/image to script
  • Hello, I have a request regarding SecuritySpy image/motion recordings and Actions.

    As I understand it, when motion is detected, Actions are triggered immediately. Actions seem geared towards real-time triggering of relays and so forth, which makes sense.

    SecuritySpy has an 'upload to' option for uploading a movie *after completion*, but there doesn't seem to be easy way to run a script or Action on a recorded movie or image *after* completion (independent of the camera global action).

    So, for example, I want to use a script to post-process a motion capture movie so I can encrypt it and move it to a file server or S3. To do this, I have to know when the movie is done writing and the file is closed before the script can commence. The dumb way to do this is to use Actions and wait an arbitrary amount of time based on the movie capture duration, but that would mean delaying all actions (you can only specify a single global delay value for actions per camera) and I don't want to do that - it's kind of a mis-use of the Actions feature.

    What would be very useful, and I think it would not be so hard to add to SecuritySpy, would be if there was a feature to simply send a completed movie's path as an input arg to a selected script once the file is written, ie, in the Motion Capture tab, under 'Motion Capture' and 'Image Capture', beneath the 'Upload to' checkbox/script selector, add a 'File action' (or 'Movie Action' or 'Image Action') checkbox and a popup menu to select a script (essentially identical to the 'upload to' checkbox configuration). When enabled, after a movie or image is written (completed, file closed), SecuritySpy would simply call the selected script, with the movie/image path sent as an input arg. Doesn't have to do anything else, just call the script, send the path as an arg.

    Then I could use a python script or applescript to do whatever I need. As I said, in my case, I want to first encrypt the motion capture movie file, then I want to upload it to AmazonS3.

    Yes, I imagine there's a way I could pull this off now, by triggering an action script which then parses a folder for new movies, tests that the files are closed/and or waits for a certain amount of time to pass since the latest file was added to know it is closed, then proceed with encryption/upload business logic, etc...and I imagine I'll probably end up writing something like that if I have to, but that's quite a lot of work just because I need to test when a movie/image is done being written. It would be great if Security Spy made this a little easier by offering a little more flexibility for the handoff of its movie/image files to a script.

    Please consider adding something like what I'm describing. Hopefully I've explained it clearly. I was really hoping something like this would be included in SecuritySpy v5.

    Thank you!
  • I notice now that when a movie file recording is in progress, the file extension is ".unf", so that's good - it makes the logic of determining whether a file is finished/closed easy enough, but it still leaves other problems. I can definitely write a script that essentially runs as a 'watch script' on the capture path and deals with parsing and keeping track of what needs to be encrypted and uploaded, but its still a bit messy to have to do all that work when all I really need is the path to the latest image/movie handed directly to a script so I can process the file.

    Also, there is another issue (something I requested a long time ago) that image and movie files all get stored in the same path, so the image files really pile up throughout the day (my camera prefs capture one image every 5 seconds continuous, plus the motion capture movies which pre-roll 1 minute and post-roll 2 minutes), making parsing a directory for movies to process a lengthier operation as the daily folder fills up with images. It would be nice if separate paths could be specified for images vs motion capture movies.

    I really think it would be useful for SecuritySpy to be able to hand off image/movie paths directly to a script as I mentioned above. Thanks!
  • SecuritySpy does in fact have the functionality you describe - please see the ProcessCapturedFile example at the bottom of the SecuritySpy AppleScript Examples page for details.

    Does this do what you want?
  • Ok! That's a bit of a hidden feature the way you've implemented it. ;)

    After doing some testing, my thoughts are - yes, it will work, but is there any chance of modernizing this functionality in the near future?

    1) It would be great if SecuritySpy could invoke python (and bash) directly. It's a waste of system resources to have to spin up applescript as an intermediary (and in my experience, sending a lot of rapid calls to applescript can lead to problems - memory leaks, OS sluggishness, crashes, etc).

    2) The ProcessCapturedFile solution is implemented globally for all SecuritySpy files that are written. I have 4 cameras. Each camera writes a JPG (capture image continuously) every 5 seconds, and captures an m4v only upon motion detection. I only want to process the m4v files. This means every 5 seconds, SecuritySpy is going to spin up 4 instances of the ProcessCapturedFile script. So then my applescript business logic executes the handoff to python only when the file path ends with 'm4v', otherwise, it just returns. 4 cameras every 5 seconds, excluding any motion capture events = 69,120 applescript launches per day. It would be great if, as I mentioned above, I could specify that a script of my choosing is run only upon motion detection, and on a per camera basis.

    3) Going a bit beyond the above suggestions, how about if SecuritySpy transmitted messages/notifications (JSON perhaps) on a specified port? Then there would be none of this overhead of spinning up scripts to process files; the user could just write a script that listened continuously for SecuritySpy messages and responded accordingly.

    Thank you!
  • Coming back to my thread from the other thread...

    I'm playing with reading eventStream via python.

    I trigger recording on a camera:

    The event stream outputs something like:
    20190715183529 508 CAM2 MOTION

    A file starts recording:
    2019-07-15 18-35-23 M CAM003.unf

    Rather oddly, the time stamp on the event stream appears to be several seconds later than the time stamp in the file name. I was thinking maybe I would be able to infer the file name via the time stamp in the event stream, but they don't line up, so that's a no-go.

    SecuritySpy is making this a challenge :-/

    Would be very useful to add the filename being recorded/finished to the event stream as I suggested in the other thread. Seems like it would fit the spec [INFO].

    Even better would be if the events were structured data (json or xml).

  • I understand your reservations about the AppleScript solution.

    We could make some changes to the event stream to make this work for you.

    The file name of the recorded file could be a few seconds before the actual motion, because SecuritySpy may have to start the capture earlier for two reasons. One is the pre-capture feature. The other is that recordings have to start on I-frames, so if the trigger occurs between I-frames, SecuritySpy has to go back to the previous I-frame, which could be several seconds before.

    So how about we add a new FILE event to the event stream, to notify whenever a new file is created, with the file path also supplied. Would that work for you?
  • Yes, a FILE event with path sounds good! Thank you very much! On the subject of paths, one other minor point - it would be helpful if the SecuritySpy file names did not contain any spaces, to eliminate some of the complexity of URL escape character complexity (spaces %20 in the domain vs '+' in the path). Underscores_should_rule_the_universe! ;-)
  • I've considered this a bit more, and I'm not sure that a new FILE event would really do the trick. What you need is some notification when a file has finished capturing, not when it has started capturing, right? Or, are you planning to use these FILE events to then monitor the file and take some action in the future when they are finished (e.g. when the file extension changes from .unf to .mov/.m4v)?
  • Yes, the use case I'm thinking would be most helpful would be a notification when the file has *finished* recording. That way I can have a daemon that just monitors your event stream, and when I get the appropriate notification, I immediately spin up another thread or whatever I end up doing and set things in motion. (My feature set at this point is: log the file path, copy the file where I need it, encrypt the copy, convert it via ffmpeg, delete the original files using my log once some # of them have accumulated, etc)

    20190715183529 508 CAM2 MOTION
    ...later on...
    20190715183629 508 CAM2 FILE /Path/To/File.mov <- a completed file<br />
    I thought that's what you meant in your prior post. Anyway, just thinking about it and the potential for future use cases, why not do both?

    20190715183529 508 CAM2 MOTION
    20190715183529 508 CAM2 FILE_START /Volumes/Disk/Path/To/File.unf
    ...later on...
    20190715183629 508 CAM2 FILE_COMPLETE /Volumes/Disk/Path/To/File.mov

    (or whatever would align best with your stream message specification)
  • OK, I have added the new FILE event. It is documented on the SecuritySpy Web Server Specification page (under Miscellaneous), and implemented in the latest beta version of SecuritySpy (currently 5.0.2b5).

    The new FILE event notifies when the file has completed. I haven't added a FILE_START event, because until the file completes it is unplayable except within SecuritySpy, so I can't think of anything useful that any external process can do with the file until it has finished.

    Note that you'll have to specify version=3 for the event stream to get the new FILE event.

    Let me know what you think!
  • Ok, just tested it out. It works! It's very nice. The stream spits out a burst of FILE events as each camera takes its 5 sec interval JPG, and a FILE event each time an m4v completes recording. Thanks!
  • Great to hear it's working well!
  • Ok, on a different but related note (I didn't want to start a separate thread and lose the context here) - as far as my daemon reading the event stream, I'm not really an expert at the best design patterns for reliably monitoring infinite event streams.

    When there's no new events, I have an open socket with an empty buffer, and an event stream reader thread that is blocked waiting for the next event.

    As soon as the SS event stream spits out a line, my reader thread grabs it, hands it off to another thread for processing, and goes back to waiting for another line. But when there's no new events for a long while, I have no way of knowing if I've lost the server connection. I would have to do something like intermittently execute some other command ie ++systemInfo to test if I get a response. That's not a terrible idea but...

    I can also set an arbitrary timeout on the socket that opened the event stream thread so that if no new messages are received, the timeout is reached, the socket can then be closed and reopened, which happens quickly, but it concerns me that in those milliseconds, maybe an event message could be missed?

    So, in your opinion, would it make sense for the SecSpy event stream to occasionally blip out a STATUS message that indicates the stream is alive, which by doing so, would also accommodate a specified timeout duration?

    ie, a "STATUS" message every 60 seconds:

    20190715183529 508 NA STATUS ALIVE

    Then I would set a timeout on my socket to 50 seconds or something like that, thus, the only case where I would need to worry about re-establishing a connection would be when the timeout is reached due to no stream messages.

    If I'm sounding ignorant here, it's because I am. ;-) Your thoughts are appreciated.
  • Yes, this makes sense, and is in fact common practice for streamed data. So I've added a NULL event that fires off every 10 seconds in the latest beta version of SecuritySpy (currently 5.0.2b6). This is now documented on the Web Server Specifications page. Let me know what you think!
  • This is great. Thanks! It is working as described.
  • Hi @Ben! These changes are really cool and very useful, thank you for adding them!

    I just grabbed the latest beta and starting writing some code. I noticed the MOTION event was removed from the web server page, but it still shows up in the event stream. Was this an oversight? All the other changes in v5 look great!
  • Hi @TwitchCaptain, great to hear that the new additions are useful for you.

    The MOTION is obsolete and has been replaced by the TRIGGER_M and TRIGGER_A events. MOTION should not appear in the current version of the stream (version 3), so I'll make sure this is removed for the next update. Thanks for letting me know!

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!