Advanced Adaptive Media Player (AAMP) 1
/opt/xrehtmlappswhitelist.conf 3
Universal Video Engine (UVE) APIs 4
AAMP Reference Player demonstrates use of Unified Video Engine (UVE) JavaScript binding APIs to interact with AAMP player.
The bindings are made available in JavaScript with the help of injectedbundle once DOM elements are loaded by webkit.
This README is targeted to OTT app vendors and HTML5 developers who are interested in evaluating/adopting AAMP for their media player applications on settops.
HLS (Clear, Access, Vanilla AES-128)
DASH ( Clear, Playready/Widevine)
Inband Closed Captions
Audio Language Selection
Trickplay and Audio/Video Bitrate Selection
Setup in RDK devices(Comcast)
Host ReferencePlayer folder in a web server or in /opt/www/ folder in device
Folders in /opt/www/ can be accessed using http://localhost:50050/<folder name>
To launch reference player, use Comcast's Chariot App (https://send2chariot.xreapps.net:8443/send2chariot/#/send/html)
Fill in X1 Device ID (from XRAY)
Select "Chariot XRE" for Launch Type
fill in URL to launch (i.e. http://localhost:50050/ReferencePlayer/index.html)
Specify "Default" for Browser Type
Select "Mute Player"
Select "Use Background"
Select "Enable Debug Mode -1"
Click "Send" button
If hosted in /opt/www folder, need the following override config files in /opt folder since XRE rejects Fling requests with URLs with domain localhost/127.0.0.1. Contents for the override files are provided in Appendix section.
/opt/webfilterpatterns.conf
/opt/xrehtmlappswhitelist.conf
-icons // UI elements of reference players and homepage
-UVE
-index.html // Homepage of UVE reference player
-UVEMediaPlayer.js // Includes "AAMPPlayer" JS class which wraps UVE binding object AAMPMediaPlayer
-UVEPlayerUI.js // JS code for the UI elements and their functionality
-UVERefPlayer.js // Main JS file
-UVERefPlayerStyle.js // CSS for reference player and its UI
-index.html // Homepage of reference player
-ReferencePlayer.js // JS code for Homepage and redirection to respective reference players
-URLs.js // list of selectable streams
-ReferencePlayerStyle.css // CSS for Homepage and its UI
{"webfilter":[
{"host":"localhost", "block":"0"},
{"host":"127.0.0.1", "block":"1"},
{"host":"169.254.*", "block":"1"},
{"host":"192.168.*", "block":"1"},
{"host":"[::1]", "block":"1"},
{"scheme":"file", "block":"1"},
{"scheme":"ftp", "block":"1"},
{"scheme":"*", "block":"0"},
{"block":"1"}
]}
{"htmlappswhitelist":
[
{
"name" : "About Blank Page",
"url" : "about:blank"
},
{
"name" : "Viper Player",
"url" : "ccr.player-platform-stage.xcr.comcast.net/index.html"
},
{
"name" : "Google",
"url" : "www.google.com"
},
{
"name" : "AAMP Reference Player",
"url" : "localhost:50050/ReferencePlayer/index.html"
}
]
}
export interface IVideoEngine {
/**
* URI of the Media being played by the Video Engine
*/
load(uri: string);
/**
* IConfig Object with key value pair of launch configuration
*/
initConfig(IConfig: Object[]);
/**
* Starts playback when enough data is buffered at playhead
*/
play(): void;
/**
* Pauses playback
*/
pause(): void;
/**
* Stop playback and free resources
*/
stop(): void;
/**
* Performs a seek
* @param timeSec the time in seconds to seek
*/
seek(timeSec: number): void;
/**
* Gets the current state
* This defaults to PlayState.PAUSED
*/
getCurrentState(): PlayState;
/**
* Gets the duration of the content in seconds.
*/
getDurationSec(): number;
/**
* Gets the current user time in seconds.
*/
getCurrentPosition(): number;
/**
* Gets available video bitrates
*/
getVideoBitrates(): number;
/**
* Gets the current video bitrate.
*/
getCurrentVideoBitrate(): number;
/**
* Sets the current video bitrate.
*/
setVideoBitrate(bitrate: number): void;
/**
* Gets the current audio bitrate
*/
getCurrentAudioBitrate(): number;
/**
* Gets the current volume (value between 0 and 1)
*/
getVolume(): number;
/**
* Sets the current volume (value between 0 and 1)
*/
setVolume(volume: number): void;
/**
* Gets the current playback rate
*/
getPlaybackRate(): number;
/**
* Sets the current playback rate and overshoot if necessary
*/
setPlaybackRate(rate: number, overshoot:number ?= 0): void;
/**
* Black out the video for parental controls
*/
setVideoMute(enabled: boolean): void;
// DAI
/**
* Subscribe to specific tags / DOM Element
*/
setSubscribedTags(tagNames: string []); // Used to identify Content Break period
addEventListener(name: string, handler: Function);
removeEventListener(name: string, handler: Function);
/**
* Set the DRM config params
*/
setDRMConfig(config: DRMConfig);
/**
* Add custom headers to HTTP requests
*/
addCustomHTTPHeader(headerName: string, headerValue: string []);
/**
* Remove a custom headers set previously, with empty args will delete all
*/
removeCustomHTTPHeader(headerName: string);
/**
* Set display video rectangle co-ordinates
*/
setVideoRect(x: number, y: number, w: number, h: number);
/**
* Set video zoom
*/
setVideoZoom(videoZoom: string);
}
export interface IConfig {
/**
* max initial bitrate (kbps)
*/
initialBitrate: number;
/**
* start position offset (ms)
*/
offset?: number;
/**
* network request timeout (ms)
*/
networkTimeout: number;
/**
* max amount of time to download ahead of playhead (seconds)
* e.x:
* with a downloadBuffer of 10s there will be 10 seconds of
* video or audio stored in javascript memory and not in a
* playback buffer
*/
downloadBuffer: number;
preferredAudioLanguage: string;
drm: DRMConfig;
/**
* network proxy to use (Format <SCHEME>://<PROXY IP:PROXY PORT>)
*/
networkProxy: string;
/**
* network proxy to use for license requests (Format same as network proxy)
*/
licenseProxy: string;
}
drmConfig = {
'com.microsoft.playready': 'http://test.playready.microsoft.com/service/rightsmanager.asmx';
'com.widevine.alpha': 'https://widevine-proxy.appspot.com/proxy';
'preferredKeysystem': 'com.widevine.alpha';
acquireLicense?: (initData: Uint8Array, challenge: ArrayBuffer) => Promise<ArrayBuffer>;
};
// set the DRM options
videoEngine.setDRMConfig(drmConfig);
event |
Payload |
description |
playbackStateChanged |
state: number |
fired as state changes across play/pause seek/not-seek quadruplet |
playbackProgressUpdate |
durationMiliseconds: number, positionMiliseconds: number, playbackSpeed: number, startMiliseconds: number, endMiliseconds: number |
fired based on the interval set |
playbackCompleted |
|
fired when there is nothing left to play |
playbackSpeedChanged |
speed: number, reason: string |
|
playbackFailed |
shouldRetry: boolean, code: number, description: string |
fired when an error occurs |
decoderAvailable |
decoderHandle: number |
fired when video decoder handle becomes available, required for closedcaption parsing + rendering by RDK ClosedCaptions module |
mediaMetadata |
durationMiliseconds: number, languages: string[], bitrates: number[], playbackSpeeds: number[], width: number, height: number, hasDrm: boolean |
fired with metadata of the asset currently played, includes duration(in ms), audio language list, available bitrate list, hasDrm, supported playback speeds |
speedsChanged |
playbackSpeeds: number[] |
fired when supported playback speeds changes (based on iframe availability) |
Player States |
|
|
Idle |
|
|
Playing |
|
|
Paused |
|
|
Seeking |
|
|
Error code |
Media Error |
Sub code |
Error String |
AAMP_TUNE_INIT_FAILED |
90 |
|
"AAMP: init failed" |
AAMP_TUNE_MANIFEST_REQ_FAILED |
90 |
|
"AAMP: Manifest Download failed" |
AAMP_TUNE_AUTHORISATION_FAILURE |
40 |
|
"AAMP: Authorization failure" |
AAMP_TUNE_FRAGMENT_DOWNLOAD_FAILURE |
90 |
|
"AAMP: fragment download failures" |
AAMP_TUNE_UNTRACKED_DRM_ERROR |
90 |
|
"AAMP: DRM error untracked error" |
AAMP_TUNE_DRM_INIT_FAILED |
90 |
|
"AAMP: DRM Initialization Failed" |
AAMP_TUNE_DRM_DATA_BIND_FAILED |
90 |
|
"AAMP: InitData-DRM Binding Failed" |
AAMP_TUNE_DRM_CHALLENGE_FAILED |
90 |
|
"AAMP: DRM License Challenge Generation Failed" |
AAMP_TUNE_LICENCE_TIMEOUT |
90 |
|
"AAMP: DRM License Request Timed out" |
AAMP_TUNE_LICENCE_REQUEST_FAILED |
90 |
|
"AAMP: DRM License Request Failed" |
AAMP_TUNE_INVALID_DRM_KEY |
90 |
|
"AAMP: Invalid Key Error, from DRM" |
AAMP_TUNE_ERROR_GETTING_ACCESS_TOKEN |
90 |
|
"AAMP: Error Getting Access Token" |
AAMP_TUNE_FAILED_TO_GET_AAMP_INSTANCE |
90 |
|
"AAMP: Failed to get AAMP instance for DRM plugin |
AAMP_TUNE_UNSUPPORTED_STREAM_TYPE |
90 |
|
"AAMP: Unsupported Stream Type" |
AAMP_TUNE_FAILED_TO_GET_KEYID |
90 |
|
"AAMP: Failed to parse key id from PSSH" |
AAMP_TUNE_FAILED_TO_GET_ACCESS_TOKEN |
90 |
|
"AAMP: Failed to get access token from Auth Service" |
AAMP_TUNE_CORRUPT_DRM_DATA |
90 |
|
"AAMP: DRM failure due to Corrupt DRM files" |
AAMP_TUNE_GST_PIPELINE_ERROR |
90 |
|
"AAMP: Error from gstreamer pipeline" |
AAMP_TUNE_FAILURE_UNKNOWN |
90 |
|
"AAMP: Unknown Failure" |