General requirements for media apps
This following general guidelines and requirements are necessary for a media streaming app on Vega to pass the appstore certification.
Release media player resources when app goes to background.
Apps must release unused media resources, specifically media playback related resources, when they are pushed to background by the Lifecyle Manager (LCM). The general guidance here is that for VOD content playback, the app must release the media resources and go back to the Movie or Content detail page. To allow users to quickly resume their playback experience from where they left off when the app is brought back to foreground, the app should retain the context of the live and VOD content playback.
Apps can release media resources by deinitializing VideoPlayer
or unmounting the Video
component from the render tree.
await shakaPlayer.detach();
await videoPlayer.deinitialize();
await shakaPlayer.unload();{}
await shakaPlayer.destroy();
For information about detecting the current state, see AppState.
Codec Selection
- Audio device capability based codec selection
The app must select the appropriate audio codec (AAC or Dolby) for playback depending on the audio capability of the connected HDMI display device such as a TV or AVR
- Switching between Bluetooth headset and HDMI output
During playback, the user might switch between Bluetooth headset and HDMI output. This can lead to changes in the supported audio codec on the display device. For example, HDMI output supports Dolby, whereas a Bluetooth headset doesn’t. Apps are required to detect this change in audio output capability and trigger audio codec switch in the MSE player.
Enforce Sequence Mode
A general recommendation is that you use the sequence mode for HLS amd MPEG2TS streaming content.
If you need to play MPEGTS content in HLS adaptive streams, enable the sequence mode flag as shown in the following sample code.
const initializeShaka = () => {
console.log('app: in initializePlayer() index = ', nextContent.index);
if (videoPlayer.current !== null) {
player.current = new ShakaPlayer(videoPlayer.current, playerSettings);
}
if (player.current !== null) {
player.current.load(content[nextContent.index], AUTOPLAY);
player.current.player.configure('manifest.hls.sequenceMode', true);
}
Manifest requirements
To properly support media plackback, you must have the following entries your manifest.toml file.
[wants]
[[wants.service]]
id = "com.amazon.mediametrics.service" # Required for metrics service
[[wants.service]]
id = "com.amazon.media.server"
[[wants.service]]
id = "com.amazon.gipc.uuid.*"
[[wants.service]]
id = "com.amazon.media.playersession.service"
[[wants.privilege]]
id = "com.amazon.devconf.privilege.accessibility" # Required for captions
[[wants.service]]
id = "com.amazon.mediabuffer.service"
[[wants.service]]
id = "com.amazon.mediatransform.service"
[offers]
[[offers.service]]
id = "com.amazon.gipc.uuid.*"
To use audio functionality for playback, you must have the following audio management services requested in the manifest.toml file:
- com.amazon.audio.stream - for all Playback/Record clients
- com.amazon.audio.control - for all AudioManager API clients
- com.amazon.audio.system - for all AudioManager API clients
[[wants.service]]
id = "com.amazon.audio.stream"
[[wants.service]]
id = "com.amazon.audio.control"
[[wants.service]]
id = "com.amazon.audio.system"
Limitation of Secure Video Decoder sessions
The first Fire TV based on Vega OS supports only one secure video decoder instance. To perform back to back secure video playback, you must deinitialize the first videoPlayer
instance before initializing the second one.
If you don't deintialize first videoPlayer
instance, the second playback will fail.
The following code sample shows how to deinitialize a videoPlayer
instance and start a new one.
// Start the first secure video playback.
// Init VideoPlayer
let videoPlayer1 = new VideoPlayer();
await videoPlayer1.initialize();
// Now perform the playback. After completion, deinitialize the player.
// Unload JS player
// Deinit VideoPlayer. Wait on promise
await videoPlayer1.deinitialize();
// After deinitialization of the first secure video playback, start the second secure video playback.
// Init VideoPlayer
let videoPlayer2 = new VideoPlayer();
await videoPlayer2.initialize();
// Now perform the playback. After completion deinitialize the player.
// Unload JS player
// Deinit VideoPlayer. Wait on promise
await videoPlayer2.deinitialize();
Last updated: Sep 30, 2025