public SymplePlayerEngineWebRTC(SymplePlayer player) : base(player)
        {
            Messenger.Broadcast(SympleLog.LogInfo, "symple:webrtc: init");

#if NETFX_CORE
            if (!webrtcInitialized)
            {
                WebRTC.Initialize(null);    // needed before calling any webrtc functions http://stackoverflow.com/questions/43331677/webrtc-for-uwp-new-rtcpeerconnection-doesnt-complete-execution
                webrtcInitialized = true;
            }


            if (player.options.rtcConfig != null)
            {
                this.rtcConfig = player.options.rtcConfig;
            }
            else
            {
                this.rtcConfig = new RTCConfiguration();
                this.rtcConfig.IceServers.Add(new RTCIceServer()
                {
                    Url = "stun:stun.l.google.com:19302", Username = string.Empty, Credential = string.Empty
                });
            }
#endif

            /*
             * this.rtcOptions = player.options.rtcOptions || {
             *  optional: [
             *      { DtlsSrtpKeyAgreement: true } // required for FF <=> Chrome interop
             *  ]
             * };
             */

            // Specifies that this client will be the ICE initiator,
            // and will be sending the initial SDP Offer.
            this.initiator = player.options.initiator;
            Messenger.Broadcast(SympleLog.LogInfo, "symple:webrtc: constructor, set this.initiator to " + this.initiator);

#if NETFX_CORE
            // Reference to the active local or remote media stream
            this.activeStream = null;
#endif
        }
Beispiel #2
0
        public void initAndStartWebRTC()
        {
#if NETFX_CORE
            JObject CLIENT_OPTIONS = new JObject();
            CLIENT_OPTIONS["secure"]        = true;
            CLIENT_OPTIONS["url"]           = this.SignallingServerUrl;
            CLIENT_OPTIONS["peer"]          = new JObject();
            CLIENT_OPTIONS["peer"]["user"]  = this.LocalPeerUsername;
            CLIENT_OPTIONS["peer"]["name"]  = this.LocalPeerNameLabel;
            CLIENT_OPTIONS["peer"]["group"] = this.LocalPeerGroup;

            SymplePlayerOptions playerOptions = new SymplePlayerOptions();
            playerOptions.engine = "WebRTC";

            switch (UserType)
            {
            case StarUserType.TRAINEE:
                playerOptions.initiator = true;
                break;

            case StarUserType.MENTOR:
                playerOptions.initiator = false;
                break;

            default:
                break;
            }


            // WebRTC config
            // This is where you would add TURN servers for use in production
            RTCConfiguration WEBRTC_CONFIG = new RTCConfiguration
            {
                IceServers = new List <RTCIceServer> {
                    new RTCIceServer {
                        Url = "stun:stun.l.google.com:19302", Username = string.Empty, Credential = string.Empty
                    },
                    new RTCIceServer {
                        Url = "stun:stun1.l.google.com:19302", Username = string.Empty, Credential = string.Empty
                    },
                    new RTCIceServer {
                        Url = "stun:stun2.l.google.com:19302", Username = string.Empty, Credential = string.Empty
                    },
                    new RTCIceServer {
                        Url = "stun:stun3.l.google.com:19302", Username = string.Empty, Credential = string.Empty
                    },
                    new RTCIceServer {
                        Url = "stun:stun4.l.google.com:19302", Username = string.Empty, Credential = string.Empty
                    },
                    new RTCIceServer {
                        Url = "turn:numb.viagenie.ca", Username = "******", Credential = "0O@S&YfP$@56"
                    }
                }
            };

            playerOptions.rtcConfig = WEBRTC_CONFIG;
            //playerOptions.iceMediaConstraints = asdf; // TODO: not using iceMediaConstraints in latest code?
            playerOptions.onStateChange = (player, state, message) =>
            {
                player.displayStatus(state);
            };

            Messenger.Broadcast(SympleLog.LogInfo, "creating player");
            player = new SymplePlayer(playerOptions);

            Messenger.Broadcast(SympleLog.LogInfo, "creating client");
            client = new SympleClient(CLIENT_OPTIONS);

            client.on("announce", (peer) => {
                Messenger.Broadcast(SympleLog.LogInfo, "Authentication success: " + peer);
            });

            client.on("addPeer", (peerObj) =>
            {
                JObject peer = (JObject)peerObj;

                Messenger.Broadcast(SympleLog.LogInfo, "adding peer: " + peer);

                if (this.UserType == StarUserType.TRAINEE)
                {
                    // the TRAINEE user waits for a peer with a specific username, then once it's connected it automatically starts sending video

                    if ((string)peer["user"] == this.ExpectedRemoteReceiverUsername && !initialized)
                    {
                        initialized = true;
                        remotePeer  = peer;
                        startPlaybackAndRecording();
                    }
                }
            });

            client.on("presence", (presence) =>
            {
                Messenger.Broadcast(SympleLog.LogInfo, "Recv presence: " + presence);
            });

            client.on("removePeer", (peerObj) =>
            {
                JObject peer = (JObject)peerObj;

                Messenger.Broadcast(SympleLog.LogInfo, "Removing peer: " + peer);

                if (remotePeer != null && remotePeer["id"].Equals(peer["id"]))
                {
                    initialized = false;
                    remotePeer  = null;
                    player.engine.destroy();
                    player.engine = null;
                }
            });

            client.on("message", (mObj) =>
            {
                Messenger.Broadcast(SympleLog.LogTrace, "mObj.GetType().ToString(): " + mObj.GetType().ToString());

                JObject m = (JObject)((Object[])mObj)[0];

                Messenger.Broadcast(SympleLog.LogTrace, "recv message: " + m);
                Messenger.Broadcast(SympleLog.LogTrace, "remotePeer: " + remotePeer);

                var mFrom = m["from"];

                JToken mFromId = null;

                if (mFrom.Type == JTokenType.Object)
                {
                    mFromId = mFrom["id"];
                }

                if (remotePeer != null && !remotePeer["id"].Equals(mFromId))
                {
                    Messenger.Broadcast(SympleLog.LogInfo, "Dropping message from unknown peer: " + m);
                    return;
                }
                if (m["offer"] != null)
                {
                    switch (UserType)
                    {
                    case StarUserType.TRAINEE:
                        Messenger.Broadcast(SympleLog.LogInfo, "Unexpected offer for one-way streaming");
                        break;

                    case StarUserType.MENTOR:

                        Messenger.Broadcast(SympleLog.LogInfo, "Receive offer: " + m["offer"]);

                        remotePeer = (JObject)m["from"];

                        JObject playParams = new JObject();       // empty params
                        player.play(playParams);

                        var engine = (SymplePlayerEngineWebRTC)player.engine;

                        engine.recvRemoteSDP((JObject)m["offer"]);

                        engine.sendLocalSDP = (desc) =>
                        {
                            Messenger.Broadcast(SympleLog.LogInfo, "Send answer: " + desc);

                            JObject sessionDesc = new JObject();
                            sessionDesc["sdp"]  = desc.Sdp;
                            if (desc.Type == Org.WebRtc.RTCSdpType.Answer)
                            {
                                sessionDesc["type"] = "answer";
                            }
                            else if (desc.Type == Org.WebRtc.RTCSdpType.Offer)
                            {
                                sessionDesc["type"] = "offer";
                            }
                            else if (desc.Type == Org.WebRtc.RTCSdpType.Pranswer)
                            {
                                sessionDesc["type"] = "pranswer";
                            }

                            JObject parameters   = new JObject();
                            parameters["to"]     = remotePeer;
                            parameters["type"]   = "message";
                            parameters["answer"] = sessionDesc;

                            client.send(parameters);
                        };

                        engine.sendLocalCandidate = (cand) =>
                        {
                            JObject candidateObj          = new JObject();
                            candidateObj["candidate"]     = cand.Candidate;
                            candidateObj["sdpMid"]        = cand.SdpMid;
                            candidateObj["sdpMLineIndex"] = cand.SdpMLineIndex;

                            JObject parameters      = new JObject();
                            parameters["to"]        = remotePeer;
                            parameters["type"]      = "message";
                            parameters["candidate"] = candidateObj;

                            client.send(parameters);
                        };

                        break;

                    default:
                        break;
                    }
                }
                else if (m["answer"] != null)
                {
                    switch (UserType)
                    {
                    case StarUserType.TRAINEE:

                        SymplePlayerEngineWebRTC engine = (SymplePlayerEngineWebRTC)player.engine;

                        string answerJsonString = JsonConvert.SerializeObject(m["answer"], Formatting.None);

                        JObject answerParams = (JObject)m["answer"];

                        Messenger.Broadcast(SympleLog.LogTrace, "Receive answer: " + answerJsonString);
                        engine.recvRemoteSDP(answerParams);

                        break;

                    case StarUserType.MENTOR:

                        Messenger.Broadcast(SympleLog.LogInfo, "Unexpected answer for one-way streaming");

                        break;

                    default:
                        break;
                    }
                }
                else if (m["candidate"] != null)
                {
                    SymplePlayerEngineWebRTC engine = (SymplePlayerEngineWebRTC)player.engine;

                    JObject candidateParams = (JObject)m["candidate"];

                    Messenger.Broadcast(SympleLog.LogInfo, "Using Candidate: " + candidateParams);
                    engine.recvRemoteCandidate(candidateParams);
                }
            });

            client.on("disconnect", (peer) =>
            {
                Messenger.Broadcast(SympleLog.LogInfo, "Disconnected from server");
            });

            client.on("error", (error) =>
            {
                Messenger.Broadcast(SympleLog.LogError, "Connection error: " + error);
            });

            client.connect();
#else
            Messenger.Broadcast(SympleLog.LogInfo, "not actually connecting via webrtc because NETFX_CORE not defined (probably this is in the unity editor)");
#endif
        }
Beispiel #3
0
 public SymplePlayerEngine(SymplePlayer player)
 {
     this.player = player;
     this.fps    = 0;
     this.seq    = 0;
 }