Getting started with the Web Player on LG webOS

A basic example for getting the Web Player running on an LG webOS TV.

Introduction

This tutorial walks you through the process of creating & deploying an app that is capable of playing back your stream with the Bitmovin Player WebSDK on LG webOS TVs.

Modern webOS TVs use a Chromium-based web-engine to execute apps. That enables us to use the same APIs that are already known from various browsers. Beware that the version of Chromium running on a TV is locked and depends on the underlying webOS version. If you want to know which version of Chromium your TV runs, have a look at this overview provided by LG.

The Bitmovin Web SDK supports a wide range of webOS versions (as well as other Smart TV platforms) that you can check out in the device and cross browser support article.

Prerequisites

In order to deploy and test applications on webOS TVs, the webOS TV SDK needs to be installed on your working machine. The SDK consists of a set of CLI tools and a Visual Studio Code Plugin. Both components have to be installed separately. The official documentation offers a step-by-step guide on how to get both the CLI and plugin installed on your machine. It’s good to know that most things that can be done with the CLI can also be triggered from the VS Code extension. Capabilities of the extension are listed here.

For testing your app on a physical webOS TV, you need to configure developer mode on the target device, which is covered in this guide by LG. Please note that the webOS emulator and simulator are not supported by our player, so the application needs to be tested on a physical webOS TV.

Once you have set up your TV and working machine, we are ready to create our first demo application.

Project setup

While you can simply follow the webOS documentation and create a new web application from scratch, for simplicity's sake, we'll use the webOS sample application from our public demo repository as a starting point.

Go ahead and clone the repository to your local machine and then open it in VS Code.

git clone https://github.com/bitmovin/bitmovin-player-webos-demo.git

The files inside the src folder are interesting for us. Here is a short overview of the project’s structure:

File/FolderDescription
index.htmlHTML laying out the structure of the demo and definition of the used player resources
js/main.jsmain javascript file our demo application will use
images/place for the application logo
css/stylesheets used for making the demo application pretty
webOSTVjs-1.2.4/LG-provided library offering TV-specific features (details)
appinfo.jsoncontains app-metadata like app-id, title and icon (details)

Application configuration

Finally, we are going to dig into some code. Let's go through the different files one by one.

index.html

In order to keep the memory footprint small, as a smart TV is quite a constrained environment, we should use the modular player in our demo application, to load as little code as possible. The player modules are simply imported through script tags in the index.html.

Please note that this is not a full list and needs to be customized depending on your stream requirements. More details can be found in our modules overview.

...
<script type="text/javascript" src="https://cdn.bitmovin.com/player/web/8/modules/bitmovinplayer-core.js"></script>
<script type="text/javascript" src="https://cdn.bitmovin.com/player/web/8/modules/bitmovinplayer-polyfill.js"></script>
<script type="text/javascript" src="https://cdn.bitmovin.com/player/web/8/modules/bitmovinplayer-engine-bitmovin.js"></script>
...
<script type="text/javascript" src="https://cdn.bitmovin.com/player/web/8/modules/bitmovinplayer-webos.js"></script>

One important part here is adding the bitmovinplayer-webos module. This is a module specifically for webOS TVs which works around certain device limitations.

Below your player related module imports, include the webOS TV library files so that we can access TV specific APIs in our main.js later on.

<script type="text/javascript" src="webOSTVjs-1.2.4/webOSTV.js"></script>
<script type="text/javascript" src="webOSTVjs-1.2.4/webOSTV-dev.js"></script>
<script type="text/javascript" src="js/main.js"></script>

Apart from that, the index.html looks similar to the example from the Getting started.

js/main.js

In this file, our player is set up and configured. Our focus here are webOS TV specific settings.

An important side note is that some older webOS platforms only support ES5 syntax, so the recommendation is to stay on that syntax for your application.

In order to kickstart the application we are using the window.onload callback, as it ensures that all static resources are available at execution time:

window.onload = function() {
  setupControllerEvents();
	setupPlayer();

	// Set up DRM support ...

	loadSource(source);
}

Let's have a look at the setupPlayer and setupControllerEvents functions and highlight some areas of interest.

Module configuration

Inside our setupPlayer function, we first need to register the modules which our application requires and were loaded within the index.html file. This can be done by our addModule API.

bitmovin.player.core.Player.addModule(window.bitmovin.player.polyfill.default);
bitmovin.player.core.Player.addModule(window.bitmovin.player['engine-bitmovin'].default);
bitmovin.player.core.Player.addModule(window.bitmovin.player['container-mp4'].default);
bitmovin.player.core.Player.addModule(window.bitmovin.player.mserenderer.default);
bitmovin.player.core.Player.addModule(window.bitmovin.player.abr.default);
bitmovin.player.core.Player.addModule(window.bitmovin.player.drm.default);
bitmovin.player.core.Player.addModule(window.bitmovin.player.xml.default);
bitmovin.player.core.Player.addModule(window.bitmovin.player.dash.default);
bitmovin.player.core.Player.addModule(window.bitmovin.player.crypto.default;
bitmovin.player.core.Player.addModule(window.bitmovin.player.style.default);
bitmovin.player.core.Player.addModule(window.bitmovin.player.webos.default);

Player configuration

After all required modules are in place you can utilize the PlayerConfigBuilder.optimizeForPlatform to apply platform specific settings like shown below:

const conf = new bitmovin.player.core.util.PlayerConfigBuilder(PLAYER_KEY)
 // the appId is only required if your html page is bundled within the app 
 .optimizeForPlatform({ appId: APP_ID }) 
 .build();

// disable the default UI
conf.ui = false;

// analytics defaults get applied by the config builder on TV models
conf.analytics.customUserId = 'my-custom-user-id';

In this case you have to provide your PLAYER_KEY which can be obtained from the dashboard and optionally the APP_ID.

The APP_ID follows a reverse dns pattern such as com.bitmovin.demo.tizenwebapp and is a replacement for the hostname in standard applications. It needs to be allow-listed in the admin portal for your license requests to work on your TV application.

More details and best practices can be found at our article around Smart TV best practices

Now that we loaded all modules properly and set up a TV-friendly config, it’s time to complete the player setup by loading the player:

var container = document.getElementById('player')
player = new bitmovin.player.core.Player(container, conf);

Key mappings

TVs require a certain key mapping to interact with your application, which are set up inside our setupControllerEvents function. Beware that these mappings may vary based on the used TV controller mode. Our basic example enables you to play / pause your configured source, jump 30 seconds for-/ backward and unload the player with a conventional remote control:

  document.addEventListener('keydown', function (inEvent) {
    var keycode;

    if (window.event) {
      keycode = inEvent.keyCode;
    } else if (inEvent.which) {
      keycode = inEvent.which;
    }
    switch (keycode) {
      case 13:
        tooglePlayPause();
        break;
      case 415:
        // Play Button Pressed
        player.play();
        break;
      // other cases ommitted for readibilty; check out demo repo for full source
      default:
        console.log('Key Pressed: ' + keycode);
    }
  });

Playback of DRM protected content

You may have noticed the // Set up DRM support ... -comment in our window.onload function above. To play back DRM protected content on our webOS TV, we need to detect if DRM is supported and if the device’s drmAgent is ready for decrypting our content. Both is done in below displayed code snippet. If you check out the demo repository, you’ll find the following code instead of that placeholder-comment:

var keySystem = webOSDev && webOSDev.DRM.Type.WIDEVINE;
var webosDrmAgent = getDrmAgent(keySystem);

 if (webosDrmAgent) {
    isDrmLoaded(webosDrmAgent)
      .then(function () {
        return loadSource(source);
      })
      .catch(function (e) {
        console.log('Error while loading drm Agent', e);
      });
    return;
  }

Check out the webOS developer documentation on DRM support for further information.

Application packaging and deployment

Finally, we can prepare our application and deploy it. For that matter, you first need to package your app. Open a command prompt and cd into the project folder, then use ares-package ./src to create a .ipk package of your app.

After packaging, you need to connect to the developer mode-enabled TV either via CLI or VS Code extension. Both ways are covered in LG’s webOS developer documentation. Now that the app is packaged and you are connected to the TV, the app is ready for deployment.

Congratulations! You have successfully deployed a webOS app containing the Bitmovin player and are now able to enjoy awesome streaming experience on your TV screen!