diff --git a/docs/config.for.camera.csi.legacy.md b/docs/config.for.camera.csi.legacy.md index b059990..8dc6d30 100644 --- a/docs/config.for.camera.csi.legacy.md +++ b/docs/config.for.camera.csi.legacy.md @@ -1,5 +1,10 @@ # CSI camera on Raspberry Pi (legacy) +![CSI Camera V2](./static/pi-camera.jpg) + +[CSI Camera V2](https://www.raspberrypi.com/products/camera-module-v2/) +as of Sat 23 Mar 08:47:12 UTC 2024. + Example for older operating systems (those with command `raspistill`): - copy `csi-legacy.dist` as `.env` if you want to use Raspberry Pi camera diff --git a/docs/config.for.camera.csi.libcamera.md b/docs/config.for.camera.csi.libcamera.md index ae8bc96..fff7f9a 100644 --- a/docs/config.for.camera.csi.libcamera.md +++ b/docs/config.for.camera.csi.libcamera.md @@ -1,5 +1,10 @@ # CSI camera on Raspberry Pi +![CSI Camera V2](./static/pi-camera.jpg) + +[CSI Camera V2](https://www.raspberrypi.com/products/camera-module-v2/) +as of Sat 23 Mar 08:47:12 UTC 2024. + Example for newer operating systems (commands `libcamera` or `rpicam-still`): - copy `csi.dist` as `.env` if you want to use Raspberry Pi camera diff --git a/docs/config.for.camera.esphome.snapshot.md b/docs/config.for.camera.esphome.snapshot.md index 77c4b9a..0b9601e 100644 --- a/docs/config.for.camera.esphome.snapshot.md +++ b/docs/config.for.camera.esphome.snapshot.md @@ -1,5 +1,7 @@ # ESPHome camera snapshot +![esp32-wrover-dev](./static/esp32-camera.jpg) + With esphome camera with snapshot we can use the ultimate power of `curl` command to fetch the image from the camera. diff --git a/docs/config.for.camera.esphome.stream.md b/docs/config.for.camera.esphome.stream.md index e9e14c3..cd69ccf 100644 --- a/docs/config.for.camera.esphome.stream.md +++ b/docs/config.for.camera.esphome.stream.md @@ -1,5 +1,7 @@ # ESPHome camera stream +![esp32-wrover-dev](./static/esp32-camera.jpg) + With esphome camera stream we can use the `ffmpeg` to fetch the image from the camera stream. It requires a bit more computing power from esp device and the host that runs the image processing. diff --git a/docs/config.for.camera.md b/docs/config.for.camera.md index fbafa74..d12f661 100644 --- a/docs/config.for.camera.md +++ b/docs/config.for.camera.md @@ -18,14 +18,25 @@ from scratch. ## Example devices +### Locally connected + - [Raspberry Pi CSI camera](./config.for.camera.csi.libcamera.md) - libcamera (recommended) - [Raspberry Pi CSI camera](./config.for.camera.csi.legacy.md) - legacy - - [USB camera](./config.for.camera.usb.md) +### Web cams + +#### Generic + +- [Snapshot cams](./config.for.camera.snapshot.md) (recommended) +- [MJPG streaming cams](./config.for.camera.mjpg.md) +- [RTSP streaming cams](./config.for.camera.rtsp.md) + +#### Specific example + - [ESPHome via camera snapshot](./config.for.camera.esphome.snapshot.md) (recommended) - [ESPHome via camera stream](./config.for.camera.esphome.stream.md) -- [RTSP streaming cams](./config.for.camera.rtsp.md) +## Next Next, [test config](./test.config.md). diff --git a/docs/config.for.camera.mjpg.md b/docs/config.for.camera.mjpg.md new file mode 100644 index 0000000..0f62ce3 --- /dev/null +++ b/docs/config.for.camera.mjpg.md @@ -0,0 +1,57 @@ +# Web Cam - MJPG stream + +This processing requires ffmpeg package. + +Most standalone webcams are actually mjpg cams, they send infinite motion jpeg stream +over specific URL. + +The best option to check what is the URL is in the camera manual, or if you +open web UI of the camera and see the stream image then right click on the image +and select Inspect to see the URL for the image - copy that URL. + +You should be able to test the stream locally with `ffplay` command. + +For example, if your camera is reachable over address `192.168.0.20` and port `8000` +under endpoint `/ipcam/mjpeg.cgi` then below command should show the stream: + +```shell +ffplay http://192.168.0.20:8000/ipcam/mjpeg.cgi + +``` + +There may be some user and password in the URL. + +If that works, then configuration should be pretty straightforward: + +- copy `ffmpeg-mjpg-stream.dist` as `.env` +- in copied file `.env` replace `token-change-me` with the value + of the token you copied +- in copied file `.env` replace `fingerprint-change-me` + with some random value, which is alphanumeric and has at least 16 chars + (and max of 40 chars), for example set it to `fingerprint-myprinter4-camera-4` +- in copied file `.env` replace your RTSP device address `raspberry-pi`, + port and stream id in `CAMERA_COMMAND_EXTRA_PARAMS` if needed +- save edited file `.env` + +Next, [test config](./test.config.md). + +## Unverified example + +Beagle Camera stream - if I remember correctly, then camera url to the stream +is something like `http://192.168.2.92/ipcam/mjpeg.cgi` + +Replace `192.168.2.92` with your address in the example below. + + +```shell +PRINTER_ADDRESS=127.0.0.1 +PRUSA_CONNECT_CAMERA_TOKEN=token-change-me +PRUSA_CONNECT_CAMERA_FINGERPRINT=fingerprint-change-me +CAMERA_DEVICE=/dev/null +CAMERA_COMMAND=ffmpeg +CAMERA_COMMAND_EXTRA_PARAMS="-y -i 'http://192.168.2.92/ipcam/mjpeg.cgi' -vframes 1 -q:v 1 -f image2 -update 1 " +``` + + +But it is better to use a snapshot instead of stream if available, +see [here](./config.for.camera.snapshot.md#beagle-camera). diff --git a/docs/config.for.camera.rtsp.md b/docs/config.for.camera.rtsp.md index eab7e02..31363bb 100644 --- a/docs/config.for.camera.rtsp.md +++ b/docs/config.for.camera.rtsp.md @@ -1,4 +1,4 @@ -# RTSP cameras +# Web Cam - RTSP stream ## Caution diff --git a/docs/config.for.camera.snapshot.md b/docs/config.for.camera.snapshot.md new file mode 100644 index 0000000..75e62ee --- /dev/null +++ b/docs/config.for.camera.snapshot.md @@ -0,0 +1,73 @@ +# Web Cam - snapshot + +Some cameras expose single image snapshot under specific URL. +we can use the ultimate power of `curl` command to fetch the image from the camera. + +This is the preferred way to use web cams because right now Prusa Connect do not +support streams, and thus there is no point in wasting CPU on that. + +The best option to check what is the URL is in the camera manual, or if you +open web UI of the camera and see the still image then right click on the image +and select Inspect to see the URL for the image - copy that URL. + +You should be able to test the stream locally with `ffplay` command. + +For example, if your camera is reachable over address `192.168.0.20` and port `8001` +under endpoint `/snap.jpg` then below command should show the image: + +```shell +curl -vvv http://another-cam.local:8081/snap.jpg -o snap.jpg +``` + +then you should see in the output something like `Content-Type: image/jpeg`, +then you are good - see `snap.jpg` in the folder you executed the command. + +## Create config for script + +- copy `snapshot.dist` as `.env` +- in copied file `.env` replace `token-change-me` with the value + of the token you copied +- in copied file `.env` replace `fingerprint-change-me` with some + random value, which is alphanumeric and has at least 16 chars (and max of 40 chars), + for example set it to `fingerprint-myprinter3-camera-3` +- in copied file `.env` replace your esphome device address and port + in `CAMERA_COMMAND_EXTRA_PARAMS` +- save edited file `.env` + +Next, [test config](./test.config.md). + +## Real world example + +### esp32 with esphome + +For more in-depth details see [esphome snapshot](./config.for.camera.esphome.snapshot.md). + +I have esp32-wrover-dev board with camera + esphome + web ui for camera exposing +snapshot frame on port `8081`. + +We can use curl to fetch it. + +```shell +PRINTER_ADDRESS=127.0.0.1 +PRUSA_CONNECT_CAMERA_TOKEN=redacted +PRUSA_CONNECT_CAMERA_FINGERPRINT=06f47777-f179-4025-bd80-9e4cb8db2aed +CAMERA_DEVICE=/dev/null +CAMERA_COMMAND=curl +CAMERA_COMMAND_EXTRA_PARAMS=http://esp32-wrover-0461c8.local:8081/ -o +``` + +### Beagle Camera + +This is not tested, I do not own such camera so hard to tell if this is right. + +Camera URL for snapshot `http://192.168.2.92/images/snapshot0.jpg` so the config +should be like below: + +```shell +PRINTER_ADDRESS=127.0.0.1 +PRUSA_CONNECT_CAMERA_TOKEN=redacted +PRUSA_CONNECT_CAMERA_FINGERPRINT=06f47777-f179-4025-bd80-9e4cb8db2aed +CAMERA_DEVICE=/dev/null +CAMERA_COMMAND=curl +CAMERA_COMMAND_EXTRA_PARAMS=http://192.168.2.92/images/snapshot0.jpg -o +``` diff --git a/docs/config.for.camera.usb.md b/docs/config.for.camera.usb.md index 03cac58..f5f1bc0 100644 --- a/docs/config.for.camera.usb.md +++ b/docs/config.for.camera.usb.md @@ -1,5 +1,7 @@ # USB camera +![USB camera](./static/usb_cam.png) + This should work on any linux distro with any sane camera that you have. ## How to get info which cameras are available? diff --git a/docs/performance.md b/docs/performance.md index ad69a7a..5a6ab9b 100644 --- a/docs/performance.md +++ b/docs/performance.md @@ -1,7 +1,14 @@ # Performance -- Raspberry Pi Zero W is able to process CSI camera (Rpi Cam v2) and USB 2k camera +- Raspberry Pi Zero W is able to process [CSI camera](./config.for.camera.csi.libcamera.md) + (Rpi Cam v2) and [USB 2k](./config.for.camera.usb.md) camera but it has load average about 1.4, and CPU is quite well utilized, so you may - need to decrease resolution per camera to see how it goes. + need to [decrease resolution](./configuration.tuning.md) per camera to see how + it goes. -- ffdshow is usually noticeably slow and cpu intensive if you do more complex operations +- for webcams it is always better to choose [snapshot](./config.for.camera.snapshot.md) + because it requires less computing both on camera and on the host, + otherwise we need to use ffmpeg + +- ffmpeg is usually noticeably slow and cpu intensive, especially if you do more + complex operations diff --git a/docs/static/esp32-camera.jpg b/docs/static/esp32-camera.jpg new file mode 100644 index 0000000..0f7e3d0 Binary files /dev/null and b/docs/static/esp32-camera.jpg differ diff --git a/docs/static/pi-camera.jpg b/docs/static/pi-camera.jpg new file mode 100644 index 0000000..f908ed4 Binary files /dev/null and b/docs/static/pi-camera.jpg differ diff --git a/docs/static/usb_cam.png b/docs/static/usb_cam.png new file mode 100644 index 0000000..daca6ba Binary files /dev/null and b/docs/static/usb_cam.png differ diff --git a/docs/stream.mediamtx.md b/docs/stream.mediamtx.md index 1fa5572..b07b4c2 100644 --- a/docs/stream.mediamtx.md +++ b/docs/stream.mediamtx.md @@ -19,9 +19,10 @@ paths: source: rpiCamera endoscope: - runOnInit: ffmpeg -f v4l2 -i /dev/video1 -pix_fmt yuv420p -preset ultrafast -b:v 600k -f rtsp rtsp://localhost:$RTSP_PORT/$MTX_PATH + runOnInit: ffmpeg -f v4l2 -i /dev/video1 -pix_fmt yuv420p -c:v libx264 -preset ultrafast -b:v 600k -f rtsp rtsp://localhost:$RTSP_PORT/$MTX_PATH runOnInitRestart: yes + ``` @@ -39,3 +40,10 @@ of your Raspberry Pi hostname or IP address. The ports are default for mediamtx. ffplay rtsp://rpi-address:8554/cam ffplay rtsp://rpi-address:8554/endoscope ``` + +Or you could watch it via web browser under endpoints such as + +```text +http://rpi-address:8889/cam +http://rpi-address:8889/endoscope +``` diff --git a/ffmpeg-mjpg-stream.dist b/ffmpeg-mjpg-stream.dist new file mode 100644 index 0000000..2e5efbe --- /dev/null +++ b/ffmpeg-mjpg-stream.dist @@ -0,0 +1,6 @@ +PRINTER_ADDRESS=127.0.0.1 +PRUSA_CONNECT_CAMERA_TOKEN=token-change-me +PRUSA_CONNECT_CAMERA_FINGERPRINT=fingerprint-change-me +CAMERA_DEVICE=/dev/null +CAMERA_COMMAND=ffmpeg +CAMERA_COMMAND_EXTRA_PARAMS="-y -i 'http://beaglecam-1.local:8080/ipcam/mjpeg.cgi' -vframes 1 -q:v 1 -f image2 -update 1 " diff --git a/markdown_link_check_config.json b/markdown_link_check_config.json index db97553..8a9355b 100644 --- a/markdown_link_check_config.json +++ b/markdown_link_check_config.json @@ -1,9 +1,15 @@ { + "ignorePatterns": [ + { + "pattern": "^https://www.raspberrypi.com" + } + ], "httpHeaders": [ { "urls": [ "https://docs.github.com/", - "https://www.raspberrypi.com" + "https://www.raspberrypi.com", + "https://www.raspberrypi.com/products/camera-module-v2/" ], "headers": { "Accept-Encoding": "br, gzip, deflate" diff --git a/mkdocs.yml b/mkdocs.yml index fbfad4c..31fe428 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -51,19 +51,24 @@ nav: - Camera configs: - General overview: config.for.camera.md - - CSI: config.for.camera.csi.libcamera.md + - CSI (legacy): config.for.camera.csi.legacy.md + - CSI: config.for.camera.csi.libcamera.md - ESPHome Snapshot: config.for.camera.esphome.snapshot.md - ESPHome Stream: config.for.camera.esphome.stream.md - - RTSP streams: config.for.camera.rtsp.md - USB: config.for.camera.usb.md + - Web Cams - Snapshot: config.for.camera.snapshot.md + - Web Cams - MJPG streams: config.for.camera.mjpg.md + - Web Cams - RTSP streams: config.for.camera.rtsp.md - Test: - Test Config: test.config.md - Service: - Systemd: service.systemd.md + - Configuration Tuning: configuration.tuning.md + - Performance: performance.md + - Advanced: - - Configuration Tuning: configuration.tuning.md - - Performance: performance.md + - Streaming cameras with mediamtx: stream.mediamtx.md diff --git a/requirements.txt b/requirements.txt index 2af32eb..ec9ae43 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,5 +4,6 @@ mkdocs-material-extensions==1.1.1 mkdocs-material==9.0.2 mkdocs-mermaid2-plugin==1.1.1 mkdocs-minify-plugin==0.6.2 +mkdocs-redirects==1.2.1 mkdocs-with-pdf==0.9.3 mkdocs==1.5.3 diff --git a/snapshot.dist b/snapshot.dist new file mode 100644 index 0000000..d50c33c --- /dev/null +++ b/snapshot.dist @@ -0,0 +1,6 @@ +PRINTER_ADDRESS=127.0.0.1 +PRUSA_CONNECT_CAMERA_TOKEN=token-change-me +PRUSA_CONNECT_CAMERA_FINGERPRINT=fingerprint-change-me +CAMERA_DEVICE=/dev/null +CAMERA_COMMAND=curl +CAMERA_COMMAND_EXTRA_PARAMS="--max-time 5 'http://another-cam.local:8081/snap.jpg' -o "