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(); }
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."); }
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; }
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); } }
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)); }
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(); }
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(); }
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)); } }
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)); } }
//ピアの作成をする 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"); }
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(); }
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); }
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(); }
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(); }
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); } }
//ピアの作成をする 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"); }
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(); }
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(); }
/// <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); }
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(); }
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(); }