Introduction
This is the documentation of the easylive.io APIs (REST and WebSocket).
Contact support@easylive.io for any question related to this documentation.
- the REST API: easylive.io methods for ingest streams management + user information.
- the WebSocket API: All the actions/methods used by the easylive.io platform.
Use case examples:
- REST API should be used by encoding or/and streaming software that would want to set up easylive.io ingest points automatically.
- WebSocket API should be used by any other external applications whishing to automate actions within the easylive.io services (graphics/videos insertion, DVR, simulcast, ingest fallback mechanism, etc...).
Visit https://easylive.io/en/features/ to learn more about easylive.io capabilities or e-mail contact@easylive.io to request additional features.
PRE-REQUIRED:
easylive.io Oauth client ID & secret key. E-mail contact@easylive.io to obtain your keys to the API.
OAuth 2.0 Authentication - Login and access
The following describes a two-step process where an easylive.io customer will grant your application access to its easylive.io account. A permanent access token is obtained on the completion of step 2.
1 - Invoking the login dialog and defining the redirect URL
Your app must initiate a redirection to an endpoint which will display the login dialog. Make sure to fill the scope appropriately according to which API/Methods are to be used.
HTTP Request
GET https://studio.easylive.io/auth/dialog/?client_id={client_id}
&redirect_uri={redirect_uri}
&scope={scope}
&state={state}
Query Parameters
Parameter | Description | |
---|---|---|
REQUIRED | client_id | Your app ID, sent by easylive.io. |
REQUIRED | redirect_uri | The URL where you want to redirect the person logging in back to. This URL will capture the response from the login dialog. |
REQUIRED | scope | A comma separated list of permissions requested to the person using your app. more information |
OPTIONAL | state | A 100 characters (or less) long arbitrary string created for your app to identify requests. easylive.io's authorization server will return it unaltered as a query parameter. |
Success Response
The user will be redirected to {redirect_uri} with the query parameters {code} and {state}:
Parameter | Description | |
---|---|---|
REQUIRED | code | A 100 characters (or less) string. "a-Z", "0-9" and "-" characters only. |
OPTIONAL | state | Parameter set as "state" in the query. |
{redirect_uri}?code={code}
Example:
https://your.website/callback.html?code=CharsHere&state=<state>
Error Response
{redirect_uri}?error={error}
Example:
https://your.website/callback.html?code=user%20canceled
2 - Generating an OAuth access token
To get an access token, send a HTTP GET request to the following OAuth endpoint:
HTTP Request
GET https:/studio.easylive.io/api/v1/oauth/access_token/?client_id={client_id}
&client_secret={client_secret}
&redirect_uri={redirect_uri}
&code={code}
Query Parameters
Parameter | Description |
---|---|
client_id | Your app ID, sent by easylive.io. |
client_secret | Your app Secret ID, sent by easylive.io. |
redirect_uri | Must be the same as step 1. |
code | Response code of step 1. |
JSON Response
A successful response will be a JSON dictionary:
{
"access_token" : ###,
"token_type" : "permanently",
"scope" : ###,
"state" : ###
}
Name | Description |
---|---|
access_token | 64 characters long token, "a-Z" & "0-9" only. Valid as long as the user doesn't revoke the authorization. |
token_type | Always “permanently”. |
scope | Allowed scope, same as step 1. |
state | Same as step 1. |
OAuth scopes
When requesting authorization from users, the scope parameter allows you to specify which permissions your app requires. These scopes are tied to the access token you receive upon a successful authorization. Without specifying scopes, your app only has access to basic information about the authenticated user. You may specify any or all of the following scopes:
Scope Name | Description |
---|---|
input_list | Can list inputs. |
input_create | Can add an input. |
user_about_me |
Provides access to:
|
websocket | Allows to manage control rooms with the WebSocket API. |
Scopes are specified as a +
separated list in the scope
query parameter when requesting authorization:
&scope=input_list+input_create
Rest API
Create an account
HTTP Request
POST https://https://ws-{region}.easylive.io/websocket/public/auth/create/
Content-Type: application/x-www-form-urlencoded; charset=UTF-8;
Query Parameters
Parameter | Description |
---|---|
region | The closest easylive.io region from your position. Possible values: us-ore-4 , us-vir-4 or eu-irl-4 . |
Body
Parameter | Description |
---|---|
time_zone | String - ISO timezone (i.e.: Europe/Paris ). |
String - Email address. |
|
phone | String - Phone number. |
first_name | String - First name. |
last_name | String - Last name. |
lang | String - Language. Possible values: en or fr . |
name | String - Company name. |
region | String - The closest easylive.io region from your position. Possible values: us-ore-4 , us-vir-4 or eu-irl-4 . |
pack | Contact us at contact@easylive.io to get your pack ID. |
{
"time_zone": "Europe/Paris"
"email": "email@example.com"
"phone": "0123456789"
"first_name": "John"
"last_name": "Snow"
"lang": "en"
"name": "Night's Watch"
"region": "us-ore-4"
"pack": "somethingFromOurEnd"
}
JSON Success Response
{
"apply": true,
"email": "email@example.com",
"has_send_mail": true
}
User about me
HTTP Request
GET https://studio.easylive.io/api/v1/user/about_me/?access_token={access_token}
Query Parameters
Parameter | Description |
---|---|
access_token | easylive.io OAuth access token. |
JSON Response
{
"zones": [
{
"id": "xxxxx",
"name": "USA East - Virginia"
}, {
"id": "yyyyy",
"name": "USA West - Oregon"
}, {
"id": "zzzzz",
"name": "Europe - Ireland"
}
],
"organisation_name": "Customer company",
"lang": {
"name": "English",
"iso": "en"
},
"time_zone": "America/New_York",
"user": {
"first_name": "John",
"last_name": "Do"
}
}
Name | Description |
---|---|
zones | List with at least one element. |
zones > id | String (40 characters max). |
zones > name | String (64 characters max). |
organisation_name | String (64 characters max). |
lang > iso | String (2 characters max) ISO code of the language (i.e.: "en"). |
lang > name | String (64 characters max). |
time_zone | String - The canonical name of the time zone. |
user > first_name | String (30 characters max). |
user > last_name | String (30 characters max). |
Input List
HTTP Request
GET https://studio.easylive.io/api/v1/input/list/?access_token={access_token}
&zone_id={zone_id}
&type_id={type_id}
Query Parameters
Parameter | Description | |
---|---|---|
REQUIRED | access_token | easylive.io OAuth access token. “input_list” scope required. |
REQUIRED | zone_id | Customer's zone ID, see user_about_me. |
OPTIONAL | type_id | To filter by type. Default: all inputs are returned. See the list of type_id. |
JSON Response
{
"list": [
{
"type": {
"name": "Other encoder",
"id": "other_push"
},
"title": "My Encoder",
"rtmp": {
"application": "live",
"server": "XXXX.easy.live",
"stream_name": "encoder_XXX_XXXXXX",
"port": 1935,
"url": "rtmp://XXXX.easy.live/live/encoder_XXXXXX"
},
"thumbnail_url": "https://s3-eu-west-1.amazonaws.com/eu-irl.el.static/camera/other_push.png"
},
...
]
}
Name | Description |
---|---|
list | List with at least one element. |
type > id | String (10 characters max). |
type > name | String (64 characters max). |
title | String (64 characters max). |
rtmp > application | String (16 characters max). |
rtmp > server | String (32 characters max). |
rtmp > stream_name | String (64 characters max). |
rtmp > port | Integer. |
rtmp > url | String (254 characters max). |
thumbnail_url | String (254 characters max). |
Input Create
HTTP Request
GET https://studio.easylive.io/api/v1/input/create/?access_token={access_token}
&zone_id={zone_id}
&type_id={type_id}
&title={title}
Query Parameters
Parameter | Description | |
---|---|---|
REQUIRED | access_token | easylive.io OAuth access token. “input_create” scope required. |
REQUIRED | zone_id | Customer's zone ID, see user_about_me. |
REQUIRED | type_id | One of the types, see the list of type_id. |
OPTIONAL | title | String (64 characters max). |
JSON Response
{
"create": “ok”
}
List of type_id
This list may be subject of changes.
Push inputs
id | Type |
---|---|
elStreamer | easylive.io streamer |
fmle | Flash Media Live Encoder |
obs | OBS - Open Broadcaster Software |
other_push | Other encoders |
teradek | Teradek |
wirecast | Wirecast |
vmix | vMix |
xsplit | Xsplit |
liveu | LiveU |
Pull inputs
id | Type |
---|---|
hdmi | HDMI |
sdi | SDI |
composite | Composite |
component | Component |
axis | Axis IP Camera |
web | Web streams (RTMP, M3U8...) |
WebRTC inputs
id | Type |
---|---|
rtc_pc_cam | WebRTC webcam |
rtc_pc_win | Screen sharing |
rtc_invite | Remote capture/Phone camera |
WebSocket API
EXAMPLE - MANUAL REQUEST WITH WEBSOCKET API:
You can use the following easylive.io - Example as both a working example of the full Oauth process and a WebSocket live connection manual request test page.
Fill in both the client ID & Secret, click on the GET button to obtain the access token. Follow the process and wait to be redirected to the easylive.io example page. Once you have the access token, click on the CONNECT button. You can then proceed with manual requests sending by copy-pasting JSON data from each request. The first request that has to be send is the INIT request.
To access the code of easylive.io - Example, send an e-mail to contact@easylive.io. You will then be able to open the Google Drive code folder.
Opening the API Websocket:
- Get the WebSocket access token using Oauth Doc. N.B: Token are permanents so you can do the operation manually once for your main account and store the token afterward.
- Open a WebSocket to the following URL:
wss://ws-<zone>.goeasy.live/websocket/public/client/?access_token=<your access token from step 1 above>
The zone parameter should be one of the zone the easylive.io client account has access to (Help - Zones). If needed, use User About Me to list the zones. - Once opened, all the requests detailed in this document can be sent through the WebSocket as JSON strings.
Init
The WebSocket requests can be done within two differents contexts. To switch context, the init message must be send
General init
Request
{
"init": false
}
Control Room init
Request
{
"init": <your control room ID>
}
To get the control room ID use List control rooms. Use the control room context to handle inputs, encoding presets, broadcaster output points, control room publishing status, etc….
Control Room
All the method in the control room section should be used within the general context. Exceptions are start test, start publish and stop publish.
List control rooms
Usable in a general context.
Request
Field | Description |
---|---|
name | scheduled or ended , to get the scheduled/ended lives information. |
page | Page number of the response (cf. page_count of the response). |
{
"website": {
"scope": 729709039,
"home": {
"action": "scheduled_ended",
"values": {
"name": "scheduled",
"page": 0
}
}
}
}
Success
Field | Description |
---|---|
count | Total number of control rooms scheduled or ended. |
page_count | Number of pages available for that request. |
boxs | Set of boxes. |
created | Control room's creation date. |
can_delete | Boolean to state whether it's possible to delete this live or not. |
start | State of the live stream, 0 : inactive/ended, 1 : test, 2 : publishing. |
archive_when_deleting | Former archive module, now useless. |
title | Name of the live stream. |
id | Control room ID. |
encrust_lan_id | Intern management field. |
preview | Preview image URL used on a wide range of broadcasters. |
ended | Live stream's end date. |
{
"customer": {
"error": null,
"scope": 729709039,
"home": {
"response": {
"count": {
"scheduled": 13,
"ended": 17
},
"page_count": 10,
"boxs": [
{
"created": "2018-05-28 06:43:00.000000",
"can_delete": true,
"start": 0,
"archive_when_deleting": false,
"title": "My wonderful stream",
"id": 4221,
"encrust_lan_id": false,
"preview": "https://tinyurl.com/y59so46l",
"ended": null
}
]
},
"action": "scheduled_ended"
}
}
}
Get default info
Used to create the default info for a control room. To be used in the control room creation method.
The get response and the creation request both have the same fields:
Field | Description |
---|---|
date | UTC datetime of the live stream. Format YYYY-MM-DD-HH-MM . Now if unset. |
description | Description of the live stream. |
facebook_sponsor_id | Sponsor ID if the live is sponsored on Facebook, empty string if not. |
facebook_stream_type | REGULAR : 4-hours max + VOD (on Facebook) / AMBIENT : no time limitation but no VOD. |
layout_id | Load a previous live stream layout if an ID is specified, -1 for a blank one (as a string). |
preview | Preview image URL used on a wide range of broadcasters. |
title | Name of the live stream. |
visibility | Visibility of the stream: public , private or no-list . |
Request
{
"website": {
"scope": 44840674,
"infos_init": true
}
}
Success
{
"customer": {
"infos_init": {
"visibility": "private",
"facebook_stream_type": "AMBIENT",
"facebook_sponsor_id": "",
"description": "Powered by easylive.io - easylive.io",
"date": "2018-02-07 15:23:32.206864",
"preview": "https://tinyurl.com/y59so46l",
"title": "Quick test"
"layout_id": "1604"
},
"scope": 44840674
}
}
Create a control room
Request
{
"website": {
"scope": 649729901,
"live_manager": {
"action": "create",
"values": {
"description": "My super description of my live event",
"visibility": "public",
"preview": "https://tinyurl.com/y59so46l",
"facebook_sponsor_id": "",
"facebook_stream_type": "Regular",
"title": "This is my live stream name!",
"date": "2019-02-18-16-00",
"layout_id": "-1"
}
}
}
}
Success
{
"customer": {
"error": null,
"scope": 649729901,
"live_manager": {
"id": 545
}
}
}
Edit the control room
Request
{
"website": {
"scope": 632772208,
"infos_set": {
"facebook_sponsor_id": "",
"title": "Meow",
"date": "2019-10-11-07-20",
"preview": "https://tinyurl.com/y59so46l",
"facebook_stream_type": "AMBIENT",
"description": "Powered by Easy Live - www.goeasylive.com",
"visibility": "public",
"hour": "9:20 AM",
"id": 27820
}
}
}
Success
{
"27820": {
"infos": {
"facebook_sponsor_id": "",
"title": "Meow",
"date": "2019-10-11 07:20:00.000000",
"preview": "https://tinyurl.com/y59so46l",
"facebook_stream_type": "AMBIENT",
"description": "Powered by Easy Live - www.goeasylive.com",
"visibility": "public"
},
"scope": 632772208,
"can_start_in": {
"duration": 0,
"date": "2019-10-11 07:20:00.000000"
}
}
}
Delete a control room
Request
Field | Description |
---|---|
id | Control room ID. |
{
"website": {
"scope": 779164690,
"home": {
"action": "scheduled_ended_delete",
"values": {
"id": 1234
}
}
}
}
Success
{
"customer": {
"home": {
"response": {},
"action": "scheduled_ended_delete"
},
"error": null,
"scope": 779164690
}
}
Start the testing phase
{
"website": {
"scope": 100508691,
"send_publish": {}
}
Stop the testing phase
{
"website": {
"scope": 304598169,
"send_stop": {}
}
}
Start the publishing phase
{
"website": {
"scope": 304598169,
"send_start": {}
}
}
Stop the publishing phase
{
"website": {
"scope": 304598169,
"send_stop": {}
}
}
Inputs
List the inputs
Request
To get all the inputs, you have to specify camera
as the model. Images, texts, videos and other assets are in the
{
"website": {
"scope": 552568526,
"objs": {
"action": "list",
"model": "camera"
}
}
}
Success
{
"customer": {
"input_list": [
{
"id": 88,
"title": "IP Axis",
"thumbnail": "https://s3-eu-west-1.amazonaws.com/eu-irl.el.static/camera/axis.png",
"description": "1280x720 HD READY (16/9) <br />IP: 192.168.0.13",
"image_url": "",
"is_type_push": false,
"stream_name": null
}
],
"scope": 552568526
}
}
Get an input's information
Request
{
"website": {
"scope": 48276231,
"objs": {
"action": "descriptor",
"model": "camera",
"object_id": 88
}
}
}
Success (Pull Input)
{
"customer": {
"box_id": 1234,
"objs": {
"action": "descriptor",
"model": "camera",
"box": 1234,
"values": [
{
"name": "axis",
"fields": [
{
"name": "name",
"label": "Name",
"default": "IP Axis"
},
{
"name": "input_custom",
"label": "Ip",
"default": "192.168.0.13"
},
{
"name": "input_size",
"label": "Video Capture",
"choices": [
["1280x720 HD READY (16/9)", "1280x720 HD READY (16/9)"],
["1920x1080 FULL HD (16/9)", "1920x1080 FULL HD (16/9)"]
],
"default": "1280x720 HD READY (16/9)"
}
],
"input": {},
"thumbnail": "https://s3-eu-west-1.amazonaws.com/eu-irl.el.static/camera/axis.png",
"label": "IP Axis",
"can_delete": false
}
]
},
"error": null,
"scope": 48276231
}
}
Success (Push Input)
Field | Description |
---|---|
server | The RTMP link used by the publishing phase. |
preview_server | The RTMP link used by the test phase. |
{
"customer": {
"box_id": 1234,
"objs": {
"action": "descriptor",
"model": "camera",
"box": 1234,
"values": [
{
"name": "obs",
"fields": [
{
"name": "name",
"label": "Name",
"default": "OBS - Open Broadcaster Software"
}
],
"input": {
"server": "rtmp://p.easy.live/live/",
"preview_server": "rtmp://eu-irl.easy.live/live/",
"type": "push",
"stream": "obs_randomKeyAndNumbers1234"
},
"thumbnail": "https://s3-eu-west-1.amazonaws.com/eu-irl.el.static/camera/obs.png",
"label": "OBS - Open Broadcaster Software",
"can_delete": false
}
]
},
"error": null,
"scope": 48276231
}
}
Add a new input
Please refer to the section activate an input to see how to add it to a line as a media asset.
List of input_type
This list may be subject of changes.
Push inputs
id | Type |
---|---|
elStreamer | easylive.io streamer |
fmle | Flash Media Live Encoder |
obs | OBS - Open Broadcaster Software |
other_push | Other encoders |
teradek | Teradek |
wirecast | Wirecast |
vmix | vMix |
xsplit | Xsplit |
liveu | LiveU |
Pull inputs
id | Type |
---|---|
hdmi | HDMI |
sdi | SDI |
composite | Composite |
component | Component |
axis | Axis IP Camera |
web | Web streams (RTMP, M3U8...) |
WebRTC inputs
id | Type |
---|---|
rtc_pc_cam | WebRTC webcam |
rtc_pc_win | Screen sharing |
rtc_invite | Remote capture/Phone camera |
Get default info
{
"website": {
"scope": 95988892,
"objs": {
"action": "descriptor",
"model": "camera"
}
}
}
Add a pull input
{
"website": {
"scope": 315761439,
"objs": {
"action": "edit",
"model": "camera",
"values": {
"input_type": "web",
"name": "My awesome RTMP",
"input_custom": "thertmplinkgoeshere"
s }
}
}
}
Add a push input
{
"website": {
"scope": 457989692,
"objs": {
"action": "edit",
"model": "camera",
"values": {
"input_type": "xsplit",
"name": "My fabulous Xsplit"
}
}
}
}
Success
{
"customer": {
"input_list": [
{
"id": 655,
"title": "My fabulous Xsplit",
"thumbnail": "https://s3-eu-west-1.amazonaws.com/eu-irl.el.static/camera/xsplit.png",
"description": " ",
"image_url": "",
"is_type_push": true,
"stream_name": "xsplit_655_War94m"
}
],
"scope": 457989692
}
}
Activate an input
Once added, the input will not be automatically added to the media assets. To achieve so, simply send the following request. It might be useful to take a loot at the lines section and the inputs information section before.
Request
Field | Description |
---|---|
action | Always unarchive . |
model | Always camera . |
object_id | The ID of the input that should be activated. |
line_id | The desired line where to activate the input. |
{
"website": {
"scope": 123456,
"objs": {
"action": "unarchive",
"model": "camera",
"object_id": 456,
"line_id": 123456789
}
}
}
Success
As a success, two different messages will be sent. One containing the scope used in the request, the second with all the draft display settings.
Scoped response:
{
"customer": {
"box_id": 987654,
"scope": 123456,
"error": null,
"objs": {
"action": "",
"box": 987654,
"model": "camera"
}
}
}
Generic response:
{
"1234": {
"draft_display_settings": [
<your draft display settings>
]
}
}
Archive an input
Request
Field | Description |
---|---|
action | Always archive . |
model | Always camera . |
object_id | The ID of the input that should be archived. |
{
"website": {
"scope": 140466141,
"objs": {
"action": "archive",
"model": "camera",
"object_id": 277
}
}
}
Success
{
"customer": {
"box_id": 1234,
"objs": {
"action": "archive",
"model": "camera",
"box": 1234
},
"error": null,
"scope": 140466141
}
}
Delete an input
Request
Field | Description |
---|---|
action | Always delete . |
model | Always camera . |
object_id | The ID of the input that should be deleted. |
{
"website": {
"scope": 140466141,
"objs": {
"action": "delete",
"model": "camera",
"object_id": 277
}
}
}
Success
{
"customer": {
"box_id": 1234,
"objs": {
"action": "delete",
"model": "camera",
"box": 1234
},
"error": null,
"scope": 140466141
}
}
Error
{
"customer": {
"box_id": 1767,
"objs": {
"action": "delete",
"model": "camera",
"box": 1767,
"error": "ERROR_ALREADY_IN_USED"
},
"error": "ERROR_ALREADY_IN_USED",
"scope": 765549192
}
}
{
"customer": {
"box_id": 1767,
"objs": {
"action": "delete",
"model": "camera",
"box": 1767,
"error": "ERROR_LIVE_RUNNING"
},
"error": "ERROR_LIVE_RUNNING",
"scope": 765549192
}
}
Media assets
Files upload
The easylive.io platform offers an upload service on Amazon Web Services servers. To do so, an URL must be created from the easylive.io API and then be used as a regular PUT request to Amazon. Although the service doesn't clearly state whether an upload is done or not, it is possible to send a recurrent GET request which will respond by 403
as long as the upload is going on.
Request
Field | Description |
---|---|
bucket | Upload bucket depending on the type. animation for videos, image for pictures, else (font, ...): static . |
directory | Directory of the upload: display for images, v2 for animations, font for fonts. |
width | The desired width of the picture (will be resized), 0 if no resize is required. |
height | The desired height of the picture (will be resized), 0 if no resize is required. |
alpha | Boolean, to precise if a picture has alpha or not (PNG). |
mime_type | MIME type, as {type}/{filetype} , see list below and IANA Media Types. |
{
"website": {
"scope": 954394435,
"uploads3_get": {
"directory": "display",
"bucket": "image",
"width": 0,
"height": 0,
"alpha": true,
"mime_type": "image/png"
}
}
}
Success
Through the response, signed_request
shall be used as a PUT request with the Content-Type
: image/{imagetype}
.
{
"customer": {
"uploads3_get": {
"signed_request": "https://www.some.url/complicated",
"url": "https://www.some.url/leading/to/a.picture",
"name": "path/to/a.picture"
},
"scope": 954394435
}
}
GET
As stated, there is no way to know if the upload is done or not. Thus, a GET request to the following link will response with a 403 Forbidden
for as long as the upload is still going on. <url>
being the field url
from the success response described above.
<url>.json
Manage media assets
Media assets are managed by a system called display_settings
. Two types exist: the draft_display_settings
, used by the preview, and the display_settings
, used by the production/program. The latter cannot be directly called, since everything done through the API first interacts with the preview which will then be applied on the production.
To edit the draft_display_settings
media assets, the current media assets list must be stored beforehand. To achieve so, it can be first found in the init
response message, path: init.customer.current_live.draft_display_settings
. This array shall be modify and set through the request to update the draft_display_settings
: if a media asset should be removed, just remove it from the list. Same goes for edition. To add one, just add the media object within it (more information below).
Request without cut to production
{
"website": {
"scope": 912129692,
"set_display_settings": [
{
"name": "placeholder_1",
"typename": "placeholder",
"line_id": 534768911
},
{
"name": "image_1",
"typename": "image",
"anim_type": "right_to_left",
"anim_time": 20,
"img_zoom": 100,
"transparency": 100,
"y": 369,
"x": 704,
"url": "https://www.some.url/leading/to/a.picture",
"natural_height": 512,
"natural_width": 512,
"line_id": 534768911,
"rotationX": 0,
"rotationY": 0,
"rotationZ": 0,
"effect_begin": "fadeIn",
"effect_begin_duration": 1,
"effect_begin_delay": 0,
"effect_end": "fadeOut",
"effect_end_duration": 1,
"effect_end_delay": 0,
"effect_init": "static",
"gs": 0,
"blur": 0,
"br": 100,
"ct": 100,
"huer": 0,
"opacity": 100,
"invert": 0,
"saturate": 100,
"sepia": 0
},
{
"name": "bg",
"autoplay": false,
"typename": "bg",
"effects": null,
"mask": "16/9"
}
]
}
}
Request to cut to production
{
"website": {
"scope": 912129692,
"goto_prod": [
"scoring",
"display"
]
}
}
Request with cut to production
{
"website": {
"scope": 912129692,
"set_display_settings": [
<your display settings>
],
"goto_prod": [
"scoring",
"display"
]
}
}
Success
{
"1608": {
"draft_display_settings": [
<your draft display settings>
],
"draft_messages_list": [
<your draft messages list>
],
"display_active": {
<your display active>
},
"font_list": [
{
"name": "magicNumbers&Letters13121997isMyBirthday",
"family": "Roboto",
"url": "https://www.some.url/complicated"
}
],
"scope": 403423651
}
}
Archive a video (animation
)
Request
Field | Description |
---|---|
action | Always archive . |
model | Always animation . |
object_id | The ID of the video that should be archived. |
{
"website": {
"scope": 123456789,
"objs": {
"action": "archive",
"model": "animation",
"object_id": 3801
},
"goto_prod": [
"display"
]
}
}
Success
{
"customer": {
"scope": 123456789,
"box_id": 29320,
"objs": {
"action": "",
"box": 29320,
"model": "animation"
},
"error": null
}
}
Delete a video (animation
)
Request
Field | Description |
---|---|
action | Always delete . |
values | Integer. The ID of the video that should be deleted. |
{
"website": {
"scope": 123456789,
"animation": {
"action": "delete",
"values": 3667
}
}
}
Success
{
"customer": {
"animation": {
"delete": true
},
"scope": 123456789
}
}
Error
{
"customer": {
"error": "ERROR_ALREADY_IN_USED",
"scope": 123456789
}
}
{
"customer": {
"error": "ERROR_LIVE_RUNNING",
"scope": 123456789
}
}
Media types
Find below a complete explanation of each media asset type. The table of this section gives a description of the common fields, as listed in the draft_display_settings
and in both the request and response messages (response only for animation
).
Even if inputs are managed as media assets, please refer to the specific input section for details, especially about how to create them.
For layers management and order, see the lines section.
About how toggle media assets, see the display section
More options are available, see optional fields.
Generic media types
Field | Description |
---|---|
id | The media asset's ID (animation only, response only). |
transparency | Opacity of the element, integer as percentage. |
typename | Type of media asset, within: animation , iframe , image , text , playlist or placeholder . |
y | Position on the y-axis (vertical) of the element within the video. |
x | Position on the x-axis (horizontal) of the element within the video. |
name | easylive.io name (auto-generated for animation ), as {typename}_{id} , see notice below. |
nice_name | Label of the media asset (field name for animation ). |
line_id | The line where to put the element, see lines section. |
img_zoom | Zoom to be applied on the media, float as percentage. |
Media type input
Field | Description |
---|---|
caching | A induced delay to play the feed on the easylive.io platform. Value in milliseconds, from 0 to 60000 . |
lcl | The media to be activated if the input were to stop (fallback). Supported media types are input , animation , image , iframe and twitter . To specify an element, use its name field (see above) or default_40970969627 for the default image. If an input is chosen, it also can be linked with a fail-safe media. Set none_40970969627 for none. The desired fallback media must be on the same line. |
Media type animation
Field | Description |
---|---|
loop | Auto-loop the animation. Values are true or false . |
rate | The speed of the playback. Value in range 33 to 200 . Must be sent as a string |
Media type bg
Field | Description |
---|---|
name | Always bg . |
autoplay | Boolean stating whether videos autoplays or not. |
typename | Always bg . |
effects | Always null for now. Undergoing development about animations - available soon. |
mask | Visual help for the preview area, regarding screen ratios within: 16/9 , 1/1 , 4/5 , 2/3 and 9/16 . |
Generic success (apart from animation
)
{
"1234": {
"draft_display_settings": [
<your draft display settings>
],
"draft_messages_list": [
<your draft messages list>
],
"display_active": {
<your display active>
},
"font_list": [
<your font list>
],
"scope": 699251016
}
}
Videos (animation
)
Request
The table below explains the properties within the values
field.
Field | Description |
---|---|
url | Video URL. |
height | Video height (pixels). |
width | Video width (pixels). |
display_aspect_ratio | String array of size 2 containing the display aspect ratio. |
sample_aspect_ratio | String array of size 2 containing the sample aspect ratio. |
duration | Duration of the video in milliseconds |
size | Video size (bytes). |
name | The video name, a label. |
{
"website": {
"scope": 209404193,
"animation": {
"action": "add",
"values": {
"url": "https://www.some.url/leading/to/a.video",
"height": 1080,
"width": 1920,
"display_aspect_ratio": [
"16",
"9"
],
"sample_aspect_ratio": [
"1",
"1"
],
"duration": 180000,
"size": 1234,
"line_id": 56789,
"name": "Video"
}
}
}
}
Success
The table below explains the property that weren't set through the values
object of the request.
Field | Description |
---|---|
thumbnail | Auto-generated thumbnail of the video. |
animation_url | Video link set through the url field. |
natural_height | Video height (pixels) set through the height field. |
natural_width | Video width (pixels) set through the width field. |
loop | Boolean stating whether the video is looping (infinite play) or played once. |
volume | Volume level, default: 256 . Range 0 to 12800 . |
{
"1612": {
"draft_display_settings": [
{
"name": "placeholder_1",
"typename": "placeholder",
"line_id": 13121997
},
{
"id": 205,
"transparency": 100,
"typename": "animation",
"size": 3497428,
"thumbnail": "https://www.some.url/leading/to/a.image",
"animation_url": "https://www.some.url/leading/to/a.video",
"natural_height": 1080,
"natural_width": 1920,
"duration": 5360,
"name": "animation_205",
"nice_name": "Video",
"loop": true,
"volume": 256,
"img_zoom": 50,
"y": 270,
"x": 480,
"line_id": 13121997
},
{
"name": "bg",
"autoplay": true,
"typename": "bg",
"effects": null,
"mask": "16/9"
}
]
}
}
Media Playlists (playlist
)
Create a new playlist
The table below explains the mandatory unmutable default properties to init the playlist object with.
Field | Description |
---|---|
id | Integer. A random number between 0 and 100000000, just like a scope. |
name | String. Always playlist_{id} . |
typename | String. Always playlist . |
thumbnail | String. Always https://static-us-vir.easylive.io/front/img/poster/notavailable-en-2020.gif . |
instagram-name | String. Always default . |
fit | String. Always cover . |
fitx | Integer. Always 1 . |
fity | Integer. Always 1 . |
rate | Integer. Always 1 . |
duration | Integer. Always 1 . |
size | Integer. Always 1 . |
natural_height | Integer. Always 1080 . |
natural_width | Integer. Always 1920 . |
volume-mute | Integer. Always 1 . |
gs | Integer. Always 0 . |
blur | Integer. Always 0 . |
br | Integer. Always 100 . |
ct | Integer. Always 100 . |
huer | Integer. Always 0 . |
invert | Integer. Always 0 . |
saturate | Integer. Always 100 . |
sepia | Integer. Always 0 . |
rotationX | Integer. Always 0 . |
rotationY | Integer. Always 0 . |
rotationZ | Integer. Always 0 . |
opacity | Integer. Always 100 . |
startDate | None. Always null . |
endDate | None. Always null . |
totalDuration | None. Always null . |
The table below explains the mandatory cutomizable properties to init the playlist object with.
Field | Description |
---|---|
elements | Array. Contains the media elements of the playlist. More info in the Playlist elements section. |
loop | Integer. Infinite loop is 0 . A positive integer will be used as the amount of iterations the playlist will be played. For example, 1 will play the whole playlist once then stop. |
Request
{
"website": {
"scope": 13121997,
"set_display_settings": [
{
"name": "playlist_23136798",
"id": 23136798,
"nice_name": "Playlist 1",
"typename": "playlist",
"transparency": 100,
"size": 1,
"thumbnail": "https://static-us-vir.easylive.io/front/img/poster/notavailable-en-2020.gif",
"natural_height": 1080,
"natural_width": 1920,
"duration": 1,
"loop": true,
"volume": 256,
"img_zoom": 100,
"y": 0,
"x": 0,
"fit": "cover",
"fitx": 50,
"fity": 50,
"rotationX": 0,
"rotationY": 0,
"rotationZ": 0,
"rate": 100,
"gs": 0,
"blur": 0,
"br": 100,
"ct": 100,
"huer": 0,
"opacity": 100,
"invert": 0,
"saturate": 100,
"sepia": 0,
"effect_end_delay": 0,
"effect_init": "static",
"effect_begin": "static",
"effect_begin_duration": 0,
"effect_begin_delay": 0,
"effect_end": "static",
"effect_end_duration": 0,
"instagram-name": "default",
"startDate": null,
"endDate": null,
"totalDuration": null,
"volume-mute": -1,
"elements": [],
"line_id": 88471340
},
{
"effects": null,
"autoplay": true,
"typename": "bg",
"name": "bg",
"mask": "16/9"
}
],
"goto_prod": [
"scoring",
"display"
]
}
}
Upload a media
Request
First, you need a AWS URL to share your file to. To get one, simply send the following request through the WebSocket:
{
"website": {
"scope": 558136060,
"uploads3_get": {
"directory": "v2",
"bucket": "animation",
"mime_type": "text/plain"
}
}
}
Response
The response will provide you with a link to be used to share your file, the signed_request
key:
`{ "customer": { "scope": 558136060, "uploads3_get": { "signed_request": "https://www.some.url/complicated", "url": "https://www.some.url/leading/to/smth", "name": "path/to/smth/complicated.ext" } }
}`
One the response obtained, store the url
& signed_request
keys. The url
will be your new file URL.
Now, send over your video link through a XHR PUT request to the signed_request
with the following information:
Header
x-amz-acl
: public-read
File
type
: text/plain
name
: nameOfYourVideo
file
: [videoUrl]
- A string array containing the video url
// JS Example
// First, let's create the File with the video's URL you wish to add
var file = new File(["https://www.some.url/leading/to/video.ext"], "MyVideoFile", {type: "text/plain"});
// Now, the XHR object is initiated and configured to send the data
var xhr = $.ajaxSettings.xhr();
xhr.open("PUT", signed_request);
xhr.setRequestHeader("x-amz-acl", "public-read");
xhr.send(file);
Success
The uploading final step may take some time to be processed: to check whether the upload is over or not, send a GET request to the url
key from the step before. As long as you get a 403
error code, the file isn't ready. Once the file is ready, you will receive the following response:
{
"original": {
"url": "https://www.some.url/leading/to/video.ext",
"width": 1280,
"height": 720,
"duration": 22344,
"probe": {
"streams": [
...
],
"format": {
...
}
},
"sample_aspect_ratio": [
"1",
"1"
],
"display_aspect_ratio": [
"16",
"9"
]
},
"png": {
"url": "https://www.some.url/leading/to/a.image",
"width": 1280,
"height": 720,
"duration": 0
},
"mini": {
"url": "https://www.some.url/leading/to/a_smaller.image",
"width": 96,
"height": 54,
"duration": 0
}
}
Add a new media
You can therefore now add the previously uploaded media to the playlist using the following request. Please keep in mind that most of the required fields expected are the one coming from the response request above.
Request
Field | Description |
---|---|
action | String. Always add . |
url | String. Response's original.url value. |
width | Integer. Response's original.width value. |
height | Integer. Response's original.height value. |
duration | Integer. Response's original.duration value. |
probe | Object. Response's original.probe value. |
sample_aspect_ratio | Array. Response's original.sample_aspect_ratio value. |
display_aspect_ratio | Array. Response's original.display_aspect_ratio value. |
size | Integer. Always 1 . |
thumbnail_url | String. Response's png.url value. |
name | String. The name you set in the XHR request. |
playlist_id | Integer. The playlist's ID to add the media to. |
{
"website": {
"scope": 252108532,
"animation": {
"action": "add",
"values": {
"url": "https://www.some.url/leading/to/video.ext",
"width": 1280,
"height": 720,
"duration": 22344,
"probe": {
...
},
"sample_aspect_ratio": [
"1",
"1"
],
"display_aspect_ratio": [
"16",
"9"
],
"size": 7650392,
"playlist_id": 23136798,
"name": "MyVideoFile",
"thumbnail_url": "https://www.some.url/leading/to/a.image"
}
}
}
}
Success
Field | Description |
---|---|
id | Integer. The media ID. |
{
"customer": {
"scope": 252108532,
"animation": {
"new_addition": {
"id": 13121997
}
}
}
}
Add a media from Media Bin
Media bin animations' are listed in the init
message response under the following key: init.customer.animations
.
To add a media from your Media Bin to a playlist, simply use the following request:
Request
Field | Description |
---|---|
object_id | Integer. The media ID. |
playlist_id | Integer. The Playlist ID. |
{
"website": {
"scope": 286389283,
"objs": {
"action": "unarchive",
"model": "animation",
"object_id": 13121997,
"playlist_id": 23136798
}
}
}
Success
{
"customer": {
"scope": 286389283,
"objs": {
"model": "animation",
"box": 1234,
"action": ""
},
"error": null,
"box_id": 1234
}
}
Playlist elements
The table below explains the elements
media properties once added within the playlist.
The following keys will not be explained because they already have been described above: id
, typename
, name
, nice_name
, x
, y
, natural_height
, natural_width
, img_zoom
, transparency
, duration
, size
, thumbnail
, animation_url
, volume
, volume-mute
.
Field | Description |
---|---|
hash | String. A unique identifier per playlist per media. Contains letters uppercase & lowercase & numbers. Do not edit. |
timestamp_start | Integer. Start time of the media. Cannot be higher than timestamp_stop or duration . Cannot be lower than 0 . Default: 0 . |
timestamp_stop | Integer. Stop time of the media. Cannot be higher than duration . Cannot be lower than timestamp_start or 0 . Default: duration . |
loop | Integer. Infinite loop is 0 . A positive integer will be used as the amount of iterations the playlist will be played. For example, 3 will play the media three times in a row and then skip to the next media. |
rate | Integer. Percentage of play rate, default is 100 . A lower value will slow the speed of the playback. A higher value will play it faster. Min: 33 , max: 200 . |
preferred_tracks | Object. Each key is a track type: video , audio and text . The value can be null , which means no track of said type, or an ID from the tracks key below. Only set an ID from the correct type of track. if 1 is a video track, it cannot be set as an audio track. |
probe | Object. Probe response from the upload request. |
tracks.video | Array. Contains the available tracks objects of the media's video tracks. |
tracks.audio | Array. Contains the available tracks objects of the media's audio tracks. |
tracks.text | Array. Contains the available tracks objects of the media's text tracks. |
The tracks object are built from the media probe
, which means the available tracks depend on the file metadata. If you need a media to have multiple audio/video/subtitle tracks, you need to encode your video with the needed tracks beforehand.
Field | Description |
---|---|
id | Integer. A unique identifier per track. Which means that there is no audio track 1 and video track 1 , IDs are not type-related. |
name | String. Built with the metadata available: "{trackName} - [{trackLang} ]" if there is a track name, else "Track #{trackId} - [{trackLang} ]". trackLang is deduced from the metadata, if unknown, will be set at und . |
{
"elements": [
{
"id": 5337,
"typename": "animation",
"name": "animation_5337",
"nice_name": "video_banner.mp4",
"x": 480,
"y": 270,
"natural_height": 720,
"natural_width": 1280,
"img_zoom": 75,
"transparency": 100,
"duration": 22344,
"size": 7650392,
"thumbnail": "https://www.some.url/leading/to/video.ext",
"animation_url": "https://www.some.url/leading/to/a.image",
"volume": 256,
"volume-mute": -1,
"hash": "nYHXxqedj3",
"timestamp_start": 0
"timestamp_stop": 22344,
"loop": "2",
"rate": 100,
"tracks": {
"video": [
{
"id": 0,
"name": "Track #0 - [und]"
}
],
"audio": [
{
"id": 1,
"name": "Track #1 - [French]"
}
],
"text": []
},
"preferred_tracks": {
"video": 0,
"audio": 1,
"text": null
},
"probe": {
...
},
}
]
}
Remove elements & empty playlist
To remove an element or many, use the draft_display_settings
object and remove from the array all the desired elements.
To keep the playlist object but get rid of all its elements, simply set the elements
key to the empty array value: []
.
Controls
Edit
To edit the playlist's or elements' loop
, preferred_tracks
, rate
, timestamp_start
, timestamp_stop
values, use the draft_display_settings
object: set the desired values and send it as usual.
Play
To start a playlist implicitly (without specifying a media), the following request must be sent.
This request will play the first media of the playlist after an init if no other elements has been played or is actually being played.
Field | Description |
---|---|
action | String. Always play . |
identifier | String. Always playlist_{playlistId} , {playlistId} being the ID sent back from the init request. |
{
"website": {
"scope": 96295433,
"player": {
"action": "play",
"identifier": "playlist_735882349"
}
}
}
To start a playlist explicitly (with a specific media), the following request must be sent.
Field | Description |
---|---|
action | String. Always play . |
identifier | String. The string playlist_{playlistId} , {playlistId} being the ID sent back from the init request. |
playlist_seek.hash | String. The hash of the media to be played. |
{
"website": {
"scope": 610097237,
"player": {
"playlist_seek": {
"hash": "nYHXxqedj3"
},
"action": "play",
"identifier": "playlist_735882349"
}
}
}
Pause
To pause a playlist, the following request must be sent.
Field | Description |
---|---|
action | String. Always pause . |
identifier | String. The string playlist_{playlistId} , {playlistId} being the ID sent back from the init request. |
{
"website": {
"scope": 434360662,
"player": {
"action": "pause",
"identifier": "playlist_735882349"
}
}
}
Seek
Seeking is a helpful way to switch to another media from the playlist. You can seek forward, seek backward, seek to the first media of the playlist or seek to the last media of the list.
Field | Description |
---|---|
identifier | String. The string playlist_{playlistId} , {playlistId} being the ID sent back from the init request. |
playlist_seek_next | Always null . Will seek to the next media in the playlist. If the current media is the last media, it will seek back to the first media of the playlist. |
playlist_seek_prev | Always null . Will seek to the previous media in the playlist. If the current media is the first media, it will seek back to the last media of the playlist. |
playlist_seek_first | Always null . Will seek to the first media in the playlist. If the current media is the first media, it will rewind the media (play it back from beginning). |
playlist_seek_last | Always null . Will seek to the last media in the playlist. If the current media is the last media, it will rewind the media (play it back from beginning). |
{ "website": { "scope": 463741979, "player": { "playlist_seek_next": null, "identifier": "playlist_735882349" } } }
Rewind
To rewind the current media, the following request must be sent. It will play the media back from its beginning, being the timestamp_start
value.
Field | Description |
---|---|
action | String. Always media_rewind . |
identifier | String. The string playlist_{playlistId} , {playlistId} being the ID sent back from the init request. |
{
"website": {
"scope": 274023108,
"player": {
"action": "media_rewind",
"identifier": "playlist_735882349"
}
}
}
Stop
To stop the playlist, the following request must be sent. It will pause the media currently being played and seek back to the first media of the playlist, in a paused state.
Field | Description |
---|---|
action | String. Always playlist_stop . |
identifier | String. The string playlist_{playlistId} , {playlistId} being the ID sent back from the init request. |
{
"website": {
"scope": 650030784,
"player": {
"action": "playlist_stop",
"identifier": "playlist_735882349"
}
}
}
Images (image
)
Request
Field | Description |
---|---|
url | The image's URl. |
natural_height | The real height of the given picture (not the desired size!). |
natural_width | The real width of the given picture (not the desired size!). |
{
"website": {
"scope": 615476078,
"set_display_settings": [
{
"name": "image_3",
"typename": "image",
"anim_type": "right_to_left",
"anim_time": 20,
"img_zoom": 100,
"transparency": 100,
"y": 390,
"x": 460,
"url": "https://www.some.url/leading/to/a.image"
"natural_height": 108,
"natural_width": 90,
"line_id": 56789
},
...
]
}
}
Webpages (iframe
)
Request
Field | Description |
---|---|
url | The webpage's URl. |
natural_height | The desired height of the webpage. |
natural_width | The desired width of the webpage. |
{
"website": {
"scope": 615476078,
"set_display_settings": [
{
"name": "iframe_1",
"typename": "iframe",
"x": 854,
"y": 434,
"img_zoom": 30,
"transparency": 100,
"natural_width": 1000,
"natural_height": 1000,
"url": "https://www.some.url/leading/to/a/webpage",
"line_id": 56789
},
...
]
}
}
Texts (text
)
Two text modes exist: unicolor and image. On unicolor mode, a colored background is used behind the text. On image mode, a picture can be used instead. The following table describe the generic fields for each mode, see below for specific changes. Animation fields are mandatory, please see the in/out animations section
Field | Description |
---|---|
group | Usually the id set in the name. Must be unique per text type assets. |
color | Text color, hexadecimal without # . |
marginTop | Top margin between the text and its background, expressed in pixels |
marginLeft | Left margin between the text and its background, expressed in pixels |
marginBottom | Bottom margin between the text and its background, expressed in pixels |
marginRight | Right margin between the text and its background, expressed in pixels |
text_align_x | Horizontal alignment of the text, values: left , center and right . |
text_align_y | Vertical alignment of the text, values: flex-start (top), center and flex-end (bottom). |
text_transparency | Opacity of the text, integer as percentage. |
fontfamily | The desired font identifier, found in any media assets response, font_list field name . |
text_x | Now useless. |
text_y | Now useless. |
size | Font size, default: 42 , because, well, it's The Answer to the Ultimate Question of Life, The Universe, and Everything. |
bgType | Type of background, between unicolor and image . |
message_type | Display type for the messages: single or loop_inf . |
time_display | Number of seconds for each message on loop_inf mode, -1 (infinite) on single mode. |
width | Width of the background division, integer as pixels. |
height | Height of the background division, integer as pixels. |
cbWidth | Boolean stating if the width value should be use as width, else auto-fitting the text. |
cbHeight | Boolean stating if the height value should be use as height, else auto-fitting the text. |
messages | Array containing the messages, see table below. |
anim_type | Transition animation. See in/out animations section. |
anim_time | Transition time. See in/out animations section. |
messages
Field | Description |
---|---|
id | A random number between 0 and 100000000, just like a scope. |
text | Text message. |
display | Boolean stating whether the message is activated or not. |
Request (unicolor)
Field | Description |
---|---|
typename | text . |
bg | Background color, hexadecimal without # . |
only_text | Always true . |
{
"website": {
"scope": 615476078,
"set_display_settings": [
{
"name": "title_11",
"group": 11,
"color": "FFFFFF",
"marginTop": 30,
"marginLeft": 50,
"marginBottom": 30,
"marginRight": 50,
"only_text": true,
"text_align_x": "left",
"text_align_y": "flex-start",
"text_transparency": 100,
"fontfamily": "magicNumbers&Letters13121997isMyBirthday",
"text_x": 0,
"text_y": 0,
"size": 42,
"bg": "131313",
"typename": "text",
"img_zoom": 100,
"params": [],
"transparency": 100,
"y": 840,
"x": 60,
"bgType": "unicolor",
"message_type": "single",
"time_display": -1,
"messages": [
{
"id": 123456789,
"text": "Put your text here!",
"display": true
}
],
"width": 960,
"height": 540,
"cbHeight": false,
"cbWidth": false,
"effect_begin": "fadeInRight",
"effect_begin_delay": 0,
"effect_begin_duration": 1500,
"effect_end": "fadeOutLeft",
"effect_end_delay": 0,
"effect_end_duration": 1500,
"effect_init": "static",
"anim_type": "top_to_bottom",
"anim_time": 10,
"line_id": 575730951
},
...
]
}
}
Request (image)
Field | Description |
---|---|
typename | image . |
url | The URL of the image to be used. |
natural_height | The real height of the given picture (not the desired size!). |
natural_width | The real width of the given picture (not the desired size!). |
{
"website": {
"scope": 615476078,
"set_display_settings": [
{
"name": "title_12",
"group": 12,
"typename": "image",
"anim_type": "fadeInDown",
"color": "FFFFFF",
"text_align_x": "left",
"text_align_y": "flex-start",
"text_transparency": 100,
"anim_time": 10,
"fontfamily": "magicNumbers&Letters13121997isMyBirthday",
"text_x": 0,
"text_y": 0,
"size": 50,
"img_zoom": 100,
"transparency": 100,
"y": 400,
"x": 300,
"bgType": "image",
"message_type": "loop_inf",
"time_display": 3,
"messages": [
{
"id": 123456789,
"text": "My amazing title!",
"display": true
},
{
"id": 987654321,
"text": "And its little brother!",
"display": true
}
],
"effect_begin": "fadeInRight",
"effect_end": "fadeOutLeft",
"marginTop": 35,
"marginLeft": 50,
"marginBottom": 30,
"marginRight": 50,
"bg": "131313",
"line_id": 575730951,
"cbWidth": true,
"width": 960,
"cbHeight": false,
"height": 540,
"rotationX": 0,
"rotationY": 0,
"rotationZ": 0,
"effect_begin_duration": 1400,
"effect_begin_delay": 0,
"effect_end_duration": 1500,
"effect_end_delay": 0,
"effect_init": "static",
"gs": 0,
"blur": 0,
"br": 125,
"ct": 80,
"huer": 0,
"opacity": 100,
"invert": 0,
"saturate": 140,
"sepia": 35,
"url": "https://www.some.url/leading/to/a.image",
"natural_height": 110,
"natural_width": 90,
"instagram-name": "walden"
},
...
]
}
}
Lines (display_settings
)
Lines are a main component of the easylive.io platform's logic. Lines are ordered following a layer principle, such as CSS z-index
, which means that elements are on top of each others, so that some will hide others.
Thus, the order is found within the draft_display_settings
: the first elements are on the background and the last elements of the array are the ones on the foreground. Each line is first indicated by a placeholder
before the elements contained in the said line. Elements are listed from left to right: first elements following the placeholder
are on the right, then it goes to the left.
On the easylive.io platform, media assets and lines would be sorted as in the following. Only the position of each line is an indicator: line 2
the closest to the foreground, while line 4
os the closest to the background (reverse order in the draft_display_settings
). Bold media assets are the ones selected (displayed).
Line | Placeholder | Media assets |
---|---|---|
2 | 6 | A |
6 | 1 | B - C - D |
1 | 4 | F - G |
4 | 2 | E |
In this configuration, element A will be displayed in front of element C, which will be displayed in front of element E. There is no selected element on line 1. This will produce following draft_display_settings
list:
{
"1234": {
"draft_display_settings": [
{
"name": "placeholder_2",
"typename": "placeholder",
"line_id": 4
},
{
"name": "element_E",
"typename": "whatever",
"line_id": 4
},
{
"name": "placeholder_4",
"typename": "placeholder",
"line_id": 1
},
{
"name": "element_F",
"typename": "whatever",
"line_id": 1
},
{
"name": "element_G",
"typename": "whatever",
"line_id": 1
},
{
"name": "placeholder_1",
"typename": "placeholder",
"line_id": 6
},
{
"name": "element_B",
"typename": "whatever",
"line_id": 6
},
{
"name": "element_C",
"typename": "whatever",
"line_id": 6
},
{
"name": "element_D",
"typename": "whatever",
"line_id": 6
},
{
"name": "placeholder_6",
"typename": "placeholder",
"line_id": 2
},
{
"name": "element_A",
"typename": "whatever",
"line_id": 2
},
{
"name": "bg",
"autoplay": true,
"typename": "bg",
"effects": null,
"mask": "16/9"
}
]
}
}
Request
Send the following to add a new line.
Field | Description |
---|---|
name | easylive.io name, as placeholder_{id} , see the 1st warning of media types. |
typename | Always placeholder . |
line_id | A random number between 0 and 100000000, just like a scope |
{
"website": {
"scope": 880655100,
"set_display_settings": [
{
"name": "placeholder_2",
"typename": "placeholder",
"line_id": 123456789
},
...
]
}
}
Display (display_active
)
The display_active
works closely with the display_settings
: where the latter state what are the available media assets and where are they displayed, the first one states which ones are active or not.
The display_active
also uses a draft_display_active
, which is applied as display_active
once a goto_prod
has been set. Hence, a set_display_active
and a goto_prod
can also be grouped in the same message, just like draft_display_settings
.
The draft_display_active
is found in the init
message response, path: init.customer.current_live.draft_display_active
, or in any response of a set_display_active
.
It works as a key/value list, where the key is the name
of the related media asset and the value is either False
(hidden) or a random number between 1 and 100000000 (shown).
Request
{
"website": {
"scope": 725016544,
"set_display_active": {
"image_1": 154511110,
...
},
"goto_prod": [
"scoring",
"display"
]
}
}
Optional fields
Rotation
Field | Description |
---|---|
rotationX | Rotation the x-axis, integer as degrees, range: 0 to 360 . |
rotationY | Rotation the y-axis, integer as degrees, range: 0 to 360 . |
rotationZ | Rotation the z-axis, integer as degrees, range: 0 to 360 . |
Filters (image
)
Field | Description |
---|---|
instagram-name | Filter preset, named after Instagram ones. Values: default (none), 1977 , aden , amaro , ashby , brannan , brooklyn , charmes , clarendon , crema , dogpatch , earlybird , gingham , ginza , hefe , helena , hudson , inkwell , juno , kelvin , lark , lofi , ludwig , maven , mayfair , moon , nashville , perpetua , poprocket , reyes , rise , sierra , skyline , slumber , stinson , sutro , toaster , valencia , vesper , walden , willow and xpro-ii . See example page. |
gs | Grayscale, integer as percentage, range: 0 to 100 . |
blur | Blur, integer as percentage, range: 0 to 10 (each step count for x10, so 1 is 10%, 7 is 70%, so on). |
br | Brightness, integer as percentage, range: 0 to 200 . |
ct | Contrast, integer as percentage, range: 0 to 200 . |
huer | Hue rotation, integer as degrees, range: 0 to 360 . |
invert | Color inversion, integer as percentage, range: 0 to 100 . |
saturate | Saturation, integer as percentage, range: 0 to 500 . |
sepia | Sepia, integer as percentage, range: 0 to 100 . |
opacity | Opacity, integer as percentage, range: 0 to 100 . |
In/out animations
In and out animations can be played on almost every media assets.
Field | Description |
---|---|
effect_begin | Animation type, see table below. |
effect_begin_duration | Duration of the in animation, in milliseconds. |
effect_begin_delay | Duration of the delay before the in animation, in milliseconds. |
effect_end | Animation type, see table below. |
effect_end_duration | Duration of the out animation, in milliseconds. |
effect_end_delay | Duration of the delay before the out animation, in milliseconds. |
effect_init | Animation effect, running infinitely, see table below. |
anim_type | Type of animation transition between two texts, only for messages . |
anim_time | Time of animation transition between two texts, only for messages , in seconds x10 (10 is 1 second, 45 is 4 seconds and a half). |
In and out animations list
In | Out | Description |
---|---|---|
fadeIn | fadeOut | Classical fade effect |
bounceIn | bounceOut | Bounce |
bounceInDown | bounceOutDown | Bounce down |
bounceInLeft | bounceOutLeft | Bounce left |
bounceInRight | bounceOutRight | Bounce right |
bounceInUp | bounceOutUp | Bounce up |
fadeInDown | fadeOutDown | Fade down |
fadeInLeft | fadeOutLeft | Fade left |
fadeInRight | fadeOutRight | Fade right |
fadeInUp | fadeOutUp | Fade up |
fadeInDownBig | fadeOutDownBig | Fade down further |
fadeInLeftBig | fadeOutLeftBig | Fade left further |
fadeInRightBig | fadeOutRightBig | Fade right further |
fadeInUpBig | fadeOutUpBig | Fade up further |
flipInX | flipOutX | Flip horizontal |
flipInY | flipOutY | Flip vertical |
rotateIn | rotateOut | Rotate |
rotateInDownLeft | rotateOutDownLeft | Rotate down-left |
rotateInDownRight | rotateOutDownRight | Rotate down-right |
rotateInUpLeft | rotateOutUpLeft | Rotate up-left |
rotateInUpRight | rotateOutUpRight | Rotate up-right |
slideInDown | slideOutDown | Slide down |
slideInLeft | slideOutLeft | Slide left |
slideInRight | slideOutRight | Slide right |
slideInUp | slideOutUp | Slide up |
zoomIn | zoomOut | Zoom |
zoomInDown | zoomOutDown | Zoom down |
zoomInLeft | zoomOutLeft | Zoom left |
zoomInRight | zoomOutRight | Zoom right |
zoomInUp | zoomOutUp | Zoom up |
rollIn | rollOut | Barrel roll |
lightSpeedIn | lightSpeedOut | Very fast movement |
jackInTheBox | Centered fade in then wiggle a bit | |
hinge | Hinge out |
Animation effects list
Field | Description |
---|---|
static | Basically does nothing. |
pulse | Slight pulse effect. |
cube | A 3D cube rotating from left to right. |
cubereverse | A 3D cube rotating from right to left. |
bounce | High bounce then smaller ones. |
flash | Vivid flash effect. |
rubberBand | Stretch and wobble effect. |
shake | Horizontal shake effect. |
swing | Up-right/up-left swing effect. |
tada | Vivid zoom and wobble effect. |
wobble | Large wobble effect. |
jello | Bottom-left/up-right stretch then jelly effect. |
flip | Wide zoom in and right-to-left flip. |
headShake | Simlar to shake but less wide. |
heartBeat | Similar to tada but without the wobble effect. |
Encoding presets
Get current encoding presets
You'll receive all the encoding presets in the init
request, fields init.customer.current_live.raw_to_raw
and init.customer.current_live.raw_to_encoded
.
It's important to distinguish raw_to_raw
to raw_to_encoded
. Once your encoding presets are set, add Publishing points and configure them.
raw_to_raw
correspond to the Format
field on the platform (Publish
panel) while the raw_to_encoded
correspond to the Quality
field. Both fields are linked by the source
field only in the raw_to_encoded
array, where the concerned raw_to_raw
ID is set.
Description
The set and get requests has the same body. Please find below the description of each field.
Formats - raw_to_raw
Field | Description |
---|---|
id | Format's ID. It's not recommanded to change the main one (default: mixer ). |
source | main : always mixer_in , others: always mixer . |
label | Format's label, usually main for main and Program feed with the resolution's details: Resolution {width}x{height} - {fps} fps - {resize_method} - {sample_rate} - {channels} for the other formats. No specific value required. |
audio | Always allow . |
video | Always allow . |
closed_captions | Always allow . |
size_method | main : resolution , for the other formats: see table below. |
resize_method | main : stretch , for the other formats: see table below. |
width | Width without unit, depending on the size_method , see table below. Pixels for main . Must be higher than 0 . See table below for main possible values. |
height | Height without unit, depending on the size_method , see table below. Pixels for main . Must be higher than 0 . See table below for main possible values. |
fps | Frame rate multiplied by 1000 (some questions don't have answers), i.e.: 60 fps = 60000. Can also be copy for other formats (will take the main format's value). Must be in range 5000 - 60000 . |
sample_rate | Audio sample rate, 44100 or 48000 . Can also be copy for other formats (will take the main format's value). |
channels | Audio channels, stereo (also 2 ) or mono (also 1 ). Can also be copy for other formats (will take the main format's value). |
enable | Boolean stating whether the format is active or not, only for non-main formats. |
main width/height
Width | Height |
---|---|
640 | 360 |
800 | 450 |
1024 | 576 |
1280 | 720 |
1920 | 1080 |
size_method
Option | Size unit | Description |
---|---|---|
copy | Main | Copy the main encoding preset's size_method , width and height . |
resolution | Pixels | Classic resolution expressed with pixels. |
aspect_ratio | Ratio | Ratio as width :height . Common ratios: 16:9 , 1:1 , 4:5 , 2:3 and 9:16 . |
max_resolution | Pixels | The video will not be resized if it's small enough but will be stretched if too big. |
resize_method
Option | Description |
---|---|
crop | The video will be cropped vertically or horizontally to fit the specified resolution. |
letterbox | Black lines will be added vertically or horizontally to fit the specified resolution. |
stretch | The video will be stretched to fit the specified resolution. |
Success
{
"1234": {
"raw_to_raw": [
{
"id": "mixer",
"source": "mixer_in",
"label": "main",
"audio": "allow",
"video": "allow",
"closed_captions": "allow",
"size_method": "resolution",
"resize_method": "stretch",
"width": 1280,
"height": 720,
"fps": 60000,
"sample_rate": 44100,
"channels": 2
},
{
"source": "mixer",
"audio": "allow",
"video": "allow",
"closed_captions": "allow",
"enable": true,
"size_method": "resolution",
"width": 1080,
"height": 720,
"resize_method": "crop",
"fps": 30000,
"sample_rate": "44100",
"channels": "stereo",
"id": "format_3",
"label": "Program feed - Resolution 1080x720 - 30 fps - Crop - 44100 - stereo"
},
{
"source": "mixer",
"audio": "allow",
"video": "allow",
"closed_captions": "allow",
"enable": true,
"size_method": "aspect_ratio",
"width": 1,
"height": 1,
"resize_method": "crop",
"fps": 60000,
"sample_rate": "copy",
"channels": "copy",
"id": "format_4",
"label": "Program feed - Aspect Ratio 1:1 - 60 fps - Crop"
}
],
"scope": 715825245
}
}
Qualities - raw_to_encoded
Field | Description |
---|---|
run_start | Always test . |
id | Quality's ID. main : main . |
label | Quality's label. main : main . |
outputs | Only for main - outputs linked to that quality, as a JSON array. Only one output is supported. See default value below. |
params | Quality's parameters as a JSON object. See table below. |
source | The format linked to that quality, as the format's ID. |
outputs
The value should always be the one below. Don't forget to set your zone within: eu-irl
, us-vir
and us-ore
. Do not edit the output_link
part!
"outputs": [
{
"label": "default save rtmp",
"id": "save",
"type": "rtmp",
"params": {
"url": "rtmp://<your-zone>.easy.live/live/%(output_link)s"
},
"run_start": "test"
}
]
params
JSON Object with two objects within: audio
and video
.
Field | Description |
---|---|
audio.codec | Always aac . |
audio.bitrate | Audio's bitrate. Range 16 to 384 . |
video.profile | Video's profile within: main and baseline . |
video.bitrate | Video's bitrate. Range 16 to 40960 . |
video.preset | Video's preset within: ultrafast , superfast , veryfast , faster , fast , medium and slow . |
video.codec | Awlays h624 . |
Success
{
"1234": {
"raw_to_encoded": [
{
"id": "main",
"source": "mixer",
"label": "main",
"run_start": "test",
"params": {
"video": {
"bitrate": "20480",
"codec": "h264",
"preset": "medium",
"profile": "main"
},
"audio": {
"codec": "aac",
"bitrate": "128"
}
},
"outputs": [
{
"id": "save",
"label": "save",
"type": "rtmp",
"run_start": "test",
"params": {
"url": "rtmp:/eu-irl.easy.live/live/%(output_link)s"
}
}
]
},
{
"source": "format_3",
"run_start": "test",
"label": "encoded_3",
"enable": true,
"params": {
"video": {
"bitrate": "800",
"preset": "medium",
"profile": "main",
"codec": "h264"
},
"audio": {
"bitrate": "64",
"codec": "aac"
}
},
"outputs": [],
"id": "encoded_3"
},
{
"source": "format_3",
"run_start": "test",
"label": "encoded_4",
"enable": false,
"params": {
"video": {
"bitrate": 2048,
"preset": "ultrafast",
"profile": "main",
"codec": "h264"
},
"audio": {
"bitrate": 128,
"codec": "aac"
}
},
"outputs": [],
"id": "encoded_4"
},
{
"source": "format_4",
"run_start": "test",
"label": "encoded_5",
"enable": true,
"params": {
"video": {
"bitrate": 2048,
"preset": "ultrafast",
"profile": "main",
"codec": "h264"
},
"audio": {
"bitrate": 128,
"codec": "aac"
}
},
"outputs": [],
"id": "encoded_5"
}
],
"scope": 109075449
}
}
Manage encoding presets
To add, edit or remove an encoding preset, it's quite simple: just send your new configuration! The body is the same as the one received, a JSON Array with JSON objects. To add a new one, add an object within the array. To remove it, remove the preset from the array. To edit it, change its values.
Requests
{
"website": {
"scope": 602845136,
"set_raw_to_raw": [
<list of your formats>
]
}
}
{
"website": {
"scope": 602845136,
"set_raw_to_encoded_": [
<list of your qualities>
]
}
}
Success
The success message will be the list of the raw_to_raw
/raw_to_encoded
presets, depending on which one has been updated.
Publishing points
List the external services
Request
{
"website": {
"scope": 878575860,
"external_services": {
"list": true
}
}
}
Success
The list of all your linked social media accounts and personnal publishing points (Custom RTMP, ...). Useful data are in the broadcaster
array of each service.
{
"1234": {
"external_services": {
"services": {
"awss3": {
"auth_method": "awss3",
"status": {
"error": null,
"connected": true
},
"about": {
"description": "some.name.like.this",
"image_url": null,
"url": null,
"credentials": {
"api_key": "magicNumbers&Letters13121997isMyBirthday",
"secret_key": "magicNumbers&Letters13121997isMyBirthday",
"region": "eu-west-1",
"bucket_name": "some.name.like.this"
}
}
},
"facebook": {
"auth_method": "oauth",
"status": {
"error": null,
"connected": true
},
"about": {
"description": "Your Name",
"image_url": "https://www.some.url/complicated",
"url": null
},
"broadcasters": [
{
"identifier": "123456789",
"description": "Your Name",
"image_url": "https://www.some.url/complicated",
"status": null,
"error": null,
"facebook_type": "user",
"url": null,
"fields": []
},
{
"identifier": "123456789",
"description": "Consommer Juste",
"image_url": "https://www.some.url/complicated",
"status": null,
"error": null,
"url": "https://www.some.url/with/your/account/name",
"facebook_type": "page",
"facebook_perms": [
"ADMINISTER",
"EDIT_PROFILE",
"CREATE_CONTENT",
"MODERATE_CONTENT",
"CREATE_ADS",
"BASIC_ADMIN"
],
"fields": []
}
]
},
"twitch": {
"auth_method": "oauth",
"status": {
"error": null,
"connected": true
},
"about": {
"description": "Your Name",
"image_url": "https://www.some.url/complicated",
"url": "https://www.some.url/with/your/account/name"
},
"broadcasters": [
{
"identifier": "123456789",
"description": "Your Name",
"image_url": "https://www.some.url/complicated",
"status": {
"video": {
"id": null,
"url_publish": null,
"source": "encoded_3",
"session_id": "magicNumbers&Letters13121997isMyBirthday",
"need_publish": false,
"stream_key": null,
"url_preview": null,
"private_data": {},
"embed_html": null,
"dash_preview_url": null,
"embed_url": null,
"access_token": null
},
"state": "init",
"source": "encoded_3",
"session_id": "magicNumbers&Letters13121997isMyBirthday"
},
"error": null,
"url": "https://www.some.url/with/your/account/name",
"fields": []
}
]
},
"twitter": {
"auth_method": "oauth",
"status": {
"error": null,
"connected": true
},
"about": {
"description": "Support_Easylive",
"image_url": "https://www.some.url/complicated",
"url": "https://www.some.url/with/your/account/name"
}
},
"periscope": {
"auth_method": "oauth",
"status": {
"error": null,
"connected": true
},
"about": {
"description": "Your Name",
"image_url": "https://www.some.url/complicated",
"url": "https://www.some.url/with/your/account/name"
},
"broadcasters": [
{
"identifier": "magicNumbers&Letters13121997isMyBirthday",
"description": "Your Name",
"image_url": "https://www.some.url/complicated",
"status": null,
"error": null,
"url": "https://www.some.url/with/your/account/name",
"fields": []
}
]
},
"dailymotion": {
"auth_method": "oauth",
"status": {
"error": null,
"connected": true
},
"about": {
"description": "Your name",
"image_url": "https://www.some.url/complicated",
"url": "https://www.some.url/with/your/account/name"
},
"broadcasters": [
{
"identifier": "magicNumbers&Letters13121997isMyBirthday",
"identifier": 1234,
"description": "Your Name",
"image_url": "https://www.some.url/complicated",
"status": {
"video": {
"id": "magicNumbers&Letters13121997isMyBirthday",
"url_publish": null,
"source": "encoded_3",
"session_id": "magicNumbers&Letters13121997isMyBirthday",
"need_publish": false,
"stream_key": null,
"url_preview": null,
"private_data": {},
"embed_html": null,
"dash_preview_url": null,
"embed_url": "https://www.some.url/with/your/video/name"
"access_token": null
},
"state": "created",
"source": "encoded_3",
"session_id": "magicNumbers&Letters13121997isMyBirthday"
},
"error": null,
"url": "https://www.some.url/with/your/video/name"
"fields": []
}
]
},
"youtube": {
"auth_method": "oauth",
"status": {
"error": null,
"connected": true
},
"about": {
"description": "Your Name",
"image_url": "https://www.some.url/complicated",
"url": "https://www.some.url/with/your/account/name"
},
"broadcasters": [
{
"identifier": "magicNumbers&Letters13121997isMyBirthday",
"description": "Your Name",
"image_url": "https://www.some.url/complicated",
"status": null,
"error": null,
"url": "https://www.some.url/with/your/video/name"
"fields": []
}
]
},
"easylive": {
"auth_method": null,
"status": {
"error": null,
"connected": true
},
"about": {
"description": null,
"image_url": null,
"url": null
},
"streams": {
"1": "Some Name"
},
"broadcasters": [
{
"identifier": "output_save",
"description": "",
"image_url": null,
"easylive_type": "save",
"status": {
"video": {
"id": null,
"url_publish": null,
"source": "main",
"session_id": "output_save",
"need_publish": false,
"stream_key": null,
"url_preview": null,
"private_data": {},
"embed_html": null,
"dash_preview_url": null,
"embed_url": null,
"access_token": null
},
"state": "created",
"source": "main",
"session_id": "output_save"
},
"error": null,
"url": null,
"fields": []
},
{
"identifier": 1234,
"description": "Some Name",
"image_url": null,
"easylive_type": "other",
"status": {
"video": {
"id": null,
"url_publish": null,
"source": "encoded_3",
"session_id": "magicNumbers&Letters13121997isMyBirthday",
"need_publish": false,
"stream_key": null,
"url_preview": null,
"private_data": {},
"embed_html": null,
"dash_preview_url": null,
"embed_url": null,
"access_token": null
},
"state": "created",
"source": "encoded_3",
"session_id": "magicNumbers&Letters13121997isMyBirthday"
},
"error": null,
"url": null,
"fields": {
"nick_name": "Some Name",
"stream_name": "Some Name",
"path": "rtmp://some.ip.v4.address/live"
}
}
]
},
"dropbox": {
"auth_method": "oauth",
"status": {
"error": null,
"connected": true
},
"about": {
"description": "Your Name",
"image_url": "https://www.some.url/complicated",
"url": null
}
}
},
"live_id": 1234
},
"error": "success"
}
}
Authorize a new service
This simply cannot be done through the websocket API. To authorize a specific service, a human interaction is needed and cannot be faked (OAuth token). Also, this would require to handle personnal and sensitive information. A customer can log into social media services through the easylive.io platform.
In order to broadcast to a specific service, a custom RTMP publishing point can be used. This solution implies that the authorization with the service is handled beforehand on the customer's side and not by the easylive.io API itself. The stream's name and key being then provided by the said service.
Add a publishing point
Only the values
field may change depending on the type of publishing point you're trying to add.
Field | Description |
---|---|
input_type | Don't be mislead by its name: it's the type of the publishing point to be created. Options are: other , akamai and multistreams . |
nick_name | The publishing point label. |
path | The URL to publish to. Only for other & akamai . |
stream_name | The stream name or stream key. Only for other & akamai . |
stream | The video stream ID to be broadcasted. Only for multistreams . |
Request type other
{
"website": {
"scope": 95787873,
"objs": {
"action": "edit",
"model": "broadcast",
"values": {
"input_type": "other",
"nick_name": "My brand new custom RTMP",
"stream_name": "yourAwesomeStreamnNameOrKey",
"path": "rtmp://192.168.0.1"
}
}
}
}
Request type akamai
{
"website": {
"scope": 668818267,
"objs": {
"action": "edit",
"model": "broadcast",
"values": {
"input_type": "akamai",
"nick_name": "My Akamai publishing point",
"stream_name": "something_like_this@randomNumbers",
"path": "rtmp://some.letters.and.digits.akamaientrypoint.net/EntryPoint"
}
}
}
}
Request type multistreams
{
"website": {
"scope": 678452895,
"objs": {
"action": "edit",
"model": "broadcast",
"values": {
"input_type": "multistreams",
"stream": "5678"
}
}
}
}
Success
{
"1234": {
"external_services": {
"services": {
<your list of services>
},
"live_id": 1234
},
"error": "success"
}
}
Select a publishing point
The request to select a publishing point is quite the same for all the services available. The main differences are within the infos
field.
broadcast_select
Field | Description |
---|---|
identifier | The identifier of the desired publishing point as an integer, found within the external_services list, path: services.MY_SERVICE.broadcasters[MY_BROADCASTER].identifier . |
service | Type of service within: facebook , twitch , periscope , dailymotion , youtube and easylive (Custom RTMP). |
source | Video source, the ID of the desired quality , see Encoding preset. |
infos | Infos needed by the service, see table below. Custom RTMP (easylive ) is always {} (empty object). |
infos
The Service
column specifies which services need the referred field. Legend: FB
- Facebook, YT
- YouTube, DM
- Dailymotion, P
- Periscope, T
- Twitch.
Field | Service | Description |
---|---|---|
preview | FB , YT , DM |
Image URL used as a preview cover. |
title | FB , YT , DM , P , T |
Name of the live stream as shown on the service. |
description | FB , YT , DM |
A description of the live stream. |
visibility | FB , YT , DM |
Visibility within: private , public and no-list . |
facebook_sponsor_id | FB |
Sponsor ID in case of a sponsored live. |
facebook_stream_type | FB |
Type of Facebook Live, see Control Room info. |
Request
{
"website": {
"scope": 653489811,
"broadcast_select": {
"identifier": 123456,
"service": "youtube",
"source": "encoded_3",
"infos": {
"preview": "https://www.some.url/complicated",
"title": "My live stream",
"description": "My description",
"visibility": "public"
}
}
}
}
Success
{
"1234": {
"external_services": {
"services": {
<your list of services>
},
"live_id": 1234
},
"error": "success"
}
}
Unselect a publishing point
Request
The value of session_id
is found within the concerned broadcaster
in the external_services
list. Path: services.MY_SERVICE.broadcasters[MY_BROADCASTER].status.session_id
. This value is indeed only available if the said publishing point has been previously selected.
{
"website": {
"scope": 838423480,
"external_services": {
"broadcaster": {
"terminate": {
"session_id": "magicNumbers&Letters13121997isMyBirthday"
}
}
}
}
}
Success
{
"1234": {
"error": "success",
"scope": 838423480
}
}
Delete a publishing point
Once a publishing point has been unselected, it can be removed if not used anylonger. The value of object_id
is the identifier
field in the external_services
list, path: services.MY_SERVICE.broadcasters[MY_BROADCASTER].identifier
.
Request
{
"website": {
"scope": 589117168,
"objs": {
"action": "delete",
"model": "broadcast",
"object_id": 1234
}
}
}
Success
{
"1234": {
"external_services": {
"services": {
<your list of services>
},
"live_id": 1234
},
"error": "success"
}
}
WebRTC
Manage WebRTC inputs
External modules can use our generic API to exchange WebRTC data, by using the following signaling protocol.
Signaling protocol
To initiate a WebRTC communication, the following request must be sent.
Field | Description |
---|---|
peerid | A generic name (label). Usually the current date and a random number between 0 and 100000000 separated by a _ . |
stream | The WebRTC name. Found in the draft_display_settings , under the desired WebRTC element, field stream_name . |
video | Always true . |
audio | Always true . |
max_size | An array describing the max size of the video. Syntax [width , height ]. |
{
"webrtc_publish": {
"peerid": "061920191557_13121997",
"stream": "rtc_pc_cam_1312_97hello",
"video": true,
"audio": true,
"max_size":[640,360]
}
}
The following success callback will be then sent by the API.
{
"webrtc_publish_ready": {
"peerid": "061920191557_13121997",
"stream": "rtc_pc_cam_1312_97hello",
"pid": 1234
}
}
The following error callback will be then sent by the API.
{
"webrtc_publish_error": {
"peerid": "061920191557_13121997",
"stream": "rtc_pc_cam_1312_97hello",
"code": 1,
"error": "Error reason here"
}
}
If a success callback has been received, send the SDP offer.
{
"webrtc_input_to_camping_1234": {
"peerid": "061920191557_13121997",
"type": "offer",
"sdp": "The SDP data here"
}
}
As well as the ICE candidates.
{
"webrtc_input_to_camping_1234":{
"type":"candidate",
"peerid":"061920191557_13121997",
"candidate":{
"candidate":"candidate:131297...",
"sdpMid": "audio",
"sdpMLineIndex": 0
},
...
}
}
Once everything has been received and processed, the WebRTC will send back its SDP answer.
{
"webrtc_input_from_camping_1234": {
"peerid": "061920191557_13121997",
"sdp": "v=0\r\no=- 13121997....\r\n",
"type": "answer"
}
}
The ICE candidates are sent too.
{
"webrtc_input_from_camping_1234": {
"signaling_candidate": {
"candidate": "candidate:19971312....",
"peerid": "061920191557_13121997",
"sdpMLineIndex": 0,
"sdpMid": "audio"
}
}
}
Example
Click here to open it.
Manage WebRTC outputs
Coming soon!
Scoring
Add a scoring
First, the scoring app must be added to the control room. To achieve so, just send a set_display_settings
with a scoring
object as described below.
Request
Field | Description |
---|---|
name | Always scoring . |
typename | Always scoring . |
layout | Display layout, either inline or col . |
size | Text size of the team names. |
size_score | Text size of the scores. |
with_bg | Boolean stating wether the scoring has a colored background or not. |
fg_logo | Integer in range 1 to 6 , can also be auto . See explanation below. |
fg_team | Integer in range 1 to 6 , can also be auto . See explanation below. |
fg_player1 | Integer in range 1 to 6 , can also be auto . See explanation below. |
fg_player2 | Integer in range 1 to 6 , can also be auto . See explanation below. |
fg_player | Integer in range 1 to 6 , can also be auto . See explanation below. |
fg_game | Integer in range 1 to 6 , can also be auto . See explanation below. |
fg_set | Integer in range 1 to 6 , can also be auto . See explanation below. |
fg_point | Integer in range 1 to 6 , can also be auto . See explanation below. |
fg_sub_game | Integer in range 1 to 6 , can also be auto . See explanation below. |
bg_color_team | Background color of the teams name. Hexadecimal color as a string, without # . Only used with with_bg at true . |
color_team | Color of the teams name. Hexadecimal color as a string, without # . Only used with with_bg at true . |
bg_color_point | Background color of the points. Hexadecimal color as a string, without # . Only used with with_bg at true . |
color_point | Color of the points. Hexadecimal color as a string, without # . Only used with with_bg at true . |
bg_color_set | Background color of the sets. Hexadecimal color as a string, without # . Only used with with_bg at true . |
color_set | Color of the sets. Hexadecimal color as a string, without # . Only used with with_bg at true . |
bg_color_game | Background color of the games. Hexadecimal color as a string, without # . Only used with with_bg at true . |
color_game | Color of the games. Hexadecimal color as a string, without # . Only used with with_bg at true . |
All of the fg
fields represent the space taken by each visual element. Not all elements are used at the same time, for instance fg_set
is used only in tennis mode. The value given works as a CSS flex-grow
value, which means that for a given space, the element will take a specific ratio of space, according to the space taken by its siblings. The auto
mode will auto-adjust the space taken accordingly to the content inside.
If element A has a fg
specified at 1
and element B has a fg
specified at 3
, B will take 3 times more space than A. See this page for more information.
{
"website": {
"scope": 334644321,
"set_display_settings": [
{
"name": "scoring",
"typename": "scoring",
"img_zoom": 100,
"x": 100,
"y": 100,
"natural_width": 400,
"natural_height": 130,
"marginRight": 20,
"marginLeft": 20,
"fontfamily": "magicNumbers&Letters13121997isMyBirthday",
"size": 30,
"with_bg": true,
"fg_logo": "auto",
"fg_team": "4",
"fg_player1": "4",
"fg_player2": "4",
"fg_player": "4",
"fg_game": "1",
"fg_set": "1",
"fg_point": "1",
"fg_sub_game": "1",
"layout": "col",
"size_score": 30,
"bg_color_team": "000000",
"color_team": "ffffff",
"bg_color_point": "000000",
"color_point": "ffffff",
"bg_color_set": "000000",
"color_set": "ffffff",
"bg_color_game": "000000",
"color_game": "ffffff",
"line_id": 602854010
}
],
"goto_prod": [
"scoring",
"display"
]
}
}
Success
The following table describes the fields of an object within the scoring
object. This differs from one sport type to another, see sports section
Field | Description |
---|---|
config | String containing the sport type, within: foot , rugby , basket , volley , tabletennis , tabletennismatch , padel2players , karate and other . |
goto_prod | Boolean stating if a modification should be directly cut to production or not. |
score.point.value | Number of points. |
score.point.size | Maximum value length (number of units). |
name.team.value | Team's name. |
name.team.size | Maximum team's name length. |
logo | Image URL used as team logo. |
{
"1234": {
"scoring": {
"teams": [
{
"score": {
"point": {
"value": 0,
"size": 3
}
},
"name": {
"team": {
"value": "Team 1",
"size": 12
}
},
"logo": ""
},
{
"score": {
"point": {
"value": 0,
"size": 3
}
},
"name": {
"team": {
"value": "Team 2",
"size": 12
}
},
"logo": ""
}
],
"config": "rugby",
"goto_prod": false
},
"scope": 886098813
}
}
Edit a scoring
To add a goal, retrieve a goal, change a team's name or anything else, the whole scoring
object must be sent as a string, with the said modifications. The best way to achieve so, is to store the object and keep it updated. A JSON stringify method must be used.
Request
{
"website": {
"scope": 799560411,
"scoring": "{
Success
Will return the same response as the scoring addition request.
Sports
Different kind of scorings are available. Please find below each configuration for each sport.
foot
, rugby
, basket
, karate
and other
{
"teams": [
{
"score": {
"point": {
"value": 0,
"size": 3
}
},
"name": {
"team": {
"value": "Team 1",
"size": 12
}
},
"logo": ""
},
{
"score": {
"point": {
"value": 0,
"size": 3
}
},
"name": {
"team": {
"value": "Team 2",
"size": 12
}
},
"logo": ""
}
]
}
volley
{
"teams": [
{
"score": {
"set": {
"value": 0,
"size": 1
},
"point": {
"value": 0,
"size": 2
}
},
"name": {
"team": {
"value": "Team 1",
"size": 12
}
},
"logo": ""
},
{
"score": {
"set": {
"value": 0,
"size": 1
},
"point": {
"value": 0,
"size": 2
}
},
"name": {
"team": {
"value": "Team 2",
"size": 12
}
},
"logo": ""
}
]
}
tabletennis
{
"teams": [
{
"score": {
"set": {
"value": 0,
"size": 1
},
"point": {
"value": 0,
"size": 2
}
},
"name": {
"team": {
"value": "Team 1",
"size": 12
},
"player": {
"value": "Player 1",
"size": 20
}
},
"logo": ""
},
{
"score": {
"set": {
"value": 0,
"size": 1
},
"point": {
"value": 0,
"size": 2
}
},
"name": {
"team": {
"value": "Team 2",
"size": 12
},
"player": {
"value": "Player 2",
"size": 20
}
},
"logo": ""
}
]
}
padel2players
{
"teams": [
{
"score": {
"set": {
"value": 0,
"size": 1
},
"sub_game": {
"value": 0,
"size": 2
}
},
"name": {
"player1": {
"value": "First Player 1",
"size": 20
},
"player2": {
"value": "Second Player 1",
"size": 20
}
},
"logo": ""
},
{
"score": {
"set": {
"value": 0,
"size": 1
},
"sub_game": {
"value": 0,
"size": 2
}
},
"name": {
"player1": {
"value": "First Player 2",
"size": 20
},
"player2": {
"value": "Second Player 2",
"size": 20
}
},
"logo": ""
}
]
}
tabletennismatch
{
"teams": [
{
"score": {
"game": {
"value": 0,
"size": 2
},
"set": {
"value": 0,
"size": 1
},
"point": {
"value": 0,
"size": 2
}
},
"name": {
"team": {
"value": "Team 1",
"size": 12
},
"player": {
"value": "Player 1",
"size": 20
}
},
"logo": ""
},
{
"score": {
"game": {
"value": 0,
"size": 2
},
"set": {
"value": 0,
"size": 1
},
"point": {
"value": 0,
"size": 2
}
},
"name": {
"team": {
"value": "Team 2",
"size": 12
},
"player": {
"value": "Player 2",
"size": 20
}
},
"logo": ""
}
]
}
Audio
Modify the audio settings
Request
Field | Description |
---|---|
set_volume | Integer indicating the volume, in range 0 (0%) to 12800 (5000%), default (100%): 256 . |
{
"website": {
"scope": 13541639,
"set_volume": 256,
"goto_prod": [
"volume"
]
}
}
Success
{
"1234": {
"draft_volume": 12800,
"prod_volume": 12800,
"scope": 260239874
}
}
Account management
Create an account
Request
The following table describes the fields within the customer_append
object.
Field | Description |
---|---|
lang | Account language, en (English) or fr (French). If not specified, will inherit the parent's account language. |
zone | easylive.io zone: eu-irl-1 , us-vir-1 , us-ore-1 , eu-irl-4 , us-vir-4 or us-ore-4 . Contact easylive.io if needed. |
name | Account name. |
{
"website": {
"scope": 123456,
"customer_append": {
"lang": "en",
"zone": "eu-irl-4",
"name": "Project Name"
}
}
}
Error
{
"customer": {
"error": "empty_name",
"scope": 123456
}
}
Success
{
"customer": {
"customer_append": {
"id": 654321,
"zone": "eu-irl-4"
},
"scope": 123456
}
}
Edit account users
Field | Description |
---|---|
field | Rank to be edited. Either is_active (user) or is_manager (admin). |
value | Boolean value, true or false . |
user_id | User to be affected, the ID can be found in the init general context response, init.user.id . |
Request to set user rights (editor
)
{
"website": {
"scope": 191558316,
"people": {
"set": {
"field": "is_active",
"value": false,
"user_id": "someLettersAndNumbers13121997"
}
}
}
}
Success
{
"customer": {
"customer_remove": {
"id": "654321"
},
"scope": 123456
}
}
Request to set manager rights (admin
)
{
"website": {
"scope": 191558316,
"people": {
"set": {
"field": "is_manager",
"value": false,
"user_id": "someLettersAndNumbers13121997"
}
}
}
}
Success
{
"customer": {
"customer_remove": {
"id": "654321"
},
"scope": 123456
}
}
Delete an account
Request
{
"website": {
"customer_remove": {
"id": 654321
},
"scope": 123456
}
}
Success
{
"customer": {
"customer_remove": {
"id": "654321"
},
"scope": 123456
}
}
List accounts
Request (without search pattern)
{
"website": {
"customer_list": {
page: 0,
search:""
},
"scope": 123456
}
}
Request (with search pattern)
Field | Description |
---|---|
search | An approximate search pattern, such as an account name or its ID. |
{
"website": {
"customer_list": {
page: 0,
search: "yoursearchpattern"
},
"scope": 123456
}
}
Success
{
"customer": {
"customer_list": {
"more": true,
"list": [
{
"id": 123,
"name": "easylive.io - 1",
"zone": "eu-irl-4"
},
{
"id": 456,
"name": "easylive.io - 2",
"zone": "us-vir-4"
},
{
"id": 789,
"name": "easylive.io - 3",
"zone": "us-ore-4"
},
{
"id": 987,
"name": "easylive.io - 4",
"zone": "eu-irl-1"
},
{
"id": 654,
"name": "easylive.io - 5",
"zone": "us-vir-1"
}
]
},
"scope": 123456
}
}
Request (more results)
{
"website": {
"customer_list": {
page: 1,
search: "yoursearchpattern"
},
"scope": 123456
}
}
List the users of a project (account
)
Request
Field | Description |
---|---|
Always true . |
{
"website": {
"scope": 721527072,
"people": {
"get": true
}
}
}
Success
Field | Description |
---|---|
id | The user id. |
The email address of the user. | |
name | The name of the user. |
is_active | Boolean. If true , the user can access the said account (manage control rooms and access calendar). |
is_manager | Boolean. If true , the user can manage the said account (add/remove users, edit account information, manage billing and payment methods). |
{
"customer": {
"people": [
{
"is_manager": true,
"name": "User One",
"is_active": true,
"email": "usermail@domainname.ext",
"id": "0102030405azeRTY"
},
{
"is_manager": false,
"name": "Player Two",
"is_active": true,
"email": "otheremail@example.com",
"id": "0102030405azeRTY"
}
]
}
}
Add a user to a project (account
)
Request
Field | Description |
---|---|
The email address of the user to be added. An email will be sent as an account creation request if the user doesn't exists. |
{
"website": {
"scope": 123456,
"people": {
"add": {
"email": "usermail@domainname.ext"
}
}
}
}
Success
Field | Description |
---|---|
id | The user id. |
The email address of the user. | |
name | The name of the user. |
is_active | Boolean. If true , the user can access the said account (manage control rooms and access calendar). |
is_manager | Boolean. If true , the user can manage the said account (add/remove users, edit account information, manage billing and payment methods). |
{
"customer": {
"people": [
{
"is_manager": true,
"name": "User One",
"is_active": true,
"email": "usermail@domainname.ext",
"id": "0102030405azeRTY"
},
{
"is_manager": false,
"name": "Player Two",
"is_active": true,
"email": "otheremail@example.com",
"id": "0102030405RTYaze"
}
]
}
}
Edit users rights
Request
Field | Description |
---|---|
field | The role to be edited. is_active : can access the project. is_manager : can manage the billing and personnal information. |
value | Boolean. Either true (will activate) or false (will deactivate). |
user_id | The user ID. Can be found in the list of users. |
{
"website": {
"scope": 255067344,
"people": {
"set": {
"field": "is_manager",
"value": true,
"user_id": "0102030405aBcDeF"
}
}
}
}
Success
{
"customer": {
"people": [
{
"is_manager": true,
"name": "User One",
"is_active": true,
"email": "usermail@domainname.ext",
"id": "0102030405azeRTY"
},
{
"is_manager": true,
"name": "Harry Potter",
"is_active": true,
"email": "harry.potter@hedwige.owl",
"id": "0102030405aBcDeF"
}
]
}
}
WebSocket - Scope
The WebSocket request scope is a random number between 0
and 100000000
. This can be considered as the unique ID of a request.
It should be uniquely generated for each request sent to the server and expected to be returned in the server's response. Requests and responses are linked this way.
The mandatoriness of the scope depends of each request.
WebRTC library
You can you can take advantage of the power of our webRTC management system without dealing with the full API. You just need our web RTC library !
Library implementation
To be able to use the WEBRTC library, you must implement the corresponding script tag at the end of your HTML code. Don't forget to implement this script on each page requiring the library functions.Once the script tag is set up, you just need to call the library functions thanks to "window.webRTLib.functionName".
E-mail contact@easylive.io to obtain your webRTC library script tag.
Functions list
Init Connection
Our solution is based on Selective Forwarding Unit (SFU), which is one of the most popular architectures for WebRTC. To get or create connection, you can use webRTCLib.init
. It requires a single object containing two keys :
Parameter | Type | Status | Description |
---|---|---|---|
ws | Object |
(REQUIRED) | Websocket. |
id | Integer |
(REQUIRED) | Your live number. |
withData | Boolean |
(OPTIONAL) - Default: false | Allows you to retrieve the monitoring data or not. |
update | Function |
(REQUIRED) | Refers to each stream that arrives. It returns in parameter a stream with two elements : settings (quality) a srcObject object, and stream name. |
isRunning | Function |
(REQUIRED) | Allows to know if a feed should be launched by your page. It takes the stream name and the settings as parameters. |
You can call the function as in the example below, while initializing a websocket :
window.webRTCLib.init({
ws : window.websocket,
id : 55930,
withData: false,
isRunning: isRunning,
update: playerUpdate
});
Update SFU Connection
You can update an existing connection with your server infos. The function webRTCLib.updateSfu
will check if the server returns webrtc_server or webrtc_data_server info. If it's the case, each available peer will be updated according to the information returned (participants, update, etc.)
Parameter | Type | Status | Description |
---|---|---|---|
serverInfos | Object |
(REQUIRED) | Server infos. |
You can use this function while updating you current live infos, for example :
window.webRTCLib.updateSfu(serverInfos);
Stop connection
Thanks to the webRTCLib.stopAndRefresh
function, you can stop and delete all active peer connections, then automatically update your stream infos. It requires only one argument :
Parameter | Type | Status | Description |
---|---|---|---|
streamId | Integer |
(REQUIRED) | Stream id for update after stopping peer connections. |
window.webRTCLib.stopAndRefresh(streamId);
Add listener on data
You can add a listener on your data thanks to webRTCLib.addDataListener
. It requires two parameters :
Parameter | Type | Status | Description |
---|---|---|---|
name | String |
(REQUIRED) | Listener target. |
callback | Function |
(REQUIRED) | Custom callback function. |
For example, if you need to add a listener on your encoder store, you can proceed like this :
window.webRTCLib.addDataListener( "encoderStore", encoderStore.update );
Add a new stream
The webRTCLib.add
function will create a new stream based on the arguments passed :
Parameter | Type | Status | Description |
---|---|---|---|
videoContainer | Object |
(REQUIRED) | DOM element containing your video. |
videoName | String |
(REQUIRED) | Video name in the stream store. |
settingsName | String |
(REQUIRED) | Settings name in WebRTC settings, same as videoName. |
boxId | Integer |
(REQUIRED) | Your live number. |
output | Boolean |
(OPTIONAL) - Default : false | Video output status. |
settings | Object |
(OPTIONAL) - Default : {} | Video settings. |
withStatus | Boolean |
(OPTIONAL) - Default : true | Show video status |
container | Object |
(OPTIONAL) - Default : videoContainer parent | videoContainer parent. |
websocket | Object |
(OPTIONAL) - Default : window.websocket | Websocket. |
The settings parameters will mainly contain the desired quality for your stream. Several options are available :
Quality | Description |
---|---|
fake | No video, only audio |
mobile | 256 15fps (video bitrate = max 300kbps) |
sd | max 640 15fps (video bitrate = max 1000kbps) |
hd | max 1280 30fps (video bitrate = max 3000kbps) |
fhd | max 1920 30fps (video bitrate = max 6000kbps) |
window.webRTCLib.add({
videoContainer: this.videoContainer,
videoName: "video_01",
settingsName: "video_01",
output: false,
settings: { quality : "hd" },
withStatus: false,
container : null,
boxId : 55930,
websocket : this.websocket
});
Remove a stream
For each stream contained in the specified container, you'll delete it from stream store. After removing, the stream list will be automatically updated thanks to the given identifier. The webRTCLib.remove
function will run based on these parameters :
Parameter | Type | Status | Description |
---|---|---|---|
container | Object |
(REQUIRED) | Object containing your streams. |
identifier | Integer |
(REQUIRED) | Your live number. |
callback | Function |
(OPTIONAL) | Custom callback function. |
The callback function will be applied on each stream in the specified container.
window.webRTCLib.remove(
this.container,
this.liveNumber,
function(name){
audioMaster.releaseStream( name );
}
);
Set or update stream settings
If you want to set or update the parameters of a stream, for example your stream quality, you just need to use the webRTCLib.setSettings
function.
If your stream does not yet have its own settings, the function will assign the settings in parameters. Otherwise, the settings will simply be updated.
If the settings change, then the stream will be automatically restarted.
Parameter | Type | Status | Description |
---|---|---|---|
streamName | String |
(REQUIRED) | Stream name in the stream store. |
settings | Object |
(REQUIRED) | New stream parameters. |
The settings parameters will mainly contain the desired quality for your stream. Several options are available :
Quality | Description |
---|---|
fake | No video, only audio |
mobile | 256 15fps (video bitrate = max 300kbps) |
sd | max 640 15fps (video bitrate = max 1000kbps) |
hd | max 1280 30fps (video bitrate = max 3000kbps) |
fhd | max 1920 30fps (video bitrate = max 6000kbps) |
window.webRTCLib.setSettings("stream-2021", {quality: "hd"});
Get streams from stream store
With webRTCLib.getFromStreamStore
, you can retrieve all the streams available in the stream store, or retrieve only one thanks to its name
Parameter | Type | Status | Description |
---|---|---|---|
streamName | String |
(OPTIONAL) | Stream name in the stream store. |
//Get all streams available in stream store
window.webRTCLib.getFromStreamStore();
//Get a specific stream window.webRTCLib.getFromStreamStore("stream-2021");
Delete a stream from stream store
You can easily delete a specific stream from the stream store with the webRTCLib.deleteFromStreamStore
function.
Parameter | Type | Status | Description |
---|---|---|---|
streamName | String |
(REQUIRED) | Stream name in the stream store. |
callback | Function |
(OPTIONAL) | Custom callback function. |
const callback = audioMaster.releaseStream( streamName );
window.webRTCLib.deleteFromStreamStore(streamName, callback);
Refresh a stream in the stream list
You can easily refresh a specific stream with the webRTCLib.updateStream
function.
Parameter | Type | Status | Description |
---|---|---|---|
streamId | String |
(REQUIRED) | Stream identifier in the stream list. |
window.webRTCLib.updateStream(streamName);
Get a specific stream and its peer connection
With the webRTCLib.getStreamAndPeer
function, you'll be able to get SFU connection and stream infos.
Parameter | Type | Status | Description |
---|---|---|---|
identifier | String |
(REQUIRED) | Your live number. |
streamName | String |
(REQUIRED) | Stream identifier in the stream list. |
settings | String |
(REQUIRED) | Stream settings. |
window.webRTCLib.getStreamAndPeer(currentLiveId, streamName, settings);
This function will return and object with two keys :
Parameter | Type | Description |
---|---|---|
peer | Object |
Peer linked to the given identifier. |
srcObject | Object |
Stream infos. |
Get ICE servers
You can get ICE servers list with the webRTCLib.getIceServers
function. It does not require any parameters.
const ices = window.webRTCLib.getIceServers();
WebRTCLib error message
Our library may sometimes returns error messages, especially when creating a peer connection.
These errors are handled by the webRTCLib.onErrorMessage
function, which performs a console.error of the returned message by default.
The following messages you might encounter are :
Error code | Description |
---|---|
network-issue | You have lost the network connection. An attempt to reconnect is in progress |
url-already-in-use | This URL is already in use by another element in your project. |