Jitsi Meet Jibriによる録画機能設定

はじめに

Jitsi Meetは、他のオンライン会議サービスと同様に、会議を録画して保存する機能が用意されています。
録画機能としては、保存先がクライアントローカルとサーバーの2種類あります。

ここでは、
クライアントローカルに保存する録画機能を「ローカル保存録画」
サーバーに保存する録画機能を「サーバー保存録画」
と呼ぶことにします。(一般的なネーミングではありません。)

「ローカル保存録画」は、以前はサイズ1GBの制限がありましたが、2025年6月にリリースされたバージョン10314から、この制限が撤廃されました。

「ローカル保存録画」はデフォルトで有効となっており、何も設定しなくてもすぐに利用できます。
サイズ制限が撤廃されたため、運用としてはローカル保存で問題ないように思いますが、ここでは「サーバー保存録画」の設定について記載します。

Jibri

「サーバー保存録画」は、Jibriというコンポーネントを使用します。
仕様上、Jibriは、1インスタンスで1つの会議しか録画できないため、会議サービスで複数の会議を同時に録画するためには、複数のインスタンスを起動する必要があります。
このため、JibriはDockerコンテナによる稼働が(ほぼ)必須となるようです。

今回は、以前構築したDocker版Jitsi Meet on Ubuntuの環境に、Jibriによるサーバー録画機能を追加する設定を記載します。
Jitsi MeetのURLは https://meet.exmaple.jp/ とします。

この設定については、Jitsi Meet Handbook の Recording 項が参考になります。

・Recording / live streaming configuration with Jibri – Jitsi Meet Handbook
https://jitsi.github.io/handbook/docs/devops-guide/devops-guide-docker/#recording–live-streaming-configuration-with-jibri

AWSサーバーの場合

AWSのサーバー(EC2やLightsail)の場合、awsカーネルではなく、generalカーネルに切り替える必要があります。

先ほど紹介した、Jitsi Meet Handbook の Recording 項に、以下のような方法が記載されています。

# open the grub file in editor
nano /etc/default/grub
# Modify the value of GRUB_DEFAULT from "0" to "1>2"
# Save and exit from file

# Update grub
update-grub
# Reboot the machine
reboot now

ですが、僕はこの方法ではうまくいかなかったため、以下を参考にしました。

(参考)
・Changing the kernel for 20.04 in AWS appears to break boot sequence (may be a grub config issue?) – ask Ubuntu
https://askubuntu.com/questions/1365369/changing-the-kernel-for-20-04-in-aws-appears-to-break-boot-sequence-may-be-a-gr

まず、稼働中のカーネルを確認します。

 # uname -r

6.8.0-1029-aws

↑末尾が -aws となっており、awsカーネルが起動していることがわかります。

genericカーネルをインストールします。

 # apt install linux-generic

GRUBのconfigで、GRUB_DEFAULT を変更します。

 # vim /etc/default/grub
#GRUB_DEFAULT=0
GRUB_DEFAULT="1>2"

GRUBのルートデバイスを強制設定するconfigで、GRUB_FORCE_PARTUUID 行をコメントアウトします。

 # vim /etc/default/grub.d/40-force-partuuid.cfg
# Force boot without an initramfs by setting GRUB_FORCE_PARTUUID
# Remove this line to enable boot with an initramfs
#GRUB_FORCE_PARTUUID=5dc615d4-2c42-4b92-8944-xxxxxxxxxxxx

GRUBとGRUB2をアップデートしてOSを再起動します。

 # update-grub

 # update-grub2

 # shutdown -r now

再起動後、稼働中のカーネルを確認します。

 # uname -r

6.8.0-60-generic

↑末尾が -aws ではなく -generic となり、genericカーネルが起動していることがわかります。

無事genericカーネルに切り替えることができました。
ただし、僕が試したときは、カーネルを切り替えると、なぜかDockerサービスが起動しなくなったため、DockerパッケージとJitsi Meetをすべてアンインストール、削除して、再インストールする必要がありました。

AWS環境でJitsi Meetを構築し、Jibriをインストールするときは、Jitsi Meetをインストールする前に、generalカーネルに切り替えるほうが安全かもしれません。

なお、以下は、Jitsi Meet 7439以前のバージョンでのみ必要な設定ですので、通常の手順で最新バージョンをインストールする際は不要です。

apt update && apt install linux-image-extra-virtual
# configure 5 capture/playback interfaces
echo "options snd-aloop enable=1,1,1,1,1 index=0,1,2,3,4" > /etc/modprobe.d/alsa-loopback.conf
# setup autoload the module
echo "snd-aloop" >> /etc/modules
# check that the module is loaded
lsmod | grep snd_aloop

Jibriの複数起動設定

ここでは、Jibriのコンテナを4つ起動し、最大で4つの会議を同時に録画できるようにします。

Jibriの有効設定

Jitsi Meetの基本設定 .env で、Jibriの録画機能を有効とします。
これにより、会議開始後のメニューに「サーバー保存録画」を意味する選択肢が表示されるようになります。

 $ cd ~/jitsi-meet/
 $ vim .env
...
ENABLE_RECORDING=1  // 追記

nftablesの設定

nftablesを使用し、かつ、Dockerが自動的にiptablesルールを追加しない設定とし、かつ、アクセス元を日本のIPアドレスに限定している場合は、Dockerのユーザー定義ブリッジネットワークのインタフェースの TCP/443 宛てのアクセス許可ルールを追加します。

 # vim /etc/nftables.conf
#!/usr/sbin/nft -f
flush ruleset

define docker_user_bridge = {"br-xxxxxxxxxxxx"}
define docker_bridges = {"docker0", "br-xxxxxxxxxxxx"}
define docker_bridges_and_lo = {"docker0", "br-xxxxxxxxxxxx", "lo"}

table ip filter {
  set country_accept {
    type ipv4_addr; flags interval;
    elements = $country_allowlist
  }

  chain INPUT {
    type filter hook input priority 0; policy drop;

    ct state established,related counter accept
    ct state invalid counter drop

    iifname "lo" counter accept

    ct state new tcp dport 80 ip saddr @country_accept counter accept
    ct state new tcp dport 443 ip saddr @country_accept counter accept
    ct state new udp dport 10000 ip saddr @country_accept counter accept
    iifname $docker_user_bridge ct state new tcp dport 8000 counter accept
    iifname $docker_user_bridge ct state new tcp dport 443 counter accept  // この行追加
    ct state new tcp dport 22 counter accept

    icmp type echo-reply counter accept
    icmp type destination-unreachable counter accept
    icmp type time-exceeded counter accept
  }

...

nftables を reload して反映します。

 # systemctl reload nftables

コンテナの再起動とjibriコンテナの起動・設定

Dockerコンテナを再起動して反映します。
まず、コンテナを停止。

 $ docker compose stop

Jibriを含めて、Dockerコンテナを起動します。
-f jibri.yml で、jibriコンテナのymlを含めるのと、
--scale jibri=4 で、jibriコンテナを4つ起動するよう指定するのがポイントです。

(参考)
・Scale multiple Jibri instance with Docker
https://github.com/danitfk/scale-jibri-docker

 $ docker compose -f docker-compose.yml -f jibri.yml up -d --scale jibri=4

 ? Container jitsi-meet-prosody-1  Sta...                                  0.4s
 ? Container jitsi-meet-jvb-1      Started                                 1.2s
 ? Container jitsi-meet-web-1      Started                                 2.4s
 ? Container jitsi-meet-jicofo-1   Star...                                 1.2s
 ? Container jitsi-meet-jibri-4    Start...                                6.4s
 ? Container jitsi-meet-jibri-1    Start...                                3.5s
 ? Container jitsi-meet-jibri-2    Start...                                2.3s
 ? Container jitsi-meet-jibri-3    Start...                                4.9s

それぞれのjibriコンテナが、異なるループバック・インタフェースを選択するよう設定します。

 $ docker exec -t jitsi-meet-jibri-2 sed -i 's/Loopback/2/g' /home/jibri/.asoundrc
 $ docker exec -t jitsi-meet-jibri-3 sed -i 's/Loopback/3/g' /home/jibri/.asoundrc
 $ docker exec -t jitsi-meet-jibri-4 sed -i 's/Loopback/4/g' /home/jibri/.asoundrc

この設定を反映するため、2,3,4つ目のjibriコンテナを再起動します。

 $ docker stop jitsi-meet-jibri-{2,3,4}

 $ docker start jitsi-meet-jibri-{2,3,4}

録画の動作確認

ブラウザでJitsi Meetにアクセスして、会議室を作成してみます。

「録画の開始」メニューを選択すると、、、

「ローカルに録画を保存(Beta)」のほかに、
「ビデオは録画サービスで録画されます」が表示されるようになりました。
(このメニューはホストユーザーの画面でのみ表示され、ゲストユーザーでは表示されないようです。)

※メニューの文言は、Jitsi Meetのバージョンによって異なる可能性があります。

この機能で録画を開始すると、英語で「録画を開始しました」という旨の音声が流れます。
終了時は「録画を終了しました」という旨の音声が流れます。

録画データは、サーバー上の
~/.jitsi-meet-cfg/jibri/recordings/
以下の、ランダム(?)なディレクトリ名の配下にmp4形式で保存されます。
ファイル名は、会議名と会議開始日時(YYYY-MM-DD-hh-mm-ss)を含みます。

 $ cd ~/.jitsi-meet-cfg/jibri/recordings/
 $ ls -l

drwxr-xr-x 2    999 crontab 4096  6月 17 11:01 727cc41b-6c78-4f22-8645-3a47ac1c1886
drwxr-xr-x 2    999 crontab 4096  6月 17 10:48 803c6e34-be86-42f6-aeb3-c16f56a5c0ca
drwxr-xr-x 2    999 crontab 4096  6月 17 11:00 fbf685e0-15cf-496d-a619-4090054fbd74

 $ cd fbf685e0-15cf-496d-a619-4090054fbd74/
 $ ls -l

-rw-r--r-- 1    999 crontab 1457117  6月 17 11:00 isdtest_2025-06-17-10-56-52.mp4
-rw-r--r-- 1    999 crontab      83  6月 17 11:00 metadata.json

Jibriによる録画ですが、実は、上記の手順でうまくいかない(「録画を準備しています」のまま録画開始せず失敗する)ことも何度かありました。
その場合は、

  • Jibriのログ ~/.jitsi-meet-cfg/jibri/logs/log..txt. を調査。
  • iptables, nftablesのアクセス制限を一時的にフル許可やファイル・ディレクトリのパーミッションなどを変更して切り分け。
  • 一度Jitsi Meetコンテナをアンインストールして、再度同じ手順でインストール。

などをやってみるとよいでしょう。

録画ファイルダウンロードの設定(案)

Jibriの設定で、「サーバー保存録画」ができるようになりましたが、Jitsi Meetの画面から録画ファイルダウンロードする機能は用意されていません。
ここでは、録画ファイルをダウンロードする方法のひとつを記載します。

方針

Jibriでは、録画終了時にフックして実行するスクリプトを設定できます。
今回は、以下の方針で、録画ファイルをダウンロードできるようにします。

  • ホストサーバーにリバースプロキシ用Nginxをインストールする。
  • Nginxで録画ファイルダウンロードディレクトリを公開し、アクセス制限をつけて、ブラウザからダウンロードできるようにする。
  • スクリプトで、録画ファイルをダウンロードディレクトリに移動する。

ホストサーバーにリバースプロキシ用Nginxをインストール

以前書いた記事を参照してください。

・Jitsi Meet ホストサーバーのNginxリバースプロキシ設定
https://inaba-serverdesign.jp/blog/20251014/jitsi-meet-nginx-reverse-proxy-on-docker-host.html

Jitsi Meetコンテナの設定

Jitsi Meetの基本設定 .env で、Jibri録画終了時に実行するスクリプトのパス設定を追記します。

 $ cd ~/jitsi-meet/
 $ vim .env
...

# The finalizing script. Will run after recording is complete
JIBRI_FINALIZE_RECORDING_SCRIPT_PATH=/config/recordings/finalyze.sh

コンテナを再作成して反映させます。

 $ docker compose -f docker-compose.yml -f jibri.yml up -d --scale jibri=4

↑これで、jibriコンテナのみrecreateされます。

jibriコンテナがrecreateされたため、再度、異なるループバック・インタフェースを選択するよう設定します。
(不要かもしれませんが念のため。)

 $ docker exec -t jitsi-meet-jibri-2 sed -i 's/Loopback/2/g' /home/jibri/.asoundrc
 $ docker exec -t jitsi-meet-jibri-3 sed -i 's/Loopback/3/g' /home/jibri/.asoundrc
 $ docker exec -t jitsi-meet-jibri-4 sed -i 's/Loopback/4/g' /home/jibri/.asoundrc

スクリプトの設定

録画終了時にフックして実行するスクリプトは、以下の記事内スクリプトをベースにして、カスタマイズしました。

(参考)
・How-to to get a WORKING setup of Google Drive, One Drive or other cloud services in Jibri, my comprehensive tutorial for the beginner – Jitsi.org Community
https://community.jitsi.org/t/how-to-to-get-a-working-setup-of-google-drive-one-drive-or-other-cloud-services-in-jibri-my-comprehensive-tutorial-for-the-beginner/42228/25

 # vim /home/jitsi-meet/.jitsi-meet-cfg/jibri/recordings/finalyze.sh
#!/bin/bash
# move jibri recording file to web server linked dir 

RECORDINGS_DIR=$1

VIDEO_FILE_PATH=$(find $RECORDINGS_DIR -name *.mp4)
VIDEO_FILE_NAME=`/usr/bin/basename ${VIDEO_FILE_PATH}`
DOCKER_RECORDINGS=/config/recordings
PUBLISH=publish
LOGFILE=${DOCKER_RECORDINGS}/publish_recording.log

echo "===== move jibri recording file =====" >> ${LOGFILE}
echo "`date` move jibri recording file start" >> ${LOGFILE}

echo "RECORDINGS DIR: ${RECORDINGS_DIR}" >> ${LOGFILE}
echo "ORIGINAL VIDEO FILE PATH: ${VIDEO_FILE_PATH}" >> ${LOGFILE}
echo "VIDEO FILE NAME: ${VIDEO_FILE_NAME}" >> ${LOGFILE}
echo "MOVED VIDEO FILE PATH: ${DOCKER_RECORDINGS}/$PUBLISH/${VIDEO_FILE_NAME}" >> ${LOGFILE}

mkdir -p $DOCKER_RECORDINGS/$PUBLISH
mv $VIDEO_FILE_PATH $DOCKER_RECORDINGS/$PUBLISH/$VIDEO_FILE_NAME

rmdir $RECORDINGS_DIR

echo "`date` move jibri recording file end" >> ${LOGFILE}

# EOF

補足します。

録画ファイル xxx.mp4 と metadata.json ファイルを、ダウンロード用ディレクトリに移動して、録画ディレクトリを削除します。
(録画ディレクトリ名はランダムっぽい文字列でわかりにくいため。)
metadata.json ファイルは、役に立つ情報がない(ように見える)ので、削除しますが、必要でしたら、ダウンロードディレクトリに移動するとよいでしょう。

jibriコンテナでの録画ファイル保存ディレクトリは
/config/recordings
とします。

jibriコンテナのconfigによると、、

-- jibri.yml

services:
    jibri:

...

        volumes:
            - ${CONFIG}/jibri:/config:Z
...
--

ホストサーバーの /home/jitsi-meet/.jitsi-meet-cfg/jibri は、
jibriコンテナの /configとしてbindマウントしています。
よって、ホストサーバー上の録画ファイル保存ディレクトリは
/home/jitsi-meet/.jitsi-meet-cfg/jibri/recordings
となり、ダウンロード用のディレクトリは、publish をプラスして
/home/jitsi-meet/.jitsi-meet-cfg/jibri/recordings/publish
とします。

スクリプトに実行権限を付与します。

 # chmod 755 /home/jitsi-meet/.jitsi-meet-cfg/jibri/recordings/finalyze.sh

Nginxの設定

Nginx VirtualHost Configで、URL https://meet.example.jp/.rec/
で、autoindexでファイル一覧を表示し、録画ファイルをダウンロードできるようにします。
また、Nginxから見た公開ディレクトリは /var/www/rec とします。

第三者に不正アクセスされないよう、BASIC認証をかけていますが、アクセス元IPアドレスで制限をかけられるとより安全です。

 # vim /etc/nginx/conf.d/vhost_meet.example.jp.conf
...

    # Download Jibri Recording Files
    location /.rec {
        # BASIC Authentication
        auth_basic              "Please inpur user/password";
        auth_basic_user_file    "/etc/nginx/.htpasswd_rec";

        alias /var/www/rec;

        autoindex on;
        autoindex_exact_size off;
        autoindex_format html;
        autoindex_localtime on;
    }

...

Nginxをreloadして反映します。

 # nginx -t
 # systemctl reload nginx

BASIC認証で使用するパスワードファイルを作成します。

 # apt install apache2-utils

 # htpasswd -c -m /etc/nginx/.htpasswd_rec <user>

公開ディレクトリの設定

先ほどスクリプトで指定した、ホストサーバー上の録画ファイルダウンロードディレクトリ
/home/jitsi-meet/.jitsi-meet-cfg/jibri/recordings/publish
を、Nginxから見た公開ディレクトリ /var/www/rec にbindマウントします。

/home/jitsi-meet/.jitsi-meet-cfg/jibri/recordings/publish
をそのままNginxから参照できるようにしてもよいのですが、その場合は、Nginxの実行ユーザー www-data が /home/jitsi-meet ディレクトリにアクセスできるよう、パーミッションを設定する必要があります。
今回はそうしたくなかったので、別名でのbindマウントとしました。

 # mkdir /home/jitsi-meet/.jitsi-meet-cfg/jibri/recordings/publish
 # chown 999:root /home/jitsi-meet/.jitsi-meet-cfg/jibri/recordings/publish

/etc/fstab の末尾にbindマウント設定のエントリーを追加します。

  # vim /etc/fstab
...
/home/jitsi-meet/.jitsi-meet-cfg/jibri/recordings/publish /var/www/rec bind defaults,bind 0 0

Systemdに反映します。

 # systemctl daemon-reload

/var/www/rec ディレクトリを作成し、マウントします。

 # mkdir /var/www/rec
 # mount /var/www/rec

録画の動作確認

ブラウザでJitsi Meetにアクセスし、会議室を作成し、三点メニューから
「録画を開始」>「ビデオは録画サービスで録画されます」
で、録画を開始します。

メニューから「録画を停止」して、録画ファイルダウンロード用公開ディレクトリにアクセスしてみます。
https://meet.example.jp/.rec/

うまくいけば、↑こんな感じで録画ファイルのリストが見えて、ファイル名をクリックすることでダウンロードできます。

意図した動作にならなかったら、録画終了時にフックして実行するスクリプトのログを確認して調査するとよいでしょう。

 # less /home/jitsi-meet/.jitsi-meet-cfg/jibri/recordings/publish/publish_recording.log

録画ファイルの自動削除設定

録画する内容と重要度、機密性、アクセス制限の強度にもよりますが、録画ファイルは長期間保存せず、早めに削除するとよいでしょう。
ファイル最終更新後、12時間以上経過したファイルを自動削除するようにしてみます。

12時間以上経過したファイルを自動削除するスクリプトを作成します。

 # vim /root/bin/remove_jitsi_recfile.sh
#!/bin/bash

RECORDNG_DIR=/home/jitsi-meet/.jitsi-meet-cfg/jibri/recordings/publish
REMOVE_MIN_AFTER=720

echo "===== remove jibri recording file ====="
echo "`date` remove jibri recording file start"

find $RECORDNG_DIR -type f -mmin +$REMOVE_MIN_AFTER -print -exec rm {} +

echo "`date` remove jibri recording file end"

実行権限を付与します。

 # chmod 700 /root/bin/remove_jitsi_recfile.sh

毎時10分に実行するcronエントリーを作成します。

 # crontab -e

10 * * * * /root/bin/remove_jitsi_recfile.sh 1>> /var/log/remove_jitsi_recfile.log 2>&1

録画ファイルが意図したとおり、最終更新後12時間以上経過したのち自動削除されて、録画ファイルダウンロードページに表示されなくなったことと、削除処理のログを確認します。

 # less /var/log/remove_jitsi_recfile.log
===== remove jibri recording file =====
2025年  6月 18日 水曜日 03:10:01 JST remove jibri recording file start
/home/mps/.jitsi-meet-cfg/jibri/recordings/publish/isdtest_2025-06-17-14-52-27.mp4
2025年  6月 18日 水曜日 03:10:01 JST remove jibri recording file end

おわりに

Jitsi Meetで、Jibriによる「サーバー保存録画」の設定方法と、録画ファイルをダウンロードするひとつの方法をまとめました。

録画ファイルのダウンロードについては、録画終了時にフックして実行するスクリプトを設定できるので、スクリプトで、他のサーバーや、Dropbox、Googleドライブなどの共有ストレージサービスに転送するのもよいでしょう。

Jitsi Meetには管理機能がありませんが、個人的には、サーバーにユーザー情報や会議の履歴情報、データを残さないのが逆にセキュリティ上のメリットだと感じています。
ですので、録画ファイルをサーバーに保存したり、ダウンロードできるようにするのは、あまり好ましくないように思います。

冒頭にも書きましたが、Jibriによる「サーバー保存録画」ではなく、デフォルトで制限なく使用できる「ローカル保存録画」を使用するのがおすすめです。


Jitsi Meetについて書いた記事まとめ。

タイトルとURLをコピーしました