Beispiel #1
0
        private IEnumerator SingleTwoWaysImpl(bool withSender1, bool withReceiver1, bool withSender2, bool withReceiver2)
        {
            // Create the peer connections
            var pc1_go = new GameObject("pc1");

            pc1_go.SetActive(false); // prevent auto-activation of components
            var pc1 = pc1_go.AddComponent <PeerConnection>();

            pc1.AutoInitializeOnStart = false;
            var pc2_go = new GameObject("pc2");

            pc2_go.SetActive(false); // prevent auto-activation of components
            var pc2 = pc2_go.AddComponent <PeerConnection>();

            pc2.AutoInitializeOnStart = false;

            // Batch changes manually
            pc1.AutoCreateOfferOnRenegotiationNeeded = false;
            pc2.AutoCreateOfferOnRenegotiationNeeded = false;

            // Create the signaler
            var sig_go = new GameObject("signaler");
            var sig    = sig_go.AddComponent <LocalOnlySignaler>();

            sig.Peer1 = pc1;
            sig.Peer2 = pc2;

            // Create the video sources on peer #1
            VideoTrackSource source1   = null;
            VideoReceiver    receiver1 = null;

            if (withSender1)
            {
                source1 = pc1_go.AddComponent <UniformColorVideoSource>();
            }
            if (withReceiver1)
            {
                receiver1 = pc1_go.AddComponent <VideoReceiver>();
            }
            MediaLine ml1 = pc1.AddMediaLine(MediaKind.Video);

            ml1.SenderTrackName = "video_track_1";
            ml1.Source          = source1;
            ml1.Receiver        = receiver1;

            // Create the video sources on peer #2
            VideoTrackSource source2   = null;
            VideoReceiver    receiver2 = null;

            if (withSender2)
            {
                source2 = pc2_go.AddComponent <UniformColorVideoSource>();
            }
            if (withReceiver2)
            {
                receiver2 = pc1_go.AddComponent <VideoReceiver>();
            }
            MediaLine ml2 = pc2.AddMediaLine(MediaKind.Video);

            ml2.SenderTrackName = "video_track_2";
            ml2.Source          = source2;
            ml2.Receiver        = receiver2;

            // Activate
            pc1_go.SetActive(true);
            pc2_go.SetActive(true);

            // Initialize
            var initializedEvent1 = new ManualResetEventSlim(initialState: false);

            pc1.OnInitialized.AddListener(() => initializedEvent1.Set());
            Assert.IsNull(pc1.Peer);
            pc1.InitializeAsync().Wait(millisecondsTimeout: 50000);
            var initializedEvent2 = new ManualResetEventSlim(initialState: false);

            pc2.OnInitialized.AddListener(() => initializedEvent2.Set());
            Assert.IsNull(pc2.Peer);
            pc2.InitializeAsync().Wait(millisecondsTimeout: 50000);

            // Wait a frame so that the Unity event OnInitialized can propagate
            yield return(null);

            // Check the event was raised
            Assert.IsTrue(initializedEvent1.Wait(millisecondsTimeout: 50000));
            Assert.IsNotNull(pc1.Peer);
            Assert.IsTrue(initializedEvent2.Wait(millisecondsTimeout: 50000));
            Assert.IsNotNull(pc2.Peer);

            // Confirm the sources are ready
            if (withSender1)
            {
                Assert.IsTrue(source1.IsStreaming);
            }
            if (withSender2)
            {
                Assert.IsTrue(source2.IsStreaming);
            }

            // Confirm the sender track is not created yet; it will be when the connection starts
            Assert.IsNull(ml1.SenderTrack);
            Assert.IsNull(ml2.SenderTrack);

            // Confirm the receiver track is not added yet, since remote tracks are only instantiated
            // as the result of a session negotiation.
            if (withReceiver1)
            {
                Assert.IsNull(receiver1.Track);
            }
            if (withReceiver2)
            {
                Assert.IsNull(receiver2.Track);
            }

            // Connect
            Assert.IsTrue(sig.StartConnection());
            yield return(sig.WaitForConnection(millisecondsTimeout: 10000));

            Assert.IsTrue(sig.IsConnected);

            // Wait a frame so that the Unity events for streams started can propagate
            yield return(null);

            // Check pairing
            {
                bool hasSend1 = false;
                bool hasSend2 = false;
                bool hasRecv1 = false;
                bool hasRecv2 = false;

                // Local tracks exist if manually added (independently of negotiation)
                Assert.AreEqual(withSender1 ? 1 : 0, pc1.Peer.LocalVideoTracks.Count());
                Assert.AreEqual(withSender2 ? 1 : 0, pc2.Peer.LocalVideoTracks.Count());

                // Remote tracks exist if paired with a sender on the remote peer
                if (withReceiver1 && withSender2) // R <= S
                {
                    Assert.IsNotNull(receiver1.Track);
                    Assert.IsNotNull(ml2.SenderTrack);
                    hasRecv1 = true;
                    hasSend2 = true;
                }
                if (withSender1 && withReceiver2) // S => R
                {
                    Assert.IsNotNull(ml1.SenderTrack);
                    Assert.IsNotNull(receiver2.Track);
                    hasSend1 = true;
                    hasRecv2 = true;
                }
                Assert.AreEqual(hasRecv1 ? 1 : 0, pc1.Peer.RemoteVideoTracks.Count());
                Assert.AreEqual(hasRecv2 ? 1 : 0, pc2.Peer.RemoteVideoTracks.Count());

                // Transceivers are consistent with pairing
                Assert.IsTrue(ml1.Transceiver.NegotiatedDirection.HasValue);
                Assert.AreEqual(hasSend1, Transceiver.HasSend(ml1.Transceiver.NegotiatedDirection.Value));
                Assert.AreEqual(hasRecv1, Transceiver.HasRecv(ml1.Transceiver.NegotiatedDirection.Value));
                Assert.IsTrue(ml2.Transceiver.NegotiatedDirection.HasValue);
                Assert.AreEqual(hasSend2, Transceiver.HasSend(ml2.Transceiver.NegotiatedDirection.Value));
                Assert.AreEqual(hasRecv2, Transceiver.HasRecv(ml2.Transceiver.NegotiatedDirection.Value));
            }
        }
Beispiel #2
0
        public IEnumerator Multi()
        {
            // Create the peer connections
            var pc1_go = new GameObject("pc1");

            pc1_go.SetActive(false); // prevent auto-activation of components
            var pc1 = pc1_go.AddComponent <PeerConnection>();

            pc1.AutoInitializeOnStart = false;
            var pc2_go = new GameObject("pc2");

            pc2_go.SetActive(false); // prevent auto-activation of components
            var pc2 = pc2_go.AddComponent <PeerConnection>();

            pc2.AutoInitializeOnStart = false;

            // Batch changes manually
            pc1.AutoCreateOfferOnRenegotiationNeeded = false;
            pc2.AutoCreateOfferOnRenegotiationNeeded = false;

            // Create the signaler
            var sig_go = new GameObject("signaler");
            var sig    = sig_go.AddComponent <LocalOnlySignaler>();

            sig.Peer1 = pc1;
            sig.Peer2 = pc2;

            // Create the senders and receivers
            //     P1     P2
            // 0 : S   =>  R
            // 1 : SR <=> SR
            // 2 : S   => SR
            // 3 :  R <=  SR
            // 4 : S   =>  R

            const int NumTransceivers = 5;

            // P1 has 4 senders added to it
            int numLocal1 = 4;

            // P1 receives 2 tracks from the 3 P2 senders (one is refused)
            int numRemote1 = 2;

            // P2 has 3 senders added to it
            int numLocal2 = 3;

            // P2 receives 4 tracks from the 4 P1 senders
            int numRemote2 = 4;

            var cfgs = new MultiConfig[NumTransceivers]
            {
                new MultiConfig {
                    peer1 = new PeerConfig {
                        desiredDirection = Transceiver.Direction.SendOnly,
                        expectSender     = true,
                        expectReceiver   = false,
                    },
                    peer2 = new PeerConfig {
                        desiredDirection = Transceiver.Direction.ReceiveOnly,
                        expectSender     = false,
                        expectReceiver   = true,
                    }
                },
                new MultiConfig {
                    peer1 = new PeerConfig {
                        desiredDirection = Transceiver.Direction.SendReceive,
                        expectSender     = true,
                        expectReceiver   = true,
                    },
                    peer2 = new PeerConfig {
                        desiredDirection = Transceiver.Direction.SendReceive,
                        expectSender     = true,
                        expectReceiver   = true,
                    },
                },
                new MultiConfig {
                    peer1 = new PeerConfig {
                        desiredDirection = Transceiver.Direction.SendOnly,
                        expectSender     = true,
                        expectReceiver   = false,
                    },
                    peer2 = new PeerConfig {
                        desiredDirection = Transceiver.Direction.SendReceive,
                        expectSender     = true,
                        expectReceiver   = true,
                    },
                },
                new MultiConfig {
                    peer1 = new PeerConfig {
                        desiredDirection = Transceiver.Direction.ReceiveOnly,
                        expectSender     = false,
                        expectReceiver   = true,
                    },
                    peer2 = new PeerConfig {
                        desiredDirection = Transceiver.Direction.SendReceive,
                        expectSender     = true,
                        expectReceiver   = false,
                    },
                },
                new MultiConfig {
                    peer1 = new PeerConfig {
                        desiredDirection = Transceiver.Direction.SendOnly,
                        expectSender     = true,
                        expectReceiver   = false,
                    },
                    peer2 = new PeerConfig {
                        desiredDirection = Transceiver.Direction.ReceiveOnly,
                        expectSender     = false,
                        expectReceiver   = true,
                    },
                },
            };

            for (int i = 0; i < NumTransceivers; ++i)
            {
                var cfg = cfgs[i];

                {
                    MediaLine ml1  = pc1.AddMediaLine(MediaKind.Video);
                    var       peer = cfg.peer1;
                    peer.mediaLine = ml1;
                    if (Transceiver.HasSend(peer.desiredDirection))
                    {
                        var source1 = pc1_go.AddComponent <UniformColorVideoSource>();
                        peer.source         = source1;
                        ml1.Source          = source1;
                        ml1.SenderTrackName = $"track{i}";
                    }
                    if (Transceiver.HasRecv(peer.desiredDirection))
                    {
                        var receiver1 = pc1_go.AddComponent <VideoReceiver>();
                        peer.receiver = receiver1;
                        ml1.Receiver  = receiver1;
                    }
                }

                {
                    MediaLine ml2  = pc2.AddMediaLine(MediaKind.Video);
                    var       peer = cfg.peer2;
                    peer.mediaLine = ml2;
                    if (Transceiver.HasSend(peer.desiredDirection))
                    {
                        var source2 = pc2_go.AddComponent <UniformColorVideoSource>();
                        peer.source         = source2;
                        ml2.Source          = source2;
                        ml2.SenderTrackName = $"track{i}";
                    }
                    if (Transceiver.HasRecv(peer.desiredDirection))
                    {
                        var receiver2 = pc2_go.AddComponent <VideoReceiver>();
                        peer.receiver = receiver2;
                        ml2.Receiver  = receiver2;
                    }
                }
            }

            // Activate
            pc1_go.SetActive(true);
            pc2_go.SetActive(true);

            // Initialize
            var initializedEvent1 = new ManualResetEventSlim(initialState: false);

            pc1.OnInitialized.AddListener(() => initializedEvent1.Set());
            Assert.IsNull(pc1.Peer);
            pc1.InitializeAsync().Wait(millisecondsTimeout: 50000);
            var initializedEvent2 = new ManualResetEventSlim(initialState: false);

            pc2.OnInitialized.AddListener(() => initializedEvent2.Set());
            Assert.IsNull(pc2.Peer);
            pc2.InitializeAsync().Wait(millisecondsTimeout: 50000);

            // Wait a frame so that the Unity event OnInitialized can propagate
            yield return(null);

            // Check the event was raised
            Assert.IsTrue(initializedEvent1.Wait(millisecondsTimeout: 50000));
            Assert.IsNotNull(pc1.Peer);
            Assert.IsTrue(initializedEvent2.Wait(millisecondsTimeout: 50000));
            Assert.IsNotNull(pc2.Peer);

            // Confirm the sources are ready
            for (int i = 0; i < NumTransceivers; ++i)
            {
                var cfg = cfgs[i];
                if (cfg.peer1.expectSender)
                {
                    Assert.IsNotNull(cfg.peer1.source, $"Missing source #{i} on Peer #1");
                    Assert.IsNotNull(cfg.peer1.source.IsStreaming, $"Source #{i} is not ready on Peer #1");
                    Assert.IsNull(cfg.peer1.mediaLine.SenderTrack); // created during connection
                }
                if (cfg.peer2.expectSender)
                {
                    Assert.IsNotNull(cfg.peer2.source, $"Missing source #{i} on Peer #2");
                    Assert.IsNotNull(cfg.peer2.source.IsStreaming, $"Source #{i} is not ready on Peer #2");
                    Assert.IsNull(cfg.peer2.mediaLine.SenderTrack); // created during connection
                }
            }

            // Connect
            Assert.IsTrue(sig.StartConnection());
            yield return(sig.WaitForConnection(millisecondsTimeout: 60000));

            Assert.IsTrue(sig.IsConnected);

            // Wait a frame so that the Unity events for streams started can propagate
            yield return(null);

            // Check pairing
            Assert.AreEqual(numLocal1, pc1.Peer.LocalVideoTracks.Count());
            Assert.AreEqual(numRemote1, pc1.Peer.RemoteVideoTracks.Count());
            Assert.AreEqual(numLocal2, pc2.Peer.LocalVideoTracks.Count());
            Assert.AreEqual(numRemote2, pc2.Peer.RemoteVideoTracks.Count());
            for (int i = 0; i < NumTransceivers; ++i)
            {
                var cfg = cfgs[i];
                if (cfg.peer1.expectSender)
                {
                    Assert.IsNotNull(cfg.peer1.mediaLine.SenderTrack, $"Transceiver #{i} missing local sender track on Peer #1");
                }
                if (cfg.peer1.expectReceiver)
                {
                    Assert.IsNotNull(cfg.peer1.receiver.Track, $"Transceiver #{i} missing remote track on Peer #1");
                }
                if (cfg.peer2.expectSender)
                {
                    Assert.IsNotNull(cfg.peer2.mediaLine.SenderTrack, $"Transceiver #{i} missing local sender track on Peer #2");
                }
                if (cfg.peer2.expectReceiver)
                {
                    Assert.IsNotNull(cfg.peer2.receiver.Track, $"Transceiver #{i} Missing remote track on Peer #2");
                }
            }

            // Change the senders and receivers and transceivers direction
            //        old            new
            //     P1     P2      P1     P2
            // 0 : S   =>  R          =   R     P1 stops sending
            // 1 : SR <=> SR      SR  =>  R     P2 stops sending
            // 2 : S   => SR      SR <=> SR     P1 starts receiving
            // 3 :  R <=  SR      SR <=> SR     P1 starts sending
            // 4 : S   =>  R      S   =         P2 stops receiving

            numLocal1  = 4;
            numRemote1 = 2;
            numLocal2  = 2;
            numRemote2 = 3;

            // #0 - P1 stops sending
            {
                var cfg = cfgs[0];
                cfg.peer1.mediaLine.Source = null;
                cfg.peer1.expectSender     = false;
                cfg.peer1.expectReceiver   = false;
                cfg.peer2.expectSender     = false;
                cfg.peer2.expectReceiver   = false;
            }

            // #1 - P2 stops sending
            {
                var cfg = cfgs[1];
                cfg.peer2.mediaLine.Source = null;
                cfg.peer1.expectSender     = true;
                cfg.peer1.expectReceiver   = false;
                cfg.peer2.expectSender     = false;
                cfg.peer2.expectReceiver   = true;
            }

            // #2 - P1 starts receiving
            {
                var cfg       = cfgs[2];
                var receiver2 = pc2_go.AddComponent <VideoReceiver>();
                cfg.peer1.receiver           = receiver2;
                cfg.peer1.mediaLine.Receiver = receiver2;
                cfg.peer1.expectSender       = true;
                cfg.peer1.expectReceiver     = true;
                cfg.peer2.expectSender       = true;
                cfg.peer2.expectReceiver     = true;
            }

            // #3 - P1 starts sending
            {
                var cfg     = cfgs[3];
                var source1 = pc1_go.AddComponent <UniformColorVideoSource>();
                cfg.peer1.source           = source1;
                cfg.peer1.mediaLine.Source = source1;
                cfg.peer1.expectSender     = true;
                cfg.peer1.expectReceiver   = true;
                cfg.peer2.expectSender     = true;
                cfg.peer2.expectReceiver   = true;
            }

            // #4 - P2 stops receiving
            {
                var cfg = cfgs[4];
                cfg.peer2.mediaLine.Receiver = null;
                cfg.peer1.expectSender       = false;
                cfg.peer1.expectReceiver     = false;
                cfg.peer2.expectSender       = false;
                cfg.peer2.expectReceiver     = false;
            }

            // Renegotiate
            Assert.IsTrue(sig.StartConnection());
            yield return(sig.WaitForConnection(millisecondsTimeout: 60000));

            Assert.IsTrue(sig.IsConnected);

            // Wait a frame so that the Unity events for streams started can propagate
            yield return(null);

            // Check pairing
            Assert.AreEqual(numLocal1, pc1.Peer.LocalVideoTracks.Count());
            Assert.AreEqual(numRemote1, pc1.Peer.RemoteVideoTracks.Count());
            Assert.AreEqual(numLocal2, pc2.Peer.LocalVideoTracks.Count());
            Assert.AreEqual(numRemote2, pc2.Peer.RemoteVideoTracks.Count());
            for (int i = 0; i < NumTransceivers; ++i)
            {
                var cfg = cfgs[i];
                if (cfg.peer1.expectReceiver)
                {
                    Assert.IsNotNull(cfg.peer1.receiver.Track, $"Transceiver #{i} missing remote track on Peer #1");
                }
                if (cfg.peer2.expectReceiver)
                {
                    Assert.IsNotNull(cfg.peer2.receiver.Track, $"Transceiver #{i} Missing remote track on Peer #2");
                }
            }
        }