Jitsi Meet 推出 Receiver Audio 订阅服务

Jitsi Meet 长期支持视频 ReceiverConstraints 功能。接收方可指定希望接收的视频流及其分辨率,后端将在可用带宽范围内尽力满足这些约束。但音频方面此前缺乏同等灵活性——客户端始终接收所有可用音频源。这一状况现已改变。

该项目是 GSoC 2025 的一部分,实现了接收方自主选择音频源的功能。

这项 API 能实现哪些功能?以下是 Jitsi Meet 构想的部分应用场景,同时也期待看到社区的创新成果:

  • 无需独立会议的分组讨论室
  • 静音功能
  • 实时翻译会议(多语言网络研讨会)

本文后续将详细阐述音频订阅功能的实现方式及开发过程中遇到的挑战。

信令消息语义

该项目的核心是一条新的信令消息:ReceiverAudioSubscription。该消息表示参与者希望从桥接器接收哪些音频源。它包含两个字段:

type ReceiverAudioSubscription = {
  mode: "All" | "None" | "Include" | "Exclude";
  list?: string[];
};
  • All– 订阅所有音频源
  • None– 不接收任何音频
  • Include– 仅接收list列出的来源
  • Exclude– 接收除list中列出的音频源之外的所有音频

list字段仅适用于 IncludeExclude操作。默认情况下,所有参与者均处于 All模式,这意味着除非发送订阅消息,否则所有音频源都会被转发(保留旧行为)。例如:

{ "colibriClass": "ReceiverAudioSubscription", "mode": "All" }
{ "colibriClass": "ReceiverAudioSubscription", "mode": "Include", "list": ["alice-a0", "bob-a0"] }

这种消息格式定义了客户端和 Videobridge 之间的契约:客户端描述他们想要什么,然后桥接器强制执行它。

客户端支持

在客户端方面,lib-jitsi-meet PR #2869 新增了对音频订阅的支持。应用程序现可通过简单 API 调用发送 ReceiverAudioSubscription 消息。主要入口点为:

conference.setAudioSubscriptionMode({
  mode: "Include",
  list: ["alice-a0", "bob-a0"]
});

这指示桥接器仅将来自 Alice 和 Bob 的流转发到本地客户端。为了方便起见,还有一个用于 deafen 功能的更高级方法:

conference.muteRemoteAudio(true);  // equivalent to { mode: "None" }
conference.muteRemoteAudio(false); // equivalent to { mode: "All" }

在内部,lib-jitsi-meet 将这些调用转换为通过桥接通道发送的 JSON 消息。如果调用IncludeExclude时传入一个空列表,客户端库会自动将请求强制转换为NoneAll。这避免了发送无操作消息,并保持了行为的一致性。

后端支持

在后端,Jitsi Videobridge 接收ReceiverAudioSubscription消息并执行相关操作。每个会议都有一个AudioSubscriptionManager,用于跟踪所有参与者的订阅。对于每个传入的 RTP 数据包,它会根据参与者当前的订阅模式决定哪些参与者应该接收该数据包。

Jitsi Videobridge中的订阅管理

在 Videobridge 中,每个会议都配备专属的 AudioSubscriptionManager 类。该类负责维护所有参与者的订阅状态,并对每个传入数据包进行判定:哪些参与者应接收该数据包,哪些不应接收。

上述机制看似简单,但实际实现中面临两大挑战:与“route-loudest-only”选项的兼容性问题,以及多桥接与网状网络场景的处理难题。

与 route-loudest-only 共存

Videobridge 提供名为 route-loudest-only 的配置选项。启用后,系统仅转发音量最大的三个音频源。此过滤机制在数据包处理管道的早期阶段生效,优先于其他处理流程。为确保与该设置共存,Videobridge 保证显式订阅的音源始终被转发,不受其音量大小影响。例如在分组讨论场景中,即使参与者均非音量最大的发言者,仍需确保彼此能听见对方。若无特殊处理,route-loudest-only=true 设置会使这些音频流在订阅逻辑生效前即被丢弃。

为解决此问题,预解密音量检测机制已扩展为同时验证是否存在明确订阅该音源的参与者。由于该检测需对每个传入数据包执行,必须具备极高效率。为此,AudioSubscriptionManager 预先计算并存储明确订阅音源的集合,使数据包处理过程中的检测可实现常数时间完成。

Multi-Bridge 会议

在大型会议中,Jitsi Meet 通常部署多个以网状结构连接的 Videobridge 服务器。连接到一个网桥的参与者可以订阅托管在另一个网桥上的源(“远程源”)。但是,订阅不会自动跨网桥传播。

为了解决这个问题,我们引入了两个新的桥间信令消息:AddAudioSubscriptionRemoveAudioSubscription

  • 当参与者订阅远程音频源时,该桥接器上的首次订阅会向拥有该音频源的桥接器触发一条AddAudioSubscription消息。
  • 相反,当删除对远程源的最后一个订阅时,RemoveAudioSubscription将发送。

这确保了订阅状态以最小的信令开销在网格中传播。同样的机制也适用于“接收方”端点——这些端点本身不发送媒体,只接收流(详情请参阅此文)。当桥接器收到一个AddAudioSubscription时,它首先检查源是否属于其直连的参与者之一。

如果是,则更新其AudioSubscriptionManager;如果不是,则将消息转发给可能托管源的桥接器。这种传播机制允许来自接收方端点的订阅(即使这些端点并非直接连接到网格)到达正确的桥接器。

总结

有了这种新的订阅模式,客户现在可以像以往的视频订阅一样选择接收哪些音频源。该功能支持分组讨论室、静音和大型会议中的选择性转发等用例。该 API 也将很快在服务器端上线,以便您在此基础上构建自定义功能。

内容源自:https://jitsi.org/blog/introducing-receiver-audio-subscriptions/

本文来自作者投稿,版权归原作者所有。如需转载,请注明出处:https://www.nxrte.com/jishu/yinshipin/62052.html

(0)

相关推荐

发表回复

登录后才能评论