The Vonage Video API live streaming feature lets you broadcast a video session to a large audience using HTTP live streaming (HLS) or an RTMP stream.
This page includes the following sections:
More clients can simultaneously view an HLS stream than can view an OpenTok live interactive video session. For example, you may provide an HLS stream to a client if the OpenTok session has reached the 3,000-connection limit for OpenTok live interactive broadcasts. HLS streams support an unlimited number of viewers. RTMP streams are limited by the number of viewers supported by the RTMP provider.
You can use the RTMP streaming feature to provide a video stream to a platform that supports RTMP streams, such as YouTube Live or Facebook.
Also, clients that do not support WebRTC can view the HLS or RTMP stream.
A broadcast can include up to 9 streams from the session. If the session includes more than 9 streams concurrently, the extra streams will not be included in the broadcast.
An HLS is delayed 15 to 20 seconds behind the live streams in the OpenTok session. During the initial delay, the broadcast stream is not available. Do not provide the broadcast URL to clients until the HLS or RTMP stream is available.
For an RTMP stream, the OpenTok platform introduces a latency of approximately 5 seconds. However, each the RTMP delivery platform (such as YouTube Live or Facebook) will add additional latency based on their processing of the video before publishing it.
The HLS and RTMP streaming feature is only available for routed sessions (sessions that use the OpenTok Media Router). For more information, see The OpenTok Media Router and Media Modes.
HLS playback is not supported in all browsers. However, there are a number of plugins, such as Flowplayer, that provide cross-browser support (using Flash Player in browsers that do not provide direct HLS support).
OpenTok RTMP streams have the following specifications:
Streams published from Safari show up as audio-only in live streaming broadcasts.
See the OpenTok pricing page for details on HLS and RTMP streaming pricing.
Use the OpenTok REST API to start and stop live streaming of a session, and to check the status of a live streaming broadcast.
The HLS and RTMP streams stop automatically 60 seconds after the last client disconnects from
the session. Also there is a default maximum duration of 2 hours for each HLS and RTMP stream
(the live stream broadcast automatically stops when this duration is reached). You can change the
maximum duration for the broadcast by setting the maxDuration
property when calling the
start REST method. You can set the maximum duration to be
60 seconds to 10 hours (36,000 seconds).
When using the OpenTok live streaming feature, you can customize the layout of videos in the HLS or RTMP stream.
By default, the OpenTok live streaming feature arranges videos from the OpenTok session in a tiled layout in the composed HLS or RTMP video. The layout is based on the number of videos in the session. For example, the following illustrates the layout when there are 1, 2, 4, or 5 streams in a session:
This is known as the "best fit" layout. Alternately, you can select from a number of other predefined layouts. For the other layouts, you assign a class name to each OpenTok video streams to determine how it will appear in the layout. (See the next section, Predefined layout types.)
You can also define your own custom layouts, using CSS.
By default, the broadcast video is 640x480 pixels. Individual OpenTok videos are arranged in
container rectangles within the composite video. By default, the video is drawn with the
CSS object-fit
property set to contain
. For example, the following illustration shows
a best-fit layout with two 4:3 videos (1 and 4) and two 16:9 videos (2 and 3):
You can modify this behavior using custom layouts.
You can also set a broadcast stream to use an 1280x720 (HD) resolution when you call the start broadcast method of the OpenTok REST API. In this case, the predefined layouts are adjusted to use a 16:9 aspect ratio.
There are four predefined layout types available: best fit, picture-in-picture, vertical presentation, and horizontal presentation.
To choose this layout, set the the type
property to "bestFit"
. (See
Specifying the initial layout type and
Dynamically changing the layout type during a live streaming broadcast.)
This is the default initial layout type.
This is a tiled layout, which scales according to the number of videos. The number of columns and rows of varies depending on the number of OpenTok streams in the broadcast. For example, the following illustrates the layout when there are 1, 2, 4, or 5 streams in a session:
Layout classes on these streams will have no effect on the layout. Each position in the list will be translated to a position in the grid.
This layout supports up to 9 OpenTok streams.
To choose this layout, set the type
property to "pip"
. (See
Specifying the initial layout type and
Dynamically changing the layout type during a live streaming broadcast.)
This is a picture-in-picture layout, where a small stream is visible over a full-size stream.
C = corner
Set the layout class of the full-size stream to "full"
. (See
Assigning layout classes to OpenTok streams.) The first stream
without this class occupies the corner position. If more than two streams are present in the
broadcast, only the first two streams will be visible in the output.
To choose this layout, set the the type
property to "verticalPresentation"
. (See
Specifying the initial layout type and
Dynamically changing the layout type during a live streaming broadcast.)
This is a layout with one large stream on the right edge of the output, and several smaller streams along the left edge of the output.
Set the layout class of the focus stream to "focus"
. (See
Assigning layout classes to OpenTok streams.)
The streams without the focus class will occupy the left edge and divide the space evenly.
If only one stream is present, it will occupy the full output size.
This layout supports 1 focus stream and up to 5 other streams.
To choose this layout, set the the type
property to "horizontalPresentation"
. (See
Specifying the initial layout type and
Dynamically changing the layout type during a live streaming broadcast.)
This is a layout with one large stream on the top edge of the output, and several smaller streams along the bottom edge of the output.
There is one layout class used to specify the position of streams in this layout: focus
. (See
Assigning layout classes to OpenTok streams) The streams
without this class will occupy the bottom edge and divide the space evenly. If only one stream is
present, it will occupy the full output size. The positions can be visualized as such:
This layout supports 1 focus stream and up to 5 other streams.
When you start the live streaming broadcast for a session, using the OpenTok REST API, you can, optionally, specify the initial layout type.
Set the Content-Type
to "application/json"
and set the in the layout type as a property of the JSON
data sent in the POST request.
{
"sessionId": "2_MX44NTQ1MTF--bm1kTGQ0RjVHeGNQZE51VG5scGNzdVl0flB-",
"layout": {
"type": "pip"
}
}
If you are using a custom layout (see Defining custom layouts), set the
type
property to "custom"
and pass in the stylesheet as an additional property —
stylesheet
:
{
"sessionId": "2_MX44NTQ1MTF--bm1kTGQ0RjVHeGNQZE51VG5scGNzdVl0flB-",
"layout": {
"type": "custom",
"stylesheet": "stream.instructor {position: absolute; width: 100%; height:50%;}"
}
}
The request returns a 400 error response code if you specify an invalid type.
If you do not specify an initial layout type, the HLS or RTMP stream uses the best fit layout type. If you specify any other layout type, be sure to apply appropriate layout classes for streams in the OpenTok session (see Assigning layout classes to OpenTok streams).
You can dynamically change the layout type by calling the OpenTok /broadcast/layout REST API.
Set the Content-Type
to "application/json"
and include the layout type as a property of
the JSON data in the PUT request:
{
"type": "pip"
}
If you are using a custom layout (see Defining custom layouts) set the type
property to "custom"
and pass in the stylesheet as an additional property — stylesheet
:
{
"type": "custom",
"stylesheet": "stream.instructor {position: absolute; width: 100%; height:50%;}"
}
The request returns a 400 error response code if you specify an invalid type.
When specifying a layout type other than the default Best Fit layout type, be sure to apply appropriate layout classes for streams in the OpenTok session (see Assigning layout classes to OpenTok streams).
When using a layout type other than the default Best Fit, you must set the layout class for the OpenTok streams to use, based on the layout type:
When you create a token for a client to connect to the OpenTok session, you can (optionally) specify the initial layout class list for streams published by the client. To do this, generate a token that includes the initial layout class list setting. The following examples use the OpenTok Node, Python, and Ruby SDKs.
Node:
var OpenTok = require('opentok'),
opentok = new OpenTok(apiKey, apiSecret);
opentok.createSession({mediaMode:"routed"}, function(err, session) {
if (err) return console.log(err);
token = session.generateToken({
expireTime : (new Date().getTime() / 1000)+(7 * 24 * 60 * 60), // in one week
data : 'name=Johnny',
initialLayoutClassList : ['focus', 'inactive']
});
});
Python:
from opentok import OpenTok
from opentok import MediaModes
from opentok import Roles
opentok = OpenTok(api_key, api_secret)
session = opentok.create_session(media_mode=MediaModes.routed)
token = session.generate_token(expire_time=int(time.time()) + 10,
data=u'name=Johnny'
initial_layout_class_list=[u'focus'])
Ruby:
opentok = OpenTok::OpenTok.new api_key, api_secret
session = opentok.create_session :media_mode => :routed
token = session.generate_token({
:role => :moderator
:expire_time => Time.now.to_i+(7 * 24 * 60 * 60) # in one week
:data => 'name=Johnny',
:initial_layout_class_list => ['focus', 'inactive']
});
You can dynamically change the layout class list for a stream by calling the OpenTok /session/{sessionId}/stream REST API. Make a PUT request to the following URL:
https://api.opentok.com/v2/project/{apiKey}/session/{sessionId}/stream
Set the Content-Type to "application/json"
and include the layout class list as a property of the
JSON data in the PUT request:
{
"items": [
{
"id": "8b732909-0a06-46a2-8ea8-074e64d43422",
"layoutClassList": ["full"]
}
]
}
The id
property is the stream ID. Note that you can update the layout class list for multiple
streams by passing in multiple JSON objects in the items array.
The request returns a 400 response code if you specify an invalid layoutClassList value. The value must be an array of strings.
You can get the layout class list for a stream by calling the OpenTok /session/{sessionId}/stream/{streamId} REST API. Make a GET request to the following URL:
https://api.opentok.com/v2/project/{apiKey}/session/{sessionId}/stream/{streamId}
The response includes JSON data, which includes a layoutClassList
array:
{
"id": "8b732909-0a06-46a2-8ea8-074e64d43422",
"videoType": "camera",
"name": "",
"layoutClassList": ["full"]
}
layoutClassList
property is an array of the layout classes for the stream.id
property is the stream ID.videoType
property is either "camera" or "screen".name
property is the stream name (if one was set when the client published the stream).The request returns a 408 error response code if you specify an invalid stream ID.
You can get the layout class list for all streams in a session by calling the /session/{sessionId}/stream REST API. Make a GET request to the following URL:
https://api.opentok.com/v2/project/{apiKey}/session/{sessionId}/stream/
The response includes JSON data, which includes an items
property, which is array containing layout information for streams in the session:
{
"count": 2
"items": [
{
"id": "8b732909-0a06-46a2-8ea8-074e64d43422",
"videoType": "camera",
"name": "",
"layoutClassList": ["full"]
},
...
]
}
layoutClassList
property is an array of the layout classes for the stream.id
property is the stream ID.video
property is either "camera"
or "screen"
.name
property is the stream name (if one was set when the client published the stream).In addition to the predefined layouts, you can use CSS to define your own custom layout for broadcast videos.
To use a custom layout, set the type property for the layout to "custom" and set an additional property,
stylesheet
, which is set to the CSS. (See
Specifying the initial layout type and
Dynamically changing the layout type during a live streaming broadcast.)
CSS used in the stylesheet
property of the layout resource will apply to a virtual DOM,
which can be described in the following format:
<broadcast class="container">
<stream class="{layoutClassList}" />
<stream class="{layoutClassList}" />
<stream class="{layoutClassList}" />
...
</broadcast>
Note: By default, the live streaming broadcast resolution is 640x480 pixels (SD). You can also set a live streaming broadcast to use an 1280x720 (HD) resolution when you call the start broadcast method of the OpenTok REST API. 640x480-pixel (SD) broadcasts have a 4:3 aspect ratio. 1280x720-pixel (HD) broadcasts have a 16:9 aspect ratio. Keep these aspect ratios in mind when defining the CSS for a custom layout.
The following default rules are applied to the <broadcast>
element:
broadcast {
position: relative;
margin:0;
width: 640px;
height:480px;
overflow: hidden;
}
The default width and height are 640 and 480 pixels. You can set a broadcast to use a 1280x720 (HD) resolution when you call the start broadcast method of the OpenTok REST API.
The following default rules are applied to <stream>
elements:
stream {
display: block;
margin: 0;
}
*Note:* The container resolution is fixed and cannot be overridden by CSS.
The following CSS selectors are supported:
.instructor
) are supported (and preferred), and can be used to select any
group of streams or individual stream.sibling-one + sibling-two
,
sibling-one ~ sibling-two
).The following pseudo-class selectors are supported:
:first-child
:last-child
:nth-child(n)
:nth-last-child(n)
The following CSS selectors are not supported:
*
).parent ancestor
, parent * ancestor
).parent > child
).#myidentifier
).[data-title*="my-title"]
).The following table describes the supported CSS properties and their possible values:
Name | Value |
---|---|
width , height |
positive number ( px / % ) |
min-width , min-height |
positive number ( px / % ) |
max-width , max-height ] |
positive number ( px / % ) |
left , right , top , bottom |
number ( px / % ) |
margin , margin-left , margin-right , margin-top , margin-bottom |
number ( px / % ) |
z-index |
positive number |
position |
'relative' , 'absolute' |
display |
'inline' , 'block' , 'inline-block' |
float |
'none' , 'left' , 'right' |
object-fit |
'contain' (the default), 'cover' |
overflow |
'hidden' |
clear |
'none' , 'left' , 'right' ,'both' , 'inherit' , 'inherit' |
The following CSS arranges two streams with class names main
and lower-left
:
stream.main {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: 100;
}
stream.lower-left {
position: absolute;
left: 10%;
bottom: 10%;
width: 20%;
height: 20%;
z-index: 200;
}
The following CSS is based on the best fit predefined layout:
stream {
float: left;
}
stream:first-child:nth-last-child(1) {
width: 100%;
height: 100%;
}
stream:first-child:nth-last-child(2),
stream:first-child:nth-last-child(2) ~ stream {
width: 50%;
height: 100%;
}
stream:first-child:nth-last-child(3),
stream:first-child:nth-last-child(3) ~ stream,
stream:first-child:nth-last-child(4),
stream:first-child:nth-last-child(4) ~ stream {
width: 50%;
height: 50%;
}
stream:first-child:nth-last-child(5),
stream:first-child:nth-last-child(5) ~ stream,
stream:first-child:nth-last-child(6),
stream:first-child:nth-last-child(6) ~ stream,
stream:first-child:nth-last-child(7),
stream:first-child:nth-last-child(7) ~ stream,
stream:first-child:nth-last-child(8),
stream:first-child:nth-last-child(8) ~ stream,
stream:first-child:nth-last-child(9),
stream:first-child:nth-last-child(9) ~ stream
{
width: 33.33%;
height: 33.33%;
}
The following CSS is based on the horizontal presentation predefined layout:
stream {
float:left;
margin-top: 60%;
width: 20%;
height: 20%;
}
stream.focus {
position: absolute;
top: 0;
left: 0;
margin-top: 0px;
height: 80%;
width: 100%;
}
The following CSS is based on the vertical presentation predefined layout:
stream {
float: left;
left: 0px;
clear: left;
width: 20%;
height: 20%;
}
stream.focus {
position: absolute;
top: 0;
left: 0;
margin: 0px;
left: 20%;
height: 100%;
width: 80%;
}
The following CSS is based on the picture-in-picture predefined layout:
stream.full {
position: absolute;
top: 0;
right: 0;
width: 100%;
height: 100%;
z-index: 100;
}
stream {
position: absolute;
right: 10%;
top: 10%;
width: 20%;
height: 20%;
z-index: 200;
}
Note: The CSS used by the predefined layouts are subject to change.
Use the OpenTok REST API to get information about a live streaming broadcast or to list live streaming broadcasts.
Currently, when you stop a live streaming broadcast, the last 5 seconds (prior to stopping the broadcast) of content from the OpenTok session are omitted from the broadcast stream.