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

From IQ-Station Wiki
Jump to navigation Jump to search

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=&LT;utilities-directory&GT;/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 server
  • 8088 — Internal Janus HTTP webserver port (default) (defined in janus.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 port
  • 8005 — 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:

http://localhost:8088/janus/info

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:

http://localhost:7088/admin

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