Build a Basic Broadcaster Application
This document contains information on using the A3FA Framework to build a basic ATSC3.0 Broadcaster Application. It uses examples from the reference common applications included in the A3FA Broadcaster Starter Kit (in the a3fa-examples/app/common-app section).
The process also includes an example of using the Broadcaster Common Application with framework common app functions like creating feeds linked to external broadband assets.
In addition an example of using Advanced Alert data (AEA) that is carried via the RF Broadcast transmission is included, with a simple addition to the application to receive an event and parse for data to display.
Prerequisites
-
The document assumes that the reader has signed up for and installed the A3FA Broadcaster Starter Kit from the A3FA NPM area, See the document link below to get more in depth instructions.
-
It will help in understanding the topics covered if you are, a Web Developer, or have some foundational level knowledge of Web technology formats, such as HTML, JSON, and Javascript.
Broadcaster Starter Kit introduction: CASE-1: How to Install the RUN3TV Application Starter Kit
Framework Overview
The A3FA Framework provides the following features for a common platform to launch ATSC3.0 Broadcast Applications.
-
API integration with ATSC3.0 Receivers, using secure web sockets and standards based API (A/344).
-
Common toolset for creating menus with consistent look and feel.
-
Flexible Branding, with ability to import different colour schemes, skins, and logo images.
-
Modular approach - Use functionality that is required, add or extended modules for future needs. e.g. DRM protection modules.
Application Structure
The framework application typically consists of two pages, the top (static) page and a dynamic (iframe) page as a child.
The Static page orchestrates all of the Framework functions and processes, whilst the dynamic page provides the entry point and interfacing of the Broadcaster Application with the framework.
The static top page is invisible on a browser or TV display.
Folder Structure
As with most web-site data, the A3FA framework uses relative links to consume various assets, scripts, and content during its operation. Therefore a predefined folder structure exists to allow access to required resources.
+---a3fa-common // Framework
| +---apps
| | +---common-app
| | +---onboarding
| | \---triggers
| +---conf
| \---libs
+---a3fa-examples // A3FA example broadcaster applications
| +---apps
| | +---aeat
| | +---common-app
| | | +---STATION-1
| | | | +---config
| | | | +---css
| | | | +---dynamic
| | | | | \---menu
| | | | +---img
| | | | | +---home-menu
| | | | | +---pics
| | | | | \---player
| | | | \---tos
| | | \---STATION-2
| | | +---config
| | | +---css
| | | +---dynamic
| | | | \---menu
| | | +---img
| | | | +---home-menu
| | | | +---pics
| | | | \---player
| | | \---tos
| | \---trigger
| | +---STATION-1
| | | \---img
| | \---STATION-2
| | \---img
| +---conf
| \---schedules
| +---AEAT
| +---STATION-1
| \---STATION-2
\---bridge-conf // Service --> Application Linking files
\---1.0
Baseline
The baseline or root folder structure contains both framework and Broadcaster Application folders along with a linking folder which contains configuration files to link Broadcaster Applications to live broadcast services.
The Broadcaster Starter Kit contains the a3fa-examples folder, which contains applications to demonstrate key framework and common app functions.
In production this folder would be replaced with an organisation group or broadcaster specific folder containing the required Broadcaster Application(s) for the market area.
|
Folder Name |
Purpose |
Details |
|---|---|---|
|
a3fa-common |
Contains files and resources to run the A3FA framework. |
Files and folders generally do not need to be edited or updated, so recommend to leave unedited. |
|
bridge-conf |
Contains configuration files for linking applications to broadcast services |
Uses the Global Service ID transmitted in the broadcast signaling to link to a broadcaster application. |
|
cp |
Contains files used to provide data to emulation functions. *DEVELOPMENT Use Only |
Provides data to run offline development to simulate ATSC3.0 receiver responses, using a web-browser. This folder is not required for applications running on actual ATSC3.0 receivers, and can be removed in live production. |
|
a3fa-examples |
Contains multiple Broadcaster Application examples to showcase the Framework capabilities. |
Contains a mix of applications, some using the common application fully integrated with the framework, and example 3rd party applications. In production would be replaced with an organisation or broadcast group folder containing the required Broadcast Applications. |
Framework (a3fa-common)
|
Folder/File |
Purpose |
|---|---|
|
a3fa-common/index.html |
Root HTML file (static config) - entry point (first request). |
|
a3fa-common/conf |
Contains framework configuration files. |
|
a3fa-common/libs |
Common framework JavaScript libraries (min.js files). |
|
a3fa-common/apps |
Common dynamic application resources directory. |
|
a3fa-common/apps/trigger |
The common application Call To Action trigger resource. |
|
a3fa-common/apps/default.html |
Default HTML is a file run when the framework finds no Global Service ID (GSID) match between live services and Broadcaster Application configuration. Displays the current live service GSID if available, as a helper. |
|
a3fa-common/apps/onboarding/ |
Folder containing resources for onboarding. |
|
a3fa-common/apps/common-app |
Folder resource for the common application. Contains the app entry point HTML. |
Linking
|
Folder/File |
Purpose |
|---|---|
|
bridge-conf/1.0 |
Folder containing current version of bridge.json, which is used to link a broadcast channel (globalServiceId) to application list and schedule files. The application schedule and list data will determine which broadcaster application is presented to the ATSC3.0 receiver. |
Broadcaster Common Application
The Broadcaster Application folder contains the file structure for all resources and files required in the application. New folders can be added as a logical separation between applications.
The index.html entry point for common applications is located in the Framework folder structure. This file is not intended for editing as it can provide a common function across multiple organisations in some use cases.
All Common Application customisation should be performed using configuration files and resources provided in the common-app folder of the Broadcaster Application area.
The starter-kit comes with a set of Broadcaster Application example which cover both 3rd party applications and ones using the A3FA Common Application structure.
To create a new Broadcaster Application instance, application files must reside in in a named folder container at the same level as the Framework (a3fa-common). It is recommended that the naming of the folder would be the organisational or broadcast group name if multiple channels are serve in a single market, or for simpler structures could be station name or call letters.
|
Folder/File |
Purpose |
|---|---|
|
a3fa-common/apps/common-app/index.html OR <Org Group>/apps/common-app/index.html |
Entry point for dynamic (Broadcaster Application). Loaded by the top page as an iframe. |
|
a3fa-examples/schedules/<station call sign | Market ID (DMA)> OR <Org Group>/schedules/<station call sign | Market ID (DMA)> |
Folder contains application schedule files. Only one schedule can run per physical TV service. If an organisation is serving multiple channels in a market, then different channel appSchedules shall be contained in separate folders using a logical name, such as station call or market identifier. |
|
a3fa-examples/apps/conf OR <Org Group>/apps/conf |
Location of
Only one appList is required per organisational group. |
|
a3fa-examples/apps OR <Org Group>/apps |
General area for broadcaster applications. Each application adding shall be contained within a folder wrapper. A3FA Common Applications are not presented at this level - see below. |
|
a3fa-examples/apps/common-app OR <Org Group>/apps/common-app |
Location for all A3FA Common Apps. Each application shall be contained in a folder with a logical name to identify. |
|
a3fa-examples/apps/common-app/<app>/config OR <Org Group>/apps/common-app/<app>/config |
Location for default language and menu settings for the common application. |
|
a3fa-examples/apps/common-app/<app>/css OR <Org Group>/apps/common-app/<app>/css |
Folder contains the default and AMP player CSS files for the common application. |
|
a3fa-examples/apps/common-app/<app>/dynamic OR <Org Group>/apps/common-app/<app>/dynamic |
Folder contains resources and files that are dynamic and can change within the applications lifecycle. |
|
a3fa-examples/apps/common-app/<app>/img OR <Org Group>/apps/common-app/<app>/img |
Folder contains all image resources required for the common application. |
|
a3fa-examples/apps/common-app/<app>/tos OR <Org Group>/apps/common-app/<app>/tos |
Folder contains files and data related to applications 'Terms Of Service'. |
Build the Application
This section deals with how to build or setup a new application based upon the A3FA Common Application. This should provide a good starting point to go onto exploring more advanced features of the framework.
Step 1 - Check the Starter-kit on local browser
Before starting to build a new application it is important to check that the existing framework and reference Broadcaster Application(s) (a3fa-examples) is functioning correctly to provide a good baseline before making additional edits.
This can be verified by running the starter kit as a node instance using NPM and testing the application behaviour in a local browser. Details of how to test an application and set up local test rig can be found in the document link below.
The result on a browser displaying the reference app should look something like this.
Step 2 - Create a new organisation folder
-
In the public folder of the Broadcaster Starter Kit copy the
a3fa-examplesfolder along with all sub-folders and files. -
Paste and rename the newly created folder to “diy-app“ at the same directory level as a3fa-common & bridge-conf.
Step 3 - Configure the appList.json file
The appList.json file contains the definitions and configuration properties of applications to be used by an organisation or broadcast group.
There can be one or more applications listed depending on the use case. However only one application is present on the TV at a time, so cycling through different applications in the list involves either defining a Call to Action trigger app to link to another main Broadcaster Application or the Application is changed using different scheduled events (defined in diy-app/apps/schedules/appSchedule.json).
For this application example we shall use a call to action trigger application to display a branded graphical pod for 5 secs, then link to a main Broadcaster Application on a button press. To do this we define a CTA application, trigger-1 , and a Broadcaster Application that links to it called STATION-1.
Here are the steps:
-
Delete the current
diy-app/conf/appList.jsonand replace with a new appList.json with the json data below.
{
"appList": {
"applications": {
"trigger-1": {
"appRoot": "/a3fa-common/apps/triggers",
"appEntry": "/cta.html",
"properties": {
"linkApp": "STATION-1",
"hidden": false,
"timeout": 5,
"img": "/diy-app/apps/trigger/STATION-1/img/img.png",
"hover": "/diy-app/apps/trigger/STATION-1/img/hover.png"
}
},
"STATION-1": {
"appRoot": "/a3fa-common/apps/common-app",
"appEntry": "/index.html",
"properties": {
"back": {"properties": {"hidden": true}},
"menu": "/diy-app/apps/common-app/STATION-1/dynamic/menu/default-menu.json",
"settings": "/diy-app/apps/common-app/STATION-1/config/default-settings.json",
"menu-settings": "/diy-app/apps/common-app/STATION-1/config/menu-settings.json",
"style": "/diy-app/apps/common-app/STATION-1/css/default.css",
"amp": "/diy-app/apps/common-app/STATION-1/css/skin.css",
"resize": true,
"header": {"type": "channel", "title": {"en": "APP ID 1", "es": "APP ID 1"}, "id": "SRV1", "name": "ID-1", "logo": "/diy-app/apps/common-app/STATION-1/img/home-menu/channel.png"},
"terms-of-service": "/diy-app/apps/common-app/STATION-1/tos/terms-of-service.html",
"privacy-policy": "/diy-app/apps/common-app/STATION-1/tos/privacy-policy.html",
"panels-ttl": 300000,
"player-ttl": 15000
},
"drm": null,
"allowConfigDRM": true,
"allowLocalStorage": true,
"allowFrameworkStorage": true
}
}
}
}
-
Save the
appList.jsonfile.
Step 4 - Link a Service to the Application
To test our changes we must link our app to a Broadcast Service. In production we would use the globalServiceId defined by the Broadcast transmission team to link an application list and schedule to this service.
This is done in the bridge-conf/1.0/bridge.json file. For our DIY application example we shall use the default globalServiceId use in the atscCmd.json file which emulates the receiver API responses, when testing using a web browser.
The linking steps are:
-
Open the
bridge-conf/1.0/bridge.jsonand delete the current json content. -
Add in the following JSON data (below). To link the DIY app to the globalServiceId and provide path pointers to the appList and appSchedule config files.
{
"connection": "bband",
"bridge": {
"tag:yottamedialabs.com,2020:globalServiceID/1": {
"bcastappList": "/diy-app/conf/appsList.json",
"bcastappSchedule": "/diy-app/schedules/STATION-1/appSchedule.json",
"appDefault": {
"appName": "trigger-1",
"properties": {}
}
}
}
}
-
Save the
bridge.jsonfile. -
Open for editing the
diy-app/schedules/STATION-1/appSchedule.jsonfile and remove the current JSON data and replace with the JSON data below. This will create a CTA event usingtrigger-1which then links to the main application, STATION-1.
{
"appSchedules": {
"schedulePoll": 10,
"schedule": {
"event1": {
"start": 1603792122,
"appName": "trigger-1",
"properties": {}
}
}
}
}
-
Save the
appSchedule .json -
Verify with the local browser that the diy-app is loaded and linked when running the local browser tests.
Step 5 - Create the menu file.
In this step we shall create a default-menu file and add some simple configurations as an example to show how top and sub-level menus can be created using the framework menu templates.
-
In the folder
public/diy-app/dynamic/menu/, delete the currentdefault-menu.jsonfile and create a new one with the same name. -
Open the new
default-menu.jsonfile for editing and add the following JSON as a placeholder and save.
{
"main": []
}Step 6 - Add Now/Next display on the application
The framework provides a widget type that can display details of the current/next program if the required Electronic Service Guide information is signalled correctly in the live over-air transmission stream.
To add the Now/Next widget complete the following steps:
-
Add two JSON objects as follows to the “main” array. This adds a top level menu item on the application. The “click“ property contains a reference name to use as a link to the sub-menu which will be created next.
{
"main": [
{"type": "button", "txt": {"en": "On NOW", "es": "Futuro: AHORA"}, "click": "now"},
{"type": "button", "txt": {"en": "On NEXT", "es": "Futuro: SIGUIENTE"}, "click": "next"}
]
}
-
Add the sub-menus for both NOW and NEXT functions using the dedicated widget types (sg-now and sg-next). This is done using the following JSON objects in the diy-menu file.
{
"main": [
{"type": "button", "txt": {"en": "On NOW", "es": "Futuro: AHORA"}, "click": "now"},
{"type": "button", "txt": {"en": "On NEXT", "es": "Futuro: SIGUIENTE"}, "click": "next"}
],
"now": [
{"type": "sg-now", "app": "broadcast", "default-title": {"en": "Current Live Program", "es": "Programación Actual"}, "default-placeholder": "img/pics/lester_holt.png"}
],
"next": [
{"type": "sg-next", "app": "broadcast", "default-title": {"en": "Next Program Title", "es": "Título del Próximo Programa"}, "default-placeholder": "img/pics/4news.png"}
]
}
Step 7 - Test the Now/Next menu options
-
Test the Now/Next additions using the local browser.
-
Confirm that these option are now present on the Top menu.
-
The result should look something like the image below.
Step 8 - Add a Feed type menu to the application
A “Feed“ type menu option is a default widget type within the framework, which allows the Broadcaster Application designer to add a menu option which can preform the following:
-
Add a broadband URL pointing to an endpoint with a JSON feed description file.
-
Retrieve the JSON feed data and parse.
-
Display as a vertical strip content that is defined within the JSON feed data.
-
Allow the user to navigate the strip and display/play the selected content.
Feed metadata uses a standardised JSON format. The details are covered in this document link:
To add a feed to our application complete the following steps:
-
Add the following JSON to the diy-menu file.
{
"main": [
{"type": "button", "txt": {"en": "On NOW", "es": "Futuro: AHORA"}, "click": "now", "focus": true},
{"type": "button", "txt": {"en": "On NEXT", "es": "Futuro: SIGUIENTE"}, "click": "next"},
{"type": "button", "txt": {"en": "Feeds", "es": "Alcanzar"}, "click": "feeds"}
],
"now": [
{"type": "description", "txt": {"en": "On NOW", "es": "AHORA"}},
{"type": "sg-now", "app": "broadcast", "default-title": {"en": "Current Live Program", "es": "Programación Actual"}, "default-placeholder": "img/pics/lester_holt.png"}
],
"next": [
{"type": "description", "txt": {"en": "Next Program", "es": "Programa Siguiente"}},
{"type": "sg-next", "app": "broadcast", "default-title": {"en": "Next Program Title", "es": "Título del Próximo Programa"}, "default-placeholder": "img/pics/4news.png"}
],
"feeds": [
{"type": "strip", "app": "catch-up", "feed": {"en": "https://secure-receiver-service.atsc3-modelmarket.com/feed/hearst/feed1.json", "es": "https://secure-receiver-service.atsc3-modelmarket.com/feed/hearst/feed2.json"}}
]
}
Step 9 - Test the feeds
-
Test the feeds addition using the local browser.
-
Confirm that the feed option appears in the top menu and that the sub-menu strip contains thumbnail assets (needs internet connection).
-
Select on of the thumbnails and press enter to play. The asset should start to play video overriding the “broadcast“ video.
-
The result should look something like the image below.
Add a basic AEA parser application
Using the framework query and notification inbuilt functions for Alerting, additional functions can be added into the Broadcaster Application to use additional data for processing and/or display.
This example uses the AEA XML table response from the framework when an alert is present, to parse the XML and extract AEA alarm text for display onscreen.
This will use a very basic new Broadcaster Application, running in the dynamic space alongside the framework. The application will use the framework Alerting functions to access AEA data contained within the broadcast transmission, via the receivers own alerting API interface.
It can be tested locally (on local machine browsers) by using pre-configured AEA alert data within atscCmd.json to simulate a receivers API response.
Pre-requisites
The default atscCmd.json file should contain an entry defining a 2nd service with globalServiceID (GSID), tag:yottamedialabs.com,2020:globalServiceID/2. This JSON object should also contain a pre-configured A/344 API response for AEA alerts. By mapping the AEA application to this GSID, an AEA event will be available to the application, simulating an event carried over the broadcast transmission.
The JSON entry should look like this.
{
"org.atsc.query.service": {
"service": "tag:yottamedialabs.com,2020:globalServiceID/2",
"a3fa-rmp": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/WeAreGoingOnBullrun.mp4"
},
"org.atsc.query.baseURI": {
"baseURI": "http://localhost:5001/dynamic-apps"
},
"org.atsc.query.alerting": {
"alertList": [
{"alertingType": "AEAT", "alertingFragment": "<?xml version=\"1.0\" encoding=\"UTF-8\"?><AEAT xmlns=\"tag:atsc.org,2016:XMLSchemas/ATSC3/Delivery/AEAT/1.0/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><AEA aeaId=\"AEAT-1-290620\" aeaType=\"alert\" audience=\"public\" issuer=\"KYML\" priority=\"3\" wakeup=\"false\"><Header effective=\"2016-03-23T12:00:00-05:00\" expires=\"2021-03-23T13:00:00-05:00\"><EventCode type=\"SAME\">HUW</EventCode><EventDesc lang=\"en\">HURRICANE WARNING</EventDesc><Location type=\"FIPS\">000000</Location></Header><AEAText lang=\"en\">An Alert AEAT-1-290620 is active</AEAText><Media contentType=\"image/jpeg\" lang=\"en\" mediaDesc=\"Winds chart png\" url=\"wind_charts.jpg\"/></AEA></AEAT>"},
{"alertingType": "OSN", "alertingFragment": "<OSN></OSN>", "receiveTime": "2020-01-01T23:54:59.590Z"}
]
}
}
To create the parser in the application follow these steps:
Step 1 - Create a New Application HTML file
-
Confirm that in the
diy-app/appsfolder there is a folder calledaeat. If not create one. -
In
diy-app/apps/aeat, check that an index.html is present and has the HTML code as shown below. Save the file if changes were required.
<!DOCTYPE html>
<html>
<head>
<title>Default</title>
<meta charset="UTF-8">
</head>
<body style="margin: 150px;">
<div id="alert" style="color: white;background-color: black;border: 2px solid red;position: absolute;top: 0;bottom: 0;left: 0;right: 0;margin: auto auto;width: 600px;height: 40px;font-size: xx-large;text-align: center;display: none;"></div>
<script>
var dynamic = document.createElement("script");
dynamic.src = new URLSearchParams(window.location.search).get("baseURI") + "/a3fa-common/libs/a3fa-framework.dynamic.min.js";
document.write(dynamic.outerHTML);
</script>
<script>
fmw
.onload(function () {
this.alerting(function (err, res) {
if (err) { return fmw.error("fmw.alerting() ifr:", err); }
alert(res);
});
})
.onAlert(function (list) {
//this.log("fmw.onAlert() ifr:", list);
alert(list);
});
function alert(list) {
for (var obj of list) {
if (typeof obj === "object" && obj && 'alertingType' in obj && 'alertingFragment' in obj && typeof obj.alertingFragment === "string") {
if (obj.alertingType === "AEAT") {
parseAEAT(obj.alertingFragment);
} else if (obj.alertingType === "OSN") {
// TODO:
}
}
}
}
function parseAEAT(data) {
var xml = new DOMParser().parseFromString(data, "text/xml"); // convert text/xml into dom object
window._aeat = xml;
if (xml.firstChild && 'getElementsByTagName' in xml.firstChild && typeof xml.firstChild.getElementsByTagName === "function") {
var aea = xml.firstChild.getElementsByTagName("AEA");
if (aea.length === 0) { return; }
var AEAText = aea[0].getElementsByTagName("AEAText");
if (AEAText.length > 0) {
document.getElementById("alert").style.display = "block";
document.getElementById("alert").innerText = AEAText[0].textContent;
}
}
}
</script>
</body>
</html>
Key index.html sections
The key operational sections of the AEA index.html are broken down as follows.
A Div is included to produce a section for display of the AEA alert text extracted by the XML parser.
<div id="alert" style="color: white;background-color: black;border: 5px solid red;position: absolute;top: 0;bottom: 0;left: 0;right: 0;margin: auto auto;width: 600px;height: 40px;font-size: xx-large;text-align: center;display: none;"></div>
The A3FA Framework dynamic library is imported, to allow interfacing with the frameworks API, which includes AEA alert functions.
<script>
var dynamic = document.createElement("script");
dynamic.src = new URLSearchParams(window.location.search).get("baseURI") + "/a3fa-common/libs/a3fa-framework.dynamic.min.js";
document.write(dynamic.outerHTML);
</script>
The index.html includes script functions to query the AEA state onloading of the page, and also to listen to future AEA change events.
fmw
.onload(function () {
this.alerting(function (err, res) {
if (err) { return fmw.error("fmw.alerting() ifr:", err); }
alert(res);
});
})
.onAlert(function (list) {
//this.log("fmw.onAlert() ifr:", list);
alert(list);
});
Finally AEA index.html includes a basic XML parser to extract the AEA alert text property from the AEA data provided by the alerting API.
function parseAEAT(data) {
var xml = new DOMParser().parseFromString(data, "text/xml"); // convert text/xml into dom object
window._aeat = xml;
if (xml.firstChild && 'getElementsByTagName' in xml.firstChild && typeof xml.firstChild.getElementsByTagName === "function") {
var aea = xml.firstChild.getElementsByTagName("AEA");
if (aea.length === 0) { return; }
var AEAText = aea[0].getElementsByTagName("AEAText");
if (AEAText.length > 0) {
document.getElementById("alert").style.display = "block";
document.getElementById("alert").innerText = AEAText[0].textContent;
}
}
}
Step 2 - Link the application to a GlobalServiceID (TV Service)
-
Edit the
bridge-conf/1.0/bridge.jsonto add a link to the new application to a 2nd service, with the JSON below.
{
"connection": "bband",
"bridge": {
"tag:yottamedialabs.com,2020:globalServiceID/1": {
"bcastappList": "/diy-app/conf/appsList.json",
"bcastappSchedule": "/diy-app/schedules/STATION-1/appSchedule.json"
},
"tag:yottamedialabs.com,2020:globalServiceID/2": {
"bcastappList": "/diy-app/conf/appsList.json",
"bcastappSchedule": "/diy-app/schedules/AEAT/appSchedule.json"
}
}
}
-
In the
diy-app/conf/appsList.jsonfile, add an aeat application entry as shown below, then save file.
{
"appList": {
"applications": {
"aeat": {
"appRoot": "/diy-app/apps/aeat",
"appEntry": "/index.html",
"properties": {}
},
"trigger-1": {
"appRoot": "/a3fa-common/apps/triggers",
"appEntry": "/cta.html",
"properties": {
"linkApp": "STATION-1",
"hidden": false,
"timeout": 5,
"img": "/diy-app/apps/trigger/STATION-1/img/img.png",
"hover": "/diy-app/apps/trigger/STATION-1/img/hover.png"
}
},
"STATION-1": {
"appRoot": "/a3fa-common/apps/common-app",
"appEntry": "/index.html",
"properties": {
"back": {"properties": {"hidden": true}},
"menu": "/diy-app/apps/common-app/STATION-1/dynamic/menu/default-menu.json",
"settings": "/diy-app/apps/common-app/STATION-1/config/default-settings.json",
"menu-settings": "/diy-app/apps/common-app/STATION-1/config/menu-settings.json",
"style": "/diy-app/apps/common-app/STATION-1/css/default.css",
"amp": "/diy-app/apps/common-app/STATION-1/css/skin.css",
"resize": true,
"header": {"type": "channel", "title": {"en": "APP ID 1", "es": "APP ID 1"}, "id": "SRV1", "name": "ID-1", "logo": "/diy-app/apps/common-app/STATION-1/img/home-menu/channel.png"},
"terms-of-service": "/diy-app/apps/common-app/STATION-1/tos/terms-of-service.html",
"privacy-policy": "/diy-app/apps/common-app/STATION-1/tos/privacy-policy.html",
"panels-ttl": 300000,
"player-ttl": 15000
},
"drm": null,
"allowConfigDRM": true,
"allowLocalStorage": true,
"allowFrameworkStorage": true
}
}
}
}
-
In the
diy-app/schedules/STATION-1/appSchedule.jsonfile add an event for theaeatapp to display. JSON data is shown below.
{
"appSchedules": {
"schedulePoll": 10,
"schedule": {
"event1": {
"start": 1603792122,
"appName": "aeat",
"properties": {}
}
}
}
}Step 3 -Test on Local Browser
-
Test the changes on the browser by navigating to the 4th service using the keyboard “u“ for channel up and “d“ for channel down.
-
On the forth service should now see an Alert Banner overlaying the background video.