fix(camera): share one ffmpeg connection for /api/camera/stream #91
Reference in New Issue
Block a user
No description provided.
Delete Branch "Pavulon87/KX-Bridge-Release:fix/camera-fix"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Description
This PR adds support for multiple concurrent MJPEG stream consumers by introducing a shared MJPEG streaming pipeline.
Previously, every request to
/api/camera/streamspawned a separate ffmpeg process and opened a new connection to the printer. Since the printer only supports a very limited number of concurrent camera clients, this could lead to HTTP 429 errors and intermittent "stream unavailable" issues when multiple clients (dashboard, Moonraker-compatible clients, plugins, etc.) accessed the camera simultaneously.The new implementation introduces a dedicated ffmpeg process that generates a shared MJPEG stream, which is then distributed to all connected
/api/camera/streamsubscribers. This approach provides:This implementation was developed with assistance from Claude AI and has been tested locally for several days. It appears to work well in my testing, but I'd appreciate additional review and testing since there may still be edge cases that I haven't encountered.
Related Issue
Closes #90
Type
Tested with
Checklist
Thanks for this, @Pavulon87 — the shared-fanout approach for /api/camera/stream is exactly right and matches the existing handle_camera_h264 pattern well. Couldn't merge the PR branch directly though: the diff contains unresolved git conflict markers (
<<<<<<< HEAD/=======/>>>>>>> c185c76) inside handle_camera_stream, most likely from a local rebase against nightly that never got resolved before pushing — merging as-is would have left literal conflict markers in the Python source.I pulled the fix in manually instead: new
mjpeg_subscribersfanout channel inCameraCache(same shape as the h264 channel), plus the two related fixes you found (theensure_running()race where two callers could both see "no process yet" and spawn duplicate ffmpeg processes, andreset()not waking a task stuck in its backoff sleep). Verified locally that two concurrent/api/camera/streamclients now share a single ffmpeg process instead of one each.Closing this in favor of the manually-integrated version, but the credit for the fix and the race-condition finds is yours. Thanks for the thorough writeup and testing notes!
View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.