コード例 #1
0
    public void DataChannel_CreateDataChannel()
    {
        RTCConfiguration config = default;

        config.iceServers = new RTCIceServer[]
        {
            new RTCIceServer
            {
                urls = new string[] { "stun:stun.l.google.com:19302" }
            }
        };
        var peer     = new RTCPeerConnection(ref config);
        var option1  = new RTCDataChannelInit(true);
        var channel1 = peer.CreateDataChannel("test1", ref option1);

        Assert.AreEqual("test1", channel1.Label);

        var option2  = new RTCDataChannelInit(false);
        var channel2 = peer.CreateDataChannel("test2", ref option2);

        Assert.AreEqual("test2", channel2.Label);

        // It is return -1 when channel is not connected.
        Assert.AreEqual(channel1.Id, -1);
        Assert.AreEqual(channel2.Id, -1);

        peer.Close();
    }
コード例 #2
0
        private void InitializeWebRtc()
        {
            WebRTC.Initialize();

            var config = new RTCConfiguration
            {
                iceServers = new[]
                {
                    new RTCIceServer
                    {
                        urls = new[] { "stun:stun.l.google.com:19302", "stun:stun1.l.google.com:19302" }
                    }
                }
            };

            _peerConnection = new RTCPeerConnection(ref config);
            _peerConnection.OnIceConnectionChange = state => Debug.LogError("State changed: " + state);
            Debug.LogError("PeerConnection created.");

            var dcInit = new RTCDataChannelInit(true);

            DataChannel         = _peerConnection.CreateDataChannel("dataChannel", ref dcInit);
            DataChannel.OnOpen  = () => Debug.LogError("Data channel opened.");
            DataChannel.OnClose = () => Debug.LogError("Data channel closed.");

            DataChannel.OnMessage = bytes => Debug.LogError("Data channel received data: " + Encoding.UTF8.GetString(bytes));
            Debug.LogError("Data channel created.");
        }
コード例 #3
0
    private void Call()
    {
        callButton.interactable = false;
        Debug.Log("GetSelectedSdpSemantics");
        var configuration = GetSelectedSdpSemantics();

        _pc1 = new RTCPeerConnection(ref configuration);
        Debug.Log("Created local peer connection object pc1");
        _pc1.OnIceCandidate        = pc1OnIceCandidate;
        _pc1.OnIceConnectionChange = pc1OnIceConnectionChange;
        _pc1.OnNegotiationNeeded   = pc1OnNegotiationNeeded;
        _pc2 = new RTCPeerConnection(ref configuration);
        Debug.Log("Created remote peer connection object pc2");
        _pc2.OnIceCandidate        = pc2OnIceCandidate;
        _pc2.OnIceConnectionChange = pc2OnIceConnectionChange;
        _pc2.OnNegotiationNeeded   = pc2OnNegotiationNeeded;
        _pc2.OnTrack = pc2Ontrack;

        RTCDataChannelInit conf = new RTCDataChannelInit(true);

        _pc1.CreateDataChannel("data", ref conf);
        audioStream     = Audio.CaptureStream();
        videoStream     = cam.CaptureStream(1280, 720, 1000000);
        RtImage.texture = cam.targetTexture;
    }
コード例 #4
0
    IEnumerator Call()
    {
        callButton.interactable = false;
        Debug.Log("GetSelectedSdpSemantics");
        var configuration = GetSelectedSdpSemantics();

        pc1 = new RTCPeerConnection(ref configuration);
        Debug.Log("Created local peer connection object pc1");
        pc1.OnIceCandidate        = pc1OnIceCandidate;
        pc1.OnIceConnectionChange = pc1OnIceConnectionChange;
        pc2 = new RTCPeerConnection(ref configuration);
        Debug.Log("Created remote peer connection object pc2");
        pc2.OnIceCandidate        = pc2OnIceCandidate;
        pc2.OnIceConnectionChange = pc2OnIceConnectionChange;
        pc2.OnDataChannel         = onDataChannel;

        RTCDataChannelInit conf = new RTCDataChannelInit(true);

        dataChannel        = pc1.CreateDataChannel("data", ref conf);
        dataChannel.OnOpen = onDataChannelOpen;

        Debug.Log("pc1 createOffer start");
        var op = pc1.CreateOffer(ref OfferOptions);

        yield return(op);

        if (!op.IsError)
        {
            yield return(StartCoroutine(OnCreateOfferSuccess(op.Desc)));
        }
        else
        {
            OnCreateSessionDescriptionError(op.Error);
        }
    }
コード例 #5
0
        public void Connect(string url)
        {
            if (!string.IsNullOrEmpty(mHost))
            {
                throw new Exception("The host has connected. Please disconnect at first.");
            }

            mHost = url;

            var conf = GetSelectedSdpSemantics();

            mPeer = new RTCPeerConnection(ref conf);
            mPeer.OnIceCandidate        = OnIceCandidate;
            mPeer.OnIceConnectionChange = OnIceConnectionChange;
            mPeer.OnDataChannel         = OnDataChannel;

            DebugUtility.Log(LoggerTags.Online, "Create peer connection : {0}", host);

            var init = new RTCDataChannelInit(true);

            mSendDataChannel         = mPeer.CreateDataChannel("data", ref init);
            mSendDataChannel.OnOpen  = OnDataChannelOpen;
            mSendDataChannel.OnClose = OnDataChannelClose;

            currentTask = StartCoroutine(StartCreationWorkflow(mPeer));
        }
コード例 #6
0
        public void CreateDataChannelWithOption()
        {
            RTCConfiguration config = default;

            config.iceServers = new[] { new RTCIceServer {
                                            urls = new[] { "stun:stun.l.google.com:19302" }
                                        } };
            var peer    = new RTCPeerConnection(ref config);
            var options = new RTCDataChannelInit
            {
                id                = 231,
                maxRetransmits    = 1,
                maxPacketLifeTime = null,
                negotiated        = false,
                ordered           = false,
                protocol          = ""
            };
            var channel1 = peer.CreateDataChannel("test1", options);

            Assert.AreEqual("test1", channel1.Label);
            Assert.AreEqual("", channel1.Protocol);
            Assert.NotZero(channel1.MaxRetransmitTime);
            Assert.NotZero(channel1.MaxRetransmits);
            Assert.False(channel1.Ordered);
            Assert.False(channel1.Negotiated);

            // It is return -1 when channel is not connected.
            Assert.AreEqual(channel1.Id, -1);

            channel1.Close();
            peer.Close();
        }
コード例 #7
0
        public IEnumerator CreateAnswer()
        {
            var config = GetDefaultConfiguration();

            var peer1 = new RTCPeerConnection(ref config);
            var peer2 = new RTCPeerConnection(ref config);

            peer1.CreateDataChannel("data");

            var op1 = peer1.CreateOffer();

            yield return(op1);

            var desc = op1.Desc;
            var op2  = peer1.SetLocalDescription(ref desc);

            yield return(op2);

            var op3 = peer2.SetRemoteDescription(ref desc);

            yield return(op3);

            var op4 = peer2.CreateAnswer();

            yield return(op4);

            Assert.True(op4.IsDone);
            Assert.False(op4.IsError);

            peer1.Close();
            peer2.Close();
            peer1.Dispose();
            peer2.Dispose();
        }
コード例 #8
0
    private void createPeer()
    {
        log(LogLevel.Log, "Create RTCPeerConnection");
        var peerConfig = new RTCConfiguration {
            iceServers = iceServers
        };

        peer = new RTCPeerConnection(ref peerConfig);
        peer.OnConnectionStateChange = connectionState =>
        {
            log(LogLevel.Log, $"[OnConnectionStateChange] connectionState: {connectionState}");
        };
        peer.OnDataChannel = channel =>
        {
            dataChannel = channel;
            setupDataChannelEventHandler();
            log(LogLevel.Log, $"[OnDataChannel] label: {channel.Label}");
        };
        peer.OnIceCandidate = candidate =>
        {
            log(LogLevel.Log, $"[OnIceCandidate]");
            log(LogLevel.Log, $">>> Send \"takeCandidate\" Command (iceCandidate: '{candidate.Candidate.Substring(0, 10)} ...')");
            signaling.SendIceCandidate(streamId, candidate.Candidate, candidate.SdpMLineIndex.Value, candidate.SdpMid);
        };
        peer.OnIceGatheringStateChange = state =>
        {
            log(LogLevel.Log, $"[OnIceGatheringStateChange] iceGatheringState: {state}");
        };
        peer.OnNegotiationNeeded = () =>
        {
            log(LogLevel.Log, $"[OnNegotiationNeeded]");
        };
        peer.OnTrack = evt =>
        {
            log(LogLevel.Log, $"[OnTrack] kind: {evt.Track.Kind}");
            if (evt.Track is VideoStreamTrack track)
            {
                var texture = track.InitializeReceiver(videoWidth, videoHeight);
                playerDisplay.GetComponent <Renderer>().material.mainTexture = texture;
            }
        };

        var dcOptions = new RTCDataChannelInit();

        log(LogLevel.Log, $"CreateDataChannel label: {dataChannelLabel}");
        dataChannel = peer.CreateDataChannel(dataChannelLabel, dcOptions);
        setupDataChannelEventHandler();
        if (clientType == ClientType.Publisher)
        {
            var videoTrack = new VideoStreamTrack("VideoTrack", videoPlayer.targetTexture);
            peer.AddTrack(videoTrack);
            StartCoroutine(createDesc(RTCSdpType.Offer));
        }
    }
コード例 #9
0
        private void connectPeer()
        {
            OnLogEvent.Invoke("new RTCPeerConnection", "");
            peer = new RTCPeerConnection(ref peerConfig);
            peer.OnConnectionStateChange = connectionState =>
            {
                OnLogEvent.Invoke("OnConnectionStateChange", connectionState.ToString());
            };
            peer.OnDataChannel = channel =>
            {
                dataChannel = channel;
                setupDataChannelEventHandler();
                OnLogEvent.Invoke("OnDataChannel", channel.Label);
            };
            peer.OnIceCandidate = candidate =>
            {
                OnLogEvent.Invoke("OnIceCandidate", "");
                OnLogEvent.Invoke("Send IceCandidate", "");
                signaling.SendIceCandidate(streamId, candidate.Candidate, candidate.SdpMLineIndex.Value, candidate.SdpMid);
            };
            peer.OnIceGatheringStateChange = state =>
            {
                OnLogEvent.Invoke("OnIceGatheringStateChange", state.ToString());
            };
            peer.OnNegotiationNeeded = () =>
            {
                OnLogEvent.Invoke("OnNegotiationNeeded", "");
            };
            peer.OnTrack = evt =>
            {
                OnLogEvent.Invoke("OnTrack", evt.Track.Kind.ToString());
                if (evt.Track is VideoStreamTrack track)
                {
                    var texture = track.InitializeReceiver(videoWidth, videoHeight);
                    OnVideoTrack.Invoke(texture);
                }
            };

            var dcOptions = new RTCDataChannelInit();

            OnLogEvent.Invoke("CreateDataChannel", "testDC");
            dataChannel = peer.CreateDataChannel("testDC", dcOptions);
            setupDataChannelEventHandler();
            if (clientType == ClientType.Publisher)
            {
                var videoTrack = new VideoStreamTrack("VideoTrack", renderTexture);
                peer.AddTrack(videoTrack);
                CoroutineHandler.StartStaticCoroutine(sendDesc(RTCSdpType.Offer));
            }
        }
コード例 #10
0
    //ピアの作成をする
    void CreatePeer()
    {
        //ローカル
        RTCConfiguration pc_config = new RTCConfiguration();
        var server = new RTCIceServer();

        server.urls          = new string[] { "stun:stun.webrtc.ecl.ntt.com:3478" };
        pc_config.iceServers = new RTCIceServer[] {
            server
        };
        localConnection = new RTCPeerConnection(ref pc_config);
        //データチャネルの作成
        RTCDataChannelInit conf = new RTCDataChannelInit(true);

        localDataChannel         = localConnection.CreateDataChannel("send", ref conf);
        localDataChannel.OnOpen  = new DelegateOnOpen(() => { Debug.Log("データチャネル:localOpen"); });
        localDataChannel.OnClose = new DelegateOnClose(() => { Debug.Log("データチャネル:localClose"); });
        //メディアストリームの追加(現在のバージョンだとメディアストリームは1つまでらしい)
        if (_rtcType == RTCTYPE.OFFER)
        {
            _videoStream = _streamCamera.CaptureStream(800, 450);
        }

        localConnection.OnDataChannel = new DelegateOnDataChannel(x => {
            Debug.Log("ondatachannel");
            remoteDataChannel           = x;
            remoteDataChannel.OnMessage = onDataChannelMessage;
        });
        localConnection.OnTrack = new DelegateOnTrack(x => {
            x.Track;
            //PlayVideo(x.Track);
        });
        localConnection.OnIceConnectionChange =
            new DelegateOnIceConnectionChange(state => { OnIceConnectionChange(localConnection, state); });

        //ICEの登録
        localConnection.OnIceCandidate = new DelegateOnIceCandidate(candidate => {
            if (!string.IsNullOrEmpty(candidate.candidate))
            {
                _localIceCandidate.Add(candidate);
                Debug.Log("アイス:add my Ice" + candidate.candidate);
            }
            else
            {
                Debug.Log("end ice candidate");
            }
        });

        Debug.Log("crete peer");
    }
コード例 #11
0
        public void CreateDataChannelFailed()
        {
            RTCConfiguration config = default;

            config.iceServers = new[] { new RTCIceServer {
                                            urls = new[] { "stun:stun.l.google.com:19302" }
                                        } };
            var peer = new RTCPeerConnection(ref config);

            RTCDataChannelInit option1 = default;

            Assert.Throws <System.ArgumentException>(() => peer.CreateDataChannel("test1", ref option1));
            peer.Close();
        }
コード例 #12
0
        public void OnAddChannel()
        {
            var connectionId = "12345";
            var peer         = new RTCPeerConnection();
            var channel      = peer.CreateDataChannel("test");
            var test         = new MonoBehaviourTest <AddChannelHandlerTest>();

            m_provider.Subscribe(test.component);
            _mDelegate.RaiseOnAddChannel(connectionId, channel);
            Assert.That(test.component.IsTestFinished, Is.True);
            Assert.That(test.component.Data.connectionId, Is.EqualTo(connectionId));
            Assert.That(test.component.Data.channel, Is.EqualTo(channel));
            UnityEngine.Object.DestroyImmediate(test.gameObject);
        }
コード例 #13
0
        public IEnumerator SetRemoteDescription()
        {
            var config   = GetConfiguration();
            var peer1    = new RTCPeerConnection(ref config);
            var peer2    = new RTCPeerConnection(ref config);
            var conf     = new RTCDataChannelInit(true);
            var channel1 = peer1.CreateDataChannel("data", ref conf);

            RTCOfferOptions  options1 = default;
            RTCAnswerOptions options2 = default;
            var op1 = peer1.CreateOffer(ref options1);

            yield return(op1);

            var desc = op1.Desc;
            var op2  = peer1.SetLocalDescription(ref desc);

            yield return(op2);

            var op3 = peer2.SetRemoteDescription(ref desc);

            yield return(op3);

            var op4 = peer2.CreateAnswer(ref options2);

            yield return(op4);

            desc = op4.Desc;
            var op5 = peer2.SetLocalDescription(ref desc);

            yield return(op5);

            var op6 = peer1.SetRemoteDescription(ref desc);

            yield return(op6);

            var desc2 = peer1.RemoteDescription;

            Assert.AreEqual(desc.sdp, desc2.sdp);
            Assert.AreEqual(desc.type, desc2.type);

            channel1.Dispose();
            peer1.Close();
            peer2.Close();
            peer1.Dispose();
            peer2.Dispose();
        }
        public IEnumerator PeerConnection_SetRemoteDescription()
        {
            RTCConfiguration config = default;

            config.iceServers = new[] { new RTCIceServer {
                                            urls = new[] { "stun:stun.l.google.com:19302" }
                                        } };
            var            peer1    = new RTCPeerConnection(ref config);
            var            peer2    = new RTCPeerConnection(ref config);
            RTCDataChannel channel1 = null;

            var conf = new RTCDataChannelInit(true);

            channel1 = peer1.CreateDataChannel("data", ref conf);

            RTCOfferOptions  options1 = default;
            RTCAnswerOptions options2 = default;
            var op1 = peer1.CreateOffer(ref options1);

            yield return(op1);

            var op2 = peer1.SetLocalDescription(ref op1.desc);

            yield return(op2);

            var op3 = peer2.SetRemoteDescription(ref op1.desc);

            yield return(op3);

            var op4 = peer2.CreateAnswer(ref options2);

            yield return(op4);

            var op5 = peer2.SetLocalDescription(ref op4.desc);

            yield return(op5);

            var op6 = peer1.SetRemoteDescription(ref op4.desc);

            yield return(op6);

            channel1.Dispose();
            peer1.Dispose();
            peer2.Dispose();
        }
コード例 #15
0
        public void CreateDataChannel()
        {
            RTCConfiguration config = default;

            config.iceServers = new[] { new RTCIceServer {
                                            urls = new[] { "stun:stun.l.google.com:19302" }
                                        } };
            var peer     = new RTCPeerConnection(ref config);
            var channel1 = peer.CreateDataChannel("test1");

            Assert.AreEqual("test1", channel1.Label);

            // It is return -1 when channel is not connected.
            Assert.AreEqual(channel1.Id, -1);

            channel1.Close();
            peer.Close();
        }
コード例 #16
0
    IEnumerator Call()
    {
        callButton.interactable = false;
        Debug.Log("GetSelectedSdpSemantics");
        var configuration = GetSelectedSdpSemantics();

        pc1 = new RTCPeerConnection(ref configuration);
        Debug.Log("Created local peer connection object pc1");
        pc1.OnIceCandidate        = pc1OnIceCandidate;
        pc1.OnIceConnectionChange = pc1OnIceConnectionChange;
        pc2 = new RTCPeerConnection(ref configuration);
        Debug.Log("Created remote peer connection object pc2");
        pc2.OnIceCandidate        = pc2OnIceCandidate;
        pc2.OnIceConnectionChange = pc2OnIceConnectionChange;
        pc2.OnDataChannel         = onDataChannel;

        dataChannel        = pc1.CreateDataChannel("data");
        dataChannel.OnOpen = onDataChannelOpen;

        var audioTrack = new AudioStreamTrack(source);
        var videoTrack = cam.CaptureStreamTrack(1280, 720);

        yield return(0);

        pc1.AddTrack(audioTrack);
        pc1.AddTrack(videoTrack);

        Debug.Log("pc1 createOffer start");
        var op = pc1.CreateOffer();

        yield return(op);

        if (!op.IsError)
        {
            yield return(StartCoroutine(OnCreateOfferSuccess(op.Desc)));
        }
        else
        {
            OnCreateSessionDescriptionError(op.Error);
        }
    }
コード例 #17
0
    //ピアの作成をする
    void CreatePeer()
    {
        //ローカル
        RTCConfiguration pc_config = new RTCConfiguration();
        var server = new RTCIceServer();

        server.urls          = new string[] { "stun:stun.webrtc.ecl.ntt.com:3478" };
        pc_config.iceServers = new RTCIceServer[] {
            server
        };
        localConnection = new RTCPeerConnection(ref pc_config);
        RTCDataChannelInit conf = new RTCDataChannelInit(true);

        localDataChannel         = localConnection.CreateDataChannel("send", ref conf);
        localDataChannel.OnOpen  = new DelegateOnOpen(() => { Debug.Log("データチャネル:localOpen"); });
        localDataChannel.OnClose = new DelegateOnClose(() => { Debug.Log("データチャネル:localClose"); });
        //localDataChannel.OnMessage = onDataChannelMessage;
        localConnection.OnDataChannel = new DelegateOnDataChannel(x => {
            Debug.Log("ondatachannel");
            remoteDataChannel           = x;
            remoteDataChannel.OnMessage = onDataChannelMessage;
        });
        localConnection.OnIceConnectionChange =
            new DelegateOnIceConnectionChange(state => { OnIceConnectionChange(localConnection, state); });

        //ICEの登録
        localConnection.OnIceCandidate = new DelegateOnIceCandidate(candidate => {
            if (!string.IsNullOrEmpty(candidate.candidate))
            {
                _localIceCandidate.Add(candidate);
                Debug.Log("アイス:add my Ice" + candidate.candidate);
            }
            else
            {
                Debug.Log("end ice candidate");
            }
        });

        Debug.Log("crete peer");
    }
コード例 #18
0
        public void CreateDataChannelFailed()
        {
            RTCConfiguration config = default;

            config.iceServers = new[] { new RTCIceServer {
                                            urls = new[] { "stun:stun.l.google.com:19302" }
                                        } };
            var peer = new RTCPeerConnection(ref config);

            // Cannot be set along with "maxRetransmits" and "maxPacketLifeTime"
            var options = new RTCDataChannelInit
            {
                id                = 231,
                maxRetransmits    = 1,
                maxPacketLifeTime = 1,
                negotiated        = false,
                ordered           = false,
                protocol          = ""
            };

            Assert.Throws <ArgumentException>(() => peer.CreateDataChannel("test1", options));
            peer.Close();
        }
コード例 #19
0
    public IEnumerator DataChannel_EventsAreSentToOther()
    {
        RTCConfiguration config = default;

        config.iceServers = new RTCIceServer[]
        {
            new RTCIceServer
            {
                urls = new string[] { "stun:stun.l.google.com:19302" }
            }
        };
        var            peer1 = new RTCPeerConnection(ref config);
        var            peer2 = new RTCPeerConnection(ref config);
        RTCDataChannel channel1 = null, channel2 = null;

        peer1.OnIceCandidate = new DelegateOnIceCandidate(candidate => { peer2.AddIceCandidate(ref candidate); });
        peer2.OnIceCandidate = new DelegateOnIceCandidate(candidate => { peer1.AddIceCandidate(ref candidate); });
        peer2.OnDataChannel  = new DelegateOnDataChannel(channel => { channel2 = channel; });

        var conf = new RTCDataChannelInit(true);

        channel1 = peer1.CreateDataChannel("data", ref conf);

        RTCOfferOptions  options1 = default;
        RTCAnswerOptions options2 = default;
        var op1 = peer1.CreateOffer(ref options1);

        yield return(op1);

        var op2 = peer1.SetLocalDescription(ref op1.desc);

        yield return(op2);

        var op3 = peer2.SetRemoteDescription(ref op1.desc);

        yield return(op3);

        var op4 = peer2.CreateAnswer(ref options2);

        yield return(op4);

        var op5 = peer2.SetLocalDescription(ref op4.desc);

        yield return(op5);

        var op6 = peer1.SetRemoteDescription(ref op4.desc);

        yield return(op6);

        yield return(new WaitUntil(() => peer1.IceConnectionState == RTCIceConnectionState.Connected || peer1.IceConnectionState == RTCIceConnectionState.Completed));

        yield return(new WaitUntil(() => peer2.IceConnectionState == RTCIceConnectionState.Connected || peer2.IceConnectionState == RTCIceConnectionState.Completed));

        yield return(new WaitUntil(() => channel2 != null));

        Assert.AreEqual(channel1.Label, channel2.Label);
        Assert.AreEqual(channel1.Id, channel2.Id);

        string message1 = "hello";
        string message2 = null;

        channel2.OnMessage = new DelegateOnMessage(bytes => { message2 = System.Text.Encoding.UTF8.GetString(bytes); });
        channel1.Send(message1);
        yield return(new WaitUntil(() => !string.IsNullOrEmpty(message2)));

        Assert.AreEqual(message1, message2);

        byte[] message3 = { 1, 2, 3 };
        byte[] message4 = null;
        channel2.OnMessage = new DelegateOnMessage(bytes => { message4 = bytes; });
        channel1.Send(message3);
        yield return(new WaitUntil(() => message4 != null));

        Assert.AreEqual(message3, message4);

        peer1.Close();
        peer2.Close();
    }
コード例 #20
0
ファイル: Conductor.cs プロジェクト: zaxy78/3dtoolkit
        /// <summary>
        /// Creates a peer connection.
        /// </summary>
        /// <returns>True if connection to a peer is successfully created.</returns>
        private async Task <bool> CreatePeerConnection(CancellationToken cancelationToken)
        {
            Debug.Assert(_peerConnection == null);
            if (cancelationToken.IsCancellationRequested)
            {
                return(false);
            }

            var config = new RTCConfiguration()
            {
                BundlePolicy = RTCBundlePolicy.Balanced,
#if ORTCLIB
                SignalingMode = _signalingMode,
                GatherOptions = new RTCIceGatherOptions()
                {
                    IceServers = new List <RTCIceServer>(_iceServers),
                }
#else
                IceTransportPolicy = RTCIceTransportPolicy.All,
                IceServers         = _iceServers
#endif
            };

            Debug.WriteLine("Conductor: Creating peer connection.");
            _peerConnection = new RTCPeerConnection(config);

            if (_peerConnection == null)
            {
                throw new NullReferenceException("Peer connection is not created.");
            }

#if !ORTCLIB
            _peerConnection.EtwStatsEnabled = _etwStatsEnabled;
            _peerConnection.ConnectionHealthStatsEnabled = _peerConnectionStatsEnabled;
#endif
            if (cancelationToken.IsCancellationRequested)
            {
                return(false);
            }
#if ORTCLIB
            OrtcStatsManager.Instance.Initialize(_peerConnection);
#endif
            OnPeerConnectionCreated?.Invoke();

            _peerConnection.OnIceCandidate += PeerConnection_OnIceCandidate;
#if ORTCLIB
            _peerConnection.OnTrack     += PeerConnection_OnAddTrack;
            _peerConnection.OnTrackGone += PeerConnection_OnRemoveTrack;
            _peerConnection.OnIceConnectionStateChange += () => { Debug.WriteLine("Conductor: Ice connection state change, state=" + (null != _peerConnection ? _peerConnection.IceConnectionState.ToString() : "closed")); };
#else
            _peerConnection.OnAddStream             += PeerConnection_OnAddStream;
            _peerConnection.OnRemoveStream          += PeerConnection_OnRemoveStream;
            _peerConnection.OnConnectionHealthStats += PeerConnection_OnConnectionHealthStats;
#endif

            // Setup Data Channel
            _peerSendDataChannel = _peerConnection.CreateDataChannel(
                "SendDataChannel",
                new RTCDataChannelInit()
            {
                Ordered = true
            });
            _peerSendDataChannel.OnOpen   += PeerSendDataChannelOnOpen;
            _peerSendDataChannel.OnClose  += PeerSendDataChannelOnClose;
            _peerSendDataChannel.OnError  += _peerSendDataChannel_OnError;
            _peerConnection.OnDataChannel += _peerConnection_OnDataChannel;     // DataChannel Setup Completed

            Debug.WriteLine("Conductor: Getting user media.");
            RTCMediaStreamConstraints mediaStreamConstraints = new RTCMediaStreamConstraints
            {
                // Always include audio/video enabled in the media stream,
                // so it will be possible to enable/disable audio/video if
                // the call was initiated without microphone/camera
                audioEnabled = true,
                videoEnabled = true
            };

            if (cancelationToken.IsCancellationRequested)
            {
                return(false);
            }

#if ORTCLIB
            var tracks = await _media.GetUserMedia(mediaStreamConstraints);

            if (tracks != null)
            {
                RTCRtpCapabilities audioCapabilities = RTCRtpSender.GetCapabilities("audio");
                RTCRtpCapabilities videoCapabilities = RTCRtpSender.GetCapabilities("video");

                _mediaStream = new MediaStream(tracks);
                Debug.WriteLine("Conductor: Adding local media stream.");
                IList <MediaStream> mediaStreamList = new List <MediaStream>();
                mediaStreamList.Add(_mediaStream);
                foreach (var mediaStreamTrack in tracks)
                {
                    //Create stream track configuration based on capabilities
                    RTCMediaStreamTrackConfiguration configuration = null;
                    if (mediaStreamTrack.Kind == MediaStreamTrackKind.Audio && audioCapabilities != null)
                    {
                        configuration =
                            await Helper.GetTrackConfigurationForCapabilities(audioCapabilities, AudioCodec);
                    }
                    else if (mediaStreamTrack.Kind == MediaStreamTrackKind.Video && videoCapabilities != null)
                    {
                        configuration =
                            await Helper.GetTrackConfigurationForCapabilities(videoCapabilities, VideoCodec);
                    }
                    if (configuration != null)
                    {
                        _peerConnection.AddTrack(mediaStreamTrack, mediaStreamList, configuration);
                    }
                }
            }
#else
            _mediaStream = await _media.GetUserMedia(mediaStreamConstraints);
#endif

            if (cancelationToken.IsCancellationRequested)
            {
                return(false);
            }

#if !ORTCLIB
            Debug.WriteLine("Conductor: Adding local media stream.");
            _peerConnection.AddStream(_mediaStream);
#endif

            OnAddLocalStream?.Invoke(new MediaStreamEvent()
            {
                Stream = _mediaStream
            });
            if (cancelationToken.IsCancellationRequested)
            {
                return(false);
            }
            return(true);
        }
コード例 #21
0
    private async void Start()
    {
        websocket = new WebSocket("ws://localhost:8000/socket");

        Debug.Log("GetSelectedSdpSemantics");
        var configuration = GetSelectedSdpSemantics();

        pc2 = new RTCPeerConnection(ref configuration);
        Debug.Log("Created remote peer connection object pc2");

        pc2.OnIceCandidate        = pc2OnIceCandidate;
        pc2.OnIceConnectionChange = pc2OnIceConnectionChange;
        pc2.OnDataChannel         = onDataChannel;

        RTCDataChannelInit conf = new RTCDataChannelInit();

        dataChannel        = pc2.CreateDataChannel("data", conf);
        dataChannel.OnOpen = onDataChannelOpen;

        //dataChannel.Send("3TEST");

        pc2OnIceConnectionChange = state => { OnIceConnectionChange(pc2, state); };
        pc2OnIceCandidate        = candidate => { OnIceCandidate(pc2, candidate); };

        textReceive.text += "0TEST";

        onDataChannel = channel =>
        {
            Debug.Log("Data Channel works!");
            textReceive.text     += "2TEST";
            dataChannel           = channel;
            dataChannel.OnMessage = onDataChannelMessage;
        };
        onDataChannelMessage = bytes =>
        {
            textReceive.text = System.Text.Encoding.UTF8.GetString(bytes);

            //         var epoint = new Uint8Array(event.data, 92);

            //   if (epoint.byteLength > 93) {

            //var dpoint = MessagePack.decode(epoint);
            //         console.log("Decoded pointarray:", dpoint);

            //var pointbuff = new Int8Array(dpoint);
            //         colate(pointbuff);
        };
        onDataChannelOpen  = () => { textReceive.text += "1TEST"; };
        onDataChannelClose = () => { sendButton.interactable = false; };

        websocket.OnOpen += () =>
        {
            Debug.Log("Connection open!");
        };

        websocket.OnError += (e) =>
        {
            Debug.Log("Error! " + e);
        };

        websocket.OnClose += (e) =>
        {
            Debug.Log("Connection closed!");
        };

        websocket.OnMessage += (bytes) =>
        {
            Debug.Log("Message: " + System.Text.Encoding.UTF8.GetString(bytes));

            Message message = JsonConvert.DeserializeObject <Message>(System.Text.Encoding.UTF8.GetString(bytes));
            Debug.Log("New message: " + message.type);

            switch (message.type)
            {
            case "offer":

                var remoteDesc = new RTCSessionDescription();
                remoteDesc.type = 0;
                remoteDesc.sdp  = message.sdp;
                pc2.SetRemoteDescription(ref remoteDesc);

                var answer = pc2.CreateAnswer(ref AnswerOptions);
                Debug.Log("Answer: " + answer.Desc.sdp);
                Debug.Log("Answer Desc: " + answer.Desc.type);

                var localDesc = new RTCSessionDescription();
                localDesc.type = answer.Desc.type;
                localDesc.sdp  = message.sdp;
                pc2.SetLocalDescription(ref localDesc);

                Message newMessage = new Message();

                newMessage.type = "answer";
                newMessage.sdp  = answer.Desc.sdp;

                string output = JsonConvert.SerializeObject(newMessage);

                websocket.SendText(output);

                break;

            case "candidate":
                RTCIceCandidateInit candidateMessage = new RTCIceCandidateInit();
                candidateMessage.candidate     = message.sdp;
                candidateMessage.sdpMLineIndex = 0;
                candidateMessage.sdpMid        = "";

                RTCIceCandidate candidate = new RTCIceCandidate(candidateMessage);

                pc2.AddIceCandidate(candidate);
                break;

            default:
                Debug.Log("P2: We got something from the signaling server but we don't know what it is!");
                Debug.Log("Take a look for yourself: " + message.type);
                Debug.Log("Take a look for yourself: " + message.sdp);
                break;
            }
        };

        await websocket.Connect();
    }
コード例 #22
0
        public IEnumerator EventsAreSentToOther()
        {
            RTCConfiguration config = default;

            config.iceServers = new[] { new RTCIceServer {
                                            urls = new[] { "stun:stun.l.google.com:19302" }
                                        } };
            var            peer1    = new RTCPeerConnection(ref config);
            var            peer2    = new RTCPeerConnection(ref config);
            RTCDataChannel channel2 = null;

            peer1.OnIceCandidate = candidate => { peer2.AddIceCandidate(candidate); };
            peer2.OnIceCandidate = candidate => { peer1.AddIceCandidate(candidate); };
            peer2.OnDataChannel  = channel => { channel2 = channel; };

            var  channel1       = peer1.CreateDataChannel("data");
            bool channel1Opened = false;
            bool channel1Closed = false;

            channel1.OnOpen  = () => { channel1Opened = true; };
            channel1.OnClose = () => { channel1Closed = true; };

            RTCOfferOptions  options1 = default;
            RTCAnswerOptions options2 = default;
            var op1 = peer1.CreateOffer(ref options1);

            yield return(op1);

            var desc = op1.Desc;
            var op2  = peer1.SetLocalDescription(ref desc);

            yield return(op2);

            var op3 = peer2.SetRemoteDescription(ref desc);

            yield return(op3);

            var op4 = peer2.CreateAnswer(ref options2);

            yield return(op4);

            desc = op4.Desc;
            var op5 = peer2.SetLocalDescription(ref desc);

            yield return(op5);

            var op6 = peer1.SetRemoteDescription(ref desc);

            yield return(op6);

            var op7 = new WaitUntilWithTimeout(
                () => peer1.IceConnectionState == RTCIceConnectionState.Connected ||
                peer1.IceConnectionState == RTCIceConnectionState.Completed, 5000);

            yield return(op7);

            Assert.True(op7.IsCompleted);
            var op8 = new WaitUntilWithTimeout(
                () => peer2.IceConnectionState == RTCIceConnectionState.Connected ||
                peer2.IceConnectionState == RTCIceConnectionState.Completed, 5000);

            yield return(op8);

            Assert.True(op8.IsCompleted);
            var op9 = new WaitUntilWithTimeout(() => channel2 != null, 5000);

            yield return(op9);

            Assert.True(op9.IsCompleted);

            Assert.True(channel1Opened);
            Assert.AreEqual(channel1.Label, channel2.Label);
            Assert.AreEqual(channel1.Id, channel2.Id);

            const string message1 = "hello";
            string       message2 = null;

            channel2.OnMessage = bytes => { message2 = System.Text.Encoding.UTF8.GetString(bytes); };
            channel1.Send(message1);
            var op10 = new WaitUntilWithTimeout(() => !string.IsNullOrEmpty(message2), 5000);

            yield return(op10);

            Assert.True(op10.IsCompleted);
            Assert.AreEqual(message1, message2);

            byte[] message3 = { 1, 2, 3 };
            byte[] message4 = null;
            channel2.OnMessage = bytes => { message4 = bytes; };
            channel1.Send(message3);
            var op11 = new WaitUntilWithTimeout(() => message4 != null, 5000);

            yield return(op11);

            Assert.True(op11.IsCompleted);
            Assert.AreEqual(message3, message4);

            channel1.Close();
            var op12 = new WaitUntilWithTimeout(() => channel1Closed, 5000);

            yield return(op12);

            Assert.True(op12.IsCompleted);

            channel2.Close();
            peer1.Close();
            peer2.Close();
        }