public override async Task OnSdpAnswerAsync(RelayMessage message) { await Context.PeerConnection.SetRemoteDescription(new RTCSessionDescription(RTCSdpType.Answer, message.Payload)); if (SdpUtils.IsHold(message.Payload)) { await Context.SwitchState(new Held()); } else { await Context.SwitchState(new Active()); } }
public override async Task OnSdpOfferAsync(RelayMessage message) { bool isHold = SdpUtils.IsHold(message.Payload); if (isHold) { Context.VoipHelper.SetCallHeld(); } else { Context.VoipHelper.SetCallActive(Context.PeerId, Context.IsVideoEnabled); } // If PeerConnection is not null, then this is an SDP renegotiation. if (Context.PeerConnection == null) { var config = new RTCConfiguration { IceServers = WebRtcSettingsUtils.ToRTCIceServer(IceServerSettings.IceServers) }; Context.PeerConnection = new RTCPeerConnection(config); } if (isHold) { // Even for just a renegotiation, it's easier to just teardown the media capture and start over. if (Context.LocalStream != null) { Context.PeerConnection.RemoveStream(Context.LocalStream); } Context.LocalStream?.Stop(); Context.LocalStream = null; Context.RemoteStream?.Stop(); Context.RemoteStream = null; Context.ResetRenderers(); } MediaVideoTrack oldVideoTrack = Context.RemoteStream?.GetVideoTracks()?.FirstOrDefault(); await Context.PeerConnection.SetRemoteDescription(new RTCSessionDescription(RTCSdpType.Offer, message.Payload)); MediaVideoTrack newVideoTrack = Context.RemoteStream?.GetVideoTracks()?.FirstOrDefault(); bool videoTrackChanged = oldVideoTrack != null && newVideoTrack != null && oldVideoTrack.Id.CompareTo(newVideoTrack.Id) != 0; if (videoTrackChanged) { Context.ResetRemoteRenderer(); var source = RtcManager.Instance.Media.CreateMediaSource(newVideoTrack, CallContext.PeerMediaStreamId); Context.RemoteVideoRenderer.SetupRenderer(Context.ForegroundProcessId, source, Context.RemoteVideoControlSize); } else if (!isHold) { Context.LocalStream = await RtcManager.Instance.Media.GetUserMedia(new RTCMediaStreamConstraints { videoEnabled = Context.IsVideoEnabled, audioEnabled = true }); Context.PeerConnection.AddStream(Context.LocalStream); // Setup the rendering of the local capture. var tracks = Context.LocalStream.GetVideoTracks(); if (tracks.Count > 0) { var source = RtcManager.Instance.Media.CreateMediaSource(tracks[0], CallContext.LocalMediaStreamId); Context.LocalVideoRenderer.SetupRenderer(Context.ForegroundProcessId, source, Context.LocalVideoControlSize); } } var sdpAnswer = await Context.PeerConnection.CreateAnswer(); await Context.PeerConnection.SetLocalDescription(sdpAnswer); var sdpVideoCodecIds = SdpUtils.GetVideoCodecIds(message.Payload); if (sdpVideoCodecIds.Count > 0) { Context.VideoCodecUsed = Array.Find((await Hub.Instance.MediaSettingsChannel.GetVideoCodecsAsync())?.Codecs, it => it.Id == sdpVideoCodecIds.First())?.FromDto(); } Context.SendToPeer(RelayMessageTags.SdpAnswer, sdpAnswer.Sdp); if (isHold) { await Context.SwitchState(new Held()); } else { await Context.SwitchState(new Active()); } }