About headless integration
Resource contention issues
Media playback and UI rendering can block each other when running on the same JavaScript thread in two main scenarios: when media playback blocks UI responsiveness, or when UI operations block smooth media playback. Common media player implementations for streaming standards, such as MPEG DASH or HLS, can require significant system resources from the CPU and network. Specifically, the playback and live streaming processes demand CPU-intesive manifest parsing. When the player runs on the same thread as the UI, these components compete for resources, resulting in delayed playback start, choppy video playback, unresponsive UI elements, and poor overall user experience. The headless implementation solves these issues by running the player in a separate JS thread from the UI, creating a service component for the player. This enables the UI controls to interact with the service component to control the media playback. In this scenario, the player UI in the interactive component is a client and the player running the service component is the server. Benefits of headless integration include improved playback start time, enhanced UI responsiveness, and better overall playback performance. To implement headless playback in your app, you need to perform three tasks:- Create the player server as a service component in your app.
- Change the player code to interact with the service vs. directly controlling a player.
- Start the service from the app.
For detailed implementation steps, see Implement the headless service below.
Implement the headless service
To implement the headless service, perform the following steps:- Add components and capabilities to your app manifest.
- Create a service.js file.
- Create the headless service file.
-
Update your player code.
- Initialize the client.
- Handle video loading.
- Handle playback controls.
- Install additional dependencies.
Add components to your app manifest
A Vega app package must contain a configuration file called manifest.toml located at the root of the package. This file describes essential information about the package. To implement headless playback in your app, you need to update your app manifest in thecomponents, processes, wants, and offers sections. The following example shows you the specific updates for each section. Replace with your app’s package name.
Create a service.js file
Create a service.js file in your project root. The service.js file allows you to register the entry points (onStartService and onStopService) for the headless JS service. Replace with your app’s package name used in the manifest.toml file above to register the entry and exit points.
Create the headless service file
Create a helper file to handle player initialization and control within the./src/PlayerService.ts file.
Service file code
Service file code
Update your player code
Initialize the client
In your App.tsx file, add the following code to initialize the client.Initialize the client code
Initialize the client code
Handle video loading
Next, in your App.tsx file, add the following code to handle video loading.Handle video loading code
Handle video loading code
Handle playback controls
Next, in your App.tsx file, add the following code to handle playback controls.Handle playback controls code
Handle playback controls code
Integrate Vega Media Controls
Vega Media Controls (KMC) provides functionality that allows media app developers on Vega to streamline the integration of various input modalities for media control. While media apps typically feature in-app user interface controls, such as play, pause, and stop, customers often want additional interaction methods, such as remote control or voice commands through services such as Alexa. Vega Media Controls functionality handles the integration of these diverse input methods, allowing you to focus on the core business logic of smooth media playback. Apps that use the headless JS playback API to play their content can now get the KMC integration for free for basic playback controls such as pause, play, and seek. The headless JS playback APIs internally creates the KMC server, publishes the server states, and handles basic commands of play, pause, and seek. Headless JS playback must only update the KMC server state for the data pertaining to basic playback. If the app handles KMCs itself, it need not use headless JS playback integration. It must integrate directly into KMC to handle the commands. This integration is only applicable for use cases where the player is integrated with an interactive component. Apps shouldn’t callplayer.setMediaControlFocus(componentInstance) or implement override functionality.
To opt-in to KMC
- Enable KMC. Add the necessary manifest entries to your manifest.toml file as described in Get started with Vega Media Controls Overview.
-
Update your package.json file to take a dependency on
@amazon-devices/kepler-media-controls. -
Get the component instance of the interactive component:
-
Before calling the
IPlayerClient.loadAPI, set the media control focus on the player instance.
playerClient instance is enabled with KMC and supports basic functionality of pause/play and seek remote control and Alexa voice controls.
Override certain control commands
In some cases, the app might want to override the handling of certain control commands that is handled by headless JS playback APIs by default. For example, you can disable seek during live content playback. Headless JS playback APIs also provides a way to achieve this experience.-
Extend
PlayerClientMediaControlHandlerprovided by@amazon-devices/kepler-player-clientand override the function that the app wants to override. -
Pass the app’s media control handler as the second parameter to the
setMediaControlFocusmethod.
Install additional dependencies
You need to install the following packages to use the headless service:@amazon-devices/kepler-player-server@amazon-devices/kepler-player-client@amazon-devices/react-native-w3cmedia
- React Native 0.72
- React Native 0.83
Best practices
Background mode
When the app goes to background, it’s recommended that the UI callsIPlayerClient::unloadSync to unload the media player. Similarly, headless JS service should unload the media player and do the necessary cleanup in its onStopService callback.
Related topics
- Vega Headless Tasks and Services
- Vega Player Client API Reference
- Vega Player Server API Reference
- Vega App Manifest
- App Performance Best Practices
- Vega Media Controls API reference

