mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-09-30 19:21:33 +02:00
Closing a camera view and reopening it immediately could leave the new stream unregistered while it was running and delivering frames. The damage was all indirect: is_stream_active() reported no viewer, so Obico polling and snapshots opened a second camera connection against the live view (the thing #1348 and #1271 exist to prevent); the janitor's /proc scan found an ffmpeg missing from _active_streams and killed the live stream as an orphan; and /camera/stop reported "Stopped 0" with a stream running. The fan-out stream id was f"{printer_id}-fanout" -- constant per printer, so every successive stream shared one registry key, and the departing generator's finally popped whatever was under it, including its successor's entry. The same finally also cleared the per-printer frame buffer unconditionally, discarding the new stream's frame. It needed the two streams to overlap, which the 4s teardown made easy. Each stream now gets its own key via _new_fanout_stream_id(), so a generator can only clean up after itself -- the external-camera path already does this (#2675) and this brings the fan-out path in line. The per-printer dicts are released through _release_printer_frame_state(), which checks that no other stream for the printer is still running; both the RTSP and chamber-image cleanups had the same unconditional pop. Also hoisted time and uuid to module level and dropped four function-local `import time` statements. A local import shadows the name for the whole function, so any use on a branch that doesn't reach the import raises UnboundLocalError -- a real hazard in camera_stream, whose external-camera branch imported both while the RTSP path needs them too. A test pins camera_stream as free of function-local imports.