/// <summary> /// Entry point for the reading task which read incoming messages from the /// receiving pipe and dispatch them through events to the WebRTC peer. /// </summary> private void ProcessIncomingMessages() { // ReadLine() will block while waiting for a new line string line; while ((line = _recvStream.ReadLine()) != null) { Console.WriteLine($"[<-] {line}"); if (line == "ice") { string sdpMid = _recvStream.ReadLine(); int sdpMlineindex = int.Parse(_recvStream.ReadLine()); // The ICE candidate is a multi-line field, ends with an empty line string candidate = ""; while ((line = _recvStream.ReadLine()) != null) { if (line.Length == 0) { break; } candidate += line; candidate += "\n"; } Console.WriteLine($"[<-] ICE candidate: {sdpMid} {sdpMlineindex} {candidate}"); var iceCandidate = new IceCandidate { SdpMid = sdpMid, SdpMlineIndex = sdpMlineindex, Content = candidate }; IceCandidateReceived?.Invoke(iceCandidate); } else if (line == "sdp") { string type = _recvStream.ReadLine(); // The SDP message content is a multi-line field, ends with an empty line string sdp = ""; while ((line = _recvStream.ReadLine()) != null) { if (line.Length == 0) { break; } sdp += line; sdp += "\n"; } Console.WriteLine($"[<-] SDP message: {type} {sdp}"); var message = new SdpMessage { Type = SdpMessage.StringToType(type), Content = sdp }; SdpMessageReceived?.Invoke(message); } } Console.WriteLine("Finished processing messages"); }
private async Task <string> ProcessIncomingMessage() { byte[] buffer = new byte[Config.SIGNALING_BUFFER_SIZE]; WebSocketReceiveResult result = await this.webSocket.ReceiveAsync(new ArraySegment <byte>(buffer), CancellationToken.None); var messageBytes = new ArraySegment <byte>(buffer, 0, result.Count).ToArray(); using (MemoryStream ms = new MemoryStream(messageBytes)) { StreamReader streamReader = new StreamReader(ms); string messageStr = streamReader.ReadLine(); if (messageStr == "null") { return("continue"); } if (messageStr == null) { return("end"); } Dictionary <string, string> messageJson = JsonConvert.DeserializeObject <Dictionary <string, string> >(messageStr); if (messageJson.ContainsKey("sdp")) { string type = messageJson["type"]; string sdp = messageJson["sdp"]; Console.WriteLine("[<-] sdp"); Console.WriteLine(type); Console.WriteLine(sdp); SdpMessage msg = new SdpMessage(); msg.Type = SdpMessage.StringToType(type); msg.Content = sdp; SdpMessageReceived?.Invoke(msg); } else if (messageJson.ContainsKey("candidate")) { string sdpMid = messageJson["sdpMid"]; string sdpMLineIndex = messageJson["sdpMLineIndex"]; string candidate = messageJson["candidate"]; Console.WriteLine("[<-] ice"); Console.WriteLine(candidate); Console.WriteLine(sdpMLineIndex); Console.WriteLine(sdpMid); IceCandidate msg = new IceCandidate(); msg.SdpMid = sdpMid; msg.SdpMlineIndex = Int32.Parse(sdpMLineIndex); msg.Content = candidate; IceCandidateReceived?.Invoke(msg); } } if (result.CloseStatus.HasValue) { return("end"); } else { return("continue"); } }
static async Task Main() { try { Console.WriteLine("Starting..."); //create and Initialize capture object to record audio var waveFormat = new WaveFormat(44100, 32, 2, AudioEncoding.MpegLayer3); WasapiCapture capture = new WasapiCapture(true, AudioClientShareMode.Shared, 100, waveFormat); //initialize the selected device for recording capture.Initialize(); //fill ice servers here List <string> urls = new List <string>(); using var pc = new PeerConnection(); var config = new PeerConnectionConfiguration { IceServers = new List <IceServer> { new IceServer { Urls = urls, } } , BundlePolicy = BundlePolicy.MaxBundle }; await pc.InitializeAsync(config); Console.WriteLine("Peer connection initialized."); //create audio transceiver Transceiver transceiver = pc.AddTransceiver(MediaKind.Audio); transceiver.DesiredDirection = Transceiver.Direction.ReceiveOnly; Console.WriteLine("Create audio transceiver ..."); DataChannel chanel = await pc.AddDataChannelAsync("Data", true, true, cancellationToken : default); string url = ""; WebSocketSharp.WebSocket signaling = new WebSocket(url); signaling.SslConfiguration.EnabledSslProtocols = System.Security.Authentication.SslProtocols.Tls12; signaling.OnMessage += async(sender, message) => { try { //response messages may differ from service provider to another, adjust WebsocketResponse object accordingly var messageObject = JsonConvert.DeserializeObject <WebsocketResponse>(message.Data); var mess = new SdpMessage { Content = messageObject.Data.Sdp, Type = SdpMessage.StringToType("answer") }; if (!string.IsNullOrEmpty(mess.Content)) { Console.WriteLine("Sdpmessage: {0}, Type: {1}", mess.Content, mess.Type); await pc.SetRemoteDescriptionAsync(mess); if (mess.Type == SdpMessageType.Answer) { bool res = pc.CreateAnswer(); Console.WriteLine("Answer created? {0}", res); } } } catch (Exception e) { Console.WriteLine(e.Message); } }; signaling.OnError += (sender, e) => { Console.WriteLine(e.Message, e.Exception); }; signaling.OnOpen += (sender, e) => { pc.CreateOffer(); Console.WriteLine("open"); }; signaling.Connect(); transceiver.Associated += (tranciever) => { Console.WriteLine("Transivier: {0}, {1}", tranciever.Name, tranciever.StreamIDs); }; pc.LocalSdpReadytoSend += (SdpMessage message) => { Console.WriteLine(message.Content); //modify the offer message according to your need var data = new { streamId = "", sdp = message.Content }; var payload = JsonConvert.SerializeObject(new { type = "cmd", transId = 0, name = "view", data = data }); Console.WriteLine("Sdp offer to send: " + payload); signaling.Send(payload); }; pc.RenegotiationNeeded += () => { Console.WriteLine("Regotiation needed"); }; //when a remote audio track is added, start recording pc.AudioTrackAdded += (RemoteAudioTrack track) => { //create a wavewriter to write the data to WaveWriter w = new WaveWriter("audio.mp3", capture.WaveFormat); //setup an eventhandler to receive the recorded data capture.DataAvailable += (s, e) => { //save the recorded audio w.Write(e.Data, e.Offset, e.ByteCount); }; //start recording capture.Start(); //this should output the sound track.OutputToDevice(true); //track.AudioFrameReady += (AudioFrame frame) => //{ //you can print anything here if you want to make sure that's you're recieving audio //}; }; pc.Connected += () => { Console.WriteLine("Connected"); Console.WriteLine(pc.DataChannels.Count); }; pc.IceStateChanged += (IceConnectionState newState) => { Console.WriteLine($"ICE state: {newState}"); }; Console.WriteLine("Press enter to stop"); Console.ReadLine(); //stop recording capture.Stop(); pc.Close(); signaling.Close(); Console.WriteLine("Program termined."); } catch (Exception e) { Console.WriteLine(e.Message); } }