cập nhật lại README và INSTALL

This commit is contained in:
2026-05-20 10:53:58 +07:00
parent 0491789777
commit a8dd5d0d9c
2 changed files with 261 additions and 101 deletions
+176 -73
View File
@@ -1,21 +1,73 @@
# IPCam Orange Pi Dashboard INSTALL
# 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.
Tài liệu này hướng dẫn triển khai toàn bộ hệ thống trên duy nhất một thiết bị `Orange Pi 5`.
## 0) Mô hình triển khai
Mục tiêu:
- MediaMTX + Dashboard backend + Dashboard frontend chạy cùng máy.
- `MediaMTX` chạy trên chính Orange Pi 5
- `FastAPI backend` chạy trên chính Orange Pi 5
- `Frontend React` build static và serve ngay trên chính Orange Pi 5
- File recordings lưu trên ổ cứng gắn trực tiếp vào Orange Pi 5
## 1) Yêu cầu
## 0) Cấu hình phần cứng khuyến nghị
- 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)
Bắt buộc theo kịch bản này:
## 2) MediaMTX cấu hình tối thiểu
- Thiết bị: `Orange Pi 5`
- RAM: `8GB` hoặc `16GB`
- Ổ lưu trữ: `>= 256GB`
Trong file `mediamtx.yml`:
Khuyến nghị mạnh:
- Dùng `NVMe SSD` thay vì thẻ nhớ
- Nếu ghi nhiều camera hoặc lưu lâu ngày, nên dùng `512GB` hoặc `1TB`
- Không nên để recordings trên thẻ microSD
## 1) Mô hình triển khai
Tất cả dịch vụ chạy trên cùng một máy Orange Pi 5:
```text
Orange Pi 5
|- MediaMTX
|- FastAPI backend
|- Frontend React static
`- Thu muc recordings tren SSD/NVMe
```
Không cần thêm server riêng cho MediaMTX hay dashboard.
## 2) Yêu cầu hệ điều hành và phần mềm
- Orange Pi 5 chạy Debian/Ubuntu
- Python `3.9+` khuyến nghị `3.10+`
- Node.js `20+`
- Docker + Docker Compose plugin
- Nginx hoặc Apache nếu muốn serve frontend static production
## 3) Chuẩn bị ổ lưu trữ
Ví dụ SSD được mount tại `/mnt/ssd`.
Tạo thư mục dự án và thư mục recordings:
```bash
sudo mkdir -p /mnt/ssd/IPCam_OrangePi_Dashboard
sudo mkdir -p /mnt/ssd/IPCam_OrangePi_Dashboard/mediamtx/recordings
sudo chown -R $USER:$USER /mnt/ssd/IPCam_OrangePi_Dashboard
```
Clone source:
```bash
cd /mnt/ssd
git clone <YOUR_REPOSITORY_URL> IPCam_OrangePi_Dashboard
cd /mnt/ssd/IPCam_OrangePi_Dashboard
```
## 4) MediaMTX cấu hình tối thiểu
Trong `mediamtx/mediamtx.yml` cần có tối thiểu:
```yaml
api: yes
@@ -27,116 +79,147 @@ webrtcAllowOrigin: '*'
record: yes
recordFormat: fmp4
recordPath: /recordings/%path/%Y-%m-%d_%H-%M-%S-%f
recordPath: /mnt/ssd/IPCam_OrangePi_Dashboard/mediamtx/recordings/%path/%Y-%m-%d_%H-%M-%S-%f
recordPartDuration: 5m
```
### 2.1) Nếu MediaMTX API bị 401 Unauthorized
Ghi chú:
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.
- `recordPath` nên trỏ thẳng vào SSD/NVMe
- Dashboard sẽ tự đồng bộ camera vào `mediamtx.yml`
- Dashboard cần truy cập được MediaMTX API ở `127.0.0.1:9997`
Ví dụ trong `mediamtx.yml`:
### 4.1) Nếu MediaMTX API dùng auth
Nếu MediaMTX bật auth và dashboard bị `401 Unauthorized`, thêm user có quyền `api`:
```yaml
authMethod: internal
authInternalUsers:
- user: dashboard
pass: dashboard_password
ips: ['127.0.0.1', '::1', '192.168.88.0/24']
ips: ['127.0.0.1', '::1', '192.168.1.0/24']
permissions:
- action: api
```
Sau đó set trực tiếp trong `api/data/config.json` của dashboard backend:
Sau đó khai báo trong `api/data/config.json`:
```
```json
{
"mediamtx_api_user": "dashboard",
"mediamtx_api_pass": "dashboard_password"
}
```
Trong `paths`, bạn có thể để dashboard tự thêm path bằng Settings (nhập RTSP URL). Backend sẽ cập nhật trực tiếp file `mediamtx.yml`.
## 5) Chạy MediaMTX trên Orange Pi 5
Tạo thư mục recordings:
Nếu project đã có `mediamtx/docker-compose.yml`, chạy:
```bash
sudo mkdir -p /recordings
sudo chown -R $USER:$USER /recordings
cd /mnt/ssd/IPCam_OrangePi_Dashboard
docker compose -f mediamtx/docker-compose.yml up -d
```
Mở firewall/cổng (tuỳ hệ thống):
- `8554/tcp` RTSP
- `8889/tcp` WebRTC HTTP
- `9997/tcp` MediaMTX Control API
- `8189/udp` ICE
## 3) Backend FastAPI
### 3.1 Cài dependencies
Kiểm tra:
```bash
cd IPCam_OrangePi_Dashboard
docker compose -f mediamtx/docker-compose.yml ps
curl http://127.0.0.1:9997/v3/paths/list
```
## 6) Cài backend FastAPI
### 6.1) Cài dependencies
```bash
cd /mnt/ssd/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
### 6.2) Cấu hình backend
Backend chỉ đọc cấu hình từ `api/data/config.json` (không đọc `.env`).
Chạy lần đầu sẽ tự tạo file này (lưu camera + schedule + các tham số backend).
Danh sách camera trong `config.json` sẽ được backend đồng bộ từ `mediamtx.yml`.
Các thông số kết nối MediaMTX (`mediamtx_api_url`, `mediamtx_webrtc_url`, credentials, `recordings_dir`) do user điền trong dashboard Settings hoặc chỉnh trực tiếp `config.json`.
Backend chỉ đọc cấu hình từ `api/data/config.json`.
Bạn có thể chỉnh:
File này chứa:
- `mediamtx_api_url` (mặc định `http://127.0.0.1:9997`)
- `mediamtx_webrtc_url` (mặc định `http://127.0.0.1:8889`)
- `mediamtx_api_user` / `mediamtx_api_pass` (nếu bật auth API của MediaMTX)
- `recordings_dir` (mặc định `./mediamtx/recordings` trong project)
- `api_port` (mặc định `8008`)
- thông số MediaMTX
- thư mục recordings
- danh sách camera
- lịch ghi hình
- cổng backend
Các thao tác trong Settings:
Chạy lần đầu, backend có thể tự tạo file nếu chưa có.
- Add Camera: chỉ nhập RTSP URL, backend tự tạo tên `camN` trong `mediamtx.yml`
- Delete Camera: xóa path tương ứng trong `mediamtx.yml`
- MediaMTX record: bật/tắt `pathDefaults.record` trong `mediamtx.yml`
- Restart MediaMTX Docker: gọi `docker compose -f mediamtx/docker-compose.yml restart mediamtx`
Các giá trị nên dùng trên Orange Pi 5:
### 3.3 Chạy backend
- `mediamtx_api_url`: `http://127.0.0.1:9997`
- `mediamtx_webrtc_url`: `http://127.0.0.1:8889`
- `recordings_dir`: `/mnt/ssd/IPCam_OrangePi_Dashboard/mediamtx/recordings`
- `api_port`: `8008`
Ví dụ `api/data/config.json`:
```json
{
"mediamtx_api_url": "http://127.0.0.1:9997",
"mediamtx_webrtc_url": "http://127.0.0.1:8889",
"mediamtx_api_user": null,
"mediamtx_api_pass": null,
"recordings_dir": "/mnt/ssd/IPCam_OrangePi_Dashboard/mediamtx/recordings",
"api_port": 8008,
"cameras": [],
"schedule": {
"enabled": true,
"weekdays_from": "18:00",
"weekdays_to": "08:00",
"weekend_all_day": true
}
}
```
### 6.3) Chạy backend
```bash
cd /mnt/ssd/IPCam_OrangePi_Dashboard
source api/.venv/bin/activate
python3 -m api.run
```
## 4) Frontend (build static)
### 4.1 Build
Kiểm tra:
```bash
cd IPCam_OrangePi_Dashboard
curl http://127.0.0.1:8008/api/health
```
## 7) Build frontend
```bash
cd /mnt/ssd/IPCam_OrangePi_Dashboard
npm install
npm run build
```
Output nằm ở `dist/`.
### 4.2 Serve frontend
## 8) Serve frontend production
2 cách phổ biến:
thể dùng `Nginx` hoặc `Apache`. Mục tiêu là:
1) Nginx serve `dist/` và reverse proxy `/api` + `/videos` về backend `:8008`
2) Dùng Caddy tương tự
- serve thư mục `dist/`
- reverse proxy `/api` về backend `127.0.0.1:8008`
- reverse proxy `/videos` về backend `127.0.0.1:8008`
Ví dụ Nginx server block tối thiểu:
### 8.1) Ví dụ Nginx
```nginx
server {
listen 80;
server_name _;
root /opt/ipcam-dashboard/dist;
root /mnt/ssd/IPCam_OrangePi_Dashboard/dist;
index index.html;
location / {
@@ -153,14 +236,14 @@ server {
}
```
Ví dụ Apache VirtualHost tối thiểu:
### 8.2) Ví dụ Apache
```apache
<VirtualHost *:80>
ServerName _
DocumentRoot /opt/ipcam-dashboard/dist
DocumentRoot /mnt/ssd/IPCam_OrangePi_Dashboard/dist
<Directory /opt/ipcam-dashboard/dist>
<Directory /mnt/ssd/IPCam_OrangePi_Dashboard/dist>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
@@ -180,16 +263,14 @@ Ví dụ Apache VirtualHost tối thiểu:
</VirtualHost>
```
Apache cần bật module trước khi reload:
Nếu dùng Apache:
```bash
sudo a2enmod rewrite proxy proxy_http
sudo systemctl reload apache2
```
## 5) Systemd service (khuyến nghị)
### 5.1 Backend service
## 9) Systemd service cho backend
Tạo file `/etc/systemd/system/ipcam-dashboard.service`:
@@ -199,8 +280,8 @@ Description=IPCam Dashboard Backend
After=network.target
[Service]
WorkingDirectory=/opt/ipcam-dashboard
ExecStart=/opt/ipcam-dashboard/api/.venv/bin/python /opt/ipcam-dashboard/api/run.py
WorkingDirectory=/mnt/ssd/IPCam_OrangePi_Dashboard
ExecStart=/mnt/ssd/IPCam_OrangePi_Dashboard/api/.venv/bin/python /mnt/ssd/IPCam_OrangePi_Dashboard/api/run.py
Restart=always
RestartSec=2
@@ -216,9 +297,31 @@ sudo systemctl enable --now ipcam-dashboard
sudo systemctl status ipcam-dashboard
```
## 6) Kiểm tra nhanh
## 10) Firewall/cổng cần mở
- Backend: `curl http://localhost:8008/api/health`
- MediaMTX API: `curl http://localhost:9997/v3/paths/list`
- Frontend: mở `http://<orange-pi-ip>/`
Tùy hệ thống mạng, cần cho phép:
- `8554/tcp` cho RTSP
- `8889/tcp` cho WebRTC HTTP
- `9997/tcp` cho MediaMTX API
- `8189/udp` cho ICE/WebRTC
- `80/tcp` hoặc `443/tcp` nếu serve dashboard qua web server
## 11) Kiểm tra nhanh sau triển khai
- Backend: `curl http://127.0.0.1:8008/api/health`
- MediaMTX API: `curl http://127.0.0.1:9997/v3/paths/list`
- Frontend: mở `http://<ip-orange-pi>/`
- Trong Settings:
- thêm camera bằng RTSP URL
- lưu cấu hình
- kiểm tra camera xuất hiện trong Live View
- kiểm tra file recordings được tạo trên SSD/NVMe
## 12) Ghi chú vận hành
- Nên để toàn bộ project và recordings trên cùng SSD/NVMe
- Nếu ghi nhiều camera liên tục, cần theo dõi dung lượng trống định kỳ
- Orange Pi 5 RAM `16GB` phù hợp hơn khi số camera lớn hơn hoặc cần playback đồng thời
- Khi cần ổn định cao, nên dùng nguồn tốt và tản nhiệt phù hợp cho Orange Pi 5
+83 -26
View File
@@ -1,36 +1,83 @@
# IPCam Orange Pi Dashboard
Dashboard giám sát camera IP gọn nhẹ chạy trên Orange Pi, dựa trên MediaMTX:
Dashboard giám sát camera IP chạy gọn trên duy nhất một thiết bị `Orange Pi 5`, dùng `MediaMTX` làm media server, `FastAPI` làm backend và `React` làm frontend.
- Live View (WebRTC WHEP) dạng grid, auto reconnect, lazy load
- Playback fMP4 theo camera + ngày (file list + HTML5 video)
- Settings: quản lý camera trực tiếp trong `mediamtx.yml` + lịch ghi hình
## Mô hình triển khai khuyến nghị
Toàn bộ hệ thống chạy trên cùng một máy:
- Thiết bị: `Orange Pi 5`
- RAM: `8GB` hoặc `16GB`
- Lưu trữ: `SSD/NVMe >= 256GB`
- Hệ điều hành: Debian/Ubuntu cho Orange Pi
- Thành phần chạy cùng máy:
- `MediaMTX`
- `FastAPI backend`
- `Frontend React build static`
- Thư mục recordings
Mô hình này phù hợp khi cần một hộp camera nội bộ gọn nhẹ, dễ bảo trì và không phụ thuộc thêm server khác.
## Tính năng chính
- Live View qua `WebRTC/WHEP`, dạng grid, tự reconnect, lazy load
- Playback file ghi hình `fMP4` theo camera và ngày
- Settings để:
- thêm/xóa camera trực tiếp vào `mediamtx.yml`
- bật/tắt ghi hình
- chỉnh lịch ghi hình
- cấu hình API/WebRTC URL của MediaMTX
- restart container MediaMTX
## Cấu trúc thư mục
- `src/`: frontend React
- `api/`: backend FastAPI
- `.trae/documents/`: tài liệu yêu cầu/kiến trúc
- `mediamtx/`: Dockerfile, `docker-compose.yml`, `mediamtx.yml`
- `.trae/documents/`: tài liệu yêu cầu và kiến trúc
## Luồng hệ thống
```text
IP Camera -> MediaMTX -> FastAPI Backend -> Frontend Dashboard
|
-> recordings tren SSD/NVMe
```
## Yêu cầu phần cứng
- `Orange Pi 5` RAM `8GB` hoặc `16GB`
- Ổ lưu trữ `>= 256GB`
- Khuyến nghị dùng `NVMe SSD` thay vì thẻ nhớ để ghi hình ổn định hơn
- Nếu ghi nhiều camera hoặc giữ file lâu ngày, nên dùng `512GB` hoặc `1TB`
## Yêu cầu phần mềm
- Python `3.9+` (khuyến nghị `3.10+`)
- Node.js `20+`
- Docker và Docker Compose plugin cho MediaMTX
- Nginx hoặc Apache nếu muốn serve frontend static qua web server
## Backend API
- `GET /api/health`
- `GET /api/config`
- `POST /api/config/basic` (cập nhật thông số `config.json`)
- `GET /api/paths` (proxy trạng thái từ MediaMTX)
- `POST /api/recording` (bật/tắt ghi hình ngay)
- `POST /api/scheduler/enabled` / `POST /api/scheduler/schedule`
- `POST /api/config/basic`
- `GET /api/paths`
- `POST /api/recording`
- `POST /api/scheduler/enabled`
- `POST /api/scheduler/schedule`
- `GET /api/mediamtx/config`
- `POST /api/mediamtx/cameras` (body: `{ "rtsp_url": "..." }`)
- `POST /api/mediamtx/cameras`
- `DELETE /api/mediamtx/cameras/{name}`
- `POST /api/mediamtx/recording` (ghi `pathDefaults.record` vào `mediamtx.yml`)
- `POST /api/mediamtx/restart` (restart container `mediamtx`)
- `POST /api/mediamtx/recording`
- `POST /api/mediamtx/restart`
- `GET /api/recordings?camera=cam1&date=YYYY-MM-DD`
- `GET /videos/<camera>/<file>.fmp4`
## Chạy dev (máy dev)
## Chạy development
### 1) Chạy backend
### Backend
```bash
python3 -m venv api/.venv
@@ -39,30 +86,32 @@ pip install -r api/requirements.txt
python3 -m api.run
```
### 2) Chạy frontend
### Frontend
```bash
npm install
npm run dev
```
Frontend dev server đã được cấu hình proxy `/api``/videos` sang `http://localhost:8008`.
Frontend dev server đã proxy sẵn `/api``/videos` sang `http://localhost:8008`.
## Cấu hình
Backend chỉ dùng file `api/data/config.json` (không đọc `.env`).
Frontend dùng `.env` ch với `VITE_DEV_BACKEND_URL``VITE_API_BASE_URL`.
Backend chỉ đọc `api/data/config.json`.
Frontend chỉ dùng `.env` cho môi trường dev với `VITE_DEV_BACKEND_URL``VITE_API_BASE_URL`.
Các key quan trọng trong `config.json`:
- `mediamtx_api_url`: ví dụ `http://127.0.0.1:9997`
- `mediamtx_webrtc_url`: ví dụ `http://127.0.0.1:8889`
- `mediamtx_api_user`: username API (nếu bật auth trong MediaMTX)
- `mediamtx_api_pass`: password API (nếu bật auth trong MediaMTX)
- `recordings_dir`: ví dụ `./mediamtx/recordings` (cùng máy) hoặc đường dẫn mount NFS/SMB
- `api_port`: cổng chạy backend (mặc định `8008`)
- `cameras`: danh sách camera được đồng bộ từ `mediamtx.yml` (`name` + `rtsp_url`)
- `mediamtx_api_user`: username API nếu bật auth
- `mediamtx_api_pass`: password API nếu bật auth
- `recordings_dir`: đường dẫn recordings trên SSD/NVMe
- `api_port`: cổng backend, mặc định `8008`
- `cameras`: danh sách camera đồng bộ từ `mediamtx.yml`
- `schedule`: lịch ghi hình
Ví dụ `config.json`:
Ví dụ:
```json
{
@@ -82,6 +131,14 @@ Ví dụ `config.json`:
}
```
## Triển khai
## Triển khai production
Xem hướng dẫn chi tiết trong `INSTALL.md`.
Kịch bản production chuẩn cho project này:
- `Orange Pi 5` là máy duy nhất chạy cả dashboard và MediaMTX
- MediaMTX chạy local trên chính Orange Pi
- Backend FastAPI chạy local trên chính Orange Pi
- Frontend build ra `dist/` và được serve local
- Recordings lưu vào SSD/NVMe gắn trực tiếp với Orange Pi
Hướng dẫn cài đặt chi tiết xem trong `INSTALL.md`.