# IPCam Orange Pi Dashboard — INSTALL Tài liệu này hướng dẫn triển khai trên Orange Pi (Linux). Mục tiêu: MediaMTX chạy như media server, FastAPI chạy như dashboard backend, React build ra static. ## 0) Mô hình triển khai ### A) 1 thiết bị (đơn giản nhất) - MediaMTX + Dashboard backend + Dashboard frontend chạy cùng máy ### B) 2 thiết bị (cùng LAN / cùng lớp mạng) - Máy A: chạy MediaMTX + lưu recordings - Máy B: chạy Dashboard backend + frontend - Máy B sẽ gọi: - MediaMTX API của máy A (port 9997) để add/remove camera + bật/tắt recording - WebRTC/WHEP của máy A (port 8889 + UDP 8189) để xem live - Playback: máy B cần đọc được recordings của máy A (khuyến nghị mount NFS/SMB) ## 1) Yêu cầu - Orange Pi chạy Debian/Ubuntu - MediaMTX đã cài và chạy được - Python 3.9+ (khuyến nghị 3.10+) - Node.js 20+ (để build frontend) ## 2) MediaMTX cấu hình tối thiểu Trong file `mediamtx.yml`: ```yaml api: yes apiAddress: :9997 webrtc: yes webrtcAddress: :8889 webrtcAllowOrigin: '*' record: yes recordFormat: fmp4 recordPath: /recordings/%path/%Y-%m-%d_%H-%M-%S-%f recordPartDuration: 5m ``` Nếu chạy mô hình 2 thiết bị, đảm bảo MediaMTX trả về đúng IP LAN để client kết nối ICE: ```yaml webrtcAdditionalHosts: - 192.168.88.10 ``` ### 2.1) Nếu MediaMTX API bị 401 Unauthorized 401 nghĩa là request thiếu thông tin xác thực hợp lệ. Khi bật auth trong MediaMTX, bạn cần tạo user có quyền `api` và cấu hình backend dashboard gửi Basic Auth. Ví dụ trong `mediamtx.yml`: ```yaml authMethod: internal authInternalUsers: - user: dashboard pass: dashboard_password ips: ['127.0.0.1', '::1', '192.168.88.0/24'] permissions: - action: api ``` Sau đó set trong file `.env` của dashboard backend: ``` MEDIAMTX_API_USER=dashboard MEDIAMTX_API_PASS=dashboard_password ``` Trong `paths`, bạn có thể để dashboard tự thêm path bằng API (Settings → Add Camera). Tạo thư mục recordings: ```bash sudo mkdir -p /recordings sudo chown -R $USER:$USER /recordings ``` Mở firewall/cổng (tuỳ hệ thống): - `8554/tcp` RTSP - `8889/tcp` WebRTC HTTP - `9997/tcp` MediaMTX Control API - `8189/udp` ICE ## 2.1) Playback khi tách 2 thiết bị (mount recordings) Vì MediaMTX ghi file recordings trên máy A, nên Dashboard (máy B) cần truy cập được folder này để: - list file `/api/recordings` - serve file `/videos/...` Khuyến nghị dùng NFS (Linux-Linux): Máy A: ```bash sudo apt-get update sudo apt-get install -y nfs-kernel-server echo "/recordings 192.168.88.0/24(rw,sync,no_subtree_check)" | sudo tee -a /etc/exports sudo exportfs -ra ``` Máy B: ```bash sudo apt-get update sudo apt-get install -y nfs-common sudo mkdir -p /recordings sudo mount -t nfs 192.168.88.10:/recordings /recordings ``` ## 3) Backend FastAPI ### 3.1 Cài dependencies ```bash cd IPCam_OrangePi_Dashboard python3 -m venv api/.venv source api/.venv/bin/activate pip install -r api/requirements.txt ``` ### 3.2 Cấu hình Tạo file `.env`: ```bash cp .env.example .env ``` Backend sẽ tự load `.env` khi start. Chạy backend lần đầu sẽ tự tạo `api/data/config.json` (lưu danh sách camera + schedule). Bạn có thể chỉnh: - `mediamtx_api_url` (mặc định `http://127.0.0.1:9997`) - `mediamtx_webrtc_url` (mặc định `http://127.0.0.1:8889`) - `recordings_dir` (mặc định `/recordings`) Nếu chạy mô hình 2 thiết bị, set theo IP máy A (MediaMTX), ví dụ: ```json { "mediamtx_api_url": "http://192.168.88.10:9997", "mediamtx_webrtc_url": "http://192.168.88.10:8889", "recordings_dir": "/recordings", "cameras": [], "schedule": { "enabled": true, "weekdays_from": "18:00", "weekdays_to": "08:00", "weekend_all_day": true } } ``` Hoặc set ENV trước lần chạy đầu tiên để tạo config mặc định: ```bash export MEDIAMTX_API_URL="http://192.168.88.10:9997" export MEDIAMTX_WEBRTC_URL="http://192.168.88.10:8889" export RECORDINGS_DIR="/recordings" ``` Nếu MediaMTX API có auth, set trong `.env`: - `MEDIAMTX_API_USER` - `MEDIAMTX_API_PASS` ### 3.3 Chạy backend ```bash source api/.venv/bin/activate python3 api/run.py ``` ## 4) Frontend (build static) ### 4.1 Build ```bash cd IPCam_OrangePi_Dashboard npm install npm run build ``` Output nằm ở `dist/`. ### 4.2 Serve frontend Có 2 cách phổ biến: 1) Nginx serve `dist/` và reverse proxy `/api` + `/videos` về backend `:8008` 2) Dùng Caddy tương tự Ví dụ Nginx server block tối thiểu: ```nginx server { listen 80; server_name _; root /opt/ipcam-dashboard/dist; index index.html; location / { try_files $uri $uri/ /index.html; } location /api/ { proxy_pass http://127.0.0.1:8008; } location /videos/ { proxy_pass http://127.0.0.1:8008; } } ``` Nếu chạy mô hình 2 thiết bị, phần Nginx ở máy B không cần proxy tới MediaMTX. Frontend sẽ gọi trực tiếp `mediamtx_webrtc_url` (máy A). ## 5) Systemd service (khuyến nghị) ### 5.1 Backend service Tạo file `/etc/systemd/system/ipcam-dashboard.service`: ```ini [Unit] Description=IPCam Dashboard Backend After=network.target [Service] WorkingDirectory=/opt/ipcam-dashboard EnvironmentFile=/opt/ipcam-dashboard/.env ExecStart=/opt/ipcam-dashboard/api/.venv/bin/python /opt/ipcam-dashboard/api/run.py Restart=always RestartSec=2 [Install] WantedBy=multi-user.target ``` Enable: ```bash sudo systemctl daemon-reload sudo systemctl enable --now ipcam-dashboard sudo systemctl status ipcam-dashboard ``` ## 6) Kiểm tra nhanh - Backend: `curl http://localhost:8008/api/health` - MediaMTX API: `curl http://localhost:9997/v3/paths/list` - Frontend: mở `http:///`