Files
2026-06-26 14:29:19 +07:00

156 lines
4.6 KiB
Markdown

# IPCam Orange Pi Dashboard
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.
![Xem DEMO](./SCREENSHOT.md)
## 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
- `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`
- `GET /api/paths`
- `POST /api/recording`
- `POST /api/scheduler/enabled`
- `POST /api/scheduler/schedule`
- `GET /api/mediamtx/config`
- `POST /api/mediamtx/cameras`
- `DELETE /api/mediamtx/cameras/{name}`
- `POST /api/mediamtx/recording`
- `POST /api/mediamtx/restart`
- `GET /api/recordings?camera=cam1&date=YYYY-MM-DD`
- `GET /videos/<camera>/<file>.fmp4`
## Chạy development
### Backend
```bash
python3 -m venv api/.venv
source api/.venv/bin/activate
pip install -r api/requirements.txt
python3 -m api.run
```
### Frontend
```bash
npm install
npm run dev
```
Frontend dev server đã proxy sẵn `/api``/videos` sang `http://localhost:8008`.
## Cấu hình
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
- `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ụ:
```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
}
}
```
## Triển khai production
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`.
## Bản quyên
Copyright (c) 2026
[Trần Thanh Tân / [TTAI Solutions Software](https://ttaisolutions.com/)]
All rights reserved.
Không được phép sao chép, phân phối hoặc truyền tải bất kỳ phần nào của phần mềm này hoặc mã nguồn của nó dưới bất kỳ hình thức hoặc phương tiện nào, bao gồm sao chụp, ghi âm hoặc các phương pháp điện tử hoặc cơ khí khác, mà không có sự cho phép bằng văn bản trước của chủ sở hữu bản quyền.