328 lines
7.3 KiB
Markdown
328 lines
7.3 KiB
Markdown
# IPCam Orange Pi Dashboard - INSTALL
|
|
|
|
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`.
|
|
|
|
Mục tiêu:
|
|
|
|
- `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
|
|
|
|
## 0) Cấu hình phần cứng khuyến nghị
|
|
|
|
Bắt buộc theo kịch bản này:
|
|
|
|
- Thiết bị: `Orange Pi 5`
|
|
- RAM: `8GB` hoặc `16GB`
|
|
- Ổ lưu trữ: `>= 256GB`
|
|
|
|
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 https://git.ttcorp.net/orangepivietnam/IPCam_OrangePi_Dashboard
|
|
cd 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
|
|
apiAddress: :9997
|
|
|
|
webrtc: yes
|
|
webrtcAddress: :8889
|
|
webrtcAllowOrigin: '*'
|
|
|
|
record: yes
|
|
recordFormat: fmp4
|
|
recordPath: /mnt/ssd/IPCam_OrangePi_Dashboard/mediamtx/recordings/%path/%Y-%m-%d_%H-%M-%S-%f
|
|
recordPartDuration: 5m
|
|
```
|
|
|
|
Ghi chú:
|
|
|
|
- `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`
|
|
|
|
### 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.1.0/24']
|
|
permissions:
|
|
- action: api
|
|
```
|
|
|
|
Sau đó khai báo trong `api/data/config.json`:
|
|
|
|
```json
|
|
{
|
|
"mediamtx_api_user": "dashboard",
|
|
"mediamtx_api_pass": "dashboard_password"
|
|
}
|
|
```
|
|
|
|
## 5) Chạy MediaMTX trên Orange Pi 5
|
|
|
|
Nếu project đã có `mediamtx/docker-compose.yml`, chạy:
|
|
|
|
```bash
|
|
cd /mnt/ssd/IPCam_OrangePi_Dashboard
|
|
docker compose -f mediamtx/docker-compose.yml up -d
|
|
```
|
|
|
|
Kiểm tra:
|
|
|
|
```bash
|
|
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
|
|
```
|
|
|
|
### 6.2) Cấu hình backend
|
|
|
|
Backend chỉ đọc cấu hình từ `api/data/config.json`.
|
|
|
|
File này chứa:
|
|
|
|
- thông số MediaMTX
|
|
- thư mục recordings
|
|
- danh sách camera
|
|
- lịch ghi hình
|
|
- cổng backend
|
|
|
|
Chạy lần đầu, backend có thể tự tạo file nếu chưa có.
|
|
|
|
Các giá trị nên dùng trên Orange Pi 5:
|
|
|
|
- `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
|
|
```
|
|
|
|
Kiểm tra:
|
|
|
|
```bash
|
|
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/`.
|
|
|
|
## 8) Serve frontend production
|
|
|
|
Có thể dùng `Nginx` hoặc `Apache`. Mục tiêu là:
|
|
|
|
- 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`
|
|
|
|
### 8.1) Ví dụ Nginx
|
|
|
|
```nginx
|
|
server {
|
|
listen 80;
|
|
server_name _;
|
|
|
|
root /mnt/ssd/IPCam_OrangePi_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;
|
|
}
|
|
}
|
|
```
|
|
|
|
### 8.2) Ví dụ Apache
|
|
|
|
```apache
|
|
<VirtualHost *:80>
|
|
ServerName _
|
|
DocumentRoot /mnt/ssd/IPCam_OrangePi_Dashboard/dist
|
|
|
|
<Directory /mnt/ssd/IPCam_OrangePi_Dashboard/dist>
|
|
Options Indexes FollowSymLinks
|
|
AllowOverride All
|
|
Require all granted
|
|
</Directory>
|
|
|
|
RewriteEngine On
|
|
RewriteCond %{REQUEST_FILENAME} !-f
|
|
RewriteCond %{REQUEST_FILENAME} !-d
|
|
RewriteRule ^ /index.html [L]
|
|
|
|
ProxyPreserveHost On
|
|
ProxyPass /api/ http://127.0.0.1:8008/api/
|
|
ProxyPassReverse /api/ http://127.0.0.1:8008/api/
|
|
|
|
ProxyPass /videos/ http://127.0.0.1:8008/videos/
|
|
ProxyPassReverse /videos/ http://127.0.0.1:8008/videos/
|
|
</VirtualHost>
|
|
```
|
|
|
|
Nếu dùng Apache:
|
|
|
|
```bash
|
|
sudo a2enmod rewrite proxy proxy_http
|
|
sudo systemctl reload apache2
|
|
```
|
|
|
|
## 9) Systemd service cho backend
|
|
|
|
Tạo file `/etc/systemd/system/ipcam-dashboard.service`:
|
|
|
|
```ini
|
|
[Unit]
|
|
Description=IPCam Dashboard Backend
|
|
After=network.target
|
|
|
|
[Service]
|
|
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
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
```
|
|
|
|
Enable:
|
|
|
|
```bash
|
|
sudo systemctl daemon-reload
|
|
sudo systemctl enable --now ipcam-dashboard
|
|
sudo systemctl status ipcam-dashboard
|
|
```
|
|
|
|
## 10) Firewall/cổng cần mở
|
|
|
|
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
|
|
|