Immersive Visualization / IQ-Station Wiki
This site hosts information on virtual reality systems that are geared toward scientific visualization, and as such often toward VR on Linux-based systems. Thus, pages here cover various software (and sometimes hardware) technologies that enable virtual reality operation on Linux.
The original IQ-station effort was to create low-cost (for the time) VR systems making use of 3DTV displays to produce CAVE/Fishtank-style VR displays. That effort pre-dated the rise of the consumer HMD VR systems, however, the realm of midrange-cost large-fishtank systems is still important, and has transitioned from 3DTV-based systems to short-throw projectors.
Janus
Janus by MeetEcho is a software tool suite for serving WebRTC communication streams for web browsers.
This entry only covers aspects of the Janus tool that were needed for this page's author's particular needs — one-way real-time video streaming. It certainly could be useful for others to at least get started with their needs, especially the building and configuring sections.
Building Janus
There are a handful of dependencies required, some of which are optional, depending on which Janus plugins are needed for a particular application. These instructions include the dependencies for nearly all of the Janus options.
These instructions have been most recently tested with Janus version 1.3.0 on a Ubuntu 22.04 system, but prior to that have worked fine with Janus version 1.2.4 on a Rocky 8.10 (RHEL branch) OS.
Ubuntu dependency list
The four primary dependencies required for a basic Janus build on Ubuntu are:
- libsrtp2-dev — may also hand-build, depending on available version
- NOTE: The version of LibSRTP2 is important, and can't be too new (at least at the time of this writing). Presently, the version available on my Ubuntu 22.04 system (Janus v2.4.2) works, but v2.6.0 may be too new. (On my previous installation I manually built v2.2.0.)
- NOTE: Module file for libsrtp should include these (extra) settings:
setenv LIBSRTP_CFLAGS -I$env(LIBSRTP_DIR)/include setenv LIBSRTP_LIBS $env(LIBSRTP_DIR)/lib/libsrtp2.a
- libnice-dev
- libjansson-dev
- libconfig-dev (and maybe libconfig++-dev)
The other packages that might be required, depending on how Janus will be used, are:
- libmicrohttpd-dev — Needed for my video streaming
- libopus-dev — for "Audio bridge" plugin (and maybe audio streaming?)
- libpaho-mqtt-dev / libpaho-mqttpp-dev
- nanomsg-dev — I do not use the NanoMsg plugin
- libsofia-sip-ua-dev — maybe for "Audio bridge" and "SIP"
- python3-paho-mqtt — installed just in case I want to interface MQTT in Python3
- libusrsctp-dev / libusrsctp-examples — for "DataChannels" (which I am not yet using)
- libwebsockets-dev — for WebSockets, obviously (also not yet using, but maybe)
- libwebsockets-test-server / libwebsockets-test-server-common — two bonus packages for possible debugging/prototyping needs
- NPM — for the
--enable-javascript-common-js-module
feature (which I do NOT install)
Rocky/RHEL dependency list
This list may not be complete, as I no longer have access to a Rocky Linux system, but these are the names of the packages I installed (or built) for the Rocky Linux installation:
- libnice — manually built version
libnice-0.1.22
- libsrtp — manually built version
libsrtp-2.2.0
with--enable-openssl
- libmicrohttpd-devel.x86_64
- paho-c-devel.x86_64 / paho-cpp-devel.x86_64
- nanomsg-devel.x86_64
NOTE: it's possible I had some needed packages previously installed on the system for other projects, and thus are in my notes documenting the required steps to build.
Build steps
In this build, I maximized the number of plugins that would work to provide
flexibility in using Janus.
However, I do not have NPM (the JavaScript NodeJS Package Manager) on the system,
so I did not include that option.
For my build, I minimally need the --enable-libsrtp2
and --enable-rest
features.
Other possible options (that I do NOT use) are --enable-javascript-common-js-module
Here are the build steps (for Janus version 1.3.0):
$ cd <utilities-directory>/Janus
$ wget https://github.com/meetecho/janus-gateway/archive/refs/tags/v1.3.0.tar.gz
$ tar -zxf v1.3.0.tar.gz
$ mkdir janus-gateway-1.3.0_u22
$ cd janus-gateway-1.3.0
$ sh autogen.sh
$ ./configure --prefix=<utilities-directory>/Janus/janus-gateway-1.3.0_u22 --enable-libsrtp2 --enable-websockets --enable-rest --enable-mqtt --enable-nanomsg --enable-plugin-textroom --enable-plugin-audiobridge --enable-data-channels
$ make
$ make install
$ vi Modules/u22/janus/1.3.0
NOTE: that I always use the Modules system for controlling the shell environment to allow for the use of multiple versions of specific tools. Hence the need to create the "janus/1.3.0" module file.
Configuring Janus
Again, these steps for configuring Janus will focus on video (and audio) streaming, but there are some steps that are generic, so we will start with those:
- Copy (or rename) all
<janus-feature>.jcfg.sample
files to just….jcfg
:
$ for file in *.jcfg.sample
> do base="${file%.jcfg.sample}"
> cp -p $base.{jcfg.sample,jcfg}
> done
Next, edit the particular "jcfg" files required for the desired output.
Ports
But first! It's important to choose what options, especially what ports will be used for communicating with Janus, with sending audio/video to Janus, and receiving WebRTC streams from Janus. These are the ports I am using (some of which are the defaults), and which will be used for the rest of the examples in this page:
8000
— Python3-based (or other) HTTP server8088
— Internal Janus HTTP webserver port (default) (defined injanus.transport.http.jcfg
)7088
— Internal Janus HTTP webserver port for Janus administration (default)8188
— Janus WebSockets interface (default) (I'm not yet using this)8004
— Incoming (to Janus) video port8005
— Incoming (to Janus) video port
Configuring Janus for Video (and Audio) Streaming
For the configuration where we will be ingesting h.264 video streams (possibly also audio streams), and streaming them to WebRTC client pages, three Janus-configuration files will need to be altered:
- janus.jcfg
- janus.transport.http.jcfg
- janus.plugin.streaming.jcfg
janus.jcfg
Presently,
I believe the only changes you may want to make to the janus.jcfg
configuration file is the debug-level and the password.
Both values are set in the general:
section at the top of
the sample version of the file.
Thus you may want to amend that section with:
general: {
debug_level = 3 # Optional: "4" is the default (and is also reasonable)
admin_secret = "myword"
...
}
janus.transport.http.jcfg
As the (default) primary means by which components communication with Janus
is through it's internal HTTP webserver, that port must be set in
janus.transport.http.jcfg
.
The same is true for the Janus administrative port.
admin:
admin_http = true # Optional: Permits extra control and monitoring on port 7088 (default)
...
}
janus.plugin.streaming.jcfg
This is where any media streams that will be served by Janus through WebRTC must be specified. Multiple streams can be defined, whereby the Janus server can report a list of options to the Application, and the Application can respond with a prefered stream — or it can just be hard-coded for a particular stream. Thus, while many example media streams are defined by default in the example configuration file, it is acceptable to leave them as-is, or to comment them out, based on preference. (I prefer to comment them out.)
However, we of course need to have at least one stream ready and configured
(assuming media streaming is your purpose for running Janus, which isn't always the case).
For MP4 video (and/or audio) streaming, the h264-sample
is a good starting
point, so I prefer to rename that to h264-vr
to stream my MP4 video.
- NOTE also that some of the parameters can be obtained from an SDP file that might be generated by
FFmpeg
if it is used to generate the media stream.
h264-vr: {
type = "rtp"
id = 10
description = "VR Live Stream" # changed to describe my stream
audio = false
video = true
videoport = 8004
videopt = 96 # changed from "126" for MP4 (match SDP)
videocodec = "h264" # (matches SDP)
videofmtp = "profile-level-id=42e01f;packetization-mode=1"
secret = "mypwd"
}
Running Janus
Once everything is configured, then running Janus is trivial!
$ module load janus
$ janus --version
$ janus
In another shell (or however you start your programs), you can start the application
that feeds the stream to Janus.
For a quick test, the FFmpeg
tool is handy — but first, the
server's HTTP interface can be tested to "confirm basic operation" (below).
Confirming Basic Operation
The first simple way to test the Janus server is to open a web-broswer, and give the URL:
This should give a lot of information about how the server was compiled and is configured.
Somewhat more advanced is to inquire about the state of any streams (which you won't have yet if your are stepping through these instructions!). This is a bit more challenging as it requires a payload to make the request. So if you just browse to the URL:
So the easiest way to add a payload to the URL is to use the curl
tool
with the -X POST
option.
This command outputs similar information as the janus/info
URL above:
$ curl -X POST http://localhost:7088/adm -H "Content-Type: application/json" -d '{ "janus": "info", "transaction": "YO", "admin_secret": "adminpwd" }'
Of course the password (here myword
) must match what you set in the file janus.jcfg
.
Also note that the value for "transaction"
is an arbitrary
string that Janus will use in it's response so you can confirm that a given
response is to a specific request.
The response will be in the form of a (large) JSON-formatted string.
So if you would like to store that string and process it (in the bash
shell) you can do something like:
$ JSON_OUTPUT=$(curl -s -X POST http://localhost:7088/admin -H "Content-Type: application/json" -d '{"janus": "list_sessions", "transaction": "abc123", "admin_secret": "myword"}')
Then you can process the result:
$ echo $JSON_OUTPUT
$ echo $JSON_OUTPUT | jq
$ echo $JSON_OUTPUT | jq '.transaction'
$ echo $JSON_OUTPUT | jq '.sessions[0]'
Note, you can do other things like inquire about the state of any streams (which you won't have yet if your are stepping through these instructions!). This command will list any existing streaming sessions:
$ curl -X POST http://localhost:7088/admin/streaming -H "Content-Type: application/json" -d '{ "janus": "list_sessions","transaction": "YO", "admin_secret": "myword" }'
Testing Media Streaming Operation
A good next step — especially if media streaming is your primary purpose for using Janus — is to send a stream to the server, and then view it.
A simple example is to use the FFmpeg
tool to generate SMPTE colorbars
with a message that includes the current time of the computer:
$ ffmpeg -re -f lavfi -i "smptehdbars=rate=30:size=1920x1080" -vf drawtext="text='YOUR MESSAGE %{localtime\:%X}':rate=30:x=(w-tw)/2:y=(h-lh)/2:fontsize=48:fontcolor=white:box=1:boxcolor=black" -c:v libx264 -profile:v baseline -pix_fmt yuv420p -preset ultrafast -tune zerolatency -crf 28 -g 60 -f rtp rtp://localhost:8004
TODO: explain how to quickly view the WebRTC stream from Janus
(Also add other ways to provide a stream to Janus)
See Also
- Janus
- WebRTC on WikiPedia
- WebRTC.org
- Streaming (on this Wiki)