Compositions

Overview

The Twilio Recording Composition API lets you transcode and combine the individual Track Recordings stored by the Twilio Video Recordings API. This API relies on the following REST resources:

  • The Composition Instance Resource: a Composition represents a media file created as a result of applying a set of media processing operations onto a number of source Recordings.
  • The Compositions List Resource represents the list of previously created Compositions.

These REST resources are located beneath of the following base URL:

https://video.twilio.com

Contents

URI Schemes

The following table summarizes the URI schemes for the Recording Composition REST API and the supported methods:

URI Scheme Supported Methods Usage
/v1/Compositions/ GET, POST
  • List Composition resources
  • Create new Composition resources
/v1/Compositions/{CompositionSid} GET, DELETE
  • Retrieve a Composition resource
  • Delete a Composition resource
/v1/Compositions/{CompositionSid}/Media GET
  • Retrieve a Composition sub-resource media file

Composition Instance Resource

Resource URI

/v1/Compositions/{CompositionSid}

Resource Properties

A Composition Instance Resource has the following properties

Name Description
account_sid

The unique ID of the Twilio Account owning this Composition. (🏢 not PII)

audio_sources

The array of audio sources as specified in the POST request that created this Composition. See the POST Parameters section for further information. (📇 PII MTL: 30 days)

audio_sources_excluded

The array of excluded audio sources, as specified in the POST request that created this Composition. See the POST Parameters section for further information. (📇 PII MTL: 30 days)

date_completed

Date conforming to UTC ISO 8601 Timestamp. Matches the time the Composition media processing task finished. (🏢 not PII)

date_created

Date conforming to UTC ISO 8601 Timestamp. Matches the time the Composition Resource was created. (🏢 not PII)

date_deleted

Date conforming to UTC ISO 8601 Timestamp. Matches the time the Composition generated media was deleted. (🏢 not PII)

duration

Duration of the Composed media file expressed in seconds. (🏢 not PII)

format

Container format of the Composition media file as specified in the POST request that created this Composition. See the POST Parameters section for further information. (🏢 not PII)

links

A JSON object that contains the URL where the media file associated to this Composition can be fetched. This object has the following structure: {'links':{'media': 'https://video.twilio.com/v1/Compositions/CJXX...XX/Media'}} (🏢 not PII)

resolution

Pixel resolution of the composed video as specified in the HTTP POST request that created this Composition. See the POST Parameters section for further information. (🏢 not PII)

room_sid

The unique ID of the Group Room where the audio and video tracks used in this composition were generated. Recall that all media sources included in a Composition must belong to the same Group Room. (🏢 not PII)

sid

CJxx…xx A system-generated 34-character string that uniquely identifies this Composition. (🏢 not PII)

size

Size of the Composed media file expressed in bytes. (🏢 not PII)

status

The status of the Composition. Possible values are processing, completed, deleted or failed. processing indicates the Composition is still being processed; completed indicates the Composition has been completed and is now available for download. deleted means the Composition media has been deleted from the system, but its metadata is still available for historical purposes during 30 days; failed indicates the Composition failed to exeute the media processing task. (🏢 not PII)

trim

Boolean flag indicating whether intervals with no media are clipped, as specified in the POST request that created this Composition. See the POST Parameters section for further information. (🏢 not PII)

url

The absolute URL for this resource. (🏢 not PII)

video_layout

The JSON video layout description of the composed video as specified in the HTTP POST request that created this Composition. See the POST Parameters section for further information. (📇 PII MTL: 30 days)

HTTP GET

Returns the single Composition identified by {CompositionSid}.

HTTP POST

Not supported.

HTTP DELETE

Deletes the media file associated with the Composition identified by {CompositionSID} and sets the Composition status as deleted. In case the media file was stored in an external S3 bucket this request has no effect on such file. Once a Composition has been deleted, its metadata (i.e. it REST resource record) is kept during 30 days.

Composition Instance Media Sub-Resource

Resource URI

/v1/Compositions/{CompositionSid}/Media

HTTP GET

Retrieves the Composition media file through an HTTP redirection. The format of the provided media file is the one specified in the Format property of the Composition (see table above). By default, the redirection URL is available for 3600 seconds, but a different TTL can be specified via the Ttl request param. If the composition is not yet available, a 404 is returned.

The HTTP GET request accepts the following parameters

Name Description
Ttl

Optional. Duration in seconds for which the redirect_to URL can be used to retrieve the media file. The maximum expiration time is 7 days (604800) (🏢 not PII)

HTTP DELETE

Not supported.

HTTP POST

Not supported.

Compositions List Resource

Resource URI

/v1/Compositions/

HTTP POST

Creates a new Composition Instance Resource and, when appropriate, launches a media processing task. The result of this task is a composed media file that, by default, is stored in Twilio’s cloud.

Developers can create a new Composition as soon as its associated Group Room exists. However, the processing task gets started only when the Room status is Completed. This guarantees that all required recording sources are available.

This HTTP POST always returns a 201 if the request is accepted (i.e. well formed), and a 4xx otherwise depending on the type of error.

Supported POST Parameters

The following table shows all the parameters that can be used when creating a new Composition Instance Resource. Parameters having “Yes” in the column “Default value/mandatory” are mandatory.

Name Description
AudioSources

Optional. An array of audio sources to merge. All the specified sources must belong to the same Group Room. It can include:

  • Zero or more RecordingTrackSid
  • Zero or more MediaTrackSid
  • Zero or more ParticipantSid
  • Zero or more Track names. These can be specified using wildcards (e.g. student*)
(📇 PII MTL: 30 days)

AudioSourcesExcluded

Optional. An array of audio sources to exclude from the Composition. Any new Composition shall include all audio sources specified in AudioSources except for the ones specified in AudioSourcesExcluded. This parameter may include:

  • Zero or more RecordingTrackSid
  • Zero or more MediaTrackSid
  • Zero or more ParticipantSid
  • Zero or more Track names. These can be specified using wildcards (e.g. student*)
(📇 PII MTL: 30 days)

Format

Optional. Container format of the Composition media file. Can be any of the following: mp4, webm. The use of mp4 or webm makes mandatory the specification of AudioSources and/or one VideoLayout element containing a valid video_sources list, otherwise an error is fired. Defaults to webm. (🏢 not PII)

Resolution

Optional. A string representing the numbers of pixels for rows (width) and columns (height) of the generated composed video. This string must have the format {width}x{height}. This parameter must comply with the following constraints:

  • width >= 16 && width <= 1280
  • height >= 16 && height <= 1280
  • width * height <= 921,600
Typical values are:
  • HD = 1280x720
  • PAL = 1024x576
  • VGA = 640x480
  • CIF = 320x240
Note that the Resolution implicitly imposes an aspect ratio to the resulting composition. When the original video tracks get constrained by this aspect ratio they are scaled-down to fit. You can find detailed information in the Managing Video Layouts section. Defaults to 640x480. (🏢 not PII)

RoomSid

Optional. Group Room SID owning the media tracks to be used as Composition sources. (🏢 not PII)

StatusCallback

Optional. A URL that Twilio sends asynchronous webhook requests to on every composition event. If not provided, status callback events will not be dispatched. (🏢 not PII)

StatusCallbackMethod

Optional. HTTP method Twilio should use when requesting the above URL. Defaults to POST. (🏢 not PII)

Trim

Optional. When activated, clips all the Composition intervals where there is no active media. This results in shorter compositions in cases when the Room was created but no Participant joined for some time, or if all the Participants left the room and joined at a later stage, as those gaps will be removed. You can find further information in the Managing Video Layouts section. Defaults to true. (🏢 not PII)

VideoLayout

Optional. A JSON object defining the video layout of the Composition in terms of regions. See the section Managing Video Layouts below for further information. (📇 PII MTL: 30 days)

Specifying Video Layouts

Video layouts are organized in terms of regions. A region is a rectangular area where a set of video sources are displayed following the region placement rules. The VideoLayout of a Composition must contain at least one region but it may contain many. Regions are independent meaning that the way placement works in a region does not affect placement in other regions.

A Composition's VideoLayout is specified as a JSON dictionary of regions following this scheme:

VideoLayout = {
                "a-region-name": {
                    region properties
                },

                "other-region-name": {
                  other region properties
                }

                ...
              }

The region properties define the size and position of the region, the video sources to include in the region and the placement rules. Regions support the following properties (recall that a “Yes” in the column “Default value/mandatory” indicates a mandatory property)

Parameter Default value / mandatory Description
x_pos 0 X axis value (in pixels) of the region's upper left corner relative to the upper left corner of the Composition viewport. Regions cannot overflow the Composition's area, so x_pos has to be a positive integer less than or equal to the difference between the Composition's width and the width of the region. If the region’s width is missing from the request, it defaults to 16 pixels for this validation.
y_pos 0 Y axis value (in pixels) of the region's upper left corner relative to the upper left corner of the Composition viewport. Regions cannot overflow the composition's area, so y_pos has to be a positive integer less than or equal to the difference between the Composition's height and the height of this region. If the region’s height is missing from the request, it defaults to 16 pixels for this validation.
z_pos 0 Z position controlling the region's visibility in case of overlaps. Regions with higher values are stacked on top of regions with lower value for visibility purposes. z_pos must be in the range [-99, 99].
width Composition's width - x_pos Region's Width. It must be in the range [16, Composition's width - x_pos]. This constraint guarantees that the region fits into the Composition's viewport.
height Composition's height - y_pos Region's Height. It must be in the range [16, Composition's height - y_pos]. This constraint guarantees that the region fits into the Composition's viewport.
max_columns -- Maximum number of columns of the region's placement grid. By default, the region has as many columns as needed to layout all the specified video sources. max_columns must be in the range [1, 1000].
max_rows -- Maximum number of rows of the region's placement grid. By default, the region has as many rows as needed to layout all the specified video sources. max_rows must be in the range [1, 1000].
cells_excluded -- A list of cell indices on the regions layout grid where no video sources can be assigned. Index of first cell (upper left) is 0. Indices grow from left to right and from top to bottom. These values must be in the range [0, 999999].
reuse show_oldest Defines how the region's grid cells are reused for placement purposes. Possible values are:
  • none: used cells are never reused.
  • show_oldest: a cell can only be reused when the video source it contains ends.
  • show_newest: a cell can be reused even if the video source it contains has not ended.
video_sources Yes The array of video sources that should be placed in this region. All the specified sources must belong to the same Room. It can include:
  • Zero or more RecordingTrackSid
  • Zero or more MediaTrackSid
  • Zero or more ParticipantSid
  • Zero or more Track names. These can be specified using wildcards (e.g. student*)
video_sources_excluded -- An array of video sources to exclude from this region. This region will attempt to display all sources specified in video_sources except for the ones specified in video_sources_excluded. This parameter may include:
  • Zero or more RecordingTrackSid
  • Zero or more MediaTrackSid
  • Zero or more ParticipantSid
  • Zero or more Track names. These can be specified using wildcards (e.g. student*).

The use of a VideoLayout not compliant with this specification shall cause the corresponding POST request to be answered with a 4xx code.

Region Positioning and Size

The following figure illustrates how regions are positioned:

Region Positioning and Size

You may find useful to remember these rules:

  • The Composition's width and height are defined through the Resolution parameter.
  • Regions are positioned relative to the Composition top-left corner using x_pos and y_pos.
  • Region dimensions are defined through the width and height properties.
  • Regions must fit inside their Composition. This makes the following mandatory:
  • x_pos + width must not be over the Composition's width.
  • y_pos + height must not be over the Composition's height.
  • In case width or heightare not specified, by default the region shall occupy all the available remaining space on the Composition's viewport.
  • When multiple regions overlap, their visibility depend on the z_pos property. Regions with higher z_pos will be visible on top of regions with lower z_pos.
The Region as a Grid

The placement of video_sources in a region takes place through a grid (i.e. matrix) where every cell is a container where one (and only one) video source may be displayed at a time. Region grids are static meaning that their number of rows and columns do not change during the Composition duration. The specific number of rows and columns depends on the region's max_columns and max_rows properties. There are three different situations:

The Region as a Grid

Unconstrained Grid

In this case, neither max_columns nor max_rows are specified in the VideoLayout. Twilio computes for you the grid dimensions to guarantee that all the provided video_sources are displayed. Due to this, the cells in the grid will be at least equal to the maximum number of simultaneous video sources in the Composition (video sources are considered to be simultaneous at a given time when their media is active at that time). For this, we try to keep the grid as square as possible making it to grow first in columns and then in rows so that their difference is never over 1. The following table illustrates this:

Maximum simultaneous video sources Region's grid dimensions (rows x columns)
1 1x1
2 1x2
3 2x2
4 2x2
5 2x3
6 2x3
7 3x3
9 3x3
10 3x4
12 3x4
17 4x5
20 4x5

Unconstrained Dimension

In this case, only one of max_columns or max_rows is specified. The grid dimensions are computed following the "Unconstrained Grid" algorithm (i.e. trying to keep the grid as square as possible) but without exceeding the specified maximum constraint. After that, the unconstrained dimension grows in order to guarantee that all the specified video sources are displayed. The following examples illustrate this:

Maximum simultaneous video sources max_rows max_columns Region's grid dimensions (rows x columns)
1 1 -- 1x1
1 -- 1 1x1
2 1 -- 1x2
2 -- 1 2x1
3 1 -- 1x3
3 -- 1 3x1
4 2 -- 2x2
4 -- 2 2x2
5 2 -- 2x3
5 -- 2 3x2
6 2 -- 2x3
6 -- 2 3x2
7 2 -- 2x4
7 -- 2 4x2
9 2 -- 2x5
9 -- 2 5x2
12 2 -- 2x6
12 -- 2 6x2

Constrained Grid In this case, both max_columns and max_rows are specified. The grid dimensions are computed following the above specified algorithms but keeping both dimensions under their limits. Due to this, the maximum number of cells is max_columns * max_rows. If the number of simultaneous video sources exceeds that value, then some video sources shall not be displayed. The following example illustrates the effect.

Maximum simultaneous video sources max_rows max_columns Region's grid dimensions (rows x columns)
1 1 1 1x1
1 1 2 1x1
1 2 2 1x1
2 1 1 1x1 (1 source not displayed)
2 1 2 1x2
2 2 2 1x2
3 1 1 1x1 (2 sources not displayed)
3 1 2 1x2 (1 source not displayed)
3 2 2 2x2
4 1 1 1x1 (3 sources not displayed)
4 1 2 1x2 (2 sources not displayed)
4 2 2 2x2
5 1 1 1x1 (4 sources not displayed)
5 1 2 1x2 (2 sources not displayed)
5 2 2 2x2 (1 source not displayed)
9 1 7 1x7 (2 sources not displayed)
9 2 7 2x5
9 3 7 3x3
Displaying Video Sources

Video sources are displayed in region grid cells. Cells size and aspect ratio is controlled by:

  • The region pixel dimensions, as defined by the width and height parameters.
  • The region grid dimensions (i.e. number of rows and columns), as introduced in the section above.

Hence, cells would have approximately (rounding effects not considered):

  • Width equal to the region's width divided by the number of columns.
  • Heigh equal to the region's height divided by the number of rows.

The display of the original video track sources in cells is performed using "object-fit contain" CSS semantics. This means that the original video is rescaled as necessary to fit into the target aspect ratio and that the remaining areas of the cell are filled in black. The following images illustrate how this happens

Displaying Video Sources in Cells

Understanding Reuse

Video sources are assigned to cells from left-to-right and from top-to-bottom in the region grid. However, this assignment depends on the value of the reuse property. For understanding how reuse works, we need some definitions:

  • We say a cell is fresh at a given time when it has not displayed any video source up to that time.
  • We say a cell is used at a given time when it is displaying a video source at that time.
  • We say a cell is idle at a given time when it has been used previously but its video source media has ended at that time.

Based on this, the possible values for reuse are the following:

  • none: in this case, used cells are never reused again and stay idle until the composition ends. Newer video sources are assigned only to fresh cells following the left-to-right top-to-bottom order. In constrained grids, we may run out of fresh cells. In that case, no further video sources are displayed.
  • show_oldest: in this case idle cells can be reused. Hence, newer video sources are assigned to both idle or fresh cells in left-to-right top-to-bottom order. In constrained grids, when running out of fresh cells, newer video sources will be displayed only as idle cells become available. In such constrained situation, this model gives display priority to older video sources (i.e. to the video sources starting first), which justifies its show_oldest name.
  • show_newest: when this value is specified, video sources are displayed first in idle and fresh cells in the left-to-right top-to-bottom order. In constrained grids it may happen that we run out of both fresh and idle cells. In that case, used cells are reused so that newer video sources are displayed on top of older video sources. When there are several available used cells, the one whose media ends first is selected. As it can be understood, this model gives display priority to newer video sources (i.e. to video sources starting later), which justifies its show_newest name.

The difference between the different reuse modes can be visually appreciated in the following figure:

Graphical examples using Reuse

As it can be observed, in this figure we assume a Room with 5 video tracks. These are numbered from 0 to 4. The Room timeline shows the time intervals (relative to the Room starting time) when such tracks are in published state. Below it, we show a number of compositions subject to the following constraints:

  • 1x1 Region Composition: in this case, the Composition has a single region where max_rows=1 and max_columns=1. When reuse=none the first track (i.e. the one identified as 0) takes the single fresh cell of the region for display. When this track is unpublished, the cell is never reused and the Composition stays black (in case Trim=false) or terminates (in case Trim=true). If reuse=show_newest newer tracks have higher priority than older tracks. Due to this, track 1 is stacked on top of track 0 and displayed while it is active. Later, tracks 2, 3 and 4 take the single region cell as soon as their media is activated. In the case where reuse=show_oldest, the first track occupying the single region cell keeps it until it ends. After that, newer tracks can take it (observe how the end of track 2 allows track 3 to be displayed and how the end of track 3 does the same with track 4.)

  • 1x2 Region Composition: now the Composition has a single region with two cells (max_rows=1 and max_columns=2). Due to this, tracks 0 and 1 can be displayed simultaneously. For tracks 2, 3 and 4 their display is controlled by the reuse model. When reuse=none, tracks 0 and 1 take the two fresh cells. After that, no further tracks can reuse such cells and the Composition stays black (in case Trim=false) or terminates (in case Trim=true). If reuse=show_newest 2 and 3 can reuse the idle cells, but when 4 arrives it reuses the used cell with track ending first (in this case 2). When reuse=show_oldest 2 and 3 have priority and hence 4 needs to wait until an idle cell is made available, which takes place when 2 ends.

  • Unconstrained Region Composition: in this case, the Composition has a single cell where neither max_rows nor max_columns have been specified. Hence, the region grid dimensions are automatically calculated to fit all the specified video sources. When reuse=none, we need 5 cells given that video sources can only occupy fresh cells. Due to this, the system uses a 2x3 grid. When reuse=show_newest or reuse=show_oldest the required grid needs to have only 3 cells given that the maximum number of simultaneous tracks is 3 (i.e. what happens during the interval in which 2, 3 and 4 are published). Hence, the system computes a 2x2 grid. Observe that when using unconstrained grids, both show_newest and show_oldest generate the same video placement for the region. This is due to the fact that in an unconstrained grid it is guaranteed that the number of video sources never exceeds the number of cells in the grid. Hence, no used cells need ever to be reused.

Understanding Trim

The Trim Composition parameter controls what happens to the composition when there is no active media. That is, during the intervals in which neither audio tracks no video tracks are published.

  • trim=false: the Composition complies exactly with the timing of the original Room keeping the time intervals where there is no media as black silent frames. These idle intervals may appear at the beginning, at the end or in the middle of the Composition.
  • trim=true (default): the Composition clips any time interval where there is no media published. Note that when an audio track is active in the composition during an interval it shall not be clipped even if there are no active video tracks on it.

The following figure illustrates how trimmed Compositions behave in the scenarios introduced in the section above.

Composing different layouts in a room (trim=true)

HTTP GET

Retrieves the list Composition Instance Records belonging to the specified AccountSid with paging data.

Supported GET Parameters

The following GET query string parameters allow you to limit the list returned. Note, parameters are case-sensitive.

Parameter Description
Status Only show Compositions with the given status.
RoomSid Only show Compositions from a certain room, identified by its SID.
DateCreatedAfter Only show Recordings that started on or after this ISO8601 date-time, given as YYYY-MM-DDThh:mm:ss-hh:mm.
DateCreatedBefore Only show Recordings that started before this this ISO8601 date-time, given as YYYY-MM-DDThh:mm:ss-hh:mm.

Note: deleted Compositions are not returned by default. For retrieving the deleted Compositions list you must explicitly specify Status=deleted.

Examples

Creating Transcoding Compositions

Example: Transcode a Video Recording

In this example we assume a Room with RoomSid=RMXXXX where a video Track with MediaTrackSid=MTXXXX is published and recorded with RecordingTrackSid=RTXXXX. We want then to generate a Composition containing such video Track but transcoded to the H.264/mp4 format. Considering that:

  • Your application credentials are (SKXXXX:your_api_key_secret)
  • You want to use the default resolution (VGA = 640x480)

You can create the desired Composition using the following:

Loading Code Samples...
Language
Response Format:
  • json
SDK Version:
  • 7.x
SDK Version:
  • 3.x
SDK Version:
  • 5.x
SDK Version:
  • 6.x
SDK Version:
  • 5.x
Format:
  • JSON
// NOTE: This example uses the next generation Twilio helper library - for more
// information on how to download and install this version, visit
// https://www.twilio.com/docs/libraries/node

// Find your credentials at twilio.com/console
const API_KEY_SID = 'SKXXXX';
const API_KEY_SECRET = 'your_api_key_secret';
const ACCOUNT_SID = 'ACXXXX';

const Twilio = require('twilio');

const client = new Twilio(API_KEY_SID, API_KEY_SECRET, {accountSid: ACCOUNT_SID});

client.video.compositions.
  create({
    roomSid: 'RMXXXX',
    videoLayout: {
      transcode: {
        video_sources: ['RTXXXX']
      }
    },
    statusCallback: 'http://my.server.org/callbacks',
    format: 'mp4'
  })
  .then(composition =>{
    console.log("Created Composition with SID=" + composition.sid);
  })
<?php
// Get the PHP helper library from https://twilio.com/docs/libraries/php
require_once '/path/to/vendor/autoload.php'; // Loads the library
use Twilio\Rest\Client;

// Find your credentials at twilio.com/console
$apiKeySid = "SKXXXX";
$apiKeySecret = "your_auth_apiKeySecret";
$client = new Client($apiKeySid, $apiKeySecret);

$composition = $client->video->compositions->create([
    'roomSid' => 'RMXXXX',
    'videoLayout' =>  array(
                        'transcode' => array (
                          'video_sources' => array('RTXXXX')
                        )
                      ),
    'statusCallback' => 'http://my.server.org/callbacks',
    'format' => 'mp4'
]);

echo $composition->sid;
# Download the helper library from https://www.twilio.com/docs/ruby/install
require 'rubygems'
require 'twilio-ruby'

# Find your credentials at twilio.com/console
api_key_sid = 'SKXXXX'
api_key_secret = 'your_api_key_secret'

@client = Twilio::REST::Client.new(api_key_sid, api_key_secret)

composition = @client.video.compositions.create(
  room_sid: 'RMXXXX',
  video_layout: {
    transcode: {
      video_sources: ['RTXXXX']
    }
  },
  status_callback: 'http://my.server.org/callbacks',
  format: 'mp4'
)

puts composition.sid
#Download the Python helper library from twilio.com/docs/python/install
from twilio.rest import Client
import json

# Find your credentials at twilio.com/console
api_key_sid = = 'SKXXXX'
api_key_secret = 'your_api_key_secret'
client = Client(api_key_sid, api_key_secret)

composition = client.video.compositions.create(
    room_sid = 'RMXXXX',
    video_layout = {
                        'transcode': {
                            'video_sources': ['RTXXXX']
                        }
                   },
    status_callback = 'http://my.server.org/callbacks',
    format='mp4')

print('Created composition with SID=%s' % (composition.sid))
// Install the Java helper library from twilio.com/docs/java/install
import com.twilio.Twilio;
import com.twilio.rest.video.v1.Composition;
import com.twilio.rest.video.v1.Composition.Format;

import com.fasterxml.jackson.databind.ObjectMapper;

public class TranscodeVideoRecording{

  // Find your credentials at twilio.com/console
  public static final String ACCOUNT_SID = "ACXXXX";
  public static final String API_KEY_SID = "SKXXXX";
  public static final String API_KEY_SECRET = "your_api_key_secret";

  public static void main( String[] args ) throws IOException{
      // Initialize the client
      Twilio.init(API_KEY_SID, API_KEY_SECRET, ACCOUNT_SID);

      final String videoLayout =
        								  "{"
        								+ "   \"transcode\": {"
        								+ "       \"video_sources\":[\"RTXXXX\"]"
        								+ "    }"
        								+ "}";

      Composition composition = Composition.creator()
        					.setRoomSid("RMXXXX")
        					.setVideoLayout(new ObjectMapper().readValue(videoLayout, HashMap.class))
        					.setStatusCallback("http://my.server.org/callbacks")
        					.setFormat(Format.MP4)
        					.create();

      System.out.println("Created composition with SID=" + composition.getSid());
  }
}
curl -X POST 'https://video.twilio.com/v1/Compositions' \
    -u 'SKXXXX:your_api_key_secret' \
    -F 'RoomSid=RMXXXX' \
    -F 'StatusCallback=http://my.server.org/callbacks' \
    -F 'Format=mp4' \
<<-EOF -F 'VideoLayout={
      "transcode":{
        "video_sources":["RTXXXX"]
      }
    }'
EOF
{
    "account_sid": "ACXXXX",
    "audio_sources": [],
    "audio_sources_excluded": [],
    "bitrate": 0,
    "date_completed": null,
    "date_created": "2018-03-26T13:01:04Z",
    "date_deleted": null,
    "duration": 0,
    "format": "mp4",
    "links": {
        "media": "https://video.twilio.com/v1/Compositions/CJXXXX/Media"
    },
    "resolution": "640x480",
    "room_sid": "RMXXXX",
    "sid": "CJXXXX",
    "size": 0,
    "status": "processing",
    "trim": true,
    "url": "https://video.twilio.com/v1/Compositions/CJXXXX",
    "video_layout": {
        "transcode": {
            "cells_excluded": [],
            "height": null,
            "max_columns": null,
            "max_rows": null,
            "reuse": "show_oldest",
            "video_sources": [
                "RTXXXX"
            ],
            "video_sources_excluded": [],
            "width": null,
            "x_pos": 0,
            "y_pos": 0,
            "z_pos": 0
        }
    }
}
Transcode a Video Recording

Example: Transcode an Audio Recording

In this example we assume a Room with RoomSid=RMXXXX where an audio Track with MediaTrackSid=MTXXXX is publishes and recorded with RecordingTrackSid=RTXXXX. We want then to generate a Composition containing such audio Track but transcoded to the AAC/mp4 format. Considering that:

  • Your application credentials are (SKXXXX:your_api_key_secret)

You can create the desired Composition using the following:

Loading Code Samples...
Language
Response Format:
  • json
SDK Version:
  • 7.x
SDK Version:
  • 3.x
SDK Version:
  • 5.x
SDK Version:
  • 6.x
SDK Version:
  • 5.x
Format:
  • JSON
// NOTE: This example uses the next generation Twilio helper library - for more
// information on how to download and install this version, visit
// https://www.twilio.com/docs/libraries/node

// Find your credentials at twilio.com/console
const API_KEY_SID = 'SKXXXX';
const API_KEY_SECRET = 'your_api_key_secret';
const ACCOUNT_SID = 'ACXXXX';

const Twilio = require('twilio');

const client = new Twilio(API_KEY_SID, API_KEY_SECRET, {accountSid: ACCOUNT_SID});

client.video.compositions.
  create({
    roomSid: 'RMXXXX',
    audioSources: 'RTXXXX',
    statusCallback: 'http://my.server.org/callbacks',
    format: 'mp4'
  })
  .then(composition =>{
    console.log('Created Composition with SID=' + composition.sid);
  });
<?php
// Get the PHP helper library from https://twilio.com/docs/libraries/php
require_once '/path/to/vendor/autoload.php'; // Loads the library
use Twilio\Rest\Client;

// Find your credentials at twilio.com/console
$apiKeySid = "SKXXXX";
$apiKeySecret = "your_auth_apiKeySecret";
$client = new Client($apiKeySid, $apiKeySecret);

$composition = $client->video->compositions->create([
    'roomSid' => 'RMXXXX',
    'audioSources' => 'RTXXXX',
    'statusCallback' => 'http://my.server.org/callbacks',
    'format' => 'mp4'
]);

echo $composition->sid;
# Download the helper library from https://www.twilio.com/docs/ruby/install
require 'rubygems'
require 'twilio-ruby'

# Find your credentials at twilio.com/console
api_key_sid = 'SKXXXX'
api_key_secret = 'your_api_key_secret'

@client = Twilio::REST::Client.new(api_key_sid, api_key_secret)

composition = @client.video.compositions.create(
  room_sid: 'RMXXXX',
  audio_sources: 'RTXXXX',
  status_callback: 'http://my.server.org/callbacks',
  format: 'mp4'
)

puts composition.sid
# Download the Python helper library from twilio.com/docs/python/install
from twilio.rest import Client

# Find your credentials at twilio.com/console
api_key_sid = = 'SKXXXX'
api_key_secret = 'your_api_key_secret'
client = Client(api_key_sid, api_key_secret)

composition = client.video.compositions.create(
    room_sid = 'RMXXXX',
    audio_sources = 'RTXXXX',
    status_callback = 'http://my.server.org/callbacks',
    format='mp4')

print('Created composition with SID=%s' % (composition.sid))
// Install the Java helper library from twilio.com/docs/java/install
import com.twilio.Twilio;
import com.twilio.rest.video.v1.Composition;
import com.twilio.rest.video.v1.Composition.Format;

public class TranscodeAudioRecording{

  // Find your credentials at twilio.com/console
  public static final String ACCOUNT_SID = "ACXXXX";
  public static final String API_KEY_SID = "SKXXXX";
  public static final String API_KEY_SECRET = "your_api_key_secret";

  public static void main( String[] args ) throws IOException{
      // Initialize the client
      Twilio.init(API_KEY_SID, API_KEY_SECRET, ACCOUNT_SID);

      Composition composition = Composition.creator()
        					.setRoomSid("RMXXXX")
        					.setAudioSources("RTXXXX")
        					.setStatusCallback("http://my.server.org/callbacks")
        					.setFormat(Format.MP4)
        					.create();

      System.out.println("Created composition with SID=" + composition.getSid());
  }
}
curl -X POST 'https://video.twilio.com/v1/Compositions' \
    -u 'SKXXXX:your_api_key_secret' \
    -F 'RoomSid=RMXXXX' \
    -F 'AudioSources=RTXXXX' \
    -F 'StatusCallback=http://my.server.org/callbacks' \
    -F 'Format=mp4'
{
    "account_sid": "ACXXXX",
    "audio_sources": [
        "RTXXXX"
    ],
    "audio_sources_excluded": [],
    "bitrate": 0,
    "date_completed": null,
    "date_created": "2018-03-26T13:15:11Z",
    "date_deleted": null,
    "duration": 0,
    "format": "mp4",
    "links": {
        "media": "https://video.twilio.com/v1/Compositions/CJXXXX/Media"
    },
    "resolution": "640x480",
    "room_sid": "RMXXXX",
    "sid": "CJXXXX",
    "size": 0,
    "status": "processing",
    "trim": true,
    "url": "https://video.twilio.com/v1/Compositions/CJXXXX",
    "video_layout": {}
}
Transcode an Audio Recording

Remark that, in spite of this being an only-audio composition, it shows default video settings in the corresponding response parameters.

Creating Compositions with Simple Layouts

Example: Compose one Participant Media

In this example we assume a Room with RoomSid=RMXXXX where a Participant with ParticipantSid=PAXXXX publishes both audio and video tracks to the Room. In this Room there may be other Participants publishing audio and video without affecting this example's result. We want to generate a Composition showing the Participant's video Track and having as audio the one of that Participant. Considering that:

  • Your application credentials are (SKXXXX:your_api_key_secret)
  • You want to use mp4 as target format
  • You want to use the default resolution (VGA = 640x480)

You can create the desired Composition using the following:

Loading Code Samples...
Language
Response Format:
  • json
SDK Version:
  • 7.x
SDK Version:
  • 3.x
SDK Version:
  • 5.x
SDK Version:
  • 6.x
SDK Version:
  • 5.x
Format:
  • JSON
// NOTE: This example uses the next generation Twilio helper library - for more
// information on how to download and install this version, visit
// https://www.twilio.com/docs/libraries/node

// Find your credentials at twilio.com/console
const API_KEY_SID = 'SKXXXX';
const API_KEY_SECRET = 'your_api_key_secret';
const ACCOUNT_SID = 'ACXXXX';

const Twilio = require('twilio');

const client = new Twilio(API_KEY_SID, API_KEY_SECRET, {accountSid: ACCOUNT_SID});

client.video.compositions.
  create({
    roomSid: 'RMXXXX',
    audioSources: 'PAXXXX',
    videoLayout: {
      single : {
        video_sources: ['PAXXXX']
      }
    },
    statusCallback: 'http://my.server.org/callbacks',
    format: 'mp4'
  })
  .then(composition =>{
    console.log('Created Composition with SID=' + composition.sid);
  });
<?php
// Get the PHP helper library from https://twilio.com/docs/libraries/php
require_once '/path/to/vendor/autoload.php'; // Loads the library
use Twilio\Rest\Client;

// Find your credentials at twilio.com/console
$apiKeySid = "SKXXXX";
$apiKeySecret = "your_auth_apiKeySecret";
$client = new Client($apiKeySid, $apiKeySecret);

$composition = $client->video->compositions->create([
    'roomSid' => 'RMXXXX',
    'audioSources' => 'PAXXXX',
    'videoLayout' =>  array(
                        'single' => array (
                          'video_sources' => array('PAXXXX')
                        )
                      ),
    'statusCallback' => 'http://my.server.org/callbacks',
    'format' => 'mp4'
]);

echo $composition->sid;
# Download the helper library from https://www.twilio.com/docs/ruby/install
require 'rubygems'
require 'twilio-ruby'

# Find your credentials at twilio.com/console
api_key_sid = 'SKXXXX'
api_key_secret = 'your_api_key_secret'

@client = Twilio::REST::Client.new(api_key_sid, api_key_secret)

composition = @client.video.compositions.create(
  room_sid: 'RMXXXX',
  audio_sources: 'PAXXXX',
  video_layout: {
    single: {
      video_sources: ['PAXXXX']
    }
  },
  status_callback: 'http://my.server.org/callbacks',
  format: 'mp4'
)

puts composition.sid
# Download the Python helper library from twilio.com/docs/python/install
from twilio.rest import Client
import json

# Find your credentials at twilio.com/console
api_key_sid = = 'SKXXXX'
api_key_secret = 'your_api_key_secret'
client = Client(api_key_sid, api_key_secret)

composition = client.video.compositions.create(
    room_sid = 'RMXXXX',
    audio_sources = 'PAXXXX',
    video_layout = {
                    'single': {
                        'video_sources': ['PAXXXX']
                    }
                   },
    status_callback = 'http://my.server.org/callbacks',
    format='mp4')

print('Created composition with SID=%s' % (composition.sid))
// Install the Java helper library from twilio.com/docs/java/install
import com.twilio.Twilio;
import com.twilio.rest.video.v1.Composition;
import com.twilio.rest.video.v1.Composition.Format;

import com.fasterxml.jackson.databind.ObjectMapper;

public class ParticipantComposition{

  // Find your credentials at twilio.com/console
  public static final String ACCOUNT_SID = "ACXXXX";
  public static final String API_KEY_SID = "SKXXXX";
  public static final String API_KEY_SECRET = "your_api_key_secret";

  public static void main( String[] args ) throws IOException{
      // Initialize the client
      Twilio.init(API_KEY_SID, API_KEY_SECRET, ACCOUNT_SID);

      final String videoLayout =
                        "{"
                     + "   \"single\": {"
                     + "       \"video_sources\":[\"PAXXXX\"]"
                     + "    }"
                     + "}";

      Composition composition = Composition.creator()
        					.setRoomSid("RMXXXX")
        					.setAudioSources("PAXXXX")
        					.setVideoLayout(new ObjectMapper().readValue(videoLayout, HashMap.class))
        					.setStatusCallback("http://my.server.org/callbacks")
        					.setFormat(Format.MP4)
        					.create();

      System.out.println("Created composition with SID=" + composition.getSid());
  }
}
curl -X POST 'https://video.twilio.com/v1/Compositions' \
    -u 'SKXXXX:your_api_key_secret' \
    -F 'RoomSid=RMXXXX' \
    -F 'AudioSources=PAXXXX' \
    -F 'StatusCallback=http://my.server.org/callbacks' \
    -F 'Format=mp4' \
<<-EOF -F 'VideoLayout={
      "single":{
        "video_sources":["PAXXXX"]
      }
    }'
EOF
{
    "account_sid": "ACXXXX",
    "audio_sources": [
        "PAXXXX"
    ],
    "audio_sources_excluded": [],
    "bitrate": 0,
    "date_completed": null,
    "date_created": "2018-03-26T13:26:28Z",
    "date_deleted": null,
    "duration": 0,
    "format": "mp4",
    "links": {
        "media": "https://video.twilio.com/v1/Compositions/CJXXXX/Media"
    },
    "resolution": "640x480",
    "room_sid": "RMXXXX",
    "sid": "CJXXXX",
    "size": 0,
    "status": "processing",
    "trim": true,
    "url": "https://video.twilio.com/v1/Compositions/CJXXXX",
    "video_layout": {
        "single": {
            "cells_excluded": [],
            "height": null,
            "max_columns": null,
            "max_rows": null,
            "reuse": "show_oldest",
            "video_sources": [
                "PAXXXX"
            ],
            "video_sources_excluded": [],
            "width": null,
            "x_pos": 0,
            "y_pos": 0,
            "z_pos": 0
        }
    }
}
Compose one Participant Media

Example: Compose One Participant Video with all Room Audios

In this example we assume a Room with RoomSid=RMXXXX where a Participant with ParticipantSid=PAXXXX publishes both audio and video Tracks. In that Room others participant publish also their audio and video Tracks. We want generate a Composition showing PAXXXX video but having as audio the complete set of Room audio Tracks mixed. Considering that:

  • Your application credentials are (SKXXXX:your_api_key_secret)
  • You want to use mp4 as target format
  • You want to use the default resolution (VGA = 640x480)

You can create the desired Composition using the following:

Loading Code Samples...
Language
Response Format:
  • json
SDK Version:
  • 7.x
SDK Version:
  • 3.x
SDK Version:
  • 5.x
SDK Version:
  • 6.x
SDK Version:
  • 5.x
Format:
  • JSON
// NOTE: This example uses the next generation Twilio helper library - for more
// information on how to download and install this version, visit
// https://www.twilio.com/docs/libraries/node

// Find your credentials at twilio.com/console
const API_KEY_SID = 'SKXXXX';
const API_KEY_SECRET = 'your_api_key_secret';
const ACCOUNT_SID = 'ACXXXX';

const Twilio = require('twilio');

const client = new Twilio(API_KEY_SID, API_KEY_SECRET, {accountSid: ACCOUNT_SID});

client.video.compositions.
  create({
    roomSid: 'RMXXXX',
    audioSources: '*',
    videoLayout: {
      single : {
        video_sources: ['PAXXXX']
      }
    },
    statusCallback: 'http://my.server.org/callbacks',
    format: 'mp4'
  })
  .then(composition =>{
    console.log('Created Composition with SID=' + composition.sid);
  });
<?php
// Get the PHP helper library from https://twilio.com/docs/libraries/php
require_once '/path/to/vendor/autoload.php'; // Loads the library
use Twilio\Rest\Client;

// Find your credentials at twilio.com/console
$apiKeySid = "SKXXXX";
$apiKeySecret = "your_auth_apiKeySecret";
$client = new Client($apiKeySid, $apiKeySecret);

$composition = $client->video->compositions->create([
    'roomSid' => 'RMXXXX',
    'audioSources' => '*',
    'videoLayout' =>  array(
                        'single' => array (
                          'video_sources' => array('PAXXXX')
                        )
                      ),
    'statusCallback' => 'http://my.server.org/callbacks',
    'format' => 'mp4'
]);

echo $composition->sid;
# Download the helper library from https://www.twilio.com/docs/ruby/install
require 'rubygems'
require 'twilio-ruby'

# Find your credentials at twilio.com/console
api_key_sid = 'SKXXXX'
api_key_secret = 'your_api_key_secret'

@client = Twilio::REST::Client.new(api_key_sid, api_key_secret)

composition = @client.video.compositions.create(
  room_sid: 'RMXXXX',
  audio_sources: '*',
  video_layout: {
    single: {
      video_sources: ['PAXXXX']
    }
  },
  status_callback: 'http://my.server.org/callbacks',
  format: 'mp4'
)

puts composition.sid
# Download the Python helper library from twilio.com/docs/python/install
from twilio.rest import Client
import json

# Find your credentials at twilio.com/console
api_key_sid = = 'SKXXXX'
api_key_secret = 'your_api_key_secret'
client = Client(api_key_sid, api_key_secret)

composition = client.video.compositions.create(\
    room_sid = 'RMXXXX',\
    audio_sources = '*',\
    video_layout = json.dumps({\
                    'single': {\
                        'video_sources': ['PAXXXX']\
                    }\
                   }),\
    status_callback = 'http://my.server.org/callbacks',\
    format='mp4')

print('Created composition with SID=%s' % (composition.sid))
// Install the Java helper library from twilio.com/docs/java/install
import com.twilio.Twilio;
import com.twilio.rest.video.v1.Composition;
import com.twilio.rest.video.v1.Composition.Format;

import com.fasterxml.jackson.databind.ObjectMapper;

public class ParticipantComposition{

  // Find your credentials at twilio.com/console
  public static final String ACCOUNT_SID = "ACXXXX";
  public static final String API_KEY_SID = "SKXXXX";
  public static final String API_KEY_SECRET = "your_api_key_secret";

  public static void main( String[] args ) throws IOException{
      // Initialize the client
      Twilio.init(API_KEY_SID, API_KEY_SECRET, ACCOUNT_SID);

      final String videoLayout =
                      "{"
                     + "   \"single\": {"
                     + "       \"video_sources\":[\"PAXXXX\"]"
                     + "    }"
                     + "}";

      Composition composition = Composition.creator()
                  .setRoomSid("RMXXXX")
                  .setAudioSources("*")
                  .setVideoLayout(new ObjectMapper().readValue(videoLayout, HashMap.class))
                  .setStatusCallback("http://my.server.org/callbacks")
                  .setFormat(Format.MP4)
                  .create();

      System.out.println("Created composition with SID=" + composition.getSid());
  }
}
curl -X POST 'https://video.twilio.com/v1/Compositions' \
    -u 'SKXXXX:your_api_key_secret' \
    -F 'RoomSid=RMXXXX' \
    -F 'AudioSources=*' \
    -F 'StatusCallback=http://my.server.org/callbacks' \
    -F 'Format=mp4' \
<<-EOF -F 'VideoLayout={
      "single":{
        "video_sources":["PAXXXX"]
      }
    }'
EOF
{
    "account_sid": "ACXXXX",
    "audio_sources": [
        "*"
    ],
    "audio_sources_excluded": [],
    "bitrate": 0,
    "date_completed": null,
    "date_created": "2018-03-26T13:44:11Z",
    "date_deleted": null,
    "duration": 0,
    "format": "mp4",
    "links": {
        "media": "https://video.twilio.com/v1/Compositions/CJXXXX/Media"
    },
    "resolution": "640x480",
    "room_sid": "RMXXXX",
    "sid": "CJXXXX",
    "size": 0,
    "status": "processing",
    "trim": true,
    "url": "https://video.twilio.com/v1/Compositions/CJXXXX",
    "video_layout": {
        "grid": {
            "cells_excluded": [],
            "height": null,
            "max_columns": null,
            "max_rows": null,
            "reuse": "show_oldest",
            "video_sources": [
                "*"
            ],
            "video_sources_excluded": [],
            "width": null,
            "x_pos": 0,
            "y_pos": 0,
            "z_pos": 0
        }
    }
}
Compose one Participant video with all Room audios

Example: Compose the Complete Room in a Grid

In this example we assume a Room with RoomSid=RMXXXX where multiple Participants publish both audio and video Tracks. We want generate a Composition showing all the room videos in a grid, as shown in the figure below, and with all audio tracks mixed.

Grid Room Composition Layout

Considering that:

  • Your application credentials are (SKXXXX:your_api_key_secret)
  • You want to use mp4 as target format
  • You want to use VGA resolution (640x480)
  • You want an unconstrained grid composition with the default cell reuse strategy (show_oldest).

You can create the desired Composition using the following:

Loading Code Samples...
Language
Response Format:
  • json
SDK Version:
  • 7.x
SDK Version:
  • 3.x
SDK Version:
  • 5.x
SDK Version:
  • 6.x
SDK Version:
  • 5.x
Format:
  • JSON
// NOTE: This example uses the next generation Twilio helper library - for more
// information on how to download and install this version, visit
// https://www.twilio.com/docs/libraries/node

// Find your credentials at twilio.com/console
const API_KEY_SID = 'SKXXXX';
const API_KEY_SECRET = 'your_api_key_secret';
const ACCOUNT_SID = 'ACXXXX';

const Twilio = require('twilio');

const client = new Twilio(API_KEY_SID, API_KEY_SECRET, {accountSid: ACCOUNT_SID});

client.video.compositions.
  create({
    roomSid: 'RMXXXX',
    audioSources: '*',
    videoLayout: {
      grid : {
        video_sources: ['*']
      }
    },
    statusCallback: 'http://my.server.org/callbacks',
    format: 'mp4'
  })
  .then(composition =>{
    console.log('Created Composition with SID=' + composition.sid);
  });
<?php
// Get the PHP helper library from https://twilio.com/docs/libraries/php
require_once '/path/to/vendor/autoload.php'; // Loads the library
use Twilio\Rest\Client;

// Find your credentials at twilio.com/console
$apiKeySid = "SKXXXX";
$apiKeySecret = "your_auth_apiKeySecret";
$client = new Client($apiKeySid, $apiKeySecret);

$composition = $client->video->compositions->create([
    'roomSid' => 'RMXXXX',
    'audioSources' => '*',
    'videoLayout' =>  array(
                        'grid' => array (
                          'video_sources' => array('*')
                        )
                      ),
    'statusCallback' => 'http://my.server.org/callbacks',
    'format' => 'mp4'
]);

echo $composition->sid;
# Download the helper library from https://www.twilio.com/docs/ruby/install
require 'rubygems'
require 'twilio-ruby'

# Find your credentials at twilio.com/console
api_key_sid = 'SKXXXX'
api_key_secret = 'your_api_key_secret'

@client = Twilio::REST::Client.new(api_key_sid, api_key_secret)

composition = @client.video.compositions.create(
  room_sid: 'RMXXXX',
  audio_sources: '*',
  video_layout: {
    grid: {
      video_sources: ['*']
    }
  },
  status_callback: 'http://my.server.org/callbacks',
  format: 'mp4'
)

puts composition.sid
# Download the Python helper library from twilio.com/docs/python/install
from twilio.rest import Client
import json

# Find your credentials at twilio.com/console
api_key_sid = = 'SKXXXX'
api_key_secret = 'your_api_key_secret'
client = Client(api_key_sid, api_key_secret)

composition = client.video.compositions.create(
    room_sid = 'RMXXXX',
    audio_sources = '*',
    video_layout = {
                        'grid' : {
                            'video_sources': ['*']
                        }
                    },
    status_callback = 'http://my.server.org/callbacks',
    format='mp4')

print('Created composition with SID=%s' % (composition.sid))
// Install the Java helper library from twilio.com/docs/java/install
import com.twilio.Twilio;
import com.twilio.rest.video.v1.Composition;
import com.twilio.rest.video.v1.Composition.Format;

import com.fasterxml.jackson.databind.ObjectMapper;

public class GridComposition{

  // Find your credentials at twilio.com/console
  public static final String ACCOUNT_SID = "ACXXXX";
  public static final String API_KEY_SID = "SKXXXX";
  public static final String API_KEY_SECRET = "your_api_key_secret";

  public static void main( String[] args ) throws IOException{
      // Initialize the client
      Twilio.init(API_KEY_SID, API_KEY_SECRET, ACCOUNT_SID);

      final String videoLayout =
                       "{"
                     + "   \"grid\": {"
                     + "       \"video_sources\":[\"*\"]"
                     + "    }"
                     + "}";

      Composition composition = Composition.creator()
                  .setRoomSid("RMXXXX")
                  .setAudioSources("*")
                  .setVideoLayout(new ObjectMapper().readValue(videoLayout, HashMap.class))
                  .setStatusCallback("http://my.server.org/callbacks")
                  .setFormat(Format.MP4)
                  .create();

      System.out.println("Created composition with SID=" + composition.getSid());
  }
}
curl -X POST 'https://video.twilio.com/v1/Compositions' \
    -u 'SKXXXX:your_api_key_secret' \
    -F 'RoomSid=RMXXXX' \
    -F 'AudioSources=*' \
    -F 'StatusCallback=http://my.server.org/callbacks' \
    -F 'Format=mp4' \
<<-EOF -F 'VideoLayout={
      "grid":{
        "video_sources":["*"]
      }
    }'
EOF
{
    "account_sid": "ACXXXX",
    "audio_sources": [
        "*"
    ],
    "audio_sources_excluded": [],
    "bitrate": 0,
    "date_completed": null,
    "date_created": "2018-03-26T13:44:11Z",
    "date_deleted": null,
    "duration": 0,
    "format": "mp4",
    "links": {
        "media": "https://video.twilio.com/v1/Compositions/CJXXXX/Media"
    },
    "resolution": "640x480",
    "room_sid": "RMXXXX",
    "sid": "CJXXXX",
    "size": 0,
    "status": "processing",
    "trim": true,
    "url": "https://video.twilio.com/v1/Compositions/CJXXXX",
    "video_layout": {
        "grid": {
            "cells_excluded": [],
            "height": null,
            "max_columns": null,
            "max_rows": null,
            "reuse": "show_oldest",
            "video_sources": [
                "*"
            ],
            "video_sources_excluded": [],
            "width": null,
            "x_pos": 0,
            "y_pos": 0,
            "z_pos": 0
        }
    }
}
Compose the complete Room in a grid

Example: Compose a Specific Set of Track Recordings in a Grid

In this example we assume a Room with RoomSid=RMXXXX where different Participants publish their audio and video Tracks. Imagine that we have special interest in some of these tracks that we identify in the following way:

  • RTAAAA: the RecordingTrackSid of of video Track.
  • MTBBBB: the MediaTrackSid of a video Track.
  • teacher-webcast: the Track name of a video track.

We want to generate a composition showing the three video Tracks in a single row and with no audio, as shown in the figure below.

Three Tracks Composition Layout

Considering that:

  • Your application credentials are (SKXXXX:your_api_key_secret)
  • You want to use mp4 as target format
  • You want to use the default resolution (VGA = 640x480)

You can create the desired Composition using the following:

Loading Code Samples...
Language
Response Format:
  • json
SDK Version:
  • 7.x
SDK Version:
  • 3.x
SDK Version:
  • 5.x
SDK Version:
  • 6.x
SDK Version:
  • 5.x
Format:
  • JSON
// NOTE: This example uses the next generation Twilio helper library - for more
// information on how to download and install this version, visit
// https://www.twilio.com/docs/libraries/node

// Find your credentials at twilio.com/console
const API_KEY_SID = 'SKXXXX';
const API_KEY_SECRET = 'your_api_key_secret';
const ACCOUNT_SID = 'ACXXXX';

const Twilio = require('twilio');

const client = new Twilio(API_KEY_SID, API_KEY_SECRET, {accountSid: ACCOUNT_SID});

client.video.compositions.
  create({
    roomSid: 'RMXXXX',
    videoLayout: {
      grid : {
        max_rows: 1,
        video_sources: [
          "RTAAAA",
          "MTBBBB",
          "teacher-webcast"
        ]
      }
    },
    statusCallback: 'http://my.server.org/callbacks',
    format: 'mp4'
  })
  .then(composition =>{
    console.log('Created Composition with SID=' + composition.sid);
  });
<?php
// Get the PHP helper library from https://twilio.com/docs/libraries/php
require_once '/path/to/vendor/autoload.php'; // Loads the library
use Twilio\Rest\Client;

// Find your credentials at twilio.com/console
$apiKeySid = "SKXXXX";
$apiKeySecret = "your_auth_apiKeySecret";
$client = new Client($apiKeySid, $apiKeySecret);

$composition = $client->video->compositions->create([
    'roomSid' => 'RMXXXX',
    'videoLayout' =>  array(
                        'grid' => array (
                          'max_rows' => 1,
                          'video_sources' => array(
                            'RTAAAA',
                            'MTBBBB',
                            'teacher-webcast'
                          )
                        )
                      ),
    'statusCallback' => 'http://my.server.org/callbacks',
    'format' => 'mp4'
]);

echo $composition->sid;
# Download the helper library from https://www.twilio.com/docs/ruby/install
require 'rubygems'
require 'twilio-ruby'

# Find your credentials at twilio.com/console
api_key_sid = 'SKXXXX'
api_key_secret = 'your_api_key_secret'

@client = Twilio::REST::Client.new(api_key_sid, api_key_secret)

composition = @client.video.compositions.create(
  room_sid: 'RMXXXX',
  video_layout: {
    grid: {
      video_sources: [
        "RTAAAA",
        "MTBBBB",
        "teacher-webcast"
      ]
    }
  },
  status_callback: 'http://my.server.org/callbacks',
  format: 'mp4'
)

puts composition.sid
# Download the Python helper library from twilio.com/docs/python/install
from twilio.rest import Client
import json

# Find your credentials at twilio.com/console
api_key_sid = = 'SKXXXX'
api_key_secret = 'your_api_key_secret'
client = Client(api_key_sid, api_key_secret)

composition = client.video.compositions.create(
    room_sid = 'RMXXXX',
    video_layout = {
                    'grid': {
                        'max_rows': 1,
                        'video_sources': [
                            'RTAAAA',
                            'MTBBBB',
                            'teacher-webcast'
                        ]
                    }
                   },
    status_callback = 'http://my.server.org/callbacks',
    format='mp4')

print('Created composition with SID=%s' % (composition.sid))
// Install the Java helper library from twilio.com/docs/java/install
import com.twilio.Twilio;
import com.twilio.rest.video.v1.Composition;
import com.twilio.rest.video.v1.Composition.Format;

import com.fasterxml.jackson.databind.ObjectMapper;

public class GridComposition{

  // Find your credentials at twilio.com/console
  public static final String ACCOUNT_SID = "ACXXXX";
  public static final String API_KEY_SID = "SKXXXX";
  public static final String API_KEY_SECRET = "your_api_key_secret";

  public static void main( String[] args ) throws IOException{
      // Initialize the client
      Twilio.init(API_KEY_SID, API_KEY_SECRET, ACCOUNT_SID);

      final String videoLayout =
                          "{"
                        + "   \"grid\": {"
                        + "       \"max_rows\": 1,"
                        + "       \"video_sources\":["
                        + "                 \"RTAAAA\","
                        + "                 \"MTBBBB\","
                        + "                 \"teacher-webcast\""
                        + "          ]"
                        + "    }"
                        + "}";

      Composition composition = Composition.creator()
                  .setRoomSid("RMXXXX")
                  .setVideoLayout(new ObjectMapper().readValue(videoLayout, HashMap.class))
                  .setStatusCallback("http://my.server.org/callbacks")
                  .setFormat(Format.MP4)
                  .create();

      System.out.println("Created composition with SID=" + composition.getSid());
  }
}
curl -X POST 'https://video.twilio.com/v1/Compositions' \
    -u 'SKXXXX:your_api_key_secret' \
    -F 'RoomSid=RMXXXX' \
    -F 'StatusCallback=http://my.server.org/callbacks' \
    -F 'Format=mp4' \
<<-EOF -F 'VideoLayout={
      "grid":{
        "max_rows":1,
        "video_sources":[
          "RTAAAA",
          "MTBBBB",
          "teacher-webcast"]
      }
    }'
EOF
{
    "account_sid": "ACXXXX",
    "audio_sources": [],
    "audio_sources_excluded": [],
    "bitrate": 0,
    "date_completed": null,
    "date_created": "2018-03-26T13:52:45Z",
    "date_deleted": null,
    "duration": 0,
    "format": "mp4",
    "links": {
        "media": "https://video.twilio.com/v1/Compositions/CJXXXX/Media"
    },
    "resolution": "640x480",
    "room_sid": "RMXXXX",
    "sid": "CJXXXX",
    "size": 0,
    "status": "processing",
    "trim": true,
    "url": "https://video.twilio.com/v1/Compositions/CJXXXX",
    "video_layout": {
        "grid": {
            "cells_excluded": [],
            "height": null,
            "max_columns": null,
            "max_rows": 1,
            "reuse": "show_oldest",
            "video_sources": [
                "RTAAAA",
                "MTBBBB",
                "teacher-webcast"
            ],
            "video_sources_excluded": [],
            "width": null,
            "x_pos": 0,
            "y_pos": 0,
            "z_pos": 0
        }
    }
}
Compose a set of Tracks in a grid

Compose a Specific Set of Track Recordings as a Sequence

In this example we assume a Room with RoomSid=RMXXXX where a teacher presents lessons to their students. These lessons consist on talks and screensharing presentations that occur in sequence. These may overlap or have idle intervals where no media is published. The Track names of the published media comply with the following pattern:

  • For video: teacher-video-sess-1, teacher-video-sess-2, etc.
  • For audio: teacher-audio-sess-1, teacher-audio-sess-2, etc.

In this context, we want to create a Compositions showing only one video source at a time. That one must match with the video track published later by the teacher at any time. We want the teacher's audio to be included in the Composition. We don't want the Composition to contain the idle intervals where the teacher is not publishing media. In this context, considering that:

  • Your application credentials are (SKXXXX:your_api_key_secret)
  • You want to use mp4 as target format
  • You want to use the default resolution (VGA = 640x480)

You can create the desired Composition using the following:

Loading Code Samples...
Language
Response Format:
  • json
SDK Version:
  • 7.x
SDK Version:
  • 3.x
SDK Version:
  • 5.x
SDK Version:
  • 6.x
SDK Version:
  • 5.x
Format:
  • JSON
// NOTE: This example uses the next generation Twilio helper library - for more
// information on how to download and install this version, visit
// https://www.twilio.com/docs/libraries/node

// Find your credentials at twilio.com/console
const API_KEY_SID = 'SKXXXX';
const API_KEY_SECRET = 'your_api_key_secret';
const ACCOUNT_SID = 'ACXXXX';

const Twilio = require('twilio');

const client = new Twilio(API_KEY_SID, API_KEY_SECRET, {accountSid: ACCOUNT_SID});

client.video.compositions.
  create({
    roomSid: 'RMXXXX',
    audioSources: 'teacher-audio-sess-*',
    videoLayout: {
      sequence: {
        max_rows: 1,
        max_columns: 1,
        reuse : "show_newest",
        video_sources: ['teacher-video-sess-*']
      }
    },
    statusCallback: 'http://my.server.org/callbacks',
    format: 'mp4'
  })
  .then(composition =>{
    console.log('Created Composition with SID=' + composition.sid);
  });
<?php
// Get the PHP helper library from https://twilio.com/docs/libraries/php
require_once '/path/to/vendor/autoload.php'; // Loads the library
use Twilio\Rest\Client;

// Find your credentials at twilio.com/console
$apiKeySid = "SKXXXX";
$apiKeySecret = "your_auth_apiKeySecret";
$client = new Client($apiKeySid, $apiKeySecret);

$composition = $client->video->compositions->create([
    'roomSid' => 'RMXXXX',
    'audioSources' => 'teacher-audio-sess-*',
    'videoLayout' =>  array(
                        'sequence' => array (
                          'max_rows' => 1,
                          'max_columns' => 1,
                          'reuse' => 'show_newest',
                          'video_sources' => array('teacher-video-sess-*')
                        )
                      ),
    'statusCallback' => 'http://my.server.org/callbacks',
    'format' => 'mp4'
]);

echo $composition->sid;
# Download the helper library from https://www.twilio.com/docs/ruby/install
require 'rubygems'
require 'twilio-ruby'

# Find your credentials at twilio.com/console
api_key_sid = 'SKXXXX'
api_key_secret = 'your_api_key_secret'

@client = Twilio::REST::Client.new(api_key_sid, api_key_secret)

composition = @client.video.compositions.create(
  room_sid: 'RMXXXX',
  audio_sources: 'teacher-audio-sess-*',
  video_layout: {
    sequence: {
      max_rows: 1,
      max_columns: 1,
      reuse: 'show_newest',
      video_sources: ['teacher-video-sess-*']
    }
  },
  status_callback: 'http://my.server.org/callbacks',
  format: 'mp4'
)

puts composition.sid
# Download the Python helper library from twilio.com/docs/python/install
from twilio.rest import Client
import json

# Find your credentials at twilio.com/console
api_key_sid = = 'SKXXXX'
api_key_secret = 'your_api_key_secret'
client = Client(api_key_sid, api_key_secret)

composition = client.video.compositions.create(
    room_sid = 'RMXXXX',
    audio_sources = 'teacher-audio-sess-*',
    video_layout = {
                    'sequence': {
                        'max_rows': 1,
                        'max_columns': 1,
                        'reuse': 'show_newest',
                        'video_sources': ['teacher-video-sess-*']
                    }
                   },
    status_callback = 'http://my.server.org/callbacks',
    format='mp4')

print('Created composition with SID=%s' % (composition.sid))
// Install the Java helper library from twilio.com/docs/java/install
import com.twilio.Twilio;
import com.twilio.rest.video.v1.Composition;
import com.twilio.rest.video.v1.Composition.Format;

import com.fasterxml.jackson.databind.ObjectMapper;

public class SequenceComposition{

  // Find your credentials at twilio.com/console
  public static final String ACCOUNT_SID = "ACXXXX";
  public static final String API_KEY_SID = "SKXXXX";
  public static final String API_KEY_SECRET = "your_api_key_secret";

  public static void main( String[] args ) throws IOException{
      // Initialize the client
      Twilio.init(API_KEY_SID, API_KEY_SECRET, ACCOUNT_SID);

      final String videoLayout =
                          "{"
                        + "   \"sequence\": {"
                        + "       \"max_rows\": 1,"
                        + "       \"max_columns\": 1,"
                        + "       \"reuse\": \"show_newest\","
                        + "       \"video_sources\":[\"teacher-video-sess-*\"]"
                        + "    }"
                        + "}";

      Composition composition = Composition.creator()
                  .setRoomSid("RMXXXX")
                  .setAudioSources("teacher-audio-sess-*")
                  .setVideoLayout(new ObjectMapper().readValue(videoLayout, HashMap.class))
                  .setStatusCallback("http://my.server.org/callbacks")
                  .setFormat(Format.MP4)
                  .create();

      System.out.println("Created composition with SID=" + composition.getSid());
  }
}
curl -X POST 'https://video.twilio.com/v1/Compositions' \
    -u 'SKXXXX:your_api_key_secret' \
    -F 'RoomSid=RMXXXX' \
    -F 'StatusCallback=http://my.server.org/callbacks' \
    -F 'Format=mp4' \
    -F 'AudioSources=teacher-audio-sess-*' \
<<-EOF -F 'VideoLayout={
      "sequence":{
        "max_rows":1,
        "max_columns":1,
        "reuse":"show_newest",
        "video_sources":["teacher-video-sess-*"]
      }
    }'
EOF
{
    "account_sid": "ACXXXX",
    "audio_sources": [
        "teacher-audio-sess-*"
    ],
    "audio_sources_excluded": [],
    "bitrate": 0,
    "date_completed": null,
    "date_created": "2018-03-26T14:26:33Z",
    "date_deleted": null,
    "duration": 0,
    "format": "mp4",
    "links": {
        "media": "https://video.twilio.com/v1/Compositions/CJXXXX/Media"
    },
    "resolution": "640x480",
    "room_sid": "RMXXXX",
    "sid": "CJXXXX",
    "size": 0,
    "status": "processing",
    "trim": true,
    "url": "https://video.twilio.com/v1/Compositions/CJXXXX",
    "video_layout": {
        "sequence": {
            "cells_excluded": [],
            "height": null,
            "max_columns": 1,
            "max_rows": 1,
            "reuse": "show_newest",
            "video_sources": [
                "teacher-video-sess-*"
            ],
            "video_sources_excluded": [],
            "width": null,
            "x_pos": 0,
            "y_pos": 0,
            "z_pos": 0
        }
    }
}
Compose a set of Tracks as a sequence

Creating Compositions with Complex Layouts

Example: Creating a PiP (Picture-in-Picture) Composition

In this example we assume a Room with RoomSid=RMXXXX where an expert presents a topic with two audio Tracks, one from his microphone with MediaTrackSid=MTAAAA and another one acting as background soundtrack with Track name =soundtrack, a webcam video track with MediaTrackSid=MTBBBB and a screensharing video Track with Track name screen-presentation.

In this context, we want to create a PiP Composition including the above mentioned audio Tracks and showing:

  • The video track screen-presentation occupying the complete Composition background.
  • The video track MTBBBB in a small box located at the top-left corner of the Composition overlayed on top of screen-presentation as shown on the figure below.

PiP Composition Layout

Assuming that:

  • Your application credentials are (SKXXXX:your_api_key_secret)
  • You want to use mp4 as target format
  • You want to use HD resolution (1280x720)

You can create the desired Composition using the following:

Loading Code Samples...
Language
Response Format:
  • json
SDK Version:
  • 7.x
SDK Version:
  • 3.x
SDK Version:
  • 5.x
SDK Version:
  • 6.x
SDK Version:
  • 5.x
Format:
  • JSON
// NOTE: This example uses the next generation Twilio helper library - for more
// information on how to download and install this version, visit
// https://www.twilio.com/docs/libraries/node

// Find your credentials at twilio.com/console
const API_KEY_SID = 'SKXXXX';
const API_KEY_SECRET = 'your_api_key_secret';
const ACCOUNT_SID = 'ACXXXX';

const Twilio = require('twilio');

const client = new Twilio(API_KEY_SID, API_KEY_SECRET, {accountSid: ACCOUNT_SID});

client.video.compositions.
  create({
    roomSid: 'RMXXXX',
    audioSources: ['MTAAAA', 'soundtrack'],
    videoLayout: {
      main: {
        z_pos: 1,
        video_sources: ['screen-presentation']
      },
      pip: {
        z_pos: 2,
        x_pos: 1000,
        y_pos: 30,
        width: 240,
        height: 180,
        video_sources: ['MTBBBB']
      }
    },
    statusCallback: 'http://my.server.org/callbacks',
    resolution: '1280x720',
    format: 'mp4'
  })
  .then(composition =>{
    console.log('Created Composition with SID=' + composition.sid);
  });
<?php
// Get the PHP helper library from https://twilio.com/docs/libraries/php
require_once '/path/to/vendor/autoload.php'; // Loads the library
use Twilio\Rest\Client;

// Find your credentials at twilio.com/console
$apiKeySid = "SKXXXX";
$apiKeySecret = "your_auth_apiKeySecret";
$client = new Client($apiKeySid, $apiKeySecret);

$composition = $client->video->compositions->create([
    'roomSid' => 'RMXXXX',
    'audioSources' => array('MTAAAA', 'soundtrack'),
    'videoLayout' =>  array(
                        'main' => array (
                          'z_pos' => 1,
                          'video_sources' => array('screen-presentation')
                        ),
                        'pip' => array(
                          'z_pos' => 2,
                          'x_pos' => 1000,
                          'y_pos' => 30,
                          'width' => 240,
                          'height' => 180,
                          'video_sources' => array('MTBBBB')
                        )
                      ),
    'statusCallback' => 'http://my.server.org/callbacks',
    'resolution' => '1280x720',
    'format' => 'mp4'
]);

echo $composition->sid;
# Download the helper library from https://www.twilio.com/docs/ruby/install
require 'rubygems'
require 'twilio-ruby'

# Find your credentials at twilio.com/console
api_key_sid = 'SKXXXX'
api_key_secret = 'your_api_key_secret'

@client = Twilio::REST::Client.new(api_key_sid, api_key_secret)

composition = @client.video.compositions.create(
  room_sid: 'RMXXXX',
  audio_sources: 'teacher-audio-sess-*',
  video_layout: {
    main: {
      z_pos: 1,
      video_sources: ['screen-presentation']
    },
    pip: {
      z_pos: 2,
      x_pos: 1000,
      y_pos: 30,
      width: 240,
      height: 180,
      video_sources: ['MTBBBB']
    }
  },
  status_callback: 'http://my.server.org/callbacks',
  resolution: '1280x720',
  format: 'mp4'
)

puts composition.sid
# Download the Python helper library from twilio.com/docs/python/install
from twilio.rest import Client
import json

# Find your credentials at twilio.com/console
api_key_sid = = 'SKXXXX'
api_key_secret = 'your_api_key_secret'
client = Client(api_key_sid, api_key_secret)

composition = client.video.compositions.create(
    room_sid = 'RMXXXX',
    audio_sources = ['MTAAAA', 'soundtrack'],
    video_layout = {
                    'main' : {
                        'z_pos': 1,
                        'video_sources': ['screen-presentation']
                        },
                    'pip': {
                        'z_pos': 2,
                        'x_pos': 1000,
                        'y_pos': 30,
                        'width': 240,
                        'height': 180,
                        'video_sources': ['MTBBBB']
                    }
                   },
    status_callback = 'http://my.server.org/callbacks',
    resolution = '1280x720',
    format='mp4')

print('Created composition with SID=%s' % (composition.sid))
// Install the Java helper library from twilio.com/docs/java/install
import com.twilio.Twilio;
import com.twilio.rest.video.v1.Composition;
import com.twilio.rest.video.v1.Composition.Format;

import com.fasterxml.jackson.databind.ObjectMapper;

public class PipComposition{

  // Find your credentials at twilio.com/console
  public static final String ACCOUNT_SID = "ACXXXX";
  public static final String API_KEY_SID = "SKXXXX";
  public static final String API_KEY_SECRET = "your_api_key_secret";

  public static void main( String[] args ) throws IOException{
      // Initialize the client
      Twilio.init(API_KEY_SID, API_KEY_SECRET, ACCOUNT_SID);

      final String videoLayout =
                        "{"
                      + "   \"main\": {"
                      + "       \"z_pos\": 1,"
                      + "       \"video_sources\":[\"screen-presetation\"]"
                      + "    },"
                      + "   \"row\": {"
                      + "       \"z_pos\": 2,"
                      + "       \"x_pos\": 1000,"
                      + "       \"y_pos\": 30,"
                      + "       \"width\": 240,"
                      + "       \"height\": 180,"
                      + "       \"video_sources\": [\"RTBBBB\"]"
                      + "    }"
                      + "}";

      Composition composition = Composition.creator()
                  .setRoomSid("RMXXXX")
                  .setAudioSources(Arrays.asList("MTAAAA","soundtrack"))
                  .setVideoLayout(new ObjectMapper().readValue(videoLayout, HashMap.class))
                  .setStatusCallback("http://my.server.org/callbacks")
                  .setResolution("1280x720")
                  .setFormat(Format.MP4)
                  .create();

      System.out.println("Created composition with SID=" + composition.getSid());
  }
}
curl -X POST 'https://video.twilio.com/v1/Compositions' \
    -u 'SKXXXX:your_api_key_secret' \
    -F 'RoomSid=RMXXXX' \
    -F 'AudioSources=MTAAAA' \
    -F 'AudioSources=soundtrack' \
    -F 'Resolution=1280x720' \
    -F 'Format=mp4' \
    -F 'StatusCallback=http://my.server.org/callbacks' \
<<-EOF -F 'VideoLayout={
      "main":{
        "z_pos":1,
        "video_sources":["screen-presentation"]
      },
      "pip":{
        "z_pos":2,
        "x_pos":1000,
        "y_pos":30,
        "width":240,
        "height":180,
        "video_sources":["MTBBBB"]
      }
    }'
EOF
{
    "account_sid": "ACXXXX",
    "audio_sources": [
        "MTAAAA",
        "soundtrack"
    ],
    "audio_sources_excluded": [],
    "bitrate": 0,
    "date_completed": null,
    "date_created": "2018-03-26T15:16:14Z",
    "date_deleted": null,
    "duration": 0,
    "format": "mp4",
    "links": {
        "media": "https://video.twilio.com/v1/Compositions/CJXXXX/Media"
    },
    "resolution": "1280x720",
    "room_sid": "RMXXXX",
    "sid": "CJXXXX",
    "size": 0,
    "status": "processing",
    "trim": true,
    "url": "https://video.twilio.com/v1/Compositions/CJXXXX",
    "video_layout": {
        "main": {
            "cells_excluded": [],
            "height": null,
            "max_columns": null,
            "max_rows": null,
            "reuse": "show_oldest",
            "video_sources": [
                "screen-presentation"
            ],
            "video_sources_excluded": [],
            "width": null,
            "x_pos": 0,
            "y_pos": 0,
            "z_pos": 1
        },
        "pip": {
            "cells_excluded": [],
            "height": 180,
            "max_columns": null,
            "max_rows": null,
            "reuse": "show_oldest",
            "video_sources": [
                "MTBBBB"
            ],
            "video_sources_excluded": [],
            "width": 240,
            "x_pos": 1000,
            "y_pos": 30,
            "z_pos": 2
        }
    }
}
Creating a Picture-in-Picture Composition

Example: Composing a a Room with Natural Layouts

In this example we assume a Room with RoomSid=RMXXXX where a lecture is taking place. The Participants are the following:

  • A teacher publishes the following Tracks:
  • A webcam video Track with name teacher-webcam-video.
  • An screensharing video Track with name teacher-screen-video.
  • An audio Track with name teacher-audio.
  • A variable number of students publishing each the following (i varies from student to student):
  • A webcam video track with name student-i-video
  • An audio Track with name student-i-audio

In this context, imagine that we want to create the following Composition:

  • Track teacher-screen-video must be shown as Composition background occupying its complete viewport. A track with such disposition is sometimes called "main".
  • The rest of video tracks should be shown in a row at the bottom of the Composition, as shown in the figure below.
  • All the audio tracks of the Room should be mixed for the Composition.

Focus + Row Composition Layout

Assuming that:

  • Your application credentials are (SKXXXX:your_api_key_secret)
  • You want to use mp4 as target format
  • You want to use HD resolution (1280x720)

You can create the desired Composition using the following:

Loading Code Samples...
Language
Response Format:
  • json
SDK Version:
  • 7.x
SDK Version:
  • 3.x
SDK Version:
  • 5.x
SDK Version:
  • 6.x
SDK Version:
  • 5.x
Format:
  • JSON
// NOTE: This example uses the next generation Twilio helper library - for more
// information on how to download and install this version, visit
// https://www.twilio.com/docs/libraries/node

// Find your credentials at twilio.com/console
const API_KEY_SID = 'SKXXXX';
const API_KEY_SECRET = 'your_api_key_secret';
const ACCOUNT_SID = 'ACXXXX';

const Twilio = require('twilio');

const client = new Twilio(API_KEY_SID, API_KEY_SECRET, {accountSid: ACCOUNT_SID});

client.video.compositions.
  create({
    roomSid: 'RMXXXX',
    audioSources: '*',
    videoLayout: {
      main: {
        z_pos: 1,
        video_sources: ['teacher-screen-video']
      },
      row: {
        z_pos: 2,
        x_pos: 10,
        y_pos: 530,
        width: 1260,
        height: 160,
        max_rows: 1,
        video_sources: ['*'],
        video_sources_excluded: ['teacher-screen-video']
      }
    },
    statusCallback: 'http://my.server.org/callbacks',
    resolution: '1280x720',
    format: 'mp4'
  })
  .then(composition =>{
    console.log('Created Composition with SID=' + composition.sid);
  });
<?php
// Get the PHP helper library from https://twilio.com/docs/libraries/php
require_once '/path/to/vendor/autoload.php'; // Loads the library
use Twilio\Rest\Client;

// Find your credentials at twilio.com/console
$apiKeySid = "SKXXXX";
$apiKeySecret = "your_auth_apiKeySecret";
$client = new Client($apiKeySid, $apiKeySecret);

$composition = $client->video->compositions->create([
    'roomSid' => 'RMXXXX',
    'audioSources' => '*',
    'videoLayout' =>  array(
                        'main' => array (
                            'z_pos' => 1,
                            'video_sources' => array('teacher-screen-video')
                        ),
                        'row' => array(
                            'z_pos' => 2,
                            'x_pos' => 10,
                            'y_pos' => 530,
                            'width' => 1260,
                            'height' => 160,
                            'max_rows' => 1,
                            'video_sources' => array('*'),
                            'video_sources_excluded' => array('teacher-screen-video')
                        )
                      ),
    'statusCallback' => 'http://my.server.org/callbacks',
    'resolution' => '1280x720',
    'format' => 'mp4'
]);

echo $composition->sid;
# Download the helper library from https://www.twilio.com/docs/ruby/install
require 'rubygems'
require 'twilio-ruby'

# Find your credentials at twilio.com/console
api_key_sid = 'SKXXXX'
api_key_secret = 'your_api_key_secret'

@client = Twilio::REST::Client.new(api_key_sid, api_key_secret)

composition = @client.video.compositions.create(
  room_sid: 'RMXXXX',
  audio_sources: '*',
  video_layout: {
    main: {
      z_pos: 1,
      video_sources: ['teacher-screen-video']
    },
    row: {
      z_pos: 2,
      x_pos: 10,
      y_pos: 530,
      width: 1260,
      height: 160,
      max_rows: 1,
      video_sources: ['*']
      video_sources_excluded: ['teacher-screen-video']
    }
  },
  status_callback: 'http://my.server.org/callbacks',
  resolution: '1280x720',
  format: 'mp4'
)

puts composition.sid
# Download the Python helper library from twilio.com/docs/python/install
from twilio.rest import Client
import json

# Find your credentials at twilio.com/console
api_key_sid = = 'SKXXXX'
api_key_secret = 'your_api_key_secret'
client = Client(api_key_sid, api_key_secret)

composition = client.video.compositions.create(
    room_sid = 'RMXXXX',
    audio_sources = '*',
    video_layout = {
                        'main' : {
                            'z_pos': 1,
                            'video_sources': ['teacher-screen-video']
                        },
                        'row': {
                            'z_pos': 2,
                            'x_pos': 10,
                            'y_pos': 530,
                            'width': 1260,
                            'height': 160,
                            'max_rows': 1,
                            'video_sources': ['*'],
                            'video_sources_excluded': ['teacher-screen-video']
                        }
                    },
    status_callback = 'http://my.server.org/callbacks',
    resolution = '1280x720',
    format='mp4')

print('Created composition with SID=%s' % (composition.sid))
// Install the Java helper library from twilio.com/docs/java/install
import com.twilio.Twilio;
import com.twilio.rest.video.v1.Composition;
import com.twilio.rest.video.v1.Composition.Format;

import com.fasterxml.jackson.databind.ObjectMapper;

public class ComplexComposition{

  // Find your credentials at twilio.com/console
  public static final String ACCOUNT_SID = "ACXXXX";
  public static final String API_KEY_SID = "SKXXXX";
  public static final String API_KEY_SECRET = "your_api_key_secret";

  public static void main( String[] args ) throws IOException{
      // Initialize the client
      Twilio.init(API_KEY_SID, API_KEY_SECRET, ACCOUNT_SID);

      final String videoLayout =
                        "{"
                      + "   \"main\": {"
                      + "       \"z_pos\": 1,"
                      + "       \"video_sources\":[\"teacher-screen-video\"]"
                      + "    },"
                      + "   \"row\": {"
                      + "       \"z_pos\": 2,"
                      + "       \"x_pos\": 10,"
                      + "       \"y_pos\": 530,"
                      + "       \"width\": 1260,"
                      + "       \"height\": 160,"
                      + "       \"max_rows\": 1,"
                      + "       \"video_sources\": [\"*\"],"
                      + "       \"video_sources_excluded\": [\"teacher-screen-video\"]"
                      + "    }"
                      + "}";

      Composition composition = Composition.creator()
                  .setRoomSid("RMXXXX")
                  .setAudioSources("*")
                  .setVideoLayout(new ObjectMapper().readValue(videoLayout, HashMap.class))
                  .setStatusCallback("http://my.server.org/callbacks")
                  .setResolution("1280x720")
                  .setFormat(Format.MP4)
                  .create();

      System.out.println("Created composition with SID=" + composition.getSid());
  }
}
curl -X POST 'https://video.twilio.com/v1/Compositions' \
    -u 'SKXXXX:your_api_key_secret' \
    -F 'RoomSid=RMXXXX' \
    -F 'AudioSources=*' \
    -F 'StatusCallback=http://my.server.org/callbacks' \
    -F 'Resolution=1280x720'\
    -F 'Format=mp4' \
<<-EOF -F 'VideoLayout={
      "main":{
        "z_pos":1,
        "video_sources":["teacher-screen-video"]
      },
      "row":{
        "z_pos":2,
        "x_pos":10,
        "y_pos":530,
        "width":1260,
        "height":160,
        "max_rows":1,
        "video_sources":["*"],
        "video_sources_excluded":["teacher-screen-video"]
      }
    }'
EOF
{{
    "account_sid": "ACXXXX",
    "audio_sources": [
        "*"
    ],
    "audio_sources_excluded": [],
    "bitrate": 0,
    "date_completed": null,
    "date_created": "2018-03-26T15:45:18Z",
    "date_deleted": null,
    "duration": 0,
    "format": "mp4",
    "links": {
        "media": "https://video.twilio.com/v1/Compositions/CJXXXX/Media"
    },
    "resolution": "1280x720",
    "room_sid": "RMXXXX",
    "sid": "CJXXXX",
    "size": 0,
    "status": "processing",
    "trim": true,
    "url": "https://video.twilio.com/v1/Compositions/CJXXXX",
    "video_layout": {
        "main": {
            "cells_excluded": [],
            "height": null,
            "max_columns": null,
            "max_rows": null,
            "reuse": "show_oldest",
            "video_sources": [
                "teacher-screen-video"
            ],
            "video_sources_excluded": [],
            "width": null,
            "x_pos": 0,
            "y_pos": 0,
            "z_pos": 1
        },
        "row": {
            "cells_excluded": [],
            "height": 160,
            "max_columns": null,
            "max_rows": 1,
            "reuse": "show_oldest",
            "video_sources": [
                "*"
            ],
            "video_sources_excluded": [
                "teacher-screen-video"
            ],
            "width": 1260,
            "x_pos": 10,
            "y_pos": 530,
            "z_pos": 2
        }
    }
}
Compose a Room with main+row layout

Imagine now that you want the Composition to have a slightly different layout:

  • Track teacher-screen-video must be shown as Composition background occupying its complete viewport.
  • Track teacher-webcam-video must be shown as a small window in the top-right corner of the Composition.
  • The rest of video tracks should be shown in a column on the left with no more than 5 rows as shown on the figure below.
  • All the audio tracks of the Room should be mixed for the Composition.

PiP + Column Composition Layout

In this case, the required code would be the following:

Loading Code Samples...
Language
Response Format:
  • json
SDK Version:
  • 7.x
SDK Version:
  • 3.x
SDK Version:
  • 5.x
SDK Version:
  • 6.x
SDK Version:
  • 5.x
Format:
  • JSON
// NOTE: This example uses the next generation Twilio helper library - for more
// information on how to download and install this version, visit
// https://www.twilio.com/docs/libraries/node

// Find your credentials at twilio.com/console
const API_KEY_SID = 'SKXXXX';
const API_KEY_SECRET = 'your_api_key_secret';
const ACCOUNT_SID = 'ACXXXX';

const Twilio = require('twilio');

const client = new Twilio(API_KEY_SID, API_KEY_SECRET, {accountSid: ACCOUNT_SID});

client.video.compositions.
  create({
    roomSid: 'RMXXXX',
    audioSources: '*',
    videoLayout: {
      main: {
        z_pos: 1,
        video_sources: ['teacher-screen-video']
      },
      pip: {
        z_pos: 2,
        x_pos: 1000,
        y_pos: 30,
        width: 240,
        height: 180,
        video_sources: ['teacher-webcam-video']
      },
      column: {
        z_pos: 3,
        x_pos: 40,
        y_pos: 10,
        width: 190,
        height: 700,
        max_rows: 5,
        max_columns: 1,
        reuse: "show_newest",
        video_sources: ['student-*']
      }
    },
    statusCallback: 'http://my.server.org/callbacks',
    resolution: '1280x720',
    format: 'mp4'
  })
  .then(composition =>{
    console.log('Created Composition with SID=' + composition.sid);
  });
<?php
// Get the PHP helper library from https://twilio.com/docs/libraries/php
require_once '/path/to/vendor/autoload.php'; // Loads the library
use Twilio\Rest\Client;

// Find your credentials at twilio.com/console
$apiKeySid = "SKXXXX";
$apiKeySecret = "your_auth_apiKeySecret";
$client = new Client($apiKeySid, $apiKeySecret);

$composition = $client->video->compositions->create([
    'roomSid' => 'RMXXXX',
    'audioSources' => '*',
    'videoLayout' =>  array(
                        'main' => array (
                            'z_pos' => 1,
                            'video_sources' => array('teacher-screen-video')
                        ),
                        'pip' => array(
                            'z_pos' => 2,
                            'x_pos' => 1000,
                            'y_pos' => 30,
                            'width' => 240,
                            'height' => 180,
                            'video_sources' => array('teacher-webcam-video')
                        ),
                        'column' => array(
                            'z_pos' => 3,
                            'x_pos' => 40,
                            'y_pos' => 10,
                            'width' => 190,
                            'height' => 700,
                            'max_rows' => 5,
                            'max_columns' => 1,
                            'reuse' => 'show_newest',
                            'video_sources' => array('student-*')
                        )
                      ),
    'statusCallback' => 'http://my.server.org/callbacks',
    'resolution' => '1280x720',
    'format' => 'mp4'
]);

echo $composition->sid;
# Download the helper library from https://www.twilio.com/docs/ruby/install
require 'rubygems'
require 'twilio-ruby'

# Find your credentials at twilio.com/console
api_key_sid = 'SKXXXX'
api_key_secret = 'your_api_key_secret'

@client = Twilio::REST::Client.new(api_key_sid, api_key_secret)

composition = @client.video.compositions.create(
  room_sid: 'RMXXXX',
  audio_sources: '*',
  video_layout: {
    main: {
      z_pos: 1,
      video_sources: ['teacher-screen-video']
    },
    pip: {
      z_pos: 2,
      x_pos: 1000,
      y_pos: 30,
      width: 240,
      height: 180,
      max_rows: 1,
      video_sources: ['teacher-webcam-video']
    },
    column: {
      z_pos: 3,
      x_pos: 40,
      y_pos: 10,
      width: 190,
      height: 700,
      max_rows: 5,
      max_columns: 1,
      reuse: 'show_newest',
      video_sources: ['student-*']
    }
  },
  status_callback: 'http://my.server.org/callbacks',
  resolution: '1280x720',
  format: 'mp4'
)

puts composition.sid
# Download the Python helper library from twilio.com/docs/python/install
from twilio.rest import Client
import json

# Find your credentials at twilio.com/console
api_key_sid = = 'SKXXXX'
api_key_secret = 'your_api_key_secret'
client = Client(api_key_sid, api_key_secret)

composition = client.video.compositions.create(
    room_sid = 'RMXXXX',
    audio_sources = '*',
    video_layout = {
                        'main' : {
                            'z_pos': 1,
                            'video_sources': ['teacher-screen-video']
                        },
                        'pip': {
                            'z_pos': 2,
                            'x_pos': 1000,
                            'y_pos': 30,
                            'width': 240,
                            'height': 180,
                            'video_sources': ['teacher-webcam-video']
                        },
                        'column': {
                            'z_pos': 3,
                            'x_pos': 40,
                            'y_pos': 10,
                            'width': 190,
                            'height': 700,
                            'max_rows': 5,
                            'max_columns': 1,
                            'reuse': 'show_newest',
                            'video_sources': ['student-*']
                        }
                    },
    status_callback = 'http://my.server.org/callbacks',
    resolution = '1280x720',
    format='mp4')

print('Created composition with SID=%s' % (composition.sid))
// Install the Java helper library from twilio.com/docs/java/install
import com.twilio.Twilio;
import com.twilio.rest.video.v1.Composition;
import com.twilio.rest.video.v1.Composition.Format;

import com.fasterxml.jackson.databind.ObjectMapper;

public class ComplexComposition{

  // Find your credentials at twilio.com/console
  public static final String ACCOUNT_SID = "ACXXXX";
  public static final String API_KEY_SID = "SKXXXX";
  public static final String API_KEY_SECRET = "your_api_key_secret";

  public static void main( String[] args ) throws IOException{
      // Initialize the client
      Twilio.init(API_KEY_SID, API_KEY_SECRET, ACCOUNT_SID);

      final String videoLayout =
                        "{"
                      + "   \"main\": {"
                      + "       \"z_pos\": 1,"
                      + "       \"video_sources\":[\"teacher-screen-video\"]"
                      + "    },"
                      + "   \"pip\": {"
                      + "       \"z_pos\": 2,"
                      + "       \"x_pos\": 1000,"
                      + "       \"y_pos\": 30,"
                      + "       \"width\": 240,"
                      + "       \"height\": 180,"
                      + "       \"video_sources\": [\"teacher-webcam-video\"]"
                      + "    },"
                      + "   \"column\": {"
                      + "       \"z_pos\": 3,"
                      + "       \"x_pos\": 40,"
                      + "       \"y_pos\": 10,"
                      + "       \"width\": 190,"
                      + "       \"height\": 700,"
                      + "       \"max_rows\": 5,"
                      + "       \"max_columns\": 1,"
                      + "       \"reuse\": \"show_newest\","
                      + "       \"video_sources\": [\"student-*\"]"
                      + "    }"
                      + "}";

      Composition composition = Composition.creator()
                  .setRoomSid("RMXXXX")
                  .setAudioSources("*")
                  .setVideoLayout(new ObjectMapper().readValue(videoLayout, HashMap.class))
                  .setStatusCallback("http://my.server.org/callbacks")
                  .setResolution("1280x720")
                  .setFormat(Format.MP4)
                  .create();

      System.out.println("Created composition with SID=" + composition.getSid());
  }
}
curl -X POST 'https://video.twilio.com/v1/Compositions' \
    -u 'SKXXXX:your_api_key_secret' \
    -F 'RoomSid=RMXXXX' \
    -F 'AudioSources=*' \
    -F 'StatusCallback=http://my.server.org/callbacks' \
    -F 'Resolution=1280x720' \
    -F 'Format=mp4' \
<<-EOF -F 'VideoLayout={
      "main":{
        "z_pos":1,
        "video_sources":["teacher-screen-video"]
      },
      "pip":{
        "z_pos":2,
        "x_pos":1000,
        "y_pos":30,
        "width":240,
        "height":180,
        "video_sources":["teacher-webcam-video"]
      },
      "column":{
        "z_pos":3,
        "x_pos":40,
        "y_pos":10,
        "width":190,
        "height":700,
        "max_rows":5,
        "max_columns":1,
        "reuse":"show_newest",
        "video_sources":["student-*"]
      }
    }'
EOF
{
    "account_sid": "ACXXXX",
    "audio_sources": [
        "*"
    ],
    "audio_sources_excluded": [],
    "bitrate": 0,
    "date_completed": null,
    "date_created": "2018-03-26T15:55:31Z",
    "date_deleted": null,
    "duration": 0,
    "format": "mp4",
    "links": {
        "media": "https://video.twilio.com/v1/Compositions/CJXXXX/Media"
    },
    "resolution": "1280x720",
    "room_sid": "RMXXXX",
    "sid": "CJXXXX",
    "size": 0,
    "status": "processing",
    "trim": true,
    "url": "https://video.twilio.com/v1/Compositions/CJXXXX",
    "video_layout": {
        "column": {
            "cells_excluded": [],
            "height": 700,
            "max_columns": 1,
            "max_rows": 5,
            "reuse": "show_newest",
            "video_sources": [
                "student-*"
            ],
            "video_sources_excluded": [],
            "width": 190,
            "x_pos": 40,
            "y_pos": 10,
            "z_pos": 3
        },
        "main": {
            "cells_excluded": [],
            "height": null,
            "max_columns": null,
            "max_rows": null,
            "reuse": "show_oldest",
            "video_sources": [
                "teacher-screen-video"
            ],
            "video_sources_excluded": [],
            "width": null,
            "x_pos": 0,
            "y_pos": 0,
            "z_pos": 1
        },
        "pip": {
            "cells_excluded": [],
            "height": 180,
            "max_columns": null,
            "max_rows": null,
            "reuse": "show_oldest",
            "video_sources": [
                "teacher-webcam-video"
            ],
            "video_sources_excluded": [],
            "width": 240,
            "x_pos": 1000,
            "y_pos": 30,
            "z_pos": 2
        }
    }
}
Compose a Room using a column+PiP layout

Example: Composing a Room with Mosaic Layout

In this example we assume a Room with RoomSid=RMXXXX where an interview is taking place through the following tracks:

  • The interviewed publishes the following:
  • A video Track named interviewed-video.
  • An audio Track named interviewed-audio.
  • A number of interviewers publishing each:
  • A video Track named iterviewer-i-video.
  • An audio Track named interviewed-i-audio.
  • An advisor, who can only be listened by the interviewed, publishes:
  • An audio Track named advisor-audio.

We want to create the following Composition:

  • Track interviewed-video must be shown centered in the middle of the composition.
  • The rest of video tracks should be shown around that one, as the figure indicates.
  • All the audio tracks of the Room should be mixed for the Composition except for advisor-audio that should not be included.

Mosaic Composition Layout

Assuming that:

  • Your application credentials are (SKXXXX:your_api_key_secret)
  • You want to use mp4 as target format
  • You want to use HD resolution (1280x720)

You can create the desired Composition using the following:

Loading Code Samples...
Language
Response Format:
  • json
SDK Version:
  • 7.x
SDK Version:
  • 3.x
SDK Version:
  • 5.x
SDK Version:
  • 6.x
SDK Version:
  • 5.x
Format:
  • JSON
// NOTE: This example uses the next generation Twilio helper library - for more
// information on how to download and install this version, visit
// https://www.twilio.com/docs/libraries/node

// Find your credentials at twilio.com/console
const API_KEY_SID = 'SKXXXX';
const API_KEY_SECRET = 'your_api_key_secret';
const ACCOUNT_SID = 'ACXXXX';

const Twilio = require('twilio');

const client = new Twilio(API_KEY_SID, API_KEY_SECRET, {accountSid: ACCOUNT_SID});

client.video.compositions.
  create({
    roomSid: 'RMXXXX',
    audioSources: '*',
    audioSourcesExcluded: 'advisor-audio'
    videoLayout: {
        interviewed: {
          z_pos: 2,
          x_pos: 400,
          y_pos: 180,
          width: 480,
          height: 360,
          video_sources: ['interviewed-video']
        },
        interviewers: {
          z_pos: 1,
          x_pos: 10,
          y_pos: 0,
          width: 1260,
          height: 720,
          max_rows: 3,
          max_columns: 3,
          reuse: "show_newest",
          cells_excluded: [4],
          video_sources: ['iterviewer-*']
        }
      },
    statusCallback: 'http://my.server.org/callbacks',
    resolution: '1280x720',
    format: 'mp4'
  })
  .then(composition =>{
    console.log('Created Composition with SID=' + composition.sid);
  });
<?php
// Get the PHP helper library from https://twilio.com/docs/libraries/php
require_once '/path/to/vendor/autoload.php'; // Loads the library
use Twilio\Rest\Client;

// Find your credentials at twilio.com/console
$apiKeySid = "SKXXXX";
$apiKeySecret = "your_auth_apiKeySecret";
$client = new Client($apiKeySid, $apiKeySecret);

$composition = $client->video->compositions->create([
    'roomSid' => 'RMXXXX',
    'audioSources' => '*',
    'audioSourcesExcluded' => 'advisor-audio',
    'videoLayout' =>  array(
                        'interviewed' => array(
                            'z_pos' => 2,
                            'x_pos' => 400,
                            'y_pos' => 180,
                            'width' => 480,
                            'height' => 360,
                            'video_sources' => array('interviewed-video')
                        ),
                        'interviewers' => array(
                            'z_pos' => 1,
                            'x_pos' => 10,
                            'y_pos' => 0,
                            'width' => 1260,
                            'height' => 720,
                            'max_rows' => 3,
                            'max_columns' => 3,
                            'reuse' => 'show_newest',
                            'cells_excluded' => array(4),
                            'video_sources' => array('interviewer-*')
                        )
                      ),
    'statusCallback' => 'http://my.server.org/callbacks',
    'resolution' => '1280x720',
    'format' => 'mp4'
]);

echo $composition->sid;
# Download the helper library from https://www.twilio.com/docs/ruby/install
require 'rubygems'
require 'twilio-ruby'

# Find your credentials at twilio.com/console
api_key_sid = 'SKXXXX'
api_key_secret = 'your_api_key_secret'

@client = Twilio::REST::Client.new(api_key_sid, api_key_secret)

composition = @client.video.compositions.create(
  room_sid: 'RMXXXX',
  audio_sources: '*',
  audio_sources_excluded: 'advisor-audio',
  video_layout: {
    interviewed: {
      z_pos: 2,
      x_pos: 400,
      y_pos: 180,
      width: 480,
      height: 360,
      video_sources: ['interviewed-video']
    },
    interviewers: {
      z_pos: 1,
      x_pos: 10,
      y_pos: 0,
      width: 1260,
      height: 720,
      max_rows: 3,
      max_columns: 3,
      reuse: 'show_newest',
      cells_excluded: [4],
      video_sources: ['iterviewer-*']
    }
  },
  status_callback: 'http://my.server.org/callbacks',
  resolution: '1280x720',
  format: 'mp4'
)

puts composition.sid
# Download the Python helper library from twilio.com/docs/python/install
from twilio.rest import Client
import json

# Find your credentials at twilio.com/console
api_key_sid = = 'SKXXXX'
api_key_secret = 'your_api_key_secret'
client = Client(api_key_sid, api_key_secret)

composition = client.video.compositions.create(
    room_sid = 'RMXXXX',
    audio_sources = '*',
    audio_sources_excluded = 'advisor-audio',
    video_layout = {
                        'interviewed' : {
                            'z_pos': 2,
                            'x_pos': 400,
                            'y_pos': 180,
                            'width': 480,
                            'height': 360,
                            'video_sources': ['interviewed-video']
                        },
                        'interviewers': {
                            'z_pos': 1,
                            'x_pos': 10,
                            'y_pos': 0,
                            'width': 1260,
                            'height': 720,
                            'max_rows': 3,
                            'max_columns': 3,
                            'reuse': 'show_newest',
                            'cells_excluded': [4],
                            'video_sources': ['iterviewer-*']
                        }
                    },
    status_callback = 'http://my.server.org/callbacks',
    resolution = '1280x720',
    format='mp4')

print('Created composition with SID=%s' % (composition.sid))
// Install the Java helper library from twilio.com/docs/java/install
import com.twilio.Twilio;
import com.twilio.rest.video.v1.Composition;
import com.twilio.rest.video.v1.Composition.Format;

import com.fasterxml.jackson.databind.ObjectMapper;

public class PipComposition{

  // Find your credentials at twilio.com/console
  public static final String ACCOUNT_SID = "ACXXXX";
  public static final String API_KEY_SID = "SKXXXX";
  public static final String API_KEY_SECRET = "your_api_key_secret";

  public static void main( String[] args ) throws IOException{
      // Initialize the client
      Twilio.init(API_KEY_SID, API_KEY_SECRET, ACCOUNT_SID);

      final String videoLayout =
                        "{"
                      + "   \"interviewed\": {"
                      + "       \"z_pos\": 2,"
                      + "       \"x_pos\": 400,"
                      + "       \"y_pos\": 180,"
                      + "       \"width\": 480,"
                      + "       \"height\": 360,"
                      + "       \"video_sources\": [\"interviewed-video\"]"
                      + "    },"
                      + "   \"interviewers\": {"
                      + "       \"z_pos\": 1,"
                      + "       \"x_pos\": 10,"
                      + "       \"y_pos\": 0,"
                      + "       \"width\": 1260,"
                      + "       \"height\": 720,"
                      + "       \"max_rows\": 3,"
                      + "       \"max_columns\": 3,"
                      + "       \"reuse\": \"show_newest\","
                      + "       \"cells_excluded\": [4],"
                      + "       \"video_sources\": [\"interviewer-*\"]"
                      + "    }"
                      + "}";

      Composition composition = Composition.creator()
                  .setRoomSid("RMXXXX")
                  .setAudioSources("*")
                  .setAudioSourcesExcluded("advisor-audio")
                  .setVideoLayout(new ObjectMapper().readValue(videoLayout, HashMap.class))
                  .setStatusCallback("http://my.server.org/callbacks")
                  .setResolution("1280x720")
                  .setFormat(Format.MP4)
                  .create();

      System.out.println("Created composition with SID=" + composition.getSid());
  }
}
curl -X POST 'https://video.twilio.com/v1/Compositions' \
    -u 'SKXXXX:your_api_key_secret' \
    -F 'RoomSid=RMXXXX' \
    -F 'AudioSources=*' \
    -F 'AudioSourcesExcluded=advisor-audio' \
    -F 'StatusCallback=http://my.server.org/callbacks' \
    -F 'Resolution=1280x720' \
    -F 'Format=mp4' \
<<-EOF -F 'VideoLayout={
      "interviewed":{
        "z_pos":2,
        "x_pos":400,
        "y_pos":180,
        "width":480,
        "height":360,
        "video_sources":["interviewed-video"]
      },
      "interviewers":{
        "z_pos":1,
        "x_pos":10,
        "y_pos":0,
        "width":1260,
        "height":720,
        "max_rows":3,
        "max_columns":3,
        "reuse":"show_newest",
        "cells_excluded":[4],
        "video_sources":["iterviewer-*"]
      }
    }'
EOF
{
    "account_sid": "ACXXXX",
    "audio_sources": [
        "*"
    ],
    "audio_sources_excluded": [
        "advisor-audio"
    ],
    "bitrate": 0,
    "date_completed": null,
    "date_created": "2018-03-26T21:24:54Z",
    "date_deleted": null,
    "duration": 0,
    "format": "mp4",
    "links": {
        "media": "https://video.twilio.com/v1/Compositions/CJXXXX/Media"
    },
    "resolution": "1280x720",
    "room_sid": "RMXXXX",
    "sid": "CJXXXX",
    "size": 0,
    "status": "processing",
    "trim": true,
    "url": "https://video.twilio.com/v1/Compositions/CJXXXX",
    "video_layout": {
        "interviewed": {
            "cells_excluded": [],
            "height": 360,
            "max_columns": null,
            "max_rows": null,
            "reuse": "show_oldest",
            "video_sources": [
                "interviewed-video"
            ],
            "video_sources_excluded": [],
            "width": 480,
            "x_pos": 400,
            "y_pos": 180,
            "z_pos": 2
        },
        "interviewers": {
            "cells_excluded": [
                4
            ],
            "height": 720,
            "max_columns": 3,
            "max_rows": 3,
            "reuse": "show_newest",
            "video_sources": [
                "iterviewer-*"
            ],
            "video_sources_excluded": [],
            "width": 1260,
            "x_pos": 10,
            "y_pos": 0,
            "z_pos": 1
        }
    }
}
Compose a Room with mosaic layout

Example: Creating a Chess-Table Layout Composition

In this example we assume a Room with RoomSid=RMXXXX where a number of participants publish their audio and video tracks. For fun, we want to create the layout depicted on the following figure.

Chess-Table Composition Layout

Assuming that:

  • Your application credentials are (SKXXXX:your_api_key_secret)
  • You want to use mp4 as target format
  • You want to use HD resolution (1280x720)

You can create the desired Composition using the following:

Loading Code Samples...
Language
Response Format:
  • json
SDK Version:
  • 7.x
SDK Version:
  • 3.x
SDK Version:
  • 5.x
SDK Version:
  • 6.x
SDK Version:
  • 5.x
Format:
  • JSON
// NOTE: This example uses the next generation Twilio helper library - for more
// information on how to download and install this version, visit
// https://www.twilio.com/docs/libraries/node

// Find your credentials at twilio.com/console
const API_KEY_SID = 'SKXXXX';
const API_KEY_SECRET = 'your_api_key_secret';
const ACCOUNT_SID = 'ACXXXX';

const Twilio = require('twilio');

const client = new Twilio(API_KEY_SID, API_KEY_SECRET, {accountSid: ACCOUNT_SID});

client.video.compositions.
  create({
    roomSid: 'RMXXXX',
    audioSources: '*',
    videoLayout: {
      videoLayout: {
        chess_table : {
          x_pos: 10,
          y_pos: 0,
          width: 1260,
          height: 720,
          max_rows: 3,
          max_columns: 3,
          reuse: "show_newest",
          cells_excluded: [1,3,5,7],
          video_sources: ['*']
        }
      },
    },
    statusCallback: 'http://my.server.org/callbacks',
    resolution: '1280x720',
    format: 'mp4'
  })
  .then(composition =>{
    console.log('Created Composition with SID=' + composition.sid);
  });
<?php
// Get the PHP helper library from https://twilio.com/docs/libraries/php
require_once '/path/to/vendor/autoload.php'; // Loads the library
use Twilio\Rest\Client;

// Find your credentials at twilio.com/console
$apiKeySid = "SKXXXX";
$apiKeySecret = "your_auth_apiKeySecret";
$client = new Client($apiKeySid, $apiKeySecret);

$composition = $client->video->compositions->create([
    'roomSid' => 'RMXXXX',
    'audioSources' => '*',
    'videoLayout' =>  array(
                        'chess_table' => array(
                            'x_pos' => 10,
                            'y_pos' => 0,
                            'width' => 1260,
                            'height' => 720,
                            'max_rows' => 3,
                            'max_columns' => 3,
                            'reuse' => 'show_newest',
                            'cells_excluded' => array(1,3,5,7),
                            'video_sources' => array('*')
                        )
                      ),
    'statusCallback' => 'http://my.server.org/callbacks',
    'resolution' => '1280x720',
    'format' => 'mp4'
]);

echo $composition->sid;
# Download the helper library from https://www.twilio.com/docs/ruby/install
require 'rubygems'
require 'twilio-ruby'

# Find your credentials at twilio.com/console
api_key_sid = 'SKXXXX'
api_key_secret = 'your_api_key_secret'

@client = Twilio::REST::Client.new(api_key_sid, api_key_secret)

composition = @client.video.compositions.create(
  room_sid: 'RMXXXX',
  audio_sources: '*',
  video_layout: {
    chess_table: {
      x_pos: 10,
      y_pos: 0,
      width: 1260,
      height: 720,
      max_rows: 3,
      max_columns: 3,
      reuse: 'show_newest',
      cells_excluded: [1,3,5,7],
      video_sources: ['interviewed-video']
    }
  },
  status_callback: 'http://my.server.org/callbacks',
  resolution: '1280x720',
  format: 'mp4'
)

puts composition.sid
# Download the Python helper library from twilio.com/docs/python/install
from twilio.rest import Client
import json

# Find your credentials at twilio.com/console
api_key_sid = = 'SKXXXX'
api_key_secret = 'your_api_key_secret'
client = Client(api_key_sid, api_key_secret)

composition = client.video.compositions.create(
    room_sid = 'RMXXXX',
    audio_sources = '*',
    video_layout = {
                        "chess_table":{
                            "x_pos": 10,
                            "y_pos": 0,
                            "width": 1260,
                            "height": 720,
                            "max_rows": 3,
                            "max_columns": 3,
                            "reuse": "show_newest",
                            "cells_excluded": [1,3,5,7],
                            "video_sources":["*"]
                        }
                    },
    status_callback = 'http://my.server.org/callbacks',
    resolution = '1280x720',
    format='mp4')

print('Created composition with SID=%s' % (composition.sid))
// Install the Java helper library from twilio.com/docs/java/install
import com.twilio.Twilio;
import com.twilio.rest.video.v1.Composition;
import com.twilio.rest.video.v1.Composition.Format;

import com.fasterxml.jackson.databind.ObjectMapper;

public class ChessComposition{

  // Find your credentials at twilio.com/console
  public static final String ACCOUNT_SID = "ACXXXX";
  public static final String API_KEY_SID = "SKXXXX";
  public static final String API_KEY_SECRET = "your_api_key_secret";

  public static void main( String[] args ) throws IOException{
      // Initialize the client
      Twilio.init(API_KEY_SID, API_KEY_SECRET, ACCOUNT_SID);

      final String videoLayout =
                        "{"
                      + "   \"column\": {"
                      + "       \"x_pos\": 10,"
                      + "       \"y_pos\": 0,"
                      + "       \"width\": 1260,"
                      + "       \"height\": 720,"
                      + "       \"max_rows\": 3,"
                      + "       \"max_columns\": 3,"
                      + "       \"reuse\": \"show_newest\","
                      + "       \"cells_excluded\": [1,3,5,7]"
                      + "       \"video_sources\": [\"student-*\"]"
                      + "    }"
                      + "}";

      Composition composition = Composition.creator()
                  .setRoomSid("RMXXXX")
                  .setAudioSources("*")
                  .setVideoLayout(new ObjectMapper().readValue(videoLayout, HashMap.class))
                  .setStatusCallback("http://my.server.org/callbacks")
                  .setResolution("1280x720")
                  .setFormat(Format.MP4)
                  .create();

      System.out.println("Created composition with SID=" + composition.getSid());
  }
}
curl -X POST 'https://video.twilio.com/v1/Compositions' \
    -u 'SKXXXX:your_api_key_secret' \
    -F 'RoomSid=RMXXXX' \
    -F 'AudioSources=*' \
    -F 'StatusCallback=http://my.server.org/callbacks' \
    -F 'Resolution=1280x720' \
    -F 'Format=mp4' \
<<-EOF -F 'VideoLayout={
      "chess_table":{
        "x_pos":10,
        "y_pos":0,
        "width":1260,
        "height":720,
        "max_rows":3,
        "max_columns":3,
        "reuse":"show_newest",
        "cells_excluded":[1,3,5,7],
        "video_sources":["*"]
      }
    }'
EOF
{
    "account_sid": "ACXXXX",
    "audio_sources": [
        "*"
    ],
    "audio_sources_excluded": [],
    "bitrate": 0,
    "date_completed": null,
    "date_created": "2018-03-27T07:42:14Z",
    "date_deleted": null,
    "duration": 0,
    "format": "mp4",
    "links": {
        "media": "https://video.twilio.com/v1/Compositions/CJXXXX/Media"
    },
    "resolution": "1280x720",
    "room_sid": "RMXXXX",
    "sid": "CJXXXX",
    "size": 0,
    "status": "processing",
    "trim": true,
    "url": "https://video.twilio.com/v1/Compositions/CJXXXX",
    "video_layout": {
        "chess_table": {
            "cells_excluded": [
                1,
                3,
                5,
                7
            ],
            "height": 720,
            "max_columns": 3,
            "max_rows": 3,
            "reuse": "show_oldest",
            "video_sources": [
                "*"
            ],
            "video_sources_excluded": [],
            "width": 1260,
            "x_pos": 10,
            "y_pos": 0,
            "z_pos": 0
        }
    }
}
Compose a Room with a chess-table like layout

Getting compositions

Example: Get a Composition Instance Resource

For executing this example you need:

  • Your application credentials (SKXXXX:your_api_key_secret)
  • The CompositionSid (CJXXXX)
Loading Code Samples...
Language
Response Format:
  • json
SDK Version:
  • 7.x
SDK Version:
  • 3.x
SDK Version:
  • 5.x
SDK Version:
  • 6.x
SDK Version:
  • 5.x
Format:
  • JSON
// NOTE: This example uses the next generation Twilio helper library - for more
// information on how to download and install this version, visit
// https://www.twilio.com/docs/libraries/node

const apiKeySid = 'SKXXXX';
const apiKeySecret = 'your_api_key_secret';
const accountSid = 'ACXXXX';
const Twilio = require('twilio');

const client = new Twilio(apiKeySid, apiKeySecret, {accountSid: accountSid});

deleted = client.video.compositions('CJXXXX')
  .fetch()
  .then(composition =>{
    console.log('Read Composition with SID=' + composition.sid);
  });

console.log(deleted)
<?php
// Get the PHP helper library from https://twilio.com/docs/libraries/php
require_once '/path/to/vendor/autoload.php'; // Loads the library
use Twilio\Rest\Client;

// Find your credentials at twilio.com/console
$apiKeySid = "SKXXXX";
$apiKeySecret = "your_auth_apiKeySecret";
$client = new Client($apiKeySid, $apiKeySecret);

$composition = $client->video->compositions("GJXXXX")
    ->fetch();

echo $composition.sid
# Download the helper library from https://www.twilio.com/docs/ruby/install
require 'rubygems'
require 'twilio-ruby'

# Find your credentials at twilio.com/console
api_key_sid = 'SKXXXX'
api_key_secret = 'your_api_key_secret'

@client = Twilio::REST::Client.new(api_key_sid, api_key_secret)

composition = @client.video.compositions(CJXXXX)
    .fetch()

puts composition.sid
# Download the Python helper library from twilio.com/docs/python/install
from twilio.rest import Client

# Your Account Sid and Auth Token from twilio.com/console
api_key_sid = = 'SKXXXX'
api_key_secret = 'your_api_key_secret'
client = Client(api_key_sid, api_key_secret)

composition = client.video\
                    .compositions('CJXXXX')\
                    .fetch()

print('Read Composition with SID=%s' % (composition.sid))
// Install the Java helper library from twilio.com/docs/java/install
import com.twilio.Twilio;
import com.twilio.rest.video.v1.Composition;
import com.twilio.rest.video.v1.Composition.Format;

public class GetComposition{

  // Find your credentials at twilio.com/console
  public static final String ACCOUNT_SID = "ACXXXX";
  public static final String API_KEY_SID = "SKXXXX";
  public static final String API_KEY_SECRET = "your_api_key_secret";

  public static void main( String[] args ) throws IOException{
      // Initialize the client
      Twilio.init(API_KEY_SID, API_KEY_SECRET, ACCOUNT_SID);

      Composition composition = Composition.fetcher("CJXXXX")
                .fetch();

      System.out.println("Read composition with SID=" + composition.getSid());
  }
}
curl -X GET https://video.twilio.com/v1/Compositions/CJXXXX \
    -u 'SKXXXX:your_api_key_secret'
{
    "account_sid": "ACXXXX",
    "audio_sources": [
        "PAXXXX"
    ],
    "audio_sources_excluded": [],
    "bitrate": 500,
    "date_completed": "2018-03-26T13:36:35Z",
    "date_created": "2018-03-26T13:26:28Z",
    "date_deleted": null,
    "duration": 15,
    "format": "mp4",
    "links": {
        "media": "https://video.twilio.com/v1/Compositions/CJXXXX/Media"
    },
    "resolution": "1280x720",
    "room_sid": "RMXXXX",
    "sid": "CJXXXX",
    "size": 283500000,
    "status": "completed",
    "trim": true,
    "url": "https://video.twilio.com/v1/Compositions/CJXXXX",
    "video_layout": {
        "single": {
            "cells_excluded": [],
            "height": null,
            "max_columns": null,
            "max_rows": null,
            "reuse": "show_oldest",
            "video_sources": [
                "PAXXXX"
            ],
            "video_sources_excluded": [],
            "width": null,
            "x_pos": 0,
            "y_pos": 0,
            "z_pos": 0
        }
    }
}
Get a Composition Instance Resource

Example: List a Page of Completed Compositions

For executing this example you need:

  • Your application credentials (SKXXXX:your_api_key_secret)
Loading Code Samples...
Language
Response Format:
  • json
SDK Version:
  • 7.x
SDK Version:
  • 3.x
SDK Version:
  • 5.x
SDK Version:
  • 6.x
SDK Version:
  • 5.x
Format:
  • JSON
// NOTE: This example uses the next generation Twilio helper library - for more
// information on how to download and install this version, visit
// https://www.twilio.com/docs/libraries/node

const apiKeySid = 'SKXXXX';
const apiKeySecret = 'your_api_key_secret';
const accountSid = 'ACXXXX';
const Twilio = require('twilio');

const client = new Twilio(apiKeySid, apiKeySecret, {accountSid: accountSid});

client.video.compositions.
  list({
    status: 'completed'
  })
  .then(compositions =>{
    console.log("Found " + compositions.length + " compositions.");
    compositions.forEach(function(composition){
      console.log('Read compositionSid=' + composition.sid);
    });
  });
<?php
// Get the PHP helper library from https://twilio.com/docs/libraries/php
require_once '/path/to/vendor/autoload.php'; // Loads the library
use Twilio\Rest\Client;

// Find your credentials at twilio.com/console
$apiKeySid = "SKXXXX";
$apiKeySecret = "your_auth_apiKeySecret";
$client = new Client($apiKeySid, $apiKeySecret);

$compositions = $client->video->compositions
    ->read([
      'status' => 'completed'
    ]);

foreach ($compositions as $c) {
    echo $c->sid;
}
# Download the helper library from https://www.twilio.com/docs/ruby/install
require 'rubygems'
require 'twilio-ruby'

# Find your credentials at twilio.com/console
api_key_sid = 'SKXXXX'
api_key_secret = 'your_api_key_secret'

@client = Twilio::REST::Client.new(api_key_sid, api_key_secret)

compositions = @client.video.compositions
                            .list(
                              status: 'completed'
                            )

compositions.each do |c|
  puts c.sid
end
# Download the Python helper library from twilio.com/docs/python/install
from twilio.rest import Client

# Your Account Sid and Auth Token from twilio.com/console
api_key_sid = = 'SKXXXX'
api_key_secret = 'your_api_key_secret'
client = Client(api_key_sid, api_key_secret)

compositions = client.video\
                    .compositions\
                    .list(status='completed')

for composition in compositions:
    print('Read compositionSid=%s' % (composition.sid))
// Install the Java helper library from twilio.com/docs/java/install
import com.twilio.Twilio;
import com.twilio.rest.video.v1.Composition;
import com.twilio.rest.video.v1.Composition.Format;
import com.twilio.rest.video.v1.Composition.Status;

public class GetCompositionList{

  // Find your credentials at twilio.com/console
  public static final String ACCOUNT_SID = "ACXXXX";
  public static final String API_KEY_SID = "SKXXXX";
  public static final String API_KEY_SECRET = "your_api_key_secret";

  public static void main( String[] args ) throws IOException{
      // Initialize the client
      Twilio.init(API_KEY_SID, API_KEY_SECRET, ACCOUNT_SID);

      ResourceSet<Composition> compositions = Composition.reader()
         		.setStatus(Status.COMPLETED)
         		.read();

      for(Composition c : compositions){
        System.out.println("Read Composition with SID=" + c.getSid());
      }
  }
}
curl -X GET https://video.twilio.com/v1/Compositions?Status=completed \
    -u 'SKXXXX:your_api_key_secret'
{
    "compositions": [
        {
            "account_sid": "ACXXXX",
            "audio_sources": [
                "PAXXXX"
            ],
            "audio_sources_excluded": [],
            "bitrate": 500,
            "date_completed": "2018-03-26T13:36:35Z",
            "date_created": "2018-03-26T13:26:28Z",
            "date_deleted": null,
            "duration": 15,
            "format": "mp4",
            "links": {
                "media": "https://video.twilio.com/v1/Compositions/CJXXXX/Media"
            },
            "resolution": "1280x720",
            "room_sid": "RMXXXX",
            "sid": "CJXXXX",
            "size": 283500000,
            "status": "completed",
            "trim": true,
            "url": "https://video.twilio.com/v1/Compositions/CJXXXX",
            "video_layout": {
                "single": {
                    "cells_excluded": [],
                    "height": null,
                    "max_columns": null,
                    "max_rows": null,
                    "reuse": "show_oldest",
                    "video_sources": [
                        "PAXXXX"
                    ],
                    "video_sources_excluded": [],
                    "width": null,
                    "x_pos": 0,
                    "y_pos": 0,
                    "z_pos": 0
                }
            }
        },
        {
            "account_sid": "ACXXXX",
            "audio_sources": [
                "MTBBBB"
            ],
            "audio_sources_excluded": [],
            "bitrate": 8322,
            "date_completed": "2018-03-26T17:22:01Z",
            "date_created": "2018-03-26T15:16:14Z",
            "date_deleted": null,
            "duration": 3600,
            "format": "mp4",
            "links": {
                "media": "https://video.twilio.com/v1/Compositions/CJXXXX/Media"
            },
            "resolution": "1280x720",
            "room_sid": "RMXXXX",
            "sid": "CJXXXX",
            "size": 3744900000,
            "status": "completed",
            "trim": true,
            "url": "https://video.twilio.com/v1/Compositions/CJXXXX",
            "video_layout": {
                "focus": {
                    "cells_excluded": [],
                    "height": null,
                    "max_columns": null,
                    "max_rows": null,
                    "reuse": "show_oldest",
                    "video_sources": [
                        "screen-presentation"
                    ],
                    "video_sources_excluded": [],
                    "width": null,
                    "x_pos": 0,
                    "y_pos": 0,
                    "z_pos": 1
                },
                "pip": {
                    "cells_excluded": [],
                    "height": 200,
                    "max_columns": null,
                    "max_rows": null,
                    "reuse": "show_oldest",
                    "video_sources": [
                        "MTBBBB"
                    ],
                    "video_sources_excluded": [],
                    "width": 300,
                    "x_pos": 900,
                    "y_pos": 50,
                    "z_pos": 2
                }
            }
        }
    ],
    "meta": {
        "first_page_url": "https://video.twilio.com/v1/Compositions?Status=completed&PageSize=50&Page=0",
        "key": "compositions",
        "next_page_url": null,
        "page": 0,
        "page_size": 50,
        "previous_page_url": null,
        "url": "https://video.twilio.com/v1/Compositions?status=completed&PageSize=50&Page=0"
    }
}
List all completed Compositions

Example: List all Compositions for a given Room

For executing this example you need:

  • Your application credentials (SKXXXX:your_api_key_secret)
  • The target RoomSid (RMXXXX)
Loading Code Samples...
Language
Response Format:
  • json
SDK Version:
  • 7.x
SDK Version:
  • 3.x
SDK Version:
  • 5.x
SDK Version:
  • 6.x
SDK Version:
  • 5.x
Format:
  • JSON
// NOTE: This example uses the next generation Twilio helper library - for more
// information on how to download and install this version, visit
// https://www.twilio.com/docs/libraries/node

const apiKeySid = 'SKXXXX';
const apiKeySecret = 'your_api_key_secret';
const accountSid = 'ACXXXX';
const Twilio = require('twilio');

const client = new Twilio(apiKeySid, apiKeySecret, {accountSid: accountSid});

client.video.compositions.
  list({
    roomSid: 'RMXXXX'
  })
  .then(compositions =>{
    console.log("Found " + compositions.length + " compositions.");
    compositions.forEach(function(composition){
      console.log('Read compositionSid=' + composition.sid);
    });
  });
<?php
// Get the PHP helper library from https://twilio.com/docs/libraries/php
require_once '/path/to/vendor/autoload.php'; // Loads the library
use Twilio\Rest\Client;

// Find your credentials at twilio.com/console
$apiKeySid = "SKXXXX";
$apiKeySecret = "your_auth_apiKeySecret";
$client = new Client($apiKeySid, $apiKeySecret);

$compositions = $client->video->compositions
    ->read([
      'roomSid' => 'RMXXXX'
    ]);

foreach ($compositions as $c) {
    echo $c->sid;
}
# Download the helper library from https://www.twilio.com/docs/ruby/install
require 'rubygems'
require 'twilio-ruby'

# Find your credentials at twilio.com/console
api_key_sid = 'SKXXXX'
api_key_secret = 'your_api_key_secret'

@client = Twilio::REST::Client.new(api_key_sid, api_key_secret)

compositions = @client.video.compositions
                            .list(
                              room_sid: 'RMXXXX'
                            )

compositions.each do |c|
  puts c.sid
end
# Download the Python helper library from twilio.com/docs/python/install
from twilio.rest import Client

# Your Account Sid and Auth Token from twilio.com/console
api_key_sid = = 'SKXXXX'
api_key_secret = 'your_api_key_secret'
client = Client(api_key_sid, api_key_secret)

compositions = client.video\
                    .compositions\
                    .list(room_sid='RMXXXX')

for composition in compositions:
    print('Read compositionSid=%s' % (composition.sid))
// Install the Java helper library from twilio.com/docs/java/install
import com.twilio.Twilio;
import com.twilio.rest.video.v1.Composition;
import com.twilio.rest.video.v1.Composition.Format;
import com.twilio.rest.video.v1.Composition.Status;

public class GetCompositionList{

  // Find your credentials at twilio.com/console
  public static final String ACCOUNT_SID = "ACXXXX";
  public static final String API_KEY_SID = "SKXXXX";
  public static final String API_KEY_SECRET = "your_api_key_secret";

  public static void main( String[] args ) throws IOException{
      // Initialize the client
      Twilio.init(API_KEY_SID, API_KEY_SECRET, ACCOUNT_SID);

      ResourceSet<Composition> compositions = Composition.reader()
              .setRoomSid("RMXXXX")
              .read();

      for(Composition c : compositions){
        System.out.println("Read Composition with SID=" + c.getSid());
      }
  }
}
curl -X GET https://video.twilio.com/v1/Compositions?RoomSid=completed \
    -u 'SKXXXX:your_api_key_secret'
{
    "compositions": [
        {
            "account_sid": "ACXXXX",
            "audio_sources": [
                "PAXXXX"
            ],
            "audio_sources_excluded": [],
            "bitrate": 500,
            "date_completed": "2018-03-26T13:36:35Z",
            "date_created": "2018-03-26T13:26:28Z",
            "date_deleted": null,
            "duration": 15,
            "format": "mp4",
            "links": {
                "media": "https://video.twilio.com/v1/Compositions/CJXXXX/Media"
            },
            "resolution": "1280x720",
            "room_sid": "RMXXXX",
            "sid": "CJXXXX",
            "size": 283500000,
            "status": "completed",
            "trim": true,
            "url": "https://video.twilio.com/v1/Compositions/CJXXXX",
            "video_layout": {
                "single": {
                    "cells_excluded": [],
                    "height": null,
                    "max_columns": null,
                    "max_rows": null,
                    "reuse": "show_oldest",
                    "video_sources": [
                        "PAXXXX"
                    ],
                    "video_sources_excluded": [],
                    "width": null,
                    "x_pos": 0,
                    "y_pos": 0,
                    "z_pos": 0
                }
            }
        }
    ],
    "meta": {
        "first_page_url": "https://video.twilio.com/v1/Compositions?Status=completed&PageSize=50&Page=0",
        "key": "compositions",
        "next_page_url": null,
        "page": 0,
        "page_size": 50,
        "previous_page_url": null,
        "url": "https://video.twilio.com/v1/Compositions?status=completed&PageSize=50&Page=0"
    }
}
List all Compositions for a Room SID

Example: Get a Composition Media File

For executing this example you need:

  • Your application credentials (SKXXXX:your_api_key_secret)
  • The CompositionSid (CJXXXX)
  • In this example we also specify a Ttl of 6000 seconds.
Loading Code Samples...
Language
Response Format:
  • json
SDK Version:
  • 7.x
SDK Version:
  • 3.x
SDK Version:
  • 5.x
SDK Version:
  • 6.x
SDK Version:
  • 5.x
Format:
  • JSON
// NOTE: This example uses the next generation Twilio helper library - for more
// information on how to download and install this version, visit
// https://www.twilio.com/docs/libraries/node

const apiKeySid = 'SKXXXX';
const apiKeySecret = 'your_api_key_secret';
const accountSid = 'ACXXXX';

const Twilio = require('twilio');
const request = require('request');

const client = new Twilio(API_KEY_SID, API_KEY_SECRET, {accountSid: ACCOUNT_SID});

const compositionSid = 'CJXXXX';
const uri ='https://video.twilio.com/v1/Compositions/' + compositionSid + '/Media?Ttl=6000';

client.request({
  method: 'GET',
  uri: uri
})
.then(response =>{
  const mediaLocation = JSON.parse(response.body).redirect_to;

  // For example, download the media to a local file
  var file = fs.createWriteStream('myFile.mp4');
  var r = request(mediaLocation)
  r.on('response', (res) =>{
    res.pipe(file)
  });
})
.catch(error =>{
  console.log("Error fetching /Media resource " + error);
});
<?php
// Get the PHP helper library from https://twilio.com/docs/libraries/php
require_once '/path/to/vendor/autoload.php'; // Loads the library
use Twilio\Rest\Client;

// Find your credentials at twilio.com/console
$apiKeySid = "SKXXXX";
$apiKeySecret = "your_auth_apiKeySecret";
$client = new Client($apiKeySid, $apiKeySecret);

$compositionSid = "CJXXXX";
$uri = "https://video.twilio.com/v1/Compositions/$compositionSid/Media?Ttl=6000";
$response = $client->request("GET", $uri);
$mediaLocation = $response->getContent()["redirect_to"];

// For example, download media to a local file
file_put_contents("myFile.mp4", fopen($mediaLocation, 'r'));
# Download the helper library from https://www.twilio.com/docs/ruby/install
require 'twilio-ruby'
require 'net/http'
require 'open-uri'

# Find your credentials at twilio.com/console
api_key_sid = 'SKXXXX'
api_key_secret = 'your_api_key_secret'

client = Twilio::REST::Client.new(api_key_sid, api_key_secret)

composition_sid = 'CJXXXX'

uri = "https://video.twilio.com/v1/Compositions/#{composition_sid}/Media?Ttl=6000"

response = client.request("video.twilio.com", 433, 'GET', uri)

media_location = response.body['redirect_to']
# For example, write the composition media to a local file
open('myFile.mp4', "wb") do |file|
  file << open(media_location).read
end
# Download the Python helper library from twilio.com/docs/python/install
import json
from urllib.request import urlopen

from twilio.rest import Client

# Your Account Sid and Auth Token from twilio.com/console
api_key_sid = = 'SKXXXX'
api_key_secret = 'your_api_key_secret'
client = Client(api_key_sid, api_key_secret)

composition_sid = 'CXXXX'
uri = 'https://video.twilio.com/v1/Compositions/{}/Media?Ttl=6000'.format(composition_sid)
response = client.request('GET', uri)
media_location = json.loads(response.text).get('redirect_to')

# For example, download the media to a local file
local_file = open('myFile.mp4', 'w')
local_file.write(urlopen(media_location).read())
// Install the Java helper library from twilio.com/docs/java/install
import com.twilio.Twilio;
import com.twilio.rest.video.v1.Composition;
import com.twilio.rest.video.v1.Composition.Format;

public class GetCompositionMedia{

  // Find your credentials at twilio.com/console
  public static final String API_KEY_SID = "SKXXXX";
  public static final String API_KEY_SECRET = "your_api_key_secret";

  public static void main( String[] args ) throws IOException{
    // Disable HttpClient follow redirect by default
    HttpClientBuilder clientBuilder = HttpClientBuilder.create();
    clientBuilder.disableRedirectHandling();

    // Initialize the client
    TwilioRestClient restClient = new TwilioRestClient
        .Builder(API_KEY_SID, API_KEY_SECRET)
        .httpClient(new NetworkHttpClient(clientBuilder))
        .build();

    // Retrieve media location
    String compositionSid = "CJXXXX";
    Request request = new Request(
        HttpMethod.GET,
        Domains.VIDEO.toString(),
        "/v1/Compositions/" + compositionSid + "/Media?Ttl=6000",
        restClient.getRegion());

    Response response = restClient.request(request);
    JSONObject json = new JSONObject(response.getContent());
    String mediaLocation = json.getString("redirect_to");

    // For example, download the media to a local file
    FileUtils.copyURLToFile(new URL(mediaLocation), new File("myFile.mp4"));
  }
}
curl -X GET 'https://video.twilio.com/v1/Composer/CJXXXX/Media?Ttl=6000' \
     -u 'SKXXXX:your_api_key_secret'
{
  "redirect_to":
  "https://com-twilio-us1-video-composition.s3.amazonaws.com/ACXXXX/CJXXXX.webm?
  X-Amz-Security-Token=XXXXX&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=XXXXXXXXXXXXXXX&
  X-Amz-SignedHeaders=host&X-Amz-Expires=6000&X-Amz-Credential=XXXX&X-Amz-Signature=XXXXX"
}
Get a Composition Media File

Deleting Compositions

Example: Delete a Composition Instance

For executing this example you need:

  • Your application credentials (SKXXXX:your_api_key_secret)
  • The Composition SID to delete (CJXXXX)
Loading Code Samples...
Language
Response Format:
  • json
SDK Version:
  • 7.x
SDK Version:
  • 3.x
SDK Version:
  • 5.x
SDK Version:
  • 6.x
SDK Version:
  • 5.x
Format:
  • JSON
// NOTE: This example uses the next generation Twilio helper library - for more
// information on how to download and install this version, visit
// https://www.twilio.com/docs/libraries/node

const apiKeySid = 'SKXXXX';
const apiKeySecret = 'your_api_key_secret';
const accountSid = 'ACXXXX';
const Twilio = require('twilio');

const client = new Twilio(apiKeySid, apiKeySecret, {accountSid: accountSid});

client.video.compositions('CJXXXX').
  remove()
  .then(response =>{
    console.log('Composition removed');
  });
<?php
// Get the PHP helper library from https://twilio.com/docs/libraries/php
require_once '/path/to/vendor/autoload.php'; // Loads the library
use Twilio\Rest\Client;

// Find your credentials at twilio.com/console
$apiKeySid = "SKXXXX";
$apiKeySecret = "your_auth_apiKeySecret";
$client = new Client($apiKeySid, $apiKeySecret);

$deleted = $client->video->compositions("CJXXXX")
    ->delete();

echo $deleted;
# Download the helper library from https://www.twilio.com/docs/ruby/install
require 'rubygems'
require 'twilio-ruby'

# Find your credentials at twilio.com/console
api_key_sid = 'SKXXXX'
api_key_secret = 'your_api_key_secret'

@client = Twilio::REST::Client.new(api_key_sid, api_key_secret)

deleted = @client.video.compositions(CJXXXX)
    .delete()

puts deleted
# Download the Python helper library from twilio.com/docs/python/install
from twilio.rest import Client

# Your Account Sid and Auth Token from twilio.com/console
api_key_sid = = 'SKXXXX'
api_key_secret = 'your_api_key_secret'
client = Client(api_key_sid, api_key_secret)

did_delete = client.video\
                    .compositions('CJXXXX')\
                    .delete()

if(did_delete):
    print('Composition removed')
// Install the Java helper library from twilio.com/docs/java/install
import com.twilio.Twilio;
import com.twilio.rest.video.v1.Composition;
import com.twilio.rest.video.v1.Composition.Format;

public class DeleteComposition{

  // Find your credentials at twilio.com/console
  public static final String ACCOUNT_SID = "ACXXXX";
  public static final String API_KEY_SID = "SKXXXX";
  public static final String API_KEY_SECRET = "your_api_key_secret";

  public static void main( String[] args ) throws IOException{
      // Initialize the client
      Twilio.init(API_KEY_SID, API_KEY_SECRET, ACCOUNT_SID);

      boolean didDelete = Composition.deleter("CJXXXX")
          .delete();

      System.out.println(didDelete);
  }
}
curl -X DELETE 'https://video.twilio.com/v1/Compositions/CJXXXX' \
  -u 'SKXXXX:your_api_key_secret'
A successful request returns an HTTP status code 204 and an empty body
Delete a Composition instance

Known issues and limitations

The following are known issues. We are working hard for having them fixed:

  • The only supported formats are MP4 and WebM. More formats will be added shortly.

Need some help?

We all do sometimes; code is hard. Get help now from our support team, or lean on the wisdom of the crowd browsing the Twilio tag on Stack Overflow.

Loading Code Samples...
Response Format:
  • json
SDK Version:
  • 7.x
SDK Version:
  • 3.x
SDK Version:
  • 5.x
SDK Version:
  • 6.x
SDK Version:
  • 5.x
Format:
  • JSON
// NOTE: This example uses the next generation Twilio helper library - for more
// information on how to download and install this version, visit
// https://www.twilio.com/docs/libraries/node

// Find your credentials at twilio.com/console
const API_KEY_SID = 'SKXXXX';
const API_KEY_SECRET = 'your_api_key_secret';
const ACCOUNT_SID = 'ACXXXX';

const Twilio = require('twilio');

const client = new Twilio(API_KEY_SID, API_KEY_SECRET, {accountSid: ACCOUNT_SID});

client.video.compositions.
  create({
    roomSid: 'RMXXXX',
    videoLayout: {
      transcode: {
        video_sources: ['RTXXXX']
      }
    },
    statusCallback: 'http://my.server.org/callbacks',
    format: 'mp4'
  })
  .then(composition =>{
    console.log("Created Composition with SID=" + composition.sid);
  })
<?php
// Get the PHP helper library from https://twilio.com/docs/libraries/php
require_once '/path/to/vendor/autoload.php'; // Loads the library
use Twilio\Rest\Client;

// Find your credentials at twilio.com/console
$apiKeySid = "SKXXXX";
$apiKeySecret = "your_auth_apiKeySecret";
$client = new Client($apiKeySid, $apiKeySecret);

$composition = $client->video->compositions->create([
    'roomSid' => 'RMXXXX',
    'videoLayout' =>  array(
                        'transcode' => array (
                          'video_sources' => array('RTXXXX')
                        )
                      ),
    'statusCallback' => 'http://my.server.org/callbacks',
    'format' => 'mp4'
]);

echo $composition->sid;
# Download the helper library from https://www.twilio.com/docs/ruby/install
require 'rubygems'
require 'twilio-ruby'

# Find your credentials at twilio.com/console
api_key_sid = 'SKXXXX'
api_key_secret = 'your_api_key_secret'

@client = Twilio::REST::Client.new(api_key_sid, api_key_secret)

composition = @client.video.compositions.create(
  room_sid: 'RMXXXX',
  video_layout: {
    transcode: {
      video_sources: ['RTXXXX']
    }
  },
  status_callback: 'http://my.server.org/callbacks',
  format: 'mp4'
)

puts composition.sid
#Download the Python helper library from twilio.com/docs/python/install
from twilio.rest import Client
import json

# Find your credentials at twilio.com/console
api_key_sid = = 'SKXXXX'
api_key_secret = 'your_api_key_secret'
client = Client(api_key_sid, api_key_secret)

composition = client.video.compositions.create(
    room_sid = 'RMXXXX',
    video_layout = {
                        'transcode': {
                            'video_sources': ['RTXXXX']
                        }
                   },
    status_callback = 'http://my.server.org/callbacks',
    format='mp4')

print('Created composition with SID=%s' % (composition.sid))
// Install the Java helper library from twilio.com/docs/java/install
import com.twilio.Twilio;
import com.twilio.rest.video.v1.Composition;
import com.twilio.rest.video.v1.Composition.Format;

import com.fasterxml.jackson.databind.ObjectMapper;

public class TranscodeVideoRecording{

  // Find your credentials at twilio.com/console
  public static final String ACCOUNT_SID = "ACXXXX";
  public static final String API_KEY_SID = "SKXXXX";
  public static final String API_KEY_SECRET = "your_api_key_secret";

  public static void main( String[] args ) throws IOException{
      // Initialize the client
      Twilio.init(API_KEY_SID, API_KEY_SECRET, ACCOUNT_SID);

      final String videoLayout =
        								  "{"
        								+ "   \"transcode\": {"
        								+ "       \"video_sources\":[\"RTXXXX\"]"
        								+ "    }"
        								+ "}";

      Composition composition = Composition.creator()
        					.setRoomSid("RMXXXX")
        					.setVideoLayout(new ObjectMapper().readValue(videoLayout, HashMap.class))
        					.setStatusCallback("http://my.server.org/callbacks")
        					.setFormat(Format.MP4)
        					.create();

      System.out.println("Created composition with SID=" + composition.getSid());
  }
}
curl -X POST 'https://video.twilio.com/v1/Compositions' \
    -u 'SKXXXX:your_api_key_secret' \
    -F 'RoomSid=RMXXXX' \
    -F 'StatusCallback=http://my.server.org/callbacks' \
    -F 'Format=mp4' \
<<-EOF -F 'VideoLayout={
      "transcode":{
        "video_sources":["RTXXXX"]
      }
    }'
EOF
{
    "account_sid": "ACXXXX",
    "audio_sources": [],
    "audio_sources_excluded": [],
    "bitrate": 0,
    "date_completed": null,
    "date_created": "2018-03-26T13:01:04Z",
    "date_deleted": null,
    "duration": 0,
    "format": "mp4",
    "links": {
        "media": "https://video.twilio.com/v1/Compositions/CJXXXX/Media"
    },
    "resolution": "640x480",
    "room_sid": "RMXXXX",
    "sid": "CJXXXX",
    "size": 0,
    "status": "processing",
    "trim": true,
    "url": "https://video.twilio.com/v1/Compositions/CJXXXX",
    "video_layout": {
        "transcode": {
            "cells_excluded": [],
            "height": null,
            "max_columns": null,
            "max_rows": null,
            "reuse": "show_oldest",
            "video_sources": [
                "RTXXXX"
            ],
            "video_sources_excluded": [],
            "width": null,
            "x_pos": 0,
            "y_pos": 0,
            "z_pos": 0
        }
    }
}
Response Format:
  • json
SDK Version:
  • 7.x
SDK Version:
  • 3.x
SDK Version:
  • 5.x
SDK Version:
  • 6.x
SDK Version:
  • 5.x
Format:
  • JSON
// NOTE: This example uses the next generation Twilio helper library - for more
// information on how to download and install this version, visit
// https://www.twilio.com/docs/libraries/node

// Find your credentials at twilio.com/console
const API_KEY_SID = 'SKXXXX';
const API_KEY_SECRET = 'your_api_key_secret';
const ACCOUNT_SID = 'ACXXXX';

const Twilio = require('twilio');

const client = new Twilio(API_KEY_SID, API_KEY_SECRET, {accountSid: ACCOUNT_SID});

client.video.compositions.
  create({
    roomSid: 'RMXXXX',
    audioSources: 'RTXXXX',
    statusCallback: 'http://my.server.org/callbacks',
    format: 'mp4'
  })
  .then(composition =>{
    console.log('Created Composition with SID=' + composition.sid);
  });
<?php
// Get the PHP helper library from https://twilio.com/docs/libraries/php
require_once '/path/to/vendor/autoload.php'; // Loads the library
use Twilio\Rest\Client;

// Find your credentials at twilio.com/console
$apiKeySid = "SKXXXX";
$apiKeySecret = "your_auth_apiKeySecret";
$client = new Client($apiKeySid, $apiKeySecret);

$composition = $client->video->compositions->create([
    'roomSid' => 'RMXXXX',
    'audioSources' => 'RTXXXX',
    'statusCallback' => 'http://my.server.org/callbacks',
    'format' => 'mp4'
]);

echo $composition->sid;
# Download the helper library from https://www.twilio.com/docs/ruby/install
require 'rubygems'
require 'twilio-ruby'

# Find your credentials at twilio.com/console
api_key_sid = 'SKXXXX'
api_key_secret = 'your_api_key_secret'

@client = Twilio::REST::Client.new(api_key_sid, api_key_secret)

composition = @client.video.compositions.create(
  room_sid: 'RMXXXX',
  audio_sources: 'RTXXXX',
  status_callback: 'http://my.server.org/callbacks',
  format: 'mp4'
)

puts composition.sid
# Download the Python helper library from twilio.com/docs/python/install
from twilio.rest import Client

# Find your credentials at twilio.com/console
api_key_sid = = 'SKXXXX'
api_key_secret = 'your_api_key_secret'
client = Client(api_key_sid, api_key_secret)

composition = client.video.compositions.create(
    room_sid = 'RMXXXX',
    audio_sources = 'RTXXXX',
    status_callback = 'http://my.server.org/callbacks',
    format='mp4')

print('Created composition with SID=%s' % (composition.sid))
// Install the Java helper library from twilio.com/docs/java/install
import com.twilio.Twilio;
import com.twilio.rest.video.v1.Composition;
import com.twilio.rest.video.v1.Composition.Format;

public class TranscodeAudioRecording{

  // Find your credentials at twilio.com/console
  public static final String ACCOUNT_SID = "ACXXXX";
  public static final String API_KEY_SID = "SKXXXX";
  public static final String API_KEY_SECRET = "your_api_key_secret";

  public static void main( String[] args ) throws IOException{
      // Initialize the client
      Twilio.init(API_KEY_SID, API_KEY_SECRET, ACCOUNT_SID);

      Composition composition = Composition.creator()
        					.setRoomSid("RMXXXX")
        					.setAudioSources("RTXXXX")
        					.setStatusCallback("http://my.server.org/callbacks")
        					.setFormat(Format.MP4)
        					.create();

      System.out.println("Created composition with SID=" + composition.getSid());
  }
}
curl -X POST 'https://video.twilio.com/v1/Compositions' \
    -u 'SKXXXX:your_api_key_secret' \
    -F 'RoomSid=RMXXXX' \
    -F 'AudioSources=RTXXXX' \
    -F 'StatusCallback=http://my.server.org/callbacks' \
    -F 'Format=mp4'
{
    "account_sid": "ACXXXX",
    "audio_sources": [
        "RTXXXX"
    ],
    "audio_sources_excluded": [],
    "bitrate": 0,
    "date_completed": null,
    "date_created": "2018-03-26T13:15:11Z",
    "date_deleted": null,
    "duration": 0,
    "format": "mp4",
    "links": {
        "media": "https://video.twilio.com/v1/Compositions/CJXXXX/Media"
    },
    "resolution": "640x480",
    "room_sid": "RMXXXX",
    "sid": "CJXXXX",
    "size": 0,
    "status": "processing",
    "trim": true,
    "url": "https://video.twilio.com/v1/Compositions/CJXXXX",
    "video_layout": {}
}
Response Format:
  • json
SDK Version:
  • 7.x
SDK Version:
  • 3.x
SDK Version:
  • 5.x
SDK Version:
  • 6.x
SDK Version:
  • 5.x
Format:
  • JSON
// NOTE: This example uses the next generation Twilio helper library - for more
// information on how to download and install this version, visit
// https://www.twilio.com/docs/libraries/node

// Find your credentials at twilio.com/console
const API_KEY_SID = 'SKXXXX';
const API_KEY_SECRET = 'your_api_key_secret';
const ACCOUNT_SID = 'ACXXXX';

const Twilio = require('twilio');

const client = new Twilio(API_KEY_SID, API_KEY_SECRET, {accountSid: ACCOUNT_SID});

client.video.compositions.
  create({
    roomSid: 'RMXXXX',
    audioSources: 'PAXXXX',
    videoLayout: {
      single : {
        video_sources: ['PAXXXX']
      }
    },
    statusCallback: 'http://my.server.org/callbacks',
    format: 'mp4'
  })
  .then(composition =>{
    console.log('Created Composition with SID=' + composition.sid);
  });
<?php
// Get the PHP helper library from https://twilio.com/docs/libraries/php
require_once '/path/to/vendor/autoload.php'; // Loads the library
use Twilio\Rest\Client;

// Find your credentials at twilio.com/console
$apiKeySid = "SKXXXX";
$apiKeySecret = "your_auth_apiKeySecret";
$client = new Client($apiKeySid, $apiKeySecret);

$composition = $client->video->compositions->create([
    'roomSid' => 'RMXXXX',
    'audioSources' => 'PAXXXX',
    'videoLayout' =>  array(
                        'single' => array (
                          'video_sources' => array('PAXXXX')
                        )
                      ),
    'statusCallback' => 'http://my.server.org/callbacks',
    'format' => 'mp4'
]);

echo $composition->sid;
# Download the helper library from https://www.twilio.com/docs/ruby/install
require 'rubygems'
require 'twilio-ruby'

# Find your credentials at twilio.com/console
api_key_sid = 'SKXXXX'
api_key_secret = 'your_api_key_secret'

@client = Twilio::REST::Client.new(api_key_sid, api_key_secret)

composition = @client.video.compositions.create(
  room_sid: 'RMXXXX',
  audio_sources: 'PAXXXX',
  video_layout: {
    single: {
      video_sources: ['PAXXXX']
    }
  },
  status_callback: 'http://my.server.org/callbacks',
  format: 'mp4'
)

puts composition.sid
# Download the Python helper library from twilio.com/docs/python/install
from twilio.rest import Client
import json

# Find your credentials at twilio.com/console
api_key_sid = = 'SKXXXX'
api_key_secret = 'your_api_key_secret'
client = Client(api_key_sid, api_key_secret)

composition = client.video.compositions.create(
    room_sid = 'RMXXXX',
    audio_sources = 'PAXXXX',
    video_layout = {
                    'single': {
                        'video_sources': ['PAXXXX']
                    }
                   },
    status_callback = 'http://my.server.org/callbacks',
    format='mp4')

print('Created composition with SID=%s' % (composition.sid))
// Install the Java helper library from twilio.com/docs/java/install
import com.twilio.Twilio;
import com.twilio.rest.video.v1.Composition;
import com.twilio.rest.video.v1.Composition.Format;

import com.fasterxml.jackson.databind.ObjectMapper;

public class ParticipantComposition{

  // Find your credentials at twilio.com/console
  public static final String ACCOUNT_SID = "ACXXXX";
  public static final String API_KEY_SID = "SKXXXX";
  public static final String API_KEY_SECRET = "your_api_key_secret";

  public static void main( String[] args ) throws IOException{
      // Initialize the client
      Twilio.init(API_KEY_SID, API_KEY_SECRET, ACCOUNT_SID);

      final String videoLayout =
                        "{"
                     + "   \"single\": {"
                     + "       \"video_sources\":[\"PAXXXX\"]"
                     + "    }"
                     + "}";

      Composition composition = Composition.creator()
        					.setRoomSid("RMXXXX")
        					.setAudioSources("PAXXXX")
        					.setVideoLayout(new ObjectMapper().readValue(videoLayout, HashMap.class))
        					.setStatusCallback("http://my.server.org/callbacks")
        					.setFormat(Format.MP4)
        					.create();

      System.out.println("Created composition with SID=" + composition.getSid());
  }
}
curl -X POST 'https://video.twilio.com/v1/Compositions' \
    -u 'SKXXXX:your_api_key_secret' \
    -F 'RoomSid=RMXXXX' \
    -F 'AudioSources=PAXXXX' \
    -F 'StatusCallback=http://my.server.org/callbacks' \
    -F 'Format=mp4' \
<<-EOF -F 'VideoLayout={
      "single":{
        "video_sources":["PAXXXX"]
      }
    }'
EOF
{
    "account_sid": "ACXXXX",
    "audio_sources": [
        "PAXXXX"
    ],
    "audio_sources_excluded": [],
    "bitrate": 0,
    "date_completed": null,
    "date_created": "2018-03-26T13:26:28Z",
    "date_deleted": null,
    "duration": 0,
    "format": "mp4",
    "links": {
        "media": "https://video.twilio.com/v1/Compositions/CJXXXX/Media"
    },
    "resolution": "640x480",
    "room_sid": "RMXXXX",
    "sid": "CJXXXX",
    "size": 0,
    "status": "processing",
    "trim": true,
    "url": "https://video.twilio.com/v1/Compositions/CJXXXX",
    "video_layout": {
        "single": {
            "cells_excluded": [],
            "height": null,
            "max_columns": null,
            "max_rows": null,
            "reuse": "show_oldest",
            "video_sources": [
                "PAXXXX"
            ],
            "video_sources_excluded": [],
            "width": null,
            "x_pos": 0,
            "y_pos": 0,
            "z_pos": 0
        }
    }
}
Response Format:
  • json
SDK Version:
  • 7.x
SDK Version:
  • 3.x
SDK Version:
  • 5.x
SDK Version:
  • 6.x
SDK Version:
  • 5.x
Format:
  • JSON
// NOTE: This example uses the next generation Twilio helper library - for more
// information on how to download and install this version, visit
// https://www.twilio.com/docs/libraries/node

// Find your credentials at twilio.com/console
const API_KEY_SID = 'SKXXXX';
const API_KEY_SECRET = 'your_api_key_secret';
const ACCOUNT_SID = 'ACXXXX';

const Twilio = require('twilio');

const client = new Twilio(API_KEY_SID, API_KEY_SECRET, {accountSid: ACCOUNT_SID});

client.video.compositions.
  create({
    roomSid: 'RMXXXX',
    audioSources: '*',
    videoLayout: {
      single : {
        video_sources: ['PAXXXX']
      }
    },
    statusCallback: 'http://my.server.org/callbacks',
    format: 'mp4'
  })
  .then(composition =>{
    console.log('Created Composition with SID=' + composition.sid);
  });
<?php
// Get the PHP helper library from https://twilio.com/docs/libraries/php
require_once '/path/to/vendor/autoload.php'; // Loads the library
use Twilio\Rest\Client;

// Find your credentials at twilio.com/console
$apiKeySid = "SKXXXX";
$apiKeySecret = "your_auth_apiKeySecret";
$client = new Client($apiKeySid, $apiKeySecret);

$composition = $client->video->compositions->create([
    'roomSid' => 'RMXXXX',
    'audioSources' => '*',
    'videoLayout' =>  array(
                        'single' => array (
                          'video_sources' => array('PAXXXX')
                        )
                      ),
    'statusCallback' => 'http://my.server.org/callbacks',
    'format' => 'mp4'
]);

echo $composition->sid;
# Download the helper library from https://www.twilio.com/docs/ruby/install
require 'rubygems'
require 'twilio-ruby'

# Find your credentials at twilio.com/console
api_key_sid = 'SKXXXX'
api_key_secret = 'your_api_key_secret'

@client = Twilio::REST::Client.new(api_key_sid, api_key_secret)

composition = @client.video.compositions.create(
  room_sid: 'RMXXXX',
  audio_sources: '*',
  video_layout: {
    single: {
      video_sources: ['PAXXXX']
    }
  },
  status_callback: 'http://my.server.org/callbacks',
  format: 'mp4'
)

puts composition.sid
# Download the Python helper library from twilio.com/docs/python/install
from twilio.rest import Client
import json

# Find your credentials at twilio.com/console
api_key_sid = = 'SKXXXX'
api_key_secret = 'your_api_key_secret'
client = Client(api_key_sid, api_key_secret)

composition = client.video.compositions.create(\
    room_sid = 'RMXXXX',\
    audio_sources = '*',\
    video_layout = json.dumps({\
                    'single': {\
                        'video_sources': ['PAXXXX']\
                    }\
                   }),\
    status_callback = 'http://my.server.org/callbacks',\
    format='mp4')

print('Created composition with SID=%s' % (composition.sid))
// Install the Java helper library from twilio.com/docs/java/install
import com.twilio.Twilio;
import com.twilio.rest.video.v1.Composition;
import com.twilio.rest.video.v1.Composition.Format;

import com.fasterxml.jackson.databind.ObjectMapper;

public class ParticipantComposition{

  // Find your credentials at twilio.com/console
  public static final String ACCOUNT_SID = "ACXXXX";
  public static final String API_KEY_SID = "SKXXXX";
  public static final String API_KEY_SECRET = "your_api_key_secret";

  public static void main( String[] args ) throws IOException{
      // Initialize the client
      Twilio.init(API_KEY_SID, API_KEY_SECRET, ACCOUNT_SID);

      final String videoLayout =
                      "{"
                     + "   \"single\": {"
                     + "       \"video_sources\":[\"PAXXXX\"]"
                     + "    }"
                     + "}";

      Composition composition = Composition.creator()
                  .setRoomSid("RMXXXX")
                  .setAudioSources("*")
                  .setVideoLayout(new ObjectMapper().readValue(videoLayout, HashMap.class))
                  .setStatusCallback("http://my.server.org/callbacks")
                  .setFormat(Format.MP4)
                  .create();

      System.out.println("Created composition with SID=" + composition.getSid());
  }
}
curl -X POST 'https://video.twilio.com/v1/Compositions' \
    -u 'SKXXXX:your_api_key_secret' \
    -F 'RoomSid=RMXXXX' \
    -F 'AudioSources=*' \
    -F 'StatusCallback=http://my.server.org/callbacks' \
    -F 'Format=mp4' \
<<-EOF -F 'VideoLayout={
      "single":{
        "video_sources":["PAXXXX"]
      }
    }'
EOF
{
    "account_sid": "ACXXXX",
    "audio_sources": [
        "*"
    ],
    "audio_sources_excluded": [],
    "bitrate": 0,
    "date_completed": null,
    "date_created": "2018-03-26T13:44:11Z",
    "date_deleted": null,
    "duration": 0,
    "format": "mp4",
    "links": {
        "media": "https://video.twilio.com/v1/Compositions/CJXXXX/Media"
    },
    "resolution": "640x480",
    "room_sid": "RMXXXX",
    "sid": "CJXXXX",
    "size": 0,
    "status": "processing",
    "trim": true,
    "url": "https://video.twilio.com/v1/Compositions/CJXXXX",
    "video_layout": {
        "grid": {
            "cells_excluded": [],
            "height": null,
            "max_columns": null,
            "max_rows": null,
            "reuse": "show_oldest",
            "video_sources": [
                "*"
            ],
            "video_sources_excluded": [],
            "width": null,
            "x_pos": 0,
            "y_pos": 0,
            "z_pos": 0
        }
    }
}
Response Format:
  • json
SDK Version:
  • 7.x
SDK Version:
  • 3.x
SDK Version:
  • 5.x
SDK Version:
  • 6.x
SDK Version:
  • 5.x
Format:
  • JSON
// NOTE: This example uses the next generation Twilio helper library - for more
// information on how to download and install this version, visit
// https://www.twilio.com/docs/libraries/node

// Find your credentials at twilio.com/console
const API_KEY_SID = 'SKXXXX';
const API_KEY_SECRET = 'your_api_key_secret';
const ACCOUNT_SID = 'ACXXXX';

const Twilio = require('twilio');

const client = new Twilio(API_KEY_SID, API_KEY_SECRET, {accountSid: ACCOUNT_SID});

client.video.compositions.
  create({
    roomSid: 'RMXXXX',
    audioSources: '*',
    videoLayout: {
      grid : {
        video_sources: ['*']
      }
    },
    statusCallback: 'http://my.server.org/callbacks',
    format: 'mp4'
  })
  .then(composition =>{
    console.log('Created Composition with SID=' + composition.sid);
  });
<?php
// Get the PHP helper library from https://twilio.com/docs/libraries/php
require_once '/path/to/vendor/autoload.php'; // Loads the library
use Twilio\Rest\Client;

// Find your credentials at twilio.com/console
$apiKeySid = "SKXXXX";
$apiKeySecret = "your_auth_apiKeySecret";
$client = new Client($apiKeySid, $apiKeySecret);

$composition = $client->video->compositions->create([
    'roomSid' => 'RMXXXX',
    'audioSources' => '*',
    'videoLayout' =>  array(
                        'grid' => array (
                          'video_sources' => array('*')
                        )
                      ),
    'statusCallback' => 'http://my.server.org/callbacks',
    'format' => 'mp4'
]);

echo $composition->sid;
# Download the helper library from https://www.twilio.com/docs/ruby/install
require 'rubygems'
require 'twilio-ruby'

# Find your credentials at twilio.com/console
api_key_sid = 'SKXXXX'
api_key_secret = 'your_api_key_secret'

@client = Twilio::REST::Client.new(api_key_sid, api_key_secret)

composition = @client.video.compositions.create(
  room_sid: 'RMXXXX',
  audio_sources: '*',
  video_layout: {
    grid: {
      video_sources: ['*']
    }
  },
  status_callback: 'http://my.server.org/callbacks',
  format: 'mp4'
)

puts composition.sid
# Download the Python helper library from twilio.com/docs/python/install
from twilio.rest import Client
import json

# Find your credentials at twilio.com/console
api_key_sid = = 'SKXXXX'
api_key_secret = 'your_api_key_secret'
client = Client(api_key_sid, api_key_secret)

composition = client.video.compositions.create(
    room_sid = 'RMXXXX',
    audio_sources = '*',
    video_layout = {
                        'grid' : {
                            'video_sources': ['*']
                        }
                    },
    status_callback = 'http://my.server.org/callbacks',
    format='mp4')

print('Created composition with SID=%s' % (composition.sid))
// Install the Java helper library from twilio.com/docs/java/install
import com.twilio.Twilio;
import com.twilio.rest.video.v1.Composition;
import com.twilio.rest.video.v1.Composition.Format;

import com.fasterxml.jackson.databind.ObjectMapper;

public class GridComposition{

  // Find your credentials at twilio.com/console
  public static final String ACCOUNT_SID = "ACXXXX";
  public static final String API_KEY_SID = "SKXXXX";
  public static final String API_KEY_SECRET = "your_api_key_secret";

  public static void main( String[] args ) throws IOException{
      // Initialize the client
      Twilio.init(API_KEY_SID, API_KEY_SECRET, ACCOUNT_SID);

      final String videoLayout =
                       "{"
                     + "   \"grid\": {"
                     + "       \"video_sources\":[\"*\"]"
                     + "    }"
                     + "}";

      Composition composition = Composition.creator()
                  .setRoomSid("RMXXXX")
                  .setAudioSources("*")
                  .setVideoLayout(new ObjectMapper().readValue(videoLayout, HashMap.class))
                  .setStatusCallback("http://my.server.org/callbacks")
                  .setFormat(Format.MP4)
                  .create();

      System.out.println("Created composition with SID=" + composition.getSid());
  }
}
curl -X POST 'https://video.twilio.com/v1/Compositions' \
    -u 'SKXXXX:your_api_key_secret' \
    -F 'RoomSid=RMXXXX' \
    -F 'AudioSources=*' \
    -F 'StatusCallback=http://my.server.org/callbacks' \
    -F 'Format=mp4' \
<<-EOF -F 'VideoLayout={
      "grid":{
        "video_sources":["*"]
      }
    }'
EOF
{
    "account_sid": "ACXXXX",
    "audio_sources": [
        "*"
    ],
    "audio_sources_excluded": [],
    "bitrate": 0,
    "date_completed": null,
    "date_created": "2018-03-26T13:44:11Z",
    "date_deleted": null,
    "duration": 0,
    "format": "mp4",
    "links": {
        "media": "https://video.twilio.com/v1/Compositions/CJXXXX/Media"
    },
    "resolution": "640x480",
    "room_sid": "RMXXXX",
    "sid": "CJXXXX",
    "size": 0,
    "status": "processing",
    "trim": true,
    "url": "https://video.twilio.com/v1/Compositions/CJXXXX",
    "video_layout": {
        "grid": {
            "cells_excluded": [],
            "height": null,
            "max_columns": null,
            "max_rows": null,
            "reuse": "show_oldest",
            "video_sources": [
                "*"
            ],
            "video_sources_excluded": [],
            "width": null,
            "x_pos": 0,
            "y_pos": 0,
            "z_pos": 0
        }
    }
}
Response Format:
  • json
SDK Version:
  • 7.x
SDK Version:
  • 3.x
SDK Version:
  • 5.x
SDK Version:
  • 6.x
SDK Version:
  • 5.x
Format:
  • JSON
// NOTE: This example uses the next generation Twilio helper library - for more
// information on how to download and install this version, visit
// https://www.twilio.com/docs/libraries/node

// Find your credentials at twilio.com/console
const API_KEY_SID = 'SKXXXX';
const API_KEY_SECRET = 'your_api_key_secret';
const ACCOUNT_SID = 'ACXXXX';

const Twilio = require('twilio');

const client = new Twilio(API_KEY_SID, API_KEY_SECRET, {accountSid: ACCOUNT_SID});

client.video.compositions.
  create({
    roomSid: 'RMXXXX',
    videoLayout: {
      grid : {
        max_rows: 1,
        video_sources: [
          "RTAAAA",
          "MTBBBB",
          "teacher-webcast"
        ]
      }
    },
    statusCallback: 'http://my.server.org/callbacks',
    format: 'mp4'
  })
  .then(composition =>{
    console.log('Created Composition with SID=' + composition.sid);
  });
<?php
// Get the PHP helper library from https://twilio.com/docs/libraries/php
require_once '/path/to/vendor/autoload.php'; // Loads the library
use Twilio\Rest\Client;

// Find your credentials at twilio.com/console
$apiKeySid = "SKXXXX";
$apiKeySecret = "your_auth_apiKeySecret";
$client = new Client($apiKeySid, $apiKeySecret);

$composition = $client->video->compositions->create([
    'roomSid' => 'RMXXXX',
    'videoLayout' =>  array(
                        'grid' => array (
                          'max_rows' => 1,
                          'video_sources' => array(
                            'RTAAAA',
                            'MTBBBB',
                            'teacher-webcast'
                          )
                        )
                      ),
    'statusCallback' => 'http://my.server.org/callbacks',
    'format' => 'mp4'
]);

echo $composition->sid;
# Download the helper library from https://www.twilio.com/docs/ruby/install
require 'rubygems'
require 'twilio-ruby'

# Find your credentials at twilio.com/console
api_key_sid = 'SKXXXX'
api_key_secret = 'your_api_key_secret'

@client = Twilio::REST::Client.new(api_key_sid, api_key_secret)

composition = @client.video.compositions.create(
  room_sid: 'RMXXXX',
  video_layout: {
    grid: {
      video_sources: [
        "RTAAAA",
        "MTBBBB",
        "teacher-webcast"
      ]
    }
  },
  status_callback: 'http://my.server.org/callbacks',
  format: 'mp4'
)

puts composition.sid
# Download the Python helper library from twilio.com/docs/python/install
from twilio.rest import Client
import json

# Find your credentials at twilio.com/console
api_key_sid = = 'SKXXXX'
api_key_secret = 'your_api_key_secret'
client = Client(api_key_sid, api_key_secret)

composition = client.video.compositions.create(
    room_sid = 'RMXXXX',
    video_layout = {
                    'grid': {
                        'max_rows': 1,
                        'video_sources': [
                            'RTAAAA',
                            'MTBBBB',
                            'teacher-webcast'
                        ]
                    }
                   },
    status_callback = 'http://my.server.org/callbacks',
    format='mp4')

print('Created composition with SID=%s' % (composition.sid))
// Install the Java helper library from twilio.com/docs/java/install
import com.twilio.Twilio;
import com.twilio.rest.video.v1.Composition;
import com.twilio.rest.video.v1.Composition.Format;

import com.fasterxml.jackson.databind.ObjectMapper;

public class GridComposition{

  // Find your credentials at twilio.com/console
  public static final String ACCOUNT_SID = "ACXXXX";
  public static final String API_KEY_SID = "SKXXXX";
  public static final String API_KEY_SECRET = "your_api_key_secret";

  public static void main( String[] args ) throws IOException{
      // Initialize the client
      Twilio.init(API_KEY_SID, API_KEY_SECRET, ACCOUNT_SID);

      final String videoLayout =
                          "{"
                        + "   \"grid\": {"
                        + "       \"max_rows\": 1,"
                        + "       \"video_sources\":["
                        + "                 \"RTAAAA\","
                        + "                 \"MTBBBB\","
                        + "                 \"teacher-webcast\""
                        + "          ]"
                        + "    }"
                        + "}";

      Composition composition = Composition.creator()
                  .setRoomSid("RMXXXX")
                  .setVideoLayout(new ObjectMapper().readValue(videoLayout, HashMap.class))
                  .setStatusCallback("http://my.server.org/callbacks")
                  .setFormat(Format.MP4)
                  .create();

      System.out.println("Created composition with SID=" + composition.getSid());
  }
}
curl -X POST 'https://video.twilio.com/v1/Compositions' \
    -u 'SKXXXX:your_api_key_secret' \
    -F 'RoomSid=RMXXXX' \
    -F 'StatusCallback=http://my.server.org/callbacks' \
    -F 'Format=mp4' \
<<-EOF -F 'VideoLayout={
      "grid":{
        "max_rows":1,
        "video_sources":[
          "RTAAAA",
          "MTBBBB",
          "teacher-webcast"]
      }
    }'
EOF
{
    "account_sid": "ACXXXX",
    "audio_sources": [],
    "audio_sources_excluded": [],
    "bitrate": 0,
    "date_completed": null,
    "date_created": "2018-03-26T13:52:45Z",
    "date_deleted": null,
    "duration": 0,
    "format": "mp4",
    "links": {
        "media": "https://video.twilio.com/v1/Compositions/CJXXXX/Media"
    },
    "resolution": "640x480",
    "room_sid": "RMXXXX",
    "sid": "CJXXXX",
    "size": 0,
    "status": "processing",
    "trim": true,
    "url": "https://video.twilio.com/v1/Compositions/CJXXXX",
    "video_layout": {
        "grid": {
            "cells_excluded": [],
            "height": null,
            "max_columns": null,
            "max_rows": 1,
            "reuse": "show_oldest",
            "video_sources": [
                "RTAAAA",
                "MTBBBB",
                "teacher-webcast"
            ],
            "video_sources_excluded": [],
            "width": null,
            "x_pos": 0,
            "y_pos": 0,
            "z_pos": 0
        }
    }
}
Response Format:
  • json
SDK Version:
  • 7.x
SDK Version:
  • 3.x
SDK Version:
  • 5.x
SDK Version:
  • 6.x
SDK Version:
  • 5.x
Format:
  • JSON
// NOTE: This example uses the next generation Twilio helper library - for more
// information on how to download and install this version, visit
// https://www.twilio.com/docs/libraries/node

// Find your credentials at twilio.com/console
const API_KEY_SID = 'SKXXXX';
const API_KEY_SECRET = 'your_api_key_secret';
const ACCOUNT_SID = 'ACXXXX';

const Twilio = require('twilio');

const client = new Twilio(API_KEY_SID, API_KEY_SECRET, {accountSid: ACCOUNT_SID});

client.video.compositions.
  create({
    roomSid: 'RMXXXX',
    audioSources: 'teacher-audio-sess-*',
    videoLayout: {
      sequence: {
        max_rows: 1,
        max_columns: 1,
        reuse : "show_newest",
        video_sources: ['teacher-video-sess-*']
      }
    },
    statusCallback: 'http://my.server.org/callbacks',
    format: 'mp4'
  })
  .then(composition =>{
    console.log('Created Composition with SID=' + composition.sid);
  });
<?php
// Get the PHP helper library from https://twilio.com/docs/libraries/php
require_once '/path/to/vendor/autoload.php'; // Loads the library
use Twilio\Rest\Client;

// Find your credentials at twilio.com/console
$apiKeySid = "SKXXXX";
$apiKeySecret = "your_auth_apiKeySecret";
$client = new Client($apiKeySid, $apiKeySecret);

$composition = $client->video->compositions->create([
    'roomSid' => 'RMXXXX',
    'audioSources' => 'teacher-audio-sess-*',
    'videoLayout' =>  array(
                        'sequence' => array (
                          'max_rows' => 1,
                          'max_columns' => 1,
                          'reuse' => 'show_newest',
                          'video_sources' => array('teacher-video-sess-*')
                        )
                      ),
    'statusCallback' => 'http://my.server.org/callbacks',
    'format' => 'mp4'
]);

echo $composition->sid;
# Download the helper library from https://www.twilio.com/docs/ruby/install
require 'rubygems'
require 'twilio-ruby'

# Find your credentials at twilio.com/console
api_key_sid = 'SKXXXX'
api_key_secret = 'your_api_key_secret'

@client = Twilio::REST::Client.new(api_key_sid, api_key_secret)

composition = @client.video.compositions.create(
  room_sid: 'RMXXXX',
  audio_sources: 'teacher-audio-sess-*',
  video_layout: {
    sequence: {
      max_rows: 1,
      max_columns: 1,
      reuse: 'show_newest',
      video_sources: ['teacher-video-sess-*']
    }
  },
  status_callback: 'http://my.server.org/callbacks',
  format: 'mp4'
)

puts composition.sid
# Download the Python helper library from twilio.com/docs/python/install
from twilio.rest import Client
import json

# Find your credentials at twilio.com/console
api_key_sid = = 'SKXXXX'
api_key_secret = 'your_api_key_secret'
client = Client(api_key_sid, api_key_secret)

composition = client.video.compositions.create(
    room_sid = 'RMXXXX',
    audio_sources = 'teacher-audio-sess-*',
    video_layout = {
                    'sequence': {
                        'max_rows': 1,
                        'max_columns': 1,
                        'reuse': 'show_newest',
                        'video_sources': ['teacher-video-sess-*']
                    }
                   },
    status_callback = 'http://my.server.org/callbacks',
    format='mp4')

print('Created composition with SID=%s' % (composition.sid))
// Install the Java helper library from twilio.com/docs/java/install
import com.twilio.Twilio;
import com.twilio.rest.video.v1.Composition;
import com.twilio.rest.video.v1.Composition.Format;

import com.fasterxml.jackson.databind.ObjectMapper;

public class SequenceComposition{

  // Find your credentials at twilio.com/console
  public static final String ACCOUNT_SID = "ACXXXX";
  public static final String API_KEY_SID = "SKXXXX";
  public static final String API_KEY_SECRET = "your_api_key_secret";

  public static void main( String[] args ) throws IOException{
      // Initialize the client
      Twilio.init(API_KEY_SID, API_KEY_SECRET, ACCOUNT_SID);

      final String videoLayout =
                          "{"
                        + "   \"sequence\": {"
                        + "       \"max_rows\": 1,"
                        + "       \"max_columns\": 1,"
                        + "       \"reuse\": \"show_newest\","
                        + "       \"video_sources\":[\"teacher-video-sess-*\"]"
                        + "    }"
                        + "}";

      Composition composition = Composition.creator()
                  .setRoomSid("RMXXXX")
                  .setAudioSources("teacher-audio-sess-*")
                  .setVideoLayout(new ObjectMapper().readValue(videoLayout, HashMap.class))
                  .setStatusCallback("http://my.server.org/callbacks")
                  .setFormat(Format.MP4)
                  .create();

      System.out.println("Created composition with SID=" + composition.getSid());
  }
}
curl -X POST 'https://video.twilio.com/v1/Compositions' \
    -u 'SKXXXX:your_api_key_secret' \
    -F 'RoomSid=RMXXXX' \
    -F 'StatusCallback=http://my.server.org/callbacks' \
    -F 'Format=mp4' \
    -F 'AudioSources=teacher-audio-sess-*' \
<<-EOF -F 'VideoLayout={
      "sequence":{
        "max_rows":1,
        "max_columns":1,
        "reuse":"show_newest",
        "video_sources":["teacher-video-sess-*"]
      }
    }'
EOF
{
    "account_sid": "ACXXXX",
    "audio_sources": [
        "teacher-audio-sess-*"
    ],
    "audio_sources_excluded": [],
    "bitrate": 0,
    "date_completed": null,
    "date_created": "2018-03-26T14:26:33Z",
    "date_deleted": null,
    "duration": 0,
    "format": "mp4",
    "links": {
        "media": "https://video.twilio.com/v1/Compositions/CJXXXX/Media"
    },
    "resolution": "640x480",
    "room_sid": "RMXXXX",
    "sid": "CJXXXX",
    "size": 0,
    "status": "processing",
    "trim": true,
    "url": "https://video.twilio.com/v1/Compositions/CJXXXX",
    "video_layout": {
        "sequence": {
            "cells_excluded": [],
            "height": null,
            "max_columns": 1,
            "max_rows": 1,
            "reuse": "show_newest",
            "video_sources": [
                "teacher-video-sess-*"
            ],
            "video_sources_excluded": [],
            "width": null,
            "x_pos": 0,
            "y_pos": 0,
            "z_pos": 0
        }
    }
}
Response Format:
  • json
SDK Version:
  • 7.x
SDK Version:
  • 3.x
SDK Version:
  • 5.x
SDK Version:
  • 6.x
SDK Version:
  • 5.x
Format:
  • JSON
// NOTE: This example uses the next generation Twilio helper library - for more
// information on how to download and install this version, visit
// https://www.twilio.com/docs/libraries/node

// Find your credentials at twilio.com/console
const API_KEY_SID = 'SKXXXX';
const API_KEY_SECRET = 'your_api_key_secret';
const ACCOUNT_SID = 'ACXXXX';

const Twilio = require('twilio');

const client = new Twilio(API_KEY_SID, API_KEY_SECRET, {accountSid: ACCOUNT_SID});

client.video.compositions.
  create({
    roomSid: 'RMXXXX',
    audioSources: ['MTAAAA', 'soundtrack'],
    videoLayout: {
      main: {
        z_pos: 1,
        video_sources: ['screen-presentation']
      },
      pip: {
        z_pos: 2,
        x_pos: 1000,
        y_pos: 30,
        width: 240,
        height: 180,
        video_sources: ['MTBBBB']
      }
    },
    statusCallback: 'http://my.server.org/callbacks',
    resolution: '1280x720',
    format: 'mp4'
  })
  .then(composition =>{
    console.log('Created Composition with SID=' + composition.sid);
  });
<?php
// Get the PHP helper library from https://twilio.com/docs/libraries/php
require_once '/path/to/vendor/autoload.php'; // Loads the library
use Twilio\Rest\Client;

// Find your credentials at twilio.com/console
$apiKeySid = "SKXXXX";
$apiKeySecret = "your_auth_apiKeySecret";
$client = new Client($apiKeySid, $apiKeySecret);

$composition = $client->video->compositions->create([
    'roomSid' => 'RMXXXX',
    'audioSources' => array('MTAAAA', 'soundtrack'),
    'videoLayout' =>  array(
                        'main' => array (
                          'z_pos' => 1,
                          'video_sources' => array('screen-presentation')
                        ),
                        'pip' => array(
                          'z_pos' => 2,
                          'x_pos' => 1000,
                          'y_pos' => 30,
                          'width' => 240,
                          'height' => 180,
                          'video_sources' => array('MTBBBB')
                        )
                      ),
    'statusCallback' => 'http://my.server.org/callbacks',
    'resolution' => '1280x720',
    'format' => 'mp4'
]);

echo $composition->sid;
# Download the helper library from https://www.twilio.com/docs/ruby/install
require 'rubygems'
require 'twilio-ruby'

# Find your credentials at twilio.com/console
api_key_sid = 'SKXXXX'
api_key_secret = 'your_api_key_secret'

@client = Twilio::REST::Client.new(api_key_sid, api_key_secret)

composition = @client.video.compositions.create(
  room_sid: 'RMXXXX',
  audio_sources: 'teacher-audio-sess-*',
  video_layout: {
    main: {
      z_pos: 1,
      video_sources: ['screen-presentation']
    },
    pip: {
      z_pos: 2,
      x_pos: 1000,
      y_pos: 30,
      width: 240,
      height: 180,
      video_sources: ['MTBBBB']
    }
  },
  status_callback: 'http://my.server.org/callbacks',
  resolution: '1280x720',
  format: 'mp4'
)

puts composition.sid
# Download the Python helper library from twilio.com/docs/python/install
from twilio.rest import Client
import json

# Find your credentials at twilio.com/console
api_key_sid = = 'SKXXXX'
api_key_secret = 'your_api_key_secret'
client = Client(api_key_sid, api_key_secret)

composition = client.video.compositions.create(
    room_sid = 'RMXXXX',
    audio_sources = ['MTAAAA', 'soundtrack'],
    video_layout = {
                    'main' : {
                        'z_pos': 1,
                        'video_sources': ['screen-presentation']
                        },
                    'pip': {
                        'z_pos': 2,
                        'x_pos': 1000,
                        'y_pos': 30,
                        'width': 240,
                        'height': 180,
                        'video_sources': ['MTBBBB']
                    }
                   },
    status_callback = 'http://my.server.org/callbacks',
    resolution = '1280x720',
    format='mp4')

print('Created composition with SID=%s' % (composition.sid))
// Install the Java helper library from twilio.com/docs/java/install
import com.twilio.Twilio;
import com.twilio.rest.video.v1.Composition;
import com.twilio.rest.video.v1.Composition.Format;

import com.fasterxml.jackson.databind.ObjectMapper;

public class PipComposition{

  // Find your credentials at twilio.com/console
  public static final String ACCOUNT_SID = "ACXXXX";
  public static final String API_KEY_SID = "SKXXXX";
  public static final String API_KEY_SECRET = "your_api_key_secret";

  public static void main( String[] args ) throws IOException{
      // Initialize the client
      Twilio.init(API_KEY_SID, API_KEY_SECRET, ACCOUNT_SID);

      final String videoLayout =
                        "{"
                      + "   \"main\": {"
                      + "       \"z_pos\": 1,"
                      + "       \"video_sources\":[\"screen-presetation\"]"
                      + "    },"
                      + "   \"row\": {"
                      + "       \"z_pos\": 2,"
                      + "       \"x_pos\": 1000,"
                      + "       \"y_pos\": 30,"
                      + "       \"width\": 240,"
                      + "       \"height\": 180,"
                      + "       \"video_sources\": [\"RTBBBB\"]"
                      + "    }"
                      + "}";

      Composition composition = Composition.creator()
                  .setRoomSid("RMXXXX")
                  .setAudioSources(Arrays.asList("MTAAAA","soundtrack"))
                  .setVideoLayout(new ObjectMapper().readValue(videoLayout, HashMap.class))
                  .setStatusCallback("http://my.server.org/callbacks")
                  .setResolution("1280x720")
                  .setFormat(Format.MP4)
                  .create();

      System.out.println("Created composition with SID=" + composition.getSid());
  }
}
curl -X POST 'https://video.twilio.com/v1/Compositions' \
    -u 'SKXXXX:your_api_key_secret' \
    -F 'RoomSid=RMXXXX' \
    -F 'AudioSources=MTAAAA' \
    -F 'AudioSources=soundtrack' \
    -F 'Resolution=1280x720' \
    -F 'Format=mp4' \
    -F 'StatusCallback=http://my.server.org/callbacks' \
<<-EOF -F 'VideoLayout={
      "main":{
        "z_pos":1,
        "video_sources":["screen-presentation"]
      },
      "pip":{
        "z_pos":2,
        "x_pos":1000,
        "y_pos":30,
        "width":240,
        "height":180,
        "video_sources":["MTBBBB"]
      }
    }'
EOF
{
    "account_sid": "ACXXXX",
    "audio_sources": [
        "MTAAAA",
        "soundtrack"
    ],
    "audio_sources_excluded": [],
    "bitrate": 0,
    "date_completed": null,
    "date_created": "2018-03-26T15:16:14Z",
    "date_deleted": null,
    "duration": 0,
    "format": "mp4",
    "links": {
        "media": "https://video.twilio.com/v1/Compositions/CJXXXX/Media"
    },
    "resolution": "1280x720",
    "room_sid": "RMXXXX",
    "sid": "CJXXXX",
    "size": 0,
    "status": "processing",
    "trim": true,
    "url": "https://video.twilio.com/v1/Compositions/CJXXXX",
    "video_layout": {
        "main": {
            "cells_excluded": [],
            "height": null,
            "max_columns": null,
            "max_rows": null,
            "reuse": "show_oldest",
            "video_sources": [
                "screen-presentation"
            ],
            "video_sources_excluded": [],
            "width": null,
            "x_pos": 0,
            "y_pos": 0,
            "z_pos": 1
        },
        "pip": {
            "cells_excluded": [],
            "height": 180,
            "max_columns": null,
            "max_rows": null,
            "reuse": "show_oldest",
            "video_sources": [
                "MTBBBB"
            ],
            "video_sources_excluded": [],
            "width": 240,
            "x_pos": 1000,
            "y_pos": 30,
            "z_pos": 2
        }
    }
}
Response Format:
  • json
SDK Version:
  • 7.x
SDK Version:
  • 3.x
SDK Version:
  • 5.x
SDK Version:
  • 6.x
SDK Version:
  • 5.x
Format:
  • JSON
// NOTE: This example uses the next generation Twilio helper library - for more
// information on how to download and install this version, visit
// https://www.twilio.com/docs/libraries/node

// Find your credentials at twilio.com/console
const API_KEY_SID = 'SKXXXX';
const API_KEY_SECRET = 'your_api_key_secret';
const ACCOUNT_SID = 'ACXXXX';

const Twilio = require('twilio');

const client = new Twilio(API_KEY_SID, API_KEY_SECRET, {accountSid: ACCOUNT_SID});

client.video.compositions.
  create({
    roomSid: 'RMXXXX',
    audioSources: '*',
    videoLayout: {
      main: {
        z_pos: 1,
        video_sources: ['teacher-screen-video']
      },
      row: {
        z_pos: 2,
        x_pos: 10,
        y_pos: 530,
        width: 1260,
        height: 160,
        max_rows: 1,
        video_sources: ['*'],
        video_sources_excluded: ['teacher-screen-video']
      }
    },
    statusCallback: 'http://my.server.org/callbacks',
    resolution: '1280x720',
    format: 'mp4'
  })
  .then(composition =>{
    console.log('Created Composition with SID=' + composition.sid);
  });
<?php
// Get the PHP helper library from https://twilio.com/docs/libraries/php
require_once '/path/to/vendor/autoload.php'; // Loads the library
use Twilio\Rest\Client;

// Find your credentials at twilio.com/console
$apiKeySid = "SKXXXX";
$apiKeySecret = "your_auth_apiKeySecret";
$client = new Client($apiKeySid, $apiKeySecret);

$composition = $client->video->compositions->create([
    'roomSid' => 'RMXXXX',
    'audioSources' => '*',
    'videoLayout' =>  array(
                        'main' => array (
                            'z_pos' => 1,
                            'video_sources' => array('teacher-screen-video')
                        ),
                        'row' => array(
                            'z_pos' => 2,
                            'x_pos' => 10,
                            'y_pos' => 530,
                            'width' => 1260,
                            'height' => 160,
                            'max_rows' => 1,
                            'video_sources' => array('*'),
                            'video_sources_excluded' => array('teacher-screen-video')
                        )
                      ),
    'statusCallback' => 'http://my.server.org/callbacks',
    'resolution' => '1280x720',
    'format' => 'mp4'
]);

echo $composition->sid;
# Download the helper library from https://www.twilio.com/docs/ruby/install
require 'rubygems'
require 'twilio-ruby'

# Find your credentials at twilio.com/console
api_key_sid = 'SKXXXX'
api_key_secret = 'your_api_key_secret'

@client = Twilio::REST::Client.new(api_key_sid, api_key_secret)

composition = @client.video.compositions.create(
  room_sid: 'RMXXXX',
  audio_sources: '*',
  video_layout: {
    main: {
      z_pos: 1,
      video_sources: ['teacher-screen-video']
    },
    row: {
      z_pos: 2,
      x_pos: 10,
      y_pos: 530,
      width: 1260,
      height: 160,
      max_rows: 1,
      video_sources: ['*']
      video_sources_excluded: ['teacher-screen-video']
    }
  },
  status_callback: 'http://my.server.org/callbacks',
  resolution: '1280x720',
  format: 'mp4'
)

puts composition.sid
# Download the Python helper library from twilio.com/docs/python/install
from twilio.rest import Client
import json

# Find your credentials at twilio.com/console
api_key_sid = = 'SKXXXX'
api_key_secret = 'your_api_key_secret'
client = Client(api_key_sid, api_key_secret)

composition = client.video.compositions.create(
    room_sid = 'RMXXXX',
    audio_sources = '*',
    video_layout = {
                        'main' : {
                            'z_pos': 1,
                            'video_sources': ['teacher-screen-video']
                        },
                        'row': {
                            'z_pos': 2,
                            'x_pos': 10,
                            'y_pos': 530,
                            'width': 1260,
                            'height': 160,
                            'max_rows': 1,
                            'video_sources': ['*'],
                            'video_sources_excluded': ['teacher-screen-video']
                        }
                    },
    status_callback = 'http://my.server.org/callbacks',
    resolution = '1280x720',
    format='mp4')

print('Created composition with SID=%s' % (composition.sid))
// Install the Java helper library from twilio.com/docs/java/install
import com.twilio.Twilio;
import com.twilio.rest.video.v1.Composition;
import com.twilio.rest.video.v1.Composition.Format;

import com.fasterxml.jackson.databind.ObjectMapper;

public class ComplexComposition{

  // Find your credentials at twilio.com/console
  public static final String ACCOUNT_SID = "ACXXXX";
  public static final String API_KEY_SID = "SKXXXX";
  public static final String API_KEY_SECRET = "your_api_key_secret";

  public static void main( String[] args ) throws IOException{
      // Initialize the client
      Twilio.init(API_KEY_SID, API_KEY_SECRET, ACCOUNT_SID);

      final String videoLayout =
                        "{"
                      + "   \"main\": {"
                      + "       \"z_pos\": 1,"
                      + "       \"video_sources\":[\"teacher-screen-video\"]"
                      + "    },"
                      + "   \"row\": {"
                      + "       \"z_pos\": 2,"
                      + "       \"x_pos\": 10,"
                      + "       \"y_pos\": 530,"
                      + "       \"width\": 1260,"
                      + "       \"height\": 160,"
                      + "       \"max_rows\": 1,"
                      + "       \"video_sources\": [\"*\"],"
                      + "       \"video_sources_excluded\": [\"teacher-screen-video\"]"
                      + "    }"
                      + "}";

      Composition composition = Composition.creator()
                  .setRoomSid("RMXXXX")
                  .setAudioSources("*")
                  .setVideoLayout(new ObjectMapper().readValue(videoLayout, HashMap.class))
                  .setStatusCallback("http://my.server.org/callbacks")
                  .setResolution("1280x720")
                  .setFormat(Format.MP4)
                  .create();

      System.out.println("Created composition with SID=" + composition.getSid());
  }
}
curl -X POST 'https://video.twilio.com/v1/Compositions' \
    -u 'SKXXXX:your_api_key_secret' \
    -F 'RoomSid=RMXXXX' \
    -F 'AudioSources=*' \
    -F 'StatusCallback=http://my.server.org/callbacks' \
    -F 'Resolution=1280x720'\
    -F 'Format=mp4' \
<<-EOF -F 'VideoLayout={
      "main":{
        "z_pos":1,
        "video_sources":["teacher-screen-video"]
      },
      "row":{
        "z_pos":2,
        "x_pos":10,
        "y_pos":530,
        "width":1260,
        "height":160,
        "max_rows":1,
        "video_sources":["*"],
        "video_sources_excluded":["teacher-screen-video"]
      }
    }'
EOF
{{
    "account_sid": "ACXXXX",
    "audio_sources": [
        "*"
    ],
    "audio_sources_excluded": [],
    "bitrate": 0,
    "date_completed": null,
    "date_created": "2018-03-26T15:45:18Z",
    "date_deleted": null,
    "duration": 0,
    "format": "mp4",
    "links": {
        "media": "https://video.twilio.com/v1/Compositions/CJXXXX/Media"
    },
    "resolution": "1280x720",
    "room_sid": "RMXXXX",
    "sid": "CJXXXX",
    "size": 0,
    "status": "processing",
    "trim": true,
    "url": "https://video.twilio.com/v1/Compositions/CJXXXX",
    "video_layout": {
        "main": {
            "cells_excluded": [],
            "height": null,
            "max_columns": null,
            "max_rows": null,
            "reuse": "show_oldest",
            "video_sources": [
                "teacher-screen-video"
            ],
            "video_sources_excluded": [],
            "width": null,
            "x_pos": 0,
            "y_pos": 0,
            "z_pos": 1
        },
        "row": {
            "cells_excluded": [],
            "height": 160,
            "max_columns": null,
            "max_rows": 1,
            "reuse": "show_oldest",
            "video_sources": [
                "*"
            ],
            "video_sources_excluded": [
                "teacher-screen-video"
            ],
            "width": 1260,
            "x_pos": 10,
            "y_pos": 530,
            "z_pos": 2
        }
    }
}
Response Format:
  • json
SDK Version:
  • 7.x
SDK Version:
  • 3.x
SDK Version:
  • 5.x
SDK Version:
  • 6.x
SDK Version:
  • 5.x
Format:
  • JSON
// NOTE: This example uses the next generation Twilio helper library - for more
// information on how to download and install this version, visit
// https://www.twilio.com/docs/libraries/node

// Find your credentials at twilio.com/console
const API_KEY_SID = 'SKXXXX';
const API_KEY_SECRET = 'your_api_key_secret';
const ACCOUNT_SID = 'ACXXXX';

const Twilio = require('twilio');

const client = new Twilio(API_KEY_SID, API_KEY_SECRET, {accountSid: ACCOUNT_SID});

client.video.compositions.
  create({
    roomSid: 'RMXXXX',
    audioSources: '*',
    videoLayout: {
      main: {
        z_pos: 1,
        video_sources: ['teacher-screen-video']
      },
      pip: {
        z_pos: 2,
        x_pos: 1000,
        y_pos: 30,
        width: 240,
        height: 180,
        video_sources: ['teacher-webcam-video']
      },
      column: {
        z_pos: 3,
        x_pos: 40,
        y_pos: 10,
        width: 190,
        height: 700,
        max_rows: 5,
        max_columns: 1,
        reuse: "show_newest",
        video_sources: ['student-*']
      }
    },
    statusCallback: 'http://my.server.org/callbacks',
    resolution: '1280x720',
    format: 'mp4'
  })
  .then(composition =>{
    console.log('Created Composition with SID=' + composition.sid);
  });
<?php
// Get the PHP helper library from https://twilio.com/docs/libraries/php
require_once '/path/to/vendor/autoload.php'; // Loads the library
use Twilio\Rest\Client;

// Find your credentials at twilio.com/console
$apiKeySid = "SKXXXX";
$apiKeySecret = "your_auth_apiKeySecret";
$client = new Client($apiKeySid, $apiKeySecret);

$composition = $client->video->compositions->create([
    'roomSid' => 'RMXXXX',
    'audioSources' => '*',
    'videoLayout' =>  array(
                        'main' => array (
                            'z_pos' => 1,
                            'video_sources' => array('teacher-screen-video')
                        ),
                        'pip' => array(
                            'z_pos' => 2,
                            'x_pos' => 1000,
                            'y_pos' => 30,
                            'width' => 240,
                            'height' => 180,
                            'video_sources' => array('teacher-webcam-video')
                        ),
                        'column' => array(
                            'z_pos' => 3,
                            'x_pos' => 40,
                            'y_pos' => 10,
                            'width' => 190,
                            'height' => 700,
                            'max_rows' => 5,
                            'max_columns' => 1,
                            'reuse' => 'show_newest',
                            'video_sources' => array('student-*')
                        )
                      ),
    'statusCallback' => 'http://my.server.org/callbacks',
    'resolution' => '1280x720',
    'format' => 'mp4'
]);

echo $composition->sid;
# Download the helper library from https://www.twilio.com/docs/ruby/install
require 'rubygems'
require 'twilio-ruby'

# Find your credentials at twilio.com/console
api_key_sid = 'SKXXXX'
api_key_secret = 'your_api_key_secret'

@client = Twilio::REST::Client.new(api_key_sid, api_key_secret)

composition = @client.video.compositions.create(
  room_sid: 'RMXXXX',
  audio_sources: '*',
  video_layout: {
    main: {
      z_pos: 1,
      video_sources: ['teacher-screen-video']
    },
    pip: {
      z_pos: 2,
      x_pos: 1000,
      y_pos: 30,
      width: 240,
      height: 180,
      max_rows: 1,
      video_sources: ['teacher-webcam-video']
    },
    column: {
      z_pos: 3,
      x_pos: 40,
      y_pos: 10,
      width: 190,
      height: 700,
      max_rows: 5,
      max_columns: 1,
      reuse: 'show_newest',
      video_sources: ['student-*']
    }
  },
  status_callback: 'http://my.server.org/callbacks',
  resolution: '1280x720',
  format: 'mp4'
)

puts composition.sid
# Download the Python helper library from twilio.com/docs/python/install
from twilio.rest import Client
import json

# Find your credentials at twilio.com/console
api_key_sid = = 'SKXXXX'
api_key_secret = 'your_api_key_secret'
client = Client(api_key_sid, api_key_secret)

composition = client.video.compositions.create(
    room_sid = 'RMXXXX',
    audio_sources = '*',
    video_layout = {
                        'main' : {
                            'z_pos': 1,
                            'video_sources': ['teacher-screen-video']
                        },
                        'pip': {
                            'z_pos': 2,
                            'x_pos': 1000,
                            'y_pos': 30,
                            'width': 240,
                            'height': 180,
                            'video_sources': ['teacher-webcam-video']
                        },
                        'column': {
                            'z_pos': 3,
                            'x_pos': 40,
                            'y_pos': 10,
                            'width': 190,
                            'height': 700,
                            'max_rows': 5,
                            'max_columns': 1,
                            'reuse': 'show_newest',
                            'video_sources': ['student-*']
                        }
                    },
    status_callback = 'http://my.server.org/callbacks',
    resolution = '1280x720',
    format='mp4')

print('Created composition with SID=%s' % (composition.sid))
// Install the Java helper library from twilio.com/docs/java/install
import com.twilio.Twilio;
import com.twilio.rest.video.v1.Composition;
import com.twilio.rest.video.v1.Composition.Format;

import com.fasterxml.jackson.databind.ObjectMapper;

public class ComplexComposition{

  // Find your credentials at twilio.com/console
  public static final String ACCOUNT_SID = "ACXXXX";
  public static final String API_KEY_SID = "SKXXXX";
  public static final String API_KEY_SECRET = "your_api_key_secret";

  public static void main( String[] args ) throws IOException{
      // Initialize the client
      Twilio.init(API_KEY_SID, API_KEY_SECRET, ACCOUNT_SID);

      final String videoLayout =
                        "{"
                      + "   \"main\": {"
                      + "       \"z_pos\": 1,"
                      + "       \"video_sources\":[\"teacher-screen-video\"]"
                      + "    },"
                      + "   \"pip\": {"
                      + "       \"z_pos\": 2,"
                      + "       \"x_pos\": 1000,"
                      + "       \"y_pos\": 30,"
                      + "       \"width\": 240,"
                      + "       \"height\": 180,"
                      + "       \"video_sources\": [\"teacher-webcam-video\"]"
                      + "    },"
                      + "   \"column\": {"
                      + "       \"z_pos\": 3,"
                      + "       \"x_pos\": 40,"
                      + "       \"y_pos\": 10,"
                      + "       \"width\": 190,"
                      + "       \"height\": 700,"
                      + "       \"max_rows\": 5,"
                      + "       \"max_columns\": 1,"
                      + "       \"reuse\": \"show_newest\","
                      + "       \"video_sources\": [\"student-*\"]"
                      + "    }"
                      + "}";

      Composition composition = Composition.creator()
                  .setRoomSid("RMXXXX")
                  .setAudioSources("*")
                  .setVideoLayout(new ObjectMapper().readValue(videoLayout, HashMap.class))
                  .setStatusCallback("http://my.server.org/callbacks")
                  .setResolution("1280x720")
                  .setFormat(Format.MP4)
                  .create();

      System.out.println("Created composition with SID=" + composition.getSid());
  }
}
curl -X POST 'https://video.twilio.com/v1/Compositions' \
    -u 'SKXXXX:your_api_key_secret' \
    -F 'RoomSid=RMXXXX' \
    -F 'AudioSources=*' \
    -F 'StatusCallback=http://my.server.org/callbacks' \
    -F 'Resolution=1280x720' \
    -F 'Format=mp4' \
<<-EOF -F 'VideoLayout={
      "main":{
        "z_pos":1,
        "video_sources":["teacher-screen-video"]
      },
      "pip":{
        "z_pos":2,
        "x_pos":1000,
        "y_pos":30,
        "width":240,
        "height":180,
        "video_sources":["teacher-webcam-video"]
      },
      "column":{
        "z_pos":3,
        "x_pos":40,
        "y_pos":10,
        "width":190,
        "height":700,
        "max_rows":5,
        "max_columns":1,
        "reuse":"show_newest",
        "video_sources":["student-*"]
      }
    }'
EOF
{
    "account_sid": "ACXXXX",
    "audio_sources": [
        "*"
    ],
    "audio_sources_excluded": [],
    "bitrate": 0,
    "date_completed": null,
    "date_created": "2018-03-26T15:55:31Z",
    "date_deleted": null,
    "duration": 0,
    "format": "mp4",
    "links": {
        "media": "https://video.twilio.com/v1/Compositions/CJXXXX/Media"
    },
    "resolution": "1280x720"