NAV Navbar

Introduction

This is the documentation of the easylive.io APIs (REST and WebSocket).

Contact support@easylive.io for any question related to this documentation.

Use case examples:

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:
  • Organisation name
  • Language
  • Time zone
  • First and last name
  • Allowed customer's easylive.io zones
(doesn't include e-mail address, address & phone number)
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).
email 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:

  1. 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.
  2. 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.
  3. 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.

Image

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
email Always true.

{ "website": { "scope": 721527072, "people": { "get": true } } }

Success

Field Description
id The user id.
email 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
email 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.
email 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.stopAndRefreshfunction, 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.