环境

  • Ubuntu18.04
  • webrtc M84

国内镜像:https://webrtc.org.cn/mirror/

webrtc交互过程

通过peerconnection的例子来分析webrtc的交互流程

peer_connection 解析

  1. 为了便于管理,如编码,回显等,需要在应用层和底层一帧数据做一个桥接层,以隔离上下层。
  2. 桥接层的代码主要位于media/basemedia/engine,WebRTC中抽象了VideoSourceInterfaceVideoSinkInterface这两个模板类分别表示生产和吸收视频流。
  3. 如果能提供视频数据,需要实现 VideoSourceInterface,此接口类暴露了 AddOrUpdateSink 函数,可以将 Sink 注册给 Source
  4. 如果想要接收视频数据,需要实现 VideoSinkInterface,此接口类暴露了 OnFrame 函数。只要将 Sink 通过 AddOrUpdateSink 函数注册给 Source, 那么 Source 就会通过 OnFrame 接口将数据传给 Sink
  5. 对于WebRTC的PeerConnection例子,其VcmCapturer类继承了VideoSinkInterfaceTestVideoCapturer类继承类VideoSourceInterface<VideoFrame>

信令交互主要是PeerConnectionClient这个类 初始化socket连接跟 绑定回调

void PeerConnectionClient::InitSocketSignals() {
  control_socket_->SignalCloseEvent.connect(this, &PeerConnectionClient::OnClose);  //连接关闭回调
  hanging_get_->SignalCloseEvent.connect(this, &PeerConnectionClient::OnClose);     //同上
  
  control_socket_->SignalConnectEvent.connect(this, &PeerConnectionClient::OnConnect);      //连接成功回调
  hanging_get_->SignalConnectEvent.connect( this, &PeerConnectionClient::OnHangingGetConnect); //同上
  
  control_socket_->SignalReadEvent.connect(this, &PeerConnectionClient::OnRead); //消息回调
  hanging_get_->SignalReadEvent.connect( this, &PeerConnectionClient::OnHangingGetRead); //同上
}

peerA:

  1. 连接server,获得自己的peer_id_; 主动连接PeerConnectionClient::DoConnect(), 发送获取peer_id_的协议GET /sign_in, 回调PeerConnectionClient::OnConnect(rtc::AsyncSocket* socket), 其他客户端连接服务,会添加到peerList
  2. 主动连接peerB, callback_->ConnectToPeer(id);
  • 初始化peerconnection, Conductor::InitializePeerConnection())
    • 创建peerConnectionConductor::CreatePeerConnection 设置IceServer服务器地址
    • add audio & video tracks,AddTrack, CreateAudioTrack, CreateVideoTrack, peer_connection_->AddTrack
  • 创建offer & SetLocalDescription, CreateOffer, peer_connection_->CreateOffer( this, webrtc::PeerConnectionInterface::RTCOfferAnswerOptions());
    • Conductor::OnSuccess, 设置本地描述符SetLocalDescription , 给peerB发送offer sdp信息。
  1. A new ICE candidate has been gathered.
  • OnIceCandidate, 并把Candidate信息发送给peerB
  1. 收到peerB发来的信息 OnMessageFromPeer
  • 设置peerB的描述信息SetRemoteDescription
  • Once a remote candidate is received from the peerB,CreateIceCandidate,AddIceCandidate
  • 添加candidate CreateIceCandidate, AddIceCandidate

peerB:

  1. 同 peerA

  2. 收到peerA发来的连接信息, OnMessageFromPeer

  • 初始化peerconnection, Conductor::InitializePeerConnection())
    • 创建peerConnectionConductor::CreatePeerConnection 设置IceServer服务器地址
    • add audio & video tracks,AddTrack, CreateAudioTrack, CreateVideoTrack, peer_connection_->AddTrack
  • 创建描述信息 CreateSessionDescription
  • 设置peerA的描述信息SetRemoteDescription
  • 创建Answer CreateAnswer
    • Conductor::OnSuccess, 设置本地描述符SetLocalDescription , 给peerA发送answer sdp信息。
  1. 收到peerA发来的信息 OnMessageFromPeer
  • 添加candidate CreateIceCandidate, AddIceCandidate
  1. A new ICE candidate has been gathered.
  • OnIceCandidate, 并把Candidate信息发送给peerB

在WebRTC的源码api/peer_connection_interface.h中,有很长一段注释,分别从呼叫方和被呼方的视角说明了整个流程,发起方:

// The following steps are needed to setup a typical call using WebRTC:
//
// 1. Create a PeerConnectionFactoryInterface. Check constructors for more
// information about input parameters.
//
// 2. Create a PeerConnection object. Provide a configuration struct which
// points to STUN and/or TURN servers used to generate ICE candidates, and
// provide an object that implements the PeerConnectionObserver interface,
// which is used to receive callbacks from the PeerConnection.
//
// 3. Create local MediaStreamTracks using the PeerConnectionFactory and add
// them to PeerConnection by calling AddTrack (or legacy method, AddStream).
//
// 4. Create an offer, call SetLocalDescription with it, serialize it, and send
// it to the remote peer
//
// 5. Once an ICE candidate has been gathered, the PeerConnection will call the
// observer function OnIceCandidate. The candidates must also be serialized and
// sent to the remote peer.
//
// 6. Once an answer is received from the remote peer, call
// SetRemoteDescription with the remote answer.
//
// 7. Once a remote candidate is received from the remote peer, provide it to
// the PeerConnection by calling AddIceCandidate.

接收方

// If the application decides to accept the call, it should:
// 1. Create PeerConnectionFactoryInterface if it doesn't exist.
// 2. Create a new PeerConnection.
// 3. Provide the remote offer to the new PeerConnection object by calling
// SetRemoteDescription.

// 4. Generate an answer to the remote offer by calling CreateAnswer and send it
// back to the remote peer.
//
// 5. Provide the local answer to the new PeerConnection by calling
// SetLocalDescription with the answer.
//
// 6. Provide the remote ICE candidates by calling AddIceCandidate.
//
// 7. Once a candidate has been gathered, the PeerConnection will call the
// observer function OnIceCandidate. Send these candidates to the remote peer.

--完--