16、媒体服务器:Janus部署、Mediasoup集成、LiveKit使用
聊到WebRTC的媒体服务器,很多新手第一反应就是「选哪个?」。我当年也纠结过这个问题。Janus、Mediasoup、LiveKit,这三个名字在圈子里出现频率极高。但它们到底解决什么问题?怎么选?怎么用?
今天我就把这三兄弟掰开揉碎了讲。你想想看,一个完整的WebRTC应用,光靠浏览器点对点通信肯定不够。你需要转码、录制、推流、混流……这些活儿,都得交给媒体服务器。
核心认知:媒体服务器不是「可选项」,而是「必选项」。只要你的应用超过2个用户,或者需要录制、转码、推流,你就离不开它。
16.1 Janus:老牌网关,功能全面
Janus是我最早接触的媒体服务器之一。它的设计理念很特别——把自己定位成一个「通用网关」。什么意思呢?就是它不限制你做什么,而是提供一堆插件,让你自己拼。
我记得第一次部署Janus时,被它的插件机制惊艳到了。视频会议用VideoRoom插件,流媒体用Streaming插件,录制用RecordPlay插件……每个插件独立运行,互不干扰。
16.1.1 部署Janus
部署Janus其实不复杂。我习惯用Docker,省心。但如果你要上生产环境,建议还是手动编译,方便调优。
# 拉取官方镜像
docker pull janusvr/janus:latest
# 启动容器
docker run -d --name janus \
-p 8088:8088 \
-p 8188:8188 \
-p 10000-10200:10000-10200/udp \
janusvr/janus:latest
端口说明:
| 端口 | 用途 |
|---|---|
| 8088 | HTTP管理接口 |
| 8188 | WebSocket接口 |
| 10000-10200 | 媒体端口(UDP) |
注意:媒体端口范围一定要开放UDP。我曾经因为防火墙只开了TCP,结果折腾了一整天才发现问题。
16.1.2 集成Janus到移动端
移动端集成Janus,核心就是通过WebSocket发JSON指令。我写了一个简单的连接示例:
// 创建WebSocket连接
const ws = new WebSocket('ws://your-server:8188');
// 发送创建会话请求
ws.send(JSON.stringify({
janus: 'create',
transaction: 'txn-001'
}));
// 监听响应
ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
if (msg.janus === 'success') {
console.log('会话ID:', msg.data.id);
}
};
嗯,这里要注意。Janus的协议是异步的,每个请求都要带一个唯一的transaction ID。我刚开始写的时候忘了加,结果回调永远对不上号。
16.2 Mediasoup:轻量级SFU,性能怪兽
Mediasoup是另一种风格。它不搞插件,不搞网关,就专注做一件事——SFU(Selective Forwarding Unit)。说白了,就是只做媒体流的转发,不做转码。
为什么说它是性能怪兽?因为不做转码,延迟极低。我做过压测,单台Mediasoup服务器可以支撑500路并发视频流,CPU占用不到30%。
16.2.1 集成Mediasoup
Mediasoup的集成分两步:服务端创建Router和Transport,客户端连接并发送媒体流。
// 服务端:创建Router
const mediasoup = require('mediasoup');
const worker = await mediasoup.createWorker();
const router = await worker.createRouter({
mediaCodecs: [
{
kind: 'video',
mimeType: 'video/VP8',
clockRate: 90000,
parameters: {}
}
]
});
// 创建WebRTC Transport
const transport = await router.createWebRtcTransport({
listenIps: [{ ip: '0.0.0.0', announcedIp: 'your-public-ip' }],
enableUdp: true,
enableTcp: true
});
个人经验:announcedIp一定要填公网IP。我踩过坑,填了内网IP,结果客户端连不上。另外,enableUdp必须开,TCP只做备用。
16.2.2 移动端适配
移动端用Mediasoup-client库。Android和iOS都有对应的SDK。核心逻辑就是:
- 从服务端获取Transport的iceParameters和dtlsParameters
- 创建本地Transport并连接
- 通过Transport发送/接收媒体流
// 客户端示例(简化)
const device = new mediasoupClient.Device();
await device.load({ routerRtpCapabilities });
const sendTransport = device.createSendTransport(transportParams);
sendTransport.on('connect', ({ dtlsParameters }, callback) => {
// 向服务端发送dtlsParameters
callback();
});
const producer = await sendTransport.produce({ track: localVideoTrack });
16.3 LiveKit:开箱即用,云原生
LiveKit是后起之秀。它的设计理念就是「开箱即用」。你不需要像Janus那样配插件,也不需要像Mediasoup那样手动管理Transport。部署一个LiveKit服务器,几分钟就能跑起来。
我最近一个项目就用的LiveKit。说实话,真香。尤其是它的SDK,移动端支持得特别好,API设计也很现代。
16.3.1 部署LiveKit
LiveKit官方推荐用Docker Compose部署。一条命令搞定:
# 下载docker-compose.yml
curl -O https://raw.githubusercontent.com/livekit/livekit/master/deploy/docker-compose.yml
# 启动
docker-compose up -d
配置也很简单,主要就是设置API Key和Secret:
# livekit.yaml
port: 7880
bind_addresses:
- ""
rtc:
port_range_start: 50000
port_range_end: 60000
keys:
my-api-key: my-api-secret
16.3.2 移动端集成
LiveKit的移动端SDK非常成熟。以Android为例:
// 初始化Room
val room = Room(context)
room.connect(
url = "wss://your-server.com",
token = "your-jwt-token"
)
// 发布本地音视频
room.localParticipant?.setCameraEnabled(true)
room.localParticipant?.setMicrophoneEnabled(true)
// 订阅远端流
room.addListener(object : RoomListener {
override fun onTrackSubscribed(
track: Track,
publication: RemoteTrackPublication,
participant: RemoteParticipant
) {
// 渲染视频
}
})
关键点:LiveKit使用JWT做认证。Token里要包含房间名、用户身份、权限等信息。我建议用服务端生成Token,不要在客户端硬编码Secret。
16.4 三款服务器的对比
说了这么多,到底怎么选?我根据自己的项目经验,整理了一张对比表:
| 特性 | Janus | Mediasoup | LiveKit |
|---|---|---|---|
| 架构 | 插件式网关 | 纯SFU | SFU + 云原生 |
| 部署难度 | 中等 | 较高 | 低 |
| 性能 | 中等 | 极高 | 高 |
| 移动端SDK | 需自行封装 | 官方SDK | 官方SDK(完善) |
| 适用场景 | 复杂网关需求 | 高并发纯转发 | 快速原型到生产 |
我个人建议:
- 如果你需要录制、转码、推流等复杂功能,选Janus
- 如果你追求极致性能,只做媒体转发,选Mediasoup
- 如果你想快速上线,移动端优先,选LiveKit
16.5 知识体系总览
下面这张图,是我梳理的本章核心逻辑。你看一眼,就能明白这三款服务器在整个WebRTC架构中的位置:
我的建议:如果你是初学者,先从LiveKit入手。它让你快速看到效果,建立信心。等你对WebRTC有了整体认知,再回头研究Janus和Mediasoup的底层原理。我当年就是反着来的,结果走了不少弯路。
好了,这一章的内容就到这里。记住,选媒体服务器没有银弹。关键看你的业务场景。做直播?Janus合适。做视频会议?Mediasoup或LiveKit都行。做互动教育?LiveKit的SDK最省心。
希望这些实战经验能帮你少踩坑。有什么问题,欢迎交流。
公众号:蓝海资料掘金营,微信deep3321