IEnumerator GotAnswerCoroutine(string connectionId, RTCPeerConnection pc, string sdp)
        {
            var desc = new RTCSessionDescription();

            desc.type = RTCSdpType.Answer;
            desc.sdp  = sdp;
            var opRemoteSdp = pc.SetRemoteDescription(ref desc);

            yield return(opRemoteSdp);

            if (opRemoteSdp.IsError)
            {
                Debug.LogError($"Network Error: {opRemoteSdp.Error.message}");
            }
            onGotAnswer?.Invoke(connectionId, sdp);
        }
Пример #2
0
 public ARDSessionDescriptionMessage(RTCSessionDescription description)
 {
     Description = description;
     if (Description.Type.Equals("offer", StringComparison.Ordinal))
     {
         Type = ARDSignalingMessageType.Offer;
     }
     else if (Description.Type.Equals("answer", StringComparison.Ordinal))
     {
         Type = ARDSignalingMessageType.Answer;
     }
     else
     {
         System.Diagnostics.Debug.WriteLine($"Unexpected type: {Type}");
     }
 }
Пример #3
0
        public async Task <ICallInfo> PlaceCallAsync(CallConfiguration config)
        {
            Debug.Assert(_peerId == -1);

            if (PeerConnection != null)
            {
                Debug.WriteLine("[Error] We only support connection to one peer at a time.");
                return(null);
            }

            if (CreatePeerConnection())
            {
                string selectedAudioCodecName = (string)_localSettings.Values["SelectedAudioCodecName"];
                string selectedVideoCodecName = (string)_localSettings.Values["SelectedVideoCodecName"];

                _peerId = PeerId;

                var offerOptions = new RTCOfferOptions();
                offerOptions.OfferToReceiveAudio = true;
                offerOptions.OfferToReceiveVideo = true;
                IRTCSessionDescription offer = await PeerConnection.CreateOffer(offerOptions);

                // Alter sdp to force usage of selected codecs
                string modifiedSdp = offer.Sdp;
                SdpUtils.SelectCodec(ref modifiedSdp, selectedAudioCodecName, "audio");
                SdpUtils.SelectCodec(ref modifiedSdp, selectedVideoCodecName, "video");
                RTCSessionDescriptionInit sdpInit = new RTCSessionDescriptionInit();
                sdpInit.Sdp  = modifiedSdp;
                sdpInit.Type = offer.SdpType;
                var modifiedOffer = new RTCSessionDescription(sdpInit);
                await PeerConnection.SetLocalDescription(modifiedOffer);

                Debug.WriteLine($"Sending offer: {modifiedOffer.Sdp}");

                string jsonString = SdpToJsonString(modifiedOffer);

                CallInfo callInfo = new CallInfo();
                callInfo.SetCall(new Call());
                callInfo.SetSdp(modifiedSdp);
                callInfo.SetJsonString(jsonString);

                OnSendMessageToRemotePeer.Invoke(this, jsonString);

                return(callInfo);
            }
            return(null);
        }
Пример #4
0
        public Task HandleAsync(
            IRemoteDevice remoteDevice,
            Guid?peerConnectionId,
            RTCSessionDescription offer,
            TransceiverMetadata[] transceivers)
        {
            Require.NotNull(offer.Sdp);
            Require.NotNull(offer.Type);

            // Ensure the user has logged in
            var deviceData = remoteDevice.GetCustomData();

            if (null == deviceData.User)
            {
                throw new UnauthorizedAccessException();
            }

            // Get or create new PeerConnection, depending on the client's requests
            IPeerConnection peerConnection = null;

            if (peerConnectionId != null)
            {
                peerConnection = deviceData.PeerConnections.First(p => p.Id == peerConnectionId.Value);
            }
            else
            {
                if (deviceData.PeerConnections.Count > 3)
                {
                    throw new InvalidOperationException($"Max 3 PeerConnection allowed per device");
                }
                peerConnection = CreatePeerConnection(remoteDevice, deviceData.User);
            }

            // Save
            deviceData.PeerConnections.Add(peerConnection);
            remoteDevice.SetCustomData(deviceData);

            // Let the negotiation service handle the rest
            // Notes - queue transceiver metadata first before queuing the remote sdp,
            // so at the time processing remote sdp (which has remote transceivers)
            // we know transceviers' metadata inhand.
            // Fail to do so will cause errors.
            _negotiationService.EnqueueRemoteTransceiverMetadata(peerConnection, transceivers);
            _negotiationService.EnqueueRemoteOffer(peerConnection, offer);
            return(Task.CompletedTask);
        }
Пример #5
0
    private IEnumerator OnCreateOfferSuccess(RTCPeerConnection pc, RTCSessionDescription desc)
    {
        Debug.Log("setLocalDescription start");
        var op = pc.SetLocalDescription(ref desc);

        yield return(op);

        if (!op.IsError)
        {
            OnSetLocalSuccess(pc);
        }
        else
        {
            var error = op.Error;
            OnSetSessionDescriptionError(ref error);
        }
    }
Пример #6
0
        /// <summary>
        /// Sets relevant properties for this session based on the SDP from the remote party.
        /// </summary>
        /// <param name="sessionDescription">The session description from the remote call party.</param>
        public override void setRemoteDescription(RTCSessionDescription sessionDescription)
        {
            base.setRemoteDescription(sessionDescription);

            var connAddr = IPAddress.Parse(sessionDescription.sdp.Connection.ConnectionAddress);

            foreach (var announcement in sessionDescription.sdp.Media)
            {
                var annAddr = connAddr;
                if (announcement.Connection != null)
                {
                    annAddr = IPAddress.Parse(announcement.Connection.ConnectionAddress);
                }

                if (announcement.Media == SDPMediaTypesEnum.audio)
                {
                    var connRtpEndPoint  = new IPEndPoint(annAddr, announcement.Port);
                    var connRtcpEndPoint = new IPEndPoint(annAddr, announcement.Port + 1);

                    SetDestination(SDPMediaTypesEnum.audio, connRtpEndPoint, connRtcpEndPoint);

                    foreach (var mediaFormat in announcement.MediaFormats)
                    {
                        if (mediaFormat.FormatAttribute?.StartsWith(TELEPHONE_EVENT_ATTRIBUTE) == true)
                        {
                            if (!int.TryParse(mediaFormat.FormatID, out var remoteRtpEventPayloadID))
                            {
                                //logger.LogWarning("The media format on the telephone event attribute was not a valid integer.");
                            }
                            else
                            {
                                base.RemoteRtpEventPayloadID = remoteRtpEventPayloadID;
                            }
                            break;
                        }
                    }
                }
                else if (announcement.Media == SDPMediaTypesEnum.video)
                {
                    var connRtpEndPoint  = new IPEndPoint(annAddr, announcement.Port);
                    var connRtcpEndPoint = new IPEndPoint(annAddr, announcement.Port + 1);

                    SetDestination(SDPMediaTypesEnum.video, connRtpEndPoint, connRtcpEndPoint);
                }
            }
        }
    IEnumerator OnCreateAnswerSuccess(RTCSessionDescription desc)
    {
        Debug.Log($"Answer created:\n{desc.sdp}");
        Debug.Log("setLocalDescription start");
        var op = peerConnection.SetLocalDescription(ref desc);

        yield return(op);

        if (!op.IsError)
        {
            OnSetLocalSuccess(desc, false);
        }
        else
        {
            var error = op.Error;
            OnSetSessionDescriptionError(ref error);
        }
    }
Пример #8
0
    IEnumerator proccessAnswer(string sdp)
    {
        //string pattern = @"(a=fmtp:\d+ .*level-asymmetry-allowed=.*)\r\n";
        //sdp = Regex.Replace(sdp, pattern, "$1;x-google-start-bitrate=16000;x-google-max-bitrate=160000\r\n");
        RTCSessionDescription answer = default;

        answer.type = RTCSdpType.Answer;
        answer.sdp  = sdp;
        Debug.Log($"set remote answer: {sdp}");
        var ret = pc.SetRemoteDescription(ref answer);

        yield return(ret);

        if (ret.isError)
        {
            Debug.Log($"processAnser error:{ret.error}");
        }
    }
    IEnumerator HandleAnswer(RTCSessionDescription desc)
    {
        Debug.Log($"HandleAnswer\n{desc.sdp}");
        Debug.Log("setRemoteDescription start");
        var op = peerConnection.SetRemoteDescription(ref desc);

        yield return(op);

        if (!op.IsError)
        {
            OnSetRemoteSuccess();
        }
        else
        {
            var error = op.Error;
            OnSetSessionDescriptionError(ref error);
        }
    }
Пример #10
0
        public void CallUser(string targetEmail, RTCSessionDescription offer)
        {
            var targetUser = Users.Where(x => x.Email == targetEmail).FirstOrDefault();
            var sourceUser = Users.Where(x => x.Email == Context.User.Identity.Name).FirstOrDefault();

            if (targetUser == null || sourceUser == null)
            {
#warning display error to user
                return;
            }
            else
            {
                //targetUser.UserStatus = OnlineUserStatus.Busy;
                //sourceUser.UserStatus = OnlineUserStatus.Busy;
                SendUserList(Users);
                SendOffer(targetUser, sourceUser, offer);
            }
        }
Пример #11
0
    private void HandleAnswer(string room, string sdp)
    {
        Debug.Log("HandleAnswer");
        if (room != roomName)
        {
            Debug.LogError("Wrong room name " + room);
            return;
        }
        if (!isCaller)
        {
            Debug.LogWarning("Not a caller, can't handle 'answer'");
            return;
        }
        RTCSessionDescription desc = new RTCSessionDescription {
            type = RTCSdpType.Answer, sdp = sdp
        };

        StartCoroutine(HandleAnswer(desc));
    }
Пример #12
0
    private IEnumerator OnCreateOfferSuccess(RTCSessionDescription desc)
    {
        Debug.Log("OnCreateOfferSuccess");
        Debug.Log($"Offer from pc\n{desc.sdp}");
        Debug.Log("pc setLocalDescription start");
        var op = peerConnection.SetLocalDescription(ref desc);

        yield return(op);

        if (!op.IsError)
        {
            OnSetLocalSuccess(desc, true);
        }
        else
        {
            var error = op.Error;
            OnSetSessionDescriptionError(ref error);
        }
    }
Пример #13
0
        private async void signaller_ReceivedOffer(object sender, RTCSessionDescription offer)
        {
            if (this.peerConnection != null)
            {
                return;
            }

            this.peerConnection = await this.buildPeerConnection(this.mediaOptions);

            await this.peerConnection.SetRemoteDescription(offer);

            var answer = await this.peerConnection.CreateAnswer(new RTCAnswerOptions());

            await this.peerConnection.SetLocalDescription(answer);

            await this.signaller.SendAnswer((RTCSessionDescription)answer);

            this.peerConnection.OnIceCandidate += this.peerConnection_OnIceCandidate;
        }
Пример #14
0
 public void SetRemoteSessionDescription(RTCSessionDescription description, Callback callback)
 {
     if (callback is null)
     {
         throw new ArgumentNullException(nameof(callback));
     }
     MustNotDisposed();
     _peerConnectionImpl.SetRemoteSessionDescription(
         description.Type,
         description.Sdp,
         new Callback().OnSuccess(delegate
     {
         try
         {
             // TODO: move this,
             // AddPeerConnection() should be called right after the peer connection
             // factory returns the newly created PeerConnection.
             //
             // To accomplish this, make sure VideoRouter listens to PeerConnection's track events,
             // because when PeerConnection has just been created, it has no track, however
             // SetRemoteSessionDescription() above adds track after the PeerConnection is added to the router.
             if (Interlocked.CompareExchange(
                     ref _addedToRouterState,
                     (int)AddedToRouterState.Added,
                     (int)AddedToRouterState.NotAdded) == (int)AddedToRouterState.NotAdded)
             {
                 // As per webRTC example, the answerer will SetRemoteSessionDescription() first,
                 // then followed by AddTrack();
                 //
                 // and AddPeerConnectionAsync() will call AddTrack() under the hood,
                 // therefore we call AddPeerConnectionAsync() right after SetRemoteSessionDescription();
                 _videoRouter.AddPeerConnection(Device, this);
             }
             callback.Success();
         }
         catch (Exception ex)
         {
             _logger.Error(ex);
             callback.Error(ex.Message);
         }
     }).OnError(msg => callback.Error(msg)));
 }
Пример #15
0
        public static ARDSignalingMessage MessageFromJSONString(string json)
        {
            var values = JsonConvert.DeserializeObject <Dictionary <string, string> >(json);
            ARDSignalingMessage message = new ARDSignalingMessage();

            if (values.ContainsKey("type"))
            {
                var type = values["type"] ?? "";
                switch (type)
                {
                case "candidate":
                    int.TryParse(values["label"], out int label);
                    RTCIceCandidate candidate = new RTCIceCandidate(values["id"], label, values["candidate"]);
                    message = new ARDICECandidateMessage(candidate);
                    break;

                case "offer":
                    RTCSessionDescription description = new RTCSessionDescription(RTCSdpType.Offer, values["sdp"]);
                    message = new ARDSessionDescriptionMessage(description);
                    break;

                case "answer":
                    description = new RTCSessionDescription(RTCSdpType.Answer, values["sdp"]);
                    message     = new ARDSessionDescriptionMessage(description);
                    break;

                case "bye":
                    message = new ARDByeMessage();
                    break;

                default:
                    System.Diagnostics.Debug.WriteLine($"ARDSignalingMessage unexpected type: {type}");
                    break;
                }
            }
            else
            {
                System.Diagnostics.Debug.WriteLine($"ARDSignalingMessage invalid json: {json}");
            }

            return(message);
        }
Пример #16
0
        public ARDSessionDescriptionMessage(RTCSessionDescription description)
        {
            Description = description;
            switch (Description.Type)
            {
            case RTCSdpType.Offer:
                Type = ARDSignalingMessageType.Offer;
                break;

            case RTCSdpType.PrAnswer:
                break;

            case RTCSdpType.Answer:
                Type = ARDSignalingMessageType.Answer;
                break;

            default:
                System.Diagnostics.Debug.WriteLine($"ARDSessionDescriptionMessage unexpected type: {Type}");
                break;
            }
        }
Пример #17
0
    IEnumerator SetDescription(RTCSessionDescription desc, Side side)
    {
        Debug.Log($"[Set {side} {desc.type}]");

        var op = side == Side.Local ? localConnection.SetLocalDescription(ref desc) : localConnection.SetRemoteDescription(ref desc);

        yield return(op);

        if (op.IsError)
        {
            Debug.LogError(op.Error.message);
        }
        else if (desc.type == RTCSdpType.Offer)
        {
            StartCoroutine(CreateDescription(RTCSdpType.Answer));
        }
        else if (side == Side.Local && desc.type == RTCSdpType.Answer)
        {
            SendDescription(ref desc);
        }
    }
    IEnumerator setDesc(string id, Side side, RTCSessionDescription desc)
    {
        var pc = pcs[id];

        Debug.Log($"[Set {side} {desc.type}] id:{id}");
        var op = side == Side.Local ? pc.SetLocalDescription(ref desc) : pc.SetRemoteDescription(ref desc);

        yield return(op);

        if (op.IsError)
        {
            Debug.LogError(op.Error.message);
        }
        else if (desc.type == RTCSdpType.Offer)
        {
            StartCoroutine(createDesc(id, RTCSdpType.Answer));
        }
        else if (side == Side.Local && desc.type == RTCSdpType.Answer)
        {
            signalingServer.Send(id, ref desc);
        }
    }
Пример #19
0
        public void DidCreateSessionDescription(RTCPeerConnection peerConnection, RTCSessionDescription sdp, NSError error)
        {
            // dispatch_async(dispatch_get_main_queue(),
            if (error != null)
            {
                System.Diagnostics.Debug.WriteLine($"Failed to create session description. Error: {error}");
                Disconnect();
                //    NSDictionary *userInfo = @{
                //      NSLocalizedDescriptionKey: @"Failed to create session description.",
                //    };
                //    NSError *sdpError =
                //        [[NSError alloc] initWithDomain:kARDAppClientErrorDomain
                //                                   code:kARDAppClientErrorCreateSDP
                //                               userInfo:userInfo];
                _delegate.DidError(this, error);
                return;
            }
            _peerConnection.SetLocalDescriptionWithDelegate(this, sdp);
            ARDSessionDescriptionMessage message = new ARDSessionDescriptionMessage(sdp);

            SendSignalingMessage(message).Wait();
        }
Пример #20
0
    IEnumerator HandleOffer(string sdp)
    {
        Debug.Log("HandleOffer start");
        Debug.Log("setRemoteDescription start");
        var desc = new RTCSessionDescription {
            sdp = sdp, type = RTCSdpType.Offer
        };
        var op = peerConnection.SetRemoteDescription(ref desc);

        yield return(op);

        if (!op.IsError)
        {
            OnSetRemoteSuccess();
            yield return(StartCoroutine(CreateAnswer()));
        }
        else
        {
            var error = op.Error;
            OnSetSessionDescriptionError(ref error);
        }
    }
Пример #21
0
        private async void signaller_ReceivedOffer(object sender, RTCSessionDescription offer)
        {
            Logger.Log("Received offer");
            if (this.peerConnection != null)
            {
                return;
            }

            this.peerConnection = await this.createPeerConnection();

            await this.peerConnection.SetRemoteDescription(offer);

            var answer = await this.peerConnection.CreateAnswer();

            await this.peerConnection.SetLocalDescription(answer);

            await this.signaller.SendAnswer(answer);

            await this.reconfigureLocalStream();

            await this.submitIceCandidatesAsync();
        }
Пример #22
0
        public async Task CreatOffer(long uid, long fromUid) //此时是发起方的操作
        {
            RTCSessionDescription offer;

            if (fromUid == 0)
            {
                offer = await CurrentRoom.Pub.CreateOffer();

                await CurrentRoom.Pub.SetLocalDescription(offer);
            }
            else
            {
                offer = await CurrentRoom.Recvs[fromUid].CreateOffer();
                await CurrentRoom.Recvs[fromUid].SetLocalDescription(offer);
            }


            var m = new GetAnswerModel();

            m.offer   = offer.Sdp;
            m.uid     = uid;
            m.fromUid = fromUid;
            var answerSdp = await SendOffer(m);

            if (answerSdp != "")
            {
                var answer = new RTCSessionDescription();
                answer.Type = RTCSdpType.Answer;
                answer.Sdp  = answerSdp;
                if (fromUid == 0)
                {
                    await CurrentRoom.Pub.SetRemoteDescription(answer);
                }
                else
                {
                    await CurrentRoom.Recvs[fromUid].SetRemoteDescription(answer);
                }
            }
        }
Пример #23
0
        IEnumerator OnAnswer(ISignaling signaling, DescData e)
        {
            if (!m_mapConnectionIdAndPeer.TryGetValue(e.connectionId, out var pc))
            {
                Debug.Log($"connectiondId:{e.connectionId}, peerConnection not exist");
                yield break;
            }

            var desc = new RTCSessionDescription();

            desc.type = RTCSdpType.Answer;
            desc.sdp  = e.sdp;
            var opRemoteSdp = pc.SetRemoteDescription(ref desc);

            yield return(opRemoteSdp);

            if (opRemoteSdp.IsError)
            {
                Debug.LogError($"Network Error: {opRemoteSdp.Error.message}");
                yield break;
            }
        }
Пример #24
0
    IEnumerator OnCreateAnswerSuccess(RTCPeerConnection pc, RTCSessionDescription desc)
    {
        Debug.Log($"Answer from {GetName(pc)}:\n{desc.sdp}");
        Debug.Log($"{GetName(pc)} setLocalDescription start");
        var op = pc.SetLocalDescription(ref desc);

        yield return(op);

        if (!op.IsError)
        {
            OnSetLocalSuccess(pc);
        }
        else
        {
            var error = op.Error;
            OnSetSessionDescriptionError(ref error);
        }

        var otherPc = GetOtherPc(pc);

        Debug.Log($"{GetName(otherPc)} setRemoteDescription start");

        var op2 = otherPc.SetRemoteDescription(ref desc);

        yield return(op2);

        if (!op2.IsError)
        {
            OnSetRemoteSuccess(otherPc);

            StartCoroutine(CheckActualCodec());
        }
        else
        {
            var error = op2.Error;
            OnSetSessionDescriptionError(ref error);
        }
    }
    private IEnumerator setRemoteDesc(RTCSdpType type, string sdp)
    {
        var desc = new RTCSessionDescription
        {
            type = type,
            sdp  = sdp
        };

        log(LogLevel.Log, $"SetRemoteDescription {type}");
        var opSetDesc = peer.SetRemoteDescription(ref desc);

        yield return(opSetDesc);

        if (opSetDesc.IsError)
        {
            log(LogLevel.Error, $"SetRemoteDescription {type}: {opSetDesc.Error.message}");
            yield break;
        }

        if (type == RTCSdpType.Offer)
        {
            yield return(StartCoroutine(createDesc(RTCSdpType.Answer)));
        }
    }
Пример #26
0
 public static string AsJSON(this RTCSessionDescription rtcSessionDescription)
 {
     return(JsonConvert.SerializeObject(new { type = rtcSessionDescription.Type, sdp = rtcSessionDescription.Description }));
 }
Пример #27
0
        static Callback SetLocalSessionDescriptionObserver(Callback completionCallback, IPeerConnection peerConnection, RTCSessionDescription offer)
        => new Callback()
        .OnError(completionCallback)
        .OnSuccess(delegate
        {
            // Generate transceiver metadata and send along with the offer.
            try
            {
                var transceivers = peerConnection.Room.VideoRouter.GetLocalTransceiverMetadata(peerConnection);
                peerConnection.Device.EnqueueOffer(peerConnection.Id, peerConnection.LastOfferId, offer,
                                                   transceivers);
                _logger.Debug($"[Renegotiation Step 1/3] Offer generated and sent for {peerConnection}.");
            }
            catch (Exception ex)
            {
                completionCallback.Error($"{nameof(IRemoteDevice.EnqueueOffer)} failed: {ex.Message}");
                if (!(ex is ObjectDisposedException))
                {
                    _logger.Error(ex);
                }
                return;
            }

            _logger.Debug($"[Renegotiation Step 2/3] Local offer set for {peerConnection}.");
            completionCallback.Success();
        });
Пример #28
0
        public void MessageFromPeerTaskRun(int peerId, string content)
        {
            PeerId = peerId;

            Task.Run(async() =>
            {
                Debug.Assert(_peerId == PeerId || _peerId == -1);
                Debug.Assert(content.Length > 0);

                if (_peerId != PeerId && _peerId != -1)
                {
                    Debug.WriteLine("Received a message from unknown peer " +
                                    "while already in a conversation with a different peer.");

                    return;
                }

                if (!JsonObject.TryParse(content, out JsonObject jMessage))
                {
                    Debug.WriteLine($"Received unknown message: {content}");
                    return;
                }

                string type = jMessage.ContainsKey(NegotiationAtributes.Type)
                       ? jMessage.GetNamedString(NegotiationAtributes.Type)
                       : null;

                if (PeerConnection == null)
                {
                    if (!string.IsNullOrEmpty(type))
                    {
                        // Create the peer connection only when call is
                        // about to get initiated. Otherwise ignore the
                        // message from peers which could be result
                        // of old (but not yet fully closed) connections.
                        if (type == "offer" || type == "answer" || type == "json")
                        {
                            Debug.Assert(_peerId == -1);
                            _peerId = PeerId;

                            if (!CreatePeerConnection())
                            {
                                Debug.WriteLine("Failed to initialize our PeerConnection instance");

                                OnSignedOut.Invoke(this, null);
                                return;
                            }
                            else if (_peerId != PeerId)
                            {
                                Debug.WriteLine("Received a message from unknown peer while already " +
                                                "in a conversation with a different peer.");

                                return;
                            }
                        }
                    }
                    else
                    {
                        Debug.WriteLine("[Warn] Received an untyped message after closing peer connection.");
                        return;
                    }
                }

                if (PeerConnection != null && !string.IsNullOrEmpty(type))
                {
                    if (type == "offer-loopback")
                    {
                        // Loopback not supported
                        Debug.Assert(false);
                    }

                    string sdp = null;

                    sdp = jMessage.ContainsKey(NegotiationAtributes.Sdp)
                          ? jMessage.GetNamedString(NegotiationAtributes.Sdp)
                          : null;

                    if (string.IsNullOrEmpty(sdp))
                    {
                        Debug.WriteLine("[Error] Can't parse received session description message.");
                        return;
                    }

                    Debug.WriteLine($"Received session description:\n{content}");

                    RTCSdpType messageType = RTCSdpType.Offer;
                    switch (type)
                    {
                    case "offer": messageType = RTCSdpType.Offer; break;

                    case "answer": messageType = RTCSdpType.Answer; break;

                    case "pranswer": messageType = RTCSdpType.Pranswer; break;

                    default: Debug.Assert(false, type); break;
                    }

                    var sdpInit     = new RTCSessionDescriptionInit();
                    sdpInit.Sdp     = sdp;
                    sdpInit.Type    = messageType;
                    var description = new RTCSessionDescription(sdpInit);

                    await PeerConnection.SetRemoteDescription(description);

                    if (messageType == RTCSdpType.Offer)
                    {
                        var answerOptions             = new RTCAnswerOptions();
                        IRTCSessionDescription answer = await PeerConnection.CreateAnswer(answerOptions);
                        await PeerConnection.SetLocalDescription(answer);
                        string jsonString = SdpToJsonString(answer);
                        // Send answer
                        OnSendMessageToRemotePeer.Invoke(this, jsonString);
                    }
                }
                else
                {
                    RTCIceCandidate candidate = null;

                    string sdpMid = jMessage.ContainsKey(NegotiationAtributes.SdpMid)
                           ? jMessage.GetNamedString(NegotiationAtributes.SdpMid)
                           : null;

                    double sdpMLineIndex = jMessage.ContainsKey(NegotiationAtributes.SdpMLineIndex)
                           ? jMessage.GetNamedNumber(NegotiationAtributes.SdpMLineIndex)
                           : -1;

                    string sdpCandidate = jMessage.ContainsKey(NegotiationAtributes.Candidate)
                           ? jMessage.GetNamedString(NegotiationAtributes.Candidate)
                           : null;

                    if (string.IsNullOrEmpty(sdpMid) || sdpMLineIndex == -1 || string.IsNullOrEmpty(sdpCandidate))
                    {
                        Debug.WriteLine($"[Error] Can't parse received message.\n{content}");
                        return;
                    }

                    var candidateInit           = new RTCIceCandidateInit();
                    candidateInit.Candidate     = sdpCandidate;
                    candidateInit.SdpMid        = sdpMid;
                    candidateInit.SdpMLineIndex = (ushort)sdpMLineIndex;
                    candidate = new RTCIceCandidate(candidateInit);

                    await PeerConnection.AddIceCandidate(candidate);

                    Debug.WriteLine($"Receiving ice candidate:\n{content}");
                }
            }).Wait();
        }
Пример #29
0
 public void setRemoteDescription(RTCSessionDescription sessionDescription)
 {
     remoteDescription = sessionDescription;
 }
Пример #30
0
 public void setLocalDescription(RTCSessionDescription sessionDescription)
 {
     localDescription = sessionDescription;
 }
Пример #31
0
 public void SetLocalDescription(RTCSessionDescription description)
 {
 }
Пример #32
0
 public void SetLocalDescription(RTCSessionDescription description, Action successCallback)
 {
 }
Пример #33
0
 public void SetRemoteDescription(RTCSessionDescription description)
 {
 }
Пример #34
0
 public void SetRemoteDescription(RTCSessionDescription description, Action successCallback)
 {
 }
Пример #35
0
 public void SetRemoteDescription(RTCSessionDescription description, Action successCallback, RTCPeerConnectionErrorCallback failureCallback)
 {
 }