news 2026/10/15 18:26:51

Commet语音与视频通话揭秘:LiveKit + WebRTC如何接入Matrix

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Commet语音与视频通话揭秘:LiveKit + WebRTC如何接入Matrix

【免费下载链接】commet

Your space to connect

项目地址:https://gitcode.com/gh_mirrors/co/commet
点击查看免费下载

📞Commet是一款主打安全与隐私的 Matrix 开源聊天客户端(口号是 "Your space to connect"),它的语音通话与视频通话能力非常值得一提。本文将揭秘 Commet 是如何把WebRTC的点对点直连与LiveKit的 SFU 群组通话两条技术路线,无缝接入 Matrix 协议的。无论你是想了解 Matrix 群组通话原理的新手,还是准备给自己的项目接入 VoIP 的开发者,这篇完整指南都能帮你在 5 分钟内看懂其中的门道。

一图看懂 Commet 的通话架构:两套引擎并存

很多用户在用 Commet 时会发现:1 对 1 聊天里点「通话」,和多人通话房间里的体验并不完全一样。这不是玄学,而是 Commet 故意设计的双引擎架构:

场景信令通道媒体传输核心代码
1 对 1 语音/视频通话Matrixto-device消息(m.call.invite等)WebRTC P2P 直连matrix_voip_component.dart
群组通话(VoIP Room)Matrix 房间状态事件 + homeserver 签发 JWTLiveKit SFU 转发matrix_livekit_backend.dart

Commet 用一个抽象层把两条路线统一起来。在 voip_component.dart 中,VoipComponent抽象类只关心四件事:发起通话(startCall)、查询会话(getSessionsInRoom)、监听会话开始/结束事件、判断房间能否通话。UI 层完全不需要知道底层是 WebRTC 还是 LiveKit,这种"策略可替换"的设计是整个 VoIP 模块的精髓。

引擎一:WebRTC 如何让两个人"直接连上"

1 对 1 通话走的是 Matrix 官方 VoIP 规范:双方通过m.call.invite、m.call.answer、m.call.hangup等to-device事件交换 SDP 与 ICE 候选,最终在两台设备之间建立WebRTC PeerConnection直连。

在 matrix_voip_component.dart 中,Commet 实现了WebRTCDelegate接口来接管这条链路,其中有两个很务实的细节:

  • ICE 服务器拆分:homeserver 下发的 STUN/TURN 配置会被拆成单个 URL 的独立条目,避免flutter_webrtc只检查第一个地址的问题;
  • TURN 回退兜底:如果 homeserver 没有配置任何 ICE 服务器,Commet 会弹出确认框,询问是否使用预设的回退 TURN 服务器(VoipTurnFallbackDialog),否则直接抛错提示"无法连接"。

底层真正干活的是flutter_webrtc库(在 pubspec.yaml 中锁定为 1.4.0,并使用了 commet 社区的 fork 以保证兼容性),它负责麦克风采集、摄像头采集、媒体流发布等 WebRTC 标准能力。

引擎二:LiveKit SFU 如何撑起群组通话 🎥

两个人直连没问题,但 10 个人互连就要维护 45 条媒体流,根本不可行。因此 Commet 的群组语音通话采用了 MSC3417 提案 中的"VoIP Room"方案:房间创建时type为org.matrix.msc3417.call,所有参与者的音视频都上传到一台LiveKit SFU(选择性转发单元)服务器,由 SFU 负责分发,任何客户端只需下载自己需要的流,带宽与延迟都大大优化。

加入一次群组通话,matrix_livekit_backend.dart 的join()方法会按下面 5 步走:

  1. 发现 LiveKit 服务地址(Focus URL):优先读取房间状态事件org.matrix.msc3401.call.member中其他成员留下的foci_preferred;找不到就查询 homeserver 的 well-known 文件里的org.matrix.msc4143.rtc_foci字段;
  2. 向 homeserver 换 JWT:调用requestOpenIdToken拿到临时访问令牌,这是"用 Matrix 身份进入 LiveKit 房间"的门票;
  3. 请求 SFU 接入点:POST 到{livekit_service_url}/sfu/get,携带设备 ID、房间 ID 和 OpenID 令牌,换回 LiveKit 连接地址与 JWT;
  4. 宣告自己在场:把自己的foci_preferred和focus_active写回房间状态事件,方便后加入的人发现同一台 SFU;
  5. 连接 LiveKit 房间并开麦:以自适应码率(adaptiveStream)与dynacast模式连接,随后自动启用默认麦克风。

加密通话里的密钥是如何悄悄交换的 🔒

在加密房间中,SFU 转发的是"密文",所以 Commet 还需要一套媒体层端到端加密。核心实现在 matrix_livekit_encryption_key_provider.dart:

  • 基于 LiveKit 的 E2EE 框架,为每个参与者维护一个 256 位的密钥环,采用 HKDF 派生与 Ratchet 滚动机制(依赖vodozemac/flutter_vodozemac加密库,见 pubspec.yaml);
  • 每当有人加入或离开通话(监听房间call.member状态变化),就会立即轮换密钥,并通过 Matrixto-device加密事件io.element.call.encryption_keys把新密钥分发给每个在席设备;
  • 旧参与者离开后,其密钥自然失效——这正是"前向保密"思想在音视频场景中的落地。

你看到的通话界面背后发生了什么

通话 UI 位于 call_view.dart,它根据VoipState(incoming / outgoing / connecting / connected / ended)切换五种界面:响铃页、拨出页、通话中网格页、结束页等。配套的 voip_stream_view.dart 负责渲染每一路视频流。

而全局的"通话大脑"是 call_manager.dart:

  • 🔔 来电时触发系统通知(Android 上直接交给推送通知响铃),其他平台播放 ringtone_in.ogg;
  • 🎵 有人加入/离开时播放joined_call.ogg、left_call.ogg提示音;
  • 🎙️ 即使不在通话中按下静音快捷键,也会播放反馈音,方便用户确认快捷键生效。

想动手看看?核心文件路径清单

模块路径
VoIP 抽象接口(组件/会话/流)commet/lib/client/components/voip/
WebRTC 1v1 通话commet/lib/client/matrix/components/voip/
LiveKit 群组通话后端commet/lib/client/matrix/components/voip_room/
通话管理(铃声/通知/快捷键)call_manager.dart
通话 UI(来电/通话中视图)commet/lib/ui/organisms/call_view/
依赖声明(livekit_client、flutter_webrtc)pubspec.yaml

写在最后:Commet 这套方案能教会我们什么?

Commet 的 VoIP 实现给了开源项目一个很好的参考范式:信令交给 Matrix 房间与 to-device 事件,媒体交给 WebRTC/LiveKit,加密交给密钥环 + 前向保密,三者各司其职。

  • 🤝 小型通话:P2P 直连,链路最短、隐私最佳;
  • 🏢 群组通话:LiveKit SFU 承担扇出,客户端只拉自己需要的流;
  • 🧩 抽象层VoipComponent/VoipSession让 UI 与底层引擎彻底解耦,未来替换或新增后端(比如换一家 SFU 厂商)几乎不用动界面代码。

如果你想给 Matrix 客户端加上自己的语音视频通话能力,或者想深入 Matrix 通话协议,从上面这张路径清单出发,按"抽象接口 → 后端实现 → UI 层"的顺序阅读源码,就是最高效的路线。

【免费下载链接】commet

Your space to connect

项目地址:https://gitcode.com/gh_mirrors/co/commet
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/15 18:26:36

智能手表源码实战:从编译到点屏的嵌入式开发避坑指南

简介:这是一套面向嵌入式开发者的STM32智能手表完整项目源码,适合具备C/C基础、希望深入实践软硬件协同开发的工程师与学习者。资源围绕WTM32智能手表展开,涵盖时间显示、健康监测、通知推送等核心功能,并涉及FreeRTOS或RT-Thread…

作者头像 李华
网站建设 2026/10/15 18:25:56

ARM编译器版本5(AC5)实践指南:选型、命令行编译与避坑

简介:面向ARM嵌入式开发者的编译器版本5安装包,适合在Cortex系列及ARM7~ARM11等处理器上从事裸机、RTOS或驱动开发的工程师。该版本支持C、C与汇编,提供O0~O3多级优化,并针对VFP浮点运算与循环指令进行专项改进,同时兼…

作者头像 李华
网站建设 2026/10/15 18:24:23

TUM、KITTI、EuRoC三大SLAM数据集选型与避坑指南

简介:这份文档面向SLAM、自动驾驶与微型无人机方向的研究者和学生,系统梳理了TUM RGB-D、KITTI与EuRoC三大主流数据集的采集平台、数据格式与评价准则,帮助读者快速建立对多传感器数据集的整体认知,解决入门选型与格式理解上的困惑…

作者头像 李华
网站建设 2026/10/15 18:21:53

为什么TechSpar题库不是固定题单?动态出题底座的核心设计深度揭秘

【免费下载链接】TechSpar 一个持续进化的面试训练系统。在线体验地址:https://techspar.cn 项目地址: https://gitcode.com/gh_mirrors/te/TechSpar 点击查看 免费下载 很多人第一次接触 TechSpar 这套面试训练系统,会下意识把它的「题库」…

作者头像 李华