Janus WebRTC Server
janus.conf.meetecho.com
janus.conf.meetecho.com
http://lup.lub.lu.se/luur/download?func=downloadFile&recordO...
One of the most useful/interesting use cases to me is the ability to have a PTP encrypted stream without having to go through weird IoT PKI hoops.
Ninja edit: If anyone has experience with Janus and/or WebRTC on edge devices I would very much like to talk as I could really use a solid consultant in this realm.
Kurento offers a variety of features apart from WebRTC, but it is more intended to be cloud-deployed as an independent media server, you could think of it as a "proxy/bridge" that distributes media between producers (like RTSP cameras) and consumers (WebRTC clients).
If those features are not needed, for purely WebRTC routing there's also mediasoup, with the same philosophy: N media producers send video to a central server, and the server distributes it to M devices consuming the media.
True peer-to-peer comms (i.e. sending data directly from producers to consumers, without an intermediate centralized server) was a cool thing to aim for by the WebRTC standard, but real-world practical constraints (i.e. bandwidth) put a limit to the usefulness of a truly p2p architecture. You'll find more info about this searching for MCU and SFU.
I'm having a hard time figuring out direct streaming from device on your local LAN without having to go out/back-in through the public internet with a hard requirement of an encrypted "point-to-point" communication (ie: can't listen into streams) which is browser trusted + the ability to ship that out to a "proxy/bridge" media server solution like you describe.
I've looked at EvoStream and Wowza as licensed solutions and I am super interested in the ability to use something like Kurento with ideally self-signed certificates to a cloud-deployed/redundant media bridge that then in-turn broadcasts to the remote clients who are consuming via the public internet.
The OpenCV tie-in with Kurento would be of great interest to me as well. That could be a game changer for what I'm currently embarking on!
Would a hybrid approach make sense to you as you're definitely an expert in this space? (ie: using Janus on-edge and Kurento in the cloud at the same time)
PS: I apologize if my questions/communication is rough... I'm two weeks into a nightmare trying to sort all of this out so I'm still coming up-to-speed on the technical details of WebRTC + secure streaming!
This however would have the bridge in the middle of LAN connections, so it wouldn't be a point-to-point flow, and the server would be able to "see" data passing through it.
There is however some new work on what's called "insertable streams" in Janus, which would allow e2e encryption directly between sender and receiver, thus having the media bridge purely act as a "blind" router, not being able to see the streams passed through it.
Janus has some very recent support for this [0], while this is (for now at least) not standardized and out of scope for Kurento.
I really like your Stylus project btw!
https://github.com/mmastrac/gst-omx-rpi-docker
I run this with the following config (just remember to map the RPi /dev/vchiq device into the container!):
gst-launch-1.0 rtspsrc location="rtsp://admin:(password)@(host):554/cam/realmonitor?channel=1&subtype=0" latency=500 ! rtph264depay ! h264parse ! omxh264dec ! omxh264enc target-bitrate=500000 control-rate=1 ! video/x-h264, profile=baseline ! h264parse ! rtph264pay name=pay0 config-interval=1 pt=96 ! udpsink host=(janus) port=8004 sync=false
The second part is the Janus configuration magic that creates the appropriate stream: [gstreamer-sample]
type = rtp
id = 1
audio = no
video = yes
videoport = 8004
videopt = 96
videortpmap = H264/90000
videofmtp = profile-level-id=42E01F\;packetization-mode=1\;level-asymmetry-allowed=1
videobufferkf = yes
> I really like your Stylus project btw!Thanks! Been working on Stylus a bit more this weekend. Nearly have all the features I need for my own setup.
Most customers run an MCU/SFU on a server, but then just a WebRTC client on the device. We do simulcast on the device to an SFU, and then distribute from there. Happy to answer questions here or directly.
I don't want to be disrespectful and sell other stuff on this thread though. I like seeing people realize how great Janus is :) don't want to distract from that conversation!
PS: I know that Amazon has a product in the space and we're vetting AWS as our cloud provider due to it's diverse product offering. I've been looking at opensource solutions due to vendor lock-in but would love to hear if you have any experience with the Amazon offering!
I also wrote Pion WebRTC, the Amazon offering is just a re-implementation of that in C. Just trying to decouple media pipelines and transport. I think WebRTC is a really great protocol, hopefully we can get software to match it :)
I've long been curious about MIPS from a hobbyist/tinkerer/maker perspective and would be very interested to know what silicon I might select at a similar price point.
You'll have to correctly deploy your servers, a TURN server to aid with ICE (NAT/Firewall traversal), and configure it all appropriately in both server and client browser applications. It is surprising how many people have problems with getting ICE, STUN and TURN servers, to work correctly, understandably because it is a complex topic.
Then once you have the basics of streaming media over the network, and your application developed (think video-based customer support, education conference, any stuff for which WebRTC is a good choice), there are still a myriad of things to worry about for a production-grade service: user permissions, autoscaling, metrics gathering, dynamic distribution of all the video streams through multiple media servers in order to accomodate for varying loads, etc.
While developing Kurento, I also work with the team that makes OpenVidu, a project that builds upon Kurento and aims to provide an all-in-one solution to all these problems, and handles all complexity of WebRTC for you.
Have a look at it if you need more than just the basics offered by media servers such as Janus, Jitsi, mediasoup, or Kurento itself:
[1] http://www.fedoa.unina.it/10403/1/miniero_lorenzo_27.pdf (PDF)
Can someone explain why webrtc needs a server and how Janus fulfills this role?
As far as I understand webrtc is meant to be peer to peer with minimal server signaling, so what role does a WebRTC server play?
* Less resource usage for users
If you do mesh signaling every user connect with each other via P2P. This means if you have a 4 person conference call everyone needs to upload their video 3 times. If you have a media server each user uploads only once, and then the server distributes the video. This means a lot less CPU and network usage for each user.
* P2P Connections reveal details about the user
If users are connecting directly to each other they are able to figure out details like their public IP. If you route everything through a server you can anonymize more things.
* Protocol Bridging
People want to view RTSP/RTMP/$X via WebRTC. A media server is the only way to make it happen.
* Less variability to deal with
When doing P2P connections you will deal with a lot more variables. It will be harder to figure out which user's internet is causing issue, or debug encode/decode issues. A few times running a SFU has come really in handy because I was able to debug something that would have been impossible when just doing P2P.
Absolute dream to work with! Thank you Lorenzo and the rest of the Janus team. Hopefully we'll get the chance to make it down to Janus Conf!
If anyone is looking for help adding it to their app hit me up!
Currently, Janus and Nginx (https/auth) run on a cheap VPS, and a device in the NAT network of the ip camera creates a Wireguard tunnel to get the RTSP stream to the VPS without needing to open/forward ports on the NAT.
Ideally, more of the components could run on the camera itself, but I haven't gotten to cross compile anything to the MIPS cpu of the Xiaomi camera. Will contact you so we can chat.
Oh well, you probably should use the rest api for generating credentials on the fly and think about scaling (depending on your needs).
[0] https://github.com/meetecho/janus-gateway/blob/master/plugin...
https://github.com/meetecho/janus-gateway/blob/master/plugin...
Yes: if you don't want any of the complex video functionality, you can easily write your own Janus plugin, and that maybe sounds reasonable for some trivial game "SFU" where you are just going to move around some data channel packets... but at that point you can (and I argue should) just use libwebrtc (I do this, and I helped one of my friends do this for his product in a weekend: people act like it is hard to compile but it really isn't).
(Even more so: the Lua script you linked to looks more like a demo/example of a way to use the Lua plugin to get some functionality vaguely similar to the VideoRoom plugin, and it is notably ridiculously long and contains a lot of codec-specific knowledge, while not having anywhere near the actual functionality of the actual real C VideoRoom plugin. It is as if Janus is just a super low-level WebRTC library in the form of a framework, with an explicitly monolithic plugin doing everything.)
> the vast majority of the VideoRoom functionality is written in C
It's still just a plugin that hooks the same callbacks and implements the same interfaces as any of the rest of them. Feel free to implement your own.
I would expect 100% of applications doing anything at all with video to want all of that functionality, but only some small number to have a "room" concept that maps to the idea of the specific schema imposed by the VideoRoom plugin. It is thereby strange that all of that general video functionality is commingled together in a 8k line C file with all of the high-level room abstraction... the answer with Janus is always "write your own plugin", but either you are doing something so trivial that Janus doesn't seem to be doing anything but the lowest level WebRTC layer, or, as far as I can tell, you have to fork the VideoRoom plugin and then hope you can merge changes from upstream back into your plugin.
Am I wrong here? Like, I would love to find out I am wrong here ;P. (Which is why I was asking the OP about if their "custom solution" was a fork of VideoRoom: to see if they told me something I don't know.) But when I skim through that C file (or even the Lua file! though that demo very notably seems "incomplete" vs. the "real" C copy) I see tons of code referencing all of the codec-specific negotiation and stuff that I would explicitly be using Janus to get, so I can't not use or fork the VideoRoom plugin without losing the purpose of the platform as I would be reimplementing all of the hard parts myself (again, unless you are doing something so trivial--broadly speaking, something that doesn't involve video--that you frankly should be using libwebrtc or one of its various alternatives, such as Pion).
If you want to implement E2E via insertable streams then you can start right here:
https://github.com/meetecho/janus-gateway/blob/master/plugin...
That said, the vast majority of people don't really need to write their own plugin, or even customizing existing ones. What we foster a lot is leveraging existing plugins as much as possible, maybe combining them at an application level, and not reinvent the wheel, and it seems to work for most (it certainly does for us, for our own applications).
On the Lua demo, it is indeed a bit more limited than the C counterpart (we clearly didn't invest as much time on it), but I'd disagree on the "incomplete" part. All the relevant parts are there, and most importantly, it's supposed to be much easier to extend and modify than the C version. There's at least one big company we're aware of that's using it in production and is very happy with it.
I would expect the logic for negotiating streams to be an unrelated layer of abstraction to the concept of room management? That the code and work 100% of video apps want--SVC, end to end encryption, negotiation complexity--is mixed up in the same giant C file as a monolithic plugin with the code for JSON configuration files of a "rooms" abstraction that is a hardcoded notion of a single narrow vision of a multiparty video chat server is really awkward, and means that at best every single application ends up either as a messy fork or with a thick middleware adapter that attempts to translate between these concepts.
It is like wanting a pub-sub solution to build your own chat system but being handed a full IRC server as your building block, where you either need to fork the system to rework the notion of "channel" and the various user mode flags to match how you want to do chat--and then hope you can easily still rebase your work to the latest codebase, as the implementation of basic things like "send a message and have other people receive it" is mixed together with the notion of "a half-operator is someone who can kick users but not change the list of operators"--or build some thick middleware adapter layer that is simulating a simpler pub-sub system on top of degenerate channels.
If the code for "rooms" was a different layer of abstraction from the code for "WebRTC VP9 SVC signaling", it would allow me to just build the parts I want on top--so I can get the semantics of a public government hearing, which is different from a business meeting or a webinar or a "house party" without figuring out how I am going to translate my concept onto the existing meeting semantics of the VideoRoom plugin--or at least if the code for this was cleanly placed into a separate C file then I would be much happier with this idea that I am supposed to "extend and modify" the codebase to implement my own semantics, as I wouldn't be so worried that one day I am going to get a merge conflict on this 8k line file full of C code I am hacking on :(.
If you forget about the videoroom.lua code and do something from scratch, you're free to handle the logic however you want: handling media is as simple as saying "send incoming media from A to B and C", and media-wise that's all you need to do in the script itself to have the C portion do the heavy lifting for you. You still need to take care of SDP and signalling, but you can do that on your own terms. I still have a plan to implement yet another plugin that delegates the logic to a remote node using something RPC-based, but unfortunately I didn't have time for that yet.
However our WebRTC stack has the minimum of congestion control features (plain REMB, no simulcast), and it doesn't implement SVC or newer toys like insertable streams, nor does it completely abstract you from the grunt work that WebRTC leaves up to the user (like signaling, setting up a TURN server, or having a minimum of understanding about ICE in order to troubleshoot when problems arise).
We have made some modifications to the Janus video room plugin but only to fix bugs or provide specific functionality we needed for certain gaming use-cases. Out of the box, the plugin is already very featureful. The key is to always stay up to date with master, the project is fairly active and so keeping up to date is very important.
We have debated writing our own plugin and that's certainly a possibility in the future. (There is a Duktape JS layer available) To be completely transparent, if we were to reach that need, I would re-evaluate the solution with more recent alternatives, like pion.ly.
Lorenzo and his colleagues are doing a really great job.
In the space of SFU/MFU, one really needs to decide beforehand what kind of solution is suitable for which requirement. I have chosen Janus because we could integrate it by 100% in our software. For example, I was also looking into Jitsi. But compared to Janus it feeled so much more complicated and not suited for that specific job.
However, it is important to point out, that this is no a ready-to-go solution. There is a long list of things you will have to dig into:
- ICE (a way to connect if you switch between WIFI and LAN or to punch a hole into your fw) [2]
- Cross-browser compatibility (Thank you iOS [4])
- TURN/STUN (Which matrix of udp/tcp and ports is needed for Hole Punching?), I recommend coturn.
- Scalability: How many clients are planned? In my experience, CPU and bandwith are bottlenecks, we went with horizontal scaling
- How do you gonna test your WebRTC application? So far great results with https://testrtc.com, but you probably also could accomplish a lot with Selenium.
- Simulcast/Bitrate or Unified Plan (Use available bandwith and adapt on-the-fly) [3][5]
But once you got it running, it is an amazing feeling. We are in 2020 and it is possible for an SMB to offer video conferencing to customers via a web-browser using your own infrastructure while being compliant to GPDR and other stuff.
[0] https://webrtchacks.com/slack-webrtc-slacking/
[1] https://janus.conf.meetecho.com/demos.html
[2] https://webrtcglossary.com/ice/
[3] https://webrtcbydralex.com/index.php/2018/03/14/extending-ja...
[4] https://webrtchacks.com/guide-to-safari-webrtc/
[5] https://www.callstats.io/blog/what-is-unified-plan-and-how-w...
We currently use Kurento for the easiness of usage + the Java client, but we have been wondering about other solutions like Janus.
It standardizes a set of conventions that web browsers could follow to a) solve the issue of NAT traversal (i.e. opening ports in consumer routers and firewalls), b) send video and audio (and possibly also arbitrary data), directly between web browsers, and c) possibly adapt the video quality to the conditions of the network, in an autonomous and automatic way.
That's the bird's-eye view of it.
Some keywords to expand on this: "a)" is done with the ICE protocol, "b)" is done with plain old SRTP, and "c)" is done with algorithms called REMB or Transport-CC.
* Slides - https://pion.github.io/talks/2018-11-28-seattle-video-tech.h...
* Video - https://www.youtube.com/watch?v=FdgoOrJH8ok&feature=youtu.be...
* Video - https://www.youtube.com/watch?v=ezZYd5NsxE4
------
But when I teach others I try to break it down into a few unique chunks.
* ICE - Establishing P2P Communication
* DTLS/SRTP - Securing Communication
* SCTP - Sending binary data over UDP and handling loss
* RTP/RTCP - Sending media data over UDP and handling loss
I found previous submissions, but no comments except https://news.ycombinator.com/item?id=22610510.