The Node.js hbbtv
module is a feature complete implementation of the HbbTV 2.0 Companion Screen components:
- HbbTV App Launch: Launching a Companion Screen application from an HbbTV application
- CS App Launch: Launching a broadcast independent HbbTV application on an HbbTV terminal from a Companion Screen application.
- App2App Communication: Exchange text and binary messages between HbbTV and Companion Screen applications
Please refer to the HbbTV 2.0 spec document for more details especially to the Companion Screen related sections 8.2.6 and 14.
The module is developed by the Fraunhofer FOKUS´s Competence Center Future Applications and Media - FAME. Please contact us [email protected] for more details or if you need help to integrate this module in your product.
If you find Bugs please submit a new GitHub issue.
- Node.js. Tested with:
- Node.js v0.12.5 on Windows, Mac and Linux.
- Node.js v0.10.25 on Windows.
- npm (will be installed with Node.js)
- Install globally: use
npm install hbbtv -g
to install the module. The-g
option installs the module globally which is preferred if the module is used just as CLI. After the module is installed thehbbtv
command will be available (Usage section explains how to use thehbbtv
command). On Mac and Linux you may need to install the module usingsudo npm install hbbtv -g
. Some optional components require Python 2.7, please ignore related error logs if Python 2.7 is not installed on your machine or usenpm install hbbtv -g --no-optional
to not install optional components.- Update globally installed module: just run
npm update -g hbbtv
- Update globally installed module: just run
- Install locally: This is not preferred if you want to use the module as CLI. Use
npm install hbbtv
without-g
option will create anode_modules
folder with thehbbtv
module in it. Please note that thehbbtv
command will be not available if you install the module locally. Another way to install locally is to clone this git repository and runnpm install
(ornpm install --no-optional
) in the home folder to install dependencies. Usage section explains how to use this module if it is installed locally.- Update locally installed module: just run
npm update hbbtv
in the same folder where you installed the module (where you rannpm install hbbtv
). If the module is cloned from git, rungit pull
and thennpm install
.
- Update locally installed module: just run
- Integrate in other Node.js applications: To integrate this module in your Node.js application just add
"hbbtv": "<version>"
(replace<version>
with the actual version) to thedependencies
element of thepackage.json
in your application. In your application usevar hbbtv = require("hbbtv")
to bind the module. For more details about the APIs supported in this module please refer to the API Documentation section.- Update module integrated in 3rd party applications: replace
<version>
with a newer version inpackage.json
of your Node.js application
- Update module integrated in 3rd party applications: replace
The hbbtv
module can be started as HbbTV Terminal (terminal
mode) or as Companion Screen (cs
mode):
-
If it is started in
terminal
mode, your machine will be seen as a HbbTV 2.0 CS compliant Terminal. You can use any HbbTV DIAL client to launch HbbTV applications and use any WebSocket client for App2App communication. The following command can be used to start interminal
mode on port8080
:-
hbbtv
installed globallyhbbtv -m terminal -p 8080
-
hbbtv
installed locallycd /path/to/folder/hbbtv/bin node hbbtv.js -m terminal -p 8080
-
-
If it is started in
cs
mode, it will turn you machine in a companion screen that runs a CSLauncher and HbbTV DIAL Client. The HbbTV Terminal started in previous step will be able to discover companion screens running a CSLauncher and to launch CS applications. Since the discovery and communication between HbbTV terminals and CSLaunchers is not part of the HbbTV 2.0 Spec, we used here also the DIAL protocol to discover CSLaunchers and launch CS Applications. The CSLauncher acts as DIAL Server that offers a non-stoppable DIAL application calledFamium
which is already registered in the DIAL registry. The application accepts DIAL launch requests in the body of the related HTTP POST requests in the same format as specified in section 14.4.2 "Payload format for Install and Launch operations" of the HbbTV 2.0 spec document. The following command can be used to start thehbbtv
module incs
mode on port8090
:-
hbbtv
installed globallyhbbtv -m cs -p 8090
-
hbbtv
installed locallycd /path/to/folder/hbbtv/bin node hbbtv.js -m cs -p 8090
-
-
To display
hbbtv
usage options use the following command:-
hbbtv
installed globallyhbbtv -h
-
hbbtv
installed locallycd /path/to/folder/hbbtv/bin node hbbtv.js -h
-
The fastest way to test this module is by using the example HbbTV and CS applications hosted on github.io:
- HbbTV App:
http://fraunhoferfokus.github.io/node-hbbtv/www/hbbtv-app.html
- CS Web App:
http://fraunhoferfokus.github.io/node-hbbtv/www/cs-app.html
-
start
hbbtv
module interminal
mode:hbbtv -m terminal -p 8080
-
start
hbbtv
module incs
mode:hbbtv -m cs -p 8090
It is possible to start
hbbtv
interminal
andcs
mode on different ports on the same device. For better understanding, it is recommended to use two different devices one forterminal
and one forcs
. both devices must be in the same network in order to discover and communicate with each others using DIAL and WebSocket. -
open CS Web App
http://fraunhoferfokus.github.io/node-hbbtv/www/cs-app.html#port=8090
in a browser on the same device from previous step wherehbbtv
is started incs
mode (the port must be the same as in previous step). -
follow the instructions in the CS App opened in the browser in previous step: You will be able to discover the HbbTV Terminal started in first step, launch an HbbTV App on it and open a WebSocket communication channel to the remote App2App Endpoint of the discovered terminal.
-
After the HbbTV App is launched on the terminal, it will be able to discover CSLaunchers, launch CS Web Apps and create WebSocket communication channels to the local App2App Endpoint.
- The following example shows an HbbTV Application that discovers CSLaunchers, launches a CS Web App on a discovered CSLauncher and creates
a WebSocket connection to the local App2App Endpoint. The following steps are needed to run this example:
- Start
hbbtv
interminal
mode:hbbtv -m terminal -p 8080
- Please don't open this application manually in the Browser. Use the example CS Web App described in next subsection to launch this application.
- Start
- The HbbTV Web App needs to include the JavaScript Lib
hbbtv-manager-polyfill.js
- Please refer to section 8.2.6 of the HbbTV 2.0 Spec document for more details about the JavaScript API of the HbbTVCSManager.
<!DOCTYPE html>
<!-- http://www.example.com/hbbtv-app.html -->
<html>
<head lang="en">
<meta charset="UTF-8">
<title>HbbTV App</title>
<script type="text/javascript" src="js/hbbtv-manager-polyfill.js"></script>
</head>
<body>
<script type="text/javascript">
var csManager = oipfObjectFactory.createCSManager();
var app2appLocalBaseUrl = csManager.getApp2AppLocalBaseURL();
var appEndpoint = "org.mychannel.myapp";
var discoverCSLaunchers = function(){
csManager.discoverCSLaunchers(function (csLaunchers) {
if(csLaunchers.length==0){
console.log("No CS launcher found.");
}
else{
console.log(csLaunchers.length, " CSLaunchers found");
var csLauncher = csLaunchers[0];
console.log("Launch CS Web App on companion device: ",csLauncher.friendly_name);
launchCsApp(csLauncher, "http://www.example.org/cs-app.html");
}
console.log("cs launchers found",csLaunchers);
});
};
var launchCsApp = function (csLauncher, csAppUrl) {
var payload = {
"launch": [
{"launchUrl": csAppUrl+"?app2appURL="+csManager.getApp2AppRemoteBaseURL(), "appType": "html"}
]
};
csManager.launchCSApp(csLauncher.enum_id, payload, function (res) {
console.log("launch cs app result code", res);
});
};
var createConnection = function (index) {
var ws = new WebSocket(app2appLocalBaseUrl + appEndpoint);
ws.binaryType = "arraybuffer";
ws.onopen = function(evt) {
console.log("Connection ",index," waiting ...");
};
ws.onclose = function(evt) {
console.log("Connection ",index," closed.");
};
ws.onerror = function (evt) {
console.log("Connection error.");
};
ws.onmessage = function(evt) {
if (evt.data == "pairingcompleted") {
console.log("connection ",index," paired");
ws.onmessage = function(evt) {
if(typeof evt.data == "string"){
console.log( "Received Message: " + evt.data);
}
else {
var data = typeof Buffer != "undefined"?new Buffer(evt.data): new Int8Array(evt.data);
console.log("Received Binary Message of " + data.length + " bytes", data);
}
};
ws.send("Hello from HbbTV App: "+index);
// create a new connection to accept additional clients
createConnection(index+1);
} else {
console.log("Unexpected message received from terminal.");
ws.close();
}
};
};
// create first connection to local App2App endpoint
createConnection(0);
</script>
</body>
</html>
- The following example show a CS Web Application that discovers HbbTV Terminals, launches an HbbTV App on a discovered terminal and creates
a WebSocket connection to the App2App Endpoint of the discovered Terminal. The following steps are needed to run this example:
- Start
hbbtv
incs
mode:hbbtv -m cs -p 8090
- Open the CS Web App in a Browser on the same device and append
#port=8090
to the URL:http://www.example.com/cs-app.html#port=8090
- Start
- The CS Web App needs to include the JavaScript Lib
hbbtv-manager-polyfill.js
- The following example uses all JavaScript functions required to discover terminals, launch HbbTV Apps and create WebSocket connection. API documentation coming soon.
<!DOCTYPE html>
<!-- http://www.example.com/cs-app.html -->
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Companion Screen App</title>
<script type="text/javascript" src="js/hbbtv-manager-polyfill.js"></script>
</head>
<body>
<script type="text/javascript">
var channel = "org.mychannel.myapp";
// create a TerminalManager instance to discover HbbTV Terminals and launch HbbTV Apps
// You need to append #port=<port> to the url in the browser.
var terminalManager = hbbtv && hbbtv.createTerminalManager();
// use the discoverTerminals supported by the TerminalManager to discover HbbTV Terminals
var discoverTerminals = function(){
terminalManager.discoverTerminals(function (terminals) {
if(terminals.length==0){
console.log("No HbbTV Terminals found");
}
else {
console.log(terminals.length, " Terminals found");
var terminal = terminals[0];
console.log("Launch HbbTV App on Terminal: ",terminal.friendly_name);
launchHbbTVApp(terminal,"http://www.example.org/hbbtv-app.html");
}
});
};
// Launch an HbbTV App on discovered terminal
var launchHbbTVApp = function (terminal, appUrl) {
var options = {
"orgId": 0,
"appId": 0,
"appUrlBase": appUrl,
"appLocation": "?channel="+channel
};
terminalManager.launchHbbTVApp(terminal.enum_id, options, function (res) {
console.log("Launch HbbTV App result code", res);
console.log("Connect to HbbTV Terminal: ",terminal.friendly_name);
connect(terminal);
});
};
// Create a WebSocket connection to the App2App endpoint of the Terminal
var connect = function (terminal) {
var app2appRemoteBaseUrl = terminal && terminal.X_HbbTV_App2AppURL ;
var ws = new WebSocket(app2appRemoteBaseUrl + channel);
ws.binaryType = "arraybuffer";
ws.onopen = function(evt) {
console.log("Connection waiting ...");
};
ws.onclose = function(evt) {
console.log("Connection closed.");
};
ws.onerror = function (evt) {
console.log("Connection error.");
};
ws.onmessage = function(evt) {
if (evt.data == "pairingcompleted") {
console.log("connection paired");
ws.onmessage = function(evt) {
console.log( "Received Message: " + evt.data);
};
var data = "Hello from Companion Screen";
ws.send(data);
var array = [0,1,2,3,4,5,6,7,8,9];
data = typeof Buffer != "undefined"?new Buffer(array): new Int8Array(array).buffer;
ws.send(data);
} else {
console.log("Unexpected message received from terminal.");
ws.close();
}
};
};
</script>
</body>
</html>
the hbbtv
module can also used to implement HbbTV CS Node.js clients without the need to develop CS Web App that runs
in the Browser. This is for example useful to run HbbTV CS test cases or to use in Node.js applications to discover HbbTV
terminals, launch HbbTV applications and create WebSocket connections to the remote App2App Endpoint of discovered terminals.
The following example illustrates the usage of supported features
var hbbtv = require("hbbtv");
var HbbTVDialClient = hbbtv.HbbTVDialClient;
var WebSocket = hbbtv.WebSocket;
// create a hbbTVDialClient instance and add listeners for ready, stop, found and error events
var hbbTVDialClient = new HbbTVDialClient().on("ready", function () {
console.log("HbbTV DIAL Client is ready");
}).on("stop", function () {
console.log("HbbTV DIAL Client is stopped");
}).on("found", function (terminal) {
// found events are triggered each time a new HbbTV terminal is found
console.log("HbbTV Terminal ", terminal.getFriendlyName()," (", terminal.getAppLaunchURL(), ") found");
var channel = (""+Math.random()).substr(2,16);
// launch HbbTV App on each discovered terminal
terminal.launchHbbTVApp({
"appUrlBase": "http://fraunhoferfokus.github.io/node-hbbtv/www/hbbtv-app.html",
"appLocation": "?channel="+channel
}, function (launchRes,err) {
if(err){
console.error("Error on launch HbbTV App", err);
}
else {
console.log("HbbTV App launched successfully: ",launchRes || "");
// create App2App connection after application is launched
createConnection(terminal, channel);
}
});
}).on("error", function (err) {
console.error(err);
});
var createConnection = function (terminal, channel) {
var app2appRemoteBaseUrl = terminal.getApp2AppURL();
var ws = new WebSocket(app2appRemoteBaseUrl + channel);
ws.binaryType = "arraybuffer";
ws.onopen = function(evt) {
console.log("Connection waiting ...");
};
ws.onclose = function(evt) {
console.log("Connection closed.");
};
ws.onerror = function (evt) {
console.log("Connection error.");
};
ws.onmessage = function(evt) {
if (evt.data == "pairingcompleted") {
console.log("pairing complete");
ws.onmessage = function(evt) {
console.log( "Received Message: " + evt.data);
};
var data = "Hello from Companion Screen";
ws.send(data);
var array = [0,1,2,3,4,5,6,7,8,9];
data = typeof Buffer != "undefined"?new Buffer(array): new Int8Array(array).buffer;
ws.send(data);
} else {
console.log("Unexpected message received from terminal.");
ws.close();
}
};
};
hbbTVDialClient.start();
// hbbTVDialClient.stop();
Please contact us [email protected] for more details
Please contact us [email protected] for more details
Please contact us [email protected] for more details
The Node.js hbbtv
module is designed to be integrated in existing products like set-top-boxes or TV sets with Node.js
environment. The current implementation launches HbbTV and Companion Screen applications in the default browser. This is
practicable to test HbbTV 2.0 CS features on the same environment developers use to develop their applications. To
use this module in real products, the HbbTV UA needs to be launched instead of the default browser. This can be easily done
by making the HbbTV UA as default Browser or just by starting it directly from this module just by replacing the lines of
code where the default Browser is launched with your launch command.
API documentation for the hbbtv-manager-polyfill.js
and the hbbtv
module and its sub-components coming soon.
We are grateful for any valuable contribution, like issue reports, tests or pull requests.
Moreover, we would love to hear which exciting apps you have created using the hbbtv
Node.js module.
Free for non commercial use released under the GNU Lesser General Public License v3.0, See LICENSE file.
Contact us for commercial use [email protected]
Copyright (c) 2015 Fraunhofer FOKUS