Scripting with Python

Everything in Strand Camera and Braid that can be controlled from the web browser can also be controlled from a Python script. The general technique is to connect to a running Strand Camera (or Braid) process over HTTP, exactly as a browser does. All scripts below require the requests library:

pip install requests

Demo: recording a video using Strand Camera from a Python script

record-mp4-video.py connects to a running Strand Camera instance, sends a command to start MP4 recording, waits five seconds, then sends a command to stop. Run it like so:

python record-mp4-video.py --strand-cam-url http://127.0.0.1:3440/

The --strand-cam-url argument defaults to http://127.0.0.1:3440/ and should be changed to match the URL shown in your Strand Camera window. Modify the time.sleep(5.0) call to change the recording duration, or replace the fixed sleep with your own experimental logic between the start and stop commands.

Demo: recording a color video with the ffmpeg codec

record-mp4-video-ffmpeg.py records an MP4 using the Ffmpeg codec, which pipes frames to the system ffmpeg binary. Unlike the built-in H.264 encoders, the ffmpeg codec accepts color input, so this is the path to use for color recordings — for example on GPUs where the built-in NVENC encoder is unavailable. Start Strand Camera with a color pixel format:

strand-cam --camera-name my-camera --pixel-format RGB8

and then run:

python record-mp4-video-ffmpeg.py --strand-cam-url http://127.0.0.1:3440/ --codec libx264

The --codec argument selects the ffmpeg encoder (default libx264; other common choices are h264_nvenc and h264_vaapi) and must be available in your ffmpeg build. Pass --verify-dir with the directory Strand Camera writes to (its --data-dir) to have the script confirm that a non-empty .mp4 was produced; this is how the script is exercised as an automated end-to-end test in the project's continuous integration, so it stays in sync with the software.

Demo: recording multiple videos using Braid from a Python script

record-mp4-video-braid-all-cams.py connects to a running Braid instance and sends a single command that starts MP4 recording on all connected cameras simultaneously, waits five seconds, then stops. Run it like so:

python record-mp4-video-braid-all-cams.py --braid-url http://127.0.0.1:8397/

The --braid-url argument defaults to http://127.0.0.1:8397/. As with the single-camera script, replace the fixed sleep with your own trigger logic to control exactly when recording starts and stops.

Demo: save preview images to disk from Strand Camera using Python

strand_cam_subscriber.py subscribes to the live image stream from Strand Camera and saves each frame as a JPEG file (image0000.jpg, image0001.jpg, …). Run it like so:

python strand_cam_subscriber.py --strand-cam-url http://127.0.0.1:3440/

Each frame is acknowledged back to Strand Camera after it is saved, which acts as flow control — Strand Camera will not send the next frame until the acknowledgment is received. This makes the script suitable as a starting point for per-frame image processing in Python.

Demo: listen to realtime 3D tracking data using Python

braid_retransmit_udp.py subscribes to the live event stream from Braid and re-transmits the 3D position of each tracked object as a UDP packet containing comma-separated x, y, z values. Run it like so:

python braid_retransmit_udp.py --braid-url http://127.0.0.1:8397/ \
    --udp-host 127.0.0.1 --udp-port 1234

The event stream carries three types of messages: Birth (a new object is first detected), Update (position estimate for a tracked object), and Death (an object is no longer tracked). The script forwards only Update events. You can extend it to handle Birth and Death events for applications that need to track object identity over time.

Demo: resetting the object detection background model using Python

reset-background.py presses the background model buttons of the object detection UI programmatically. By default it acts like the Take Current Image As Background button, re-initializing the background model from the next ~20 incoming frames:

python reset-background.py --strand-cam-url http://127.0.0.1:3440/

With --clear-to-value, it instead acts like the Set background to mid-gray button, setting the background model to a uniform gray value:

python reset-background.py --strand-cam-url http://127.0.0.1:3440/ --clear-to-value 127

The underlying HTTP calls are simple: a POST to the /callback endpoint with the JSON body "TakeCurrentImageAsBackground" or {"ClearBackground": 127.0}.

Demo: resetting the background model on all cameras of a Braid setup

reset-background-braid-all-cams.py performs the same background reset on every camera connected to a running Braid instance. Run it like so:

python reset-background-braid-all-cams.py --braid-url http://127.0.0.1:8397/

Unlike MP4 recording, there is no single Braid command for this. Instead, the script asks Braid for the HTTP address of every connected camera (this is carried in the connected_cameras field of the Braid event stream) and then sends the command to each Strand Camera directly. The same pattern can be used to automate any other per-camera action across a whole Braid setup.

Advanced: automating manual actions

Any action available in the browser UI can be scripted. To discover the corresponding HTTP call, open your browser's developer tools (F12 in most browsers), go to the Network tab, and perform the action manually. You will see the POST request sent to the /callback endpoint and the JSON body it carries. You can then replicate that call in Python using the StrandCamProxy or BraidProxy pattern shown in the demo scripts above.