HTML/H5P Player v2.0 Design
Introduction:
This document describes the design approach for HTML/H5P player
SB-28712: Tech Design - HTML Player V2 - Part 2Released
Background:
Now to play HTML or H5P content we use content player version 1 which is the combination of all the players as a single player.
Playing of the content is with the initial load is slow due to the heaviness of the player since it has all the players embedded as one
Extending it for further enhancements are harder to implement since it is tightly coupled with other players as once player
The current player is not adaptable to all the screens and it is having limitations on rendering in all the screen resolutions
Problem Statement:
Html player should be independently launched and player specific to html only
The player should have better performance
Key design problems:
Player - Define player and its dependencies and interactions with other components and the parent container
Player config - simplifying the player input configuration to start the content play
How to handle telemetry events
The player should support to the all screen resolutions
Performance of player should be better compared to older player
How to handle content consumption progress bar
How to handle page change events
How to show end page for html content
How to handle pagination for html and h5p content
How to handle next and previous interact events
Solution :
As we are building independent player performance will be better because its not tightly coupled with any player and it will be light weight
We can pass minimal player config to player or mandatory config to the player
playerConfig = { "context": {}, "config": {}, "metadata": { "identifier": "", // Mandatory, content id "name": "", // Mandatory, name of the content "pkgVersion": "", // Mandatory, package version "streamingUrl": "", // Mandatory, defines the streaming url "artifactUrl": "", // Mandatory, Defines the artifact url "isAvailableLocally": "", // Mandatory, defines the content availability status "basePath": "", // Mandatory, defines the base path "baseDir": "", // Mandatory, defines the base directory }, }
The screen resolution issue will be resolved by adding css to the iframe
we can handle telemetry events by using html interface file provided by html content
We can handle content consumption progress by using interface file provided by html content , below is the code snippet
org.ekstep.renderer.html.ProgressBar = function(flag){ org.ekstep.contentrenderer.progressbar(flag); }
We can handle end page by using methods provided by interface file , bellow is code snippet
org.ekstep.renderer.html.showEndPage = function() { org.ekstep.renderer.html.EkstepRendererAPI.showEndPage(); };
Design :
Player config:
playerConfig = {
"context": {
"mode": "play", // Optional, To identify preview used by the user to play/edit/preview
"authToken": "", // Optional, Auth key to make api calls
"sid": "7283cf2e-d215-9944-b0c5-269489c6fa56", // Optional,User sessionid on portal or mobile
"did": "3c0a3724311fe944dec5df559cc4e006", // Optional, Unique id to identify the device or browser
"uid": "anonymous", // Optional, Current logged in user id
"channel": "505c7c48ac6dc1edc9b08f21db5a571d", // Optional,Unique id of the channel(Channel ID)
"pdata": { // Optional,
"id": "sunbird.portal", // Optional, Producer ID. For ex: For sunbird it would be "portal" or "genie"
"ver": "3.2.12", // Optional, Version of the App
"pid": "sunbird-portal.contentplayer" // Optional, In case the component is distributed, then which instance of that component
},
"contextRollup": { // Optional, Defines the content roll up data
"l1": "505c7c48ac6dc1edc9b08f21db5a571d"
},
"tags": [ // Optional, Defines the tags data
""
],
"cdata": [], // Optional, Defines correlation data
"timeDiff": 0, // Optional, Defines the time difference
"objectRollup": {}, // Optional, Defines the object roll up data
"host": "", // Optional, Defines the from which domain content should be load
"endpoint": "", // Optional, Defines the end point
"userData": { // Optional, Defines the user data firstname & lastname
"firstName": "",
"lastName": ""
}
},
"config": {
"toolBar": { // Optional
"showZoomButtons": false, // show/hide zoom buttons. default value is false
"showPagesButton": false, // show/hide pages button. default value is false
"showPagingButtons": false, // show/hide paging buttons. default value is false
"showSearchButton": false, // show/hide search button. default value is false
"showRotateButton": false // show/hide rotation button. default value is false
},
"sideMenu": { // Optional and has default values
"showShare": true, // show/hide share button in side menu. default value is true
"showDownload": false, // show/hide download button in side menu. default value is false
"showReplay": false, // show/hide replay button in side menu. default value is false
"showExit": false, // show/hide exit button in side menu. default value is false
"showPrint": false // show/hide print button in side menu. default value is false
}
},
"metadata": {
"identifier": "", // Mandatory, content id
"name": "", // Mandatory, name of the content
"pkgVersion": "", // Mandatory, package version
"streamingUrl": "", // Mandatory, defines the streaming url
"artifactUrl": "", // Mandatory, Defines the streaming url
"isAvailableLocally": "", // Mandatory, defines the content availability status
"basePath": "", // Mandatory, defines the base path
"baseDir": "", // Mandatory, defines the base directory
},
}
Telemetry property description:
Property Name | Description | Default Value |
---|---|---|
| It is an |
|
| It is |
|
| It is |
|
| It is |
|
| It is |
|
| It is |
|
| It is |
|
| It is an |
|
| It is an |
|
| It is an |
|
| It is an |
|
| It is |
|
| It is an |
|
| It is an |
|
Config property description:
Property Name | Description | Default Value |
---|---|---|
| It is an |
|
| It is |
|
| It is |
|
| It is |
|
| It is |
|
| It is |
|
| It is an |
|
| It is |
|
| It is |
|
| It is |
|
| It is |
|
| It is |
|
Player events:
a) Start
This event is the beginning of the player event and will be triggered when the player starts.
{
eid: ‘START’, // event id
ver: ‘1.0’, // version of the application
edata: {
type: ‘START’, // edata type
currentPage: ‘2’, // current page count when content loads
duration: ‘’ // duration of content play's
},
metaData: {
identifier: '', // content id
name: '', // name of the content
}
}
b) End
This is one of the player event , which will be triggered when the player reaches the end of the content.
{
eid: ‘END’, // event id
ver: ‘1.0’, // version of the application
edata: {
type: ‘END’, // edata type
currentPage: ‘1’, // current page count when content loads
totalPages: ‘10’, // Total number of pages
duration: ‘’ // duration of content play's
},
metaData: {
"pagesVisited": [1], // page visited data
"totalPages": 184, // total numbber of pages
"duration": [107741], // pages visited/spent time
"zoom": ["auto"], // pages zoom values
"rotation": [0] // pages rotation values
}
}
c) HEARTBEAT
The player also has some other events like share, full screen, minimize screen, open menu, close menu, reply. and bellow are the type of heartbeat events with sample data
Open menu
This is one of the player event which is triggered when user clicks on menu icon{ "eid": "HEARTBEAT", "ver": "1.0", "edata": { "type": "OPEN_MENU", "currentPage": 1 }, "metaData": { "pagesVisited": [ 1, 1 ], "totalPages": 184, "duration": [ 11434, 281039 ], "zoom": [ 90, 100 ], "rotation": [ 0, 0 ] } }
Close menu
This is one of the player event which is triggered when user clicks on menu close icon{ "eid": "HEARTBEAT", "ver": "1.0", "edata": { "type": "CLOSE_MENU", "currentPage": 1 }, "metaData": { "pagesVisited": [ 1, 1 ], "totalPages": 184, "duration": [ 11434, 281039 ], "zoom": [ 90, 100 ], "rotation": [ 0, 0 ] } }
Share
This is one of the player event which is triggered when user clicks on share icon{ "eid": "HEARTBEAT", "ver": "1.0", "edata": { "type": "SHARE", "currentPage": 4 }, "metaData": { "pagesVisited": [ 4 ], "totalPages": 184, "duration": [ 18 ], "zoom": [ "auto" ], "rotation": [ 0 ] } }
Minimize screen
This is one of the player event which is triggered when user clicks on minimize{ "eid": "HEARTBEAT", "ver": "1.0", "edata": { "type": "MINIMIZE_SCREEN", "currentPage": 1 }, "metaData": { "pagesVisited": [ 1 ], "totalPages": 184, "duration": [ 11434 ], "zoom": [ 90 ], "rotation": [ 0 ] } }
Full screen
This is one of the player event which is triggered when user clicks on fullscreen{ "eid": "HEARTBEAT", "ver": "1.0", "edata": { "type": "FULL_SCREEN", "currentPage": 1 }, "metaData": { "pagesVisited": [ 1, 1 ], "totalPages": 184, "duration": [ 11434, 281039 ], "zoom": [ 90, 100 ], "rotation": [ 0, 0 ] } }
Turn off sound
This is one of the player event which is triggered when user clicks on turn off sound{ "eid": "HEARTBEAT", "ver": "1.0", "edata": { "type": "MUTE_SOUND", "currentPage": 4 }, "metaData": { "pagesVisited": [ 4 ], "totalPages": 184, "duration": [ 18 ], "zoom": [ "auto" ], "rotation": [ 0 ] } }
Turn on sound
This is one of the player event which is triggered when user clicks on turn on sound{ "eid": "HEARTBEAT", "ver": "1.0", "edata": { "type": "UNMUTE_SOUND", "currentPage": 4 }, "metaData": { "pagesVisited": [ 4 ], "totalPages": 184, "duration": [ 18 ], "zoom": [ "auto" ], "rotation": [ 0 ] } }
Replay
This is one of the player event which is triggered when user clicks on replay{ "eid": "HEARTBEAT", "ver": "1.0", "edata": { "type": "REPLAY", "currentPage": 184 }, "metaData": { "pagesVisited": [ 1, 1, 1, 183, 184 ], "totalPages": 184, "duration": [ 11434, 281039, 2194402, 1828, 99 ], "zoom": [ 90, 100, 90, 90, 90 ], "rotation": [ 0, 0, 0, 0, 0 ] } }
Property Name | Description | Default Value |
---|---|---|
| It is |
|
| It is |
|
| It is |
|
| It is |
|
| It is |
|
| It is |
|
| It is |
|
| It is |
|
| It is |
|
| It is |
|
| It is |
|
Telemetry events:
a) Start Event
This is the start event that will be triggered when the player starts playing and the following is the sample telemetry data.
"edata": {
"type": "content", // Defines edata type
"mode": "play", // Defines edata mode
"pageid": "", // Defines page id/number
"duration": 7.47 // Defines duration of play
}
b) Interact Event
This is the Interact event which will be triggered when the user does any interaction in the player like menu open or share and etc and following is the sample telemetry data.
"edata": {
"type": "TOUCH", // Defines edata type
"subtype": "", // Defines edata sub type
"id": "gc_menuopen", // Defines edata id
"pageid": "2" // Defines page id/number
}
c) Impression Event
This is the impression event that will be triggered when we open the player and the following is the sample telemetry data.
"edata": {
"type": "content", // Defines edata type
"mode": "play", // Defines edata mode
"pageid": "2", // Defines page id/number
"duration": 1 // Defines duration
}
d) End event
This is the end event and the following is the sample telemetry data.
"edata": {
"type": "content", // Defines edata type
"mode": "play", // Defines mode
"pageid": "sunbird-player-Endpage", // Defines page id
"summary": [
{
"progress": 50
},
{
"totallength": ""
},
{
"visitedlength": ""
},
{
"visitedcontentend": ""
},
{
"totalseekedlength": ""
},
{
"endpageseen": false
}
],
"duration": 1996.559 // Defines duration of the play
}
Sample complete telemetry data
{
"eid": "INTERACT", // Event id
"ets": 1646727758517, // Event time stamp
"ver": "3.0", // Version
"mid": "INTERACT:e6cf5520a276294b068acfabd52f363a",
"actor": { // User details
"id": "280d913d358428e24c92ed6b9e6d89a7",
"type": "User"
},
"context": {
"channel": "01268904781886259221", // Channel id
"pdata": {
"id": "preprod.diksha.portal", // Producer ID.
"ver": "4.7.0", // Version of the app
"pid": "sunbird-portal.contentplayer" //Optional. In case the component is distributed, then which instance of that component
},
"env": "contentplayer", // Defines the environment
"sid": "f7a8a672-9a3b-e83e-42a7-6131a553f65f", // User sessionid
"did": "280d913d358428e24c92ed6b9e6d89a7", // Unique id to identify the device or browser
"cdata": [ // Defines correlation data
{
"id": "fdaafa8413a27931dc01ff5a4cb3a0e2",
"type": "ContentSession"
},
{
"id": "7e20b101878957052b8cb9a9ec770ce7",
"type": "PlaySession"
}
],
"rollup": { // Roll up data
"l1": "01268904781886259221"
}
},
"object": {
"id": "do_2134417722515210241147", // Content identifier
"type": "Content", // Resource type
"ver": "1", // Defines version
"rollup": {} // Roll up data
},
"tags": [ // Defines the tags data
"01268904781886259221"
],
"edata": {
"type": "TOUCH", // Event data type
"subtype": "", // Event sub data type
"id": "gc_menuopen", // Defines the id
"pageid": "2" // Defines the page id
}
}
Pros:
Separation of Concern: With Separation of Concern we will have highly modular and maintainable code . Tight Coupling of Systems ends up constraining the player to put most part of the code which is non-functional for itself.
Any Potential changes to telemetry shouldn’t ideally end up republishing the player. An update on CSL should be enough. Which kind of reduces the risk of regression to Telemetry Only.
Modular Player: Since the entire player is an npm repo. It becomes easy to detach the existing player and move into the new one without any hassles
It is quite practical to interpret telemetry spec in a very customized way for most of the adaptors of Sunbird. This telemetry behaviour should be allowed to override with minimal effort.
Any new players created in future, will be less context aware and more functional in nature.
Cons:
Any player created in the future will have a dependency on CSL for default telemetry implementation. Could potentially be a source of friction.
Creating a Telemetry Interpreter can be a two-step task.
References:
Sunbird content player https://github.com/project-sunbird/sunbird-content-player/tree/release-4.6.0
Sunbird player sdk https://github.com/project-sunbird/sunbird-player-sdk/tree/release-4.8.0
Sunbird telemetry sdk https://github.com/project-sunbird/sunbird-telemetry-sdk/tree/release-3.3.0
Sunbird client services https://github.com/Sunbird-Ed/sunbird-client-services/tree/release-4.6.0