How to use your Raspberry Pi Camera in Apple Homekit with Scrypted (Bookworm, Trixie)

Hardware needed
- Raspberry Pi Model A or B, gen 2, 3, 4 or 5
- Raspberry Pi OS 11 Bullseye (libcamera) or newer. (Tested on Bookworm and Trixie)
- SD Card with capacity of 4GB or higher
- Raspberry Pi compatible camera with flatband cable
- Raspberry Pi Camera Module v1, v2 or v3
or
- Raspberry Pi HQ Camera
or
- ArduCam 16MP Autofocus
- Raspberry Pi Enclosure
- Poolside Factory Camera Mount
- Tilt-Adjustable Mount for Camera Module v1/v2/PiNoir
or
- Universal Tilt-Adjustable Mount for v1/v2/PiNoir/ArduCam 16MP Autofocus or HQ camera
Note: For the Raspberry Pi OS 11 (Bullseye) or earlier, you can also follow this earlier tutorial that was based on Homebridge and the ffmpeg plugin.:
Instructions
If you already have an SD card with a working Raspberry Pi image, you can use that one, otherwise you can follow these steps to create a fresh one without needing a screen or keyboard for your Raspberry Pi.
Log in to your Raspberry Pi.
If you are using an official Raspberry Pi camera, you can skip this paragraph:
For an Arducam 16MP with Autofocus, if you don't care about autofocus, it's sufficient to add dtoverlay=imx519,vcm=off under the [all] section in /boot/firmware/config.txt and reboot. For getting autofocus to work, you'll have to install the Arducam camera drivers and libcamera apps by following these instructions.
Find the latest mediamtx release on this page and adjust the version in the url below accordingly on the second and third line of this big block, then run (will take several minuts)
sudo apt install -y ffmpeg wget curl libcamera-apps-lite vim
wget https://github.com/bluenviron/mediamtx/releases/download/v1.15.3/mediamtx_v1.15.3_linux_arm64.tar.gz
tar -xzf mediamtx_v1.15.3_linux_arm64.tar.gz
sudo mkdir -p /opt/mediamtx
sudo mv mediamtx mediamtx.yml /opt/mediamtx/
sudo chmod +x /opt/mediamtx/mediamtx
cat << EOF | sudo tee /opt/mediamtx/mediamtx.yml
# Global settings
rtspAddress: :8554
# rtpAddress: :8000
webrtcAddress: :8889
rtspTransports: [tcp, multicast, udp]
paths:
cam:
# source: publisher/rpi
runOnInit: ""
runOnInitRestart: yes
all_others:
# readTimeout: 10s
EOF
cat << EOF | sudo tee /opt/mediamtx/stream.sh
#!/bin/bash
# Stream RPi Camera Module 3 via TCP to MediaMTX
exec > >(tee -a /var/log/stream.log) 2>&1 # Log to file
rpicam-vid \
--width 1920 --height 1080 \
--framerate 15 \
--bitrate 1000000 \
--inline \
--flush \
--listen \
-t 0 \
--codec h264 \
-o tcp://0.0.0.0:8000 & \
sleep 2 # Wait for rpicam-vid to start TCP server
ffmpeg \
-re \
-fflags +genpts+discardcorrupt \
-flags low_delay \
-avioflags direct \
-i tcp://127.0.0.1:8000 \
-c:v copy \
-f rtsp \
rtsp://localhost:8554/cam
EOF
sudo chmod +x /opt/mediamtx/stream.sh
cat << EOF | sudo tee /etc/systemd/system/mediamtx.service
[Unit]
Description=MediaMTX RTSP Server
Wants=network-online.target
After=network-online.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/mediamtx
ExecStart=/opt/mediamtx/mediamtx /opt/mediamtx/mediamtx.yml
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
cat << EOF | sudo tee /etc/systemd/system/rpi-stream.service
[Unit]
Description=RPi Camera Stream to MediaMTX
Wants=network-online.target mediamtx.service
After=network-online.target mediamtx.service
[Service]
Type=simple
User=root
ExecStart=/opt/mediamtx/stream.sh
ExecStop=/bin/kill -TERM \$MAINPID
ExecStopPost=/usr/bin/pkill -f rpicam-vid
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable mediamtx
sudo systemctl start mediamtx
sudo systemctl enable rpi-stream
sudo systemctl start rpi-stream
# Install Scrypted
curl -s https://raw.githubusercontent.com/koush/scrypted/main/install/docker/install-scrypted-docker-compose.sh > ~/install-scrypted-docker-compose.sh
sudo SERVICE_USER=$USER bash ~/install-scrypted-docker-compose.sh
rm ~/install-scrypted-docker-compose.sh
When your Apple device requests the video stream from your homebridge camera, the resolution that is requested depends on the device that is requesting the stream:
iPad requests are 1920 x 1080, 802kbps
iPhone requests are 1280 x 720, 15fps, 299kbps
So no matter what settings you configure in the configuration above, you can't go beyond these limits. It does make a lot of sense though to reduce the frame rate for some camera placements, which will result in the video feed being much sharper, as it doesn't need to be compressed as much.
I have had mixed result in opening the scrypted url in the browser with using hostname.local, so safer to look up the current ip address of your Raspberry Pi with
sudo ifconfig wlan0 or in color: ip addr show wlan0 and open in your browser:
https://your-ip-addr-from-above:10443/endpoint/@scrypted/core/public/#/
Your browser will likely complain, but click on Advanced and then on "proceed". Here's an example how this looks in a Chrome browser:

Create a new login on the following page:

Then click Management Console.

Then click on INSTALL PLUGIN.

Install the RTSP plugin.

Click ADD RTSP CAMERA.

Give it a name with which to identify the camera in Scrypted. Later, when adding to Homekit, you will once more be asked for a name that is then used in Homekit.

And fill in the following rtsp stream url:
rtsp://localhost:8554/cam

Then go to the plugin install page again and also install the homekit plugin:

Enable the switch for the camera you just created (very bottom of this picture).

Go back to the RTSP plugin, select the camera that you previously added, and go on the now appearing homekit tab, then pairing, then enable Standalone Accessory Mode. 
Then go to the "General" tab and scan the homekit QR code with your iPhone to add the camera to Homekit and give it its final name.

Note that if you don't enable the camera as a standalone camera, you can also scan the bridge QR code to add, and then also scan the camera QR code, and also get the camera working that way. The proposed way with standalone mode makes it so you just need to scan one QR code.
On your phone in the Home app, click the + and then 'Add Accessory' and scan the 2D barcode displayed in the browser.

Accept the homekit warning that this is an uncertified product.
Done, the Raspberry Pi camera should now be visible in your Home app.
Attach your Raspberry Pi camera module or HQ camera directly to the Raspberry Pi case using one the Poolside Factory mounts:
Tilt-Adjustable Camera Mount for Raspberry Pi Camera Modules
Universal-Tilt-Adjustable Camera Mount for all Raspberry Pi Cameras
See the output of the services we created (for debugging)
sudo systemctl status mediamtx
sudo systemctl status rpi-stream
# or
journalctl -u mediamtx -u rpi-stream
journalctl -u rpi-stream # or individually
# or
tail -f /var/log/stream.log # note, this might be too verbose to keep storing
# and see the mediamtx port
sudo netstat -tulnp | grep 8000
If you want to access the camera for other tasks than homekit from the Raspberry Pi, you need to stop the streaming service, and then restart it again for Homkeit afterwards:
sudo systemctl stop rpi-stream
# for instance, use the rpicam tools
rpicam-hello
rpicam-still --list-cameras
rpicam-still -o test.jpg
rpicam-vid -t 5000 -o test.h264
sudo systemctl start rpi-stream # re-enable
