Created
February 4, 2021 12:17
-
-
Save SiddharthaChowdhury/8b8d5bc56ac3c12905b6bb4d5b5693b9 to your computer and use it in GitHub Desktop.
VideoPlayerDRM_LIVE
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function () { | |
'use strict'; | |
/** | |
* Displays logging information on the screen and in the console. | |
* @param {string} msg - Message to log. | |
*/ | |
function log(msg) { | |
var logsEl = document.getElementById('logs'); | |
if (msg) { | |
// Update logs | |
console.log('[PlayerAvplayDRM]: ', msg); | |
logsEl.innerHTML += msg + '<br />'; | |
} else { | |
// Clear logs | |
logsEl.innerHTML = ''; | |
} | |
logsEl.scrollTop = logsEl.scrollHeight; | |
} | |
var player; | |
// flag to monitor UHD toggling | |
var uhdStatus = false; | |
// Configuration data for different DRM systems | |
/** | |
* | |
* @property {String} name - name to be displayed in UI | |
* @property {String} url - content url | |
* @property {String} licenseServer - [Playready/Widevine] url to the license server | |
* @property {String} customData - [Playready] extra data to add to the license request | |
*/ | |
var drms = { | |
NO_DRM: { | |
name: 'No DRM', | |
url: 'http://playready.directtaps.net/smoothstreaming/SSWSS720H264/SuperSpeedway_720.ism/Manifest' | |
}, | |
// PLAYREADY: { | |
// name: 'Playready', | |
// url: 'http://playready.directtaps.net/smoothstreaming/SSWSS720H264PR/SuperSpeedway_720.ism/Manifest', | |
// licenseServer: 'http://playready.directtaps.net/pr/svc/rightsmanager.asmx?PlayRight=1&UseSimpleNonPersistentLicense=1', | |
// customData: '' | |
// }, | |
PLAYREADY: { | |
name: 'Playready', | |
url: 'http://ac-001.live.p7s1video.net/5186392a/t_001/prosieben-de-mss/cenc_mss.isml/Manifest', | |
licenseServer: 'https://licenses.drm.p7s1video.net/drm/v1/ksm?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6InRlc3RLSUQifQ.eyJpYXQiOjE2MTIxODQ4OTEsIm5iZiI6MTYxMjE4NDgzMSwiZXhwIjoxNjEzOTEyODkxLCJhaWQiOiJwcm9zaWViZW4tZGUtc2QiLCJjZmciOiJsMSJ9.-FGmJE0vV9kWXiJkrmi0VpoC6bzmSDU4ikbpQkx0KlI', | |
customData: '' | |
}, | |
// PLAYREADY_GET_CHALLENGE: { | |
// name: 'Playready GetChallenge', | |
// url: 'http://playready.directtaps.net/smoothstreaming/SSWSS720H264PR/SuperSpeedway_720.ism/Manifest', | |
// licenseServer: '', | |
// customData: '' | |
// }, | |
PLAYREADY_GET_CHALLENGE: { | |
name: 'Playready GetChallenge', | |
url: 'https://ac-001.live.p7s1video.net/44e2a246/t_001/prosieben-de-sd/cenc-default.mpd', | |
licenseServer: 'https://licenses.drm.p7s1video.net/drm/v1/ksm?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6InRlc3RLSUQifQ.eyJpYXQiOjE2MTIxODQ4OTEsIm5iZiI6MTYxMjE4NDgzMSwiZXhwIjoxNjEzOTEyODkxLCJhaWQiOiJwcm9zaWViZW4tZGUtc2QiLCJjZmciOiJsMSJ9.-FGmJE0vV9kWXiJkrmi0VpoC6bzmSDU4ikbpQkx0KlI', | |
customData: '' | |
}, | |
WIDEVINE: { | |
name: 'Widevine', | |
url: 'http://commondatastorage.googleapis.com/wvmedia/starz_main_720p_6br_tp.wvm', | |
licenseServer: 'https://license.uat.widevine.com/getlicense/widevine', | |
customData: '' | |
} | |
/*Smooth Streaming examples*/ | |
// url: | |
// 'http://playready.directtaps.net/smoothstreaming/SSWSS720H264/SuperSpeedway_720.ism/Manifest', url: | |
// 'http://playready.directtaps.net/smoothstreaming/TTLSS720VC1/To_The_Limit_720.ism/Manifest', | |
/*Smooth Streaming + Playready example*/ | |
// url: | |
// "http://playready.directtaps.net/smoothstreaming/SSWSS720H264PR/SuperSpeedway_720.ism/Manifest", | |
// licenseServer: | |
// 'http://playready.directtaps.net/pr/svc/rightsmanager.asmx?PlayRight=1&UseSimpleNonPersistentLicense=1' | |
}; | |
/** | |
* Register keys used in this application | |
*/ | |
function registerKeys() { | |
var usedKeys = [ | |
'MediaPause', | |
'MediaPlay', | |
'MediaPlayPause', | |
'MediaFastForward', | |
'MediaRewind', | |
'MediaStop', | |
'0', | |
'1', | |
'2', | |
'3' | |
]; | |
usedKeys.forEach( | |
function (keyName) { | |
tizen.tvinputdevice.registerKey(keyName); | |
} | |
); | |
} | |
/** | |
* Handle input from remote | |
*/ | |
function registerKeyHandler() { | |
document.addEventListener('keydown', function (e) { | |
switch (e.keyCode) { | |
case 13: // Enter | |
player.toggleFullscreen(); | |
break; | |
case 38: //UP arrow | |
switchDrm('up'); | |
break; | |
case 40: //DOWN arrow | |
switchDrm('down'); | |
break; | |
case 10252: // MediaPlayPause | |
case 415: // MediaPlay | |
case 19: // MediaPause | |
player.playPause(); | |
break; | |
case 413: // MediaStop | |
player.stop(); | |
break; | |
case 417: // MediaFastForward | |
player.ff(); | |
break; | |
case 412: // MediaRewind | |
player.rew(); | |
break; | |
case 48: //key 0 | |
log(); | |
break; | |
case 49: //Key 1 | |
setUhd(); | |
break; | |
case 50: //Key 2 | |
player.getTracks(); | |
break; | |
case 51: //Key 3 | |
player.getProperties(); | |
break; | |
case 10009: // Return | |
if (webapis.avplay.getState() !== 'IDLE' && webapis.avplay.getState() !== 'NONE') { | |
player.stop(); | |
} else { | |
tizen.application.getCurrentApplication().hide(); | |
} | |
break; | |
default: | |
log("Unhandled key"); | |
} | |
}); | |
} | |
/** | |
* Display application version | |
*/ | |
function displayVersion() { | |
var el = document.createElement('div'); | |
el.id = 'version'; | |
el.innerHTML = 'ver: ' + tizen.application.getAppInfo().version; | |
document.body.appendChild(el); | |
} | |
function registerMouseEvents() { | |
document.querySelector('.video-controls .play').addEventListener( | |
'click', | |
function () { | |
player.playPause(); | |
document.getElementById('streamParams').style.visibility = 'visible'; | |
} | |
); | |
document.querySelector('.video-controls .stop').addEventListener( | |
'click', | |
function () { | |
player.stop(); | |
document.getElementById('streamParams').style.visibility = 'hidden'; | |
} | |
); | |
document.querySelector('.video-controls .pause').addEventListener( | |
'click', | |
player.playPause | |
); | |
document.querySelector('.video-controls .ff').addEventListener( | |
'click', | |
player.ff | |
); | |
document.querySelector('.video-controls .rew').addEventListener( | |
'click', | |
player.rew | |
); | |
document.querySelector('.video-controls .fullscreen').addEventListener( | |
'click', | |
player.toggleFullscreen | |
); | |
} | |
/** | |
* Create drm switching list | |
*/ | |
function createDrmList () { | |
var drmParent = document.querySelector('.drms'); | |
var currentDrm; | |
var li; | |
for (var drmID in drms) { | |
li = document.createElement('li'); | |
li.className = li.innerHTML = drms[drmID].name; | |
li.dataset.drm = drmID; | |
drmParent.appendChild(li); | |
} | |
currentDrm = drmParent.firstElementChild; | |
currentDrm.classList.add('drmFocused'); | |
} | |
/** | |
* Enabling uhd manually in order to play uhd streams | |
*/ | |
function setUhd() { | |
if (!uhdStatus) { | |
if (webapis.productinfo.isUdPanelSupported()) { | |
log('4k enabled'); | |
uhdStatus = true; | |
} else { | |
log('this device does not have a panel capable of displaying 4k content'); | |
} | |
} else { | |
log('4k disabled'); | |
uhdStatus = false; | |
} | |
player.setUhd(uhdStatus); | |
} | |
/** | |
* Changes drm settings according to user's action | |
* @param {String} direction - 'up' or 'down' | |
*/ | |
function switchDrm (direction) { | |
var drmParent = document.querySelector('.drms'); | |
var currentDrm = drmParent.querySelector('.drmFocused'); | |
currentDrm.classList.remove('drmFocused'); | |
if (direction === 'up') { | |
if (currentDrm === drmParent.firstElementChild) { | |
currentDrm = drmParent.lastElementChild; | |
} else { | |
currentDrm = currentDrm.previousElementSibling; | |
} | |
} else if (direction === 'down') { | |
if (currentDrm === drmParent.lastElementChild) { | |
currentDrm = drmParent.firstElementChild; | |
} else { | |
currentDrm = currentDrm.nextElementSibling; | |
} | |
} | |
currentDrm.classList.add('drmFocused'); | |
player.setChosenDrm(drms[currentDrm.dataset.drm]); | |
} | |
/** | |
* Function initialising application. | |
*/ | |
window.onload = function () { | |
if (window.tizen === undefined) { | |
log('This application needs to be run on Tizen device'); | |
return; | |
} | |
/** | |
* Player configuration object. | |
* | |
* @property {Object} drms - object containing drm configurations | |
* @property {HTML Element} player - application/avplayer object | |
* @property {HTML Div Element} controls - player controls | |
* @property {HTLM Div Element} info - place to display stream info | |
* @property {Function} logger - function to use for logging within player component | |
* | |
*/ | |
var config = { | |
drms:drms, | |
player: document.getElementById('av-player'), | |
controls: document.querySelector('.video-controls'), | |
info: document.getElementById('info'), | |
logger: log | |
}; | |
displayVersion(); | |
createDrmList(); | |
registerKeys(); | |
registerKeyHandler(); | |
//Check the screen width so that the AVPlay can be scaled accordingly | |
tizen.systeminfo.getPropertyValue( | |
"DISPLAY", | |
function (display) { | |
log("The display width is " + display.resolutionWidth); | |
config.resolutionWidth = display.resolutionWidth; | |
// initialize player - loaded from videoPlayer.js | |
player = new VideoPlayer(config); | |
registerMouseEvents(); | |
}, | |
function(error) { | |
log("An error occurred " + error.message); | |
} | |
); | |
} | |
}()); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Player object constructor. | |
* | |
* @param {Object} config - Playback and player configuration. | |
* @returns {Object} | |
*/ | |
function VideoPlayer(config) { | |
var log = config.logger; | |
/** | |
* HTML av-player element | |
*/ | |
var player = config.player; | |
/** | |
* HTML controls div | |
*/ | |
var controls = config.controls; | |
/** | |
* Fullscreen flag | |
* @type {Boolean} | |
*/ | |
var isFullscreen = false; | |
/** | |
* DRM type to handle | |
* @type {String} | |
*/ | |
var chosenDrm = config.drms.NO_DRM; | |
/** | |
* HTML element to display stream properties. | |
*/ | |
var info = config.info; | |
var defaultResolutionWidth = 1920; | |
var resolutionWidth = config.resolutionWidth; | |
var playerCoords = { | |
x: Math.floor(10 * resolutionWidth / defaultResolutionWidth), | |
y: Math.floor(300 * resolutionWidth / defaultResolutionWidth), | |
width: Math.floor(854 * resolutionWidth / defaultResolutionWidth), | |
height: Math.floor(480 * resolutionWidth / defaultResolutionWidth) | |
}; | |
/** | |
* 4k flag | |
* @type {Boolean} | |
*/ | |
var isUhd = false; | |
return { | |
/** | |
* Function to initialize the playback. | |
* @param {String} url - content url, if there is no value then take url from config | |
*/ | |
play: function (url) { | |
log('Starting playback'); | |
/* Create listener object. */ | |
var listener = { | |
onbufferingstart: function () { | |
log("Buffering start."); | |
}, | |
onbufferingprogress: function (percent) { | |
log("Buffering progress data : " + percent); | |
}, | |
onbufferingcomplete: function () { | |
log("Buffering complete."); | |
}, | |
oncurrentplaytime: function (currentTime) { | |
log("Current playtime: " + currentTime); | |
}, | |
onevent: function (eventType, eventData) { | |
log("event type: " + eventType + ", data: " + eventData); | |
}, | |
ondrmevent: function (drmEvent, drmData) { | |
log("DRM callback: " + drmEvent + ", data: " + drmData); | |
/* Playready Challenge alternative scenario start */ | |
if (drmData.name === "Challenge") { | |
var drmParam = { | |
ResponseMessage: drmData.message | |
}; | |
log('setDrm InstallLicense: ' + JSON.stringify(drmParam)); | |
webapis.avplay.setDrm("PLAYREADY", "InstallLicense", JSON.stringify(drmParam)); | |
} | |
/* Playready Challenge alternative scenario end */ | |
}, | |
onstreamcompleted: function () { | |
log("Stream Completed"); | |
this.stop(); | |
}.bind(this), | |
onerror: function (eventType) { | |
log("event type error : " + eventType); | |
} | |
}; | |
if (!url) { | |
url = config.url; | |
} | |
log('videoPlayer open: ' + url); | |
try { | |
webapis.avplay.open(url); | |
webapis.avplay.setDisplayRect( | |
playerCoords.x, | |
playerCoords.y, | |
playerCoords.width, | |
playerCoords.height | |
); | |
webapis.avplay.setListener(listener); | |
} catch (e) { | |
log(e); | |
} | |
//set bitrates according to the values in your stream manifest | |
// this.setBitrate(477000, 2056000, 2056000, 688000); | |
//set 4k | |
if (isUhd) { | |
this.set4K(); | |
} | |
/* Setting DRMs */ | |
switch (chosenDrm) { | |
case config.drms.PLAYREADY: | |
this.setPlayready(); | |
break; | |
case config.drms.PLAYREADY_GET_CHALLENGE: | |
this.setPlayreadyChallenge(); | |
break; | |
case config.drms.WIDEVINE: | |
this.setWidevine(); | |
break; | |
default: | |
log('no DRM'); | |
} | |
if (chosenDrm !== config.drms.PLAYREADY_GET_CHALLENGE) { | |
webapis.avplay.prepare(); | |
webapis.avplay.play(); | |
} | |
}, | |
/** | |
* Function to start/pause playback. | |
* @param {String} url - content url, if there is no value then take url from config | |
*/ | |
playPause: function (url) { | |
if (!url) { | |
url = chosenDrm.url; | |
} | |
if (webapis.avplay.getState() === 'PLAYING' || webapis.avplay.getState() === 'PAUSED') { | |
this.pause(); | |
} else { | |
this.play(url); | |
} | |
}, | |
/** | |
* Function to stop current playback. | |
*/ | |
stop: function () { | |
webapis.avplay.stop(); | |
//switch back from fullscreen to window if stream finished playing | |
if (isFullscreen === true) { | |
this.toggleFullscreen(); | |
} | |
info.innerHTML = ''; | |
}, | |
/** | |
* Function to pause/resume playback. | |
* @param {String} url - content url, if there is no value then take url from config | |
*/ | |
pause: function (url) { | |
if (!url) { | |
url = chosenDrm.url; | |
} | |
if (webapis.avplay.getState() === 'PLAYING') { | |
webapis.avplay.pause(); | |
} else if (webapis.avplay.getState() === 'NONE' || webapis.avplay.getState() === 'IDLE') { | |
this.play(url); | |
} else { | |
webapis.avplay.play(); | |
} | |
}, | |
/** | |
* Jump forward 3 seconds (3000 ms). | |
*/ | |
ff: function () { | |
webapis.avplay.jumpForward('3000'); | |
}, | |
/** | |
* Rewind 3 seconds (3000 ms). | |
*/ | |
rew: function () { | |
webapis.avplay.jumpBackward('3000'); | |
}, | |
/** | |
* Set information about chosen DRM type. | |
* @param {String} drm - String name of the DRM option to call correct option in play() function. | |
*/ | |
setChosenDrm: function (drm) { | |
chosenDrm = drm; | |
}, | |
/** | |
* Set flag to play UHD content. | |
* @param {Boolean} isEnabled - Flag to set UHD. | |
*/ | |
setUhd: function (isEnabled) { | |
isUhd = isEnabled; | |
}, | |
/** | |
* Set to TV to play UHD content. | |
*/ | |
set4K: function () { | |
webapis.avplay.setStreamingProperty("SET_MODE_4K", "true"); | |
}, | |
/** | |
* Function to set specific bitrates used to play the stream. | |
* In case of Smooth Streaming STARTBITRATE and SKIPBITRATE values 'LOWEST', 'HIGHEST', 'AVERAGE' can be set. | |
* For other streaming engines there must be numeric values. | |
* | |
* @param {Number} from - Lower value of bitrates range. | |
* @param {Number} to - Hieher value of the birrates range. | |
* @param {Number} start - Bitrate which should be used for initial chunks. | |
* @param {Number} skip - Bitrate that will not be used. | |
*/ | |
setBitrate: function (from, to, start, skip) { | |
var bitrates = '|BITRATES=' + from + '~' + to; | |
if (start !== '' && start !== undefined) { | |
bitrates += '|STARTBITRATE=' + start; | |
} | |
if (to !== '' && to !== undefined) { | |
bitrates += '|SKIPBITRATE=' + skip; | |
} | |
webapis.avplay.setStreamingProperty("ADAPTIVE_INFO", bitrates); | |
}, | |
/** | |
* Function to change current VIDEO/AUDIO/TEXT track | |
* @param {String} type - Streaming type received with webapis.avplay.getTotalTrackInfo(), possible values | |
* are: VIDEO, AUDIO, TEXT. | |
* @param {Number} index - Track id received with webapis.avplay.getTotalTrackInfo(). | |
*/ | |
setTrack: function (type, index) { | |
webapis.avplay.setSelectTrack(type, index); | |
}, | |
/** | |
* Function to set Playready license server and (optionally) custom data. | |
* It needs special privilege in config.xml: | |
* <tizen:privilege name="http://developer.samsung.com/privilege/drmplay"/> | |
*/ | |
setPlayready: function () { | |
var drmParam = { | |
DeleteLicenseAfterUse: true | |
}; | |
if (chosenDrm.licenseServer !== '' && chosenDrm.licenseServer !== undefined) { | |
drmParam.LicenseServer = chosenDrm.licenseServer; | |
} | |
if (chosenDrm.customData !== '' && chosenDrm.customData !== undefined) { | |
drmParam.CustomData = chosenDrm.customData; | |
} | |
log('setDrm Playready param: ' + JSON.stringify(drmParam)); | |
try { | |
webapis.avplay.setDrm("PLAYREADY", "SetProperties", JSON.stringify(drmParam)); | |
} catch (e) { | |
log(e.name) | |
} | |
}, | |
/** | |
* Function send challenge request to playready license server. | |
* It needs special privilege in config.xml: | |
* <tizen:privilege name="http://developer.samsung.com/privilege/drmplay"/> | |
*/ | |
setPlayreadyChallenge: function () { | |
var drmParam = { | |
DeleteLicenseAfterUse: true, | |
GetChallenge: true | |
}; | |
var PrepareSuccessCallback = function () { | |
log('PrepareSuccessCallback'); | |
webapis.avplay.play(); | |
}; | |
log('setDrm Playready GetChallenge param: ' + JSON.stringify(drmParam)); | |
webapis.avplay.setDrm("PLAYREADY", "SetProperties", JSON.stringify(drmParam)); | |
webapis.avplay.prepareAsync(PrepareSuccessCallback); | |
}, | |
/** | |
* Function to set Widevine license server and (optionally) custom data. | |
* It needs special privilege in config.xml: | |
* <tizen:privilege name="http://developer.samsung.com/privilege/drminfo"/> | |
*/ | |
setWidevine: function () { | |
var deviceId = webapis.drminfo.getEsn('WIDEVINE'); | |
var drmParam = "DEVICE_ID=" + deviceId + "|DEVICE_TYPE_ID=60|STREAM_ID=|IP_ADDR=|DRM_URL=" + | |
chosenDrm.licenseServer + "|PORTAL=OEM|I_SEEK=|CUR_TIME=|USER_DATA="; | |
if (chosenDrm.customData !== '' && chosenDrm.customData !== undefined) { | |
drmParam += chosenDrm.customData; | |
} | |
log('setStreamingProperty Widevine param: ' + drmParam); | |
try { | |
webapis.avplay.setStreamingProperty("WIDEVINE", drmParam); | |
} catch (e) { | |
log(e.name) | |
} | |
}, | |
/** | |
* Show information about all available stream tracks on the screen. | |
*/ | |
getTracks: function () { | |
var trackInfo = webapis.avplay.getTotalTrackInfo(); | |
var text = 'type of track info: ' + typeof trackInfo + '<br />'; | |
text += 'length: ' + trackInfo.length + '<br />'; | |
for (var i = 0; i < trackInfo.length; i++) { | |
text += 'index: ' + trackInfo[i].index + ' '; | |
text += 'type: ' + trackInfo[i].type + ' '; | |
text += 'extra_info: ' + trackInfo[i].extra_info + '<br />'; | |
} | |
info.innerHTML = text; | |
}, | |
/** | |
* Show streaming properties on the screen. | |
*/ | |
getProperties: function () { | |
var text = 'AVAILABLE_BITRATE: ' + webapis.avplay.getStreamingProperty("AVAILABLE_BITRATE") + '<br />'; | |
text += 'CURRENT_BANDWIDTH: ' + webapis.avplay.getStreamingProperty("CURRENT_BANDWITH") + '<br />'; | |
text += 'DURATION: ' + webapis.avplay.getStreamingProperty("DURATION") + '<br />'; | |
text += 'BUFFER_SIZE: ' + webapis.avplay.getStreamingProperty("BUFFER_SIZE") + '<br />'; | |
text += 'START_FRAGMENT: ' + webapis.avplay.getStreamingProperty("START_FRAGMENT") + '<br />'; | |
text += 'COOKIE: ' + webapis.avplay.getStreamingProperty("COOKIE") + '<br />'; | |
text += 'CUSTOM_MESSAGE: ' + webapis.avplay.getStreamingProperty("CUSTOM_MESSAGE"); | |
info.innerHTML = text; | |
}, | |
/** | |
* Switch between full screen mode and normal windowed mode. | |
*/ | |
toggleFullscreen: function () { | |
if (isFullscreen === false) { | |
// webapis.avplay.setDisplayRect(0, 0, 1920, 1080); | |
player.classList.add('fullscreenMode'); | |
controls.classList.add('fullscreenMode'); | |
isFullscreen = true; | |
} else { | |
try { | |
webapis.avplay.setDisplayRect( | |
playerCoords.x, | |
playerCoords.y, | |
playerCoords.width, | |
playerCoords.height | |
); | |
} catch (e) { | |
log(e); | |
} | |
player.classList.remove('fullscreenMode'); | |
controls.classList.remove('fullscreenMode'); | |
isFullscreen = false; | |
} | |
} | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi , i am trying to play playready drm video in tizen by using ur code and i alwayes gettin this error "PLAYER_ERROR_CONNECTION_FAILED"
can u please guide me what i am doing wrong.