Пример #1
0
        public void StopConference(Action <string> callback)
        {
            // Detach signalling from the conference.
            Signalling.Detach((error) =>
            {
                // Stop echo canceller.
                if (EnableSoftwareEchoCancellation)
                {
                    OpusEchoCanceller.Stop();
                    OpusEchoCanceller = null;
                }

                Conference.OnLinkInit -= LogLinkInit;
                Conference.OnLinkUp   -= LogLinkUp;
                Conference.OnLinkDown -= LogLinkDown;
                Conference             = null;

                VideoStream.OnLinkInit -= AddRemoteVideoControl;
                VideoStream.OnLinkDown -= RemoveRemoteVideoControl;
                VideoStream             = null;

                AudioStream = null;

                callback(error);
            });
        }
Пример #2
0
        private void StopConference()
        {
            // Detach signalling from the conference.
            Signalling.Detach((error) =>
            {
                if (error != null)
                {
                    Alert(error);
                }
            });

                        #if __ANDROID__
            // Stop echo canceller.
            OpusEchoCanceller.Stop();
            OpusEchoCanceller = null;
                        #endif

            Conference.OnLinkInit -= LogLinkInit;
            Conference.OnLinkUp   -= LogLinkUp;
            Conference.OnLinkDown -= LogLinkDown;
            Conference             = null;

            VideoStream.OnLinkInit -= AddRemoteVideoControl;
            VideoStream.OnLinkDown -= RemoveRemoteVideoControl;
            VideoStream             = null;

            AudioStream = null;
        }
        // TODO: will move to dispose
        /// <summary>
        /// Stops the conference.
        /// </summary>
        /// <returns>The conference.</returns>
        private void StopConference()
        {
            try
            {
#if __ANDROID__
                // Stop echo canceller.
                OpusEchoCanceller.Stop();
                OpusEchoCanceller = null;
#endif
                conference.OnLinkInit -= LogLinkInit;
                conference.OnLinkUp   -= LogLinkUp;
                conference.OnLinkDown -= LogLinkDown;

                conference.OnLinkOfferAnswer -= OnLinkSendOfferAnswer;
                conference.OnLinkCandidate   -= OnLinkSendCandidate;
                conference = null;

                videoStream.OnLinkInit -= AddRemoteVideoControl;
                videoStream.OnLinkDown -= RemoveRemoteVideoControl;
                videoStream             = null;

                audioStream = null;
            }
            catch (Exception ex)
            {
                FM.Log.Debug(ex.ToString());
            }
        }
Пример #4
0
        //Video Chat is the main form
        public void StartConference(Action <string> callback)
        {
            // Create a WebRTC audio stream description (requires a
            // reference to the local audio feed).
            AudioStream = new AudioStream(LocalMedia.LocalMediaStream);

            // Create a WebRTC video stream description (requires a
            // reference to the local video feed). Whenever a P2P link
            // initializes using this description, position and display
            // the remote video control on-screen by passing it to the
            // layout manager created above. Whenever a P2P link goes
            // down, remove it.
            VideoStream             = new VideoStream(LocalMedia.LocalMediaStream);
            VideoStream.OnLinkInit += AddRemoteVideoControl;
            VideoStream.OnLinkDown += RemoveRemoteVideoControl;

            // Create a new IceLink conference.
            Conference = new FM.IceLink.Conference(IceLinkServerAddress, new Stream[] { AudioStream, VideoStream });

            // Supply TURN relay credentials in case we are behind a
            // highly restrictive firewall. These credentials will be
            // verified by the TURN server.
            Conference.RelayUsername = "******";
            Conference.RelayPassword = "******";

            // Add a few event handlers to the conference so we can see
            // when a new P2P link is created or changes state.
            Conference.OnLinkInit += LogLinkInit;
            Conference.OnLinkUp   += LogLinkUp;
            Conference.OnLinkDown += LogLinkDown;

            // Attach signalling to the conference.
            Signalling.Attach(Conference, SessionId, callback);
        }
Пример #5
0
        /// <summary>
        /// Creates the local audio and video devices, from Icelink demo
        /// </summary>
        /// <param name="callType"></param>
        /// <param name="callback"></param>
        public void StartConference(string callType, Action <string> callback)
        {
            // Create a WebRTC audio stream description (requires a
            // reference to the local audio feed).
            AudioStream = new AudioStream(LocalMedia.LocalMediaStream);

            // Create a WebRTC video stream description (requires a
            // reference to the local video feed). Whenever a P2P link
            // initializes using this description, position and display
            // the remote video control on-screen by passing it to the
            // layout manager created above. Whenever a P2P link goes
            // down, remove it.
            VideoStream             = new VideoStream(LocalMedia.LocalMediaStream);
            VideoStream.OnLinkInit += AddRemoteVideoControl;
            VideoStream.OnLinkDown += RemoveRemoteVideoControl;

            // Create a conference using our stream descriptions.

            Conference = new FM.IceLink.Conference(StunServerAddress, new Stream[] { AudioStream, VideoStream });
            Conference.CandidateMode = CandidateMode.Early;
            // Use our pre-generated DTLS certificate.
            Conference.DtlsCertificate = Certificate;

            // Supply TURN relay credentials in case we are behind a
            // highly restrictive firewall. These credentials will be
            // verified by the TURN server.
            Conference.RelayUsername = "******";
            Conference.RelayPassword = "******";

            // Add a few event handlers to the conference so we can see
            // when a new P2P link is created or changes state.
            Conference.OnLinkInit += LogLinkInit;
            Conference.OnLinkUp   += LogLinkUp;
            Conference.OnLinkDown += LogLinkDown;


            // Start echo canceller.
            if (EnableSoftwareEchoCancellation)
            {
                OpusEchoCanceller = new OpusEchoCanceller(OpusClockRate, OpusChannels, true);
                OpusEchoCanceller.Start();
            }

            if (callType == "outgoing")
            {
                // Outgoing call
                Signalling.Call(Conference, Jid, callback);
            }
            else if (callType == "incoming")
            {
                // Incoming call
                Signalling.Answer(Conference, Jid, Sdp, callback);
            }
        }
Пример #6
0
        private void StartConference()
        {
            ConferenceStarted = true;

            // Create a WebRTC audio stream description (requires a
            // reference to the local audio feed).
            AudioStream = new AudioStream(LocalMedia.LocalMediaStream);

            // Create a WebRTC video stream description (requires a
            // reference to the local video feed). Whenever a P2P link
            // initializes using this description, position and display
            // the remote video control on-screen by passing it to the
            // layout manager created above. Whenever a P2P link goes
            // down, remove it.
            VideoStream             = new VideoStream(LocalMedia.LocalMediaStream);
            VideoStream.OnLinkInit += AddRemoteVideoControl;
            VideoStream.OnLinkDown += RemoveRemoteVideoControl;

            // Create a conference using our stream descriptions.
            Conference = new FM.IceLink.Conference(IceLinkServerAddress, new Stream[] { AudioStream, VideoStream });

            // Use our pre-generated DTLS certificate.
            Conference.DtlsCertificate = Certificate;

            // Supply TURN relay credentials in case we are behind a
            // highly restrictive firewall. These credentials will be
            // verified by the TURN server.
            Conference.RelayUsername = "******";
            Conference.RelayPassword = "******";

            // Add a few event handlers to the conference so we can see
            // when a new P2P link is created or changes state.
            Conference.OnLinkInit += LogLinkInit;
            Conference.OnLinkUp   += LogLinkUp;
            Conference.OnLinkDown += LogLinkDown;

                        #if __ANDROID__
            // Start echo canceller.
            OpusEchoCanceller = new OpusEchoCanceller(OpusClockRate, OpusChannels);
            OpusEchoCanceller.Start();
                        #endif

            Signalling.Attach(Conference, SessionId, (error) =>
            {
                if (error != null)
                {
                    Alert(error);
                }
            });
        }
Пример #7
0
        /// <summary>
        /// Begin outgoing call
        /// </summary>
        /// <param name="conference"></param>
        /// <param name="to"></param>
        /// <param name="callback"></param>
        public void Call(FM.IceLink.Conference conference, string to, Action <string> callback)
        {
            To = to;
            Messaging.Log.Info(">Call " + to);
            Conference = conference;

            // when IceLink generates an Offer or a Candidate, raise event
            Conference.OnLinkOfferAnswer    += SendSessionInitiate;
            Conference.OnLinkCandidate      += SendCandidate;
            Conference.OnUnhandledException += Conference_OnUnhandledException;

            // Icelink generate candidates
            Conference.Link(to);
        }
Пример #8
0
        public void Detach(Action <string> callback)
        {
            if (UseWebSyncExtension)
            {
                // Leave the managed WebSync channel.
                WebSyncClient.LeaveConference(new LeaveConferenceArgs("/" + SessionId)
                {
                    OnSuccess = (e) =>
                    {
                        Conference = null;
                        SessionId  = null;

                        callback(null);
                    },
                    OnFailure = (e) =>
                    {
                        callback(string.Format("Could not detach signalling from conference {0}. {1}", SessionId, e.Exception.Message));
                    }
                });
            }
            else
            {
                // Unsubscribe from the WebSync channel.
                WebSyncClient.Unsubscribe(new UnsubscribeArgs("/" + SessionId)
                {
                    OnSuccess = (e) =>
                    {
                        // Detach our event handlers.
                        Conference.OnLinkOfferAnswer -= SendOfferAnswer;
                        Conference.OnLinkCandidate   -= SendCandidate;
                        WebSyncClient.OnNotify       -= ReceiveOfferAnswerOrCandidate;

                        Conference = null;
                        SessionId  = null;

                        callback(null);
                    },
                    OnFailure = (e) =>
                    {
                        callback(string.Format("Could not detach signalling from conference {0}. {1}", SessionId, e.Exception.Message));
                    }
                });
            }
        }
Пример #9
0
        public void StopConference(Action <string> callback)
        {
            // Detach signalling from the conference.
            Signalling.Detach((error) =>
            {
                Conference.OnLinkInit -= LogLinkInit;
                Conference.OnLinkUp   -= LogLinkUp;
                Conference.OnLinkDown -= LogLinkDown;
                Conference             = null;

                VideoStream.OnLinkInit -= AddRemoteVideoControl;
                VideoStream.OnLinkDown -= RemoveRemoteVideoControl;
                VideoStream             = null;

                AudioStream = null;

                callback(error);
            });
        }
Пример #10
0
        /// <summary>
        /// Recipient accepted call
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void Xmpp_OnReceiveSessionAccept(object sender, Messaging.Jingle.JingleSdpEventArgs e)
        {
            Messaging.Log.Debug("OnReceiveSessionAccept > Conference.ReceiveOfferAnswer " + e.From);

            OfferAnswer oa = new OfferAnswer();

            oa.SdpMessage = e.Sdp;
            oa.IsOffer    = false;

            Messaging.Log.Info("Peer ID: " + e.From);
            Messaging.Log.Info("SA SDP in:  " + e.Sdp);


            if (Conference == null)
            {
                Conference = ActivityService.GetInstance.App.GetConference();
            }
            // send candidates to Icelink to negotiate connection
            Conference.ReceiveOfferAnswer(oa, e.From);
        }
Пример #11
0
        /// <summary>
        /// hangup
        /// </summary>
        /// <param name="callback"></param>
        public void Detach(Action <string> callback)
        {
            Messaging.Log.Debug("Signalling.Detach");
            //this.xmpp.OnReceiveSessionAccept -= Xmpp_OnReceiveSessionAccept;
            //this.xmpp.OnReceiveSessionInitiate -= Xmpp_OnReceiveSessionInitiate;
            //this.xmpp.OnReceiveCandidate -= Xmpp_OnReceiveCandidate;
            if (Conference != null)
            {
                Conference.OnLinkOfferAnswer    -= SendSessionInitiate;
                Conference.OnLinkCandidate      -= SendCandidate;
                Conference.OnUnhandledException -= Conference_OnUnhandledException;

                Conference = null;
            }

            if (callback != null)
            {
                Messaging.Log.Debug("Signallin.gDetach callback");
                callback(null);
            }
        }
Пример #12
0
        /// <summary>
        /// Answer incoming call
        /// </summary>
        /// <param name="conference"></param>
        /// <param name="to"></param>
        /// <param name="sdp"></param>
        /// <param name="callback"></param>
        public void Answer(FM.IceLink.Conference conference, string to, string sdp, Action <string> callback)
        {
            To = to;
            // Console.WriteLine ("Answer callback");
            Conference = conference;

            Conference.OnLinkOfferAnswer       += SendSessionAccept;
            Conference.OnLinkCandidate         += SendCandidate;
            Conference.OnUnhandledException    += Conference_OnUnhandledException;
            Conference.OnLinkRemoteOfferAnswer += LinkRemoteOfferAnswer;

            OfferAnswer oa = new OfferAnswer();

            oa.SdpMessage = sdp;
            oa.IsOffer    = true;

            Messaging.Log.Info("Peer ID: " + to);
            Messaging.Log.Info("SI SDP in:\n" + sdp);

            Messaging.Log.Debug("Answer > Conference.ReceiveOfferAnswer");
            // send to Icelink to generate candidates
            Conference.ReceiveOfferAnswer(oa, to);
        }
        public ConferenceWrapper(string sessionId,
                                 LocalMedia localMedia)
        {
            this.LocalMedia = localMedia;
            InitAudioAndVideoStreams();

            // Create a conference using our stream descriptions.
            conference = new FM.IceLink.Conference(this.IceServers, new Stream[] { audioStream, videoStream });

            // Use our pre-generated DTLS certificate.
            conference.DtlsCertificate = Certificate;

            // Supply TURN relay credentials in case we are behind a
            // highly restrictive firewall. These credentials will be
            // verified by the TURN server.
            conference.RelayUsername = "******";
            conference.RelayPassword = "******";
            conference.ServerPort    = 3478;

            // Add a few event handlers to the conference so we can see
            // when a new P2P link is created or changes state.
            conference.OnLinkInit += LogLinkInit;
            conference.OnLinkUp   += LogLinkUp;
            conference.OnLinkDown += LogLinkDown;

            conference.OnLinkOfferAnswer += OnLinkSendOfferAnswer;
            conference.OnLinkCandidate   += OnLinkSendCandidate;
            conference.Timeout            = ConferenceTimeout;

#if __ANDROID__
            // Start echo canceller.
            OpusEchoCanceller = new OpusEchoCanceller(OpusClockRate, OpusChannels);
            OpusEchoCanceller.Start();
#endif

            this.sessionId = sessionId;
        }
Пример #14
0
        //Video Chat is the main form
        public void StartConference(Action<string> callback)
        {
            // Create a WebRTC audio stream description (requires a
            // reference to the local audio feed).
            AudioStream = new AudioStream(LocalMedia.LocalMediaStream);

            // Create a WebRTC video stream description (requires a
            // reference to the local video feed). Whenever a P2P link
            // initializes using this description, position and display
            // the remote video control on-screen by passing it to the
            // layout manager created above. Whenever a P2P link goes
            // down, remove it.
            VideoStream = new VideoStream(LocalMedia.LocalMediaStream);
            VideoStream.OnLinkInit += AddRemoteVideoControl;
            VideoStream.OnLinkDown += RemoveRemoteVideoControl;

            // Create a new IceLink conference.
            Conference = new FM.IceLink.Conference(IceLinkServerAddress, new Stream[] { AudioStream, VideoStream });

            // Supply TURN relay credentials in case we are behind a
            // highly restrictive firewall. These credentials will be
            // verified by the TURN server.
            Conference.RelayUsername = "******";
            Conference.RelayPassword = "******";

            // Add a few event handlers to the conference so we can see
            // when a new P2P link is created or changes state.
            Conference.OnLinkInit += LogLinkInit;
            Conference.OnLinkUp += LogLinkUp;
            Conference.OnLinkDown += LogLinkDown;

            // Attach signalling to the conference.
            Signalling.Attach(Conference, SessionId, callback);
        }
Пример #15
0
        public void StopConference(Action<string> callback)
        {
            // Detach signalling from the conference.
            Signalling.Detach((error) =>
            {
                Conference.OnLinkInit -= LogLinkInit;
                Conference.OnLinkUp   -= LogLinkUp;
                Conference.OnLinkDown -= LogLinkDown;
                Conference = null;

                VideoStream.OnLinkInit -= AddRemoteVideoControl;
                VideoStream.OnLinkDown -= RemoveRemoteVideoControl;
                VideoStream = null;

                AudioStream = null;
                
                callback(error);
            });
        }
Пример #16
0
		public void Attach(FM.IceLink.Conference conference, Action<Exception> callback)
		{
			try {
				this.Conference = conference;

				conference.OnLinkOfferAnswer += (e) =>
				{
					try {
						Signal signal = new Signal();
						signal.PeerId = e.PeerId;
						signal.DataJson = e.OfferAnswer.ToJson();
						#if USE_TCP_SIGNALLING
							TCPSender<Signal> sender = new TCPSender<Signal> ();
							if (sender.Connect (IPAddress, TCP_PORT_SIGNALLING)) {
								sender.Send (TCP_MESSAGE_OFFER_ANSWER, signal);
								sender.Disconnect ();
							}
						#else
							UDPSender<Signal> sender = new UDPSender<Signal>();
							sender.Send(TCP_MESSAGE_OFFER_ANSWER,signal,this.IPAddress,TCP_PORT_SIGNALLING);
						#endif

					}
					catch (Exception ex)
					{
						Console.WriteLine(ex.Message);
					}
						
				};
				conference.OnLinkCandidate += (e) =>
				{
					try {
						Signal signal = new Signal();
						signal.PeerId = e.PeerId;
						signal.DataJson = e.Candidate.ToJson();
						#if USE_TCP_SIGNALLING
							TCPSender<Signal> sender = new TCPSender<Signal> ();
							if (sender.Connect (IPAddress, TCP_PORT_SIGNALLING)) {
								sender.Send (TCP_MESSAGE_CANDIDATE, signal);
								sender.Disconnect ();
							}
						#else
							UDPSender<Signal> sender = new UDPSender<Signal>();
							sender.Send(TCP_MESSAGE_CANDIDATE,signal,this.IPAddress,TCP_PORT_SIGNALLING);
						#endif


					}
					catch (Exception ex)
					{
						Console.WriteLine(ex.Message);
					}
						
				};					
			}
			catch (Exception ex)
			{
				callback(ex);
			}
		}
Пример #17
0
		public void StartConference(ViewGroup videoContainer, Action<Exception> callback)
		{           
			try {                   
				var localVideoControl = LocalMedia.LocalVideoControl;
				var layoutManager = new AndroidLayoutManager (videoContainer);					                   
				layoutManager.SetLocalVideoControl (localVideoControl);					                   
				var videoStream = new VideoStream (LocalMedia.LocalStream);
				videoStream.OnLinkInit += (e) => {
					var remoteVideoControl = e.Link.GetRemoteVideoControl ();
					layoutManager.AddRemoteVideoControl (e.PeerId, remoteVideoControl);
				};
				videoStream.OnLinkDown += (e) => {
					layoutManager.RemoveRemoteVideoControl (e.PeerId);
				};

				// Create a conference using our stream descriptions.
				Conference = new FM.IceLink.Conference (videoStream);                
				Conference.MaxLinks = 1;

				Signalling.Attach (Conference, (ex) => {
					if (ex != null) {
						ex = new Exception ("Could not attach signalling to conference.", ex);
						LastStartConferenceException = ex;
					}

					callback (ex);
				});
			} catch (Exception ex) {
				LastStartConferenceException = ex;
				callback (ex);
			}          
        
		}
Пример #18
0
		public void StopLink()
		{
			try {
				if (Signalling != null) {
					Signalling.Stop (null);
					Signalling = null;
				}
			} catch {}

			try {
				if (LocalMedia != null) {
					LocalMedia.Stop (null);
					LocalMedia = null;
				}
			} catch {}

			try {
				if (Conference != null) {
					Conference.UnlinkAll ();
					Conference = null;
				}
			} catch {}
					
		}
Пример #19
0
        //Video Chat is the main form
        public void StartConference(MainPage videoWindow, Action<Exception> callback)
        {
            if (!SignallingExists())
            {
                callback(new Exception("Signalling must exist before starting a conference."));
            }
            else if (!LocalMediaExists())
            {
                callback(new Exception("Local media must exist before starting a conference."));
            }
            else if (ConferenceExists())
            {
                //trying to start a conference again
                callback(signalling.LastConferenceException);
            }
            else
            {
                try
                {
                    var localMediaStream = localMedia.LocalStream;
                    
                    // This is our local video control, a WinForms Control or
                    // WPF FrameworkElement. It is constantly updated with
                    // our live video feed since we requested video above.
                    // Add it directly to the UI or use the IceLink layout
                    // manager, which we do below.
                    var localVideoControl = localMedia.LocalVideoControl;

                    // Create an IceLink layout manager, which makes the task
                    // of arranging video controls easy. Give it a reference
                    // to a WinForms control that can be filled with video feeds.
                    // For WPF users, the WebRTC extension includes
                    // WpfLayoutManager, which accepts a Canvas.
                    var layoutManager = localMedia.LayoutManager;

                    // Create a WebRTC audio stream description (requires a
                    // reference to the local audio feed).
                    var audioStream = new AudioStream(localMediaStream);

                    // Create a WebRTC video stream description (requires a
                    // reference to the local video feed). Whenever a P2P link
                    // initializes using this description, position and display
                    // the remote video control on-screen by passing it to the
                    // layout manager created above. Whenever a P2P link goes
                    // down, remove it.
                    var videoStream = new VideoStream(localMediaStream);
                    videoStream.OnLinkInit += (e) =>
                    {
                        var remoteVideoControl = (FrameworkElement)e.Link.GetRemoteVideoControl();
                        layoutManager.AddRemoteVideoControl(e.PeerId, remoteVideoControl);

                        // When double-clicked, mute/unmute the remote video.
                        videoWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
                        {
                            // When double-tapped, mute/unmute the remote video.
                            remoteVideoControl.DoubleTapped += (sender, ce) =>
                            {
                                if (e.Link.RemoteVideoIsMuted())
                                {
                                    // Resume rendering incoming video.
                                    e.Link.UnmuteRemoteVideo();
                                }
                                else
                                {
                                    // Stop rendering incoming video.
                                    e.Link.MuteRemoteVideo();
                                }
                            };
                        });
                    };
                    videoStream.OnLinkDown += (e) =>
                    {
                        layoutManager.RemoveRemoteVideoControl(e.PeerId);
                    };

                    // Create a new IceLink conference.
                    conference = new FM.IceLink.Conference(IceLinkServerAddress, new Stream[] { audioStream, videoStream });

                    //Use our generated DTLS certificate.
                    conference.DtlsCertificate = Certificate;
                    
                    // Supply TURN relay credentials in case we are behind a
                    // highly restrictive firewall. These credentials will be
                    // verified by the TURN server.
                    conference.RelayUsername = "******";
                    conference.RelayPassword = "******";

                    // Add a few event handlers to the conference so we can see
                    // when a new P2P link is created or changes state.
                    conference.OnLinkInit += (e) =>
                    {
                        Log.Info("Link to peer initializing...");
                    };
                    conference.OnLinkUp += (e) =>
                    {
                        Log.Info("Link to peer is UP.");
                    };
                    conference.OnLinkDown += (e) =>
                    {
                        Log.InfoFormat("Link to peer is DOWN. {0}", e.Exception.Message);
                    };
                    callback(null);
                }
                catch (Exception ex)
                {
                    callback(ex);
                }
            }
        }
Пример #20
0
        public void Detach(Action<string> callback)
        {
            if (UseWebSyncExtension)
            {
                // Leave the managed WebSync channel.
                WebSyncClient.LeaveConference(new LeaveConferenceArgs("/" + SessionId)
                {
                    OnFailure = (e) =>
                    {
                        callback(string.Format("Could not detach signalling from conference {0}. {1}", SessionId, e.Exception.Message));
                    },
                    OnSuccess = (e) =>
                    {
                        Conference = null;
                        SessionId = null;

                        callback(null);
                    }
                });
            }
            else
            {
                // Unsubscribe from the WebSync channel.
                WebSyncClient.Unsubscribe(new UnsubscribeArgs("/" + SessionId)
                {
                    OnFailure = (e) =>
                    {
                        callback(string.Format("Could not detach signalling from conference {0}. {1}", SessionId, e.Exception.Message));
                    },
                    OnSuccess = (e) =>
                    {
                        // Detach our event handlers.
                        Conference.OnLinkOfferAnswer -= SendOfferAnswer;
                        Conference.OnLinkCandidate -= SendCandidate;
                        WebSyncClient.OnNotify -= ReceiveOfferAnswerOrCandidate;

                        Conference = null;
                        SessionId = null;

                        callback(null);
                    }
                });
            }
        }
Пример #21
0
        public void Attach(FM.IceLink.Conference conference, string sessionId, Action<string> callback)
        {
            Conference = conference;
            SessionId = sessionId;

            // IceLink includes a WebSync client extension that will
            // automatically manage session negotiation for you. If
            // you are not using WebSync, see the 'else' block for a
            // session negotiation template.
            if (UseWebSyncExtension)
            {
                // Manage the conference automatically using a WebSync
                // channel. P2P links will be created automatically to
                // peers that join the same channel.
                WebSyncClient.JoinConference(new JoinConferenceArgs("/" + SessionId, conference)
                {
                    OnFailure = (e) =>
                    {
                        callback(string.Format("Could not attach signalling to conference {0}. {1}", SessionId, e.Exception.Message));
                    },
                    OnSuccess = (e) =>
                    {
                        callback(null);
                    }
                });
            }
            else
            {
                // When the conference generates an offer/answer or candidate,
                // we want to send it to the remote peer immediately.
                Conference.OnLinkOfferAnswer += SendOfferAnswer;
                Conference.OnLinkCandidate += SendCandidate;

                // When we receive an offer/answer or candidate, we want to
                // inform the conference immediately.
                WebSyncClient.OnNotify += ReceiveOfferAnswerOrCandidate;

                // Subscribe to a WebSync channel. When another client joins the same
                // channel, create a P2P link. When a client leaves, destroy it.
                WebSyncClient.Subscribe(new SubscribeArgs("/" + SessionId)
                {
                    OnFailure = (e) =>
                    {
                        callback(string.Format("Could not attach signalling to conference {0}. {1}", SessionId, e.Exception.Message));
                    },
                    OnReceive = (e) => { },
                    OnSuccess = (e) =>
                    {
                        callback(null);
                    }
                }
                .SetOnClientSubscribe((e) =>
                {
                    // Kick off a P2P link.
                    var peerId = e.SubscribedClient.ClientId.ToString();
                    var peerState = e.SubscribedClient.BoundRecords;
                    Conference.Link(peerId, peerState);
                })
                .SetOnClientUnsubscribe((e) =>
                {
                    // Tear down a P2P link.
                    var peerId = e.UnsubscribedClient.ClientId.ToString();
                    Conference.Unlink(peerId);
                }));
            }
        }
		public ConferenceWrapper(string sessionId, 
		                         LocalMedia localMedia)
		{
			this.LocalMedia = localMedia;
			InitAudioAndVideoStreams();

			// Create a conference using our stream descriptions.
			conference = new FM.IceLink.Conference(this.IceServers, new Stream[] { audioStream, videoStream });

			// Use our pre-generated DTLS certificate.
			conference.DtlsCertificate = Certificate;

			// Supply TURN relay credentials in case we are behind a
			// highly restrictive firewall. These credentials will be
			// verified by the TURN server.
			conference.RelayUsername = "******";
			conference.RelayPassword = "******";
			conference.ServerPort = 3478;

			// Add a few event handlers to the conference so we can see
			// when a new P2P link is created or changes state.
			conference.OnLinkInit += LogLinkInit;
			conference.OnLinkUp += LogLinkUp;
			conference.OnLinkDown += LogLinkDown;

			conference.OnLinkOfferAnswer += OnLinkSendOfferAnswer;
			conference.OnLinkCandidate += OnLinkSendCandidate;
			conference.Timeout = ConferenceTimeout;

#if __ANDROID__
			// Start echo canceller.
			OpusEchoCanceller = new OpusEchoCanceller(OpusClockRate, OpusChannels);
			OpusEchoCanceller.Start();
#endif

			this.sessionId = sessionId;
		}
		// TODO: will move to dispose
		/// <summary>
		/// Stops the conference.
		/// </summary>
		/// <returns>The conference.</returns>
		private void StopConference()
		{
			try
			{
#if __ANDROID__
				// Stop echo canceller.
				OpusEchoCanceller.Stop();
				OpusEchoCanceller = null;
#endif
				conference.OnLinkInit -= LogLinkInit;
				conference.OnLinkUp -= LogLinkUp;
				conference.OnLinkDown -= LogLinkDown;

				conference.OnLinkOfferAnswer -= OnLinkSendOfferAnswer;
				conference.OnLinkCandidate -= OnLinkSendCandidate;
				conference = null;

				videoStream.OnLinkInit -= AddRemoteVideoControl;
				videoStream.OnLinkDown -= RemoveRemoteVideoControl;
				videoStream = null;

				audioStream = null;
			}
			catch (Exception ex)
			{
				FM.Log.Debug(ex.ToString());
			}
		}
Пример #24
0
        public void Attach(FM.IceLink.Conference conference, string sessionId, Action <string> callback)
        {
            Conference = conference;
            SessionId  = sessionId;

            if (UseWebSyncExtension)
            {
                // Manage the conference automatically using a WebSync
                // channel. P2P links will be created automatically to
                // peers that join the same channel.
                WebSyncClient.JoinConference(new JoinConferenceArgs("/" + SessionId, conference)
                {
                    OnFailure = (e) =>
                    {
                        callback(string.Format("Could not join conference {0}. {1}", e.ConferenceChannel, e.Exception.Message));
                    },
                    OnSuccess = (e) =>
                    {
                        callback(null);
                    }
                });
            }
            else
            {
                // When the conference generates an offer/answer or candidate,
                // we want to send it to the remote peer immediately.
                Conference.OnLinkOfferAnswer += SendOfferAnswer;
                Conference.OnLinkCandidate   += SendCandidate;

                // When we receive an offer/answer or candidate, we want to
                // inform the conference immediately.
                WebSyncClient.OnNotify += ReceiveOfferAnswerOrCandidate;

                // Subscribe to a WebSync channel. When another client joins the same
                // channel, create a P2P link. When a client leaves, destroy it.
                WebSyncClient.Subscribe(new SubscribeArgs("/" + SessionId)
                {
                    OnFailure = (e) =>
                    {
                        callback(string.Format("Could not attach signalling to conference {0}. {1}", SessionId, e.Exception.Message));
                    },
                    OnReceive = (e) => { },
                    OnSuccess = (e) =>
                    {
                        callback(null);
                    }
                }
                                        .SetOnClientSubscribe((e) =>
                {
                    // Kick off a P2P link.
                    var peerId    = e.SubscribedClient.ClientId.ToString();
                    var peerState = e.SubscribedClient.BoundRecords;
                    Conference.Link(peerId, peerState);
                })
                                        .SetOnClientUnsubscribe((e) =>
                {
                    // Tear down a P2P link.
                    var peerId = e.UnsubscribedClient.ClientId.ToString();
                    Conference.Unlink(peerId);
                }));
            }
        }
Пример #25
0
        //Video Chat is the main form
        public void StartConference(MainPage videoWindow, Action <Exception> callback)
        {
            if (!SignallingExists())
            {
                callback(new Exception("Signalling must exist before starting a conference."));
            }
            else if (!LocalMediaExists())
            {
                callback(new Exception("Local media must exist before starting a conference."));
            }
            else if (ConferenceExists())
            {
                //trying to start a conference again
                callback(signalling.LastConferenceException);
            }
            else
            {
                try
                {
                    var localMediaStream = localMedia.LocalStream;

                    // This is our local video control, a WinForms Control or
                    // WPF FrameworkElement. It is constantly updated with
                    // our live video feed since we requested video above.
                    // Add it directly to the UI or use the IceLink layout
                    // manager, which we do below.
                    var localVideoControl = localMedia.LocalVideoControl;

                    // Create an IceLink layout manager, which makes the task
                    // of arranging video controls easy. Give it a reference
                    // to a WinForms control that can be filled with video feeds.
                    // For WPF users, the WebRTC extension includes
                    // WpfLayoutManager, which accepts a Canvas.
                    var layoutManager = localMedia.LayoutManager;

                    // Create a WebRTC audio stream description (requires a
                    // reference to the local audio feed).
                    var audioStream = new AudioStream(localMediaStream);

                    // Create a WebRTC video stream description (requires a
                    // reference to the local video feed). Whenever a P2P link
                    // initializes using this description, position and display
                    // the remote video control on-screen by passing it to the
                    // layout manager created above. Whenever a P2P link goes
                    // down, remove it.
                    var videoStream = new VideoStream(localMediaStream);
                    videoStream.OnLinkInit += (e) =>
                    {
                        var remoteVideoControl = (FrameworkElement)e.Link.GetRemoteVideoControl();
                        layoutManager.AddRemoteVideoControl(e.PeerId, remoteVideoControl);

                        // When double-clicked, mute/unmute the remote video.
                        videoWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async() =>
                        {
                            // When double-tapped, mute/unmute the remote video.
                            remoteVideoControl.DoubleTapped += (sender, ce) =>
                            {
                                if (e.Link.RemoteVideoIsMuted())
                                {
                                    // Resume rendering incoming video.
                                    e.Link.UnmuteRemoteVideo();
                                }
                                else
                                {
                                    // Stop rendering incoming video.
                                    e.Link.MuteRemoteVideo();
                                }
                            };
                        });
                    };
                    videoStream.OnLinkDown += (e) =>
                    {
                        layoutManager.RemoveRemoteVideoControl(e.PeerId);
                    };

                    // Create a new IceLink conference.
                    conference = new FM.IceLink.Conference(IceLinkServerAddress, new Stream[] { audioStream, videoStream });

                    //Use our generated DTLS certificate.
                    conference.DtlsCertificate = Certificate;

                    // Supply TURN relay credentials in case we are behind a
                    // highly restrictive firewall. These credentials will be
                    // verified by the TURN server.
                    conference.RelayUsername = "******";
                    conference.RelayPassword = "******";

                    // Add a few event handlers to the conference so we can see
                    // when a new P2P link is created or changes state.
                    conference.OnLinkInit += (e) =>
                    {
                        Log.Info("Link to peer initializing...");
                    };
                    conference.OnLinkUp += (e) =>
                    {
                        Log.Info("Link to peer is UP.");
                    };
                    conference.OnLinkDown += (e) =>
                    {
                        Log.InfoFormat("Link to peer is DOWN. {0}", e.Exception.Message);
                    };
                    callback(null);
                }
                catch (Exception ex)
                {
                    callback(ex);
                }
            }
        }