Jitsi Meet

Ʌ: Tech

Hiding the UI

In case you want to use Jitsi Meet as a video transport (say, in a gallery context), you might want to disable the UI so that it is not apparent that it is in fact a videoconference.

The userstyle below does just that. I recommend the use of the Stylus 🌐 extension (available for both Firefox and Chrome) for the management of user-styles; it also supports keyboard shortcuts.

/* ==UserStyle==
@name           Jitsi UI-less mode
@namespace      t.mldk.cz
@version        1.1.0
@description    Hide the UI in Jitsi calls
@author         t@mldk.cz
==/UserStyle== */

@-moz-document domain("meet.vpsfree.cz"), domain("meet.jit.si") {
    .new-toolbox,
    .filmstrip,
    .with-filmstrip,
    .subject,
    .atlaskit-portal-container,
    .atlaskit-portal {
        display: none !important;
    }
}

Up-to-date version at: https://gitlab.com/-/snippets/2043771 🌐

Automatically muting / adjusting the volume of remote participants

Similarly, you might want to enable audio output only from a select few participants, and mute the others. Jitsi Meet does support adjusting the volume of remote streams on an individual basis - however, this setting does not persist over disconnects/reconnects.

The userscript below checks every second for the nicks of currently connected participants, and mutes everyone but those participants whose nicks match any of the patterns in MATCH_NAMES (either plain strings or regexes). I recommend Tampermonkey 🌐 for user-script management.

// ==UserScript==
// @name         Jitsi Auto-mute
// @namespace    http://t.mldk.cz
// @version      1.0
// @description  Automatically mutes every participant but those whose nick matches MATCH_NAMES.
// @author       t.mldk.cz
// @match        https://meet.jit.si/*
// @match        https://meet.vpsfree.cz/*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    const MATCH_NAMES = ["Max", /[Hh]eadroom/];

    setInterval(() => {
        Array.from(document.querySelectorAll(".displayName"))
            .filter((el) =>
                !MATCH_NAMES.some(
                    (name) => typeof (name) === "string"
                        ? el.textContent.toLowerCase().includes(name.toLowerCase())
                        : name.test(el.textContent)))
            .forEach((el) => {
                let audioElement = el.parentNode.parentNode.querySelector('audio');
                if (audioElement) {
                    audioElement.volume = 0;
                }
            });
    }, 1000);
})();

Up-to-date version at: https://gitlab.com/-/snippets/2046481 🌐