Record an Agora channel as a grid and upload it to S3

Record Agora calls or live channels without operating a native Agora recording client for every job.

The pipeline

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

What this replaces

Build it yourself

  • Provision native Agora recording instances
  • Merge per-user files into one deterministic layout
  • Scale recorders with channel concurrency
  • Retry uploads when a recorder or worker dies

With AVFlow

  • Pass your Agora App ID, channel, and RTC token
  • Compose once and upload once through segment storage
  • Use policies to control idle timeout
  • Submit the same Job shape used for LiveKit and Daily

The validated Job

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

15-agora-recording.json Download
{
  "name": "agora-recording",
  "sources": [
    {
      "name": "channel_src",
      "type": "agora",
      "config": {
        "appId": "<agora-app-id>",
        "channel": "live-show",
        "token": "<agora-rtc-token>",
        "uid": 1001,
        "select": {
          "mediaTypes": [
            "video",
            "audio"
          ]
        }
      }
    }
  ],
  "nodes": [
    {
      "name": "mix_video",
      "type": "video_mixer",
      "inputs": [
        "channel_src"
      ],
      "config": {
        "canvas": {
          "width": 1920,
          "height": 1080,
          "backgroundColor": "#1a1a2e"
        },
        "layout": {
          "mode": "grid",
          "common": {
            "borderRadius": 8
          },
          "grid": {
            "maxColumns": 3,
            "gap": 4,
            "fit": "cover"
          }
        }
      }
    },
    {
      "name": "mix_audio",
      "type": "audio_mixer",
      "inputs": [
        "channel_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": "daily/{jobName}/{date}/",
          "filename": "{jobName}_{timestamp}"
        },
        "encoding": {
          "videoCodec": "h264",
          "audioCodec": "aac"
        },
        "pathPrefix": "agora/{jobName}/{date}/",
        "filename": "{jobName}_{timestamp}"
      }
    }
  ]
}
Submit it API
curl -X POST "https://api.avflow.dev/v1/jobs" \
  -H "Authorization: Bearer $AVFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d @15-agora-recording.json

Know the limits before you ship

  • Secured Agora channels require an RTC token generated by your backend.
  • The example uses a fixed subscriber UID; adjust it if it collides with your channel.
  • AVFlow does not replace Agora billing for the original RTC session.

Run this Agora pipeline

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