๐Ÿฆ BirdWatchAI Manual Part 2 ยท Camera Hardware Community Feed
Part 2

Camera Hardware

Everything about the camera end of the system โ€” what works, how to wire it up, and where to point it. Most installs use an off-the-shelf RTSP camera (TP-Link Tapo is the most popular). The server edition also supports a wired Raspberry Pi Camera Module on the CSI ribbon cable.

RTSP cameras

RTSP (Real-Time Streaming Protocol) is a standard way for cameras to send live video over a network. BirdWatchAI connects to your camera with an RTSP address that looks like this:

rtsp://username:password@camera_ip:port/stream_path

For example: rtsp://birduser:secret123@192.168.1.105/stream2. The pieces are:

Common stream paths by brand:

BrandStream pathNotes
TP-Link Tapo/stream2 (recommended) ยท /stream1Use /stream2 on every model โ€” see the Tapo section below
Wyze (RTSP firmware)/liveRequires custom RTSP firmware flashed
Amcrest / Dahua/cam/realmonitor?channel=1&subtype=0
Reolink/h264Preview_01_main
Hikvision/Streaming/Channels/101
Test in VLC first If you have VLC Media Player, you can verify an RTSP URL works before using it here: Media โ†’ Open Network Stream (Ctrl+N), paste the URL, and click Play. If VLC shows live video, BirdWatchAI will connect too.

TP-Link Tapo step-by-step

Tapo cameras (C100/C110/C113/C120/C200/C210/C310/C320WS/C500/C510W/C520WS, etc.) are popular, affordable, and well supported. The most important thing to understand is the Camera Account.

The Camera Account is separate from your Tapo login RTSP requires a dedicated Camera Account that you create inside the Tapo app. This is not the same as your TP-Link / Tapo cloud login. Use a different username and password for it.

Create the Camera Account (for RTSP)

  1. Open the Tapo app and tap your camera to open Live View.
  2. Tap the โš™ gear (top right) โ†’ Advanced Settings โ†’ Camera Account.
  3. Tap Understand and Agree to Use.
  4. Set a username (6โ€“32 characters) and password (6โ€“32 characters), then Save. Use these in BirdWatchAI's RTSP fields.

Find the camera's IP address

Tapo app โ†’ โš™ gear โ†’ Device Info โ†’ IP Address (e.g. 192.168.1.105). Alternatively, check your router's connected-devices list for a name like TAPO_C120_XXXX.

Streams & quality โ€” which stream path to use

Tapo cameras expose two RTSP streams:

Use /stream2 on every Tapo model. The sub-stream is 720p on the C113 and comparable models โ€” reliable, easy on the camera's Wi-Fi uplink, and plenty of detail for the AI to identify birds. It's also the stream BirdWatchAI uses for software motion detection.

Avoid the 2K main stream The main stream (/stream1) is heavier, and at 2K it saturates the camera's Wi-Fi uplink and causes H.264 corruption and instability. If you have a specific reason to use /stream1, drop the camera to 1080p first in Tapo app โ†’ Camera Settings โ†’ Video Quality.
FAQ

Q: Which Tapo stream should I use?
Use /stream2 on every model โ€” it's 720p, reliable, and easy on the camera's Wi-Fi. Avoid /stream1 (especially at 2K), which can corrupt the feed.

Quick reference

SettingValue
RTSP Port554
ONVIF Port (motion events)2020
Camera account username / password6โ€“32 characters each
Stream limits Tapo cameras allow only a limited number of simultaneous RTSP streams. If you also run TAPO Care cloud recording, microSD recording, and an NVR at the same time, RTSP may stop working โ€” disable one of them if you have connection trouble.

Optional: remote camera reboot (desktop only)

The desktop app can power-cycle a frozen Tapo camera automatically (or on demand via the tray menu's ๐Ÿ”„ Restart Camera). This feature needs your TP-Link cloud account email and password, entered in Settings โ†’ Camera (RTSP) โ†’ TAPO Camera Reboot. These are your cloud-login credentials, distinct from the RTSP camera account.

Reserving the camera's IP in your router

Strongly recommended for every camera By default, your router hands out IP addresses dynamically (via DHCP), which means your camera's address can change after a power outage, a reboot, or simply over time. If the camera's IP changes, BirdWatchAI will no longer find it at the old address and the connection will fail until you update the IP by hand. A DHCP reservation tells the router to always give this particular camera the same IP address.

Every router brand has a slightly different menu, but the concept is identical everywhere:

  1. Open your router's admin page in a web browser (commonly 192.168.1.1 or 192.168.0.1 โ€” check the label on your router) and sign in.
  2. Find the DHCP settings. Depending on the brand this lives under a menu such as LAN, Network, DHCP Server, Address Reservation, or Connected Devices / Client List.
  3. Locate your camera in the list of connected devices (look for a name like TAPO_C120_XXXX, or match it by its MAC address โ€” a unique hardware ID printed on the camera and shown in the camera app under Device Info).
  4. Choose Reserve / Bind / Add Static Lease for that device, and either keep its current IP or assign one you'll remember.
  5. Save / apply. Then reboot the camera (or wait for its lease to renew) so it picks up the reserved address.
  6. Use that same reserved IP in BirdWatchAI's Camera IP Address field.
Where to find the exact steps for your router Search the web for "[your router brand/model] DHCP reservation" (for example, "Netgear Nighthawk address reservation" or "TP-Link bind IP to MAC"). The terminology differs by brand, but you're always doing the same thing: tying the camera's MAC address to a fixed IP. If you can't reserve in the router, an alternative is to set a static IP directly in the camera's own settings โ€” just make sure it's outside the router's automatic DHCP range to avoid conflicts.

Other camera brands

Any RTSP camera works. General tips:

Raspberry Pi camera (CSI ribbon, server only)

The server edition supports a wired Arducam / Raspberry Pi Camera Module attached over the CSI ribbon cable, as an alternative to RTSP. Capture goes through libcamera (the modern Pi camera stack), not legacy v4l2 โ€” so the container needs broader access to the Pi's hardware than a USB webcam would.

One-time setup

  1. Plug the ribbon cable in with the Pi powered off. Lift the CSI port's clip, slide the ribbon in (contacts facing the HDMI side of the board), press the clip back down.
  2. Enable the camera interface on the Pi. On Pi OS Bookworm, sudo raspi-config โ†’ Interface Options โ†’ Camera โ†’ Yes โ†’ Finish โ†’ reboot. (No-op on most fresh installs: libcamera + v4l2 compat are enabled by default.)
  3. Verify the OS sees it. SSH in and run libcamera-hello --list-cameras โ€” you should see at least one camera listed (e.g. imx519 for an Arducam motorized-lens module, imx708 for the Camera Module 3, ov5647 for the original v1 module). If "No cameras available!", go back to the ribbon-cable seat โ€” that's the most common cause.
  4. Edit ~/birdwatch/docker-compose.yml to grant camera access. The file ships with a single commented-out line under the "Pi camera support" block: # privileged: true. Uncomment it (delete the leading # , keep the indentation matching the lines above it like restart: and ports:). That's the entire compose change.
  5. Recreate the container so the new mode takes effect:
    cd ~/birdwatch
    docker compose up -d --force-recreate birdwatch
  6. Switch the camera type in the dashboard. Open http://<your-host>:8080 โ†’ Settings โ†’ Camera โ†’ set Camera type to Pi camera โ†’ leave the device path at 0 (libcamera's camera index; the field also accepts /dev/video0 for compatibility) โ†’ click Test camera. A frame should come back within a few seconds. Save.
Why privileged mode and not selective device passthrough? libcamera reads the host's device tree at /proc/device-tree/model to confirm "this is a Raspberry Pi" before it'll initialize the camera stack. Docker mounts its own procfs over /proc after applying bind mounts, so a - /proc/device-tree:/proc/device-tree:ro mount gets shadowed and the platform check fails ("No cameras available!" inside the container even though all the video / media nodes are wired through). Granular device passthrough was the original approach and works on Bullseye but not Bookworm. Privileged mode grants the container the host's full device + sysfs view in one line โ€” the standard pattern for libcamera in Docker.

If Test camera errors out

The most useful diagnostic is, from the host shell:

docker exec birdwatch rpicam-hello --list-cameras

Run inside the container โ€” if it lists your sensor, the access path works and the issue is on the app side. If it says "No cameras available!" inside the container but works on the host, you likely missed step 4 (the privileged: true uncomment). Confirm with:

docker inspect birdwatch --format '{{.HostConfig.Privileged}}'

It should print true.

The existing motion + identify pipeline runs on the Pi camera feed the same as on RTSP โ€” frame-diff motion detection is the default trigger (Settings โ†’ Detection โ†’ Motion detection threshold). ONVIF doesn't apply to wired cameras.

Placement & lighting

The single biggest accuracy improvement you can make isn't a setting โ€” it's a better view of the bird.

Low light hurts identification Dim conditions โ€” early morning, dusk, heavy overcast, or a shaded feeder โ€” are a leading cause of wrong species and low confidence: grainy, low-contrast, or motion-blurred frames simply give the AI less to work with. Favor a spot with even natural daylight, keep the sun behind the camera rather than in front of it, and if your feeder is busy before sunrise or after sunset consider a camera with strong low-light / color-night performance. Raising the confidence threshold also helps by holding back marginal dim-light guesses.
The recommended camera For most installs the TP-Link Tapo C113 is the best bang for the buck (~$30 at the time of writing) โ€” 720p, great color, weather- resistant variants available, and the default /stream2 just works.

Optional: a macro lens

A clip-on macro (close-up) lens fits over the camera's own lens and shortens its focus distance. Two things change, and both help:

The trade-off is depth of field: with the lens fitted, only a narrow band of distance is sharp, so the camera has to sit toward the close end of the 3โ€“10 foot range and the feeder has to stay put. Check the live preview after fitting it and nudge the camera until the perch is crisp โ€” if the whole frame looks soft, you are too far away.

Where to get one A macro lens matched to the recommended camera is sold on the BirdWatchAI site. Any clip-on close-up lens that fits the camera body will do the same job.