Basic application
This section will cover all of the basics that you need for setting up an application that can:
- Start up
- Render a menu
- Render a content page
- Render a detail page
- Play back a stream
Which is essentially all you'll need to set up an OTT application.
Starting up
The start cycle usually consists of requesting the application config and using the values from there to make any subsequent calls to other API endpoints.
You can grab the configuration object by calling /configurations/application
. You'll get an object that looks something like this:
{
"api": {},
"theming": {},
"features": {},
"application": {}
}
For the front-end apps really only the features
part is important (the other ones contain information for our legacy SmartOTT product).
The features
object can contain information about certain features that you might need later on or things like: what main menu to use, whether a welcome screen needs to be shown and many other things. You'll find the parts of the config you need in the feature specific sections of the integration guide.
Make sure you've got the contents of this resource easily available throughout your application.
Menus
Most apps need a menu, backstage offers an endpoint to retrieve either a list of all menus available in the system or a specific menu by ID.
You can grab all menus via /menus
and specific ones via /menus/{id}
.
There is a value in the config to specify the main menu. You can use this ID to grab the specific menu you want to display. This will allow the customer to change out the menu dynamically via the CMS.
{
"features": {
"menus": {
"main": "ID"
}
}
}
Once you have your desired menu resource, either by selecting one from the list or grabbing a specific one you can render the menu items in your app. The menu items will dictate what the operation should be and where it should point the app to when pressed/clicked.
A menu item will have the following properties:
label
, the text you'll want to render in the menu itemslug
, the slug of the menu item, can be used to render prettier web URL'stype
, the type indicates where the menu item needs to navigateicon
, the icon for the menu item to render. This is a key that corresponds to a value in the icon set. (only available on the root level)reference
, contains the ID of the resource to route to when applicable (for pages / textpages)item
, when a menuitem is of the typesubmenu
this property contains the menu items for it.
Menu items can be of the following types:
Type | Operation |
---|---|
page | Open a content page, you'll be given an ID by the reference field |
tabs | Open a tabs page, works similar to a submenu but instead opens a page with the first entry and shows the other pages in separate tabs. |
channels | Open a list of channels |
epg | Open an EPG (overview of channels & what's being broadcasted) |
search | Open a search page |
submenu | Open a submenu and render the items given in the items property |
textPage | Open a text page, you'll be given an ID by the reference field |
external | Open an external URL (if possible on the platform you're developing on) |
Pages
Once an end-user has clicked a menu item that needs to navigate to a content page (or just rendering the first page), you'll need to load the page structure and it's contents
Page structure
Page structures are retrieved via /pages/{id}
. They'll provide you with objects we call sections, these objects dictate how a page element should look like (visually) and where you can grab it's contents.
A section object contains the following properties:
Property | Description |
---|---|
label | The label is the "title" of the section, in most cases this will be rendered just above the shown assets. |
type | The type dictates HOW the section should be rendered, right now all the types are linked to SmartOTT, you can however just map it to whatever you're using in your app |
playlistId | This is a reference to the playlist that contains the items for this section. It can be used to call the playlist endpoint |
computedPlaylist | Optionally this can be given instead of a playlistId property. In that case one of the computed playlist endpoints need to be called. |
pinnedItems | This is an array containing the ID's of items pinned to the front of the section. These need to be passed into the playlist endpoint when retrieving items to make sure they're not retrieved again further up in the playlist asset collection |
Supported Types
slider
header
single_row
single_highlight
double_row
double_highlighted_row
Computed playlists
You can find an overview of the computed playlists here: TODO ADD DOC LINK TO COMPUTED PLAYLISTS
Retrieving content
When you have your page sections set up you'll probably want to fill them with content! The playlist objects (computed or playlistId reference) will provide you with the content to render within the sections.
You can retrieve the playlist items through the following call: /playlists/{id}
or a computed playlist such as /playlists/user-continue-watching
.
Pagination
Playlists are paginated and have query parameters available to control this.
Parameter | Description | Default value |
---|---|---|
size | Dictates how many items are returned in the call | 24 |
offset | Determines from which point items will be returned, so if you're chunking playlist calls in batches of 10 you would increment this in steps of 10: 0, 10, 20, 30 | 0 |
Now that your application is aware of the amount of items it should be retrieving you can start to load new ones as soon as you reach the end of your section by scrolling. When that happens you can request the next batch of items until the number of items returned to you is lower than the given value.
Passing values from a section
Because section & playlist objects are separate entities in the system, neither one is aware of the other. As section objects can dictate some behavioural properties of a playlist these need to be passed through when making the call.
Pinned items
Pinned items are assets that have been "pinned" to the front of the section. Because a playlist can be re-used across multiple sections only the actual section is aware of which ID's have been pinned. That's why you'll need to specify the pinned items in a playlist call to make sure these assets are always moved to the front and will not show up in later paginated calls.
Parameter | Description |
---|---|
pinnedItems | A comma separated list of pinned item ID's. You can find these in the section object under the pinnedItems property (as an array). |
Sorting options
A section object can dictate how items can be sorted by default. For example sorting on label to return items in A-Z order.
Parameter | Description |
---|---|
sortField | The property that the playlist needs to be sorted on. You can find this in the section object under the sorting.field property (so field within an object called sorting). |
sortOrder | The order in which the playlist needs to be sorted, can be either asc or desc. You can find this in the section object under the sorting.order property. |
In case you want the user to be able to set his/her own sorting option of a section you can use these parameters to achieve that. Be aware: not all properties support sorting at the moment!
Detail
When a user has clicked on an asset in a section you'll most likely want to route them to a detail page. It's recommended that you make a separate entity (detail) call to grab the info for this for a number of reasons:
- Deeplinking, this is easier when your detail page is aware of the ID
- Additional data, some data is only available in detail calls (for example MVPD block checking) due to external limitations. These "can" affect overall usage of assets.
You can grab an assets detail information via /media/{type}/{id}
. You can find the relevant API docs here: http://docs.backstage-api.com/#/media/movies/{id} (example for a movie).
Once you have the detail data you can start rendering your detail page with it however you see fit (or according to the requirements). Here's an overview of the basic properties and what they "can" be used for:
Property | Description | Type |
---|---|---|
label | The title of the asset, this will usually be prominently featured on the detail page. | string |
description | Long form description of the asset. This is the required description value and should always be available | string |
shortDescription | Short form description of the asset. If this is available (and the description value is longer than the size you want to display by default) you can display this in your detail page and allow the user to expand to the description value. | string |
images.still | Can contain multiple sizes of a 16:9 image to display. | array |
images.poster | Can contain multiple sizes of a 2:3 image to display. | array |
images.background | Can contain multiple sizes of a 16:9 image to display in the background of your detail pages (usually only used on 10ft devices) | array |
genres | An array of genre objects for this item. Usually you'd display the label property of the genre objects in the detail page as a comma separated string. | array |
crew | An array of crew objects. A crew object consists of a name (the person name) and their role (for example director or actor). Crew objects now also have support for image sets attached to them, as seen in the documentation here: http://docs.backstage-api.com/#/persons/{id} which can be used for rendering their portraits as well. | array |
duration | The duration of the asset in seconds | int |
year | The year in which the asset was released | int |
rating | A "rating" value between 0 and 100. Can be rendered as stars, percentage or whatever rating mechanism you'd want. | int |
Seasons
In case you're dealing with a series object you'll probably want to render your episodic content in a structured manner. Right now the only way to do so is to add an includeEpisodes
query parameter to the request.
This will add an extra seasons property to the response that contains an array with "season objects". They will be ordered in an ascending order based on season and episode number.
A better structure for retrieving seasons and episodes separately will be added in the future.
Playback
On your detail page you'd usually have a play button to go into the player and start playing your movie/episode/channel.
You can retrieve the stream through Backstage by performing two steps:
- Retrieve edition: edition objects dictate what the stream will contain. Currently only the distinction between a trailer or full edition, but later this will also support various qualities through TVOD.
- Retrieve stream: the edition object will contain info about what kind of streams are available, select the best one for your device and retrieve the stream using those parameters.
Editions can be retreived via
/media/{type}/{id}/editions
http://docs.backstage-api.com/#/media/movies/{id}/editions
Once you've retrieved the list of editions you can select which one you want to play out, which in most cases will be either a trailer or full edition based on the editionType
property.
Every edition object will contain a streams array which contains a list of redacted stream objects, only the type & drm flavour will be given. Based on the device that your application is running on you can select the stream you want to retrieve (for example iOS will thrive best under HLS & Fairplay if available). Once you've got the type and drm flavour you're happy with you can retrieve the actual stream.
streams can be retrieved via
/media/{type}/{id}/stream
http://docs.backstage-api.com/#/media/movies/{id}/stream
When you request a stream based on your previously selected values (edition ID, stream type, drm flavour) the backstage system will retrieve the actual stream URL and optionally perform some extra steps with an externally configured system to make sure it's playable for the user (for example when tokenisation is needed).
You'll receive the valid stream in the url property of the object. If additional DRM data is available (such as custom data that needs to be set or the license URI) they will be available in the data property.
Wrap Up
That's in essence all that's needed to build an app that handles navigation & playback. Fairly simple, but also not feature rich. In the next section we'll go over all individual features and how to implement them in your apps.