libdatachannel和libWebRTC对比

libdatachannel 和 libWebRTC 的简要比较

注意:此比较是在 2024 年年中进行的。

WebRTC (Web Real-Time Communication) 是数据、音频和视频流的标准。它可以在浏览器中使用,无需插件,并允许视频和语音聊天等功能实时运行。在浏览器中运行的应用程序可以使用由万维网联盟 (W3C) 和 Internet 工程任务组 (IETF) 标准化的 WebRTC Javascript API,以确保跨浏览器支持。

C++ 应用程序可以使用 Google 的 WebRTC 实现,我将其称为 libWebRTC,它在 Google Chrome 中使用。尽管它是大型且复杂的库,但它确实提供了一组全面的功能。

libdatachannel 是一种替代的开源 C++ WebRTC 实现。它比 libWebRTC 小得多,缺少许多 WebRTC 功能,但比 libWebRTC 使用简单得多。

易于构建和集成

构建 libdatachannel 相对简单。它使用 CMake 构建系统,开发人员可以通过克隆存储库、运行和执行 CMake 命令来构建。git submodule update --init

这与使用 Google 的 GN 构建系统的 libWebRTC 形成鲜明对比。GN 管理依赖项和配置,但在集成到其他项目时可能会带来挑战。事实上,仅同步 libWebRTC 就比 libdatachannel 的整个构建过程花费的时间要长。

libdatachannel 具有最少的依赖项,包括 libJuice,这是同一开发人员提供的用于 UDP NAT 遍历的美味开源项目。对于证书签名,该库可以在 OpenSSL(默认使用)、GnuTLS 或 Mbed TLS 之间切换。libWebRTC 依赖于数百个库。由于依赖项数量庞大,这可能会导致在集成到其他应用程序时出现符号冲突等问题。

在撰写本文时,编译后的 libdatachannel 库只有 20MB,而对于 Windows 版本,libWebRTC 为 600MB。

libdatachannel 提供了一些易于运行和演示视频和音频流式示例的可访问示例。他们提供 Python 脚本来设置信令和 Web 服务器以演示流式处理。libWebRTC 也提供了一些示例,尽管已经有关于一些问题的 bug 报告

代码差异

libdatachannel 更喜欢使用回调,而不是 libWebRTC 使用接口和继承。std::function

例如,libWebRTC 使用它希望用户实现的虚拟方法,如以下示例所示:PeerConnectionObserver

class PeerConnectionObserver {
 public:
    // Snippet from PeerConnectionObserver
    virtual void OnSignalingChange(PeerConnectionInterface::SignalingState new_state) = 0;
    virtual void OnDataChannel(rtc::scoped_refptr<DataChannelInterface> data_channel) = 0;
    virtual void OnIceConnectionChange(PeerConnectionInterface::IceConnectionState new_state) {}
    virtual void OnStandardizedIceConnectionChange(PeerConnectionInterface::IceConnectionState new_state) {}
    virtual void OnConnectionChange(PeerConnectionInterface::PeerConnectionState new_state) {}
    virtual void OnIceGatheringChange( PeerConnectionInterface::IceGatheringState new_state) = 0;
    virtual void OnIceCandidate(const IceCandidateInterface* candidate) = 0;
};

  相比之下,libdataChannel 用于回调,如下所示:std::functionPeerConnection

class PeerConnection final : CheshireCat<impl::PeerConnection> {
public:
    // Snippet from PeerConnection
    void onDataChannel(std::function<void(std::shared_ptr<DataChannel> dataChannel)> callback);
    void onLocalDescription(std::function<void(Description description)> callback);
    void onLocalCandidate(std::function<void(Candidate candidate)> callback);
    void onStateChange(std::function<void(State state)> callback);
    void onIceStateChange(std::function<void(IceState state)> callback);
    void onGatheringStateChange(std::function<void(GatheringState state)> callback);
    void onSignalingStateChange(std::function<void(SignalingState state)> callback);
};

  libdatachannel 旨在通过使用 PIMPL 惯用语(也称为 CheshireCat 技术)来维护稳定的 ABI。这种设计模式涉及将实现细节保存在一个单独的私有类中,从而允许接口保持不变,即使底层实现发生变化。

打包和编解码器支持

这两个库都提供了打包器,它获取视频数据并将这些数据拆分为多个数据包。它们还提供 de-packetizer 在接收端重新组装这些数据包。这是必需的,因为 Internet 数据包的大小有限,并且视频帧可以大于此数据包大小。此外,每个编解码器在如何转换为数据包方面都有不同的标准。

libdatachannel 支持 H.264 (AVC)、H.265 (HEVC) 和 AV1 的打包。但是,它缺少 VP8 和 VP9 支持。在解包方面,它仅支持 H.264。libdatachannel 不提供任何编码器或解码器,因此依赖于开发人员自带。

相比之下,libWebRTC 支持 H.264、VP8、VP9、AV1,并增加了对 H.265 的支持,用于打包和解包。这种支持与上述所有软件编码器和解码器相辅相成,同时还允许用户提供自己的编码器和解码器。

带宽估算和比特率

我发现 libdatachannel 中最缺少的功能是带宽估计和接收视频比特率请求。例如,libWebRTC 包括复杂的带宽估计,这对于保持最佳视频质量和在恶劣网络条件下最大限度地减少缓冲或中断至关重要。libWebRTC 将调用以提供它期望对视频进行编码的比特率,以保持在估计的带宽内。SetRates

libdatachannel 不管理带宽估计或比特率调整。开发者只是打电话,没有收到码率请求。这种更简单的方法适用于受控的网络条件或提供单个预编码视频或数据。send

结论

libdatachannel 的简单性是其最大的优势。对于只需要流式传输视频、音频或纯数据的开发人员来说,该库的简单使用使其具有吸引力。根据库的名称,当带宽不是一个问题时,它非常适合流式传输数据。它的小特性使其易于集成到项目中,并且该库还可以作为添加功能的良好基础。

该库缺少许多关键功能,如带宽估计、编解码器编码和解码支持,因此需要这些功能的项目可能更适合选择 Google 的 libWebRTC 实现。

但是,libdatachannel 会定期接收更新,并且正在添加功能。我期待看到库的进步和演变。

翻译自:https://tensorworks.com.au/blog/a-brief-comparison-of-libdatachannel-and-libwebrtc/

posted @ 2025-03-07 16:49  Smah  阅读(1274)  评论(0)    收藏  举报