We’ve talked many times about WHIP and WHEP on this blog post. Since before WHIP was even a thing on the IETF’s radar, we prototyped it with CoSMo, as it seemed like a great first step towards my dream (and Ph.D thesis topic) of having a pure WebRTC based broadcasting solution. We then covered it even more after it was adopted in the IETF WISH Working Group, until it was time to address how to distribute a WHIP ingested stream using WHEP, and all the updates it then went through. WHIP also was a great opportunity for us nerds to reference Indiana Jones over and over when talking about it, as I just did again in the picture above (we’re talking of WHIP and of a library, so what better picture than that? ).
Now that WHIP has officially become an RFC, and that WHEP has a new steward who’ll hopefully help it become a standard soon too, I thought it made sense to revisit my prototype efforts (which were all already available as open source software on GitHub) from all those previous posts, and get something out of them that might be more of use to interested developers.
TLDR; my WHIP and WHEP servers, both making use of the Janus WebRTC Server to power their WebRTC functionality, were originally conceived as standalone Node.js applications, and I refactored them as Node.js libraries instead, so that they could be easily integrated in existing applications (possibly both at the same time!). Want to know how, or what you can do with them now? Read on!
A quick recap on WHIP and WHEP
If you’ve never heard of WHIP and WHEP before, that intro you just read may have been very confusing to you. In the world of standard protocols, which makes such a heavy use of cryptic acronyms, that’s quite common when you’re not 100% familiar with some specific domains.
As anticipated in the intro, I’ve covered both extensively, so to get a good understanding of what those protocols are, I definitely recommend reading them first, possibly in order:
If you really don’t want to go through all that wall of text (and I wouldn’t blame you, I do tend to write way more than I should!), in a nutshell WHIP and WHEP try to pave the foundation for a specific use case, that is purely WebRTC-based broadcasting, as an alternative (and ultralow latency) solution to established standards like RTMP, HLS and DASH.
Specifically, WHIP (which stands for “WebRTC-HTTP Ingestion Protocol”) addresses how you can use basic HTTP requests to negotiate a WebRTC PeerConnection you’ll use to ingest media (a bit like RTMP is normally used in the broadcasting world), while WHEP (WebRTC-HTTP Egress Protocol) addresses its counterpart, that is how interested consumers can use HTTP to negotiate WebRTC PeerConnections to subscribe to media they want to receive instead. If you use both WHIP and WHEP at the same time, where media ingested via WHIP is then consumed via WHEP, you basically have a broadcasting solution where media is entirely WebRTC-based from the source up to the (possibly many) sinks.
Considering the extremely low-latency nature of WebRTC (which was originally conceived for conversational sessions, but has then evolved to cover way more scenarios than that), this potentially allows for much more interactive broadcasts, as consumers basically get media as soon as it’s actually produced, rather than, e.g., 30 seconds later as would be the norm for traditional broadcasting. Scaling these broadcasts is of course a challenge (traditional broadcasting has an established literature for that), but that’s orthogonal to WHIP and WHEP as protocols, which provide the building blocks to make this WebRTC 1-to-N flow possible in a standard way in the first place.
I mentioned how WebRTC broadcasting was the topic of my Ph.D thesis, 10 years ago, so I of course jumped at the opportunity of playing with both protocols as soon as they came out. As I explained in detail in my blog posts, I wrote basic Node.js applications that would translate the WHIP and WHEP signalling to the Janus API, thus allowing interested WHIP and WHEP clients to leverage Janus as the WebRTC engine to use for WebRTC broadcasting. Inspired by a lightning of creativity, I called those projects Simple WHIP Server and Simple WHEP Server respectively.
Considering the world of broadcasting is not usually web-based, at least not on the ingest side of things, at the time I also experimented on the client side. Specifically, I used the excellent GStreamer library to write standalone CLI clients for both protocols: the same bolt of creativity thus lead to the Simple WHIP Client (that would allow you to capture media locally and send it via WebRTC to a WHIP server) and to the Simple WHEP Server (which would on the other end subscribe to WHEP servers to receive and render WebRTC media in a window).
Now, this all worked great, and it was an excellent way of proving how Janus could easily be used to power a WebRTC broadcast by simply adding a thin signalling translation layer in front of it to handle the WHIP and WHEP messaging on its behalf. That said, I was never very happy with my WHIP and WHEP servers being standalone applications, as they felt like components you could not really easily integrate in existing frameworks, especially for the purpose of building something that could be richer in features, or more simply more production ready.
That’s what eventually led me to refactor the code to turn them into Node.js libraries instead, so that they could be embedded in existing applications to simply add WHIP/WHEP server functionality where required.
From Node.js application to Node.js library
As anticipated, both WHIP and WHEP servers were initially conceived as basic, and standalone, Node.js applications, implementing a thin shim/layer between the WHIP/WHEP protocols, and the Janus API actually enforcing the WebRTC establishment. This meant that both servers could be configured to talk to a specific Janus instance, while at the same time exposing a dedicated REST server that would provide interested clients with access to the WHIP and WHEP protocol: any interaction with those REST endpoints would then translate to Janus API interactions on the Janus side, thus bridging the signalling and negotiation accordingly to finally establish a WebRTC PeerConnection between the WHIP/WHEP client and the Janus plugin responsible for the media itself.
Considering the different nature of the two protocols, those servers mapped WHIP to the VideoRoom plugin (which is the plugin providing SFU functionality, and so the most suited for flexible WebRTC ingestion), and WHEP to the Streaming plugin (which is optimized for broadcasting WebRTC streams). A summary of how the translation process works is depicted in the two diagrams below.


Both servers would then expose custom (and not standard, as in not being part of the WHIP/WHEP specifications themselves) REST addresses to manage endpoints, e.g., to add new WHIP endpoints that people could publish to (and configure the associated VideoRoom resource accordingly), or do the same for WHEP, or simply remove existing endpoints dynamically.
This already provided a good deal of flexibility (endpoints could be created/destroyed dynamically, assuming something else dealt with managing the associated resources on the Janus side contextually), but it required some sort of SaaS-like kind of interaction, where you had to use HTTP requests for the purpose. This made little sense to me, especially in the context of a larger orchestrating application that could control more things at the same time: having a network API to control an endpoint is good in terms of having separate components, but that shouldn’t be a requirement, especially in cases where that’s not really needed.
As such, I decided to try and refactor both servers as Node.js libraries instead. The idea was to provide the same exact WHIP/WHEP translation functionality (meaning implementing the REST communication for WHIP/WHEP purposes, and the associated translation to/from Janus API), but keep the endpoint management separate, and as a programming API instead. This would allow applications to still expose those APIs via network, if they wanted, but most importantly allow them to manage endpoints as part of the application workflow directly as well, if of interest.
I was also particularly interested in allowing an application to provide WHIP and WHEP functionality as part of the same application. The way it was before, with separate standalone applications, that really wasn’t possible: it would always be separate processes, and the only way to orchestrate some form of synchronization of the two would need to happen through their network interfaces. Why not allow an application to have its own REST server, instead, and then simply “add” both WHIP and WHEP handlers to that, where different path prefixes would poke one rather than the other, and the application would have a direct way of controlling both programmatically? An HTTP “unification” of the API was already possible before, e.g., via proxying via components like nginx or httpd, but again I wanted applications to have more control on the possibilities they had access to.
This kind of flexibility would also make it easier to control the associated Janus resources accordingly. I’ve mentioned how the WHIP and WHEP servers transparently leverage VideoRoom and Streaming plugin resources for their WebRTC needs, but I’ve also mentioned how those resources need to exist already, for them to be “used” by the WHIP and WHEP servers. This means, for instance, that if I wanted a WHIP server to expose a new endpoint called abc123
and ensure that publishing to it would end up in VideoRoom 1234
, room 1234
needed to exist already on the Janus instance: the WHIP server would not create it for me. It would be much easier for an application to optionally have direct control on all the different parts, so that if the application wants to create a broadcast, it can first create a room on a Janus instance, then create multiple mountpoints on other instances for distribution, and then configure the WHIP and WHEP endpoints accordingly to use those. All this can be done much more easily if what provides WHIP and WHEP functionality is a library, especially considering that for the Janus API itself we already provide an excellent Node.js library called Janode, implemented by my talented colleague Alessandro Toppi. Janode is a library we use ourselves in a ton of stuff we write, including the Virtual Event Platform that powers IETF and RIPE meetings, and so it can be considered battle tested.
As such, upgrading the WHIP and WHEP servers to use Janode was indeed my very first step in this process. In fact, when I first started working on those prototype servers, I wrote my own crummy JavaScript stack to talk to Janus: since I’m not really a very proficient JavaScript developer, this ended up being something that would make your average JavaScript developer tear their hair out of their head, with barbaric practices like fake async mixed with what could be simply described as a “callback hell”. As a consequence, starting to use a proper and very efficient library like Janode seemed like the most reasonable first step towards a more comprehensive refactoring, especially if the purpose was to make it easier to come up with a redistributable and reliable library myself. This effort was carried out in a couple of dedicated pull requests that, at the time of writing, have been merged already: for the WHIP server you can refer to PR #17, while for the WHEP server the equivalent effort was carried out in PR #5 instead.
At this point, the next step was in refactoring both standalone applications to become Node.js libraries instead. In a nutshell, this meant:
- In a configurable way, either create a new REST server from scratch (as before), or re-use an existing one if provided (i.e., to add features to an existing backend).
- Keep the WHIP/WHEP to Janus API translation as before.
- Get rid of the REST APIs to create/edit/destroy endpoints, and turn them into programmable APIs instead.
- More in general, create Node.js classes for the involved resources.
- Provide an event framework to keep applications updated on relevant things happening in the library.
- Expose all that as a Node.js module that could be used by applications.
- Write sample applications to show how to use the libraries (possibly applications that would provide the same functionality the standalone applications did before).
This is exactly what I ended up doing in the now merged PR #18 (for WHIP) and PR #6 (for WHEP). You can refer to the respective pull requests if you’re interested to see the actual changes in the code, and how the libraries look like now, but let’s have a look at a couple of examples.
How do you use the libraries?
The idea of making the WHIP and WHEP features available as a library means you should be able to use them as any other Node.js library out there: you import it, and then start creating server instances, adding and removing endpoints as you need them, possibly intercepting some relevant events you may be interested in while the WHIP and WHEP stacks do their job. The repos do come with a few examples that show how to use them in practice, but let’s show something here too, starting from WHIP.
The way you create a new WHIP server is basically this:
server = new JanusWhipServer(config);
await server.start();
where config is an object containing some details on what the library should do: that will include the address of the Janus instance to connect to, some configuration options related to the REST behaviour, and a few other properties. The REST behaviour is particularly interesting, as both libraries allow you to either create a new server from scratch, or try to re-use an existing one: in both cases, nodes will be added so that the library can intercept HTTP requests for the WHIP/WHEP messaging.
If we want to spawn a brand new REST server and let the library worry about it, we can do something like this:
server = new JanusWhipServer({
janus: {
address: 'ws://localhost:8188'
},
rest: {
port: 7080,
basePath: '/whip'
}
});
We’re connecting to a local Janus instance via WebSockets, creating a new web server binding it to port 7080
, and then telling the library that the prefix to use as a base path for the WHIP management will be /whip
: this means that if we create, for instance, an endpoint called abc123
, a WHIP client will need to send their post to /whip/endpoint/abc123
, and other WHIP resources will have the /whip
base path too. This helps separating contexts when reusing the same REST server for the job, as we’ll see later.
If the application already has an Express app of its own, and we want the WHIP library to add its nodes there, we can do it like this:
server = new JanusWhipServer({
janus: {
address: 'ws://localhost:8188'
},
rest: {
app: myApp,
basePath: '/whip'
}
});
Once a server is created, we can start configuring it: this includes, for instance, adding listeners for events we may be interested in, or pre-creating endpoints that we want served right away. This adds listeners to be notified in case the WHIP server loses connectivity to Janus, for instance:
server.on('janus-disconnected', () => {
console.log('WHIP server lost connection to Janus');
});
server.on('janus-reconnected', () => {
console.log('WHIP server reconnected to Janus');
});
while this is an example of how we can create a new endpoint:
endpoint = server.createEndpoint({ id: 'test', room: 1234, token: 'verysecret' });
In this specific example, we’re creating a new endpoint called test (which means it will be available through the /whip/endpoint/test
path) that will publish to VideoRoom 1234
in the Janus instance: in order to publish to that endpoint, clients will need to present the authorization token verysecret
. It’s worth pointing out that, if you want the token not to be static, or need it to sometimes change over the course of the endpoint life cycle, you can configure a callback function rather than a static string, like this:
endpoint = server.createEndpoint({ id: 'test', room: 1234, token: function(authtoken) {
return authtoken === 'verysecret';
}});
Endpoints can emit events too. Should you be interested to know when a publisher has connected to the endpoint or when they go away, for instance (e.g., for monitoring purposes or to update some UI)/c, you can listen to the endpoint-active
and endpoint-inactive
events for the purpose:
endpoint.on('endpoint-active', function() {
console.log(this.id + ': Endpoint is active');
});
endpoint.on('endpoint-inactive', function() {
console.log(this.id + ': Endpoint is inactive');
});
Once you’re ready, you can actually start the WHIP server like this:
await server.start();
which will allocate all the resources needed to get the WHIP server ready for action. Notice that you can of course configure listeners and endpoints at any time, before or after starting the server.
The WHEP library works pretty much the same way, using a different constructor obviously:
server = new JanusWhepServer(config);
await server.start();
The syntax for creating endpoints is of course a bit different, since Streaming plugin mountpoints are used instead of VideoRoom rooms, but apart from that they work pretty much the same way too:
endpoint = server.createEndpoint({ id: 'abc123', mountpoint: 1, token: 'verysecret' });
Unlike WHIP endpoints, where each endpoint is only accessible to one WHIP client at a time, WHEP endpoints are actually accessible to multiple WHEP clients at the same time (since it’s a distribution point). As such, there’s no active/inactive event you can listen to there, but there are events associated to when subscribers join and leave the broadcast:
endpoint.on('new-subscriber', function() {
console.log(this.id + ': Endpoint has a new subscriber');
});
endpoint.on('subscriber-gone', function() {
console.log(this.id + ': Endpoint subscriber left');
});
That’s it in a nutshell: as you can see, all very easy to use. At the time of writing, there’s not much else that is available in terms of configuration options or available events, but in time we plan to expand on that based on requirements that may emerge from people using the libraries.
A practical example: WHIP and WHEP in the same app!
We’ve seen how we can use the WHIP and WHEP libraries on their own, using different approaches for what concerns how to setup the REST backend. But what if we wanted to use both of them at the same time? A simple example may be creating a WHIP endpoint that automatically feeds a WHEP endpoint, and serving both of them as part of the same REST backend. How do we do that?
Well, firstly, since they’re both libraries now, we can definitely use them both as part of the same application. Besides, considering both of them can be instructed to re-use existing REST backends, creating a REST server externally and passing that same instance to both of them would make both servers available as part of the same process. How do we somehow “tie” the two endpoints, now?
Considering the WHIP server relies on the VideoRoom plugin, while the WHEP server relies on the Streaming plugin, the most natural way to have one feed the other is by using the RTP forwarders functionality in Janus. I’ve talked about this feature on numerous occasions, and it is at the foundation of every configuration that requires scalability out of a Janus-based architecture: if you want to learn more, you can refer to this presentation I made at FOSDEM on WebRTC and broadcasting (which of course focused heavily on WHIP and WHEP too).
In a nutshell, we need to ensure that, whenever a publisher starts sending media to a WHIP endpoint, RTP forwarders are triggered so that the published media is forwarded to the Streaming plugin mountpoint, in order to have it distributed there to interested subscribers using WHEP. This is indeed one of the configuration features that the WHIP library provides, so let’s have a look at how we can build this application.
First of all, we import both libraries:
import { JanusWhipServer } from 'janus-whip-server';
import { JanusWhepServer } from 'janus-whep-server';
Then we pre-create a REST backend that we’ll use for a few different things: the WHIP and WHEP servers, of course, but also a basic informational endpoint (to query which endpoints exist) and a static web page to host a basic WHEP player.
let myApp = express();
myApp.get('/endpoints', async (_req, res) => {
let list = {
whip: whip.listEndpoints(),
whep: whep.listEndpoints()
};
res.setHeader('content-type', 'application/json');
res.status(200);
res.send(list);
});
myApp.use(express.static('web'));
http.createServer({}, myApp).listen(7070);
At this point, we can create both servers, and add them to the application REST backend.
// Create a WHIP server, and add it with base path /whip to the server above
whip = new JanusWhipServer({
janus: {
address: 'ws://localhost:8188'
},
rest: {
app: myApp,
basePath: '/whip'
}
});
// Create a WHEP server, and add it with base path /whep to the server above
whep = new JanusWhepServer({
janus: {
address: 'ws://localhost:8188'
},
rest: {
app: myApp,
basePath: '/whep'
}
});
// Start the servers
await whip.start();
await whep.start();
We need an endpoint for both protocols, so let’s start with WHIP. As we mentioned, we also want that endpoint to automatically start feeding our WHEP endpoint. In this example, we’re assuming we’ll use some specific resources, namely:
- VideoRoom
1234
, and - Streaming mountpoint
1
(configured to expect audio on port5002
, video on port5004
, and video RTCP on port5005
).
Both of these resources are what you get out of the box when you install Janus from scratch, as they’re part of the VideoRoom and Streaming plugin configuration file samples. This means they should work right away even if you’re not very familiar with how to configure or use Janus yourself. The important point, here, is that we’re assuming both resources exist already on the Janus instance we’re talking to: in a more dynamic application, we’d probably involve Janode as well to create those resources before we refer to them in our WHIP/WHEP endpoints, and destroy them when we don’t need them anymore, but that’s out of scope to this basic example here.
Long story short, this means we can now create our WHEP endpoint:
let whepEndpoint = whep.createEndpoint({ id: 'abc123', mountpoint: 1, token: 'verysecret' });
and our WHIP endpoint:
let whipEndpoint = whip.createEndpoint({ id: 'abc123', room: 1234, token: 'verysecret',
secret: 'adminpwd', recipient: { host: '127.0.0.1', audioPort: 5002, videoPort: 5004, videoRtcpPort: 5005 } });
Notice how, unlike the previous examples, we’re also providing a recipient
property for WHIP: this is how we instruct the WHIP server (and so Janus) to forward any media published to that endpoint to the addresses specified in the recipient
object. Considering those are the addresses the Streaming mountpoint 1
(the one we use for WHEP) listens on, this means that we’ll implicitly feed the WHEP endpoint automatically as soon as someone publishes to the WHIP one.
Now, let’s see if all this will work as expected. As soon as we start the application, all resources will be allocated. The first thing we can check is if the endpoints are correctly configured, and if the WHIP and WHEP backends are on as well:
lminiero@lminiero ~ $ curl http://localhost:7070/endpoints
{"whip":[{"id":"abc123","enabled":false}],"whep":[{"id":"abc123","subscribers":0}]}
lminiero@lminiero ~ $ curl http://localhost:7070/whip/healthcheck
OK
lminiero@lminiero ~ $ curl http://localhost:7070/whep/healthcheck
OK
So far, so good: /healthcheck
probes to both the WHIP and WHEP backends are successful (meaning they’re up and running), and our custom /endpoints
handler is correctly listing the WHIP and WHEP endpoints we created, meaning the respective libraries are aware of them.
Now it’s time to check if WHIP and WHEP actually work, so let’s try and use the Simple WHIP Client first to publish audio and video to our WHIP endpoint. We’ll use one of the examples the client README provides, and have it point to our endpoint:
./whip-client -u http://localhost:7070/whip/endpoint/abc123 \
-t verysecret \
-A "audiotestsrc is-live=true wave=red-noise ! audioconvert ! audioresample ! queue ! \
opusenc ! rtpopuspay pt=100 ssrc=1 ! queue ! \
application/x-rtp,media=audio,encoding-name=OPUS,payload=100" \
-V "videotestsrc is-live=true pattern=ball ! videoconvert ! queue ! \
vp8enc deadline=1 ! rtpvp8pay pt=96 ssrc=2 ! queue ! \
application/x-rtp,media=video,encoding-name=VP8,payload=96"
This should result in the WHIP client correctly establishing a WebRTC PeerConnection with Janus through our integrated WHIP server. Poking the /endpoints
node should return something like this:
lminiero@lminiero ~ $ curl http://localhost:7070/endpoints
{"whip":[{"id":"abc123","enabled":true}],"whep":[{"id":"abc123","subscribers":0}]}
Still no subscribers (we haven’t involved WHEP yet), but the WHIP endpoint is now marked as active and alive (enabled
is set to true
). Considering we involved RTP forwarders, we should also see something like this on the Janus logs:
[rtp-sample] New audio stream! (#0, ssrc=2357291848)
[rtp-sample] New video stream! (#1, ssrc=737454302, index 0)
That’s printed by the Streaming plugin, which means it’s a confirmation that the forwarding actually took place, and so the Streaming plugin now does have media it can rebroadcast to interested subscribers. As such, let’s try to use the Simple WHEP Client to subscribe to our WHEP endpoint, again using one of the command line examples provided in the README there:
./whep-client -u http://localhost:7070/whep/endpoint/abc123 \
-A "application/x-rtp,media=audio,encoding-name=opus,clock-rate=48000,encoding-params=(string)2,payload=111" \
-V "application/x-rtp,media=video,encoding-name=VP8,clock-rate=90000,payload=96" \
-t verysecret
If everything works as expected, this should also result in a new WebRTC PeerConnection, and in a new window being created to render the incoming audio and video streams:
That bouncing ball and red noise is indeed what we were expecting to get, as that’s what the WHIP client was configured to send: eureka! The new subscriber is now also listed when we probe the /endpoints
node again:
lminiero@lminiero ~ $ curl http://localhost:7070/endpoints
{"whip":[{"id":"abc123","enabled":true}],"whep":[{"id":"abc123","subscribers":1}]}
Our application also hosts a basic web-based WHEP player on the same server, though, by re-using the code we had in the standalone WHEP server, so let’s see what happens when we try to open the player and have it subscribe to the WHEP endpoint abc123
:
http://localhost:7070/?id=abc123
Again, no surprise there: we get the same exact audio/video feed as the other WHEP client, and the /endpoints
node will now return 2 active subscribers for the WHEP endpoint, should we poke it again.
As you can see, with just a few lines of code, thanks to the help of Janus we had an effective and self-contained WHIP/WHEP broadcasting solution. Of course for a larger service serving content to a larger audience you may want to build something that’s not self-contained as this demo was, but the important point to take away was that, unlike the previous standalone applications, these libraries now give you the flexibility to do whatever you want in that regard, including go as self-contained as possible for projects with more limited requirements.
That’s great! How do I use the libraries in my projects?
Now that both servers are actually provided in convenient libraries, we pushed them to npm
for easier access. More precisely, we pushed the janus-whip-server
and janus-whep-server
packages to npm, both as version 1.0.0
at the time of writing.
This means that all you need to do to start using them, is referring to janus-whip-server
(for WHIP) and/or janus-whep-server
(for WHEP) in your package.json
file, or when doing an npm install
directly. Of course, since both servers are completely open source, you can also simply refer to local copies of the libraries pulled from GitHub.
Once the libraries are available as dependencies in your project, all you need to do is importing the relevant class(es), as shown in the examples above, and starting to use them as per the respective APIs. If you’re familiar with Node.js development, this should all be pretty straightforward, but if you encounter issues, you can refer to the GitHub repos for more information and help.
Considering that both libraries rely on Janode as their Janus API stack, this also means you can directly import Janode as a dependency too in your project. This may be very helpful, e.g., any time you need to orchestrate Janus resources as part of your WHIP/WHEP related operations.
What’s next?
This was a considerable refactoring, so there may be things that still don’t really work as expected. The only way to know for sure will be to wait for some more usage and feedback from users, as there’s only so much we can do on our own in that regard. Basic functional testing seems to work as expected, but I’m sure there are edge cases we may not have bumped into that need attention. Documentation is also sorely lacking, at the moment, if we exclude the detailed README
and examples, so that will need to be addressed too sooner or later.
Then of course there’s the matter of the protocols themselves. WHIP is now an RFC, so we can consider the protocol stable and established: apart from bug fixing or other potential problems associated to how we implemented the protocol, I don’t expect to have to make any specific functional changes, unless new interesting scenarios emerge. WHEP, on the other hand, is very much under construction right now, and debate around it has been heated enough to require a new editor to join the efforts in order to steer the work to conclusion.
First of all, there are features that are already part of WHEP that are not in the library yet, namely the Server Side Events (SSE) way of notifying subscribers about stuff. This is something I already started to address at the time (see PR #3), but that was for ye old standalone version of the server, meaning it’s completely broken now. That’s definitely the first thing we should add to the new WHEP library, and considering the way it now works using EventEmitters, I think that shouldn’t be too much of a titanic efforts.
There are other changes that will probably occur in the WHEP specification in the next few months, though. As you can see in the list of issues opened for the draft, there are a few things interested parties cared about, and so good chances are that some of them will be addressed soon. One of them, possibly the most heated source of discussion, is the optional ability for WHEP servers to originate SDP offers themselves, rather than have WHEP clients do it themselves: this was a supported feature in the original WHEP specification, and I voiced my complaints when it was removed, so having it back in a standard way would definitely be a good thing in my book (the WHEP library currently supports that too, but obviously using a non-standard mechanism for the purpose). WHEP discoverability as a url may be another interesting new feature that could be added, which may need updates to the way HTTP is used in the library.
Long story short, though, I just hope that this refactoring will encourage more people to start experimenting with WHIP and WHEP using Janus as their media backend. I still care a lot about the use case (even 10 years after I worked on it for my Ph.D thesis), and it would be great to see more companies and individuals start focusing on WebRTC broadcasting, especially if Janus plays an important part in it. Hopefully the examples I provided will be a good starting point: should you want or need our help to build something out of what we provided as open source software, please don’t hesitate to get in touch!
That’s all folks!
I know, I did it again… I wrote a way too long blog post that most people will not 100% read through, and the 5th one on WHIP and WHEP too! But I hope you appreciated the new content anyway, and that you’ll find this overview on the new libraries we provided useful for whatever you’ll build next, with or without our help.