blob: 99c02aa807c22d5b9cc09336e720918d299ddc75 [file] [log] [blame] [view]
# Matter Camera Controller Example
This example application demonstrates the CHIP Camera Controller running on a
Linux platform and explains how to build and run the Camera Controller Example
on Linux.
In a typical setup, the Camera Controller app manages a CameraDevice app running
on a Raspberry Pi. The CameraDevice captures and encodes the video feed before
streaming it through a WebRTC track, while the CameraController receives this
video stream and displays it, creating a complete end-to-end camera solution.
---
- [Building the Example Application](#building-the-example-application)
---
## Overview
The example consists of two primary applications:
Camera App (chip-camera-app): This application functions as the Matter
accessory. It captures and encodes a video feed, making it available for
streaming over a WebRTC connection. It is typically run on a device with a
camera, such as a Raspberry Pi.
Camera Controller (chip-camera-controller): This application acts as the client.
It commissions the Camera App onto the Matter network, discovers it, and
receives and displays the video stream.
## Building the Example Application
### 1. Prerequisites
Before building, you must install the necessary GStreamer libraries and
development packages, which are used for video processing and streaming.
```
sudo apt update
sudo apt install \
gstreamer1.0-plugins-base \
gstreamer1.0-plugins-good \
gstreamer1.0-plugins-bad \
gstreamer1.0-libav \
libgstreamer1.0-dev \
libgstreamer-plugins-base1.0-dev
```
### 2. Building the Applications
1. Initialize the Build Environment This command configures your shell with the
necessary build tools. You only need to run this once per terminal session.
```
source scripts/activate.sh
```
2. Build the Camera App (Device)
Follow the build instructions from examples/camera-app/linux/README.md
3. Build the Camera Controller (Client)
You can either build the applications for a local Linux machine or cross-compile
them for a Raspberry Pi.
Option A: Build for a Local Linux (x86_64)
This is the simplest method for testing the camera pipeline on a single Linux
computer.
```
# Navigate to the examples directory
cd examples/camera-controller/
# Compile the Linux x86‑64 camera‑controller target
./scripts/build/build_examples.py \
--target linux-x64-camera-controller \
build
```
The resulting executable is placed in:
```
out/linux-x64-camera-controller/chip-camera-controller.
```
Option B: Cross-Compile for Raspberry Pi (arm64)
To run an application on a Raspberry Pi, you must cross-compile it from an
x86_64 host machine. The recommended method is to use the provided Docker build
environment to ensure all dependencies are correct.
1. Pull the Cross-Compilation Docker Image
```
docker pull ghcr.io/project-chip/chip-build-crosscompile:167
```
2. Run the Docker Container This command starts an interactive shell inside the
container and mounts your local connectedhomeip repository into the
container's /var/connectedhomeip directory.
```
docker run -it -v ~/connectedhomeip:/var/connectedhomeip ghcr.io/project-chip/chip-build-crosscompile:167 /bin/bash
```
3. Build Inside the Container From within the Docker container's shell, execute
the build script.
```
cd /var/connectedhomeip
# Required to fix git repository ownership issues inside Docker
git config --global --add safe.directory /var/connectedhomeip
git config --global --add safe.directory /var/connectedhomeip/third_party/pigweed/repo
# Run the build script for the Raspberry Pi (arm64) target
./scripts/run_in_build_env.sh \
"./scripts/build/build_examples.py \
--target linux-arm64-camera-controller-clang \
build"
```
4. Transfer the Binary to the Raspberry Pi After the build completes, exit the
Docker container. The compiled binary will be available on your host machine
in the out/ directory. Use scp to copy it to your Raspberry Pi.
```
# The binary path on your host machine
# out/linux-arm64-camera-controller-clang/chip-camera-controller
# SCP command to transfer the file
scp ./out/linux-arm64-camera-controller-clang/chip-camera-controller ubuntu@<RASPBERRY_PI_IP_ADDRESS>:/home/ubuntu
```
### 3. Running the Live View Demo
After building the applications using Option A, you can run the full end-to-end
example on your Linux machine. You will need two separate terminal windows.
Terminal 1: Start the Camera App (Device)
1. Launch the chip-camera-app binary.
Clean up any existing configurations (first-time pairing only):
```
sudo rm -rf /tmp/chip_*
```
#### Video Format (`YUYV` Only)
This demo supports only the uncompressed `YUYV` pixel format for capture.
Identify the correct video device first (examples: `video0`, `video1`). You can
list devices and verify the format support with:
```
v4l2-ctl --list-devices
v4l2-ctl -d /dev/video0 --list-formats-ext | grep -A4 YUYV || true
```
Launch the camera app explicitly selecting the device (replace `video0` if
needed):
```
./out/linux-x64-camera/chip-camera-app --camera-video-device video0
```
Terminal 2: Launch and Use the Camera Controller (Client)
1. Launch the Controller Start the interactive controller shell.
```
./out/linux-x64-camera-controller/chip-camera-controller
```
2. Commission the Device At the controller's > prompt, use the pairing command
to securely commission the Camera App onto the Matter network.
onnetwork: Specifies pairing over the local IP network.
```
pairing onnetwork 1 20202021
```
Wait for the command to complete and confirm that commissioning was successful.
3. To start a live video stream from your camera, use the `liveview start`
command followed by the nodeID you set during pairing. For example, if your
nodeID is 1, you can request a stream with a minimum resolution of 640x480
pixels and a minimum frame rate of 30 frames per second using the command
below.
```
liveview start 1 --min-res-width 640 --min-res-height 480 --min-framerate 30
```
To see what video formats and resolutions your camera supports, first list the
available video devices, then check the formats for your specific device:
```
# List all available video devices
v4l2-ctl --list-devices
# Check formats for a specific device (replace /dev/video0 with your device)
v4l2-ctl -d /dev/video0 --list-formats-ext
```
Wave your hand in front of the camera to trigger live view; a video window will
appear, confirming that the stream is active.
### 4. Running the Video Recording Upload Demo
The Push AV Server acts as the recording destination (like a cloud service) for
video clips. The demo shows how a Matter Camera Controller tells a Matter Camera
to record a clip and upload it to that server.
The server itself doesn't control the camera; it's a passive service that
securely receives and stores media. The relationship is established by the
controller.
#### The Server's Role: The Recording Destination
The Push AV Server runs in the background, waiting for authenticated devices to
push video content to it. The key piece of information it provides is its ingest
URL, which, for example, looks like this: `https://localhost:1234/streams/1`
Think of this server as a secure, private YouTube or Dropbox, but just for your
camera's video clips.
Here is the command to set up a local Push AV Server, using a virtual
environment. (recommended)
```
# Create a virtual environment
python3 -m venv pavs_env
# Activate it
source pavs_env/bin/activate
# Install dependencies
pip install uvicorn fastapi jinja2 cryptography zeroconf pydantic
# Run the server
python server.py --working-directory ~/.pavstest
```
#### The Controller's Role: The Orchestrator
The `chip-camera-controller` acts as the "brain" of the operation. It's what you
use to configure the system. It tells the camera where to send its recordings.
This happens in this specific command:
- Build & run camera application
```
./scripts/examples/gn_build_example.sh examples/camera-app/linux out/debug
./out/debug/chip-camera-app
```
- Build & run `chip-camera-controller` steps for clip recording & uploading
```
./scripts/build/build_examples.py --target linux-x64-camera-controller build
./out/linux-x64-camera-controller/chip-camera-controller
```
- Pair Camera
```
pairing code 1 34970112332
```
- Video Stream Allocation
```
cameraavstreammanagement video-stream-allocate 3 0 30 30 '{ "width":640, "height":480}' '{ "width":640, "height":480}' 10000 10000 1 10 1 1 --WatermarkEnabled 1 --OSDEnabled 1
```
- Audio Stream Allocation
```
cameraavstreammanagement audio-stream-allocate 3 0 2 48000 96000 16 1 1
```
- Push AV Transport allocation
```
pushavstreamtransport allocate-push-transport '{"streamUsage":0, "videoStreamID":1, "audioStreamID":2, "endpointID":1, "url":"https://localhost:1234/streams/1", "triggerOptions":{"triggerType":0, "maxPreRollLen":1, "motionTimeControl":{"initialDuration":20, "augmentationDuration":5,"maxDuration":40, "blindDuration":5}}, "ingestMethod":0, "containerOptions":{"containerType":0, "CMAFContainerOptions": {"chunkDuration": 4, "CMAFInterface": 0, "segmentDuration": 6, "sessionGroup": 1, "trackName": "main"}}}' 1 1
```
Here, the controller is sending the server's URL to the camera. It's essentially
saying, "When I tell you to record a clip, this is the address you need to send
it to."
#### The Camera's Role: The Content Producer
The `chip-camera-app` is the device that does the actual work of recording and
sending the video. After it receives the configuration from the controller, it
waits for a trigger.
This command from the controller is the trigger:
```
pushavstreamtransport manually-trigger-transport 1 0 1 1
```
This command means, "Start recording now and upload the clip to the URL I gave
you earlier." The camera then connects to the push_av_server at
`https://localhost:1234/streams/1` and pushes the video clip.