1 /* 2 * This is system cordova_plugin (TV specific API). 3 * Apache License (2004). See http://www.apache.org/licenses/LICENSE-2.0 4 * 5 * Copyright (c) 2014, LG Electronics, Inc. 6 */ 7 8 9 /** 10 * This represents the video API itself, and provides a global namespace for operating video service. 11 * @class 12 */ 13 cordova.define('cordova/plugin/video', function (require, exports, module) { // jshint ignore:line 14 15 function log(msg) { 16 //console.log//will be removed // jshint ignore:line 17 } 18 19 var service; 20 if (window.PalmSystem) { // jshint ignore:line 21 log("Window.PalmSystem Available"); 22 service = require('cordova/plugin/webos/service'); 23 } else { 24 service = { 25 Request : function(uri, params) { 26 log(uri + " invoked. But I am a dummy because PalmSystem is not available"); 27 28 if (typeof params.onFailure === 'function') { 29 params.onFailure({ returnValue:false, 30 errorText:"PalmSystem Not Available. Cordova is not installed?"}); 31 } 32 }}; 33 } 34 35 /** 36 * video interface 37 */ 38 var Video = function () { 39 }; 40 41 42 function checkErrorCodeNText(result, errorCode, errorText) { 43 44 if (result.errorCode === undefined || result.errorCode === null ) { 45 result.errorCode = errorCode; 46 } 47 if (result.errorText ===undefined || result.errorText === null) { 48 result.errorText = errorText; 49 } 50 } 51 52 /** 53 * Gets video position and size. 54 * @class Video 55 * @param {Function} successCallback success callback function. 56 * @param {Function} errorCallback failure callback function. 57 * @return {Object} 58 * <div align=left> 59 * <table class="hcap_spec" width=400> 60 * <thead><tr><th>Property</th><th>Type</th><th>Description</th></tr></thead> 61 * <tbody> 62 * <tr><th>source</th><th>Object</th><th>source rectangle of video. </th></tr> 63 * <tr><th>source.x</th><th>Number</th><th>The x coordinate of the upper-left corner of the rectangle. </th></tr> 64 * <tr class="odd"><th>source.y</th><th>Number</th><th>The y coordinate of the upper-left corner of the rectangle. </th></tr> 65 * <tr><th>source.width</th><th>Number</th><th>The width of the rectangle. </th></tr> 66 * <tr class="odd"><th>source.height</th><th>Number</th><th>The height of the rectangle. </th></tr> 67 * </tbody> 68 * </table> 69 * 70 * @example 71 * // Javascript code 72 * function getVideoStatus () { 73 * function successCb(cbObject) { 74 * console.log("cbObject : " + JSON.stringify(cbObject.source)); 75 * 76 * console.log("source.x : " + cbObject.source.x); 77 * console.log("source.y : " + cbObject.source.y); 78 * console.log("source.width : " + cbObject.source.width); 79 * console.log("source.height : " + cbObject.source.height); 80 * 81 * // Do something 82 * ... 83 * } 84 * 85 * function failureCb(cbObject) { 86 * var errorCode = cbObject.errorCode; 87 * var errorText = cbObject.errorText; 88 * console.log ("Error Code [" + errorCode + "]: " + errorText); 89 * } 90 * 91 * var video = new Video(); 92 * video.getVideoStatus(successCb, failureCb); 93 * } 94 * @since 1.0 95 * @see 96 * <a href="Video%23setVideoSize.html">Video.setVideoSize()</a><br> 97 */ 98 Video.prototype.getVideoStatus = function (successCallback, errorCallback) { 99 100 log("getVideoStatus: "); 101 102 service.Request("luna://com.webos.service.tv.signage/", { 103 method : "getVideoSize", 104 onSuccess : function(result) { 105 log("getVideoStatus: On Success"); 106 107 if (result.returnValue === true) { 108 if (successCallback && typeof successCallback === 'function') { 109 var cbObj = {}; 110 cbObj.source = result.videoSize.source; 111 successCallback(cbObj); 112 } 113 } 114 }, 115 onFailure : function(result) { 116 log("getVideoStatus: On Failure"); 117 delete result.returnValue; 118 if (errorCallback && typeof errorCallback === 'function') { 119 checkErrorCodeNText(result, "VGVS", "Video.getVideoStatus returns failure."); 120 errorCallback(result); 121 } 122 } 123 }); 124 125 log("Video.getVideoStatus Done"); 126 127 }; 128 129 Video.currentVideo = {uri : null, source : null, tagId : null}; 130 131 /** 132 * Sets video size.<br> 133 * Original video(source rectangle) will be adjusted to the full screen size. It can be resized or a zoom effect can be applied to the video. 134 * <br> 135 * Note : Using more than one video tag in an html page may not be supported due to hardware limitation. 136 * 137 * @class Video 138 * @param {Function} successCallback success callback function. 139 * @param {Function} errorCallback failure callback function. 140 * @param {Object} options source object vary depending on video resolution. 141 * And rectangle object has boundary value as : <br> 142 * source.x + source.width <= width of video resolution , source.y + source.height <= height of video resolution <br> 143 * x and y value of rectangle are upper than zero. 144 * <br><image src="./image/setVideoSize.png"><br> 145 * <div align=left> 146 * <table class="hcap_spec" width=400> 147 * <thead><tr><th>Property</th><th>Type</th><th>Description</th><th>Required</th></tr></thead> 148 * <tbody> 149 * <tr><th>source</th><th>Object</th><th>source rectangle of video. </th><th>required</th></tr> 150 * <tr><th>source.x</th><th>Number</th><th>The x coordinate of the upper-left corner of the rectangle. </th><th>required</th></tr> 151 * <tr class="odd"><th>source.y</th><th>Number</th><th>The y coordinate of the upper-left corner of the rectangle. </th><th>required</th></tr> 152 * <tr><th>source.width</th><th>Number</th><th>The width of the rectangle. </th><th>required</th></tr> 153 * <tr class="odd"><th>source.height</th><th>Number</th><th>The height of the rectangle. </th><th>required</th></tr> 154 * </tbody> 155 * </table> 156 * 157 * @return <p>If the method is successfully executed, success callback function is called without a parameter.</br> 158 * If an error occurs, failure callback function is called with a failure callback object as a parameter.</p> 159 * @example 160 * // Javascript code 161 * function setVideoSize () { 162 * var options = {source: {x:10, y:10, width:900, height:600}}; 163 * 164 * function successCb() { 165 * // Do something 166 * } 167 * 168 * function failureCb(cbObject) { 169 * var errorCode = cbObject.errorCode; 170 * var errorText = cbObject.errorText; 171 * console.log ("Error Code [" + errorCode + "]: " + errorText); 172 * } 173 * 174 * var video = new Video(); 175 * video.setVideoSize(successCb, failureCb, options); 176 * } 177 * @since 1.0 178 * @see 179 * <a href="Video%23getVideoStatus.html">Video.getVideoStatus()</a><br> 180 * <a href="InputSource%23initialize.html#constructor">InputSource.initialize()</a><br> 181 */ 182 Video.prototype.setVideoSize = function (successCallback, errorCallback, options) { 183 184 log("setVideoSize: " + JSON.stringify(options)); 185 186 if (options.source === undefined || 187 typeof options.source.x !== 'number' || typeof options.source.y !== 'number' || 188 typeof options.source.width !== 'number' || typeof options.source.height !== 'number' || 189 isNaN(options.source.x) || isNaN(options.source.y) || isNaN(options.source.width) || isNaN(options.source.height) || 190 options.source.x < 0 || options.source.y < 0 || options.source.width <= 0 || options.source.height <= 0 ) { 191 192 if (errorCallback && typeof errorCallback === 'function') { 193 var result = {}; 194 checkErrorCodeNText(result, "VSVS", "Video.setVideoSize returns failure. out of range or type error."); 195 errorCallback(result); 196 } 197 198 return; 199 } 200 201 service.Request("luna://com.webos.service.tv.signage/", { 202 method : "getVideoSize", 203 onSuccess : function(result) { 204 log("setVideoSize: On Success"); 205 206 if (result.returnValue === true) { 207 208 var cbObj = {}; 209 cbObj.x = result.videoSize.destination.x; 210 cbObj.y = result.videoSize.destination.y; 211 cbObj.width = result.videoSize.destination.width; 212 cbObj.height = result.videoSize.destination.height; 213 214 //console.log("current video size : " + JSON.stringify(result.videoSize.source)); 215 //console.log("saved video : " + JSON.stringify(Video.currentVideo)); 216 217 var videoTags = document.getElementsByTagName("video"); // jshint ignore:line 218 var findVideoTags = false; 219 for (var i=0; i<videoTags.length; i++) { 220 //console.log("video tag: " + videoTags[i]); 221 //console.log("video tag:id " + videoTags[i].id); 222 // video tag 223 if (videoTags[i].currentTime > 0) { 224 //console.log("video tag is working"); 225 findVideoTags = true; 226 if (Video.currentVideo.uri !== videoTags[i].src || 227 (videoTags[i].id !== null && videoTags[i].id !== undefined && Video.currentVideo.tagId !== null && Video.currentVideo.tagId !== undefined && Video.currentVideo.tagId !== videoTags[i].id) ) { 228 Video.currentVideo.uri = videoTags[i].src; 229 Video.currentVideo.source = result.videoSize.source; 230 Video.currentVideo.tagId = videoTags[i].id; 231 //console.log("saved new video : " + JSON.stringify(Video.currentVideo)); 232 } 233 break; 234 } 235 } 236 if(findVideoTags === false) { 237 // external input 238 service.Request("luna://com.webos.service.eim/", { 239 method : "getCurrentInput", 240 parameters : {}, 241 onSuccess : function(resultw) { 242 //console.log("current input " + JSON.stringify(resultw)); 243 244 if (resultw.returnValue === true && Video.currentVideo.uri !== resultw.mainInputSourceId || 245 (videoTags[0].id !== null && videoTags[0].id !== undefined && Video.currentVideo.tagId !== null && Video.currentVideo.tagId !== undefined && Video.currentVideo.tagId !== videoTags[0].id) ) { 246 Video.currentVideo.uri = resultw.mainInputSourceId; 247 Video.currentVideo.tagId = (videoTags[0] !== null && videoTags[0].id !== null && videoTags[0].id !== undefined ? videoTags[0].id : null); 248 service.Request("luna://com.webos.service.tv.signage/", { 249 method : "getVideoSize", 250 onSuccess : function(resultx) { 251 log("setVideoSize: On Success 1"); 252 253 if (resultx.returnValue === true) { 254 255 Video.currentVideo.source = resultx.videoSize.source; 256 //console.log("saved new video : " + JSON.stringify(Video.currentVideo)); 257 258 if (resultx.videoSize.source.width === 0 && resultx.videoSize.source.height === 0) { 259 260 Video.currentVideo = {uri : null, source : null, tagId : null}; 261 262 var resultCallBack = {}; 263 checkErrorCodeNText(resultCallBack, "VSVS", "Video.setVideoSize returns failure. Not ready to setVideoSize." ); 264 errorCallback(resultCallBack); 265 return; 266 } else if ( Video.currentVideo.uri === null || Video.currentVideo.source === null || 267 (options.source.width + options.source.x) > (Video.currentVideo.source.x + Video.currentVideo.source.width) || 268 (options.source.height + options.source.y) > (Video.currentVideo.source.y + Video.currentVideo.source.height) ) { 269 270 var resultCallBack2 = {}; 271 checkErrorCodeNText(resultCallBack2, "VSVS", "Video.setVideoSize returns failure. out of range or type error. (" + Video.currentVideo.source.width + " : " + Video.currentVideo.source.height + ")"); 272 errorCallback(resultCallBack2); 273 return; 274 275 } 276 277 service.Request("luna://com.webos.service.tv.signage/", { 278 method : "setVideoSize", 279 parameters : { 280 videoSize : { "source": { 281 "x": options.source.x, 282 "y": options.source.y, 283 "width": options.source.width, 284 "height": options.source.height 285 }, 286 "destination": { 287 "x": cbObj.x, 288 "y": cbObj.y, 289 "width": cbObj.width, 290 "height": cbObj.height 291 } 292 } 293 }, 294 onSuccess : function(result) { 295 log("setVideoSize: On Success 2"); 296 297 if (result.returnValue === true && successCallback && typeof successCallback === 'function') { 298 successCallback(); 299 return; 300 } 301 }, 302 onFailure : function(result) { 303 log("setVideoSize: On Failure 2"); 304 delete result.returnValue; 305 if (errorCallback && typeof errorCallback === 'function') { 306 checkErrorCodeNText(result, "VSVS", "Video.setVideoSize returns failure. Can't current video source size."); 307 errorCallback(result); 308 return; 309 } 310 } 311 }); 312 313 } 314 } 315 }); 316 } else { 317 if ( Video.currentVideo.uri === null || Video.currentVideo.source === null || 318 (options.source.width + options.source.x) > (Video.currentVideo.source.x + Video.currentVideo.source.width)|| 319 (options.source.height + options.source.y) > (Video.currentVideo.source.y + Video.currentVideo.source.height) ){ 320 321 var resultCallBack = {}; 322 checkErrorCodeNText(resultCallBack, "VSVS", "Video.setVideoSize returns failure. out of range or type error. (" + Video.currentVideo.source.width + " : " + Video.currentVideo.source.height + ")"); 323 errorCallback(resultCallBack); 324 return; 325 } 326 327 service.Request("luna://com.webos.service.tv.signage/", { 328 method : "setVideoSize", 329 parameters : { 330 videoSize : { "source": { 331 "x": options.source.x, 332 "y": options.source.y, 333 "width": options.source.width, 334 "height": options.source.height 335 }, 336 "destination": { 337 "x": cbObj.x, 338 "y": cbObj.y, 339 "width": cbObj.width, 340 "height": cbObj.height 341 } 342 } 343 }, 344 onSuccess : function(result) { 345 log("setVideoSize: On Success 3"); 346 347 if (result.returnValue === true && successCallback && typeof successCallback === 'function') { 348 successCallback(); 349 return; 350 } 351 }, 352 onFailure : function(result) { 353 log("setVideoSize: On Failure 3"); 354 delete result.returnValue; 355 if (errorCallback && typeof errorCallback === 'function') { 356 checkErrorCodeNText(result, "VSVS", "Video.setVideoSize returns failure. Can't current video source size."); 357 errorCallback(result); 358 return; 359 } 360 } 361 }); 362 } 363 }, 364 onFailure : function() {} 365 }); 366 } else { 367 368 if ( Video.currentVideo.uri === null || Video.currentVideo.source === null || 369 (options.source.width + options.source.x) > (Video.currentVideo.source.x + Video.currentVideo.source.width) || 370 (options.source.height + options.source.y) > (Video.currentVideo.source.y + Video.currentVideo.source.height) ) { 371 372 var resultCallBack = {}; 373 checkErrorCodeNText(resultCallBack, "VSVS", "Video.setVideoSize returns failure. out of range or type error. (" + Video.currentVideo.source.width + " : " + Video.currentVideo.source.height + ")"); 374 errorCallback(resultCallBack); 375 return; 376 } 377 378 service.Request("luna://com.webos.service.tv.signage/", { 379 method : "setVideoSize", 380 parameters : { 381 videoSize : { "source": { 382 "x": options.source.x, 383 "y": options.source.y, 384 "width": options.source.width, 385 "height": options.source.height 386 }, 387 "destination": { 388 "x": cbObj.x, 389 "y": cbObj.y, 390 "width": cbObj.width, 391 "height": cbObj.height 392 } 393 } 394 }, 395 onSuccess : function(result) { 396 log("setVideoSize: On Success 4"); 397 398 if (result.returnValue === true && successCallback && typeof successCallback === 'function') { 399 successCallback(); 400 return; 401 } 402 }, 403 onFailure : function(result) { 404 log("setVideoSize: On Failure 4"); 405 delete result.returnValue; 406 if (errorCallback && typeof errorCallback === 'function') { 407 checkErrorCodeNText(result, "VSVS", "Video.setVideoSize returns failure. Can't current video source size."); 408 errorCallback(result); 409 return; 410 } 411 } 412 }); 413 } 414 415 416 } 417 }, 418 onFailure : function(result) { 419 log("setVideoSize: On Failure"); 420 delete result.returnValue; 421 if (errorCallback && typeof errorCallback === 'function') { 422 checkErrorCodeNText(result, "VSVS", "Video.setVideoSize returns failure."); 423 errorCallback(result); 424 return; 425 } 426 } 427 }); 428 429 log("Video.setVideoSize Done"); 430 }; 431 432 433 /** 434 * Sets content rotation.<br> 435 * <br> 436 * Note :Only full screen video rotation is supported. 437 * 438 * @class Video 439 * @param {Function} successCallback success callback function. 440 * @param {Function} errorCallback failure callback function. 441 * @param {Object} options 442 * 443 * <div align=left> 444 * <table class="hcap_spec" width=400> 445 * <thead><tr><th>Property</th><th>Type</th><th>Description</th><th>Required</th></tr></thead> 446 * <tbody> 447 * <tr><th>degree</th><th>String</th><th>"off", "90", or "270"</th><th>required</th></tr> 448 * <tr class="odd"><tr><th>aspectRatio</th><th>String</th><th>"full" or "original" </th><th>required</th></tr> 449 * </tbody> 450 * </table> 451 * 452 * @return <p>If the method is successfully executed, success callback function is called without a parameter.</br> 453 * If an error occurs, failure callback function is called with a failure callback object as a parameter.</p> 454 * @example 455 * // Javascript code 456 * function setContentRotation () { 457 * var options = {degree : "90", aspectRatio : "full"}; 458 * 459 * function successCb() { 460 * // Do something 461 * } 462 * 463 * function failureCb(cbObject) { 464 * var errorCode = cbObject.errorCode; 465 * var errorText = cbObject.errorText; 466 * console.log ("Error Code [" + errorCode + "]: " + errorText); 467 * } 468 * 469 * var video = new Video(); 470 * video.setContentRotation(successCb, failureCb, options); 471 * } 472 * @since 1.3 473 * @see 474 * <a href="Video%23getContentRotation.html">Video.getContentRotation()</a><br> 475 */ 476 Video.prototype.setContentRotation = function (successCallback, errorCallback, options) { 477 478 log("setContentRotation: "); 479 480 if (typeof options === "undefined" || options === null || 481 (options.degree !== "off" && options.degree !== "90" && options.degree !== "270") || 482 (options.aspectRatio !== "full" && options.aspectRatio != "original")) { 483 484 checkErrorCodeNText(result, "VSCR", "Video.setContentRotation invlalid parameters."); 485 } 486 487 service.Request("luna://com.webos.service.commercial.signage.storageservice/video/", { 488 method : "setContentRotation", 489 parameters : options, 490 onSuccess : function(result) { 491 log("setContentRotation: On Success"); 492 493 if (result.returnValue === true && successCallback && typeof successCallback === 'function') { 494 successCallback(); 495 return; 496 } 497 }, 498 onFailure : function(result) { 499 log("setContentRotation: On Failure"); 500 delete result.returnValue; 501 if (errorCallback && typeof errorCallback === 'function') { 502 checkErrorCodeNText(result, "VSCR", "Video.setContentRotation returns failure."); 503 errorCallback(result); 504 return; 505 } 506 } 507 }); 508 509 log("Video.setContentRotation: Done "); 510 511 }; 512 513 /** 514 * Gets content rotation status. 515 * @class Video 516 * @param {Function} successCallback success callback function. 517 * @param {Function} errorCallback failure callback function. 518 * @return {Object} 519 * <div align=left> 520 * <table class="hcap_spec" width=400> 521 * <thead><tr><th>Property</th><th>Type</th><th>Description</th><th>Required</th></tr></thead> 522 * <tbody> 523 * <tr><th>degree</th><th>String</th><th>"off", "90", or "270"</th><th>required</th></tr> 524 * <tr class="odd"><tr><th>aspectRatio</th><th>String</th><th>"full" or "original" </th><th>required</th></tr> 525 * </tbody> 526 * </table> 527 * 528 * @example 529 * // Javascript code 530 * function getContentRotation () { 531 * function successCb(cbObject) { 532 * console.log("cbObject : " + JSON.stringify(cbObject.source)); 533 * 534 * console.log("degree : " + cbObject.degree); 535 * console.log("aspectRatio : " + cbObject.aspectRatio); 536 * 537 * // Do something 538 * } 539 * 540 * function failureCb(cbObject) { 541 * var errorCode = cbObject.errorCode; 542 * var errorText = cbObject.errorText; 543 * console.log ("Error Code [" + errorCode + "]: " + errorText); 544 * } 545 * 546 * var video = new Video(); 547 * video.getContentRotation(successCb, failureCb); 548 * } 549 * @since 1.3 550 * @see 551 * <a href="Video%23setContentRotation.html">Video.setContentRotation()</a><br> 552 */ 553 Video.prototype.getContentRotation = function (successCallback, errorCallback) { 554 555 log("getContentRotation: "); 556 557 service.Request("luna://com.webos.service.commercial.signage.storageservice/video/", { 558 method : "getContentRotation", 559 onSuccess : function(result) { 560 log("getContentRotation: On Success"); 561 562 if (result.returnValue === true) { 563 if (successCallback && typeof successCallback === 'function') { 564 successCallback(result); 565 } 566 } 567 }, 568 onFailure : function(result) { 569 log("getContentRotation: On Failure"); 570 delete result.returnValue; 571 if (errorCallback && typeof errorCallback === 'function') { 572 checkErrorCodeNText(result, "VGCR", "Video.getContentRotation returns failure."); 573 errorCallback(result); 574 } 575 } 576 }); 577 578 log("Video.getContentRotation Done"); 579 580 }; 581 582 module.exports = Video; 583 }); 584 585 Video = cordova.require('cordova/plugin/video'); // jshint ignore:line 586 587