Recording calls

Calls can be recorded for later use. Calls recording can be started/stopped via API calls or configured to start automatically when the first user joins the call. Call recording is done by Stream server-side and later stored on AWS S3. There is no charge for storage of recordings. You can also configure your Stream application to have files stored on your own S3 bucket.

By default, calls will be recorded as mp4 video files. You can configure recording to only capture the audio.

Note: by default, recordings contain all tracks mixed in a single file. You can follow the discussion here if you are interested in different ways to record calls.

Start and stop call recording

// starts recording
call.startRecording();

// stops the recording for the call
call.stopRecording();

List call recording

This endpoint returns the list of recordings for a call. When using Stream S3 as storage (default) all links are signed and expire after 2-weeks.

call.listRecordings();

Delete call recording

This endpoint allows to delete call recording. Please note that recordings will be deleted only if they are stored on Stream side (default).

An error will be returned if the recording doesn’t exist.

call.deleteRecording({ session: '<session id>', filename: '<filename>' });

Events

These events are sent to users connected to the call and your webhook/SQS:

  • call.recording_started when the call recording has started
  • call.recording_stopped when the call recording has stopped
  • call.recording_ready when the recording is available for download
  • call.recording_failed when recording fails for any reason

User Permissions

The following permissions are checked when users interact with the call recording API.

  • StartRecording required to start the recording
  • StopRecording required to stop the recording
  • ListRecordings required to retrieve the list of recordings
  • DeleteRecording required to delete an existing recording (including its files if stored using Stream S3 storage)

Enabling / Disabling call recording

Recording can be configured from the Dashboard (see call type screen) or directly via the API. It is also possible to change the recording settings for a call and override the default settings coming from the its call type.

// Disable on call level
call.update({
  settings_override: {
    recording: {
      mode: 'disabled',
    },
  },
});

// Disable on call type level
client.video.updateCallType({
  name: '<call type name>',
  settings: {
    recording: {
      mode: 'disabled',
    },
  },
});

// Enable
call.update({
  settings_override: {
    recording: {
      mode: 'available',
    },
  },
});

// Other settings
call.update({
  settings_override: {
    recording: {
      mode: 'available',
      audio_only: false,
      quality: '1080p',
    },
  },
});

Audio only recording

You can configure your calls to only record the audio tracks and exclude the video. You can do this from the dashboard (Call Types sections) or set it for individual calls.

// Enable
call.update({
  settings_override: {
    recording: {
      mode: 'available',
      audio_only: true,
    },
  },
});

Recording layouts

Recording can be customized in several ways:

  • You can pick one of the built-in layouts and pass some options to it
  • You can further customize the style of the call by providing your own CSS file
  • You can use your own recording application

There are three available layouts you can use for your calls: "single_participant", "grid" and "spotlight"

Single Participant

This layout shows only one participant video at a time, other video tracks are hidden.

Layout Single Participant

The visible video is selected based on this priority:

  • Participant is pinned
  • Participant is screen-sharing
  • Participant is the dominant speaker
  • Participant has a video track

Grid

This layout shows a configurable number of tracks in an equally sized grid.

Layout Grid

Spotlight

This layout shows a video in a spotlight and the rest of the participants in a separate list or grid.

Layout Spotlight

Layout options

Each layout has a number of options that you can configure. Here is an example:

Layout Custom Options

const layoutOptions = {
  'logo.image_url':
    'https://theme.zdassets.com/theme_assets/9442057/efc3820e436f9150bc8cf34267fff4df052a1f9c.png',
  'logo.horizontal_position': 'center',
  'title.text': 'Building Stream Video Q&A',
  'title.horizontal_position': 'center',
  'title.color': 'black',
  'participant_label.border_radius': '0px',
  'participant.border_radius': '0px',
  'layout.spotlight.participants_bar_position': 'top',
  'layout.background_color': '#f2f2f2',
  'participant.placeholder_background_color': '#1f1f1f',
  'layout.single-participant.padding_inline': '20%',
  'participant_label.background_color': 'transparent',
};

client.video.updateCallType({
  name: callTypeName,
  settings: {
    recording: {
      mode: 'available',
      audio_only: false,
      quality: '1080p',
      layout: {
        name: 'spotlight',
        options: layoutOptions,
      },
    },
  },
});

Here you can find the complete list of options available to each layout.

Single Participant

OptionTypeDefaultAllowed ValuesDescription
video.background_colorcolor#000000The background color
video.screenshare_scale_modestringfit[fit fill]How source video is displayed inside a box when aspect ratio does not match. ‘fill’ crops the video to fill the entire box, ‘fit’ ensures the video fits inside the box by padding necessary padding
participant.label_horizontal_positionstringleft[center left right]horizontal position for the participant label
participant.video_border_radiusnumber1.2The corner radius used for the participant video border
logo.horizontal_positionstringcenter[center left right]horizontal position of the logo
participant.label_displaybooleantrueShow the participant label
participant.label_text_colorcolor#000000Text color of the participant label
participant.label_background_colorcolor#00000000Background color of the participant label
participant.label_border_radiusnumber1.2The corner radius used for the label border
logo.vertical_positionstringtop[top bottom center]vertical position of the logo
participant.label_display_borderbooleantrueRender label border
participant.label_vertical_positionstringbottom[top bottom center]vertical position for the participant label
participant.video_highlight_border_colorcolor#7CFC00The color used for highlighted participants video border
participant.video_border_roundedbooleantrueRender the participant video border rounded
participant.video_border_widthbooleantrueThe stroke width used to render a participant border
participant.placeholder_background_colorcolor#000000Sets the background color for video placeholder tile
video.scale_modestringfill[fit fill]How source video is displayed inside a box when aspect ratio does not match. ‘fill’ crops the video to fill the entire box, ‘fit’ ensures the video fits inside the box by padding necessary padding
logo.image_urlstringadd a logo image to the video layout
participant.label_border_colorcolor#CCCCCCLabel border color
participant.label_border_roundedbooleantrueRender the label border rounded
participant.video_border_colorcolor#CCCCCCThe color used for the participant video border
participant.aspect_ratiostring"9/16", "4/3", "1/1", ...The aspect ratio of the participant

Spotlight

OptionTypeDefaultAllowed ValuesDescription
participant.video_border_widthbooleantrueThe stroke width used to render a participant border
grid.positionstringbottom[top bottom left right]position of the grid in relation to the spotlight
participant.label_display_borderbooleantrueRender label border
participant.label_horizontal_positionstringleft[center left right]horizontal position for the participant label
participant.video_border_colorcolor#CCCCCCThe color used for the participant video border
grid.columnsnumber5how many column to use in grid mode
video.background_colorcolor#000000The background color
logo.horizontal_positionstringcenter[center left right]horizontal position of the logo
participant.label_border_colorcolor#CCCCCCLabel border color
participant.label_background_colorcolor#00000000Background color of the participant label
grid.cell_paddingsize10padding between cells
screenshare_layoutstringspotlight[grid spotlight single-participant]The layout to use when entering screenshare mode
grid.size_percentagenumber20The percentage of the screen the grid should take up
participant.label_border_radiusnumber1.2The corner radius used for the label border
participant.video_highlight_border_colorcolor#7CFC00The color used for highlighted participants video border
participant.placeholder_background_colorcolor#000000Sets the background color for video placeholder tile
participant.video_border_radiusnumber1.2The corner radius used for the participant video border
participant.label_displaybooleantrueShow the participant label
participant.label_border_roundedbooleantrueRender the label border rounded
participant.video_border_roundedbooleantrueRender the participant video border rounded
grid.rowsnumber1how many rows to use in grid mode
grid.marginsize10the margin between grid and spotlight
video.scale_modestringfill[fit fill]How source video is displayed inside a box when aspect ratio does not match. ‘fill’ crops the video to fill the entire box, ‘fit’ ensures the video fits inside the box by padding necessary padding
logo.image_urlstringadd a logo image to the video layout
logo.vertical_positionstringtop[top bottom center]vertical position of the logo
video.screenshare_scale_modestringfit[fit fill]How source video is displayed inside a box when aspect ratio does not match. ‘fill’ crops the video to fill the entire box, ‘fit’ ensures the video fits inside the box by padding necessary padding
participant.label_text_colorcolor#000000Text color of the participant label
participant.label_vertical_positionstringbottom[top bottom center]vertical position for the participant label
participant.aspect_ratiostring"9/16", "4/3", "1/1", ...The aspect ratio of the participant

Grid

OptionTypeDefaultAllowed ValuesDescription
logo.image_urlstringadd a logo image to the video layout
logo.vertical_positionstringtop[top bottom center]vertical position of the logo
participant.label_horizontal_positionstringleft[center left right]horizontal position for the participant label
participant.placeholder_background_colorcolor#000000Sets the background color for video placeholder tile
video.scale_modestringfill[fit fill]How source video is displayed inside a box when the aspect ratio does not match. ‘fill’ crops the video to fill the entire box, ‘fit’ ensures the video fits inside the box by padding necessary padding
logo.horizontal_positionstringcenter[center left right]horizontal position of the logo
participant.video_border_roundedbooleantrueRender the participant video border rounded
participant.label_display_borderbooleantrueRender label border
participant.label_border_colorcolor#CCCCCCLabel border color
grid.cell_paddingsize10padding between cells
video.screenshare_scale_modestringfit[fit fill]How source video is displayed inside a box when the aspect ratio does not match. ‘fill’ crops the video to fill the entire box, ‘fit’ ensures the video fits inside the box by padding necessary padding
video.background_colorcolor#000000The background color
participant.label_border_radiusnumber1.2The corner radius used for the label border
grid.size_percentagenumber90The percentage of the screen the grid should take up
grid.marginsize10the margin between grid and spotlight
grid.columnsnumber5how many column to use in grid mode
participant.label_vertical_positionstringbottom[top bottom center]vertical position for the participant label
participant.label_displaybooleantrueShow the participant label
participant.video_border_colorcolor#CCCCCCThe color used for the participant video border
participant.video_border_widthbooleantrueThe stroke width used to render a participant border
screenshare_layoutstringspotlight[grid spotlight single-participant]The layout to use when entering screen share mode
participant.label_text_colorcolor#000000Text color of the participant label
participant.label_background_colorcolor#00000000Background color of the participant label
participant.label_border_roundedbooleantrueRender the label border rounded
participant.video_border_radiusnumber1.2The corner radius used for the participant video border
participant.video_highlight_border_colorcolor#7CFC00The color used for highlighted participants video border
grid.rowsnumber4how many rows to use in grid mode
participant.aspect_ratiostring"9/16", "4/3", "1/1", ...The aspect ratio of the participant

Recording resolution and portrait mode

Calls can be recorded in different resolutions and modes (landscape and portrait). On the dashboard, you can configure the default settings for all calls of a specific call type.

Recording Resolution And Orientation

While this can be configured from the dashboard, you can also set it for individual calls:

client.video.updateCallType({
  name: callTypeName,
  settings: {
    recording: {
      mode: 'available',
      quality: 'portrait-1080x1920',
    },
  },
});

Custom recording styling using external CSS

You can customize how recorded calls look by providing an external CSS file. The CSS file needs to be publicly available and ideally hosted on a CDN to ensure the best performance. The best way to find the right CSS setup is by running the layout app directly. The application is publicly available on Github here and contains instructions on how to be used.

client.video.updateCallType({
  name: callTypeName,
  settings: {
    recording: {
      mode: 'available',
      audio_only: false,
      quality: '1080p',
      layout: {
        name: 'spotlight',
        external_css_url: 'https://path/to/custom.css',
      },
    },
  },
});

Advanced - record calls using a custom web application

If needed, you can use your own custom application to record a call. This is the most flexible and complex approach to record calls, make sure to reach out to our customer support before going with this approach.

The layout app used to record calls is available on GitHub and is a good starting point. The repository also includes information on how to build your own.

client.video.updateCallType({
  name: callTypeName,
  settings: {
    recording: {
      mode: 'available',
      audio_only: false,
      quality: '1080p',
      layout: {
        name: 'custom',
        external_app_url: 'https://path/to/layout/app',
      },
    },
  },
});

Client-side recording

Unfortunately, there is no direct support for client-side recording at the moment. Call recording at the moment is done by Stream server-side. If client-side recording is important for you please make sure to follow the conversation here.

© Getstream.io, Inc. All Rights Reserved.