├── LICENSE.txt ├── PlayerAVPlayDRM.wgt └── PlayerAVPlayDRM ├── config.xml ├── index.html ├── main.js ├── style.css └── videoPlayer.js /LICENSE.txt: -------------------------------------------------------------------------------- 1 | /* ! Copyright (c) 2016, Samsung Electronics Co., Ltd 2 | 3 | 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | 11 | 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | 15 | 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. */ 23 | -------------------------------------------------------------------------------- /PlayerAVPlayDRM.wgt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamsungDForum/PlayerAVPlayDRM/205d1cec423661d2f3f49fc12a88c02456711075/PlayerAVPlayDRM.wgt -------------------------------------------------------------------------------- /PlayerAVPlayDRM/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | PlayerAVPlayDRM 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /PlayerAVPlayDRM/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 9 | 10 | Tizen Video Example App 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |

Tizen Video DRM App

22 |

Video player based on Tizen webapis.avplay

23 | 24 |
25 |

Available buttons/actions:

26 |
27 | 1 - Toggle UHD content playback - use before starting playback and only for 4K content
28 | 2 - display track info - while playback active
29 | 3 - display stream properties - while playback active 30 |
31 | 32 | 33 | 34 | 35 |
36 |
PLAY
37 |
STOP
38 |
PAUSE
39 |
FF
40 |
REW
41 |
TOGGLE FULLSCREEN MODE
42 |
43 | 44 |
45 | Logs 46 |
47 |
48 |
49 | 50 |
51 |

Info

52 | 53 |

This application demonstrates the use of AVPlay based player with DRM

54 | 55 |

The application downloads video content from http://playready.directtaps.net and http://commondatastorage.googleapis.com - it will not work if these domains are not accessible
56 | 57 | You can change the source for video content by modifying contents of drms variable in main.js file

58 | 59 |

60 | 61 |

Operation

62 | 63 |

Use mouse or remote to operate on video player.
64 | Use UP/DOWN arrows to select DRM system
65 | Available keys: PLAY, PAUSE, FW, RW, STOP, ENTER (Fullscreen), RETURN, PLAY/PAUSE (Smart Remote 2015)

66 | 67 |
68 | Video info 69 |
70 |
71 | 72 |
73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /PlayerAVPlayDRM/main.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | /** 5 | * Displays logging information on the screen and in the console. 6 | * @param {string} msg - Message to log. 7 | */ 8 | function log(msg) { 9 | var logsEl = document.getElementById('logs'); 10 | 11 | if (msg) { 12 | // Update logs 13 | console.log('[PlayerAvplayDRM]: ', msg); 14 | logsEl.innerHTML += msg + '
'; 15 | } else { 16 | // Clear logs 17 | logsEl.innerHTML = ''; 18 | } 19 | 20 | logsEl.scrollTop = logsEl.scrollHeight; 21 | } 22 | 23 | var player; 24 | 25 | // flag to monitor UHD toggling 26 | var uhdStatus = false; 27 | 28 | // Configuration data for different DRM systems 29 | /** 30 | * 31 | * @property {String} name - name to be displayed in UI 32 | * @property {String} url - content url 33 | * @property {String} licenseServer - [Playready/Widevine] url to the license server 34 | * @property {String} customData - [Playready] extra data to add to the license request 35 | */ 36 | var drms = { 37 | NO_DRM: { 38 | name: 'No DRM', 39 | url: 'http://playready.directtaps.net/smoothstreaming/SSWSS720H264/SuperSpeedway_720.ism/Manifest' 40 | }, 41 | PLAYREADY: { 42 | name: 'Playready', 43 | url: 'http://playready.directtaps.net/smoothstreaming/SSWSS720H264PR/SuperSpeedway_720.ism/Manifest', 44 | licenseServer: 'http://playready.directtaps.net/pr/svc/rightsmanager.asmx?PlayRight=1&UseSimpleNonPersistentLicense=1', 45 | customData: '' 46 | }, 47 | PLAYREADY_GET_CHALLENGE: { 48 | name: 'Playready GetChallenge', 49 | url: 'http://playready.directtaps.net/smoothstreaming/SSWSS720H264PR/SuperSpeedway_720.ism/Manifest', 50 | licenseServer: '', 51 | customData: '' 52 | }, 53 | WIDEVINE: { 54 | name: 'Widevine', 55 | url: 'http://commondatastorage.googleapis.com/wvmedia/starz_main_720p_6br_tp.wvm', 56 | licenseServer: 'https://license.uat.widevine.com/getlicense/widevine', 57 | customData: '' 58 | } 59 | 60 | /*Smooth Streaming examples*/ 61 | // url: 62 | // 'http://playready.directtaps.net/smoothstreaming/SSWSS720H264/SuperSpeedway_720.ism/Manifest', url: 63 | // 'http://playready.directtaps.net/smoothstreaming/TTLSS720VC1/To_The_Limit_720.ism/Manifest', 64 | 65 | /*Smooth Streaming + Playready example*/ 66 | // url: 67 | // "http://playready.directtaps.net/smoothstreaming/SSWSS720H264PR/SuperSpeedway_720.ism/Manifest", 68 | // licenseServer: 69 | // 'http://playready.directtaps.net/pr/svc/rightsmanager.asmx?PlayRight=1&UseSimpleNonPersistentLicense=1' 70 | }; 71 | 72 | /** 73 | * Register keys used in this application 74 | */ 75 | function registerKeys() { 76 | var usedKeys = [ 77 | 'MediaPause', 78 | 'MediaPlay', 79 | 'MediaPlayPause', 80 | 'MediaFastForward', 81 | 'MediaRewind', 82 | 'MediaStop', 83 | '0', 84 | '1', 85 | '2', 86 | '3' 87 | ]; 88 | 89 | usedKeys.forEach( 90 | function (keyName) { 91 | tizen.tvinputdevice.registerKey(keyName); 92 | } 93 | ); 94 | } 95 | 96 | 97 | /** 98 | * Handle input from remote 99 | */ 100 | function registerKeyHandler() { 101 | document.addEventListener('keydown', function (e) { 102 | switch (e.keyCode) { 103 | case 13: // Enter 104 | player.toggleFullscreen(); 105 | break; 106 | case 38: //UP arrow 107 | switchDrm('up'); 108 | break; 109 | case 40: //DOWN arrow 110 | switchDrm('down'); 111 | break; 112 | case 10252: // MediaPlayPause 113 | case 415: // MediaPlay 114 | case 19: // MediaPause 115 | player.playPause(); 116 | break; 117 | case 413: // MediaStop 118 | player.stop(); 119 | break; 120 | case 417: // MediaFastForward 121 | player.ff(); 122 | break; 123 | case 412: // MediaRewind 124 | player.rew(); 125 | break; 126 | case 48: //key 0 127 | log(); 128 | break; 129 | case 49: //Key 1 130 | setUhd(); 131 | break; 132 | case 50: //Key 2 133 | player.getTracks(); 134 | break; 135 | case 51: //Key 3 136 | player.getProperties(); 137 | break; 138 | case 10009: // Return 139 | if (webapis.avplay.getState() !== 'IDLE' && webapis.avplay.getState() !== 'NONE') { 140 | player.stop(); 141 | } else { 142 | tizen.application.getCurrentApplication().hide(); 143 | } 144 | break; 145 | default: 146 | log("Unhandled key"); 147 | } 148 | }); 149 | } 150 | 151 | /** 152 | * Display application version 153 | */ 154 | function displayVersion() { 155 | var el = document.createElement('div'); 156 | el.id = 'version'; 157 | el.innerHTML = 'ver: ' + tizen.application.getAppInfo().version; 158 | document.body.appendChild(el); 159 | } 160 | 161 | function registerMouseEvents() { 162 | document.querySelector('.video-controls .play').addEventListener( 163 | 'click', 164 | function () { 165 | player.playPause(); 166 | document.getElementById('streamParams').style.visibility = 'visible'; 167 | } 168 | ); 169 | document.querySelector('.video-controls .stop').addEventListener( 170 | 'click', 171 | function () { 172 | player.stop(); 173 | document.getElementById('streamParams').style.visibility = 'hidden'; 174 | } 175 | ); 176 | document.querySelector('.video-controls .pause').addEventListener( 177 | 'click', 178 | player.playPause 179 | ); 180 | document.querySelector('.video-controls .ff').addEventListener( 181 | 'click', 182 | player.ff 183 | ); 184 | document.querySelector('.video-controls .rew').addEventListener( 185 | 'click', 186 | player.rew 187 | ); 188 | document.querySelector('.video-controls .fullscreen').addEventListener( 189 | 'click', 190 | player.toggleFullscreen 191 | ); 192 | } 193 | 194 | /** 195 | * Create drm switching list 196 | */ 197 | function createDrmList () { 198 | var drmParent = document.querySelector('.drms'); 199 | var currentDrm; 200 | var li; 201 | for (var drmID in drms) { 202 | li = document.createElement('li'); 203 | li.className = li.innerHTML = drms[drmID].name; 204 | li.dataset.drm = drmID; 205 | drmParent.appendChild(li); 206 | } 207 | currentDrm = drmParent.firstElementChild; 208 | currentDrm.classList.add('drmFocused'); 209 | } 210 | 211 | /** 212 | * Enabling uhd manually in order to play uhd streams 213 | */ 214 | function setUhd() { 215 | if (!uhdStatus) { 216 | if (webapis.productinfo.isUdPanelSupported()) { 217 | log('4k enabled'); 218 | uhdStatus = true; 219 | } else { 220 | log('this device does not have a panel capable of displaying 4k content'); 221 | } 222 | } else { 223 | log('4k disabled'); 224 | uhdStatus = false; 225 | } 226 | player.setUhd(uhdStatus); 227 | } 228 | 229 | /** 230 | * Changes drm settings according to user's action 231 | * @param {String} direction - 'up' or 'down' 232 | */ 233 | function switchDrm (direction) { 234 | var drmParent = document.querySelector('.drms'); 235 | var currentDrm = drmParent.querySelector('.drmFocused'); 236 | 237 | currentDrm.classList.remove('drmFocused'); 238 | if (direction === 'up') { 239 | if (currentDrm === drmParent.firstElementChild) { 240 | currentDrm = drmParent.lastElementChild; 241 | } else { 242 | currentDrm = currentDrm.previousElementSibling; 243 | } 244 | } else if (direction === 'down') { 245 | if (currentDrm === drmParent.lastElementChild) { 246 | currentDrm = drmParent.firstElementChild; 247 | } else { 248 | currentDrm = currentDrm.nextElementSibling; 249 | } 250 | } 251 | currentDrm.classList.add('drmFocused'); 252 | player.setChosenDrm(drms[currentDrm.dataset.drm]); 253 | } 254 | 255 | /** 256 | * Function initialising application. 257 | */ 258 | window.onload = function () { 259 | 260 | if (window.tizen === undefined) { 261 | log('This application needs to be run on Tizen device'); 262 | return; 263 | } 264 | 265 | /** 266 | * Player configuration object. 267 | * 268 | * @property {Object} drms - object containing drm configurations 269 | * @property {HTML Element} player - application/avplayer object 270 | * @property {HTML Div Element} controls - player controls 271 | * @property {HTLM Div Element} info - place to display stream info 272 | * @property {Function} logger - function to use for logging within player component 273 | * 274 | */ 275 | var config = { 276 | drms:drms, 277 | player: document.getElementById('av-player'), 278 | controls: document.querySelector('.video-controls'), 279 | info: document.getElementById('info'), 280 | logger: log 281 | }; 282 | 283 | displayVersion(); 284 | createDrmList(); 285 | registerKeys(); 286 | registerKeyHandler(); 287 | 288 | //Check the screen width so that the AVPlay can be scaled accordingly 289 | tizen.systeminfo.getPropertyValue( 290 | "DISPLAY", 291 | function (display) { 292 | log("The display width is " + display.resolutionWidth); 293 | config.resolutionWidth = display.resolutionWidth; 294 | 295 | // initialize player - loaded from videoPlayer.js 296 | player = new VideoPlayer(config); 297 | registerMouseEvents(); 298 | }, 299 | function(error) { 300 | log("An error occurred " + error.message); 301 | } 302 | ); 303 | } 304 | }()); 305 | -------------------------------------------------------------------------------- /PlayerAVPlayDRM/style.css: -------------------------------------------------------------------------------- 1 | @CHARSET "UTF-8"; 2 | 3 | body { 4 | font-size: 1.5em; 5 | padding: 0; 6 | margin: 0; 7 | width: 1920px; 8 | height: 1080px; 9 | overflow: hidden; 10 | background-color: #222222; 11 | color: silver; 12 | text-shadow: #000 3px 3px 3px; 13 | font-family: 'Open Sans', sans-serif; 14 | } 15 | 16 | body:after { 17 | content: ""; 18 | display: block; 19 | position: absolute; 20 | top: 0; 21 | left: 0; 22 | background-image: url('lightblue_empty_grid.svg'); 23 | width: 100%; 24 | height: 100%; 25 | opacity: 0.05; 26 | z-index: -1; 27 | } 28 | 29 | h1, h2, h3, h4, h5, h6 { 30 | font-family: sans-serif; 31 | text-align: center; 32 | padding: 10px; 33 | color: lightgray; 34 | background: rgba(0, 0, 0, 0.2); 35 | margin: 0; 36 | } 37 | 38 | p { 39 | margin: 8px 0; 40 | } 41 | 42 | .left, .right { 43 | width: 50%; 44 | float: left; 45 | padding: 10px; 46 | box-sizing: border-box; 47 | } 48 | 49 | .left { 50 | width: 60%; 51 | } 52 | 53 | .right { 54 | width: 40%; 55 | font-size: 0.9em; 56 | } 57 | 58 | .logs { 59 | border: 0px; 60 | overflow: auto; 61 | font-family: monospace; 62 | } 63 | 64 | fieldset { 65 | margin-top: 10px; 66 | } 67 | 68 | #av-player { 69 | z-index: -1; 70 | width: 854px; 71 | height: 480px; 72 | display: block; 73 | position: fixed; 74 | top: 300px; 75 | left: 10px; 76 | } 77 | 78 | #av-player.fullscreenMode { 79 | top: 0; 80 | left: 0; 81 | width: 1920px; 82 | height: 1080px; 83 | z-index: 1; 84 | } 85 | 86 | .drms { 87 | font-size: 30px; 88 | margin-left: 860px; 89 | } 90 | 91 | .drmFocused { 92 | color: #FFF; 93 | background-color: #666; 94 | width: 200px; 95 | } 96 | 97 | #streamParams { 98 | visibility: hidden; 99 | font-size: 30px; 100 | width: 500px; 101 | padding: 5px; 102 | } 103 | 104 | .video-controls { 105 | z-index: 2; 106 | margin: 0; 107 | padding: 0; 108 | width: 854px; 109 | height: 40px; 110 | border-top: solid 1px #fff; 111 | background-color: rgba(0, 0, 0, 0.5); 112 | opacity: 0.8; 113 | position: fixed; 114 | top: 780px; 115 | left: 10px; 116 | } 117 | 118 | .video-controls.fullscreenMode { 119 | top: 1040px; 120 | left: 0; 121 | width: 1920px; 122 | } 123 | 124 | .video-controls div { 125 | float: left; 126 | color: #fff; 127 | font-weight: bold; 128 | padding: 10px; 129 | cursor: pointer; 130 | } 131 | 132 | .video-controls div.fullscreen { 133 | float: right; 134 | } 135 | 136 | #info { 137 | height: 450px; 138 | } 139 | 140 | #logsFieldset { 141 | position: fixed; 142 | top: 812px; 143 | } 144 | 145 | #logs { 146 | height: 180px; 147 | width: 854px; 148 | } 149 | 150 | #version { 151 | position: fixed; 152 | top: 5px; 153 | left: 5px; 154 | } 155 | -------------------------------------------------------------------------------- /PlayerAVPlayDRM/videoPlayer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Player object constructor. 3 | * 4 | * @param {Object} config - Playback and player configuration. 5 | * @returns {Object} 6 | */ 7 | function VideoPlayer(config) { 8 | var log = config.logger; 9 | 10 | /** 11 | * HTML av-player element 12 | */ 13 | var player = config.player; 14 | 15 | /** 16 | * HTML controls div 17 | */ 18 | var controls = config.controls; 19 | 20 | /** 21 | * Fullscreen flag 22 | * @type {Boolean} 23 | */ 24 | var isFullscreen = false; 25 | 26 | /** 27 | * DRM type to handle 28 | * @type {String} 29 | */ 30 | var chosenDrm = config.drms.NO_DRM; 31 | 32 | /** 33 | * HTML element to display stream properties. 34 | */ 35 | var info = config.info; 36 | 37 | var defaultResolutionWidth = 1920; 38 | var resolutionWidth = config.resolutionWidth; 39 | 40 | var playerCoords = { 41 | x: Math.floor(10 * resolutionWidth / defaultResolutionWidth), 42 | y: Math.floor(300 * resolutionWidth / defaultResolutionWidth), 43 | width: Math.floor(854 * resolutionWidth / defaultResolutionWidth), 44 | height: Math.floor(480 * resolutionWidth / defaultResolutionWidth) 45 | }; 46 | 47 | /** 48 | * 4k flag 49 | * @type {Boolean} 50 | */ 51 | var isUhd = false; 52 | 53 | return { 54 | /** 55 | * Function to initialize the playback. 56 | * @param {String} url - content url, if there is no value then take url from config 57 | */ 58 | play: function (url) { 59 | log('Starting playback'); 60 | /* Create listener object. */ 61 | var listener = { 62 | onbufferingstart: function () { 63 | log("Buffering start."); 64 | }, 65 | onbufferingprogress: function (percent) { 66 | log("Buffering progress data : " + percent); 67 | }, 68 | onbufferingcomplete: function () { 69 | log("Buffering complete."); 70 | }, 71 | oncurrentplaytime: function (currentTime) { 72 | log("Current playtime: " + currentTime); 73 | }, 74 | onevent: function (eventType, eventData) { 75 | log("event type: " + eventType + ", data: " + eventData); 76 | }, 77 | ondrmevent: function (drmEvent, drmData) { 78 | log("DRM callback: " + drmEvent + ", data: " + drmData); 79 | /* Playready Challenge alternative scenario start */ 80 | if (drmData.name === "Challenge") { 81 | var drmParam = { 82 | ResponseMessage: drmData.message 83 | }; 84 | log('setDrm InstallLicense: ' + JSON.stringify(drmParam)); 85 | webapis.avplay.setDrm("PLAYREADY", "InstallLicense", JSON.stringify(drmParam)); 86 | } 87 | /* Playready Challenge alternative scenario end */ 88 | }, 89 | onstreamcompleted: function () { 90 | log("Stream Completed"); 91 | this.stop(); 92 | }.bind(this), 93 | onerror: function (eventType) { 94 | log("event type error : " + eventType); 95 | } 96 | }; 97 | 98 | if (!url) { 99 | url = config.url; 100 | } 101 | log('videoPlayer open: ' + url); 102 | try { 103 | webapis.avplay.open(url); 104 | webapis.avplay.setDisplayRect( 105 | playerCoords.x, 106 | playerCoords.y, 107 | playerCoords.width, 108 | playerCoords.height 109 | ); 110 | webapis.avplay.setListener(listener); 111 | } catch (e) { 112 | log(e); 113 | } 114 | 115 | //set bitrates according to the values in your stream manifest 116 | // this.setBitrate(477000, 2056000, 2056000, 688000); 117 | 118 | //set 4k 119 | if (isUhd) { 120 | this.set4K(); 121 | } 122 | 123 | /* Setting DRMs */ 124 | switch (chosenDrm) { 125 | case config.drms.PLAYREADY: 126 | this.setPlayready(); 127 | break; 128 | case config.drms.PLAYREADY_GET_CHALLENGE: 129 | this.setPlayreadyChallenge(); 130 | break; 131 | case config.drms.WIDEVINE: 132 | this.setWidevine(); 133 | break; 134 | default: 135 | log('no DRM'); 136 | } 137 | 138 | if (chosenDrm !== config.drms.PLAYREADY_GET_CHALLENGE) { 139 | webapis.avplay.prepare(); 140 | webapis.avplay.play(); 141 | } 142 | }, 143 | /** 144 | * Function to start/pause playback. 145 | * @param {String} url - content url, if there is no value then take url from config 146 | */ 147 | playPause: function (url) { 148 | if (!url) { 149 | url = chosenDrm.url; 150 | } 151 | 152 | if (webapis.avplay.getState() === 'PLAYING' || webapis.avplay.getState() === 'PAUSED') { 153 | this.pause(); 154 | } else { 155 | this.play(url); 156 | } 157 | }, 158 | /** 159 | * Function to stop current playback. 160 | */ 161 | stop: function () { 162 | webapis.avplay.stop(); 163 | 164 | //switch back from fullscreen to window if stream finished playing 165 | if (isFullscreen === true) { 166 | this.toggleFullscreen(); 167 | } 168 | info.innerHTML = ''; 169 | }, 170 | /** 171 | * Function to pause/resume playback. 172 | * @param {String} url - content url, if there is no value then take url from config 173 | */ 174 | pause: function (url) { 175 | if (!url) { 176 | url = chosenDrm.url; 177 | } 178 | if (webapis.avplay.getState() === 'PLAYING') { 179 | webapis.avplay.pause(); 180 | } else if (webapis.avplay.getState() === 'NONE' || webapis.avplay.getState() === 'IDLE') { 181 | this.play(url); 182 | } else { 183 | webapis.avplay.play(); 184 | } 185 | }, 186 | /** 187 | * Jump forward 3 seconds (3000 ms). 188 | */ 189 | ff: function () { 190 | webapis.avplay.jumpForward('3000'); 191 | }, 192 | /** 193 | * Rewind 3 seconds (3000 ms). 194 | */ 195 | rew: function () { 196 | webapis.avplay.jumpBackward('3000'); 197 | }, 198 | /** 199 | * Set information about chosen DRM type. 200 | * @param {String} drm - String name of the DRM option to call correct option in play() function. 201 | */ 202 | setChosenDrm: function (drm) { 203 | chosenDrm = drm; 204 | }, 205 | /** 206 | * Set flag to play UHD content. 207 | * @param {Boolean} isEnabled - Flag to set UHD. 208 | */ 209 | setUhd: function (isEnabled) { 210 | isUhd = isEnabled; 211 | }, 212 | /** 213 | * Set to TV to play UHD content. 214 | */ 215 | set4K: function () { 216 | webapis.avplay.setStreamingProperty("SET_MODE_4K", "true"); 217 | }, 218 | /** 219 | * Function to set specific bitrates used to play the stream. 220 | * In case of Smooth Streaming STARTBITRATE and SKIPBITRATE values 'LOWEST', 'HIGHEST', 'AVERAGE' can be set. 221 | * For other streaming engines there must be numeric values. 222 | * 223 | * @param {Number} from - Lower value of bitrates range. 224 | * @param {Number} to - Hieher value of the birrates range. 225 | * @param {Number} start - Bitrate which should be used for initial chunks. 226 | * @param {Number} skip - Bitrate that will not be used. 227 | */ 228 | setBitrate: function (from, to, start, skip) { 229 | var bitrates = '|BITRATES=' + from + '~' + to; 230 | 231 | if (start !== '' && start !== undefined) { 232 | bitrates += '|STARTBITRATE=' + start; 233 | } 234 | if (to !== '' && to !== undefined) { 235 | bitrates += '|SKIPBITRATE=' + skip; 236 | } 237 | 238 | webapis.avplay.setStreamingProperty("ADAPTIVE_INFO", bitrates); 239 | }, 240 | /** 241 | * Function to change current VIDEO/AUDIO/TEXT track 242 | * @param {String} type - Streaming type received with webapis.avplay.getTotalTrackInfo(), possible values 243 | * are: VIDEO, AUDIO, TEXT. 244 | * @param {Number} index - Track id received with webapis.avplay.getTotalTrackInfo(). 245 | */ 246 | setTrack: function (type, index) { 247 | webapis.avplay.setSelectTrack(type, index); 248 | }, 249 | /** 250 | * Function to set Playready license server and (optionally) custom data. 251 | * It needs special privilege in config.xml: 252 | * 253 | */ 254 | setPlayready: function () { 255 | var drmParam = { 256 | DeleteLicenseAfterUse: true 257 | }; 258 | if (chosenDrm.licenseServer !== '' && chosenDrm.licenseServer !== undefined) { 259 | drmParam.LicenseServer = chosenDrm.licenseServer; 260 | } 261 | if (chosenDrm.customData !== '' && chosenDrm.customData !== undefined) { 262 | drmParam.CustomData = chosenDrm.customData; 263 | } 264 | 265 | log('setDrm Playready param: ' + JSON.stringify(drmParam)); 266 | try { 267 | webapis.avplay.setDrm("PLAYREADY", "SetProperties", JSON.stringify(drmParam)); 268 | } catch (e) { 269 | log(e.name) 270 | } 271 | }, 272 | /** 273 | * Function send challenge request to playready license server. 274 | * It needs special privilege in config.xml: 275 | * 276 | */ 277 | setPlayreadyChallenge: function () { 278 | var drmParam = { 279 | DeleteLicenseAfterUse: true, 280 | GetChallenge: true 281 | }; 282 | 283 | var PrepareSuccessCallback = function () { 284 | log('PrepareSuccessCallback'); 285 | webapis.avplay.play(); 286 | }; 287 | 288 | log('setDrm Playready GetChallenge param: ' + JSON.stringify(drmParam)); 289 | webapis.avplay.setDrm("PLAYREADY", "SetProperties", JSON.stringify(drmParam)); 290 | webapis.avplay.prepareAsync(PrepareSuccessCallback); 291 | }, 292 | /** 293 | * Function to set Widevine license server and (optionally) custom data. 294 | * It needs special privilege in config.xml: 295 | * 296 | */ 297 | setWidevine: function () { 298 | var deviceId = webapis.drminfo.getEsn('WIDEVINE'); 299 | var drmParam = "DEVICE_ID=" + deviceId + "|DEVICE_TYPE_ID=60|STREAM_ID=|IP_ADDR=|DRM_URL=" + 300 | chosenDrm.licenseServer + "|PORTAL=OEM|I_SEEK=|CUR_TIME=|USER_DATA="; 301 | if (chosenDrm.customData !== '' && chosenDrm.customData !== undefined) { 302 | drmParam += chosenDrm.customData; 303 | } 304 | log('setStreamingProperty Widevine param: ' + drmParam); 305 | try { 306 | webapis.avplay.setStreamingProperty("WIDEVINE", drmParam); 307 | } catch (e) { 308 | log(e.name) 309 | } 310 | }, 311 | /** 312 | * Show information about all available stream tracks on the screen. 313 | */ 314 | getTracks: function () { 315 | var trackInfo = webapis.avplay.getTotalTrackInfo(); 316 | var text = 'type of track info: ' + typeof trackInfo + '
'; 317 | text += 'length: ' + trackInfo.length + '
'; 318 | for (var i = 0; i < trackInfo.length; i++) { 319 | text += 'index: ' + trackInfo[i].index + ' '; 320 | text += 'type: ' + trackInfo[i].type + ' '; 321 | text += 'extra_info: ' + trackInfo[i].extra_info + '
'; 322 | } 323 | info.innerHTML = text; 324 | }, 325 | /** 326 | * Show streaming properties on the screen. 327 | */ 328 | getProperties: function () { 329 | var text = 'AVAILABLE_BITRATE: ' + webapis.avplay.getStreamingProperty("AVAILABLE_BITRATE") + '
'; 330 | text += 'CURRENT_BANDWIDTH: ' + webapis.avplay.getStreamingProperty("CURRENT_BANDWITH") + '
'; 331 | text += 'DURATION: ' + webapis.avplay.getStreamingProperty("DURATION") + '
'; 332 | text += 'BUFFER_SIZE: ' + webapis.avplay.getStreamingProperty("BUFFER_SIZE") + '
'; 333 | text += 'START_FRAGMENT: ' + webapis.avplay.getStreamingProperty("START_FRAGMENT") + '
'; 334 | text += 'COOKIE: ' + webapis.avplay.getStreamingProperty("COOKIE") + '
'; 335 | text += 'CUSTOM_MESSAGE: ' + webapis.avplay.getStreamingProperty("CUSTOM_MESSAGE"); 336 | info.innerHTML = text; 337 | }, 338 | 339 | /** 340 | * Switch between full screen mode and normal windowed mode. 341 | */ 342 | toggleFullscreen: function () { 343 | if (isFullscreen === false) { 344 | webapis.avplay.setDisplayRect(0, 0, 1920, 1080); 345 | player.classList.add('fullscreenMode'); 346 | controls.classList.add('fullscreenMode'); 347 | isFullscreen = true; 348 | } else { 349 | try { 350 | webapis.avplay.setDisplayRect( 351 | playerCoords.x, 352 | playerCoords.y, 353 | playerCoords.width, 354 | playerCoords.height 355 | ); 356 | } catch (e) { 357 | log(e); 358 | } 359 | player.classList.remove('fullscreenMode'); 360 | controls.classList.remove('fullscreenMode'); 361 | isFullscreen = false; 362 | } 363 | } 364 | }; 365 | } 366 | --------------------------------------------------------------------------------