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'.
Hi! Nick here, author of librtcdcpp - mind elaborating on why you don't like log4cxx? Boost I get - I'm only using one or two easily-replaced headers, and would like to remove it next release :)
Hi! Thanks for linking my project - I'm currently trying to make librtcdcpp production-ready after having many issues with librtcdc. Patches very welcome!