Files
reflector/server/contrib/jitsi/README.md

6.5 KiB

Event Logger for Docker-Jitsi-Meet

A Prosody module that logs Jitsi meeting events to JSONL files alongside recordings, enabling complete participant tracking and speaker statistics.

Prerequisites

  • Running docker-jitsi-meet installation
  • Jibri configured for recording

Installation

Step 1: Copy the Module

Copy the Prosody module to your custom plugins directory:

# Create the directory if it doesn't exist
mkdir -p ~/.jitsi-meet-cfg/prosody/prosody-plugins-custom

# Copy the module
cp mod_event_logger.lua ~/.jitsi-meet-cfg/prosody/prosody-plugins-custom/

Step 2: Update Your .env File

Add or modify these variables in your .env file:

# If XMPP_MUC_MODULES already exists, append event_logger
# Example: XMPP_MUC_MODULES=existing_module,event_logger
XMPP_MUC_MODULES=event_logger

# Optional: Configure the module (these are defaults)
JIBRI_RECORDINGS_PATH=/config/recordings
JIBRI_LOG_SPEAKER_STATS=true
JIBRI_SPEAKER_STATS_INTERVAL=10

Important: If you already have XMPP_MUC_MODULES defined, add event_logger to the comma-separated list:

# Existing modules + our module
XMPP_MUC_MODULES=mod_info,mod_alert,event_logger

Step 3: Modify docker-compose.yml

Add a shared recordings volume so Prosody can write events alongside Jibri recordings:

services:
  prosody:
    # ... existing configuration ...
    volumes:
      - ${CONFIG}/prosody/config:/config:Z
      - ${CONFIG}/prosody/prosody-plugins-custom:/prosody-plugins-custom:Z
      - ${CONFIG}/recordings:/config/recordings:Z  # Add this line
    environment:
      # Add if not using .env file
      - XMPP_MUC_MODULES=${XMPP_MUC_MODULES:-event_logger}
      - JIBRI_RECORDINGS_PATH=/config/recordings

  jibri:
    # ... existing configuration ...
    volumes:
      - ${CONFIG}/jibri:/config:Z
      - ${CONFIG}/recordings:/config/recordings:Z  # Add this line
    environment:
      # For Reflector webhook integration (optional)
      - REFLECTOR_WEBHOOK_URL=${REFLECTOR_WEBHOOK_URL:-}
      - JIBRI_FINALIZE_RECORDING_SCRIPT_PATH=/config/finalize.sh

Step 4: Add Finalize Script (Optional - For Reflector Integration)

If you want to notify Reflector when recordings complete:

# Copy the finalize script
cp finalize.sh ~/.jitsi-meet-cfg/jibri/finalize.sh
chmod +x ~/.jitsi-meet-cfg/jibri/finalize.sh

# Add to .env
REFLECTOR_WEBHOOK_URL=http://your-reflector-api:8000

Step 5: Restart Services

docker-compose down
docker-compose up -d

What Gets Created

After a recording, you'll find in ~/.jitsi-meet-cfg/recordings/{session-id}/:

  • recording.mp4 - The video recording (created by Jibri)
  • metadata.json - Basic metadata (created by Jibri)
  • events.jsonl - Complete participant timeline (created by this module)

Event Format

Each line in events.jsonl is a JSON object:

{"type":"room_created","timestamp":1234567890,"room_name":"TestRoom","room_jid":"testroom@conference.meet.jitsi","meeting_url":"https://meet.jitsi/TestRoom"}
{"type":"recording_started","timestamp":1234567891,"room_name":"TestRoom","session_id":"20240115120000_TestRoom","jibri_jid":"jibri@recorder.meet.jitsi"}
{"type":"participant_joined","timestamp":1234567892,"room_name":"TestRoom","participant":{"jid":"user1@meet.jitsi/web","nick":"John Doe","id":"user1@meet.jitsi","is_moderator":false}}
{"type":"speaker_active","timestamp":1234567895,"room_name":"TestRoom","speaker_jid":"user1@meet.jitsi","speaker_nick":"John Doe","duration":10}
{"type":"participant_left","timestamp":1234567920,"room_name":"TestRoom","participant":{"jid":"user1@meet.jitsi/web","nick":"John Doe","duration_seconds":28}}
{"type":"recording_stopped","timestamp":1234567950,"room_name":"TestRoom","session_id":"20240115120000_TestRoom","meeting_url":"https://meet.jitsi/TestRoom"}

Configuration Options

All configuration can be done via environment variables:

Environment Variable Default Description
JIBRI_RECORDINGS_PATH /config/recordings Path where recordings are stored
JIBRI_LOG_SPEAKER_STATS true Enable speaker statistics logging
JIBRI_SPEAKER_STATS_INTERVAL 10 Seconds between speaker stats updates

Verifying Installation

Check that the module is loaded:

docker-compose logs prosody | grep "Event Logger"
# Should see: "Event Logger loaded - writing to /config/recordings"

Check for events after a recording:

ls -la ~/.jitsi-meet-cfg/recordings/*/events.jsonl
cat ~/.jitsi-meet-cfg/recordings/*/events.jsonl | jq .

Troubleshooting

No events.jsonl file created

  1. Check module is enabled:

    docker-compose exec prosody grep -r "event_logger" /config
    
  2. Verify volume permissions:

    docker-compose exec prosody ls -la /config/recordings
    
  3. Check Prosody logs for errors:

    docker-compose logs prosody | grep -i error
    

Module not loading

  1. Verify file exists in container:

    docker-compose exec prosody ls -la /prosody-plugins-custom/
    
  2. Check XMPP_MUC_MODULES format (must be comma-separated, no spaces):

    • Correct: XMPP_MUC_MODULES=mod1,mod2,event_logger
    • Wrong: XMPP_MUC_MODULES=mod1, mod2, event_logger

Common docker-compose.yml Patterns

Minimal Addition (if you trust defaults)

services:
  prosody:
    volumes:
      - ${CONFIG}/recordings:/config/recordings:Z  # Just add this

Full Configuration

services:
  prosody:
    volumes:
      - ${CONFIG}/prosody/config:/config:Z
      - ${CONFIG}/prosody/prosody-plugins-custom:/prosody-plugins-custom:Z
      - ${CONFIG}/recordings:/config/recordings:Z
    environment:
      - XMPP_MUC_MODULES=event_logger
      - JIBRI_RECORDINGS_PATH=/config/recordings
      - JIBRI_LOG_SPEAKER_STATS=true
      - JIBRI_SPEAKER_STATS_INTERVAL=10

  jibri:
    volumes:
      - ${CONFIG}/jibri:/config:Z
      - ${CONFIG}/recordings:/config/recordings:Z
    environment:
      - JIBRI_RECORDING_DIR=/config/recordings
      - JIBRI_FINALIZE_RECORDING_SCRIPT_PATH=/config/finalize.sh

Integration with Reflector

The finalize.sh script will automatically notify Reflector when a recording completes if REFLECTOR_WEBHOOK_URL is set. Reflector will receive:

{
  "session_id": "20240115120000_TestRoom",
  "path": "20240115120000_TestRoom",
  "meeting_url": "https://meet.jitsi/TestRoom"
}

Reflector then processes the recording along with the complete participant timeline from events.jsonl.