Record a Jitsi meeting and store the composite in S3

Produce one predictable meeting file instead of assembling per-participant recordings after the call.

The pipeline

  1. Jitsi source
  2. video mixer
  3. audio mixer
  4. S3 segment sink

What this replaces

Build it yourself

  • Deploy Jibri and size it for concurrent recordings
  • Configure hidden recorder domains on self-hosted Jitsi
  • Post-process separate tracks into a shared layout
  • Move finished files into durable storage

With AVFlow

  • Connect by Jitsi domain and room name
  • Choose the same grid layout model used by other AVFlow Jobs
  • Write to your own S3 path prefix
  • Stop the Job explicitly or let idle policy end it

The validated Job

This is the same file 16-jitsi-recording.json serves. Replace platform credentials, output URLs, and storage secrets before running it.

16-jitsi-recording.json Download
{
  "name": "jitsi-recording",
  "sources": [
    {
      "name": "conf_src",
      "type": "jitsi",
      "config": {
        "domain": "meet.jit.si",
        "roomName": "MyRoomABC123",
        "select": {
          "mediaTypes": [
            "video",
            "audio"
          ]
        }
      }
    }
  ],
  "nodes": [
    {
      "name": "mix_video",
      "type": "video_mixer",
      "inputs": [
        "conf_src"
      ],
      "config": {
        "canvas": {
          "width": 1280,
          "height": 720,
          "backgroundColor": "#1a1a2e"
        },
        "layout": {
          "mode": "grid",
          "common": {
            "borderRadius": 8
          },
          "grid": {
            "maxColumns": 3,
            "gap": 4,
            "fit": "cover"
          }
        }
      }
    },
    {
      "name": "mix_audio",
      "type": "audio_mixer",
      "inputs": [
        "conf_src"
      ],
      "config": {}
    }
  ],
  "sinks": [
    {
      "name": "segment_out",
      "type": "segment",
      "inputs": [
        "mix_video",
        "mix_audio"
      ],
      "config": {
        "storageType": "s3",
        "storageConfig": {
          "bucket": "recordings",
          "region": "us-east-1",
          "accessKeyId": "AKIAIOSFODNN7EXAMPLE",
          "secretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
          "pathPrefix": "jitsi/{jobName}/{date}/",
          "filename": "{jobName}_{timestamp}"
        },
        "encoding": {
          "videoCodec": "h264",
          "audioCodec": "aac"
        }
      }
    }
  ],
  "policies": {
    "idleTimeoutSec": 120
  }
}
Submit it API
curl -X POST "https://api.avflow.dev/v1/jobs" \
  -H "Authorization: Bearer $AVFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d @16-jitsi-recording.json

Know the limits before you ship

  • Self-hosted hidden-domain recording may require Jibri-compatible XMPP credentials.
  • meet.jit.si and JaaS impose their own access and visibility constraints.
  • The example records a grid; speaker and custom layouts need a different mixer config.

Run this Jitsi pipeline

Generate the Job in Playground, then run it with $20 promotional credit.