In an ideal world, you'd send 1080p high profile h264 encoded with a bitrate above 8Mbps (or CRF 18 for x264 nerds), with a max keyframe interval of around 5 seconds. Closed GOPs also makes processing more efficient.
I think one huge difference between Twitch and YouTube is that the CEO of Twitch will still personally respond to someone on HN when they have troubles streaming :'D
NAT traversal is part of ICE, but another part is formally specifying things like how to trigger accepting a connection, and which connection can be tied to which WebRTC session. This can actually make it easier, not harder, to use WebRTC.
In addition, the SDP exchange also sets up DTLS, making sure that whoever the WebRTC SDP was exchanged with is the same as whoever connects at a low-level. While you can implement this as a messaging exchange over UDP once the connection is established, its a nice property that WebRTC doesn't even allow the connection to be established with a non-secured link.
I think the hardest part of the stack is getting a decent, stand-alone implementation. With things like Websockets creating a server is straightforward, but libraries for low-level webrtc are much harder to build.
You must supply a STUN/Turn server to the browser when setting up the connection, but if you're connecting to a public server you can use ICE-Lite implementations server-side to simplify the setup.
I had exactly the same experience (albeit more recently) getting a simple WebRTC DataChannels implementation up-and-running.
Once you realize its just ICE + DTLS + SCTP, and that each layer has a corresponding library, the work getting it up and running is mainly just 'plumbing'.
If you're actively pursuing "the simplest server-side WebRTC UDP implementation" and the associated tech support then you should throw UDP into your project description and README alongside "DataChannels" for noobs like me.
Beyond the valid patent worries (Broadway.js uses Android code, which isn't cleared by the MPAA in the way the Cisco code is), I would be interested to have a proper comparison with jsmpeg in terms of FPS and battery use on mobile. I would assume there is a CPU cost associated with more complex decoding operations.
Edit: here is jsmpeg's author talking about it:
> There's been an experiment, called Broadway.js, which tries to decode H.264 in JavaScript. And there's some demos available, but I haven't been able to make this work consistently. It's very flaky. It tries to decode different stuff, and different threads And it barely works, if it works at all, so-- and you have to download, maybe, one megabyte of JavaScript for this. It's all part of EM script. [sic — emscripten?] And it's-- yeah, it's very complicated to get working, which is why the MPEG1 form of this is so nice for this, because it's so simple. And you end up with a decoder that's 30 kilobytes in size.
This seems risky to use in production due to H.264 patent issues. MPEG-1, on the other hand, could seemingly work as a drop-in replacement for GIFs in a variety of cases with no such worries.
Media source extensions don't give you the low-level control needed for low-latency and streams need to be re-muxed into fMP4. Web-RTC is a good option, but the infrastructure required can be a non-starter for many projects. For example, native webRTC libraries for golang are currently lacking to support needed to stream low-latency video.