Skip to content

Repository files navigation

IR Camera Controller icon

Raspberry Pi 5 IMX708 NoIR Camera Controller

English | 简体中文

A hardware-validated camera system that turns a Raspberry Pi 5 and an IMX708 NoIR autofocus camera into a secure LAN or offline wireless camera, controlled from a native macOS application.

The Raspberry Pi runs a loopback-only FastAPI/Picamera2 service. The macOS client reaches it through an SSH tunnel, provides a live MJPEG preview, and controls exposure, focus, digital zoom, still capture, and recording without exposing the camera API directly to the network.

Project status: working prototype validated on real Raspberry Pi 5 and IMX708 NoIR hardware. The Objective-C/AppKit client is the primary macOS app; the SwiftUI implementation is retained as an optional reference.

Highlights

  • Native macOS AppKit client that builds with Command Line Tools; no recent full Xcode installation is required.
  • SSH-tunneled API: the Pi service listens on 127.0.0.1:8765 by default.
  • 1280×720 MJPEG live preview and live camera metadata.
  • 4608×2592 JPEG still capture.
  • 1920×1080, 30 fps H.264/MP4 recording on the Pi.
  • Continuous, single-shot, and manual autofocus controls.
  • Live manual exposure and Camera Module 3 lens-position sliders.
  • 1×–4× center-crop digital zoom for preview, photos, and recordings.
  • Keychain storage for optional API tokens.
  • Offline 5 GHz fallback hotspot support for field use without a router.
  • Fake-camera backend and automated API tests for development without hardware.

Architecture

IR Camera Controller.app
        │
        ├── SSH: local 127.0.0.1:18765 → Pi 127.0.0.1:8765
        │
        └── HTTP API / MJPEG stream
                    │
             FastAPI + Picamera2
                    │
            Raspberry Pi 5 + IMX708 NoIR

The Pi owns the camera lifecycle as a single systemd service. Network loss does not interrupt an active Pi-side recording; finalized files can be downloaded after reconnecting.

Requirements

Raspberry Pi

  • Raspberry Pi 5
  • IMX708 autofocus NoIR camera (for example, Raspberry Pi Camera Module 3 NoIR)
  • Raspberry Pi OS Lite 64-bit with SSH enabled
  • Reliable Pi 5 power supply and active or adequate passive cooling
  • microSD card with at least 16 GB; more capacity is recommended for recordings

The tested device uses Raspberry Pi OS Lite 64-bit (Debian 13 Trixie), a 128 GB card, and an IMX708 sensor at 4608×2592.

Mac

  • macOS 12 or later
  • Command Line Tools (xcode-select --install) to rebuild the AppKit client
  • An SSH private key authorized for the Raspberry Pi account

Quick start

1. Prepare the Pi

Use Raspberry Pi Imager to install Raspberry Pi OS Lite 64-bit. In Imager's advanced settings, configure a hostname, create a user, enable SSH, and add the Mac's public SSH key.

Deploy the service from the repository root:

export PI_HOST=ir-camera.local
export PI_USER=<pi-user>

rsync -az pi/ "${PI_USER}@${PI_HOST}:/tmp/ir-camera-deploy/"
ssh "${PI_USER}@${PI_HOST}" 'sudo /tmp/ir-camera-deploy/install.sh'

Verify the service:

ssh "${PI_USER}@${PI_HOST}" 'systemctl status ir-camera --no-pager'

2. Build the macOS app

./macos-objc/build_app.sh

Build products are created locally under macos-objc/dist/ and are excluded from Git. Publish signed release binaries through GitHub Releases rather than committing the .app bundle.

3. Connect

Open IR Camera Controller.app and enter:

  • Host: ir-camera.local
  • SSH user: the user created in Raspberry Pi Imager
  • SSH key: for example ~/.ssh/id_ed25519
  • API token: leave empty while the service remains loopback-only

Select Connect, then Start Live.

Offline wireless mode

For use without a router, configure the Pi's built-in Wi-Fi as a low-priority fallback access point. Run this over Ethernet because activating it changes the Wi-Fi interface mode:

ssh "${PI_USER}@${PI_HOST}"
cd /tmp/ir-camera-deploy
sudo ./setup_offline_hotspot.sh

The script securely prompts for a WPA2 password and creates:

  • SSID: IR-Camera-Direct by default
  • Pi address: 10.42.0.1
  • 5 GHz AP on channel 36
  • autoconnect priority -100

Normal saved Wi-Fi profiles with a higher priority remain preferred. When no known network is available, connect the Mac to IR-Camera-Direct, then use ir-camera.local or 10.42.0.1 in the app. The password is never stored in this repository.

API access without the app

Create a tunnel:

ssh -N -L 18765:127.0.0.1:8765 "${PI_USER}@${PI_HOST}"

Then, in another terminal:

curl http://127.0.0.1:18765/health

OpenAPI documentation is available at http://127.0.0.1:18765/docs while the tunnel is active. See the API contract for endpoint details.

Security model

  • The camera API binds to loopback by default and is not directly reachable from the LAN or hotspot.
  • The Mac accesses the API only through an authenticated SSH tunnel.
  • Binding the API to a non-loopback address requires a bearer token.
  • Optional API tokens are stored in macOS Keychain.
  • SSH private keys, Wi-Fi passwords, API tokens, and media are excluded from Git.
  • Media uses opaque IDs; API clients cannot provide arbitrary filesystem paths.

Validation

The real-hardware acceptance run covers autofocus, manual controls, full-size JPEG capture, MJPEG streaming, 1080p30 recording, SSH tunneling, media cleanup, service recovery, offline hotspot startup, and a 108-second recording stress test. See the acceptance checklist and hardware validation notes.

Run the hardware-independent API tests with:

PYTHONPATH=pi/app python3 -m pytest -q pi/tests

Repository layout

├── pi/                 FastAPI/Picamera2 service, systemd unit, tests and tools
├── macos-objc/         Primary native AppKit client and build script
├── macos/              Optional SwiftUI/Xcode implementation
├── hardware/           OpenPiCase modification, printable STL and Blender tools
├── docs/               Architecture, setup, API, troubleshooting and acceptance
└── artifacts/          Selected real-hardware validation outputs

Generated apps, caches, Blender backups, third-party reference CAD files, and large validation videos are intentionally ignored. Use GitHub Releases or Git LFS if those binaries need to be distributed.

Documentation

License

The project source is released under the MIT License. Third-party reference CAD assets are excluded from the repository and remain subject to their respective owners' terms.

About

Secure Raspberry Pi 5 IMX708 NoIR camera controller with a native macOS client

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages