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