# 开源视频对讲项目对比:LiveKit / Jitsi / SRS
在本机(Windows + Docker)下载并部署了三个主流开源 WebRTC 视频对讲项目,用**同一台电脑的两个浏览器标签页**实测双向视频通话,目的是对比哪个更适合「开箱即用」。
* **LiveKit**:现代 SFU,部署最轻、SDK 最全,**实测可用** ✅
* **Jitsi**:功能最全(完整会议 UI),部署最重,**已修复并可测试** ✅
* **SRS**:偏流媒体 / 直播方向,**不适合开箱即用做双向对讲**(详见下文)⚠️
***
## 目录结构
```
video-call-comparison/
├── README.md ← 本文档
├── 对比可视化.html ← 三项目对比可视化页面
├── livekit/
│ ├── livekit-server/ ← 官方源码(浅克隆)
│ ├── run/
│ │ ├── livekit.yaml ← 服务端配置(已生效)
│ │ └── livekit-server.exe ← 本机二进制(备用)
│ └── test-client/
│ ├── server.js ← 本地测试客户端(签发 token + 托管页面)
│ ├── index.html ← 测试页面(房间连接 / 发布 / 订阅展示)
│ └── node_modules/ ← livekit-client SDK(本地安装)
├── jitsi/
│ ├── docker-jitsi-meet/ ← Jitsi 官方 docker-compose 仓库
│ │ └── .env ← 部署配置(已按本机调试优化)
│ ├── jitsi-meet/ ← 官方前端源码(浅克隆)
│ └── .jitsi-meet-cfg/ ← 各服务持久化配置目录
└── srs/
├── srs/ ← 官方源码(浅克隆)
├── demos/ ← 从容器拷出的 demo 页面
├── run/
│ └── srs.conf ← 服务端配置(已生效)
└── docker.conf.actual ← 配置取证副本
```
***
## 环境要求
| 依赖 | 版本 |
| -------------- | -------------------- |
| Windows | 10/11 |
| Docker Desktop | 29.x(WSL2 后端) |
| Node.js | ≥ 18(LiveKit 测试客户端用) |
| Git | ≥ 2.x |
> 本机内存共 15.7GB,但系统空闲内存常年紧张(浏览器、WSL、其他应用占用高)。
>
> **Jitsi 前端吃内存,测试前建议关闭占用高的程序。**
***
## 快速开始(当前运行状态)
三个服务均已部署并运行(截至本 README 编写时):
| 服务 | 容器 | 状态 | 端口 |
| ----------- | ---------------------------------------------- | ------- | ----------------------------- |
| LiveKit | `livekit` | Up | 7880/7881 TCP,50000–50100 UDP |
| Jitsi | `docker-jitsi-meet-{web,jvb,jicofo,prosody}-1` | Up | 8000/8443 TCP,10000 UDP |
| SRS | `srs` | Up | 1935/1985/8080 TCP,8000 UDP |
| LiveKit 测试页 | node 进程 | 监听 3000 | 3000 |
测试入口:
* LiveKit:`http://localhost:3000`
* Jitsi:`https://localhost:8443`
* SRS:`http://localhost:8080/players/whip.html`(推)/ `.../whep.html`(拉)
***
## 一、LiveKit(实测可用 ✅)
### 部署
用官方镜像启动,**关键点**:
1. 必须传 `--node-ip 127.0.0.1`,让 SFU 广播回环地址(否则广播容器私网 IP,本机浏览器连不上,媒体流建立失败);
2. UDP 端口范围要与发布端口一致。
```
docker run -d --name livekit `
-p 7880:7880 -p 7881:7881 `
-p 50000-50100:50000-50100/udp `
-v D:\myDoubao\video-call-comparison\livekit\run\livekit.yaml:/etc/livekit.yaml `
docker.1ms.run/livekit/livekit-server:latest `
--config /etc/livekit.yaml --node-ip 127.0.0.1
```
`livekit/run/livekit.yaml` 核心内容:
```
port: 7880
rtc:
tcp_port: 7881
port_range_start: 50000
port_range_end: 50100
use_external_ip: false # 关闭外部 IP 探测,强制用 --node-ip
keys:
devkey: secret # 开发用 API key/secret,生产务必更换
logging:
level: info
```
> 镜像因网络原因使用加速器
>
> `docker.1ms.run`
>
> (LiveKit 官方镜像)。版本 v1.13.10。
### 调试与测试
启动测试客户端(签发 JWT token + 托管页面):
```
node D:\myDoubao\video-call-comparison\livekit\test-client\server.js
# 输出:LiveKit test client running at http://localhost:3000
```
浏览器开**两个标签页**访问 `http://localhost:3000`,输入**同一房间名**(如 `room1`),分别点击加入。两个页面都能看到对方的摄像头画面即成功。
验证服务端配置已生效:
```
docker logs livekit 2>&1 | Select-String "nodeIP|portICERange"
# 应看到 nodeIP=127.0.0.1, rtc.portICERange=[50000,50100]
```
### 踩坑记录
| 问题 | 现象 | 根因 | 解决 |
| ----------- | -------------------------------------------------------- | ----------------------------------------------- | -------------------------------------- |
| 连不上 | `could not establish pc connection` | 开发模式默认监听 UDP 7882,与发布的 50000–50100 不匹配;且广播容器 IP | 用配置文件固定 UDP 范围 + `--node-ip 127.0.0.1` |
| Node 无法自动验证 | LiveKit 报 "doesn't seem to be supported on this browser" | livekit-client 需浏览器环境建 RTCPeerConnection | 放弃 Node 端自动验证,改用浏览器双标签实测 |
***
## 二、Jitsi(已修复,可测试 ✅)
### 部署
Jitsi 用官方 docker-compose 全栈(web /prosody/jicofo /jvb 四个服务):
```
cd D:\myDoubao\video-call-comparison\jitsi\docker-jitsi-meet
# 首次需复制 env.example 为 .env,本文已配置好
docker compose up -d
```
`.env` 关键配置(已按本机调试优化):
```
CONFIG=D:/myDoubao/video-call-comparison/jitsi/.jitsi-meet-cfg
HTTP_PORT=8000
HTTPS_PORT=8443
PUBLIC_URL=https://localhost:8443
ENABLE_XMPP_WEBSOCKET=1
JVB_ADVERTISE_IPS=127.0.0.1 # 关键:让 JVB 广播回环地址,同机双标签可直达
JVB_COLIBRI_PORT=16080 # 关键:避开 SRS 的 8080 与 Windows 排除段
```
> Jitsi 四个服务镜像均为
>
> `ghcr.io/jitsi/*:unstable`
>
> 。
### 调试与测试
浏览器开**两个标签页**访问 `https://localhost:8443`(自签名证书,浏览器点「高级 → 继续访问」):
1. 标签页 A:新建会议;
2. 标签页 B:输入**同一房间名**加入;
3. 两个标签都允许摄像头 / 麦克风。
验证 JVB 已正确注册为视频桥:
```
docker logs --tail 12 docker-jitsi-meet-jvb-1 2>&1
# 应看到 Joined MUC: jvbbrewery@internal-muc.meet.jitsi(无 DNS 报错)
```
### 踩坑记录(重点,曾导致 "开第二个标签全崩")
| 问题 | 现象 | 根因 | 解决 |
| ------------ | ------------------------------------------- | ----------------------------------------------------------------------------------------------- | ------------------------------------------------------------ |
| 标签页全崩 | 开第二个标签后所有标签崩溃 | JVB 容器**没挂进 **`meet.jitsi`** 内部网络** → 无法解析 `xmpp.meet.jitsi` → 注册不上视频桥,第二人加入时会议拿不到视频桥 | 干净重建:`docker compose down && docker compose up -d`,确保 JVB 联网 |
| 端口冲突 | JVB 无法启动 / 联网 | SRS 占用宿主 8080,JVB colibri 也要 8080 | 改 `JVB_COLIBRI_PORT=16080` |
| Windows 端口排除 | `bind: forbidden by its access permissions` | 18080 落在 WSL2 排除段(17553–18152) | 改到 16080(不在排除段) |
> **排查要点**
>
> :JVB 必须能解析
>
> `xmpp.meet.jitsi`
>
> 。检查
>
> `docker inspect --format '{{json .NetworkSettings.Networks}}' docker-jitsi-meet-jvb-1`
>
> ,若输出
>
> `{}`
>
> 说明没联网,需重建。
***
## 三、SRS(偏流媒体,双向对讲需自行组装 ⚠️)
### 部署
SRS 用核心镜像(`ossrs/srs:5`,阿里云源可拉取),**必须显式传入自定义配置**(否则镜像按默认 conf/docker.conf 启动):
```
docker run -d --name srs `
-p 1935:1935 -p 1985:1985 -p 8080:8080 -p 8000:8000/udp `
-v D:\myDoubao\video-call-comparison\srs\run\srs.conf:/usr/local/srs/conf/srs.conf `
registry.cn-hangzhou.aliyuncs.com/ossrs/srs:5 `
/usr/local/srs/objs/srs -c /usr/local/srs/conf/srs.conf
```
`run/srs.conf` 关键点:`http_api` 绑定 `0.0.0.0:1985`、`rtc_server` 端口 8000/UDP 且 `candidate 127.0.0.1`。
> SRS 官方仓库镜像(1ms /ghcr 源)拉不动,改用阿里云
>
> `registry.cn-hangzhou.aliyuncs.com/ossrs/...`
>
> 。版本 v5.0.225。
### 调试与测试(v5 走 WHIP/WHEP)
SRS v5 的 WebRTC 信令是 **WHIP/WHEP(HTTP 协议)**,正确的单路视频测试:
* **推流(标签页 A)**:`http://localhost:8080/players/whip.html?autostart=true`
* **拉流(标签页 B)**:`http://localhost:8080/players/whep.html?autostart=true`
* 默认推 / 拉同一条流:`webrtc://localhost/live/livestream`
> 这只实现
>
> **单向**
>
> (A 推、B 看)。
>
> **SRS 开箱不提供双向互讲**
>
> ,群组会议需走 SRS Stack 或自建 WHIP/WHEP 客户端。
### 踩坑记录
| 问题 | 现象 | 根因 | 解决 |
| ----------- | -------------------- | ----------------------------------------------------------------------- | ----------------------------------------------------- |
| 开会 "没反应" | 自带 room.html 多人会议打不开 | SRS v5 废弃了旧 WebSocket 信令 `/sig/v1/rtc`(返回 non-101),自带 room.html 用的正是旧协议 | 改走 WHIP/WHEP;或换 SRS Stack |
| 镜像拉不动 | 1ms /ghcr 源超时 | 网络问题 | 换阿里云源 `registry.cn-hangzhou.aliyuncs.com/ossrs/srs:5` |
| Stack 裸跑不可用 | 会议场景 | SRS Stack 内部 http\_api 绑 127.0.0.1、需 verify 钩子 | 改用 SRS 核心镜像 + 自定义配置 |
***
## 四、为什么 [localhost](https://localhost) 不用 HTTPS
浏览器能否调用摄像头 / 麦克风(`getUserMedia`)的判断标准是**安全上下文(secure context)**,而非单纯 "必须 https"。
安全上下文包括:
* `https://` 的页面;
* `http://localhost`** / **`http://127.0.0.1` —— 被浏览器永久豁免,即使协议是 http 也允许调摄像头。
所以:
* **LiveKit** 用 `http://localhost:3000` 直接可用(靠 [localhost](https://localhost) 豁免省掉 https 麻烦);
* **Jitsi** 默认就配成 https + 自签名证书(所以要点「继续访问」),它也可以配成 http 走 [localhost](https://localhost)。
**注意**:一旦部署到别人能访问的域名(非本机),必须上 https,否则远程用户调不了摄像头。
***
## 五、三项目对比与结论
| 维度 | LiveKit | Jitsi | SRS |
| --------- | ------------------------------------ | ------------------------------------------- | ------------------------------------ |
| 定位 | 现代 SFU + SDK | 完整开源会议系统 | 流媒体服务器(RTMP/WebRTC) |
| 部署难度 | ★ 低(单容器) | ★★★ 高(4 容器 compose) | ★★ 中(单容器,配置灵活) |
| 开箱即用做双向对讲 | ✅ 是 | ✅ 是(配置正确后) | ⚠️ 否(需自行组装) |
| 前端体验 | 需自己写测试页 | 完整会议 UI | 偏推拉流 demo |
| SDK / 集成 | 极全(多语言) | 提供 iframe 嵌入 | 需自写 WHIP/WHEP 客户端 |
| 本机访问 | [http://localhost](http://localhost) | [https://localhost](https://localhost)(自签名) | [http://localhost](http://localhost) |
| 内存占用 | 低(\~15MB) | 较高(\~500MB 服务端 + 重前端) | 低(\~14MB) |
**结论**:
* 只想**快速跑通、做二次开发** → 选 **LiveKit**(最省事、SDK 全);
* 想要**开箱即用的完整会议功能**(录屏、字幕、白板等)→ 选 **Jitsi**,但部署最重、吃内存;
* 侧重**直播 / 流媒体推送** → 选 **SRS**,但**不适合开箱即用做视频对讲**。
详细对比可视化见 `对比可视化.html`。
***
## 六、停止与清理
```
# 停止单个服务
docker stop livekit
docker compose -f D:\myDoubao\video-call-comparison\jitsi\docker-jitsi-meet\docker-compose.yml down
docker stop srs
# 停止全部
docker stop livekit srs docker-jitsi-meet-web-1 docker-jitsi-meet-jvb-1 docker-jitsi-meet-jicofo-1 docker-jitsi-meet-prosody-1
# 彻底删除(会删容器,配置文件保留在项目目录)
docker rm -f livekit srs
docker compose -f D:\myDoubao\video-call-comparison\jitsi\docker-jitsi-meet\docker-compose.yml down
```
> 想重新完整启动 Jitsi:
>
> `cd .../docker-jitsi-meet && docker compose down && docker compose up -d`
>
> (干净重建,确保各容器正确联网)。
***
## 七、常见问题(FAQ)
**Q1:开第二个 Jitsi 标签全崩?**
A:先确认 JVB 是否注册成功(日志有 `Joined MUC: jvbbrewery`、无 `xmpp.meet.jitsi` 解析报错);其次检查系统空闲内存是否过低,测试前关闭占用高的程序。
**Q2:LiveKit 报 "could not establish pc connection"?**
A:检查启动命令是否带 `--node-ip 127.0.0.1`,且 UDP 发布端口与配置的 50000–50100 一致。
**Q3:SRS 的 room.html/one2one.html 打不开?**
A:v5 已废弃旧 WebSocket 信令,请改用 WHIP/WHEP 页面(`whip.html` / `whep.html`)。
**Q4:能只用两个不同浏览器窗口测吗?**
A:可以,同一浏览器两个标签页、或不同浏览器各开一个、或再加一台设备,用同一房间名即可互相看到。