跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++大前端

WebRTC 源码解析:应用层 API 功能实现

综述由AI生成深入解析 WebRTC 源码架构,重点介绍应用层如何通过核心 API(getUserMedia、RTCPeerConnection 等)实现音视频通信。文章梳理了 API 层与核心引擎层的交互流程,包括媒体流获取、连接建立、SDP 协商及 ICE 候选交换。同时剖析了关键 C++ 源码文件(如 peerconnectioninterface.h)的结构与作用,并详细阐述了信令机制在会话建立中的原理与异常处理策略。

编程诗人发布于 2026/4/6更新于 2026/5/2023 浏览
WebRTC 源码解析:应用层 API 功能实现

1. WebRTC 层级定位与核心功能

WebRTC 为应用层提供了四个核心 API,这些 API 是构建实时通信应用的基础:

API功能关键作用浏览器兼容性
getUserMedia获取本地音视频流访问摄像头、麦克风等硬件设备Chrome, Firefox, Edge, Safari
RTCPeerConnection建立点对点连接管理连接、交换媒体数据、处理 ICE 候选Chrome, Firefox, Edge, Safari
RTCDataChannel传输任意数据实现文本、文件等非媒体数据传输Chrome, Firefox, Edge
getDisplayMedia获取屏幕共享流实现屏幕共享功能Chrome, Firefox

1.1 WebRTC API 的层级定位

WebRTC API 位于API 层,是应用层与核心引擎层之间的桥梁。应用层通过调用这些 API,无需了解底层实现细节,即可实现复杂的实时通信功能。

1.2 WebRTC API 的工作原理

WebRTC API 本质上是 JavaScript 接口,它封装了底层 WebRTC 核心引擎的功能。当应用层调用这些 API 时,WebRTC 引擎会执行以下操作:

  1. 通过系统接口层访问硬件设备
  2. 与核心引擎层交互,处理媒体流和网络连接
  3. 通过信令机制与其他端点交换连接信息

1.3 API 层的核心功能与作用

核心功能定位

功能说明重要性
标准化接口提供统一的 WebRTC API,使开发者无需关心底层实现⭐⭐⭐⭐⭐
复杂性封装将 ICE 候选收集、SDP 协商、媒体处理等复杂逻辑封装⭐⭐⭐⭐
生命周期管理管理 RTCPeerConnection 等对象的创建、使用和销毁⭐⭐⭐⭐
跨平台支持确保不同浏览器提供一致的 API 体验⭐⭐⭐
错误处理提供标准化的错误处理机制⭐⭐⭐

2. API 层关键源码应用层开发的基本流程

WebRTC 应用开发的完整流程可以概括为'获取媒体→建立连接→交换信令→处理媒体→数据传输'五个核心步骤:

应用层 │ ├── 1. 获取本地媒体流 (getUserMedia) │ ├── 2. 创建 RTCPeerConnection 实例 (RTCPeerConnection) │ ├── 3. 信令交换 (SDP 与 ICE 候选) │ ├── 3.1 创建 Offer │ ├── 3.2 发送 Offer 给对方 │ ├── 3.3 接收 Answer │ └── 3.4 交换 ICE 候选 │ ├── 4. 处理媒体流 (ontrack 事件) │ └── 5. 数据传输 (RTCDataChannel)

2.1 源码结构与目录组织

WebRTC 源码中 API 层主要位于 api/ 目录下:

api/
├── peerconnectioninterface.h
├── peerconnectionfactoryinterface.h
├── mediastreaminterface.h
├── datachannelinterface.h
├── sdp.h
├── ...
pc/
├── peerconnectioninterface.cc
├── peerconnectionfactory.cc
├── ...

2.2 关键源码文件解析

2.2.1 peerconnectioninterface.h - 核心接口
// api/peerconnectioninterface.h
// RTCPeerConnection 的核心接口定义
class RTCPeerConnectionInterface {
public:
    // 创建 offer
    virtual void CreateOffer(CreateSessionDescriptionObserver* observer,
                             const RTCOfferOptions* options) = 0;
    // 创建 answer
    virtual void CreateAnswer(CreateSessionDescriptionObserver* observer,
                              const RTCOfferOptions* options) = 0;
    // 设置远程描述
    virtual void SetRemoteDescription(SetSessionDescriptionObserver* observer,
                                      const SessionDescriptionInterface* desc) = 0;
    // 设置本地描述
    virtual void SetLocalDescription(SetSessionDescriptionObserver* observer,
                                     const SessionDescriptionInterface* desc) = 0;
    // 添加媒体轨道
    virtual void AddTrack(const rtc::scoped_refptr<MediaStreamTrackInterface>& track,
                          const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) = 0;
    // 添加 ICE 候选
    virtual void AddIceCandidate(const IceCandidateInterface* candidate) = 0;
    // 监听事件
    virtual void OnTrack(const rtc::scoped_refptr<TrackEvent>& event) = 0;
    // 获取连接状态
    virtual std::string iceConnectionState() const = 0;
    virtual std::string connectionState() const = 0;
    // ... 其他方法
};
  • 该接口定义了 WebRTC 的核心功能,是 API 层的'心脏'
  • 使用纯虚函数定义,由实现类具体实现
  • CreateSessionDescriptionObserver 等接口用于处理异步操作
  • 所有方法都设计为异步,避免阻塞 UI 线程
2.2.2 peerconnectionfactoryinterface.h - 工厂接口
// api/peerconnectionfactoryinterface.h
// PeerConnectionFactory 的接口定义
class PeerConnectionFactoryInterface {
public:
    // 创建 PeerConnection 对象
    virtual rtc::scoped_refptr<RTCPeerConnectionInterface> CreatePeerConnection(
        const PeerConnectionInterface::Options& options,
        const PeerConnectionInterface::RTCConfiguration& config,
        const std::vector<rtc::scoped_refptr<PeerConnectionInterface::IceServer>>& ice_servers) = 0;
    // 创建 DataChannel
    virtual rtc::scoped_refptr<RTCDataChannelInterface> CreateDataChannel(
        const std::string& label, const DataChannelInterface::Init& config) = 0;
    // 创建 MediaStream
    virtual rtc::scoped_refptr<MediaStreamInterface> CreateLocalMediaStream(
        const std::string& label) = 0;
    // 创建 MediaStreamTrack
    virtual rtc::scoped_refptr<MediaStreamTrackInterface> CreateVideoTrack(
        const std::string& id, VideoTrackSourceInterface* source) = 0;
    // ... 其他方法
};
  • 工厂接口负责创建 WebRTC 核心对象
  • CreatePeerConnection 是创建 RTCPeerConnection 的入口
  • 使用 scoped_refptr 管理对象生命周期,避免内存泄漏
  • RTCConfiguration 用于配置 ICE 服务器等连接参数
2.2.3 mediastreaminterface.h - 媒体流接口
// api/mediastreaminterface.h
// MediaStream API 的核心接口
class MediaStreamInterface {
public:
    // 获取媒体流 ID
    virtual std::string id() const = 0;
    // 获取媒体轨道列表
    virtual const std::vector<rtc::scoped_refptr<MediaStreamTrackInterface>>& GetAudioTracks() const = 0;
    virtual const std::vector<rtc::scoped_refptr<MediaStreamTrackInterface>>& GetVideoTracks() const = 0;
    // 添加媒体轨道
    virtual void AddTrack(const rtc::scoped_refptr<MediaStreamTrackInterface>& track) = 0;
    // 移除媒体轨道
    virtual void RemoveTrack(const rtc::scoped_refptr<MediaStreamTrackInterface>& track) = 0;
};

// MediaStreamTrack 的核心接口
class MediaStreamTrackInterface {
public:
    // 获取轨道 ID
    virtual std::string id() const = 0;
    // 获取轨道类型
    virtual std::string kind() const = 0;
    // 获取轨道状态
    virtual std::string state() const = 0;
    // 获取轨道的媒体源
    virtual MediaStreamSourceInterface* GetSource() const = 0;
};
  • 提供了媒体流和媒体轨道的标准接口
  • getUserMedia() API 最终会调用这些接口
  • MediaStreamTrack 是媒体流的基本单元,可以是音频或视频
2.2.4 sdp.h - SDP 处理接口
// api/sdp.h
// SDP 处理核心接口
class SessionDescriptionInterface {
public:
    // 获取 SDP 类型
    virtual SdpType type() const = 0;
    // 获取 SDP 内容
    virtual std::string ToString() const = 0;
    // 获取 SDP 的媒体描述
    virtual const std::vector<MediaDescriptionInterface*>& GetMediaDescriptions() const = 0;
};

// SDP 解析器接口
class SdpParseError {
public:
    // 错误类型
    enum Type { kNoError, kInvalidFormat, kInvalidMLine, kInvalidAttribute /*...*/ };
};

// SDP 解析器
class SdpParse {
public:
    // 解析 SDP 字符串
    static rtc::scoped_refptr<SessionDescriptionInterface> ParseSdp(
        const std::string& sdp, SdpParseError* error);
    // 生成 SDP 字符串
    static std::string GenerateSdp(const SessionDescriptionInterface* desc);
};
  • SDP(Session Description Protocol)是 WebRTC 信令交换的核心
  • SdpParse 类负责 SDP 的解析和生成
  • SessionDescriptionInterface 是 SDP 的抽象表示
2.2.5 peerconnectioninterface.cc - 实现层
// pc/peerconnectioninterface.cc
// RTCPeerConnection 的实现
class PeerConnection : public RTCPeerConnectionInterface {
public:
    PeerConnection(const PeerConnectionInterface::Options& options,
                   const PeerConnectionInterface::RTCConfiguration& config,
                   const std::vector<rtc::scoped_refptr<IceServer>>& ice_servers) {
        Initialize(options, config, ice_servers);
    }

    // 创建 offer
    void CreateOffer(CreateSessionDescriptionObserver* observer,
                     const RTCOfferOptions* options) override {
        // 1. 创建 SDP Offer
        SessionDescriptionInterface* offer = CreateOfferInternal(options);
        // 2. 设置本地描述
        if (offer) SetLocalDescriptionInternal(offer);
        // 3. 通过 Observer 返回结果
        if (observer) observer->OnSuccess(offer);
    }

    // 设置本地描述
    void SetLocalDescription(SetSessionDescriptionObserver* observer,
                             const SessionDescriptionInterface* desc) override {
        // 1. 更新本地描述状态
        local_desc_ = desc;
        // 2. 生成 ICE 候选
        GenerateIceCandidates();
        // 3. 通知核心引擎
        core_engine_->SetLocalDescription(desc);
        // 4. 通过 Observer 通知应用层
        if (observer) observer->OnSuccess();
    }

    // 添加 ICE 候选
    void AddIceCandidate(const IceCandidateInterface* candidate) override {
        // 1. 添加候选到内部列表
        ice_candidates_.push_back(candidate);
        // 2. 通知核心引擎
        core_engine_->AddIceCandidate(candidate);
    }

private:
    SessionDescriptionInterface* local_desc_ = nullptr;
    SessionDescriptionInterface* remote_desc_ = nullptr;
    std::vector<rtc::scoped_refptr<IceCandidateInterface>> ice_candidates_;
    std::unique_ptr<CoreEngine> core_engine_;

    void Initialize(const PeerConnectionInterface::Options& options,
                    const PeerConnectionInterface::RTCConfiguration& config,
                    const std::vector<rtc::scoped_refptr<IceServer>>& ice_servers) {
        // 1. 创建核心引擎
        core_engine_ = std::make_unique<CoreEngine>(config, ice_servers);
        // 2. 设置内部状态
    }
};
  • PeerConnection 类实现了 RTCPeerConnectionInterface 接口
  • 所有 API 方法都调用内部 core_engine_ 进行实际操作
  • 使用 scoped_refptr 管理对象生命周期
  • 通过 Observer 模式处理异步操作
2.2.6 peerconnectionfactory.cc - 工厂实现
// pc/peerconnectionfactory.cc
// PeerConnectionFactory 的实现
class PeerConnectionFactory : public PeerConnectionFactoryInterface {
public:
    // 创建 PeerConnection
    rtc::scoped_refptr<RTCPeerConnectionInterface> CreatePeerConnection(
        const PeerConnectionInterface::Options& options,
        const PeerConnectionInterface::RTCConfiguration& config,
        const std::vector<rtc::scoped_refptr<PeerConnectionInterface::IceServer>>& ice_servers) override {
        // 1. 创建 PeerConnection 对象
        PeerConnection* pc = new PeerConnection(options, config, ice_servers);
        // 2. 初始化内部状态
        pc->Initialize();
        // 3. 返回封装对象
        return rtc::scoped_refptr<RTCPeerConnectionInterface>(pc);
    }

    // 创建 DataChannel
    rtc::scoped_refptr<RTCDataChannelInterface> CreateDataChannel(
        const std::string& label, const DataChannelInterface::Init& config) override {
        // 实现 DataChannel 创建逻辑
        // ...
    }
};
  • 工厂方法负责创建和初始化 PeerConnection 对象
  • 使用 scoped_refptr 确保对象生命周期安全
  • 实现了 PeerConnectionFactoryInterface 接口

3. API 层工作流程详解

3.1 API 层交互流程

应用层 (JavaScript) -> API 层 (WebRTC API) -> 核心引擎层 (C++)
1. new RTCPeerConnection()
2. 调用 PeerConnectionFactory::CreatePeerConnection()
3. 创建 PeerConnection 对象
4. 返回 PeerConnection 实例
5. 返回 RTCPeerConnection 实例
6. getUserMedia()
7. 调用 MediaStreamInterface 实现
8. 获取媒体设备
9. 返回媒体流
10. 返回 MediaStream 对象
11. createOffer()
12. 调用 PeerConnection::CreateOffer()
13. 生成 SDP Offer
14. 返回 SDP Offer
15. 返回 Offer SDP
16. setLocalDescription()
17. 调用 PeerConnection::SetLocalDescription()
18. 更新连接状态
19. 确认设置
20. 确认设置
21. addTrack()
22. 调用 PeerConnection::AddTrack()
23. 添加媒体轨道
24. 确认添加
25. 确认添加
26. onicecandidate 事件处理
27. 监听 ICE 候选
28. 收集 ICE 候选
29. 触发 onicecandidate 事件

3.2 详细工作流程

3.2.1 创建 RTCPeerConnection

JavaScript 应用层代码:

const pc = new RTCPeerConnection({
    iceServers: [{ urls: "stun:stun.l.google.com:19302" }]
});

API 层工作流程:

  1. 应用层调用 new RTCPeerConnection()
  2. API 层调用 PeerConnectionFactory::CreatePeerConnection()
  3. 工厂创建 PeerConnection 对象
  4. 初始化内部状态(包括 ICE 服务器配置)
  5. 返回封装的 RTCPeerConnectionInterface 对象

关键源码:

// pc/peerconnectionfactory.cc
rtc::scoped_refptr<RTCPeerConnectionInterface>
PeerConnectionFactory::CreatePeerConnection(
    const PeerConnectionInterface::Options& options,
    const PeerConnectionInterface::RTCConfiguration& config,
    const std::vector<rtc::scoped_refptr<PeerConnectionInterface::IceServer>>& ice_servers) {
    // 创建 PeerConnection 对象
    PeerConnection* pc = new PeerConnection(options, config, ice_servers);
    // 初始化内部状态
    pc->Initialize();
    // 返回封装对象
    return rtc::scoped_refptr<RTCPeerConnectionInterface>(pc);
}
3.2.2 获取媒体流

JavaScript 应用层代码:

const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });

API 层工作流程:

  1. 应用层调用 getUserMedia()
  2. API 层调用 MediaStreamInterface 实现
  3. 调用底层 C++ API 获取媒体设备
  4. 返回媒体流对象

关键源码:

// api/mediastreaminterface.h
class MediaStreamInterface {
public:
    static rtc::scoped_refptr<MediaStreamInterface> CreateLocalMediaStream(const std::string& label);
};

// 实现部分
rtc::scoped_refptr<MediaStreamInterface>
MediaStreamInterface::CreateLocalMediaStream(const std::string& label) {
    return CreateLocalMediaStreamInternal(label);
}
3.2.3 SDP 协商过程

JavaScript 应用层代码:

const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
signalingServer.send({ type: "offer", sdp: offer.sdp });

API 层工作流程:

  1. 应用层调用 createOffer()
  2. API 层调用 PeerConnection::CreateOffer()
  3. 内部调用 CreateOfferInternal() 生成 SDP Offer
  4. 调用 SetLocalDescriptionInternal() 设置本地描述
  5. 通过 Observer 返回结果

关键源码:

// pc/peerconnectioninterface.cc
void PeerConnection::CreateOffer(CreateSessionDescriptionObserver* observer,
                                 const RTCOfferOptions* options) {
    SessionDescriptionInterface* offer = CreateOfferInternal(options);
    if (offer) SetLocalDescriptionInternal(offer);
    if (observer) observer->OnSuccess(offer);
}

SessionDescriptionInterface* PeerConnection::CreateOfferInternal(const RTCOfferOptions* options) {
    // 实际 SDP 生成逻辑
    return new SessionDescription(offer_sdp);
}

void PeerConnection::SetLocalDescriptionInternal(SessionDescriptionInterface* desc) {
    local_desc_ = desc;
    GenerateIceCandidates();
    core_engine_->SetLocalDescription(desc);
}
3.2.4 ICE 候选交换

JavaScript 应用层代码:

pc.onicecandidate = event => {
    if (event.candidate) {
        signalingServer.send({ type: "candidate", candidate: event.candidate });
    }
};

API 层工作流程:

  1. 应用层监听 onicecandidate 事件
  2. API 层在内部收集 ICE 候选
  3. 通过 onicecandidate 事件通知应用层
  4. 应用层将候选发送到信令服务器

关键源码:

// pc/peerconnectioninterface.cc
void PeerConnection::GenerateIceCandidates() {
    std::vector<IceCandidateInterface*> candidates;
    core_engine_->GetIceCandidates(&candidates);
    for (auto& candidate : candidates) {
        OnIceCandidate(candidate);
    }
}

void PeerConnection::OnIceCandidate(const IceCandidateInterface* candidate) {
    if (ice_candidate_observer_) {
        ice_candidate_observer_->OnIceCandidate(candidate);
    }
}

4. 信令机制

4.1 信令机制的核心作用与原理

信令模块是 WebRTC 核心引擎层的关键组成部分,负责处理 WebRTC 会话的建立、协商和管理。信令模块的主要作用是交换 SDP(Session Description Protocol)描述和 ICE 候选地址,以建立 P2P 连接。

WebRTC 本身不提供信令机制,需要开发者实现自己的信令服务器。虽然 WebRTC核心源码本身不包含完整的信令服务器实现,但这是设计层面的刻意选择:

  • 核心原因:WebRTC 标准只定义了「实时媒体传输」的核心逻辑,但信令协议是完全开放的(可以用 WebSocket/HTTP/GRPC 等任意协议),因此 Google 没有在核心库中固化某一种信令实现。
  • 源码中的相关部分:WebRTC 源码提供了信令交互所需的「数据结构和接口」(如 SDP 解析、ICE 候选者交换的结构体),但不会实现信令的收发、转发逻辑。

实际开发:信令服务器需要开发者自行实现(或使用开源方案如 Janus/Mediasoup/OpenVidu),核心职责是转发 SDP、ICE 候选者、房间控制指令等。

信令服务器用于交换以下关键信息:

  1. SDP (Session Description Protocol):会话描述信息,包含媒体格式、编解码器等
  2. ICE Candidates:网络地址信息,用于建立 P2P 连接

信令机制的核心原理

WebRTC 的信令机制是'桥梁',连接两个对等端。它不负责媒体传输,只负责交换建立连接所需的信息。信令机制包括以下关键步骤:

  1. 初始化:双方建立连接
  2. Offer/Answer:协商媒体能力
  3. ICE 候选交换:确定网络路径
  4. 连接建立:P2P 连接成功

信令模块的作用:

  1. 会话协商:通过 SDP 交换,协商双方支持的媒体类型、编解码器、分辨率等参数
  2. 网络信息交换:交换 ICE 候选地址,用于 NAT 穿透和建立 P2P 连接
  3. 连接管理:管理连接状态,处理连接断开和重连
  4. 媒体流控制:控制媒体流的添加、删除和修改
  5. 错误处理:处理连接过程中的错误和异常情况

4.2 关键源码文件及作用

信令模块的核心代码位于 webrtc/pc 和 webrtc/api 目录下,以下是关键文件及其作用:

4.2.1 peer_connection.h 和 peer_connection_impl.h
// webrtc/pc/peer_connection.h
class RTCPeerConnection {
public:
    static std::unique_ptr<RTCPeerConnection> Create(const PeerConnectionInterface::Options& options);
    virtual void CreateOffer(CreateSessionDescriptionObserver* observer,
                             const RTCOfferAnswerOptions* options = nullptr) = 0;
    virtual void CreateAnswer(CreateSessionDescriptionObserver* observer,
                              const RTCOfferAnswerOptions* options = nullptr) = 0;
    virtual void SetLocalDescription(SetSessionDescriptionObserver* observer,
                                     SessionDescriptionInterface* desc) = 0;
    virtual void SetRemoteDescription(SetSessionDescriptionObserver* observer,
                                      SessionDescriptionInterface* desc) = 0;
    virtual void AddIceCandidate(const IceCandidateInterface* candidate) = 0;
    virtual void GetIceCandidates(std::vector<IceCandidateInterface*>* candidates) = 0;
    virtual void OnIceConnectionStateChange(IceConnectionState state) = 0;
};

作用:定义 RTCPeerConnection 接口,实现信令交互的核心功能,包括创建 offer/answer、设置本地/远程描述、添加 ICE 候选等。

4.2.2 session_description.h 和 session_description_impl.h
// webrtc/pc/session_description.h
class SessionDescriptionInterface {
public:
    virtual SessionDescriptionType type() const = 0;
    virtual const std::string& ToString() const = 0;
    virtual const std::vector<MediaContentDescriptionInterface*>& contents() const = 0;
};

作用:定义 SDP 会话描述的接口,用于表示 offer 和 answer 的媒体信息,包括编解码器、分辨率、带宽等参数。

4.2.3 ice_candidate.h 和 ice_candidate_impl.h
// webrtc/pc/ice_candidate.h
class IceCandidateInterface {
public:
    virtual const std::string& candidate() const = 0;
    virtual const std::string& sdp_mid() const = 0;
    virtual int sdp_mline_index() const = 0;
};

作用:定义 ICE 候选的接口,用于表示 NAT 穿透过程中收集的候选地址,包括 Host 候选、Server Reflexive 候选和 Relay 候选。

4.2.4 signaling_channel.h 和 signaling_channel_impl.h
// webrtc/pc/signaling_channel.h
class SignalingChannel {
public:
    virtual ~SignalingChannel() {}
    virtual void SendOffer(const SessionDescriptionInterface* offer) = 0;
    virtual void SendAnswer(const SessionDescriptionInterface* answer) = 0;
    virtual void SendLocalDescription(const SessionDescriptionInterface* desc) = 0;
    virtual void SendIceCandidate(const IceCandidateInterface* candidate) = 0;
    virtual void SetMessageHandler(std::function<void(const SignalingMessage&)> handler) = 0;
};

作用:定义信令通道的接口,用于实现具体的信令传输方式(如 WebSocket、MQTT 等),将 SDP 和 ICE 候选通过信令服务器发送给对端。

4.3 与其他模块的交互

4.3.1 与传输模块的交互
  • 信令模块创建 RTCPeerConnection 实例
  • 传输模块初始化 RTP/RTCP 和 ICE
  • 传输模块收集 ICE 候选并返回给信令模块
  • 信令模块将 ICE 候选通过信令服务器交换给对方
  • 信令模块设置对方的 ICE 候选给传输模块
  • 传输模块建立 P2P 连接
4.3.2 与媒体引擎的交互
  • 信令模块创建 RTCPeerConnection 实例
  • 媒体引擎初始化并采集媒体流
  • 信令模块生成 SDP offer 并交换
  • 信令模块设置远程描述
  • 媒体引擎根据远程描述配置媒体处理

4.4 源码示例

4.4.1 RTCPeerConnection 实现
// webrtc/pc/peer_connection_impl.cc
class RTCPeerConnectionImpl : public RTCPeerConnection {
public:
    RTCPeerConnectionImpl(const PeerConnectionInterface::Options& options)
        : options_(options), signaling_thread_(nullptr), transport_(nullptr), media_engine_(nullptr) {
        signaling_thread_ = new rtc::Thread("SignalingThread");
        signaling_thread_->Start();
        transport_ = new Transport();
        transport_->Init();
        media_engine_ = new MediaEngine();
        media_engine_->Init();
    }

    void CreateOffer(CreateSessionDescriptionObserver* observer,
                     const RTCOfferAnswerOptions* options) override {
        SessionDescriptionInterface* offer = media_engine_->CreateOffer(options);
        local_description_ = offer;
        if (signaling_channel_) signaling_channel_->SendOffer(offer);
        observer->OnSuccess(offer);
    }

    void CreateAnswer(CreateSessionDescriptionObserver* observer,
                      const RTCOfferAnswerOptions* options) override {
        SessionDescriptionInterface* answer = media_engine_->CreateAnswer(options);
        local_description_ = answer;
        if (signaling_channel_) signaling_channel_->SendAnswer(answer);
        observer->OnSuccess(answer);
    }

    void SetLocalDescription(SetSessionDescriptionObserver* observer,
                             SessionDescriptionInterface* desc) override {
        local_description_ = desc;
        if (signaling_channel_) signaling_channel_->SendLocalDescription(desc);
        observer->OnSuccess();
    }

    void SetRemoteDescription(SetSessionDescriptionObserver* observer,
                              SessionDescriptionInterface* desc) override {
        remote_description_ = desc;
        media_engine_->SetRemoteDescription(desc);
        transport_->SetRemoteDescription(desc);
        observer->OnSuccess();
    }

    void AddIceCandidate(const IceCandidateInterface* candidate) override {
        ice_candidates_.push_back(candidate);
        if (signaling_channel_) signaling_channel_->SendIceCandidate(candidate);
    }

    void OnIceConnectionStateChange(IceConnectionState state) override {
        ice_connection_state_ = state;
        if (ice_connection_state_observer_) {
            ice_connection_state_observer_->OnIceConnectionStateChange(state);
        }
    }

private:
    PeerConnectionInterface::Options options_;
    rtc::Thread* signaling_thread_;
    Transport* transport_;
    MediaEngine* media_engine_;
    SessionDescriptionInterface* local_description_;
    SessionDescriptionInterface* remote_description_;
    std::vector<IceCandidateInterface*> ice_candidates_;
    IceConnectionState ice_connection_state_;
    IceConnectionStateObserver* ice_connection_state_observer_;
    SignalingChannel* signaling_channel_;
};
  • RTCPeerConnectionImpl 是 RTCPeerConnection 的实现类
  • 通过组合模式管理传输模块、媒体引擎和信令通道
  • CreateOffer() 和 CreateAnswer() 生成 SDP 描述
  • SetLocalDescription() 和 SetRemoteDescription() 设置本地和远程描述
  • AddIceCandidate() 添加 ICE 候选
  • OnIceConnectionStateChange() 处理 ICE 连接状态变化
4.4.2 信令通道实现
// webrtc/pc/signaling_channel_impl.h
class WebSocketSignalingChannel : public SignalingChannel {
public:
    WebSocketSignalingChannel(const std::string& url) : url_(url), socket_(nullptr) {
        Connect();
    }

    void SendOffer(const SessionDescriptionInterface* offer) override {
        SignalingMessage message;
        message.type = "sdp_offer";
        message.data = offer->ToString();
        Send(message);
    }

    void SendAnswer(const SessionDescriptionInterface* answer) override {
        SignalingMessage message;
        message.type = "sdp_answer";
        message.data = answer->ToString();
        Send(message);
    }

    void SendLocalDescription(const SessionDescriptionInterface* desc) override {
        SignalingMessage message;
        message.type = "sdp_local";
        message.data = desc->ToString();
        Send(message);
    }

    void SendIceCandidate(const IceCandidateInterface* candidate) override {
        SignalingMessage message;
        message.type = "ice_candidate";
        message.data = candidate->candidate();
        message.sdp_mid = candidate->sdp_mid();
        message.sdp_mline_index = candidate->sdp_mline_index();
        Send(message);
    }

    void SetMessageHandler(std::function<void(const SignalingMessage&)> handler) override {
        message_handler_ = handler;
    }

private:
    void Connect() {
        socket_ = new WebSocket(url_);
        socket_->SetMessageHandler([this](const std::string& message) {
            SignalingMessage msg;
            ParseMessage(message, &msg);
            if (message_handler_) message_handler_(msg);
        });
    }

    void Send(const SignalingMessage& message) {
        std::string json = SerializeMessage(message);
        socket_->Send(json);
    }

    std::string url_;
    WebSocket* socket_;
    std::function<void(const SignalingMessage&)> message_handler_;
};
  • SignalingChannel 是信令通道的接口类
  • WebSocketSignalingChannel 是 WebSocket 信令通道的实现类
  • SendOffer() 和 SendAnswer() 发送 SDP offer 和 answer
  • SendIceCandidate() 发送 ICE 候选
  • SetMessageHandler() 设置消息处理回调
  • 信令通道负责将 SDP 和 ICE 候选通过 WebSocket 发送给对端

4.5 信令模块工作时序

参与者 A -> 信令模块 -> 信令服务器 -> 信令模块 -> 参与者 B
1. 创建 RTCPeerConnection
2. 采集媒体流
3. CreateOffer -> 生成 SDP offer
4. 发送 SDP offer -> 转发 SDP offer
5. 创建 RTCPeerConnection
6. 采集媒体流
7. CreateAnswer -> 生成 SDP answer
8. 发送 SDP answer -> 转发 SDP answer
9. SetRemoteDescription -> 配置媒体引擎
10. AddIceCandidate -> 收集 ICE 候选
11. 通过 STUN 获取公网 IP -> 返回 ICE 候选
12. 发送 ICE 候选 -> 转发 ICE 候选
13. AddIceCandidate -> 设置 ICE 候选
14. 尝试建立 P2P 连接 -> 连接成功
15. 通知连接状态 -> 通知连接状态
16. 接收媒体流 -> 接收媒体流

4.6 信令模块核心流程

  1. 参与者 A:创建 RTCPeerConnection,采集媒体流,生成 SDP offer,通过信令服务器发送 offer
  2. 参与者 B:接收 offer,生成 SDP answer,通过信令服务器发送 answer
  3. 参与者 A:接收 answer,设置远程描述,配置媒体引擎,收集 ICE 候选,通过 STUN 获取公网 IP,发送 ICE 候选
  4. 参与者 B:接收 ICE 候选,设置 ICE 候选,尝试建立 P2P 连接,连接成功,传输媒体流

4.7 信令模块的关键技术

4.7.1 SDP(Session Description Protocol)

SDP 是 WebRTC 信令的核心,用于描述媒体会话的参数,包括:

  • 会话名称
  • 会话时间
  • 媒体类型(音频、视频)
  • 编解码器
  • 分辨率
  • 带宽
  • ICE 候选地址

SDP 格式示例:

v=0 o=- 123456 1 IN IP4 127.0.0.1 s=- t=0 0 m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 c=IN IP4 192.168.1.100 a=rtcp:9 IN IP4 192.168.1.100 a=rtpmap:111 opus/48000/2 a=fmtp:111 minptime=10;useinbandfec=1 a=sendrecv
4.7.2 ICE 候选交换

ICE 候选是 NAT 穿透的关键,包括:

  • Host Candidate:本地网络地址
  • Server Reflexive Candidate:NAT 反射地址
  • Relay Candidate:TURN 中继地址

ICE 候选格式示例:

candidate:1 1 udp 2130706431 192.168.1.100 54321 typ host
candidate:2 1 udp 1686052607 203.0.113.1 54321 typ srflx raddr 192.168.1.100 rport 54321
candidate:3 1 udp 1500000000 198.51.100.1 54321 typ relay raddr 192.168.1.100 rport 54321
4.7.3 信令协议

WebRTC 没有定义具体的信令协议,开发者可以使用各种方式,如:

  • WebSocket
  • XMPP
  • SIP
  • HTTP
  • MQTT

信令消息格式示例:

{"type":"sdp_offer","data":"v=0\r\no=- 123456 1 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\nm=audio 9 UDP/TLS/RTP/SAVPF 111 103 104\r\nc=IN IP4 192.168.1.100\r\na=rtcp:9 IN IP4 192.168.1.100\r\na=rtpmap:111 opus/48000/2\r\na=fmtp:111 minptime=10;useinbandfec=1\r\na=sendrecv\r\n"}

4.8 信令模块的异常处理

4.8.1 连接失败处理
pc.oniceconnectionstatechange = () => {
    if (pc.iceconnectionstate() == "disconnected") {
        restartIce();
    }
};

function restartIce() {
    const offer = pc.createoffer();
    pc.setlocaldescription(offer);
    signaling_channel_->sendoffer(offer);
}

关键点:

  • 监听 ICE 连接状态变化
  • 当连接断开时,重新发起 ICE 协商
  • 创建新的 offer 并发送给对端
4.8.2 媒体流中断处理
pc.addeventlistener("negotiationneeded", () => {
    const transceiver = pc.gettransceivers()[0];
    transceiver.setcodecpreferences(filtercodecs("vp9"));
});

关键点:

  • 监听 negotiationneeded 事件
  • 当媒体流中断时,切换编解码器
  • 优先使用高效的编解码器如 VP9

4.9 信令模块的未来发展方向

更高效的信令协议

WebRTC 信令模块将采用更高效的信令协议:

  • MQTT:轻量级消息传输协议,适合低带宽环境
  • QUIC:基于 UDP 的多路复用传输协议,减少连接建立时间
  • WebTransport:基于 Web 标准的传输协议,支持更丰富的信令功能

AI 增强的信令处理

WebRTC 信令模块将集成 AI 技术,实现更智能的信令处理:

  • AI 信令优化:使用 AI 算法优化信令消息的发送和处理
  • AI 连接预测:使用 AI 算法预测连接状态,提前进行优化
  • AI 异常检测:使用 AI 算法检测连接异常,自动进行处理

信令与边缘计算结合

WebRTC 信令模块将与边缘计算结合,实现更高效的信令处理:

  • 边缘信令服务器:在边缘节点部署信令服务器,减少延迟
  • 本地信令处理:在设备端进行部分信令处理,减少对中心服务器的依赖
  • 分布式信令网络:构建分布式信令网络,提高信令处理的可靠性和效率

目录

  1. 1. WebRTC 层级定位与核心功能
  2. 1.1 WebRTC API 的层级定位
  3. 1.2 WebRTC API 的工作原理
  4. 1.3 API 层的核心功能与作用
  5. 2. API 层关键源码应用层开发的基本流程
  6. 2.1 源码结构与目录组织
  7. 2.2 关键源码文件解析
  8. 2.2.1 peerconnectioninterface.h - 核心接口
  9. 2.2.2 peerconnectionfactoryinterface.h - 工厂接口
  10. 2.2.3 mediastreaminterface.h - 媒体流接口
  11. 2.2.4 sdp.h - SDP 处理接口
  12. 2.2.5 peerconnectioninterface.cc - 实现层
  13. 2.2.6 peerconnectionfactory.cc - 工厂实现
  14. 3. API 层工作流程详解
  15. 3.1 API 层交互流程
  16. 3.2 详细工作流程
  17. 3.2.1 创建 RTCPeerConnection
  18. 3.2.2 获取媒体流
  19. 3.2.3 SDP 协商过程
  20. 3.2.4 ICE 候选交换
  21. 4. 信令机制
  22. 4.1 信令机制的核心作用与原理
  23. 4.2 关键源码文件及作用
  24. 4.2.1 peerconnection.h 和 peerconnection_impl.h
  25. 4.2.2 sessiondescription.h 和 sessiondescription_impl.h
  26. 4.2.3 icecandidate.h 和 icecandidate_impl.h
  27. 4.2.4 signalingchannel.h 和 signalingchannel_impl.h
  28. 4.3 与其他模块的交互
  29. 4.3.1 与传输模块的交互
  30. 4.3.2 与媒体引擎的交互
  31. 4.4 源码示例
  32. 4.4.1 RTCPeerConnection 实现
  33. 4.4.2 信令通道实现
  34. 4.5 信令模块工作时序
  35. 4.6 信令模块核心流程
  36. 4.7 信令模块的关键技术
  37. 4.7.1 SDP(Session Description Protocol)
  38. 4.7.2 ICE 候选交换
  39. 4.7.3 信令协议
  40. 4.8 信令模块的异常处理
  41. 4.8.1 连接失败处理
  42. 4.8.2 媒体流中断处理
  43. 4.9 信令模块的未来发展方向
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • HTML 基础语法与常用标签详解
  • Python 与 PyCharm 虚拟环境搭建及实战指南
  • OpenClaw(龙虾)如何掀起 AI 智能体革命
  • 汽车雷达多径环境下幽灵目标检测算法
  • 人形全身 VLA 模型Ψ0:人类视频预训练与流匹配动作专家
  • 大语言模型 (LLM) 分布式高效训练技术综述:背景、并行、计算、内存、通信、容错、展望
  • Flutter 三方库 webrtc_interface 的鸿蒙化适配指南
  • 使用 Anthropic frontend-design skill 增强大模型前端设计审美
  • 基于 Ocelot+Nacos+WebAPI 的网关鉴权实现
  • Cogito-v1-preview-llama-3B:工业设备故障日志分析与维修建议
  • Java 微服务架构设计模式:构建云原生时代的分布式系统
  • Visual C++ 运行库缺失解决方案与安装指南
  • 国内主流大模型 API 调用指南与 Python 实战
  • MATLAB 与 Python 苹果检测技术对比:传统特征工程与深度学习
  • Rust 从入门到实战:读取命令行参数
  • 基于小米 9 手机搭建天马 G 复古掌机前端
  • 腾讯云部署 OpenClaw 对接飞书实战指南
  • Android 免 Root 自动抢红包工具 AutoRobRedPackage 使用指南
  • MS-S1 MAX 搭配 AI MAX 395 在 Ubuntu 24 下运行 gpt-oss 120B
  • PromptPilot 实战指南:自动化优化 AI 提示词与批量评测

相关免费在线工具

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online

  • JSON美化和格式化

    将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online