Concurrent, extensible, frame-scrubbing webcam gateway.
Web API service to stream doorcam and spacecam to Bricodash and public gateway, respectively, while tracking activity and performance of these and other webcams at the space. Will be more efficient and reliable than spawning PHP and Python processes on an as-they-come basis.
Written in Elixir, will be taking advantage of various new features of the language, building on the strengths of Erlang/OTP, including
Presently, webcam-related features of Bricodash are provided on a two-prong basis.
The public-facing Camera showing current activity in the space is presently relayed via a PHP script. This script is configured to relay various HM cameras, including those for the exterior door, the CR-10 and (when online) the hydroponics lab. In the case of the spacecam, all relayed requests are tracked to feed the sous veil Creepy Eyeball: snapshot requests touch a file identifying the requesting pid; stream requests trigger touch two files, one on initiation of the relay, one at process termination. The Creepy Eyeball feature uses the modification times on all such files to transition the opacity of the eyeball animated gif that indicates observers are viewing the camera feed.
The Apache server hosting the Bricodash back-end imposes a cap on the number of executing PHP processes, returning a 504 Gateway Timeout error when this cap is exceeded. Under normal usage, this isn't an issue, but PHP scripts are meant to assemble dynamic content and deliver it, not to provide a data stream as a continuously running process of indeterminate duration. The current setup is thus not ideal.
A legacy gateway for the same Camera remains on Bo.x0.rs. When users of our Slack type "Who's at the space?", the snapshot that our resident slackbot posts in response is drawn from the Bo.x0.rs gateway. Bo.x0.rs also tracks camera access, exposing it via the sousveillance Chrome notification mechanism. However, the sous veil Creepy Eyeball and the sousveillance Chrome notifications system do not, at present, interact or share information.
Bricodash displays a feed of the exterior door camera. Rather than the PHP script, the doorcam display is drawn from a Python3 CGI script.
These flipbooks are executed as upward to 10 snapshot requests per second, from each client, all of which are relayed directly to the webcam. It is possible that this has lead to greater instability on the external door camera that could be resolved by extracting frames from a single stream rather than pounding the server with near two dozen requests per second.
The CGI script also tracks delays on flipbook snapshot requests from the Bricodash clients, reading such delays as evidence of a stalled client. This triggers a restart of the Bricodash client on the Chromecast, and would trigger a webhook alert for the pishop client (if webhooks were not currently disabled). This trigger does not distinguish between delays in flipbook snapshot requests due to stalls of the client and delays due to timeouts on the client while waiting for a stalled doorcam feed. Which means that stalls on the webcam can presently result is a restart of the Chromecast that is not, itself, stalled.
BindSight will replace both the PHP and Python gateways, and will be designed to allow for integration between the sous veil Creepy Eyeball observer-tracking system and the Bo.x0.rs sousveillance view-tracking and Chrome notifications system.
Features will include:
BindSight will leverage Elixir's GenStage behavior to convert a single MJPEG stream into a series of frames that will then be served as any number of snapshots or reconstituted MJPEG streams on demand. This will be implemented as two half-pipelines, or spigots. For each webcam, as slurpspigot will consume an MJPEG stream, releasing it as individual frames, initiate frame corruption checking, track camera performance, and broadcast to sinks. For each client request, a spewspigot will subscribe to the appropriate slurpspigot, scrub out corrupt frames, watermark the last available image in the event of a camera timeout, and serve the resulting snapshot or stream via HTTPS.
Custom plug-ins (including several local plug-ins) will be installable per camera (slurpspigot) or per client/request (spewspigot). These will operate out-of-band as GenStage processes running concurrently with the throughput of the main pipeline. Likewise, frame corruption checks will run asynchronously, allowing frames to be passed down the pipeline independent of JPEG decompression and pixel inspection. Concurrency is the core strength of the Erlang virtual machine (BEAM), which is designed to obtain exceptional performance by spinning up large numbers of lightweight threads.
Erlang, and thus Elixir, is also designed for distributed systems. We will take advantage of this for integration with Bo.x0.rs, relying on Erlang's native node-discovery to manage message passing between souseveillance and sous veil, despite these systems running on different hardware.
Current Project Plan