MeetStream Guide: Per-Participant Video Streams

View as Markdown

This guide explains how to capture individual video recordings per participant in a meeting. Instead of a single composite screen recording, you receive a separate WebM video file for each participant’s webcam and any screen shares.

Supported platforms: Google Meet, Zoom, Microsoft Teams.


1) What you need

  1. A MeetStream API key (see the Quickstart Guide).
  2. A meeting link (Google Meet, Zoom, or Microsoft Teams).
  3. Set video_separate_streams: true in your Create Bot request.

2) Create a bot with per-participant video

Use the Create Agent endpoint: https://docs.meetstream.ai/api-reference/api-reference/bot-endpoints/create-agent

Minimal example

$curl -X POST "https://api.meetstream.ai/api/v1/bots/create_agent" \
> -H "Authorization: Token <YOUR_API_KEY>" \
> -H "Content-Type: application/json" \
> -d '{
> "meeting_link": "<YOUR_MEETING_LINK>",
> "bot_name": "RecorderBot",
> "video_separate_streams": true
> }'

Full example with recording config

1{
2 "meeting_link": "https://meet.google.com/abc-defg-hij",
3 "bot_name": "RecorderBot",
4 "video_required": true,
5 "video_separate_streams": true,
6 "recording_config": {
7 "transcript": {
8 "provider": {
9 "deepgram": {
10 "model": "nova-3",
11 "language": "en"
12 }
13 }
14 }
15 },
16 "automatic_leave": {
17 "everyone_left_timeout": 5
18 }
19}

Parameter reference

ParameterTypeDefaultDescription
video_separate_streamsbooleanfalseEnable per-participant video capture
video_requiredbooleanfalseEnable composite screen recording (single MP4). Can be used alongside video_separate_streams

Tip: You can also pass video_separate_streams nested inside recording_config:

1"recording_config": {
2 "video_separate_streams": true
3}

The top-level parameter takes precedence if both are set.


3) What happens during the meeting

Once the bot joins, it automatically:

  • Captures each participant’s webcam feed as a separate video stream.
  • Captures screen shares as separate streams.
  • Records up to 6 concurrent webcam streams. If more than 6 participants have cameras on, additional cameras are queued and start recording when a slot frees up.
  • Screen shares are always captured (1 concurrent on Teams/Zoom, multiple possible on Google Meet).

No additional configuration is needed per participant — the bot handles everything.


4) Retrieve per-participant video streams

After the bot leaves and video processing completes, call:

$curl -X GET "https://api.meetstream.ai/api/v1/bots/<BOT_ID>/get_recording_streams" \
> -H "Authorization: Token <YOUR_API_KEY>"

Response when processing is complete

1{
2 "bot_id": "f923cd21-da86-4d77-b37b-0707d37751c8",
3 "video_status": "Success",
4 "recording_streams_available": true,
5 "participants": [
6 {
7 "participant_name": "John Doe",
8 "streams": [
9 {
10 "stream_id": "user_456",
11 "segments": [
12 {
13 "segment_index": 0,
14 "url": "https://s3.amazonaws.com/...?X-Amz-Signature=...",
15 "filename": "John_Doe_456_0.webm",
16 "duration_seconds": 125.5,
17 "width": 640,
18 "height": 360,
19 "codec": "vp8"
20 }
21 ]
22 }
23 ]
24 },
25 {
26 "participant_name": "Jane Smith",
27 "streams": [
28 {
29 "stream_id": "user_789",
30 "segments": [
31 {
32 "segment_index": 0,
33 "url": "https://s3.amazonaws.com/...?X-Amz-Signature=...",
34 "filename": "Jane_Smith_789_0.webm",
35 "duration_seconds": 130.2,
36 "width": 854,
37 "height": 480,
38 "codec": "vp8"
39 }
40 ]
41 }
42 ]
43 }
44 ],
45 "screenshares": [
46 {
47 "participant_name": "John Doe",
48 "streams": [
49 {
50 "stream_id": "source_101",
51 "segments": [
52 {
53 "segment_index": 0,
54 "url": "https://s3.amazonaws.com/...?X-Amz-Signature=...",
55 "filename": "John_Doe_101_0.webm",
56 "duration_seconds": 60.0,
57 "width": 1280,
58 "height": 720,
59 "codec": "vp8"
60 }
61 ]
62 }
63 ]
64 }
65 ],
66 "summary": {
67 "total_participants": 2,
68 "total_screenshares": 1,
69 "total_segments": 3
70 }
71}

Response when processing is still in progress

1{
2 "video_status": "processing",
3 "stage": "Core Processing",
4 "message": "Video is being processed. Try again later."
5}

HTTP status 202 is returned when processing is not yet complete. The stage field indicates the current processing step. Poll again after 10-30 seconds.


5) Download the video files

Each segment in the response contains a url field — a presigned S3 URL that allows direct download without additional authentication.

$# Download a participant's video
>curl -o "John_Doe.webm" "<PRESIGNED_URL_FROM_RESPONSE>"

Important: Presigned URLs expire after 10 minutes. If a URL has expired, call get_recording_streams again to get fresh URLs.

File format

PropertyValue
ContainerWebM
Video codecVP8
Frame rate15 FPS
AudioNone (video-only files)

Audio is available separately via the standard Get Bot Audio endpoint.


6) Understanding segments

A participant may have multiple segments. A new segment is created when:

  • A screen share resolution changes (e.g., switching from fullscreen 1080p to a smaller window) on Teams or Zoom.
  • A participant shares their screen multiple times (each share session is a separate segment).
  • A webcam video dimension change occurs on Teams.

Camera off/on does not create a new segment — the bot maintains a continuous recording file per participant across camera toggles.

Segments are ordered by segment_index and are chronologically sequential. Use the duration_seconds field to determine segment timing.


7) Video resolution by platform

Webcam and screen share resolutions differ by platform:

PlatformWebcamWebcam BitrateScreen shareScreen share Bitrate
Google MeetUp to 854x480800 kbpsUp to 1280x7202 Mbps
Microsoft TeamsUp to 854x480800 kbpsUp to 1280x7202 Mbps
Zoom640x360 (fixed)300 kbpsNative resolution1.5 Mbps

8) Using both composite and per-participant video

You can enable both video_required and video_separate_streams simultaneously:

1{
2 "meeting_link": "<MEETING_LINK>",
3 "video_required": true,
4 "video_separate_streams": true
5}

This produces:

  • A composite MP4 (single screen recording of the meeting view) — retrieve via the Get Bot Video endpoint.
  • Per-participant WebM files — retrieve via the Get Recording Streams endpoint.

9) Webhook notifications

If you have webhooks configured, you will receive notifications when video processing starts and completes. Use the video_status field in webhook payloads or poll get_recording_streams until video_status is "Success".


10) Troubleshooting

  • recording_streams_available: false with video_status: "Success"?

    • The bot may have been in the meeting but no participant had their camera on. Per-participant streams are only produced for participants whose cameras were active.
  • Missing a participant’s video?

    • The bot captures up to 6 concurrent webcam streams. If more than 6 cameras were active, some participants may not have been captured.
    • Participants who never turned on their camera will not appear in the response.
  • Getting video_status: "processing"?

    • Video processing takes a short time after the bot exits. Poll again after 10-30 seconds.
  • Presigned URL returns 403 Forbidden?

    • The URL has expired (10-minute lifetime). Call get_recording_streams again for fresh URLs.
  • Video file has no audio?

    • Per-participant video files are video-only. Use the Get Bot Audio endpoint to retrieve the meeting audio separately.