WebRTC

Apr 27, 2015 at 5:11 PM
I'm trying to get a working WebRTC setup together in C# and it looks like SIPSorcery would be a great place to get what I need. All of the WebRTC libraries that I can find are commercial, so rolling my own would be great for me and presumably others too! The problem is I'm still learning this stuff so it's a slow process. Can anyone help me to understand how I can use the ICE and STUN components of SIPSorcery to implement the RTCPeerConnection and RTCDataChannel stuff? Accepting candidates and figuring out the best route based on the SDP offer/answer/candidate signal types would be very helpful! Thanks in advance!
Coordinator
Apr 28, 2015 at 12:14 AM
Take a look at this sample program http://sipsorcery.codeplex.com/SourceControl/latest#sipsorcery-media/samples/WebRTCVideoServer/Program.cs. I wrote it a while ago and was able to get a one way video stream working where I displayed the contents of my webcam or a local file in a browser using WebRTC.

It's rough code as it was a prototype for my own purposes. It "may" help you and I'm happy to answer any questions on it.
May 2, 2015 at 6:42 PM
Thanks very much for responding to this! After a lot of work I was able to compile client parts of SIPSorcery for MonoAndroid (for Xamarin). I'm still pretty lost though. Lots of building blocks though, but I'm just trying to nail the PeerConnection stuff right now and I'm hitting roadblocks every which way. I have the JS side done (so many examples there!) but understanding the C# side is killing me. I have my own signaling working with SignalR, so I get SDP and candidates, but as far as adding and consuming streams, and really understanding how best to leverage SIPSorcery is lost on me. Any chance you can help out more?

Coordinator
May 4, 2015 at 1:28 PM
Can you give an overview of your application? Particularly where you are hoping to set up the WebRTC stream to/from.

I don't think compiling the client parts of SIPSorcery is going to help much. The WebRTC sample I referenced above doesn't even use the SIP stack. It does use some other bits and pieces from the code base such as the STUN and SDP classes.
May 4, 2015 at 6:41 PM
I want to mimic the RTCPeerConnection from browser-based WebRTC, but in a native app. There are solutions for doing this, but they all cost money. I can collect the STUN/TURN candidates on the browser side and sent them to my native client (currently using SignalR) but I'm not really sure how to package up my candidates on the native client side to send back, nor am I sure how to find the best candidate. It's all so easy when you are just using the browser WebRTC stuff!

Coordinator
May 5, 2015 at 1:21 AM
Yep that was my experience as well. WebRTC is easy to use if you're setting up a call between two browsers. If, as in your case, you want to set up a call with a non-browser app participant it's very difficult.

What is your native app running on? Is it a Windows PC? That's what the example I referenced is for.

As far as your ICE candidates go I'd recommend that initially you just send a single option bak to the browser. The general format of the SDP offer to send back to the WebRTC browser is:
_sourceSDPOffer = @"v=0
o=- 2925822133501083390 2 IN IP4 127.0.0.1
s=-
t=0 0
m=video {0} RTP/SAVPF 100
c=IN IP4 {1}
a=rtcp:{0} IN IP4 {1}
a=candidate:2675262800 1 udp 2122194687 {1} {0} typ host generation 0
a=ice-ufrag:{2}
a=ice-pwd:{3}
a=mid:video
a=sendonly
a=rtcp-mux
a=crypto:0 AES_CM_128_HMAC_SHA1_80 inline:{4}
a=rtpmap:100 VP8/90000
";
After the SDP exchange is done then you have to complete a STUN authentication exchange on the media sockets. And after that you have have to start sending and/or receiving the SRTP encrypted media packets, VP8 in the case of video. Getting the VP8 encoding parameters adjusted so that the Chrome WebRTC stack was happy was actually the hardest part for me.
May 5, 2015 at 2:36 AM
What I would REALLY love is an implementation with matching RTC* classes so it really was like on the JS side. That way the source samples for browser-to-browser just worked! (RTCPeerConnection, RTCSessionDescription...)

So I started with your sample that you sent, and made it work for PCL on MonoAndroid (had to remove all log4net and a number of other things). I'm still just confused about things though. For example, why does your _sourceSDPOffer use _localIPAddress which is hard-coded to 10.1.1.2? Shouldn't I have an actual list of ICE candidates to choose from? Where does the ice ufrag/pwd fit in? If I understand right, in a real implementation, the SDP would be constructed from the ICE candidates that each end finds. It seems that the STUNListener class should be able to help, but PCL's don't support much of System.Net, so it rules out IPEndPoint and IPAddress. Both SIPSorcery packages on Nuget won't support PCL on MonoAndroid.

Is this just the wrong direction to take? It's been a painful process so far!

Coordinator
May 6, 2015 at 1:47 AM
atkulp wrote:
What I would REALLY love is an implementation with matching RTC* classes so it really was like on the JS side. That way the source samples for browser-to-browser just worked! (RTCPeerConnection, RTCSessionDescription...)
I suspect you'll need to go back to the commercial libraries to get that level of polish.

atkulp wrote:
For example, why does your _sourceSDPOffer use _localIPAddress which is hard-coded to 10.1.1.2? Shouldn't I have an actual list of ICE candidates to choose from?
That's the IP address of the machine I was doing some testing from. And yes in a proper implementation you would generate a list of ICE candidates and put that in the SDP. For my purposes I only needed to create a one way video stream and therefore didn't go to the effort of gathering ICE candidates.

atkulp wrote:
Is this just the wrong direction to take? It's been a painful process so far!
And you haven't even got to the media encryption and encoding yet which is even more so. If you just want to use WebRTC without having to get into the internals of it then following my path is not the way to go. In my case I only needed to support a single scenario which was to stream a video from my native Windows application to a WebRTC browser. I did the bare minimum to get that working. To get a full feature complete WebRTC stack would be a big chunk of work.
May 6, 2015 at 3:58 AM
I am definitely seeing this to be the case! At this point, even just getting ICE candidate collection via STUN would help. I could technically do my own thing over the resultant connection right? I can't even find a STUN implementation in a PCL. Would you have an interest in partnering on doing that piece of it?

Coordinator
May 6, 2015 at 5:40 AM
ICE candidates are just a list of the IP address, port and protocol that your application can potentially be contacted on. STUN can get your public IP address & port for you if you are behind a NAT. STUN is a very simple protocol and there are a number of free servers around on the internet you could use. But again it's only going to let you know your internet accessible address nothing more.

I don't have a need for WebRTC at the moment and would struggle to find any time to work on it so I'm not going to be any help with the coding sorry.
May 6, 2015 at 7:14 AM
That's ok. Thanks for the response though! I'll work on the ICE stuff for now. I may have to do a custom frame sequence and DIY audio packets for now. I have to decide if paying for a commercial product is worth it. It amazes me that there aren't any PCL solutions yet