1
0
Fork 0
mirror of https://github.com/maziggy/bambuddy.git synced 2026-05-09 08:25:54 +02:00

[GH-ISSUE #1177] [Bug]: External camera images show as black in notifications/timelapse #850

Closed
opened 2026-05-07 00:14:21 +02:00 by BreizhHardware · 6 comments

Originally created by @nkm8 on GitHub (Apr 30, 2026).
Original GitHub issue: https://github.com/maziggy/bambuddy/issues/1177

Originally assigned to: @maziggy on GitHub.

Component

Bambuddy

Bug Description

With an external camera configured - tried both as a direct device connection and an external mjpeg stream hosted in go2rtc - the images all show as black.

Expected Behavior

Images/timelapse images show actual camera stream contents.

Steps to Reproduce

  1. Configure external camera in go2rtc as mjpeg stream
  2. Add in bambuddy
  3. Start a print
  4. Receive notifications with black image attachments

Printer Model

A1 Mini

Bambuddy Version

v0.2.4b2

SpoolBuddy Version

No response

Printer Firmware Version

No response

Installation Method

Docker

Operating System

Linux (Ubuntu/Debian)

Relevant Logs / Support Package

bambuddy-support-20260430-100200.zip

Screenshots

No response

Additional Context

No response

Checklist

  • I have searched existing issues to ensure this bug hasn't already been reported
  • I am using the latest version of Bambuddy
  • My printer is set to LAN Only mode
  • My printer has Developer Mode enabled
Originally created by @nkm8 on GitHub (Apr 30, 2026). Original GitHub issue: https://github.com/maziggy/bambuddy/issues/1177 Originally assigned to: @maziggy on GitHub. ### Component Bambuddy ### Bug Description With an external camera configured - tried both as a direct device connection and an external mjpeg stream hosted in go2rtc - the images all show as black. ### Expected Behavior Images/timelapse images show actual camera stream contents. ### Steps to Reproduce 1. Configure external camera in go2rtc as mjpeg stream 2. Add in bambuddy 3. Start a print 4. Receive notifications with black image attachments ### Printer Model A1 Mini ### Bambuddy Version v0.2.4b2 ### SpoolBuddy Version _No response_ ### Printer Firmware Version _No response_ ### Installation Method Docker ### Operating System Linux (Ubuntu/Debian) ### Relevant Logs / Support Package [bambuddy-support-20260430-100200.zip](https://github.com/user-attachments/files/27246370/bambuddy-support-20260430-100200.zip) ### Screenshots _No response_ ### Additional Context _No response_ ### Checklist - [x] I have searched existing issues to ensure this bug hasn't already been reported - [x] I am using the latest version of Bambuddy - [x] My printer is set to LAN Only mode - [x] My printer has Developer Mode enabled
BreizhHardware 2026-05-07 00:14:21 +02:00
  • closed this issue
  • added the
    bug
    label
Author
Owner

@nkm8 commented on GitHub (Apr 30, 2026):

Additional context - I don't think it shows in the logs I shared, but I noticed that eventually the notification images started working mid-way through the print. I theorize this happened after I went into the Settings page and clicked the 'Test' button on the camera. From the logs, after the test:

10:02:26,738
[backend.app.api.routes.camera][4b9c879e] Using external camera (mjpeg) for printer 1 at 15 fps
10:02:31,248
[backend.app.services.external_camera][4b9c879e] MJPEG stream cancelled
10:02:31,248
[backend.app.services.external_camera][4b9c879e] External MJPEG stream ended, reconnecting (attempt 1/3)...
10:02:31,249
[backend.app.api.routes.camera][4b9c879e] External camera stream ended for printer 1
10:02:31,496
[backend.app.api.routes.camera][bbbfdf6b] Stopped 0 camera stream(s) for printer 1
10:02:31,498
[uvicorn.access][-] 192.168.1.8:50806 - "POST /api/v1/printers/1/camera/stop HTTP/1.1" 200
10:02:31,895
[backend.app.services.external_camera][-] capture_frame called: type=mjpeg, url=http://192.168.1.61:1984/api/stream.mjpeg?src=prin...
10:02:47,400
[backend.app.services.external_camera][-] capture_frame called: type=mjpeg, url=http://192.168.1.61:1984/api/stream.mjpeg?src=prin...
10:03:04,027
[backend.app.services.external_camera][-] capture_frame called: type=mjpeg, url=http://192.168.1.61:1984/api/stream.mjpeg?src=prin...
10:03:19,439
[backend.app.services.external_camera][-] capture_frame called: type=mjpeg, url=http://192.168.1.61:1984/api/stream.mjpeg?src=prin...
10:03:35,396
[backend.app.services.external_camera][-] capture_frame called: type=mjpeg, url=http://192.168.1.61:1984/api/stream.mjpeg?src=prin...
10:03:51,440
[backend.app.services.external_camera][-] capture_frame called: type=mjpeg, url=http://192.168.1.61:1984/api/stream.mjpeg?src=prin...
10:04:43,962
[backend.app.services.external_camera][ec3695e9] Testing camera connection: type=mjpeg, url=http://192.168.1.61:1984/api/stream.mjpeg?src=prin...
10:04:43,967
[backend.app.services.external_camera][ec3695e9] Capture result: 45753 bytes
10:04:43,969
[uvicorn.access][-] 192.168.1.8:35360 - "POST /api/v1/printers/1/camera/external/test?url=http%3A%2F%2F192.168.1.61%3A1984%2Fapi%2Fstream.mjpeg%3Fsrc%3Dprinter&camera_type=mjpeg HTTP/1.1" 200
10:06:54,506
[backend.app.main][-] [SNAPSHOT] Capturing from external camera for printer 1
10:06:54,570
[backend.app.main][-] [SNAPSHOT] External camera frame: 36996 bytes
10:10:34,035
[backend.app.main][-] [SNAPSHOT] Capturing from external camera for printer 1
10:10:34,070
[backend.app.main][-] [SNAPSHOT] External camera frame: 39362 bytes
10:15:58,209
[backend.app.main][-] [SNAPSHOT] Capturing from external camera for printer 1
10:15:58,276
[backend.app.main][-] [SNAPSHOT] External camera frame: 36136 bytes
10:23:33,533
[backend.app.main][-] [PHOTO-BG] Using external camera
10:23:33,590
[backend.app.main][-] [PHOTO-BG] Saved external camera frame: finish_20260430_102333_97283aee.jpg

However, the final print finish image shows as black - that is still viewable and downloadable from the UI.

Just a theory - but I noticed that when viewing the go2rtc mjpeg stream in a browser - there is a brief moment, maybe a second, where the image displayed is black. After the stream loads, it is consistent and never shows a black frame. This is on a pi4 - maybe there is a delay needed before capturing the image to allow the camera image to load?

<!-- gh-comment-id:4353784009 --> @nkm8 commented on GitHub (Apr 30, 2026): Additional context - I don't think it shows in the logs I shared, but I noticed that eventually the notification images started working mid-way through the print. I theorize this happened after I went into the Settings page and clicked the 'Test' button on the camera. From the logs, after the test: ``` 10:02:26,738 [backend.app.api.routes.camera][4b9c879e] Using external camera (mjpeg) for printer 1 at 15 fps 10:02:31,248 [backend.app.services.external_camera][4b9c879e] MJPEG stream cancelled 10:02:31,248 [backend.app.services.external_camera][4b9c879e] External MJPEG stream ended, reconnecting (attempt 1/3)... 10:02:31,249 [backend.app.api.routes.camera][4b9c879e] External camera stream ended for printer 1 10:02:31,496 [backend.app.api.routes.camera][bbbfdf6b] Stopped 0 camera stream(s) for printer 1 10:02:31,498 [uvicorn.access][-] 192.168.1.8:50806 - "POST /api/v1/printers/1/camera/stop HTTP/1.1" 200 10:02:31,895 [backend.app.services.external_camera][-] capture_frame called: type=mjpeg, url=http://192.168.1.61:1984/api/stream.mjpeg?src=prin... 10:02:47,400 [backend.app.services.external_camera][-] capture_frame called: type=mjpeg, url=http://192.168.1.61:1984/api/stream.mjpeg?src=prin... 10:03:04,027 [backend.app.services.external_camera][-] capture_frame called: type=mjpeg, url=http://192.168.1.61:1984/api/stream.mjpeg?src=prin... 10:03:19,439 [backend.app.services.external_camera][-] capture_frame called: type=mjpeg, url=http://192.168.1.61:1984/api/stream.mjpeg?src=prin... 10:03:35,396 [backend.app.services.external_camera][-] capture_frame called: type=mjpeg, url=http://192.168.1.61:1984/api/stream.mjpeg?src=prin... 10:03:51,440 [backend.app.services.external_camera][-] capture_frame called: type=mjpeg, url=http://192.168.1.61:1984/api/stream.mjpeg?src=prin... 10:04:43,962 [backend.app.services.external_camera][ec3695e9] Testing camera connection: type=mjpeg, url=http://192.168.1.61:1984/api/stream.mjpeg?src=prin... 10:04:43,967 [backend.app.services.external_camera][ec3695e9] Capture result: 45753 bytes 10:04:43,969 [uvicorn.access][-] 192.168.1.8:35360 - "POST /api/v1/printers/1/camera/external/test?url=http%3A%2F%2F192.168.1.61%3A1984%2Fapi%2Fstream.mjpeg%3Fsrc%3Dprinter&camera_type=mjpeg HTTP/1.1" 200 10:06:54,506 [backend.app.main][-] [SNAPSHOT] Capturing from external camera for printer 1 10:06:54,570 [backend.app.main][-] [SNAPSHOT] External camera frame: 36996 bytes 10:10:34,035 [backend.app.main][-] [SNAPSHOT] Capturing from external camera for printer 1 10:10:34,070 [backend.app.main][-] [SNAPSHOT] External camera frame: 39362 bytes 10:15:58,209 [backend.app.main][-] [SNAPSHOT] Capturing from external camera for printer 1 10:15:58,276 [backend.app.main][-] [SNAPSHOT] External camera frame: 36136 bytes 10:23:33,533 [backend.app.main][-] [PHOTO-BG] Using external camera 10:23:33,590 [backend.app.main][-] [PHOTO-BG] Saved external camera frame: finish_20260430_102333_97283aee.jpg ``` However, the final print finish image shows as black - that is still viewable and downloadable from the UI. Just a theory - but I noticed that when viewing the go2rtc mjpeg stream in a browser - there is a brief moment, maybe a second, where the image displayed is black. After the stream loads, it is consistent and never shows a black frame. This is on a pi4 - maybe there is a delay needed before capturing the image to allow the camera image to load?
Author
Owner

@nkm8 commented on GitHub (Apr 30, 2026):

More research - I'm not sure if it is possible to delay the capture or detect if an all-black image is captured. I also noticed that go2rtc provides a specific endpoint for a single frame - in my example, it is: http://192.168.1.61:1984/api/frame.jpeg?src=printer

I refreshed that page a bunch and never saw an all-black result. Does it make sense to add an additional/optional input for image capture in addition to live stream?

<!-- gh-comment-id:4354190535 --> @nkm8 commented on GitHub (Apr 30, 2026): More research - I'm not sure if it is possible to delay the capture or detect if an all-black image is captured. I also noticed that go2rtc provides a specific endpoint for a single frame - in my example, it is: http://192.168.1.61:1984/api/frame.jpeg?src=printer I refreshed that page a bunch and never saw an all-black result. Does it make sense to add an additional/optional input for image capture in addition to live stream?
Author
Owner

@maziggy commented on GitHub (May 1, 2026):

Thanks for the methodical follow-ups — the size details in your log plus the go2rtc /api/frame.jpeg observation made the root cause diagnosis clean.

Confirmed and fixed in dev. Bambuddy was returning the very first JPEG it found on the MJPEG stream — and go2rtc (along with several IP cameras) emits a warm-up / black frame on the byte that follows connection accept, before the encoder catches up to live content. Subsequent frames on the same connection are fine, which is why everything worked from the live-view tab once the stream had been running for a second, and why your post-Test-button captures came through correctly while fresh-connection captures did not.

The fix reads past the first frame and returns the second; on a single-frame stream or a timeout it falls back to the warm-up frame so the snapshot / plate-detect / timelapse code paths never silently get None instead of something. 7 regression tests pin both the new behaviour and the fallback guarantees. Latency penalty is at most one frame interval — well inside the 15 s timeout window.

The separate /api/frame.jpeg endpoint suggestion is reasonable for a future "snapshot URL" override on cameras where the warm-up frame persists, but the warm-up skip covers your case directly without needing extra config.

Available/Fixed in branch dev and available with the next release or daily build. Please let me know if it works for you.


If you find Bambuddy useful, please consider giving it a on GitHub — it helps others discover the project!

<!-- gh-comment-id:4358198132 --> @maziggy commented on GitHub (May 1, 2026): Thanks for the methodical follow-ups — the size details in your log plus the go2rtc /api/frame.jpeg observation made the root cause diagnosis clean. Confirmed and fixed in dev. Bambuddy was returning the very first JPEG it found on the MJPEG stream — and go2rtc (along with several IP cameras) emits a warm-up / black frame on the byte that follows connection accept, before the encoder catches up to live content. Subsequent frames on the same connection are fine, which is why everything worked from the live-view tab once the stream had been running for a second, and why your post-Test-button captures came through correctly while fresh-connection captures did not. The fix reads past the first frame and returns the second; on a single-frame stream or a timeout it falls back to the warm-up frame so the snapshot / plate-detect / timelapse code paths never silently get None instead of *something*. 7 regression tests pin both the new behaviour and the fallback guarantees. Latency penalty is at most one frame interval — well inside the 15 s timeout window. The separate /api/frame.jpeg endpoint suggestion is reasonable for a future "snapshot URL" override on cameras where the warm-up frame persists, but the warm-up skip covers your case directly without needing extra config. Available/Fixed in branch dev and available with the next release or daily build. Please let me know if it works for you. ----- If you find Bambuddy useful, please consider giving it a ⭐ on [GitHub](https://github.com/maziggy/bambuddy) — it helps others discover the project!
Author
Owner

@nkm8 commented on GitHub (May 2, 2026):

Thank you for the quick and thorough response! I pulled the latest daily, but unfortunately I am still seeing the same issue (support bundle attached).

A few notes:

  • it is still inconsistent, sometimes all the notification thumbnails work, sometimes they are all black
  • I got the timelapse to work once, but I noticed that the output is a lot less compelling. It is probably a result of the fix, but each image shows the nozzle in a slightly different position, so instead of a clean 'print building up from the bed' I got a disjointed video of the nozzle jumping around
  • I noticed this last issue even before the fix, but the 'print completed' notification (when it works) - shows the nozzle floating in the air - the bed/print isn't even visible in the frame. The same image is visible by selecting 'View snapshot' in the overflow menu for a print in the Archives page.

Some additional context: I don't think the root issue is go2rtc, I think it is the camera itself. I added go2rtc to try to stabilize the stream - but I also tried letting bambuddy stream directly from the device. Direct from device, I saw a lot of connection issues - after playing with go2rtc, I think this is because my camera supports both an mjpeg stream and a RAW yuyv stream. go2rtc allows me to pick between them, but bambuddy doesn't - from my testing, the yuyv stream is unstable in both, but the mjpeg stream is rock solid in go2rtc.

Here's my go2rtc config, for reference:

streams: 
  printer: v4l2:device?video=/dev/video0&input_format=mjpeg&video_size=800x600&framerate=10
<!-- gh-comment-id:4364284424 --> @nkm8 commented on GitHub (May 2, 2026): Thank you for the quick and thorough response! I pulled the latest daily, but unfortunately I am still seeing the same issue (support bundle attached). A few notes: - it is still inconsistent, sometimes all the notification thumbnails work, sometimes they are all black - I got the timelapse to work once, but I noticed that the output is a lot less compelling. It is probably a result of the fix, but each image shows the nozzle in a slightly different position, so instead of a clean 'print building up from the bed' I got a disjointed video of the nozzle jumping around - I noticed this last issue even before the fix, but the 'print completed' notification (when it works) - shows the nozzle floating in the air - the bed/print isn't even visible in the frame. The same image is visible by selecting 'View snapshot' in the overflow menu for a print in the Archives page. Some additional context: I don't think the root issue is go2rtc, I think it is the camera itself. I added go2rtc to try to stabilize the stream - but I also tried letting bambuddy stream directly from the device. Direct from device, I saw a lot of connection issues - after playing with go2rtc, I think this is because my camera supports both an mjpeg stream and a RAW yuyv stream. go2rtc allows me to pick between them, but bambuddy doesn't - from my testing, the yuyv stream is unstable in both, but the mjpeg stream is rock solid in go2rtc. Here's my go2rtc config, for reference: ``` streams: printer: v4l2:device?video=/dev/video0&input_format=mjpeg&video_size=800x600&framerate=10 ```
Author
Owner

@nkm8 commented on GitHub (May 2, 2026):

D'oh - forgot the attachment:

bambuddy-support-20260502-124045.zip

<!-- gh-comment-id:4364300707 --> @nkm8 commented on GitHub (May 2, 2026): D'oh - forgot the attachment: [bambuddy-support-20260502-124045.zip](https://github.com/user-attachments/files/27305658/bambuddy-support-20260502-124045.zip)
Author
Owner

@maziggy commented on GitHub (May 3, 2026):

Thanks for the follow-up — the camera-positioning observations (timelapse showing nozzle in different positions per frame, finish photo framing the nozzle instead of the bed) are physical-setup matters that any snapshot-from-live-stream timelapse will inherit; those aren't something the core can fix.

The intermittent black thumbnails were addressable, and your /api/frame.jpeg observation pointed at the cleanest fix. Shipped in dev as a new optional Snapshot URL field under Settings → External Cameras (visible for MJPEG / RTSP / USB stream types). When set, every single-frame capture (notification thumbnails, finish photo, timelapse, plate detection, Obico) goes through that URL via plain HTTP GET, bypassing the warm-up dance entirely. Your config would be:

Available/Fixed in branch dev and available with the next release or daily build. Please let me know if it works for you.


If you find Bambuddy useful, please consider giving it a on GitHub — it helps others discover the project!

<!-- gh-comment-id:4365513589 --> @maziggy commented on GitHub (May 3, 2026): Thanks for the follow-up — the camera-positioning observations (timelapse showing nozzle in different positions per frame, finish photo framing the nozzle instead of the bed) are physical-setup matters that any snapshot-from-live-stream timelapse will inherit; those aren't something the core can fix. The intermittent black thumbnails were addressable, and your /api/frame.jpeg observation pointed at the cleanest fix. Shipped in dev as a new optional Snapshot URL field under Settings → External Cameras (visible for MJPEG / RTSP / USB stream types). When set, every single-frame capture (notification thumbnails, finish photo, timelapse, plate detection, Obico) goes through that URL via plain HTTP GET, bypassing the warm-up dance entirely. Your config would be: - Camera URL: http://192.168.1.61:1984/api/stream.mjpeg?src=printer (live view) - Snapshot URL: http://192.168.1.61:1984/api/frame.jpeg?src=printer (everything else) Available/Fixed in branch dev and available with the next release or daily build. Please let me know if it works for you. ----- If you find Bambuddy useful, please consider giving it a ⭐ on [GitHub](https://github.com/maziggy/bambuddy) — it helps others discover the project!
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/bambuddy-maziggy-1#850
No description provided.