Содержание
Jitsi
Бесплатная система видеоконференцсвязи.
https://jitsi.org/
https://github.com/jitsi/jitsi-meet
Тестовый сервер: https://meet.jit.si/
# Ubuntu/Debian: # First install the Jitsi repository key onto your system: wget -qO - https://download.jitsi.org/jitsi-key.gpg.key | sudo apt-key add - # Create a sources.list.d file with the repository: sudo sh -c "echo 'deb https://download.jitsi.org stable/' > /etc/apt/sources.list.d/jitsi-stable.list" # Update your package list: sudo apt-get -y update # Install the full suite: sudo apt-get -y install jitsi-meet # or only the packages you need like for example: sudo apt-get -y install jitsi-videobridge sudo apt-get -y install jicofo sudo apt-get -y install jigasi
https://jitsi.org/downloads/ubuntu-debian-installations-instructions/
Read the quick-install guide and its advanced section for further configuration (Firewall, Port Forwarding or for Running jitsi-videobridge behind NAT)!
Ограничение на создание комнат: https://jitsi.github.io/handbook/docs/devops-guide/secure-domain/
Автоконфиг
Размер watermark.svg - 140×70 px.
- /root/watermark.sha256
035f1f16d756e70908a274080aaa81afc43835dc93fd8fdf75e33ca48790f71e /usr/share/jitsi-meet/images/watermark.svg
- /root/jitsi-autoconfig.sh
if ! sha256sum -c /root/watermark.sha256; then # copy files cp /root/jitsi-watermark-company.svg /usr/share/jitsi-meet/images/watermark.svg cp /root/jitsi-favicon-company.ico /usr/share/jitsi-meet/images/favicon.ico # interface settings (new file) sed -i " /defaultRemoteDisplayName:/c defaultRemoteDisplayName: 'Participant', /disableE2EE:/c disableE2EE: true, " /usr/share/jitsi-meet-web-config/config.js # interface settings (old file) sed -i " /APP_NAME:/c APP_NAME: 'VICS Horns and Hooves', /JITSI_WATERMARK_LINK:/c JITSI_WATERMARK_LINK: 'https://www.hornsandhooves.ru/', /LIVE_STREAMING_HELP_LINK:/c LIVE_STREAMING_HELP_LINK: 'https://support.google.com/youtube/answer/2474026', /DISPLAY_WELCOME_FOOTER:/c DISPLAY_WELCOME_FOOTER: false, /GENERATE_ROOMNAMES_ON_WELCOME_PAGE:/c GENERATE_ROOMNAMES_ON_WELCOME_PAGE: false, /DEFAULT_REMOTE_DISPLAY_NAME:/c DEFAULT_REMOTE_DISPLAY_NAME: 'Participant', " /usr/share/jitsi-meet/interface_config.js # English default titles sed -i ' s/"headerTitle":"Jitsi Meet"/"headerTitle":"VIC system of Horns and Hooves"/ s/"headerSubtitle":"Secure and high quality meetings"/"headerSubtitle":" "/ ' /usr/share/jitsi-meet/libs/app.bundle.min.js # language settings sed -E -i ' s/(.*: ")Сервер видеоконференцсвязи.*(".*)/\1ВКС АО «Рога и Копыта»\2/ /"appDescription":/c "appDescription": " ", /"headerSubtitle":/c "headerSubtitle": " ", s/из Jitsi Meet/из {{appName}}/g s/ссылку Jitsi/ссылку {{appName}}/g ' /usr/share/jitsi-meet/lang/main-ru.json sed -i ' s/Secure, fully featured, and completely free video conferencing/VIC system of Horns and Hooves/g /"headerTitle":/c "headerTitle": "VIC system of Horns and Hooves", /"appDescription":/c "appDescription": " ", /"headerSubtitle":/c "headerSubtitle": " ", s/from Jitsi Meet/c from {{appName}}/g s/Jitsi link/{{appName}} link/g ' /usr/share/jitsi-meet/lang/main.json fi
echo >> /etc/crontab echo "jitsi autorestore settings after update" >> /etc/crontab echo "*/15 * * * * root /root/jitsi-autoconfig.sh" >> /etc/crontab
# Включить возможность локальной записи - браузер сохраняет аудиофайл в свою папку загрузки nano /etc/jitsi/meet/domain.ru-config.js # раскомментировать раздел localRecording nano /usr/share/jitsi-meet/interface_config.js # включить кнопку localrecording в интерфейсе # формат лучше оставить flac, ogg получается кривой.
Список комнат
egrep -o "(Created|Disposed).*count[^,]*" /var/log/jitsi/jicofo.log
Пользователи
Создать
prosodyctl register <username> jitsi-meet.example.com <password> systemctl restart prosody systemctl restart jicofo systemctl restart jitsi-videobridge2
https://jitsi.github.io/handbook/docs/devops-guide/secure-domain
https://prosody.im/doc/creating_accounts
Список существующих
ls /var/lib/prosody/XXXX/accounts
“XXXX” is your domain. “.” are represented by “%2e”
To remove users I would recommend not to just delete their account files. Better use unregister command:
prosodyctl unregister USERNAME XXXX
Default timeout for authenticated users
In jicofo there is an auto login option which you can disable and no caching will be taken into account, and will ask for user/pass every time
nano /etc/jitsi/jicofo/jicofo.conf
jicofo { authentication: { ... enable-auto-login = false } }
Устаревший метод
nano /etc/jitsi/jicofo/sip-communicator.properties
org.jitsi.jicofo.auth.DISABLE_AUTOLOGIN=true
https://community.jitsi.org/t/default-timeout-for-authenticated-users/17664
Lobby
Ниже информация для устаревших систем. В новой установке лобби включено сразу.
Для использования новых фич, в частности, Lobby, надо обновить компонент Prosody
echo deb http://packages.prosody.im/debian $(lsb_release -sc) main | sudo tee -a /etc/apt/sources.list wget https://prosody.im/files/prosody-debian-packages.key -O- | sudo apt-key add - apt update && apt upgrade -y && apt autoremove nano /etc/prosody/conf.avail/meet.domain.com.cfg.lua # Replace: storage = "none" with storage = "memory" service prosody restart && service jicofo restart
https://community.jitsi.org/t/how-to-how-do-i-update-prosody/72205
Потом отредактировать конфиг /etc/prosody/conf.d/meet.example.com.cfg.lua
VirtualHost "meet.example.com" ... modules_enabled = { ... "conference_duration"; "muc_lobby_rooms"; } c2s_require_encryption = false lobby_muc = "lobby.meet.example.com" main_muc = "conference.meet.example.com" -- muc_lobby_whitelist = { "recorder.meet.example.com" } -- Here we can whitelist jibri to enter lobby enabled rooms ... Component "lobby.meet.example.com" "muc" storage = "memory" restrict_room_creation = true muc_room_locking = false muc_room_default_public_jids = true ...
Раньше конфиг лобби добавлялся в VirtualHost guest.meet.example.com, но теперь конфигурация перенесена в основной домен. Из гостевого хоста конфигурацию лобби необходимо убрать, иначе опция лобби появится, но запросы от участников модератору приходить не будут!
https://community.jitsi.org/t/how-to-how-do-i-use-the-new-lobby-feature/73100
https://community.jitsi.org/t/fix-lobby-not-working-after-upgrade-to-latest-version-2-0-5390/90541
Whiteboard
Интерактивная доска с общим доступом и возможностью совместной работы.
Node в стандартных репозиториях старый, поэтому нужно добавить сторонний.
# Obtain the Node.js source curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash - # Install the 16.x version of Node.js (This process also automatically installs NPM) sudo apt install -y nodejs # Если появляется ошибка типа # /var/cache/apt/archives/nodejs_16.15.0-deb-1nodesource1_amd64.deb trying to overwrite '/usr/share/systemtap/tapset/node.stp', # which is also in package libnode72:amd64 12.22.9~dfsg-1ubuntu3, выполнить sudo dpkg --remove --force-remove-reinstreq libnode-dev sudo dpkg --remove --force-remove-reinstreq libnode72:amd64 # Затем опять можно ставить node sudo apt install -y nodejs
https://www.linode.com/docs/guides/install-nodejs-on-ubuntu-22-04/#installing-a-specific-version
https://github.com/nodesource/distributions/issues/1157#issuecomment-1131212089
Установка excalidraw-backend
# Создать юзера для работы сервиса с домашним каталогом /opt/excalidraw-backend sudo useradd -r -d /opt/excalidraw-backend excali mkdir /opt/excalidraw-backend chown -R excali: /opt/excalidraw-backend # Зайти под этим юзером, клонировать репозиторий, скачать зависимости su - excal cd /opt git clone https://github.com/jitsi/excalidraw-backend.git cd ~ npm install
С настройками по умолчанию работать не будет, т. к. порты 80 и 9090 уже заняты nginx/jvb. Поэтому:
echo "PORT=3002" >.env.production
В файле src/index.ts
поменять порт 9090 на 9091 или ещё какой-нибудь.
// listens on host:9090/metrics prometheus.metrics(io, { port: 9091, collectDefaultMetrics: true });
Протестировать запуск
DEBUG=* npm start Ctrl+C Ctrl+D # Дальше нужно выйти из юзера excali и продолжать под рутом.
Настроить Jitsi: в /etc/jitsi/meet/jitsi.example.com-config.js
- Включить кнопку whiteboard в разделе toolbarButtons
- Отредактировать секцию и включить функционал
whiteboard: { enabled: true, collabServerBaseUrl: 'https://jitsi.example.com' },
Настроить nginx, вставив туда
# excalidraw-backend websockets location = /socket.io/ { proxy_pass http://127.0.0.1:3002/socket.io/?$args; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $http_host; tcp_nodelay on; }
Написать юнит для автозапуска
- /etc/systemd/system/excalidraw.service
[Unit] Description=Excalidraw-backend Requires=network.target After=network.target [Service] User=excali WorkingDirectory=/opt/excalidraw-backend Type=simple ExecStart=/usr/bin/npm start Restart=on-failure RestartSec=250s TimeoutStartSec=20s TimeoutStopSec=1min [Install] WantedBy=multi-user.target
# Запустить демон и проверить systemctl daemon-reload systemctl enable excalidraw.service systemctl start excalidraw.service systemctl status excalidraw.service # Перезапустить jitsi systemctl restart prosody systemctl restart jicofo systemctl restart jitsi-videobridge2
https://community.jitsi.org/t/installing-excalidraw-backend-for-whiteboard-feature-on-self-hosted-jitsi-mee/118883
https://community.jitsi.org/t/whiteboard-is-available-but-not-functioning/126490/22
Docker
Инструкция: https://jitsi.github.io/handbook/docs/devops-guide/devops-guide-docker
Скачать последнюю версию: https://github.com/jitsi/docker-jitsi-meet/releases/latest
mkdir jitsi wget https://github.com/jitsi/docker-jitsi-meet/archive/stable-5390-3.tar.gz tar xzf stable-5390-3.tar.gz --strip=1 -C jitsi/ cd jitsi cp env.example .env sh ./gen-passwords.sh mkdir -p ./.jitsi-meet-cfg/{web/letsencrypt,transcripts,prosody/config,prosody/prosody-plugins-custom,jicofo,jvb,jigasi,jibri} docker-compose up -d WARNING: The RESTART_POLICY variable is not set. Defaulting to a blank string. WARNING: The HTTP_PORT variable is not set. Defaulting to a blank string. WARNING: The HTTPS_PORT variable is not set. Defaulting to a blank string. WARNING: The CONFIG variable is not set. Defaulting to a blank string. WARNING: The XMPP_DOMAIN variable is not set. Defaulting to a blank string. WARNING: The XMPP_SERVER variable is not set. Defaulting to a blank string. WARNING: The JVB_PORT variable is not set. Defaulting to a blank string. WARNING: The JVB_TCP_PORT variable is not set. Defaulting to a blank string. ERROR: The Compose file 'docker-compose.yml' is invalid because: services.jvb.ports contains an invalid type, it should be a number, or an object services.jvb.ports contains an invalid type, it should be a number, or an object services.web.ports contains an invalid type, it should be a number, or an object services.web.ports contains an invalid type, it should be a number, or an object
Jibri
Компонент для записи.
https://github.com/jitsi/jibri
# edit config vi /etc/jitsi/jibri/config.json # restart jibri systemctl restart jibri # view log tail -f /var/log/jitsi/jibri/log.0.txt
Для Jibri (компонента записи) нужно дать достаточное кол-во процессорных ядер, например, 4. Иначе, ffmpeg через короткое время вылетает.
Обновление уже установленной системы
# Update the system apt update && apt upgrade -y && apt dist-upgrade -y && apt autoremove -y # Update Chrome driver CHROME_DRIVER_VERSION=`curl -sS chromedriver.storage.googleapis.com/LATEST_RELEASE` wget -N http://chromedriver.storage.googleapis.com/$CHROME_DRIVER_VERSION/chromedriver_linux64.zip -P ~/ unzip ~/chromedriver_linux64.zip -d ~/ rm ~/chromedriver_linux64.zip mv -f ~/chromedriver /usr/local/bin/chromedriver chown root:root /usr/local/bin/chromedriver chmod 0755 /usr/local/bin/chromedriver
Создание samba-сервера для доступа к записям
adduser --home /home/recordings --no-create-home --shell /usr/sbin/nologin --ingroup jibri recordings smbpasswd -a recordings
/etc/samba/smb.conf
[global] workgroup = WORKGROUP server string = Videoconf recording server ntlm auth = true [recordings] path = /recordings comment = Recordings browsable = yes read only = no force create mode = 0660 force directory mode = 2770 force user = jibri valid users = recordings @jibri
Несколько экземпляров Jibri
Т. к. один экземпляр может писать только одну конференцию, то может понадобиться больше экземпляров.
Сначала нужно завести на сервере jitsi учётки jibri и recorder:
prosodyctl register jibri auth.jitsi.mydomain.org JibriPassword prosodyctl register recorder recorder.jitsi.mydomain.org RecPassword
Заводить их для каждого сервера не нужно. У сервера Jibri должен быть уникальный nickname в /etc/jitsi/jibri/config.json
, а пользователи могут быть одинаковыми.
Чтобы запись работала на запароленной конференции
Создать на сервере Jitsi файл vi /usr/share/jitsi-meet/prosody-plugins/mod_jibri_wo_passwd.lua
c содержимым (менять ничего, кроме домена, не нужно)
local MUC_NS = "http://jabber.org/protocol/muc"; local jid = require "util.jid"; module:hook("muc-occupant-pre-join", function (event) local room, stanza = event.room, event.stanza; local user, domain, res = jid.split(event.stanza.attr.from); log("info", "--------------> user %s domain %s res %s pass %s", tostring(user),tostring(domain),tostring(res),tostring(room:get_password())); if ( user=='recorder' and domain=='recorder.jitsi.domain.ru' ) then local join = stanza:get_child("x", MUC_NS); join:tag("password", { xmlns = MUC_NS }):text(room:get_password()); end; end);
В файле vi /etc/prosody/conf.avail/jitsi.domain.ru.cfg.lua
на сервере Jitsi добавить модуль (здесь: jibri_wo_passwd)
Component "conference.jitsi.domain.ru" "muc" restrict_room_creation = true storage = "memory" modules_enabled = { "muc_meeting_id"; "muc_domain_mapper"; "polls"; --"token_verification"; "muc_rate_limit"; "jibri_wo_passwd"; } admins = { "focus@auth.jitsi.domain.ru" } muc_room_locking = false muc_room_default_public_jids = true
Склонировать (если это VM) настроенный сервер jibri, на нём
# поменять hostname и IP hostnamectl set-hostname srv-jibri2 nano /etc/hosts nano /etc/netplan/00-installer-config.yaml netplan apply # отредактировать config.json и вставить туда соответствующие имена учёток nano /etc/jitsi/jibri/config.json
https://community.jitsi.org/t/how-to-setup-multiple-jibri-servers-need-help-around-config/33604
Синхронизация на Windows-сервер по SMB
#!/bin/sh username="vasya" domain="domain.ru" password="12345678" smbsrv="srv-fs" smbpath="//$smbsrv/ВКС" smbfolder="/media/smbshare" recfolder="/recordings" smbcredfile="/root/smbcred" syncfile="/root/sync.sh" wipefile="/root/wipe-recordings.sh" # required components apt install cifs-utils -y # mount folder mkdir $smbfolder # SMB credentials file echo "username=$username" > $smbcredfile echo "domain=$domain" >> $smbcredfile echo "password=$password" >> $smbcredfile chmod 600 $smbcredfile # mount command # mount -t cifs -o credentials=$smbcredfile "$smbpath" $smbfolder # mount on boot echo >> /etc/fstab echo "# SMB share at $smbsrv" >> /etc/fstab echo "$smbpath $smbfolder cifs credentials=$smbcredfile,file_mode=0755,dir_mode=0755 0 0" >> /etc/fstab # sync echo "#!/bin/sh" > $syncfile echo "if grep -qs '//$smbsrv' /proc/mounts; then" >> $syncfile echo " rsync --archive --include=*.mp4 --exclude=* $recfolder/*/ $smbfolder/" >> $syncfile echo "fi" >> $syncfile chmod +x $syncfile # launch every 5 min echo >> /etc/crontab echo "# Sync $recfolder folder" >> /etc/crontab echo "*/5 * * * * root $syncfile" >> /etc/crontab # del files older than 3 days echo "#!/bin/sh" > $wipefile echo "find $recfolder -name '*' -mtime +3 -exec rm -f {} \;" >> $wipefile echo "rmdir $recfolder/*" >> $wipefile chmod +x $wipefile # launch once per day at 7 AM echo >> /etc/crontab echo "# Wipe old recordings" >> /etc/crontab echo "0 7 * * * root $wipefile" >> /etc/crontab
Стриминг
Если не на Youtube, то
Just use the full RTMP destination URL as a stream key.
https://sourceforge.net/projects/monaserver/ - RTMP-сервер для Windows. Он просто запускается, а потом на него можно натравить VLC, который будет показывать картинку.
Качество видеозахвата и конференции в целом
Разрешение видео в конференции: nano /etc/jitsi/meet/<jitsi-url>-config.js
For example: set resolution: 1080
(and uncomment if necessary); uncomment the entire constraints section and set ideal: 1080
, max: 1080
Разрешение захвата/трансляции можно понизить, например, до 720p. На серверах Jibri:
nano /etc/jitsi/jibri/xorg-video-dummy.conf # Section "Screen" Modes "1280x720" #Modes "1920x1080" # В старых версиях - параметр Virtual: #Virtual 1920 1080 Virtual 1280 720 nano /etc/jitsi/jibri/jibri.conf jibri { ffmpeg { resolution = "1280x720" } } systemctl stop jibri-xorg sleep 3 systemctl start jibri
https://community.jitsi.org/t/jitsi-not-joined-yet-cannot-read-properties-of-undefined-reading-isjoined/110642/30
https://community.jitsi.org/t/jibri-resolution-now-defaults-to-1080p/95478
По конференции в целом - настройки на сервере Jitsi.
https://community.jitsi.org/t/video-quality-and-new-install/101297/11
https://community.jitsi.org/t/improving-video-quality/92700/13
https://community.jitsi.org/t/decreasing-video-resolution-does-not-decrease-kbits-traffic-on-jitsi-server/17263/12
https://community.jitsi.org/t/reducing-resource-usage-to-improve-performance-both-client-side-and-server-side/39891
Решение проблем
После начала записи ffmpeg съедает все ресурсы и вылетает
Добавить процессорных ядер на виртуалке.
https://github.com/jitsi/jibri/issues/269
Видеофайл не открывается
Нужно на сервере Jibri установить java 8, а не 11.
sudo apt-get install openjdk-8-jdk openjdk-8-jre sudo update-alternatives --config java # выбрать 8-ю версию
https://community.jitsi.org/t/fixed-cannot-open-file-recording/21348/3
Запись или стрим выключаются сами собой через какое-то время
Происходит, когда тупо заводят ролик и выключают все камеры и микрофоны. Решение - не делать так, либо переопределить в /etc/jitsi/jibri/jibri.conf
jibri { call-status-checks { // If all clients have their audio and video muted and if Jibri does not // detect any data stream (audio or video) comming in, it will stop // recording after NO_MEDIA_TIMEOUT expires. no-media-timeout = 30 seconds // If all clients have their audio and video muted, Jibri consideres this // as an empty call and stops the recording after ALL_MUTED_TIMEOUT expires. all-muted-timeout = 10 minutes // When detecting if a call is empty, Jibri takes into consideration for how // long the call has been empty already. If it has been empty for more than // DEFAULT_CALL_EMPTY_TIMEOUT, it will consider it empty and stop the recording. default-call-empty-timeout = 30 seconds } }
https://community.jitsi.org/t/jibri-recording-empty-conference/84283/5
Ошибка при обновлении сертификата Let's Encrypt
nginx: [emerg] "server_names_hash_bucket_size" directive is duplicate in /etc/nginx/sites-enabled/jitsi.domain.ru.conf:1 Cleaning up challenges Attempting to renew cert (jitsi.domain.ru) from /etc/letsencrypt/renewal/jitsi.domain.ru.conf produced an unexpected error: nginx restart failed: . Skipping. All renewal attempts failed. The following certs could not be renewed: /etc/letsencrypt/live/jitsi.domain.ru/fullchain.pem (failure)
Решение:
# Закомментировать параметр в конфиге сайта sed -i ' s/server_names_hash_bucket_size/# server_names_hash_bucket_size 128;/g ' /etc/nginx/sites-enabled/jitsi.domain.ru.conf # Прописать в общем конфиге nginx sed -i ' s/server_names_hash_bucket_size/server_names_hash_bucket_size 128;/g ' /etc/nginx/nginx.conf # Запустить обновление сертификата certbot-auto renew
https://community.jitsi.org/t/lets-encrypt-wont-renew-tls-certificates-with-jitsi-nginx-config/61172
Jitsi не обновляется
# apt update && apt upgrade -y && apt autoremove -y Hit:1 http://ru.archive.ubuntu.com/ubuntu focal InRelease Get:2 http://ru.archive.ubuntu.com/ubuntu focal-updates InRelease [114 kB] Get:3 http://ru.archive.ubuntu.com/ubuntu focal-backports InRelease [108 kB] Get:4 http://ru.archive.ubuntu.com/ubuntu focal-security InRelease [114 kB] Get:5 http://packages.prosody.im/debian focal InRelease [7275 B] Get:6 http://packages.prosody.im/debian focal/main amd64 Packages [1830 B] Hit:7 https://download.jitsi.org stable/ InRelease Fetched 345 kB in 1s (337 kB/s) Reading package lists... Done Building dependency tree Reading state information... Done 7 packages can be upgraded. Run 'apt list --upgradable' to see them. Reading package lists... Done Building dependency tree Reading state information... Done Calculating upgrade... Done The following packages have been kept back: jicofo jitsi-meet jitsi-meet-prosody jitsi-meet-web jitsi-meet-web-config jitsi-videobridge2 prosody 0 upgraded, 0 newly installed, 0 to remove and 7 not upgraded. Reading package lists... Done Building dependency tree Reading state information... Done 0 upgraded, 0 newly installed, 0 to remove and 7 not upgraded.
Проблема в том, что Prosody имеет версию ниже требуемой (0.11.7).
# prosodyctl about Prosody 0.11.4 ...
Решение - установить последнюю версию prosody 0.11 (0.12 несовместима на конец 2022 г):
apt install prosody-0.11
Дальше можно обновляться как обычно.
Если перед версией 0.11 сначала была по ошибке установлена версия 0.12, то запуск службы будет заблокирован:
systemctl start prosody
Failed to start prosody.service: Unit prosody.service is masked.
# Решение
systemctl unmask prosody
systemctl start prosody