--- gitea: none include_toc: true --- # Element Call Element Call enables users to have audio and videocalls with groups, while maintaining full E2E encryption. It requires several bits of software and entries in .well-known/matrix/client This bit is for later, but here's a nice bit of documentation to start: https://sspaeth.de/2024/11/sfu/ # Install prerequisites Define an entry in DNS for Livekit and Call, e.g. `livekit.matrixdev.example.com` and `call.matrixdev.example.com`. Get certificates for them. Expand `.well-known/matrix/client` to contain the pointer to the SFU: ``` "org.matrix.msc4143.rtc_foci": [ { "type": "livekit", "livekit_service_url": "https://livekit.matrixdev.example.com" } ] ``` Create `.well-known/element/element.json`, which is opened by Element-web and ElementX to find the Element Call widget. It should contain something like this: ``` { "call": { "widget_url": "https://call.matrixdev.example.com" } } ``` Make sure it is served as `application/json`, just like the other .well-known files. lk-jwt-service is a small Go program that handles authorization tokens. You'll need a Go compiler, so install that: ``` apt install golang ``` # lk-jwt-service {#livekit} Get the latest source code and comile it (preferably *NOT* as root): ``` git clone https://github.com/element-hq/lk-jwt-service.git cd lk-jwt-service go build -o lk-jwt-service ``` You'll then notice that you need a newer compiler, so we'll download that and add it to our PATH (again not as root): ``` wget https://go.dev/dl/go1.23.3.linux-amd64.tar.gz tar xvfz go1.23.3.linux-amd64.tar.gz cd go/bin export PATH=`pwd`:$PATH cd ``` Now, compile: ``` cd lk-jwt-service go build -o lk-jwt-service ``` Copy and chown the binary to `/usr/local/sbin` (yes: as root): ``` cp ~user/lk-jwt-service/lk-jwt-service /usr/local/sbin chown root:root /usr/local/sbin/lk-jwt-service ``` Create a service file for systemd, something like this: ``` # This thing does authorization for Element Call [Unit] Description=LiveKit JWT Service After=network.target [Service] Restart=always User=www-data Group=www-data #WorkingDirectory=/opt/lk-jwt-service EnvironmentFile=/etc/lk-jwt-service/config ExecStart=/usr/local/sbin/lk-jwt-service [Install] WantedBy=multi-user.target ``` Not sure about the `WorkingDirectory`, so it's commented out until it turns out to be necessary. We read the options from `/etc/lk-jwt-service/config`, which we make read-only for group `www-data` and non-accessible by anyone else. ``` mkdir /etc/lk-jwt-service vi /etc/lk-jwt-service/config chgrp -R www-data /etc/lk-jwt-service chmod -R o-rwx /etc/lk-jwt-service ``` The contents of `/etc/lk-jwt-service/config` are not fully known yet ([see further, installation of the actual LiveKit, the SFU](#generatekeys)), but for now it's enough to fill it with this: ``` LIVEKIT_URL=wss://livekit.matrixdev.example.com LIVEKIT_SECRET=xxx LIVEKIT_KEY=xxx LK_JWT_PORT=8080 ``` Now enable and start this thing: ``` systemctl enable --now lk-jwt-service ``` # LiveKit The actual SFU, Selective Forwarding Unit, is LiveKit. Downloading and installing is easy: download the [binary from Github](https://github.com/livekit/livekit/releases/download/v1.8.0/livekit_1.8.0_linux_amd64.tar.gz) to /usr/local/bin, chown it to root:root and you're done. The quickest way to do precisely that, is to run the script: ``` curl -sSL https://get.livekit.io | bash ``` You can do this as a normal user, it will use sudo to do its job. Configuring this thing is [documented here](https://docs.livekit.io/home/self-hosting/deployment/). Create a key and secret: {#generatekeys} ``` livekit-server generate-keys ``` This key/secret has to be fed to lk-jwt-service, of course. Create a configuration file for livekit, `/etc/livekit/livekit.yaml`: ``` port: 7880 bind_addresses: - "" rtc: tcp_port: 7881 port_range_start: 50000 port_range_end: 60000 use_external_ip: true enable_loopback_candidate: false turn: enabled: true domain: livekit.matrixdev.procolix.com cert_file: /etc/coturn/ssl/fullchain.pem key_file: /etc/coturn/ssl/privkey.pem tls_port: 5349 udp_port: 3478 external_tls: true keys: # KEY: secret were autogenerated by livekit/generate # in the lk-jwt-service environment variables xxxxxxxxxxxxxxx: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ``` Now define a systemd servicefile, like this: ``` [Unit] Description=LiveKit Server After=network.target Documentation=https://docs.livekit.io [Service] User=turnserver Group=turnserver LimitNOFILE=500000 Restart=on-failure WorkingDirectory=/etc/livekit ExecStart=/usr/local/bin/livekit-server --config /etc/livekit/livekit.yaml [Install] WantedBy=multi-user.target ``` Enable and start it. IMPORTANT! If you're running [coturn](../coturn), you'll have to shut that down! Otherwise LiveKit will not be able to claim the ports for TURN and ICE. And in that case, Synapse will probably not be able to provide clients with the correct TURN data, that is still to be researched... # Element Call widget {#widget} This is a Node.js thingy, so start by installing yarn. Unfortunately both npm and `yarnpkg` in Debian are antique, so we need to update them after installation. Install Node.js and upgrade everything. Do not do this as root, we'll only need to "compile" Element Call once. See [the Node.js website](https://nodejs.org/en/download/package-manager/current) for instructions. ``` curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash ``` Exit and login again to set some environment variables (yes, the installation changes .bashrc). Then install and upgrade: ``` nvm install 23 sudo apt install yarnpkg /usr/share/nodejs/yarn/bin/yarn set version stable /usr/share/nodejs/yarn/bin/yarn install ``` Now clone the Element Call repository and "compile" stuff (again: not as root): ``` git clone https://github.com/element-hq/element-call.git cd element-call /usr/share/nodejs/yarn/bin/yarn /usr/share/nodejs/yarn/bin/yarn build ``` After that, you can find the whole shebang under "dist". Copy that to `/var/www/element-call` and point nginx to it ([see nginx](../nginx#callwidget)).