MediaSoup WebRTC server cho phép nhận video/audio từ FFmpeg (hoặc PC streaming) qua RTP và phát lại cho trình duyệt thông qua WebRTC.
- Server: Node.js + Express + MediaSoup 3.13.24
- Signaling: WebSocket
- Codec: H264 (video), Opus (audio)
- RTP Input: FFmpeg gửi RTP đến server
- WebRTC Output: Browser nhận stream từ server
- Node.js >= 18.0.0
- FFmpeg (nếu stream từ video file)
npm installAPP_IP=localhost
APP_PORT=3000Lưu ý: Trên server EC2, đặt APP_IP = public IP của instance
npm startServer sẽ khởi động tại http://localhost:3000
docker build -t web-rtc-mediasoup .docker run -d \
--name web-rtc-server \
-p 3000:3000 \
-p 10000-10100:10000-10100/udp \
-p 10000-10100:10000-10100/tcp \
-e APP_IP=<YOUR_SERVER_IP> \
web-rtc-mediasoupThay <YOUR_SERVER_IP> bằng IP công cộng của server.
export APP_IP=<YOUR_SERVER_IP>
docker-compose up -d| Protocol | Port | Loại | Mục đích |
|---|---|---|---|
| TCP | 3000 | Inbound | WebSocket signaling (Browser ↔ Server) |
| Protocol | Port Range | Loại | Mục đích |
|---|---|---|---|
| UDP | 10000-10100 | Inbound/Outbound | WebRTC media (Browser ↔ Server) |
| TCP | 10000-10100 | Inbound/Outbound | WebRTC fallback (nếu UDP bị block) |
| Protocol | Port Range | Loại | Mục đích |
|---|---|---|---|
| UDP | 20000-40000 | Inbound | Nhận RTP từ FFmpeg/PC |
Vào AWS Console → Security Groups → Thêm Inbound Rules:
Rule 1: Type HTTP, Protocol TCP, Port 3000, Source 0.0.0.0/0
Rule 2: Type Custom UDP, Protocol UDP, Port Range 10000-10100, Source 0.0.0.0/0
Rule 3: Type Custom UDP, Protocol UDP, Port Range 20000-40000, Source 0.0.0.0/0
Rule 4: Type Custom TCP, Protocol TCP, Port Range 10000-10100, Source 0.0.0.0/0
ffmpeg -re -i video.mp4 \
-f rtp \
-c:v h264 \
-rtpflags latm \
'rtp://SERVER_IP:20000' \
-c:a libopus \
'rtp://SERVER_IP:20001'ffmpeg -f v4l2 -i /dev/video0 \
-f rtp \
-c:v h264 \
'rtp://SERVER_IP:20000' \
-c:a libopus \
'rtp://SERVER_IP:20001'ffmpeg -f x11grab -i :0.0 \
-f rtp \
-c:v h264 \
'rtp://SERVER_IP:20000' \
-c:a libopus \
'rtp://SERVER_IP:20001'
### Từ RTSP Camera/Source
```bash
# Re-encode to H264 baseline + Opus to match server
ffmpeg -rtsp_transport tcp -i rtsp://user:pass@CAMERA_HOST:PORT/path \
-f rtp \
-c:v libx264 -profile:v baseline -level 3.1 -tune zerolatency \
'rtp://SERVER_IP:20000' \
-c:a libopus -ar 48000 -ac 2 \
'rtp://SERVER_IP:20001'Hoặc dùng script tiện lợi:
# .env cần có EC2_HOST (vd: ubuntu@1.2.3.4), optional KEY_FILE
./stream-rtsp.sh rtsp://user:pass@CAMERA_HOST:PORT/path- Cách 1 (đơn giản, có giới hạn ~3 phút mỗi lần): dùng
adb screenrecordvà auto-restart.
# Chạy script mẫu
./example/stream-android-adb.sh
# Biến tuỳ chọn
# ADB_SERIAL: serial thiết bị (nếu có nhiều thiết bị)
# SIZE: độ phân giải (mặc định 1280x720)
# BITRATE: bitrate video bps (mặc định 4000000)Script sẽ:
-
Lấy RTP ports từ log server
-
Stream video từ
adb exec-out screenrecord→ FFmpeg → RTP (PT=96, SSRC=11111111) -
Tạo audio im lặng Opus → RTP (PT=97, SSRC=22222222) để trình duyệt luôn có track audio
-
Tự động restart sau mỗi lần
screenrecordkết thúc -
Cách 2 (ổn định, liên tục): dùng
scrcpyvà FFmpeg.- Khuyến nghị:
scrcpy+v4l2loopbackđể tạo virtual camera, FFmpeg đọc từ/dev/videoXvà đẩy RTP. - Chạy script mẫu:
# Yêu cầu: scrcpy, v4l2loopback, ffmpeg # Tuỳ chọn: ADB_SERIAL, V4L2_DEV (mặc định /dev/video10), BITRATE, FPS, SIZE ./example/stream-android-scrcpy.sh
- Âm thanh: dùng
anullsrc(im lặng) hoặc thêmsndcpyđể lấy audio thật từ thiết bị.
- Khuyến nghị:
Lưu ý:
adb screenrecordcó giới hạn thời gian; script đã auto-restart.- Nếu cần RTSP, dùng app Android xuất RTSP (ví dụ IP Webcam) và chạy
./stream-rtsp.sh ....
---
## 🌐 Kết nối từ Browser
1. Mở `http://SERVER_IP:3000` trên trình duyệt
2. Server sẽ gửi:
- Router RTP capabilities
- Video/Audio producer IDs
3. Browser tạo WebRTC transport
4. Browser nhận video/audio stream
### Client nên support:
- H264 video codec
- Opus audio codec
- WebRTC
---
## 🔍 Kiểm tra Server đang chạy
```bash
# Check nếu chạy trực tiếp
curl http://localhost:3000
# Check logs nếu chạy Docker
docker logs -f web-rtc-server
# Check port listening
netstat -tlnp | grep 3000
netstat -ulnp | grep 20000
Sửa trong server.js:
const APP_PORT = Number(process.env.APP_PORT || 3000);Sửa trong server.js:
const worker = await mediasoup.createWorker({
rtcMinPort: 20000, // RTP min port
rtcMaxPort: 40000, // RTP max port
});Sửa mediaCodecs trong server.js - hiện tại là H264, có thể đổi sang:
- VP8
- VP9
- AV1
| File | Mục đích |
|---|---|
server.js |
Main server logic (MediaSoup + WebSocket) |
index.html |
Frontend HTML |
package.json |
Dependencies |
Dockerfile |
Docker image |
docker-compose.yml |
Docker Compose config |
webpack.config.cjs |
Webpack config (nếu cần build frontend) |
.env |
Environment variables |
# Tìm process dùng port 3000
lsof -i :3000
# Kill process
kill -9 <PID>- Kiểm tra AWS Security Group inbound rules
- Kiểm tra Linux firewall:
ufw status - Kiểm tra iptables:
sudo iptables -L
- Kiểm tra
APP_IPđúng là public IP của server - Kiểm tra console browser để xem WebSocket connect error
- Kiểm tra server logs:
docker logs web-rtc-server
MIT - Lamvuon.shop