Repository navigation
feat: take camera snapshots from the camera's RTSP stream, without Connect - #3
Conversation
|
The architecture fits, and it still fits after I found three credential paths that need closing before this merges:
Since the Buddy3D use case is Also pushing: the fallback to Connect says why RTSP was skipped (the likely case is ffmpeg on the terminal PATH but not the MCP server's, so the local camera never works and nobody knows), a non-404 from After that lands, could you re-test a grab on your camera? I'll test on my Buddy3D as well. |
a1d1374 to
a5dccb1
Compare
…nnect `get_camera_snapshot` and `prusactl camera` needed Prusa Connect. The PrusaLink of Buddy firmware has no camera endpoint. The Buddy3D camera is a separate Wi-Fi device that serves RTSP at `rtsp://<camera-ip>/live`. A printer that was reached only directly therefore had no picture. `prusactl setup --camera URL` (or `PRUSACTL_CAMERA_URL`) saves the address beside the printer. ffmpeg grabs one frame. A snapshot comes from the first source that works: 1. the `/api/v1/cameras/snap` endpoint of the printer 2. the RTSP stream 3. Prusa Connect If the camera fails, the Connect fallback is used. A printer without any camera still says so. `setup --no-camera` forgets only the camera. `--forget` removes it with the printer, also when it was saved without one. `status` shows the camera. The address can carry a password. prusactl masks it wherever it shows the address, including in the error for an address that does not parse, and in `internal/redact`. Only plain `rtsp://` is accepted. With ffmpeg 7.1.5, a self-signed certificate completes the TLS handshake and ffmpeg sends the credentials, even with `-tls_verify 1`. Therefore `rtsps://` is refused. A picture that was cut short is refused. A scheme in capitals is lowercased, because ffmpeg needs this. The config file is now read in one place (`readFile`). Saving the printer keeps the camera, and saving the camera keeps the printer. The Connect snapshot moved into `connectSnapshot`. Both routes share one reader for the image they get back. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Petr Štetiar <ynezz@true.cz>
…a was skipped A password in the RTSP address went two places it shouldn't: onto ffmpeg's command line, where any local user can read it with ps for the length of the grab, and into config.json in plain text while the printer's own password goes to the keychain. The Buddy3D camera takes no credentials, so rather than carry a password carefully the address is refused, with the plain address to use instead. The saved address is checked again before every grab, so PRUSACTL_CAMERA_URL is checked too. connection_status printed the raw value when the scheme was wrong: the mask only knew rtsp://, and a one-character typo in the environment variable showed the password in the first tool an agent calls. It validates first and never prints the raw value. A camera that couldn't be grabbed fell back to Connect's picture with nothing said, so the likely cause, ffmpeg on the terminal's PATH but not the MCP server's, would never be noticed. The note says the camera was skipped and why. A printer that errored on its camera endpoint ended the call, though the camera is its own device; the RTSP source is tried unless there is nothing else local to try. setup refuses --camera with --forget and the printer-only flags on a camera-only run instead of ignoring them, and --forget says when it took the camera address too. The bundle gains the camera setting its own advice pointed at. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
a5dccb1 to
3bec180
Compare
|
Merged in v0.3.0, with one change from what I said: instead of feeding the URL to ffmpeg off argv, credentials in the address are refused outright, since the Buddy3D takes none. The rebase onto main's camera-service change kept your handler and moved the GraphQL lookup into |
hi, my clankers found this nice project during research, I liked it so decided to make you aware about the changes I've made for my use cases, so everyone can profit from that, but feel free to close it or implement it differently, happy to help with testing, cheers, Petr
get_camera_snapshotandprusactl cameraneeded Prusa Connect. The PrusaLink of Buddy firmware has no camera endpoint, and the Buddy3D camera is a separate Wi-Fi device. The Buddy3D serves RTSP atrtsp://<camera-ip>/live. This PR adds that stream as a local source.prusactl setup --camera URLsaves the address next to the printer.PRUSACTL_CAMERA_URLoverrides it.--no-cameraforgets only the camera.--forgetalso removes it.A snapshot comes from the first source that works:
/api/v1/cameras/snapendpoint of the printerIf the camera fails, prusactl falls back to Connect.
The address can carry a password. prusactl masks it wherever it shows the address, including in errors for addresses that do not parse, and in
internal/redact.Only
rtsp://is accepted. With ffmpeg 7.1.5, the RTSP demuxer does not pass-tls_verifyor-ca_fileto TLS. A self-signed impostor received the RTSPOPTIONSrequest even with-tls_verify 1. Thereforertsps://is refused. The README states that plain RTSP sends the password and the video unencrypted.Two more checks: a picture that was cut short is rejected, and a scheme in capitals is lowercased, because ffmpeg needs lowercase.
Two refactors are included. The config file is now read in one place (
readFile), so saving the printer keeps the camera and saving the camera keeps the printer. Both snapshot routes also share one image reader.Testing
rtsps://.