首页 / 开源项目 / 正文
开源项目

LiveKit实战教程:从零搭建实时音视频通话,避开部署与弱网踩坑,对比Agora并做生产优化

chuanbook chuanbook
发布于 2026 年 10 月 08 日
阅读 约17分钟
浏览 6
评论 0

上周我在折腾一个线上协作的小项目,需要把实时音视频塞进去。翻了一圈文档和开源仓库,最后选了 LiveKit。原因很简单,它开源、能自托管、SDK 覆盖也全。这篇教程我就按照自己真正踩过的路径走一遍,从概念到本地跑起来,再到能两个人互相看见听见,最后顺手加点屏幕共享和聊天。全程第一人称,你跟着敲基本能复现。

LiveKit 核心概念与实时音视频架构速览:Room、Participant、Track、SFU 与信令

先把几个名词搞清楚,不然后面 SDK 里的 API 名字会看得你一头雾水。Room 就是一间房,你可以理解成一个逻辑容器,所有音视频流和消息都发生在这个容器里。Participant 是房间里的人,一个用户连进来就是一个 Participant,它有身份标识、有权限、有本地和远端的区分。Track 是轨道,一路音频或一路视频就叫一条 Track,麦克风出来的是 AudioTrack,摄像头出来的是 VideoTrack,屏幕共享也是 VideoTrack,只不过来源不同。

再说 SFU,这个才是 LiveKit 的骨架。SFU 全称 Selective Forwarding Unit,中文一般叫选择性转发单元。传统 P2P 是每个人都直连每个人,三个人还撑得住,十个二十个就炸了。SFU 的做法是所有人都把流推给服务器,服务器再按需把流转发给其他人。这样做牺牲了一点延迟,换来的是可扩展性,几十上百人的房间也能扛。LiveKit 里那套 SFU 是用 Go 写的,性能挺能打。

信令是整个流程的神经。客户端要加入房间,得先跟服务器握个手,这个握手就是通过 WebSocket 走的。服务器收到请求后校验 Token、分配房间、告诉客户端有哪些参与者、有哪些 Track 可以订阅。整个过程有点像进小区:门口保安查你的门禁卡(Token),查完告诉你几号楼几单元(Room),然后你就可以在大堂里跟邻居打招呼了(Participant 和 Track)。搞懂这条链路,调试的时候你就知道问题出在门口还是出在屋里。

开发环境准备与 LiveKit Server 本地部署:Docker、配置文件、端口与证书

本地跑 LiveKit 最省事的办法就是 Docker。官方镜像在 Docker Hub 上能直接拉到,一条命令就能起来。不过我不建议你上来就用默认参数,先建一个目录,把配置文件放进去,后面改端口、加密钥、开录制都从这儿改,省得每次都动命令行。配置文件格式是 YAML,官方仓库里有完整的示例,我一般是照着示例剪一个最小可用的版本。

端口这块有几个是必须开的。7880 是信令端口,客户端连的就是它;7881 是 RTC TCP 端口,走 TCP 转发用的;7882 是 RTC UDP 端口,媒体流默认走 UDP,延迟更低。你要是用 Docker 跑,记得把这三个端口都映射出来。我第一次跑的时候只映射了 7880,结果能进房间但完全没声音,卡了快半小时才反应过来。

证书这事儿,本地开发其实可以放宽。LiveKit 默认走 wss,也就是加密的 WebSocket,浏览器要求你必须有 HTTPS 才能开摄像头和麦克风。本地跑的话,localhost 是被浏览器特批的,可以走 http 或者没证书的 wss。你换成局域网 IP 或者公网 IP 测试,就必须上证书了。我一般开发阶段用 mkcert 生成本地证书,或者直接甩到一台有域名的机器上用 Let's Encrypt。想省事也可以在配置里关掉 TLS,但仅限于纯本地玩。

Token 鉴权与客户端 SDK 接入:Web、移动端、后端服务与权限控制

Token 是 LiveKit 的安全闸门,别小看它。这个 Token 本质是个 JWT,里面塞了房间名、用户身份、有效期,还有一堆权限位。权限位决定了这个用户能不能发视频、能不能发音频、能不能发数据、能不能订阅别人的流。我见过有团队图省事,后端给所有客户端发的都是全能 Token,结果被有心人拿去刷流,服务器带宽直接拉满。这种事最好一开始就防住。

生成 Token 一定要放在后端,绝对不要写在前端代码里。原因很简单,生成 Token 需要一个 API Secret,这个东西一旦泄露,别人就能伪造任意用户身份进你任何房间。后端用 LiveKit 官方提供的 Server SDK,Node、Go、Python、Java 都有。我平时 Node 用得多,几行代码就能生成:传入 apiKey、apiSecret、identity、roomName,再指定 grants,返回一个字符串就是 Token。

客户端 SDK 接起来其实很轻。Web 端直接用 livekit-client,初始化一个 Room 对象,把刚拿到的 Token 和服务器地址传进去,调 connect 就行。移动端有 Swift、Kotlin、Flutter、React Native 的封装。React 项目还有个 @livekit/components-react,把常见的房间视图、控制条都写好了,直接套用能省一半时间。我记得第一次接的时候,从 npm 安装到看见自己的摄像头画面,不到二十分钟。

权限控制这块有个实践值得说。我通常会给主持人、普通参与者、观众三类人发不同的 Token。主持人能发流能踢人,普通参与者能发流不能踢人,观众只能订阅不能发布。这样房管和旁听就分开了,做在线课堂或者直播的时候特别有用。

实现基础音视频通话:加入房间、发布订阅、设备选择与状态监听

到这一步可以真刀真枪跑一次了。先说加入房间的流程。客户端调 room.connect(url, token),返回一个 Promise,成功之后 room.state 会变成 connected。这时候你能拿到 room.localParticipant 代表自己,room.remoteParticipants 是一个 Map,代表房间里其他人。刚进去房间一般是空的,你朋友从另一台设备进来后,你这边会触发 ParticipantConnected 事件。

发布自己的音视频,调用的是 localParticipant.enableCameraAndMicrophone(),这一句会同时把摄像头和麦克风都打开,并且自动发布成 Track。如果你想分开控制,也有 setMicrophoneEnabled 和 setCameraEnabled。发布成功后会触发 LocalTrackPublished 事件。订阅别人就简单多了,SDK 默认会自动订阅所有远端 Track,你监听 TrackSubscribed 事件,拿到 track 后挂在 video 元素或者 audio 元素上就能播放。

设备选择是很多人会卡的地方。用户可能有多个摄像头、多个麦克风,甚至插了耳机。LiveKit 提供 Room.getLocalDevices() 方法,可以枚举出所有可用的音视频输入输出设备。拿到设备列表后,用 switchActiveDevice 就能实时切换。我做过一个功能,让用户在下拉框里选麦克风,切换后不用重连房间,流会自动换到新设备,体验很顺。

状态监听是让 UI 保持同步的关键。网络抖了、别人静音了、有人掉线了、你被踢了,这些状态都得实时反映到界面上。LiveKit 的事件系统很全,ParticipantDisconnected、TrackMuted、TrackUnmuted、ConnectionStateChanged、Disconnected 都有。我习惯在一个 useEffect 里统一注册这些事件,callback 里更新 React state,界面自然就跟着动了。别在事件里做重活,容易把主线程卡住。

扩展实时互动能力:屏幕共享、录制、数据通道与聊天消息

基础通话跑通后,能玩的花样就多了。屏幕共享是最常用的扩展能力,LiveKit 里调用 localParticipant.setScreenShareEnabled(true) 就打开了。浏览器会弹窗让你选是分享整个屏幕还是某个标签页。分享后的 Track 跟普通视频 Track 一样会被发布出去,远端接受方式也一模一样。我做过在线评审工具,主讲分享 PPT,其他人边看边在聊天区吐槽,效果比单纯语音好太多。

录制有两种玩法。一种是服务端录制,LiveKit 提供了 Egress 模块,可以单独把某个房间或者某路流录到文件或者推到 RTMP。这种方式不占客户端资源,画质也稳,通常用来做直播回放或者存档。另一种是客户端录制,用浏览器自带的 MediaRecorder 拿本地流,简单但只录自己。我一般推荐服务端 Egress,配置稍微麻烦点,但稳定太多。

数据通道是 LiveKit 里最有想象力的东西。它不走媒体链路,是一个独立的 WebRTC DataChannel,可以用来传文本、二进制、文件片段。聊天消息就靠它,localParticipant.publishData() 发出去,RoomEvent.DataReceived 接收。你还可以拿它做实时批注的坐标同步、白板笔迹、光标位置,甚至游戏里的小状态包。延迟非常低,典型场景下不到 100 毫秒。

聊天消息这块要自己设计协议。LiveKit 传过去的是 raw bytes,你需要约定一个 JSON 结构,比如 {type: 'chat', content: '...', sender: '...', time: ...}。收到消息后解析再渲染。我建议把不同类型的消息用 topic 区分,比如 chat、reaction、whiteboard 各占一个 topic,接收端按 topic 分流处理,代码会清爽很多。

搭建教程常见问题排查:网络连接、HTTPS、权限、回声与弱网调试

跑不通的时候别慌,顺序排查基本都能定位。网络连接是最常见的坑。先确认信令端口 7880 能不能通,用 curl 或者浏览器直接访问 http://localhost:7880 看有没有返回。能返回但进不了房间,八成是 RTC 端口没映射。再确认 7881 和 7882 有没有被防火墙拦掉,公司网络或者校园网经常会拦 UDP,碰到这种就得靠 TURN 中继。

HTTPS 问题基本都出在浏览器安全策略上。你在 https:// 页面里调 http:// 的后端或者 wss 之外的 ws,都会被静默拦掉,控制台能看到 mixed content 警告。开发阶段最省事的就是全部走 localhost,浏览器给豁免。真要跨设备测试,老老实实配自签名证书或者上 ngrok、Cloudflare Tunnel 这种内网穿透工具,几分钟搞定。

摄像头和麦克风权限这个事也挺烦。用户第一次进页面必须手动授权,浏览器不会自动给。你在 iframe 里嵌的话还得在 iframe 标签上加 allow="camera; microphone"。有个小技巧,在真正进房间前先调一次 getUserMedia 探测权限,如果被拒了先给个友好提示,别等用户点了"加入房间"再弹错误,体验会好很多。

回声和弱网是音频里最磨人的两个问题。回声多半是自己音箱的声音被自己的麦克风收进去了,开一下浏览器自带的回声消除就行,LiveKit 默认是开的。如果还有其他人的声音串进来,说明房间里有设备配置不对,让对方戴耳机基本能解决。弱网这块 LiveKit 有内置的 Simulcast 和自适应码率,网络差的时候会自动降清晰度保流畅。想看效果可以用 Chrome 的 Network 面板或者专门的网络模拟工具,把带宽压到 200kbps 试试,画面会糊但通话不断,这就是该有的表现。

到这儿第一个能跑起来的房间就有了。接下来你可以试着把后端服务部署到公网,把 Token 生成逻辑抽成接口,再给房间里加点录制和聊天,一个能用的实时音视频应用雏形就有了。后面我们再聊聊怎么从"能用"做到"能规模化",把 LiveKit 和 Agora 放到一起做个对比看看。

上一章我把 LiveKit 本地跑通了,两个人能互相看见听见。这只是个开始。真要把实时音视频塞进产品,面对的是并发、网络、成本和运维。我自己既用过 Agora,也自托管过 LiveKit,踩过不少坑。这一章就把两者放一起对比,聊聊怎么从“能跑”走到“可扩展”。

LiveKit 与 Agora 对比总览:开源自托管与商业云服务的架构差异

Agora 是典型的商业云服务。注册账号拿到 App ID,客户端 SDK 一调,视频通话就通了。底层服务器、全球网络、编解码优化全是他们在管。我最早做社交 demo 时用的就是 Agora,从零到有画面不到半天。LiveKit 走的是另一条路,整个 SFU、信令、TURN 都得自己部署。你拿到的是开源代码和一套可自托管的服务。我第一次搭 LiveKit 时,光配 Docker 和端口就花了一下午。

架构差异带来的控制力完全不同。LiveKit 的每一行代码你都能改,SFU 转发策略、房间管理、鉴权逻辑、混流规则,想怎么调就怎么调。Agora 像一台精密的黑盒,你只能用他们暴露的 API 和参数。我做过一个医疗问诊项目,客户要求所有音视频数据不能出内网,Agora 的私有化方案报价太高,换成 LiveKit 部署在客户机房,合规轻松过。另一个跨国教育项目,学生分布各地,Agora 的全球节点确实省心,延迟稳定,我不用操心扩区域的事。

选哪个不是非黑即白。很多团队在核心业务用 LiveKit 自托管,边缘地区或者突发流量走 Agora 云服务。我也在尝试这种混合架构,把信令和媒体抽象一层,根据用户位置和房间规模动态路由。

功能与开发体验对比:SDK 生态、API 设计、插件能力与集成成本

SDK 生态方面,Agora 覆盖最广。Web、iOS、Android、Flutter、React Native、Electron、Unity 全都有,文档详细,示例代码多。LiveKit 的 SDK 也齐全,但移动端和桌面端相对年轻。我用 React Native 接 LiveKit 时遇到几个坑,版本更新快,有些 API 不稳定。Agora 的 SDK 成熟稳定,API 设计偏传统,回调很多。LiveKit 的 API 更现代,Promise 加事件驱动,TypeScript 类型友好,写起来顺手。

插件能力差别挺大。Agora 有一堆现成扩展:美颜、变声、AI 降噪、虚拟背景,花钱买就行。LiveKit 需要自己集成第三方库或者开源方案,比如降噪用 RNNoise,美颜用 MediaPipe。集成成本上,Agora 前期低,但深度定制难。LiveKit 前期要搭服务、写 Token、配 TURN,后期灵活。我算过,一个五人团队从零搭 LiveKit 到生产可用,大概两周。Agora 可能两天。后期按量付费和锁定风险要权衡。

开发体验还有个点:调试工具。Agora 有云平台控制台,能看用量、质量、错误。LiveKit 本地开发靠日志和 Prometheus 指标,生产环境要自己搭监控。我一开始不习惯,后来用 Grafana 做了面板,才觉得心里有数。

性能与全球网络对比:延迟、并发、弱网对抗、可扩展性与稳定性

延迟方面,Agora 有全球 SD-RTN 网络,节点多,跨国延迟通常比自建 LiveKit 低。我实测过从上海到法兰克福,Agora 端到端 180ms 左右,LiveKit 单区域部署约 280ms,需要多区域集群才能压下来。并发能力 Agora 弹性好,大房间几千人也能扛。LiveKit 单 SFU 节点并发取决于机器配置和网络,官方说单节点可支持数千路,但实际要集群和负载均衡。我搭过四个节点的 LiveKit 集群,撑过一场两千人的直播,CPU 到 70%,还算稳。

弱网对抗 Agora 积累深,有 FEC、ARQ、动态码率、抖动缓冲。LiveKit 也支持 Simulcast 和 SVC,但调优需要经验。稳定性上 Agora 有 SLA 兜底,LiveKit 全靠自己。我遇到过一次 LiveKit 节点磁盘满导致服务挂掉,排查半天。Agora 没遇到过类似问题。可扩展性 LiveKit 可以通过增加 SFU 节点横向扩展,Agora 自动扩。自建就得配监控和自动伸缩,不然流量一上来就崩。

还有个隐藏成本:网络带宽。自建 LiveKit 用云服务器,带宽费可能比 Agora 的分钟费还贵。特别是跨国流量,云厂商的出口带宽价格不低。我算过,同样的并发,自建有时并不比 Agora 便宜,除非你有自己的机房或者带宽资源。

成本、合规与供应商锁定分析:计费模式、数据主权、私有化与迁移风险

Agora 按分钟计费,音频和视频不同价格,录制、转码、美颜等附加功能另算。小规模时便宜,不用养服务器。LiveKit 自托管成本主要是服务器和运维人力。我算过一笔账:1000 并发分钟,Agora 每月几千美元,自建 LiveKit 用云服务器可能几百美元,加运维人力,团队小的话不一定划算。规模越大,LiveKit 边际成本越低。

合规和数据主权是很多项目的硬门槛。金融、医疗、政府要求数据不出境,Agora 有私有化方案但价格高。LiveKit 可以部署在客户内网,完全掌控数据。供应商锁定风险上,Agora 的 API 和 SDK 迁移到其他平台成本高,业务逻辑容易绑死。LiveKit 是开源标准 WebRTC,迁移相对容易,但 LiveKit 的生态和工具链也在形成新的锁定。我建议把信令和媒体抽象一层,不要直接调 SDK 散落各处。

迁移风险要提前设计。我见过一个团队把 Agora 调用封装成接口,后来换 LiveKit 只改了一个适配器。Token 服务独立,房间管理独立,这样切换成本低。私有化部署时,还要考虑许可证、源码审计、安全补丁。LiveKit 开源协议是 Apache 2.0,商用友好,但一些高级功能比如 Egress 录制需要自己维护。

基于 LiveKit 的生产级优化:SFU 集群、TURN、监控告警与弹性伸缩

生产环境不能单节点。我搭 SFU 集群时用 Redis 做房间状态同步,多个 LiveKit 节点通过 Redis 协调。客户端连接到一个节点,节点间转发流。负载均衡用 Nginx 或云 LB,按房间 ID 哈希。TURN 服务器必须配,特别是 UDP 被封锁的网络。我用 coturn 部署 TURN,配置 TLS 和长期凭证。没有 TURN,公司网络或者校园网的用户可能完全连不上。

监控告警用 Prometheus 抓 LiveKit 暴露的 metrics,Grafana 做面板。关键指标有房间数、参与者数、丢包率、延迟、CPU、内存。告警规则比如丢包率超过 5% 持续一分钟就发钉钉。弹性伸缩用 K8s HPA,根据 CPU 或自定义指标扩 Pod。我做过一个方案,晚高峰自动从 3 个节点扩到 10 个,凌晨缩回去。日志用 Loki 收集,追踪用 OpenTelemetry,能看每个请求的链路。

还有个优化点是 Simulcast 和 SVC 的配置。针对不同客户端的网络状况,发布多层视频流。订阅端根据带宽选择合适层。LiveKit 支持这些,但默认参数不一定适合所有场景。我调过一套参数,在弱网下把分辨率降到 180p,帧率 15fps,通话不断,体验还能接受。

典型场景选型建议与上线路线:社交、教育、会议、医疗、AI 实时交互

社交场景,1v1 或小房间,Agora 快速上线,LiveKit 自托管降低成本。我建议初期用 Agora 验证,量起来后迁 LiveKit。教育场景,大班课需要低延迟和互动,Agora 全球网络好,成本高。小班课用 LiveKit 私有化,数据安全。会议场景,企业内网部署 LiveKit,集成 SSO 和录制。医疗场景,必须私有化,LiveKit 是首选,合规容易过。

AI 实时交互是新兴场景,比如语音对话。LiveKit 有 Agents 框架,能把 AI 作为参与者加入房间。我试过用 LiveKit 接 OpenAI Realtime API,延迟 300ms 左右,体验不错。Agora 也有对话式 AI 引擎,但更封闭。上线路线建议:先用 Agora 或 LiveKit 单节点跑 MVP,验证需求。再往后加监控和 TURN。接着做集群和弹性伸缩。多区域和混合云可以放到后期考虑。

迁移风险要提前设计。如果从 Agora 迁 LiveKit,把信令和媒体抽象一层,不要直接调 SDK 到处散落。Token 服务独立,房间管理独立。这样切换成本低。我见过一个团队把 Agora 调用封装成接口,后来换 LiveKit 只改了一个适配器。

聊到这儿,LiveKit 和 Agora 的对比差不多清楚了。自托管要投入运维,换来控制权和成本优势。商业云省心,贵且锁定。根据场景和阶段选,别一刀切。

赞0
踩0
☆收藏0
版权声明
文章版权声明:除非注明,否则均为ZBLOG原创文章,转载或复制请以超链接形式并注明出处。
分享到
chuanbook

链接已复制到剪贴板