Introduction
This is the documentation of the LiveU Studio APIs (REST and WebSocket).
Contact support@liveu.tv for any question related to this documentation.
- the REST API: LiveU Studio methods for ingest streams management + user information.
- the WebSocket API: All the actions/methods used by the LiveU Studio platform.
Use case examples:
- REST API should be used by encoding or/and streaming software that would want to set up LiveU Studio ingest points automatically.
- WebSocket API should be used by any other external applications whishing to automate actions within the LiveU Studio services (graphics/videos insertion, DVR, simulcast, ingest fallback mechanism, etc...).
PRE-REQUIRED:
LiveU Studio Oauth client ID & secret key. E-mail support@liveu.tv to obtain your keys to the API.
OAuth 2.0
The following describes a two-step process where an LiveU Studio customer will grant your application access to its LiveU Studio account. A permanent access token is obtained on the completion of step 2.
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
GEThttps://studio.liveu.tv/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 LiveU Studio. |
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. LiveU Studio'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
To get an access token, send a HTTP GET request to the following OAuth endpoint:
HTTP Request
GET https:/studio.studio.liveu.tv/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 LiveU Studio. |
client_secret | Your app Secret ID, sent by LiveU Studio. |
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. |
{
"error" : “###”
}
Where "error" can be:
- "A required GET parameter is missing (client_id)"
- "A required GET parameter is missing (client_secret)"
- "A required GET parameter is missing (code)"
- "A required GET parameter is missing (redirect_uri)"
- "Bad client_id": client_id {client_id_passed} not found
- "Bad code": {code_passed} not found
- "Redirect_uri doesn't match"
- "client_id doesn't match"
- "client_secret doesn't match"
When requesting authorization from users, the scope parameter allows you to specify which permissions your app requires. These scopes are tied to the access token you receive upon a successful authorization. Without specifying scopes, your app only has access to basic information about the authenticated user. You may specify any or all of the following scopes:
Scope Name | Description |
---|---|
input_list | Can list inputs. |
input_create | Can add an input. |
user_about_me | Provides access to:
|
websocket | Allows to manage control rooms with the WebSocket API. |
Scopes are specified as a +
separated list in the scope
query parameter when requesting authorization: &scope=input_list+input_create
Rest API
HTTP Request
GEThttps://studio.liveu.tv/api/v1/user/about_me/?access_token={access_token}
Query Parameters
Parameter | Description |
---|---|
access_token | LiveU Studio 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). |
{
"error" : “###”
}
Where "error" can be:
- "A required GET parameter is missing (access_token)"
- "Invalid access_token"
- "Scope error: access token doesn't have access to the scope “user_about_me”"
HTTP Request
GEThttps://studio.liveu.tv/api/v1/input/list/?access_token={access_token}
&zone_id={zone_id}
&type_id={type_id}
Query Parameters
Parameter | Description | |
---|---|---|
REQUIRED | access_token | LiveU Studio 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.studio.liveu.tv",
"stream_name": "encoder_XXX_XXXXXX",
"port": 1935,
"url": "rtmp://XXXX.studio.liveu.tv/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). |
An error response will be a JSON dictionary.
{
"error" : “###”
}
Where "error" can be:
- "A required GET parameter is missing (access_token)"
- "A required GET parameter is missing (zone_id)"
- "Scope error: access token doesn't have access to the scope “input_list”"
HTTP Request
GEThttps://studio.liveu.tv/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 | LiveU Studio 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”
}
{
"error" : “###”
}
Where "error" can be:
- "A required GET parameter is missing (access_token)"
- "A required GET parameter is missing (zone_id)"
- "A required GET parameter is missing (type_id)"
- "type_id forbidden: type_id not in list of valid type_id"
- "Invalid access_token"
- "Title too long"
- "Account must have already created an event to add an entry"
- "limit_assets"
- "Scope error: access token doesn't have access to the scope “input_create”"
This list may be subject of changes.
Push inputs
id | Type |
---|---|
elStreamer | LiveU Studio 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 LiveU Studio - 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 LiveU Studio 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 LiveU Studio - Example, send an e-mail to support@liveu.tv. You will then be able to open the Google Drive code folder.
Opening the API Websocket:
- Get the WebSocket access token using Oauth Doc. N.B: Token are permanents so you can do the operation manually once for your main account and store the token afterward.
- Open a WebSocket to the following URL:
The zone parameter should be one of the zone the LiveU Studio client account has access to. If needed, use User About Me to list the zones.wss://ws-<zone>.studio.liveu.tv/websocket/public/client/?access_token=<your access token from step 1 above>
- Once opened, all the requests detailed in this document can be sent through the WebSocket as JSON strings.
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….
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 LiveU Studio - LiveU Studio",
"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 LiveU Studio - https://studio.liveu.tv",
"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 LiveU Studio - https://studio.liveu.tv",
"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": {}
}
}
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.studio.liveu.tv/live/",
"preview_server": "rtmp://eu-irl.studio.liveu.tv/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 | LiveU Studio 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
}
}
Files upload
The LiveU Studio platform offers an upload service on Amazon Web Services servers. To do so, an URL must be created from the LiveU Studio 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).
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 | LiveU Studio 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 LiveU Studio 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,
"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",
},
{
"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,
},
{
"name": "bg",
"autoplay": true,
"typename": "bg",
"effects": null,
"mask": "16/9"
}
]
}
}
Clip player
Create a new clip player
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.studio.liveu.tv/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": "Player 1",
"typename": "playlist",
"transparency": 100,
"size": 1,
"thumbnail": "https://static-us-vir.studio.liveu.tv/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
}
}
Media player 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 media player 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 media player
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 media player 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 media player, 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 media player. You can seek forward, seek backward, seek to the first media of the player 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 media player , the following request must be sent. It will pause the media currently being played and seek back to the first media of the player , 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",
"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.
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. |
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",
"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",
"color": "FFFFFF",
"text_align_x": "left",
"text_align_y": "flex-start",
"text_transparency": 100,
"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 LiveU Studio 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 LiveU Studio 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 | LiveU Studio 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 . |
Scenes & Transitions
The studio is now working with a new transition system, based on scenes. Each layer in your control room creates a dedicated scene and you can apply a transition to them when displayed in the program.
Field |
Description |
---|---|
method |
String: the transition method you want to apply. It can be "fade", "slide_left", "slide_right", "slide_up", "slide_down", "flip_vertical", "flip_horizontal" or "graphic". If you want to apply a cut, use "fade" with 0 duration. |
delay |
Int: from 0 to 3000. Delay of your transition in milliseconds |
duration |
Int: from 0 to 3000. Duration of your transition in milliseconds. A transition with duration at 0 will result as a cut. |
timing-function |
String: always "ease-in-out". |
trigger-out |
String: always "after". |
url |
String: the url of the APNG image you want to use as a graphic transition. Only for graphic transition. |
format |
String: format of your graphic transiton file. For now, always "image/png" or "image/apng". Only for graphic transition. |
To apply a transition, you just need to apply your settings inside the PROGRAM as usual with a goto_prod call and add the transition settings you want:
{
website: {
scope: 63288740,
goto_prod: ["display", "scoring"],
transition: {
method: "fade",
delay: 0,
duration: 1000,
format: null,
timing-function: "ease-in-out",
trigger-out: "after",
url: null
}
}
}
Scenes
The transition scene system is plugged into your layers. To be able to create a scene, you must be sure to create lines with a name respecting the nomenclature by "placeholder_{number}". Example: "placeholder_4". Here is the correct structure of a layer:
Field |
Description |
---|---|
name |
String: always “placeholder_{number}” |
typename |
String: always “placeholder” |
locked_scene |
Boolean: always true |
line_id |
String: layer unique ID |
{
"name": "placeholder_3",
"typename": "placeholder",
"locked_scene": true,
"line_id": 00000001
}
Hotkeys
You can assign a transition to your hotkey. To do this, simply add the desired transition to your call.
{
website: {
scope: 970821418,
goto_prod: ["scoring", "display"],
set_display_active: {…},
set_display_settings: […],
transition: transition: {
method: "fade",
delay: 0,
duration: 0,
format: null,
timing-function: "ease-in-out",
trigger-out: "after",
url: null
}
}
}
The apply hotkey is now replaced by 4 default transitions hotkeys. This will simply send the elements of your preview into the program and works the same as a go_to_prod call.
{
website: {
scope: 63288740,
goto_prod: ["display", "scoring"],
transition: {
method: "fade",
delay: 0,
duration: 500,
format: null,
timing-function: "ease-in-out",
trigger-out: "after",
url: null
}
}
}
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. |
scan | progressive: interlaced_bff : interlaced_tff |
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>.studio.liveu.tv/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.studio.liveu.tv/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.
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_LiveU Studio",
"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": []
}
]
},
"liveu Studio": {
"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 LiveU Studio 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 LiveU Studio 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 studio.liveu.tv (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 (studio.liveu.tv ) 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"
}
}
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"
}
}
}
Manage WebRTC outputs
Coming soon!
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": ""
}
]
}
Modify the audio settings
The studio audio mixer is now in decibels. Make sure that the volume value sent is compatible with the new system. The calls to our API are the same, only the volume value changes.
For example, if you want 5db, you need to send 50 to our API.
- 11.7db (117 for API) is the maximum value.
- 0db is the default value.
- -75db (-755 for API) is the minimum value. In that case, audio is muted.
There are 200 allowed values -> go to V30 changes section to know more.
Request
Field | Description |
---|---|
volume |
Int: volume in decibel*10. |
{
"website":{
"scope":4918743,
"audio_temp":{
"name":"master",
"volume":-48
}
}
}
Success
{
"website":{
"scope":869851899,
"set_volume":-48,
"goto_prod":["volume"]
}
}
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 | LiveU Studio zone: eu-irl-1 , us-vir-1 , us-ore-1 , eu-irl-4 , us-vir-4 or us-ore-4 . Contact LiveU Studio 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": "LiveU Studio - 1",
"zone": "eu-irl-4"
},
{
"id": 456,
"name": "LiveU Studio - 2",
"zone": "us-vir-4"
},
{
"id": 789,
"name": "LiveU Studio - 3",
"zone": "us-ore-4"
},
{
"id": 987,
"name": "LiveU Studio - 4",
"zone": "eu-irl-1"
},
{
"id": 654,
"name": "LiveU Studio - 5",
"zone": "us-vir-1"
}
]
},
"scope": 123456
}
}
Request (more results)
{
"website": {
"customer_list": {
page: 1,
search: "yoursearchpattern"
},
"scope": 123456
}
}
List the users of a project (account
)
Request
Field | Description |
---|---|
Always true . |
{
"website": {
"scope": 721527072,
"people": {
"get": true
}
}
}
Success
Field | Description |
---|---|
id | The user id. |
The email address of the user. | |
name | The name of the user. |
is_active | Boolean. If true , the user can access the said account (manage control rooms and access calendar). |
is_manager | Boolean. If true , the user can manage the said account (add/remove users, edit account information, manage billing and payment methods). |
{
"customer": {
"people": [
{
"is_manager": true,
"name": "User One",
"is_active": true,
"email": "usermail@domainname.ext",
"id": "0102030405azeRTY"
},
{
"is_manager": false,
"name": "Player Two",
"is_active": true,
"email": "otheremail@example.com",
"id": "0102030405azeRTY"
}
]
}
}
Add a user to a project (account
)
Request
Field | Description |
---|---|
The email address of the user to be added. An email will be sent as an account creation request if the user doesn't exists. |
{
"website": {
"scope": 123456,
"people": {
"add": {
"email": "usermail@domainname.ext"
}
}
}
}
Success
Field | Description |
---|---|
id | The user id. |
The email address of the user. | |
name | The name of the user. |
is_active | Boolean. If true , the user can access the said account (manage control rooms and access calendar). |
is_manager | Boolean. If true , the user can manage the said account (add/remove users, edit account information, manage billing and payment methods). |
{
"customer": {
"people": [
{
"is_manager": true,
"name": "User One",
"is_active": true,
"email": "usermail@domainname.ext",
"id": "0102030405azeRTY"
},
{
"is_manager": false,
"name": "Player Two",
"is_active": true,
"email": "otheremail@example.com",
"id": "0102030405RTYaze"
}
]
}
}
Edit users rights
Request
Field | Description |
---|---|
field | The role to be edited. is_active : can access the project. is_manager : can manage the billing and personnal information. |
value | Boolean. Either true (will activate) or false (will deactivate). |
user_id | The user ID. Can be found in the list of users. |
{
"website": {
"scope": 255067344,
"people": {
"set": {
"field": "is_manager",
"value": true,
"user_id": "0102030405aBcDeF"
}
}
}
}
Success
{
"customer": {
"people": [
{
"is_manager": true,
"name": "User One",
"is_active": true,
"email": "usermail@domainname.ext",
"id": "0102030405azeRTY"
},
{
"is_manager": true,
"name": "Harry Potter",
"is_active": true,
"email": "harry.potter@hedwige.owl",
"id": "0102030405aBcDeF"
}
]
}
}
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 !
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 support@liveu.tv to obtain your webRTC library script tag.
Init Connection
Our solution is based on Selective Forwarding Unit (SFU), which is one of the most popular architectures for WebRTC. To get or create connection, you can use webRTCLib.init
. It requires a single object containing two keys :
Parameter | Type | Status | Description |
---|---|---|---|
ws | Object |
(REQUIRED) | Websocket. |
id | Integer |
(REQUIRED) | Your live number. |
withData | Boolean |
(OPTIONAL) - Default: false | Allows you to retrieve the monitoring data or not. |
update | Function |
(REQUIRED) | Refers to each stream that arrives. It returns in parameter a stream with two elements : settings (quality) a srcObject object, and stream name. |
isRunning | Function |
(REQUIRED) | Allows to know if a feed should be launched by your page. It takes the stream name and the settings as parameters. |
You can call the function as in the example below, while initializing a websocket :
window.webRTCLib.init({
ws : window.websocket,
id : 55930,
withData: false,
isRunning: isRunning,
update: playerUpdate
});
Update SFU Connection
You can update an existing connection with your server infos. The function webRTCLib.updateSfu
will check if the server returns webrtc_server or webrtc_data_server info. If it's the case, each available peer will be updated according to the information returned (participants, update, etc.)
Parameter | Type | Status | Description |
---|---|---|---|
serverInfos | Object |
(REQUIRED) | Server infos. |
You can use this function while updating you current live infos, for example :
window.webRTCLib.updateSfu(serverInfos);
Stop connection
Thanks to the webRTCLib.stopAndRefresh
function, you can stop and delete all active peer connections, then automatically update your stream infos. It requires only one argument :
Parameter | Type | Status | Description |
---|---|---|---|
streamId | Integer |
(REQUIRED) | Stream id for update after stopping peer connections. |
window.webRTCLib.stopAndRefresh(streamId);
Add listener on data
You can add a listener on your data thanks to webRTCLib.addDataListener
. It requires two parameters :
Parameter | Type | Status | Description |
---|---|---|---|
name | String |
(REQUIRED) | Listener target. |
callback | Function |
(REQUIRED) | Custom callback function. |
For example, if you need to add a listener on your encoder store, you can proceed like this :
window.webRTCLib.addDataListener( "encoderStore", encoderStore.update );
Add a new stream
The webRTCLib.add
function will create a new stream based on the arguments passed :
Parameter | Type | Status | Description |
---|---|---|---|
videoContainer | Object |
(REQUIRED) | DOM element containing your video. |
videoName | String |
(REQUIRED) | Video name in the stream store. |
settingsName | String |
(REQUIRED) | Settings name in WebRTC settings, same as videoName. |
boxId | Integer |
(REQUIRED) | Your live number. |
output | Boolean |
(OPTIONAL) - Default : false | Video output status. |
settings | Object |
(OPTIONAL) - Default : {} | Video settings. |
withStatus | Boolean |
(OPTIONAL) - Default : true | Show video status |
container | Object |
(OPTIONAL) - Default : videoContainer parent | videoContainer parent. |
websocket | Object |
(OPTIONAL) - Default : window.websocket | Websocket. |
The settings parameters will mainly contain the desired quality for your stream. Several options are available :
Quality | Description |
---|---|
fake | No video, only audio |
mobile | 256 15fps (video bitrate = max 300kbps) |
sd | max 640 15fps (video bitrate = max 1000kbps) |
hd | max 1280 30fps (video bitrate = max 3000kbps) |
fhd | max 1920 30fps (video bitrate = max 6000kbps) |
window.webRTCLib.add({
videoContainer: this.videoContainer,
videoName: "video_01",
settingsName: "video_01",
output: false,
settings: { quality : "hd" },
withStatus: false,
container : null,
boxId : 55930,
websocket : this.websocket
});
Remove a stream
For each stream contained in the specified container, you'll delete it from stream store. After removing, the stream list will be automatically updated thanks to the given identifier. The webRTCLib.remove
function will run based on these parameters :
Parameter | Type | Status | Description |
---|---|---|---|
container | Object |
(REQUIRED) | Object containing your streams. |
identifier | Integer |
(REQUIRED) | Your live number. |
callback | Function |
(OPTIONAL) | Custom callback function. |
The callback function will be applied on each stream in the specified container.
window.webRTCLib.remove(
this.container,
this.liveNumber,
function(name){
audioMaster.releaseStream( name );
}
);
Set or update stream settings
If you want to set or update the parameters of a stream, for example your stream quality, you just need to use the webRTCLib.setSettings
function.
If your stream does not yet have its own settings, the function will assign the settings in parameters. Otherwise, the settings will simply be updated.
If the settings change, then the stream will be automatically restarted.
Parameter | Type | Status | Description |
---|---|---|---|
streamName | String |
(REQUIRED) | Stream name in the stream store. |
settings | Object |
(REQUIRED) | New stream parameters. |
The settings parameters will mainly contain the desired quality for your stream. Several options are available :
Quality | Description |
---|---|
fake | No video, only audio |
mobile | 256 15fps (video bitrate = max 300kbps) |
sd | max 640 15fps (video bitrate = max 1000kbps) |
hd | max 1280 30fps (video bitrate = max 3000kbps) |
fhd | max 1920 30fps (video bitrate = max 6000kbps) |
window.webRTCLib.setSettings("stream-2021", {quality: "hd"});
Get streams from stream store
With webRTCLib.getFromStreamStore
, you can retrieve all the streams available in the stream store, or retrieve only one thanks to its name
Parameter | Type | Status | Description |
---|---|---|---|
streamName | String |
(OPTIONAL) | Stream name in the stream store. |
//Get all streams available in stream store
window.webRTCLib.getFromStreamStore();
//Get a specific stream window.webRTCLib.getFromStreamStore("stream-2021");
Delete a stream from stream store
You can easily delete a specific stream from the stream store with the webRTCLib.deleteFromStreamStore
function.
Parameter | Type | Status | Description |
---|---|---|---|
streamName | String |
(REQUIRED) | Stream name in the stream store. |
callback | Function |
(OPTIONAL) | Custom callback function. |
const callback = audioMaster.releaseStream( streamName );
window.webRTCLib.deleteFromStreamStore(streamName, callback);
Refresh a stream in the stream list
You can easily refresh a specific stream with the webRTCLib.updateStream
function.
Parameter | Type | Status | Description |
---|---|---|---|
streamId | String |
(REQUIRED) | Stream identifier in the stream list. |
window.webRTCLib.updateStream(streamName);
Get a specific stream and its peer connection
With the webRTCLib.getStreamAndPeer
function, you'll be able to get SFU connection and stream infos.
Parameter | Type | Status | Description |
---|---|---|---|
identifier | String |
(REQUIRED) | Your live number. |
streamName | String |
(REQUIRED) | Stream identifier in the stream list. |
settings | String |
(REQUIRED) | Stream settings. |
window.webRTCLib.getStreamAndPeer(currentLiveId, streamName, settings);
This function will return and object with two keys :
Parameter | Type | Description |
---|---|---|
peer | Object |
Peer linked to the given identifier. |
srcObject | Object |
Stream infos. |
Get ICE servers
You can get ICE servers list with the webRTCLib.getIceServers
function. It does not require any parameters.
const ices = window.webRTCLib.getIceServers();
WebRTCLib error message
Our library may sometimes returns error messages, especially when creating a peer connection.
These errors are handled by the webRTCLib.onErrorMessage
function, which performs a console.error of the returned message by default.
The following messages you might encounter are :
Error code | Description |
---|---|
network-issue | You have lost the network connection. An attempt to reconnect is in progress |
url-already-in-use | This URL is already in use by another element in your project. |
Last update & changes
V32 (coming soon)
Media Assets
Create or update an Ad break:
Get Ad break duration
Webpages (Iframe) update
Request
Field | Description |
---|---|
url | The webpage's URl. |
natural_height | The desired height of the webpage. |
natural_width | The desired width of the webpage. |
refresh_in_pgm | True or False - refresh the webpage each time it's loaded in the PGM. |
{
"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,
"refresh_in_pgm" : false,
"url": "https://www.some.url/leading/to/a/webpage",
"line_id": 56789
},
...
]
}
}
V30/31
Transition
The studio is now working with a new transition system, based on scenes. Each layer in your control room creates a dedicated scene and you can apply a transition to them when displayed in the program.
Field |
Description |
---|---|
method |
String: the transition method you want to apply. It can be "fade", "slide_left", "slide_right", "slide_up", "slide_down", "flip_vertical", "flip_horizontal" or "graphic". If you want to apply a use, use "fade" with 0 duration. |
delay |
Int: from 0 to 3000. Delay of your transition in milliseconds |
duration |
Int: from 0 to 3000. Duration of your transition in milliseconds. A transition with duration at 0 will result as a cut. |
timing-function |
String: always "ease-in-out". |
trigger-out |
String: always "after". |
url |
String: the url of the APNG image you want to use as a graphic transition. Only for graphic transition. |
format |
String: format of your graphic transiton file. For now, always "image/png" or "image/apng". Only for graphic transition. |
To apply a transition, you just need to apply your settings inside the PROGRAM as usual with a goto_prod call and add the transition settings you want:
{
website: {
scope: 63288740,
goto_prod: ["display", "scoring"],
transition: {
method: "fade",
delay: 0,
duration: 1000,
format: null,
timing-function: "ease-in-out",
trigger-out: "after",
url: null
}
}
}
Scenes
The transition scene system is plugged into your layers. To be able to create a scene, you must be sure to create lines with a name respecting the nomenclature by "placeholder_{number}". Example: "placeholder_4". Here is the correct structure of a layer:
Field |
Description |
---|---|
name |
String: always “placeholder_{number}” |
typename |
String: always “placeholder” |
locked_scene |
Boolean: always true |
line_id |
String: layer unique ID |
{
"name": "placeholder_3",
"typename": "placeholder",
"locked_scene": true,
"line_id": 00000001
}
Hotkeys
You can assign a transition to your hotkey. To do this, simply add the desired transition to your call.
{
website: {
scope: 970821418,
goto_prod: ["scoring", "display"],
set_display_active: {…},
set_display_settings: […],
transition: transition: {
method: "fade",
delay: 0,
duration: 0,
format: null,
timing-function: "ease-in-out",
trigger-out: "after",
url: null
}
}
}
The apply hotkey is now replaced by 4 default transitions hotkeys. This will simply send the elements of your preview into the program and works the same as a go_to_prod call.
{
website: {
scope: 63288740,
goto_prod: ["display", "scoring"],
transition: {
method: "fade",
delay: 0,
duration: 500,
format: null,
timing-function: "ease-in-out",
trigger-out: "after",
url: null
}
}
}
LUC Groups
Retrieve the project LUC groups
{
website: {
scope: 175796336,
groups: {
get: true
}
}
}
Update the LUC groups list
Field |
Description |
---|---|
groups |
Array: list of group_id, contains all the group ids you want to save in your project. |
{
website: {
scope: 791193310,
groups: {
set: {
groups: [1506, 8886]
}
}
}
}
Retrieve project users:
{
website: {
scope: 860695012,
account_users: {
get: true
}
}
}
This will retrieve all the LUC and non-LUC users who have access to your project.
If you’re not using the LUC group system and still have access to the old people system, please use the old method:
{
website:{
scope: 860695058,
"people": {
"get": true
}
}
}
Media player/clip/playlist changes:
-
In Videos (animation) section
-
remove “line_id“:
-
{
"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, // remove
"name": "Video"
}
}
}
}
-
replace the nice_name in the request
{
"website": {
"scope": 13121997,
"set_display_settings": [
{
"name": "playlist_23136798",
"id": 23136798,
"nice_name": "Playlist 1", ->
"nice_name": "Player 2",
Audio Mixer
The studio audio mixer is now in decibels. Make sure that the volume value sent is compatible with the new system. The calls to our API are the same, only the volume value changes.
Field |
Description |
---|---|
volume |
Int: volume in decibel*10. |
For example, if you want 5db, you need to send 50 to our API.
11.7db (117 for API) is the maximum value.
0db is the default value.
-75db (-755 for API) is the minimum value. In that case, audio is muted.
117 |
115 |
114 |
112 |
111 |
109 |
107 |
106 |
104 |
102 |
101 |
99 |
97 |
96 |
94 |
92 |
90 |
89 |
87 |
85 |
83 |
82 |
80 |
78 |
76 |
74 |
73 |
71 |
69 |
67 |
65 |
63 |
62 |
60 |
58 |
56 |
54 |
52 |
50 |
48 |
46 |
44 |
42 |
40 |
38 |
36 |
34 |
32 |
30 |
28 |
26 |
24 |
22 |
20 |
17 |
15 |
13 |
11 |
9 |
7 |
4 |
2 |
0 |
-2 |
-5 |
-7 |
-9 |
-11 |
-14 |
-16 |
-18 |
-21 |
-23 |
-26 |
-28 |
-30 |
-33 |
-35 |
-38 |
-40 |
-43 |
-45 |
-48 |
-51 |
-53 |
-56 |
-58 |
-61 |
-64 |
-66 |
-69 |
-72 |
-75 |
-77 |
-80 |
-83 |
-86 |
-89 |
-92 |
-95 |
-98 |
-101 |
-104 |
-107 |
-110 |
-113 |
-116 |
-119 |
-122 |
-125 |
-129 |
-132 |
-135 |
-138 |
-142 |
-145 |
-149 |
-152 |
-156 |
-159 |
-163 |
-166 |
-170 |
-173 |
-177 |
-181 |
-185 |
-189 |
-192 |
-196 |
-200 |
-204 |
-208 |
-212 |
-217 |
-221 |
-225 |
-229 |
-234 |
-238 |
-242 |
-247 |
-252 |
-256 |
-261 |
-266 |
-270 |
-275 |
-280 |
-285 |
-290 |
-296 |
-301 |
-306 |
-312 |
-317 |
-323 |
-328 |
-334 |
-340 |
-346 |
-352 |
-358 |
-365 |
-371 |
-378 |
-384 |
-391 |
-398 |
-405 |
-412 |
-420 |
-427 |
-435 |
-443 |
-451 |
-459 |
-467 |
-476 |
-485 |
-494 |
-503 |
-513 |
-523 |
-533 |
-543 |
-554 |
-565 |
-577 |
-589 |
-601 |
-614 |
-627 |
-640 |
-655 |
-670 |
-685 |
-701 |
-719 |
-736 |
-755 |