From 478222ca3bee5e20432dcc052a74e955d3fa255a Mon Sep 17 00:00:00 2001 From: thlo Date: Mon, 9 Jun 2014 12:56:48 +0200 Subject: * Time zone and no time source issue fixed * Commands Menu Entry (when enabled in plugin) * Fix of sorting bug (blue key in recordings) * Improved buffering tuning for Live * Fixes with respect to using HLS for Recordings * Touch Remote Control support * New 21:9 crop (picture size key) * Making additional notifications (such as Recording has finished) optional * Show Language Code for Audio Track Select * Bug Fixes --- smarttv-client/CSS/Main.css | 42 +- smarttv-client/Javascript/Buttons.js | 2 +- smarttv-client/Javascript/Comm.js | 44 +- smarttv-client/Javascript/Config.js | 66 ++- smarttv-client/Javascript/Data.js | 40 +- smarttv-client/Javascript/DirectAccess.js | 20 +- smarttv-client/Javascript/Display.js | 245 ++++++--- smarttv-client/Javascript/Epg.js | 11 +- smarttv-client/Javascript/Main.js | 261 ++++++--- smarttv-client/Javascript/OverlayMenu.js | 69 ++- smarttv-client/Javascript/Player.js | 881 ++++++++++++++++++------------ smarttv-client/Javascript/SelectScreen.js | 23 +- smarttv-client/Javascript/Server.js | 126 ++++- smarttv-client/Javascript/Timers.js | 2 +- smarttv-client/Javascript/Urls.js | 25 + smarttv-client/config.xml | 3 +- smarttv-client/index.html | 3 +- 17 files changed, 1262 insertions(+), 601 deletions(-) diff --git a/smarttv-client/CSS/Main.css b/smarttv-client/CSS/Main.css index c9d8f5f..6c30936 100755 --- a/smarttv-client/CSS/Main.css +++ b/smarttv-client/CSS/Main.css @@ -289,46 +289,58 @@ body { position: absolute; display: none; left: 0px; top: 0px; - width: 960px; height: 162px; + width: 940px; height: 162px; border-style:solid; z-index:50; - padding-top:20px; - padding-left:20px; - padding-right:20px; - background-color: darkblue; - background-color: rgba(0, 0, 139, 0.5); - background-color: -webkit-linear-gradient(-45deg, rgba(167,207,223,1) 0%,rgba(35,83,138,1) 100%); + padding-top:10px; + padding-bottom:10px; + padding-left:10px; + padding-right:10px; + background: darkblue; + background: rgba(0, 0, 139, 0.5); } #infoTitle{ position: absolute; - left: 2px; top: 0px; - width: 960px; height: 26px; + left: 0px; top: 0px; + width: 98%; height: 26px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; + padding-top: 0.5%; + padding-left: 1%; + padding-right: 1%; } #infoDuration{ position: absolute; - left: 2px; top: 26px; - width: 960px; height: 21px; + left: 0px; top: 26px; + width: 98%; height: 21px; font-size:14px; + padding-left: 1%; + padding-right: 1%; } #infoDesc{ position: absolute; - left: 2px; top: 47px; - width: 960px; height: 90px; + left: 0px; top: 45px; + width: 98%; height: 85px; font-size:14px; overflow:hidden; + padding-top: 0.5%; + padding-left: 1%; + padding-right: 1%; + border-radius: 5px; + background: rgba(0, 0, 139, 0.5); } #infoAudio { position: absolute; - left: 2px; top: 141px; - width: 960px; height: 21px; + left: 0px; top: 141px; + width: 98%; height: 21px; font-size:14px; + padding-left: 1%; + padding-right: 1%; } #popup{ position: absolute; diff --git a/smarttv-client/Javascript/Buttons.js b/smarttv-client/Javascript/Buttons.js index 7fa30bb..184b435 100644 --- a/smarttv-client/Javascript/Buttons.js +++ b/smarttv-client/Javascript/Buttons.js @@ -357,7 +357,7 @@ ButtonHandler.prototype.show = function () { }; ButtonHandler.prototype.hide = function () { - Main.log(this.hndlName + ".hide(): masterElm= " +this.masterElm + " inputElm= " + this.inputElm); + Main.logToServer(this.hndlName + ".hide(): masterElm= " +this.masterElm + " inputElm= " + this.inputElm); $(this.masterElm).hide(); $(this.inputElm).blur(); Main.enableKeys(); diff --git a/smarttv-client/Javascript/Comm.js b/smarttv-client/Javascript/Comm.js index 9ae9a44..ba327a6 100644 --- a/smarttv-client/Javascript/Comm.js +++ b/smarttv-client/Javascript/Comm.js @@ -15,12 +15,16 @@ Comm.init = function () { if (Config.deviceType != 0) return; - Comm.customMgr = webapis.customdevice || {}; - - Comm.customMgr.registerManagerCallback(Comm.onDeviceStatusChange); - - // >> Initializes custom device profile and gets available devices - Comm.customMgr.getCustomDevices(Comm.onCustomObtained); + try { + Comm.customMgr = webapis.customdevice || {}; + + Comm.customMgr.registerManagerCallback(Comm.onDeviceStatusChange); + + // >> Initializes custom device profile and gets available devices + Comm.customMgr.getCustomDevices(Comm.onCustomObtained); + } + catch (e) { + } Main.log("curWidget.id= " + curWidget.id); Main.logToServer("curWidget.id= (" + curWidget.id+")"); }; @@ -123,29 +127,43 @@ Comm.onMessageReceived = function(message, context) { Main.logToServer("INFO: type= " + msg.payload.type + " val= " + msg.payload.name); switch(msg.payload.type) { case "RECSTART": - Notify.showNotify("Recording started: '" + msg.payload.name +"'", true); if (Main.state == Main.eREC) { Server.updateEntry(msg.payload.guid); } + + if (Config.showInfoMsgs == true) + Notify.showNotify("Recording started: '" + msg.payload.name +"'", true); break; case "RECSTOP": - Notify.showNotify("Recording finished: " + msg.payload.name+"'", true); + if (Config.showInfoMsgs == true) + Notify.showNotify("Recording finished: " + msg.payload.name+"'", true); break; case "TCADD": - Notify.showNotify("Timer added: '" + msg.payload.name+"'", true); if (Main.state == Main.eTMR) { Timers.resetView(); + Notify.showNotify("Timer added: '" + msg.payload.name+"'", true); } + else + if (Config.showInfoMsgs == true) + Notify.showNotify("Timer added: '" + msg.payload.name+"'", true); + break; case "TCMOD": - Notify.showNotify("Timer modified: '" + msg.payload.name+"'", true); if (Main.state == Main.eTMR) { - Timers.resetView(); } + Timers.resetView(); + Notify.showNotify("Timer modified: '" + msg.payload.name+"'", true); + } + else if (Config.showInfoMsgs == true) + Notify.showNotify("Timer modified: '" + msg.payload.name+"'", true); + break; case "TCDEL": - Notify.showNotify("Timer deleted: '" + msg.payload.name+"'", true); if (Main.state == Main.eTMR) { - Timers.resetView(); } + Timers.resetView(); + Notify.showNotify("Timer deleted: '" + msg.payload.name+"'", true); + } + else if (Config.showInfoMsgs == true) + Notify.showNotify("Timer deleted: '" + msg.payload.name+"'", true); break; } diff --git a/smarttv-client/Javascript/Config.js b/smarttv-client/Javascript/Config.js index 7496cbc..f58c964 100755 --- a/smarttv-client/Javascript/Config.js +++ b/smarttv-client/Javascript/Config.js @@ -7,23 +7,40 @@ var Config = { serverAddr : "", serverName : "", serverAddrDefault: "192.168.1.122:8000", + haveCmds : false, format :"has", tgtBufferBitrate : 6000, // kbps + useDefaultBuffer : true, totalBufferDuration : 30, // sec initialBuffer : 10, // in percent pendingBuffer: 40, // in percent - initialTimeOut: 3, // sec + //--- for debugging purpose + totalBufferSize : 1024, + initialBufferSize : 1024, + pendingBufferSize : 1024, + //------ skipDuration : 30, // sec liveChannels : 30, firstLaunch : false, debug : false, usePdlForRecordings : true, - uploadJsFile : "", + uploadJsFile : false, + uploadJsFilename : "", directAcessTimeout : 1500, infoTimeout : 3000, + smartTouchTimeout : 300, + showInfoMsgs : true, + sortType : 0, + curSortType : 0, + preferredQuality : 2, widgetVersion : "unknown", +//-- time tzCorrection : 0, + useVdrTime : false, + uvtUtcTime : 0, + uvtlocRefTime : 0, +//--- recSortType : 0, playKeyBehavior : 0, haveYouTube : false, @@ -162,30 +179,42 @@ Config.fetchConfig = function () { Main.logToServer("Parsing config XML now"); Config.format = $(data).find('format').text(); - Config.tgtBufferBitrate = parseFloat($(data).find('tgtBufferBitrate').text()); - Config.totalBufferDuration = parseFloat($(data).find('totalBufferDuration').text()); - Config.initialBuffer = parseFloat($(data).find('initialBuffer').text()); - Config.pendingBuffer = parseFloat($(data).find('pendingBuffer').text()); + Config.useDefaultBuffer = ($(data).find('useDefaultBuffer').text() == "false") ? false : true; + + Config.totalBufferSize = parseInt($(data).find('totalBufferSize').text()); + Config.initialBufferSize = parseInt($(data).find('initialBufferSize').text()); + Config.pendingBufferSize = parseInt($(data).find('pendingBufferSize').text()); + if (isNaN(Config.totalBufferSize)) Config.totalBufferSize = 1024; + if (isNaN(Config.initialBufferSize)) Config.initialBufferSize = 1024; + if (isNaN(Config.pendingBufferSize)) Config.pendingBufferSize = 1024; + Config.skipDuration = parseFloat($(data).find('skipDuration').text()); - Config.initialTimeOut = parseFloat($(data).find('initialTimeOut').text()); Config.liveChannels = parseInt($(data).find('liveChannels').text()); Config.debug = ($(data).find('widgetdebug').text() == "true") ? true : false; Config.usePdlForRecordings = ($(data).find('usePdlForRecordings').text() == "false") ? false : true; - Config.uploadJsFile = $(data).find('uploadJsFile').text(); + Config.uploadJsFile = ($(data).find('uploadJsFile').text() == "true") ? true : false; + Config.uploadJsFilename = $(data).find('uploadJsFilename').text(); Config.directAcessTimeout = $(data).find('directAcessTimeout').text(); + Config.smartTouchTimeout = parseInt($(data).find('smartTouchTimeout').text()); + Config.smartTouchTimeout = isNaN(Config.smartTouchTimeout) ? 300 : Config.smartTouchTimeout; + Config.infoTimeout = parseInt( $(data).find('infoTimeout').text()); Config.infoTimeout = isNaN(Config.infoTimeout) ? 3000 : Config.infoTimeout; + Config.showInfoMsgs = ($(data).find('showInfoMsgs').text() == "false") ? false : true; Config.preferredQuality = $(data).find('preferredQuality').text(); Config.sortType= parseInt($(data).find('sortType').text()); if ((Config.sortType < 0) || (Config.sortType > Data.maxSort) || isNaN(Config.sortType)) { Config.sortType = 0; } + Config.curSortType = Config.sortType; + Data.sortType = Config.sortType; + Config.playKeyBehavior = parseInt($(data).find('playKeyBehavior').text()); Config.playKeyBehavior = isNaN(Config.playKeyBehavior) ? 0 : Config.playKeyBehavior; - Config.haveYouTube = ($(data).find('youtubemenu').text() == "true") ? true : false + Config.haveYouTube = ($(data).find('youtubemenu').text() == "true") ? true : false; Player.skipDuration = Config.skipDuration; if (Config.directAcessTimeout != "") { @@ -194,12 +223,11 @@ Config.fetchConfig = function () { Main.log("**** Config ****"); Main.log("serverUrl= " + Config.serverUrl); Main.log("format= " + Config.format); - Main.log("tgtBufferBitrate= " + Config.tgtBufferBitrate); - Main.log("totalBufferDuration= " + Config.totalBufferDuration); - Main.log("initialBuffer= " + Config.initialBuffer); - Main.log("pendingBuffer= " + Config.pendingBuffer); + Main.log("useDefaultBuffer= " + (Config.useDefaultBuffer) ? "true" : "false"); + Main.log("totalBufferSize= " + Config.totalBufferSize); + Main.log("initialBufferSize= " + Config.initialBufferSize); + Main.log("pendingBufferSize= " + Config.pendingBufferSize); Main.log("skipDuration= " + Config.skipDuration); - Main.log("initialTimeOut= " + Config.initialTimeOut); Main.log("liveChannels= " + Config.liveChannels); Main.log("debug= " + Config.debug); Main.log("usePdlForRecordings= " + Config.usePdlForRecordings); @@ -389,7 +417,7 @@ VdrServers.prototype.handleResponse = function () { switch (this.activeServers.length) { case 0: this.retries ++; - if (this.retries <2) { + if (this.retries <5) { this.checkServers(); } else @@ -400,6 +428,7 @@ VdrServers.prototype.handleResponse = function () { Config.serverAddr = this.activeServers[0].addr; Config.serverUrl = "http://" + Config.serverAddr; Config.serverName = this.activeServers[0].name; + Config.haveCmds = this.activeServers[0].cmds; Notify.showNotify("Only " + Config.serverName + " found", true); $("#selectTitle").text(Config.serverName ); @@ -426,6 +455,7 @@ VdrServers.prototype.selectCallback = function (idx) { Config.serverAddr = this.activeServers[idx].addr; Config.serverUrl = "http://" + Config.serverAddr; Config.serverName = this.activeServers[idx].name; + Config.haveCmds = this.activeServers[0].cmds; Main.log ("vdrServers.selectCallback idx= " + idx + " Config.serverUrl= " + Config.serverUrl); @@ -451,12 +481,14 @@ VdrServerChecker.prototype.checkServer = function (addr) { url: url, type : "GET", context : this, - timeout : 400, + timeout : 1000, success : function(data, status, XHR ) { var name = $(data).find('hostname').text(); var ip = $(data).find('ipaddress').text(); + var cmds = ($(data).find('cmds').text() == "true") ? true : false; + Main.log ("checkServer Success Inst= " + this.ipaddr + " " + name + " " + ip); - this.parent.activeServers.push({name : name, addr : ip}); + this.parent.activeServers.push({name : name, addr : ip, cmds : cmds}); this.parent.handleResponse(); }, error : function (XHR, status, error) { diff --git a/smarttv-client/Javascript/Data.js b/smarttv-client/Javascript/Data.js index 7933de6..ab19830 100755 --- a/smarttv-client/Javascript/Data.js +++ b/smarttv-client/Javascript/Data.js @@ -5,7 +5,7 @@ var Data = createAccessMap : false, directAccessMap : {}, sortType : 0, - maxSort : 3 + maxSort : 4 }; Array.prototype.remove = function(from, to) { @@ -19,28 +19,31 @@ Data.reset = function() { this.assets = new Item; this.folderList = []; this.createAccessMap = false; - this.sortType = Config.sortType; + Data.sortType = Config.curSortType; // this.folderList.push({item : this.assets, id: 0}); Main.log("Data.reset: folderList.push. this.folderList.length= " + this.folderList.length); }; Data.completed= function(sort) { + this.folderList.push({item : this.assets, id: 0}); + if (sort == true) { - this.assets.sortPayload(Data.sortType); + Data.assets.sortPayload(Data.sortType); if (this.createAccessMap == true) { Main.log("ERROR: access map does not match anymore"); } } - this.folderList.push({item : this.assets, id: 0}); Main.log("---------- completed ------------"); Main.log("Data.completed: Data.folderList.length= " + this.folderList.length); + Main.log("Data.completed sort= " + ((sort)? "true" : "false") + ((sort) ? " sortType= " + Data.sortType : "")); Main.log("Data.completed(): createAccessMap= " + ((this.createAccessMap == true) ? "true": "false")); }; Data.nextSortType = function () { Data.sortType = (Data.sortType +1) % Data.maxSort; this.assets.sortPayload(Data.sortType); + Config.curSortType = Data.sortType; }; Data.selectFolder = function (idx, first_idx) { @@ -93,7 +96,8 @@ Data.dumpDirectAccessMap = function(){ }; Data.findEpgUpdateTime = function() { - return this.assets.findEpgUpdateTime(Display.GetEpochTime() + 10000, "", 0); + return this.assets.findEpgUpdateTime(Display.GetUtcTime() + 10000, "", 0); +// return this.assets.findEpgUpdateTime((new MyDate()).getTimeSec() + 10000, "", 0); // min, guid, level }; @@ -258,16 +262,12 @@ Item.prototype.findEpgUpdateTime = function (min, guid, level) { guid = res.guid; } else { - var digi =new Date(this.childs[i].payload['start'] * 1000); - var str = digi.getHours() + ":" + digi.getMinutes(); +// var digi =new MyDate(this.childs[i].payload['start'] * 1000); +// var str = digi.getHours() + ":" + digi.getMinutes(); -// Main.log(prefix + "min= " + min+ " start= " + this.childs[i].payload['start'] + " (" + str+ ") title= " + this.childs[i].title); - if ((this.childs[i].payload['start'] != 0) && ((this.childs[i].payload['start'] + this.childs[i].payload['dur']) < min)) { min = this.childs[i].payload['start'] + this.childs[i].payload['dur']; guid = this.childs[i].payload['guid'] ; -// Main.log(prefix + "New Min= " + min + " new id= " + guid + " title= " + this.childs[i].title); -// Main.logToServer(prefix + "New Min= " + min + " new id= " + guid + " title= " + this.childs[i].title); } } } @@ -314,14 +314,9 @@ Item.prototype.print = function(level) { }; Item.prototype.sortPayload = function(sel) { - for (var i = 0; i < this.childs.length; i++) { - if (this.childs[i].isFolder == true) { - this.childs[i].sortPayload(sel); - } - } switch (sel) { - case 1: + case 2: // Dy Date this.childs.sort(function(a,b) { if (a.payload.start == b.payload.start) { @@ -332,7 +327,7 @@ Item.prototype.sortPayload = function(sel) { } }); break; - case 2: + case 3: // Dy Date this.childs.sort(function(a,b) { if (a.payload.start == b.payload.start) { @@ -343,7 +338,7 @@ Item.prototype.sortPayload = function(sel) { } }); break; - case 3: + case 1: this.childs.sort(function(a,b) { if (a.title == b.title) { return (b.payload.start -a.payload.start); @@ -368,4 +363,11 @@ Item.prototype.sortPayload = function(sel) { break; } + + for (var i = 0; i < this.childs.length; i++) { + if (this.childs[i].isFolder == true) { + this.childs[i].sortPayload(sel); + } + } + }; diff --git a/smarttv-client/Javascript/DirectAccess.js b/smarttv-client/Javascript/DirectAccess.js index b274498..b519fc3 100644 --- a/smarttv-client/Javascript/DirectAccess.js +++ b/smarttv-client/Javascript/DirectAccess.js @@ -87,9 +87,12 @@ DirectAccess.show = function (val) { $("#directAccessText").text(val); $("#directChanAccess").show(); $("#directAccessAnchor").focus(); - DirectAccess.timeout = Display.GetEpochTime() + (DirectAccess.delay / 1000.0); + + DirectAccess.timeout = Display.GetUtcTime() + (DirectAccess.delay / 1000.0); +// DirectAccess.timeout = (new MyDate()).getTimeSec() + (DirectAccess.delay / 1000.0); DirectAccess.timeoutObj = window.setTimeout( function() {DirectAccess.handleTimeout();}, DirectAccess.delay); - Main.log("DirectAccess.show: now= "+ Display.GetEpochTime() +" timeout= " + DirectAccess.timeout +" delta= " + (DirectAccess.timeout -Display.GetEpochTime())); + Main.log("DirectAccess.show: now= "+ Display.GetUtcTime() +" timeout= " + DirectAccess.timeout +" delta= " + (DirectAccess.timeout -Display.GetUtcTime())); +// Main.log("DirectAccess.show: now= "+ (new MyDate()).getTimeSec() +" timeout= " + DirectAccess.timeout +" delta= " + (DirectAccess.timeout -(new MyDate()).getTimeSec())); }; @@ -110,10 +113,14 @@ DirectAccess.hide = function () { DirectAccess.handleTimeout = function () { Main.log("DirectAccess.handleTimeout"); DirectAccess.timeoutObj = null; - if (Display.GetEpochTime() < DirectAccess.timeout) { - var delta = (DirectAccess.timeout -Display.GetEpochTime()) *1000.0; + + if (Display.GetUtcTime() < DirectAccess.timeout) { +// if ((new MyDate()).getTimeSec() < DirectAccess.timeout) { + var delta = (DirectAccess.timeout -Display.GetUtcTime()) *1000.0; +// var delta = (DirectAccess.timeout -(new MyDate()).getTimeSec()) *1000.0; DirectAccess.timeoutObj = window.setTimeout( DirectAccess.handleTimeout, delta); - DirectAccess.timeout = Display.GetEpochTime() + (delta / 1000.0); + DirectAccess.timeout = Display.GetUtcTime() + (delta / 1000.0); +// DirectAccess.timeout = (new MyDate()).getTimeSec() + (delta / 1000.0); Main.log("DirectAccess.timeout: " + DirectAccess.timeout); } else { @@ -123,7 +130,8 @@ DirectAccess.handleTimeout = function () { }; DirectAccess.extendTimer = function () { - DirectAccess.timeout = Display.GetEpochTime() + (DirectAccess.delay / 1000.0); + DirectAccess.timeout = Display.GetUtcTime() + (DirectAccess.delay / 1000.0); +// DirectAccess.timeout = (new MyDate()).getTimeSec() + (DirectAccess.delay / 1000.0); Main.log("DirectAccess.extendTimer: " + DirectAccess.timeout); }; diff --git a/smarttv-client/Javascript/Display.js b/smarttv-client/Javascript/Display.js index 660a007..39f75f7 100755 --- a/smarttv-client/Javascript/Display.js +++ b/smarttv-client/Javascript/Display.js @@ -103,24 +103,6 @@ Display.putInnerHTML = function (elm, val) { }; -Display.GetEpochTime = function() { - var res = 0; - switch (Config.deviceType) { - case 0: - // Samsung specific UTC time function -// res = Display.pluginTime.GetEpochTime(); - var now_millis = ((new Date).getTime()); - res = ((now_millis /1000.0) - (Config.tzCorrection * 60)); - - break; - default: - var now_millis = ((new Date).getTime()); - res = ((now_millis /1000.0) - (Config.tzCorrection * 60)); - break; - } - - return res; -}; Display.durationString = function(time) { var timeHour = 0; @@ -183,9 +165,7 @@ Display.selectItem = function (item) { }; Display.unselectItem = function (item) { -// item.setAttribute("class", "style_menuItem"); item.style.color = "white"; -// item.style.backgroundColor = "transparent"; item.style.background = "transparent"; item.style.borderRadius= "0px"; item.style["-webkit-box-shadow"] = ""; @@ -236,7 +216,6 @@ Display.updateWidgetVersion = function (ver) { Display.addHeadline = function (name) { // Add the headline to first element -// Main.log("Display.addHeadline " + name); Display.setVideoItem(document.getElementById("video0"), {c1: "", c2: name, c3: ""}); Display.FIRSTIDX= 1; @@ -250,7 +229,6 @@ Display.addHeadline = function (name) { }; Display.removeHeadline = function () { -// Main.log("Display.removeHeadline "); Display.FIRSTIDX= 0; var item = document.getElementById("video0"); @@ -319,13 +297,9 @@ Display.setVideoList = function(selected, first) { var first_item = first; //thlo -// Main.log("Display.setVideoList selected= " + selected + " first= " + first + " curWin= " + this.currentWindow + " NoOfItems= " + Display.getNumberOfVideoListItems()); - tab_style = Display.tuneLeftSide(); var i=0; var max_idx = (Data.getVideoCount() < Display.getNumberOfVideoListItems()) ? Data.getVideoCount() :(Display.getNumberOfVideoListItems()) ; -// Main.log("Display.setVideoList max_idx= " + max_idx + " NoOfItems= " + Display.getNumberOfVideoListItems()); -// Main.log("Display.setVideoList title= " +Data.getCurrentItem().childs[selected].title + " selected= " + selected + " first_item= " + first_item + " FIRSTIDX= " + this.FIRSTIDX); this.handleDescription(selected); @@ -338,7 +312,6 @@ Display.setVideoList = function(selected, first) { res = Display.getDisplayTitle (Data.getCurrentItem().childs[(first_item+i) + Data.getVideoCount()]); } else if ((first_item+i) >= Data.getVideoCount()) { -// Main.log ("first_item= " + first_item + " i= " + i + " VideoCount()= " +Data.getVideoCount() ); idx = (first_item+i) - Data.getVideoCount(); res = Display.getDisplayTitle (Data.getCurrentItem().childs[(first_item+i) - Data.getVideoCount()]); } @@ -434,18 +407,18 @@ Display.handleDescription =function (selected) { var desc = itm.payload.desc; var length = itm.payload.dur; - var digi = new Date(parseInt(itm.payload.start*1000)); + var digi = new MyDate(parseInt(itm.payload.start*1000)); var mon = Display.getNumString ((digi.getMonth()+1), 2); var day = Display.getNumString (digi.getDate(), 2); var hour = Display.getNumString (digi.getHours(), 2); var min = Display.getNumString (digi.getMinutes(), 2); var d_str =""; -// var msg = ""; switch (Main.state) { case Main.eLIVE: - var now = Display.GetEpochTime(); - + var now = Display.GetUtcTime(); +// var now = (new MyDate()).getTimeSec(); + d_str = hour + ":" + min; $("#descProg").show(); @@ -473,11 +446,9 @@ Display.handleDescription =function (selected) { break; case Main.eMED: -// msg += "" + title + ""; $("#descTitle").text(title); break; case Main.eURLS: -// msg += "" + title + ""; $("#descTitle").text(title); $("#descDuration").text("Duration: " + Display.durationString(length) + "h"); $("#descDesc").text(desc); @@ -507,7 +478,6 @@ Display.resetDescription = function () { * this.currentWindow: Cursor (selected item) */ Display.setVideoListPosition = function(position, move) { -// Main.log("Display.setVideoListPosition position= " + position ); this.handleDescription(position); $("#videoCount").text((position + 1) + " / " + Data.getVideoCount()); @@ -538,7 +508,6 @@ Display.setVideoListPosition = function(position, move) { } else if(this.currentWindow == (this.LASTIDX -this.FIRSTIDX)&& move == Main.DOWN) { // Next Page -// Main.log("Display.setVideoListPosition: next page. position= " + position); var c_pos = position - this.currentWindow; if (c_pos < 0) c_pos += Data.getVideoCount(); @@ -574,7 +543,7 @@ Display.getDisplayTitle = function(item) { res.c2 = item.title; if(item.payload.start>0) { - var epg_start_time=new Date(item.payload.start*1000); + var epg_start_time=new MyDate(item.payload.start*1000); var epg_start_hour=epg_start_time.getHours(); if(epg_start_hour<10) { @@ -599,7 +568,7 @@ Display.getDisplayTitle = function(item) { res.c2 = item.title; } else { - var digi = new Date(parseInt(item.payload.start*1000)); + var digi = new MyDate(parseInt(item.payload.start*1000)); var mon = Display.getNumString ((digi.getMonth()+1), 2); var day = Display.getNumString (digi.getDate(), 2); var hour = Display.getNumString (digi.getHours(), 2); @@ -676,11 +645,7 @@ Display.updateOlForLive = function (start_time, duration, now) { Display.setOlTitle(Data.getCurrentItem().childs[Main.selectedVideo].title + " - " +Data.getCurrentItem().childs[Main.selectedVideo].payload.prog); Display.setStartStop (start_time, (start_time + duration)); Player.setDuration(); -//thlo Player.totalTime = Data.getCurrentItem().childs[Main.selectedVideo].payload.dur * 1000; -//thlo Player.totalTimeStr =Display.durationString(Player.totalTime / 1000.0); -// var digi = new Date((Data.getCurrentItem().childs[Main.selectedVideo].payload.start*1000)); -// Main.log (" Date(): StartTime= " + digi.getHours() + ":" + digi.getMinutes() + ":" + digi.getSeconds()); Player.setCurrentPlayTimeOffset((now - Data.getCurrentItem().childs[Main.selectedVideo].payload.start) * 1000); Player.OnCurrentPlayTime(0); // updates the HTML elements of the Progressbar }; @@ -691,7 +656,6 @@ Display.setOlTitle = function (title) { }; Display.resetStartStop = function () { -// Main.log("Display.resetStartStop"); Display.olStartStop = ""; Display.hideOlStartStop(); $("#olStartStop").text(""); @@ -701,14 +665,14 @@ Display.setStartStop = function(start, stop) { this.olStartStop = ""; Display.showOlStartStop(); - var digi =new Date(start * 1000); + var digi =new MyDate(start * 1000); var hours=digi.getHours(); var minutes=digi.getMinutes(); if (minutes<=9) minutes='0'+minutes; this.olStartStop = hours + ":" + minutes + " - "; - digi =new Date(stop * 1000); + digi =new MyDate(stop * 1000); hours=digi.getHours(); minutes=digi.getMinutes(); if (minutes<=9) @@ -720,7 +684,6 @@ Display.setStartStop = function(start, stop) { }; Display.setSkipDuration = function(duration) { -// Main.log("Display.setSkipDuration: duration= " +duration); this.olStartStop = ""; // if (this.olStartStop == "") Display.showOlStartStop(); @@ -743,18 +706,17 @@ Display.setTrickplay = function(direction, multiple) { // Player.OnCurrentPlayTime Display.updatePlayTime = function() { -// $("#olTimeInfo").text(Player.curPlayTimeStr + " / " + Player.totalTimeStr); $("#olTimeInfo").text(Player.curPlayTimeStr + " / " + Player.getDurationStr()); }; Display.updateProgressBar = function () { -//thlo var timePercent = (Player.curPlayTime *100)/ Player.totalTime; var timePercent = (Player.curPlayTime *100)/ Player.getDuration(); $("#olProgressBar").css("width", (Math.round(timePercent) + "%")); }; Display.updateRecBar = function (start_time, duration){ - var now = Display.GetEpochTime(); + var now = Display.GetUtcTime(); +// var now = (new MyDate()).getTimeSec(); var remaining = Math.round(((start_time + duration) - now) * 100/ duration); $("#olRecProgressBar").show(); @@ -764,7 +726,6 @@ Display.updateRecBar = function (start_time, duration){ Display.status = function(status) { -// Main.log("Display.status: " +status); Display.putInnerHTML(this.statusDiv, status); Display.putInnerHTML(this.statusPopup, status); }; @@ -833,7 +794,7 @@ Display.showInfo = function(selected) { var desc = itm.payload.desc; var length = itm.payload.dur; - var digi = new Date(parseInt(itm.payload.start*1000)); + var digi = new MyDate(parseInt(itm.payload.start*1000)); var mon = Display.getNumString ((digi.getMonth()+1), 2); var day = Display.getNumString (digi.getDate(), 2); var hour = Display.getNumString (digi.getHours(), 2); @@ -842,7 +803,8 @@ Display.showInfo = function(selected) { var d_str =""; switch (Main.state) { case Main.eLIVE: - var now = Display.GetEpochTime(); + var now = Display.GetUtcTime(); +// var now = (new MyDate()).getTimeSec(); d_str = hour + ":" + min; @@ -856,7 +818,12 @@ Display.showInfo = function(selected) { $("#infoTitle").text(title); $("#infoDuration").text(d_str + " Duration: " + Display.durationString(length) + "h"); $("#infoDesc").text(desc); - $("#infoAudio").text("Audio Tracks: " + Player.getNumOfAudioTracks() + " Subtitle Tracks: " + Player.getNumOfSubtitleTracks()); + try { + $("#infoAudio").text("Audio Tracks: " + Player.getNumOfAudioTracks() + " Subtitle Tracks: " + Player.getNumOfSubtitleTracks()); + } + catch (e) { + $("#infoAudio").text("Audio Tracks: " + 0 + " Subtitle Tracks: " + 0); + } break; case Main.eMED: $("#infoTitle").text(title); @@ -868,18 +835,6 @@ Display.showInfo = function(selected) { $("#infoDuration").text("Duration: " + Display.durationString(length) ); $("#infoDesc").text(desc); -/* var tgt_height = $("#infoDesc").height(); - var temp = desc; - - Main.log("tgt_height= " +tgt_height + " outerHeight= " + $('#infoDesc').outerHeight()); - if( tgt_height < $('#infoDesc').outerHeight() ) { - while(tgt_height < $('#infoDesc').outerHeight()) { - $('#infoDesc').text( temp = temp.substr(0, temp.length-1) ); - } - $('#infoDesc').text( temp = temp.substr(0, temp.length-3) ); - $('#infoDesc').append('...'); - } - */ $("#infoAudio").text("Audio Tracks: " + Player.getNumOfAudioTracks() + " Subtitle Tracks: " + Player.getNumOfSubtitleTracks()); break; default: @@ -894,12 +849,10 @@ Display.showInfo = function(selected) { }; Display.handlerShowInfo = function() { -// $("#infoOverlay").show(); $("#infoOverlay").slideDown(300); }; Display.handlerHideInfo = function() { -// $("#infoOverlay").hide(); $("#infoOverlay").slideUp(300); }; @@ -908,8 +861,6 @@ Display.handlerHideInfo = function() { * Popup handlers */ Display.showPopup = function(text) { -// var oldHTML = document.getElementById("popup").innerHTML; -// Display.putInnerHTML(document.getElementById("popup"), oldHTML + "
" + text); Main.log("Display.showPopup text= " + text); if (text == "") @@ -972,7 +923,9 @@ Display.handlerShowProgress = function() { if ((Player.startTime + Player.getDuration()) > now) { // not done $("#olRecProgressBar").show(); - var now = Display.GetEpochTime(); + var now = Display.GetUtcTime(); +// var now = (new MyDate()).getTimeSec(); + var remaining_px = ((Player.startTime + Player.getDuration()) - now) * bar_width/ Player.getDuration(); var elm = document.getElementById("olRecProgressBar"); elm.style.display="block"; @@ -990,8 +943,8 @@ Display.handlerShowProgress = function() { $("#olTimeInfo").text(Player.curPlayTimeStr + " / " + Player.getDurationStr()); - var Digital=new Date(); - var hours= (Digital.getHours()- Config.tzCorrection ) ; + var Digital=new MyDate(); + var hours= Digital.getHours() ; var minutes=Digital.getMinutes(); if (minutes<=9) minutes='0'+minutes; @@ -1015,8 +968,17 @@ ClockHandler.start = function(elm){ }; ClockHandler.update = function() { - var date = new Date(); - var hours= (date.getHours() - Config.tzCorrection); + var date = new MyDate(); +// Main.log("ClockHandler.update "+ date.getHours()); + + if (Config.useVdrTime) { + if (Config.deviceType == 0) + Main.logToServer("Display.GetUtcTime: uvtUtcTime= " + Config.uvtUtcTime + " locRef= " + Config.uvtlocRefTime + " d= " + (Config.uvtUtcTime - Config.uvtlocRefTime) +" plgUtc= " + Display.pluginTime.GetEpochTime()); + else + Main.logToServer("Display.GetUtcTime: uvtUtcTime= " + Config.uvtUtcTime + " locRef= " + Config.uvtlocRefTime + " d= " + (Config.uvtUtcTime - Config.uvtlocRefTime) +" plgUtc= " + new Date().getTime()); + } + + var hours= date.getHours() ; var minutes= date.getMinutes(); if (minutes<=9) minutes='0'+minutes; @@ -1038,7 +1000,6 @@ ClockHandler.stop = function(){ * */ function OverlayHandler (n) { -// this.pluginTime = null; this.active = false; this.startTime = 0; this.hideTime = 0; @@ -1054,20 +1015,15 @@ OverlayHandler.prototype.init = function(showcb, hidecb) { var success = true; this.showCallback = showcb; this.hideCallback = hidecb; -/* this.pluginTime = document.getElementById("pluginTime"); - if (!this.pluginTime) { - Main.log(this.handlerName + " cannot aquire time plugin : " + success); - success = false; - } -*/ return success; }; OverlayHandler.prototype.checkHideCallback = function () { - var now = Display.GetEpochTime(); + var now = Display.GetUtcTime(); +// var now = (new MyDate()).getTimeSec(); + if (now >= this.hideTime) { -// this.olDelay = 3000; if (this.hideCallback) { this.hideCallback(); } @@ -1086,7 +1042,8 @@ OverlayHandler.prototype.checkHideCallback = function () { OverlayHandler.prototype.show = function() { if (!this.active ) { - this.startTime = Display.GetEpochTime(); + this.startTime = Display.GetUtcTime(); +// this.startTime = (new MyDate()).getTimeSec(); this.hideTime = this.startTime + (this.olDelay / 1000); @@ -1101,7 +1058,8 @@ OverlayHandler.prototype.show = function() { Main.log(this.handlerName + ": No showCallback defined - ignoring " ); } else { - this.hideTime = Display.GetEpochTime() + (this.olDelay /1000); + this.hideTime = Display.GetUtcTime() + (this.olDelay /1000); +// this.hideTime = (new MyDate()).getTimeSec() + (this.olDelay /1000); } }; @@ -1118,4 +1076,121 @@ OverlayHandler.prototype.cancel = function () { this.active = false; window.clearTimeout(this.timeoutObj); -}; \ No newline at end of file +}; + + +Display.GetUtcTime = function() { + var res = 0; + switch (Config.deviceType) { + case 0: + if (Config.useVdrTime == false) + // Samsung specific UTC time function + res = Display.pluginTime.GetEpochTime(); // always in UTC + else { + // In case the Samsung does not have a TV input + res = (Config.uvtUtcTime - Config.uvtlocRefTime) + Display.pluginTime.GetEpochTime() ; + } + + break; + default: + var now_millis = ((new Date()).getTime()); + res = (now_millis /1000.0) ; + break; + } + + return res; +}; + + +function MyDate (input) { + this.date = null; + + switch(arguments.length) { + case 0: + // Should only be used by clock function, otherwise use Display.pluginTime.GetEpochTime() !!!! + if (Config.deviceType == 0) { +// var cor = Display.GetEpochTime()*1000 - (Config.tzCorrection * 3600000); + var cor = Display.GetUtcTime()*1000 - (Config.tzCorrection * 3600000); + + this.date = new Date(cor); + } + else + // Browser + this.date = new Date(); + break; + case 1: + // in millisec or string + if (typeof arguments[0] == "number") { + if (Config.tzCorrection == 0) { + this.date = new Date(arguments[0]); + } + else { + Main.log("MyDate arg[0]= " + arguments[0] + " cor= " + (Config.tzCorrection * 3600000) + " args= " + MyDate.arguments.length ); + this.date = new Date(arguments[0] - (Config.tzCorrection * 3600000)); + } + + } + else { + Main.log("MyDate - ERROR not handled correctly - type String"); + Main.logToServer("MyDate - ERROR not handled correctly - type String"); + this.date = new Date(arguments[0]); + } + break; + default: + Main.log("MyDate - ERROR not handled correctly - args= " + MyDate.arguments.length ); + Main.logToServer("MyDate - ERROR not handled correctly - args= " + MyDate.arguments.length ); + if (MyDate.arguments.length == 3) + this.date = new Date(arguments[0], arguments[1], arguments[2]); + else + this.date = new Date(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]); + break; + } + +}; + +// in millis. Not a UTC time due to TZ correction +MyDate.prototype.getTime = function() { + return this.date.getTime(); +}; + +// in seconds. Not a UTC time due to TZ correction +MyDate.prototype.getTimeSec = function () { + return (this.date.getTime() / 1000.0) ; +// return ((this.date.getTime() / 1000.0) - (Config.tzCorrection * 60)) ; + +// var now_millis = ((new MyDate()).getTime()); +// res = ((now_millis /1000.0) - (Config.tzCorrection * 60)); + +}; + +MyDate.prototype.getHours = function () { + return this.date.getHours(); +}; + +MyDate.prototype.getMinutes = function () { + return this.date.getMinutes(); +}; + +MyDate.prototype.getSeconds = function () { + return this.date.getSeconds(); +}; + +MyDate.prototype.getTimezoneOffset = function () { + return this.date.getTimezoneOffset(); +}; + +MyDate.prototype.getDate = function () { + return this.date.getDate(); +}; + +MyDate.prototype.getDay = function () { + return this.date.getDay(); +}; + +MyDate.prototype.getMonth = function () { + return this.date.getMonth(); +}; + +MyDate.prototype.getFullYear = function () { + return this.date.getFullYear(); +}; diff --git a/smarttv-client/Javascript/Epg.js b/smarttv-client/Javascript/Epg.js index 87325a8..3b54929 100644 --- a/smarttv-client/Javascript/Epg.js +++ b/smarttv-client/Javascript/Epg.js @@ -48,7 +48,8 @@ Epg.startEpgUpdating = function() { this.isActive = true; var res = Data.findEpgUpdateTime(); - var now = Display.GetEpochTime(); + var now = Display.GetUtcTime(); +// var now = (new MyDate()).getTimeSec(); var delay = Math.round(res.min - now) *1000; this.curGuid = res.guid; @@ -136,8 +137,8 @@ Epg.handleError = function (XHR, textStatus, errorThrown) { Epg.insertFakeEntry = function (guid) { // Main.logToServer("Epg.insertFakeEntry for guid= " + guid + " (" + Epg.guidErrors[guid] +")"); - var now = Display.GetEpochTime(); - + var now = Display.GetUtcTime(); +// var now = (new MyDate()).getTimeSec() ; entry={}; entry.prog = "Unknown"; entry.desc = "Empty"; @@ -174,7 +175,9 @@ Epg.parseResponse = function (message,text, XHR) { // the updated record is either playing or in Menu if (Player.state != Player.STOPPED) { Main.logToServer("Updating Progress Bar"); - Display.updateOlForLive (entry.start, entry.dur, Display.GetEpochTime()); // Updates the progress bar + + Display.updateOlForLive (entry.start, entry.dur, Display.GetUtcTime()); // Updates the progress bar +// Display.updateOlForLive (entry.start, entry.dur, (new MyDate()).getTimeSec() ); // Updates the progress bar } else { Main.logToServer("Updating Right Half"); diff --git a/smarttv-client/Javascript/Main.js b/smarttv-client/Javascript/Main.js index 48b4e44..bfb2214 100755 --- a/smarttv-client/Javascript/Main.js +++ b/smarttv-client/Javascript/Main.js @@ -26,10 +26,22 @@ catch (e) { * Display.GetEpochTime: returns the current time (UTC) in seconds * * Player: All operations to get the video playing - * + * + * URL suffix handling should be in Player + * mFormat should be in Config or Main */ - +/* + * TODO: + * Audio Track Errors should be rendered differently + * Comm Error, when a new recording is added + * Clean Player APIs + * Keep State of Recording Sortings + * Issue, whether is a "_" folder + * Use Flash Player for YT + * Check that getBuffer is only used for PDL recordings and Live... + * Consider ? in reccmds and commands + */ var Main = { state : 0, // selectScreen @@ -54,14 +66,16 @@ var Main = { eMED : 3, // State Media Select Screen / Video Playing eTMR : 4, // State Timer Screen eURLS : 5, // State Urls - eSRVR : 6, // State Select Server - eOPT : 7, // Options + eCMDS : 6, // Command Conf + eSRVR : 7, // State Select Server + eOPT : 8, // Options defKeyHndl : null, selectMenuKeyHndl : null, playStateKeyHndl : null, livePlayStateKeyHndl : null, - menuKeyHndl : null + menuKeyHndl : null, + }; $(document).unload(function(){ @@ -94,7 +108,6 @@ Main.onLoad = function() { Config.serverUrl = "http://" + Config.serverAddrDefault; Main.log("Not a Samsung Smart TV" ); -// Display.showPopup("Not a Samsung Smart TV. Lets see, how far we come"); } $.ajaxSetup ({ @@ -102,7 +115,6 @@ Main.onLoad = function() { }); Display.init(); -// Display.selectItem(document.getElementById("selectItem1")); Notify.init(); Spinner.init(); Helpbar.init(); @@ -198,14 +210,11 @@ Main.init = function () { Timers.init(); ImgViewer.init(); -// Timers.show(); //set popup to normal timeout duration Display.popupOlHandler.olDelay = 3*1000; Config.verboseStart = false; -// Display.scrollPopup (); - // end if (Config.deviceType == 0){ Main.log("ProductInfo= " + deviceapis.tv.info.getProduct()); @@ -222,16 +231,20 @@ Main.init = function () { /* * Fetch JS file */ -/* if (Config.uploadJsFile != "undefined") { - Main.logToServer ("Upload: " + Config.uploadJsFile ); - xhttp=new XMLHttpRequest(); - xhttp.open("GET",Config.uploadJsFile,false); - xhttp.send(""); - xmlDoc=xhttp.responseText; - Main.logToServer (xmlDoc); - + if (Config.uploadJsFile == true) { + Main.logToServer ("Upload: " + Config.uploadJsFilename ); + try { + xhttp=new XMLHttpRequest(); + xhttp.open("GET","$MANAGER_WIDGET/Common/webapi/1.0/webapis.js", false); + xhttp.send(""); + xmlDoc=xhttp.responseText; + Main.logToServer (xmlDoc); + } + catch (e) { + Main.logToServer ("Upload Error!"); + }; } -*/ + // Read widget conf. find the file to log /* @@ -339,6 +352,10 @@ Main.changeState = function (state) { Main.selectedVideo = 0; Main.urlsSelected(); + break; + case Main.eCMDS: + CmdHandler.showMenu(); + break; case Main.eTMR: $("#selectScreen").hide(); @@ -384,7 +401,9 @@ Main.recordingsSelected = function() { Server.errorCallback = Main.serverError; Server.setSort(true); -/* if (Config.format == "") { + Data.sortType = Config.curSortType; + + /* if (Config.format == "") { Server.fetchVideoList(Config.serverUrl + "/recordings.xml?model=samsung"); Main.log("fetchVideoList from: " + Config.serverUrl + "/recordings.xml?model=samsung"); } @@ -398,7 +417,8 @@ Main.recordingsSelected = function() { */ Spinner.show(); Server.fetchVideoList(Config.serverUrl + "/recordings.xml"); /* Request video information from server */ - Main.log("fetchVideoList from: " + Config.serverUrl + "/recordings.xml"); + + Main.log("fetchVideoList from: " + Config.serverUrl + "/recordings.xml"); }; @@ -419,7 +439,17 @@ Main.mediaSelected = function() { Main.urlsSelected = function() { Server.retries = 0; - Player.stopCallback = function() { + +/* + var plyr = $("", {type : "application/x-shockwave-flash", id : "ytplayer", width : "960", height : "540", + style : "position: absolute; left: 0px; top:0px; z-index: 0; display: none"}); + plyr.append($("", {name : "movie", value : "http://www.youtube.com/apiplayer?&enablejsapi=1&version=2&playerapiid=ytplayer"})); + plyr.append($("", {name : "allowFullScreen", value : "true"})); + plyr.append($("", {name : "allowScriptAccess", value : "always"})); + $('body').append(plyr); +*/ + + Player.stopCallback = function() { // Display.show(); }; @@ -438,26 +468,56 @@ Main.optionsSelected = function() { Main.serverError = function(errorcode) { - if (Server.retries < 2) { - switch (this.state) { - case this.eLIVE: // live + Main.logToServer("Main.serverError state= " + Main.state + " retries= " + Server.retries); + switch (Server.retries) { + case 0: + case 1: + case 2: + switch (Main.state) { + case Main.eLIVE: // live + Server.fetchVideoList( Config.serverUrl + "/channels.xml"); /* Request video information from server */ + break; + case Main.eRECE: + Server.fetchVideoList( Config.serverUrl + "/recordings.xml"); /* Request video information from server */ + break; + } + break; + case 3: + case 4: + switch (Main.state) { + case Main.eLIVE: // live Server.fetchVideoList( Config.serverUrl + "/channels.xml?mode=nodesc"); /* Request video information from server */ break; - case this.eRECE: + case Main.eRECE: Server.fetchVideoList( Config.serverUrl + "/recordings.xml?mode=nodesc"); /* Request video information from server */ break; } + break; + default: + Display.showPopup(msg); + Main.changeState(0); + break; + }; +/* if (Server.retries < 2) { + switch (this.state) { + case Main.eLIVE: // live + Server.fetchVideoList( Config.serverUrl + "/channels.xml?mode=nodesc"); + break; + case Main.eRECE: + Server.fetchVideoList( Config.serverUrl + "/recordings.xml?mode=nodesc"); + break; + } } else { Display.showPopup(msg); Main.changeState(0); } - +*/ }; Main.enableKeys = function() { - Main.log("Main.enableKeys"); + Main.logToServer("Main.enableKeys"); document.getElementById("anchor").focus(); }; @@ -513,9 +573,10 @@ Main.playItem = function (url) { Main.log(Main.state + " playItem for " +Data.getCurrentItem().childs[Main.selectedVideo].payload.link); var start_time = Data.getCurrentItem().childs[Main.selectedVideo].payload.start; var duration = Data.getCurrentItem().childs[Main.selectedVideo].payload.dur; - var now = Display.GetEpochTime(); - -// document.getElementById("olRecProgressBar").style.display="none"; + var now = Display.GetUtcTime(); +// var now = (new MyDate()).getTimeSec(); + + // document.getElementById("olRecProgressBar").style.display="none"; // Player.mFormat = Player.eUND; // default val switch (this.state) { @@ -528,8 +589,8 @@ Main.playItem = function (url) { Player.isLive = true; Display.updateOlForLive (start_time, duration, now); - Main.log ("Live now= " + now + " StartTime= " + Data.getCurrentItem().childs[Main.selectedVideo].payload.start + " offset= " +Player.cptOffset ); - Main.log("Live Content= " + Data.getCurrentItem().childs[Main.selectedVideo].title + " dur= " + Data.getCurrentItem().childs[Main.selectedVideo].payload.dur); + Main.logToServer ("Live now= " + now + " StartTime= " + Data.getCurrentItem().childs[Main.selectedVideo].payload.start + " offset= " +Player.cptOffset ); + Main.logToServer("Live Content= " + Data.getCurrentItem().childs[Main.selectedVideo].title + " dur= " + Data.getCurrentItem().childs[Main.selectedVideo].payload.dur); Player.guid = Data.getCurrentItem().childs[Main.selectedVideo].payload.guid; @@ -538,8 +599,9 @@ Main.playItem = function (url) { break; case Main.eREC: - var url_ext = ""; - Player.mFormat = Player.ePDL; + Player.setPdl(); +// var url_ext = ""; +// Player.mFormat = Player.ePDL; // Server.getResume(Player.guid); Main.log(" playItem: now= " + now + " start_time= " + start_time + " dur= " + duration + " (Start + Dur - now)= " + ((start_time + duration) -now)); @@ -556,12 +618,14 @@ Main.playItem = function (url) { if ((Data.getCurrentItem().childs[Main.selectedVideo].payload.fps <= 30) && (Data.getCurrentItem().childs[Main.selectedVideo].payload.ispes == "false")) { // in case fps is smaller than 30 and ts recording use HLS or HAS if (Config.format == "hls") { - Player.mFormat = Player.eHLS; - url_ext = "/manifest-seg.m3u8|COMPONENT=HLS"; + Player.setHls(); +// Player.mFormat = Player.eHLS; +// url_ext = "/manifest-seg.m3u8|COMPONENT=HLS"; } - Player.mFormat = Player.eHAS; if (Config.format == "has") { - url_ext = "/manifest-seg.mpd|COMPONENT=HAS"; + Player.setHas(); +// Player.mFormat = Player.eHAS; +// url_ext = "/manifest-seg.mpd|COMPONENT=HAS"; } } } @@ -578,8 +642,9 @@ Main.playItem = function (url) { Display.updateRecBar(start_time, duration); // New recording in progress handling - url_ext = ""; - Player.mFormat = Player.ePDL; + Player.setPdl(); +// url_ext = ""; +// Player.mFormat = Player.ePDL; /* if ((Data.getCurrentItem().childs[Main.selectedVideo].payload.fps <= 30) && (Data.getCurrentItem().childs[Main.selectedVideo].payload.ispes == "false")) { // HLS only works for framerate smaller 30fps @@ -595,7 +660,8 @@ Main.playItem = function (url) { } */ } - Player.setVideoURL( Data.getCurrentItem().childs[Main.selectedVideo].payload.link + url_ext); +// Player.setVideoURL( Data.getCurrentItem().childs[Main.selectedVideo].payload.link + url_ext); + Player.setVideoURL( Data.getCurrentItem().childs[Main.selectedVideo].payload.link); Player.guid = Data.getCurrentItem().childs[Main.selectedVideo].payload.guid; Main.log("Main.playItem - Player.guid= " +Player.guid); @@ -619,7 +685,17 @@ Main.playItem = function (url) { Display.setOlTitle(Data.getCurrentItem().childs[Main.selectedVideo].title); - Player.setVideoURL( Data.getCurrentItem().childs[Main.selectedVideo].payload.link); + var url = Data.getCurrentItem().childs[Main.selectedVideo].payload.link; + var ext = url.split('.').pop(); + if ((ext == "M3U8") || (ext == "m3u8") ) + Player.setHls(); +// url += "|COMPONENT=HLS"; + if ((ext == "MPD") || (ext == "mpd") ) + Player.setHas(); +// url += "|COMPONENT=HAS"; + Main.log ("Url= " + url); + Player.setVideoURL( url); +// Player.setVideoURL( Data.getCurrentItem().childs[Main.selectedVideo].payload.link); Player.playVideo(-1); Player.guid = "unknown"; @@ -628,7 +704,8 @@ Main.playItem = function (url) { case Main.eURLS: Display.hide(); Display.showProgress(); - Player.mFormat = Player.ePDL; + Player.setPdl(); +// Player.mFormat = Player.ePDL; Main.log(" playItem: now= " + now + " start_time= " + start_time + " dur= " + duration + " (Start + Dur - now)= " + ((start_time + duration) -now)); @@ -717,7 +794,10 @@ function cPlayStateKeyHndl(def_hndl) { this.defaultKeyHandler = def_hndl; this.handlerName = "PlayStateKeyHanlder"; Main.log(this.handlerName + " created"); - + this.lastDragRightUp = 0; + this.lastDragRightDn = 0; + this.lastDragTopRt = 0; + this.lastDragTopLt = 0; }; @@ -729,65 +809,66 @@ cPlayStateKeyHndl.prototype.handleKeyDown = function (keyCode) { return; } + var smart_touch_timeout = Config.smartTouchTimeout / 1000; // Main.log(this.handlerName+": Key pressed: " + Main.getKeyCode(keyCode)); // Main.logToServer(this.handlerName+": Key pressed: " + Main.getKeyCode(keyCode)); - - switch(keyCode) { + if ((keyCode >= 50100001) && (keyCode <= 50400050)) { + if ((keyCode >= 50400001) && (keyCode <= 50400025)) // Smart Touch, polierter Steg oben, nach rechts, langsam + keyCode = 50400001; + if ((keyCode >= 50400025) && (keyCode <= 50400050)) { // Smart Touch, polierter Steg oben, nach rechts, langsam + keyCode = 50400001; + smart_touch_timeout = Config.smartTouchTimeout / 2000; + } + if ( (keyCode >= 50300001) && (keyCode <= 50300025) ) // Smart Touch, polierter Steg oben, nach links + keyCode = 50300001; + if ( (keyCode >= 50300025) && (keyCode <= 50300050) ){ // Smart Touch, polierter Steg oben, nach links + keyCode = 50300001; + smart_touch_timeout = Config.smartTouchTimeout / 2000; + } + if ((keyCode >= 50100001) && (keyCode <= 50100050)) // Smart Touch, polierter Steg rechts & links, nach oben + keyCode = 50100001; + if ((keyCode >= 50200001) && (keyCode <= 50200050)) // Smart Touch, polierter Steg rechts & links, nach oben + keyCode = 50200001; + Main.logToServer(this.handlerName+": SmartTouch: " +keyCode + " to= " + smart_touch_timeout); + } + switch(keyCode) { case tvKey.KEY_TOOLS: Helpbar.showHelpbar(); break; case tvKey.KEY_1: Main.log("KEY_1 pressed"); -// Display.showProgress(); -// Player.jumpToVideo(10); Player.numKeyJump(1); break; case tvKey.KEY_2: Main.log("KEY_2 pressed"); -// Display.showProgress(); -// Player.jumpToVideo(20); Player.numKeyJump(2); break; case tvKey.KEY_3: Main.log("KEY_3 pressed"); -// Display.showProgress(); -// Player.jumpToVideo(30); Player.numKeyJump(3); break; case tvKey.KEY_4: Main.log("KEY_4 pressed"); -// Display.showProgress(); -// Player.jumpToVideo(40); Player.numKeyJump(4); break; case tvKey.KEY_5: Main.log("KEY_5 pressed"); -// Display.showProgress(); -// Player.jumpToVideo(50); Player.numKeyJump(5); break; case tvKey.KEY_6: Main.log("KEY_6 pressed"); -// Display.showProgress(); -// Player.jumpToVideo(60); Player.numKeyJump(6); break; case tvKey.KEY_7: Main.log("KEY_7 pressed"); -// Display.showProgress(); -// Player.jumpToVideo(70); Player.numKeyJump(7); break; case tvKey.KEY_8: Main.log("KEY_8 pressed"); -// Display.showProgress(); -// Player.jumpToVideo(80); Player.numKeyJump(8); break; case tvKey.KEY_9: Main.log("KEY_9 pressed"); -// Display.showProgress(); -// Player.jumpToVideo(90); Player.numKeyJump(9); break; @@ -812,6 +893,14 @@ cPlayStateKeyHndl.prototype.handleKeyDown = function (keyCode) { break; /* Works only for progressive streams, not Adaptive HTTP */ + + case 50400001: // Smart Touch, polierter Steg oben, nach rechts + var now = Display.GetUtcTime(); +// var now = (new MyDate()).getTimeSec(); + if ((now - this.lastDragTopRt) < smart_touch_timeout) { + return; + } + this.lastDragTopRt = now; case tvKey.KEY_FF: Main.log("FF"); Display.showProgress(); @@ -820,12 +909,21 @@ cPlayStateKeyHndl.prototype.handleKeyDown = function (keyCode) { } else */ // if (Player.mFormat != Player.ePDL ) - if (Player.mFormat == Player.eHLS ) +// if (Player.mFormat == Player.eHLS ) + if (Player.isHls()) Notify.showNotify("Not supported", true); else Player.fastForwardVideo(); break; + + case 50300001: // Smart Touch, polierter Steg oben, nach links + var now = Display.GetUtcTime(); +// var now = (new MyDate()).getTimeSec(); + if ((now - this.lastDragTopLt) < smart_touch_timeout) { + return; + } + this.lastDragTopLt = now; case tvKey.KEY_RW: Main.log("RW"); Display.showProgress(); @@ -834,12 +932,20 @@ cPlayStateKeyHndl.prototype.handleKeyDown = function (keyCode) { } else */ // if (Player.mFormat != Player.ePDL ) - if (Player.mFormat == Player.eHLS ) +// if (Player.mFormat == Player.eHLS ) + if (Player.isHls()) Notify.showNotify("Not supported", true); else Player.RewindVideo(); break; + case 50100001 : // Smart Touch, polierter Steg rechts & links, nach oben + var now = Display.GetUtcTime(); +// var now = (new MyDate()).getTimeSec(); + if ((now - this.lastDragRightUp) < smart_touch_timeout) { + return; + } + this.lastDragRightUp = now; case tvKey.KEY_ENTER: case tvKey.KEY_PLAY: case tvKey.KEY_PANEL_ENTER: @@ -861,9 +967,20 @@ cPlayStateKeyHndl.prototype.handleKeyDown = function (keyCode) { case tvKey.KEY_STOP: Main.log("STOP"); Player.stopVideo(); - widgetAPI.blockNavigation(event); - + try { + widgetAPI.blockNavigation(event); + } + catch (e) { + } break; + + case 50200001: // Smart Touch, polierter Steg rechts & links, nach oben + var now = Display.GetUtcTime(); +// var now = (new MyDate()).getTimeSec(); + if ((now - this.lastDragRightDn) < smart_touch_timeout) { + return; + } + this.lastDragRightDn = now; case tvKey.KEY_PAUSE: Main.log("PAUSE"); if(Player.getState() == Player.PAUSED) { @@ -884,6 +1001,7 @@ cPlayStateKeyHndl.prototype.handleKeyDown = function (keyCode) { case tvKey.KEY_INFO: Display.showInfo(Main.selectedVideo); break; + case tvKey.KEY_RED: // for Smart Touch FBs case tvKey.KEY_ASPECT: Player.toggleAspectRatio(); break; @@ -1091,6 +1209,7 @@ cLivePlayStateKeyHndl.prototype.handleKeyDown = function (keyCode) { case tvKey.KEY_INFO: Display.showInfo(Main.selectedVideo); break; + case tvKey.KEY_RED: // for Smart Touch FBs case tvKey.KEY_ASPECT: Player.toggleAspectRatio(); break; @@ -1127,6 +1246,10 @@ cMenuKeyHndl.prototype.handleKeyDown = function (keyCode) { // var keyCode = event.keyCode; switch(keyCode) { + case 65: + Main.logToServer("a pressed"); + Display.showInfo(Main.selectedVideo); + break; case tvKey.KEY_TOOLS: Helpbar.showHelpbar(); break; diff --git a/smarttv-client/Javascript/OverlayMenu.js b/smarttv-client/Javascript/OverlayMenu.js index 64a7eba..b337c8a 100644 --- a/smarttv-client/Javascript/OverlayMenu.js +++ b/smarttv-client/Javascript/OverlayMenu.js @@ -1,7 +1,8 @@ var OverlayMenu = { menu : [], scrollDur : 300, - scrollFlip : 100 + scrollFlip : 100, + returnCallback : null }; OverlayMenu.init = function () { @@ -42,7 +43,7 @@ OverlayMenu.hide = function() { $(this.inputElm).blur(); $("#ovlTable").remove(); Main.enableKeys(); - + }; OverlayMenu.createStyleSheet = function () { @@ -210,6 +211,7 @@ OverlayMenu.createHelpItem = function(url, msg) { OverlayMenu.reset = function () { + this.returnCallback = null; this.btnSelected = 0; for (var i =0; i <= OverlayMenu.menu.length; i++) { $(this.elmName + i).removeClass('ovlmn-itm-selected').addClass('ovl-itm'); @@ -295,8 +297,13 @@ OverlayMenu.onInput = function () { case tvKey.KEY_RETURN: case tvKey.KEY_EXIT: OverlayMenu.hide(); - if (this.returnCallback != null) - this.returnCallback(); + Main.log("OverlayMenu.onInput -> Exit"); + + if (Main.state == Main.eCMDS) + Main.changeState(0); + + if (OverlayMenu.returnCallback != null) + OverlayMenu.returnCallback(); break; } @@ -374,3 +381,57 @@ RecCmdHandler.selectCallback = function (idx) { Server.execRecCmd(RecCmds.getCurrentItem().childs[idx].payload.cmd, RecCmdHandler.guid); } }; + + +//----------------------------------------------------------------------- +var CmdHandler = { + guid : "" +}; + + +CmdHandler.showMenu = function (guid) { + this.guid = guid; + RecCmds.reset(); + Server.fetchCmdsList(); // calls RecCmdHandler.createRecCmdOverlay() when finished + OverlayMenu.reset(); + OverlayMenu.menu = []; + +}; + +CmdHandler.fillMenuArray = function () { + for (var i = 0; i < RecCmds.getVideoCount(); i++) { + var self = this; + OverlayMenu.menu.push ({title: RecCmds.getCurrentItem().childs[i].title, func : function (idx) { self.selectCallback(idx); } }); + } + +}; + +CmdHandler.createCmdOverlay = function () { + //called, when Server.fetchRecCmdsList() is finished. + Main.log("CmdHandler.createCmdOverlay for guid " + CmdHandler.guid); + Main.logToServer("CmdHandler.createCmdOverlay for guid " + CmdHandler.guid); + if (RecCmds.getVideoCount()== 0) { + Main.log("CmdHandler.createCmdOverlay: RecCmds is empty" ); + Main.logToServer("CmdHandler.createCmdOverlay: RecCmds is empty" ); + return; + } + CmdHandler.fillMenuArray(); + + OverlayMenu.show(); +}; + +CmdHandler.selectCallback = function (idx) { + Main.logToServer("CmdHandler.selectCallback idx= " + idx + " t= " + RecCmds.getCurrentItem().childs[idx].title); + if (RecCmds.getCurrentItem().childs[idx].isFolder == true) { + Main.logToServer("CmdHandler.selectCallback isFolder"); + RecCmds.selectFolder(idx, 0); + + OverlayMenu.reset(); + OverlayMenu.menu = []; + CmdHandler.fillMenuArray(); + } + else { + Main.logToServer("CmdHandler.selectCallback idx= " + idx + " cmd= " + RecCmds.getCurrentItem().childs[idx].payload.cmd); + Server.execCmd(RecCmds.getCurrentItem().childs[idx].payload.cmd); + } +}; diff --git a/smarttv-client/Javascript/Player.js b/smarttv-client/Javascript/Player.js index 5fd6990..acecf5c 100755 --- a/smarttv-client/Javascript/Player.js +++ b/smarttv-client/Javascript/Player.js @@ -5,56 +5,72 @@ var mainPlayer; var Player = { - AVPlayerObj : null, - screenObj : null, - isLive : false, - isRecording : false, + isLive : false, + isRecording : false, + + startTime : 0, + duration : 0, // EpgDuration + + stopCallback : null, /* Callback function to be set by client */ + errorCallback : null, mFormat : 0, + + guid : "unknown", + + trickPlaySpeed : 1, // Multiple of 2 only. + + curPlayTimeStr : "00:00:00", // millis + curPlayTime : 0, // millis + + resumePos : -1, + + skipDuration : 30, // only used by config to set the skipDuration + bufferState : 0, // buffer state in %, Used by Display + + + //state value + STOPPED : 0, + PLAYING : 1, + PAUSED : 2, + FORWARD : 3, + REWIND : 4, + + //mFormat values eUND : 0, // undefined ePDL : 1, eHLS : 2, eHAS : 3, + + //Player Modules Internal Members + AVPlayerObj : null, + screenObj : null, url : "", - guid : "unknown", - startTime : 0, - duration : 0, // EpgDuration - - resumePos : -1, + urlExtension : "", + state : 0, cptOffset : 0, // millis - curPlayTime : 0, // millis + reportCurPlayTime : true, totalTime : -1, // millis - skipDuration : 30, - curPlayTimeStr : "00:00:00", // millis totalTimeStr : "", - stopCallback : null, /* Callback function to be set by client */ - errorCallback : null, originalSource : null, - - bufferState : 0, // buffer state in % - - trickPlaySpeed : 1, // Multiple of 2 only. + trickPlayDirection : 1, curAudioTrack : 0, + audioLanguages : [], curSubtitleTrack : 0, // Zero means off - STOPPED : 0, - PLAYING : 1, - PAUSED : 2, - FORWARD : 3, - REWIND : 4, - effectMode : 0, // 3DEffect Mode value (range from 0 to 7) aspectRatio :0, eASP16to9 :0, eASP4to3 :1, eASPcrop16to9 :2, + eASP21to9 : 3, bufferStartTime : 0, requestStartTime :0 @@ -85,44 +101,81 @@ Player.init = function() { return success; }; -// This function is called when Stop was pressed -Player.resetAtStop = function () { - // the default is for plain on-demand recording - // should be called with the Diplayer overlay Reset - - if (this.state != Player.STOPPED) { - Main.log("ERROR in Player.reset: should not be here"); - return; - } - this.aspectRatio = this.eASP16to9; - if (this.effectMode != 0) { - Player.screenObj.Set3DEffectMode(0); - } - this.effectMode = 0; - this.bufferState = 0; + +Player.deinit = function() { + Main.log("Player deinit !!! " ); + Main.logToServer("Player deinit !!! " ); + + if (Player.AVPlayerObj != null) { + Player.AVPlayerObj.stop(); + } +}; + +Player.isPdl = function () { + return (Player.mFormat == Player.ePDL); +}; + +Player.setPdl = function () { + Player.mFormat = Player.ePDL; + Player.urlExtensionurlExtension = ""; - Player.ResetTrickPlay(); // is the GUI resetted as well? - Player.adjustSkipDuration (0); +}; - this.cptOffset = 0; - this.curPlayTime = 0; - this.totalTime = -1; // negative on purpose - this.totalTimeStr = "0:00:00"; - this.curPlayTimeStr = "0:00:00"; +Player.isHls = function () { + return (Player.mFormat == Player.eHLS); +}; - this.isLive =false; - this.isRecording = false; - this.mFormat =Player.eUND; - this.curAudioTrack =0; - this.curSubtitleTrack = 0; +Player.setHls = function () { + Player.mFormat = Player.eHLS; + Player.urlExtensionurlExtension = "/manifest-seg.m3u8|COMPONENT=HLS"; +}; + +Player.isHas = function () { + return (Player.mFormat == Player.eHAS); +}; + +Player.setHas = function () { + Player.mFormat = Player.eHAS; + Player.urlExtensionurlExtension = "/manifest-seg.mpd|COMPONENT=HAS"; +}; + +Player.setVideoURL = function(url) { + this.url = url + this.urlExtensionurlExtension; + Main.log("Player.setVideoURL: URL = " + this.url); +}; + +// for Live and for on-going recordings +Player.setDuration = function () { + Player.totalTime = Data.getCurrentItem().childs[Main.selectedVideo].payload.dur * 1000; + Player.totalTimeStr =Display.durationString(Player.totalTime / 1000.0); +}; + +Player.getDurationStr = function () { + return Player.totalTimeStr; +}; + +Player.getDuration = function () { + return Player.totalTime; +}; + +// function for live +Player.setCurrentPlayTimeOffset = function(val) { + // val in milli sec + this.cptOffset = val; +// Display.showPopup("CurrentPlayTimeOffset= " + this.cptOffset); +}; + + +Player.getState = function() { + return this.state; }; Player.toggleAspectRatio = function () { -/* var height = Player.plugin.GetVideoHeight(); - var width = Player.plugin.GetVideoWidth(); - Main.logToServer ("Resolution= " + width + " x " + height ); - Main.log ("Resolution= " + width + " x " + height ); -*/ + /* var height = Player.plugin.GetVideoHeight(); + var width = Player.plugin.GetVideoWidth(); + Main.logToServer ("Resolution= " + width + " x " + height ); + Main.log ("Resolution= " + width + " x " + height ); + */ switch (this.aspectRatio) { case this.eASP16to9: //it is 16 to 9, so do 4 to 3 @@ -136,9 +189,15 @@ Player.toggleAspectRatio = function () { break; case this.eASPcrop16to9: // it is cropped 16 to 9 + this.aspectRatio = this.eASP21to9; + Notify.showNotify("21 : 9", true); +// Main.logToServer("Player.toggleAspectRatio: 16 by 9 Now"); + break; + case this.eASP21to9: + // it is 21 to 9 this.aspectRatio = this.eASP16to9; Notify.showNotify("16 : 9", true); -// Main.logToServer("Player.toggleAspectRatio: 16 by 9 Now"); +// Main.logToServer("Player.toggleAspectRatio: 16 by 9 Now"); break; } Player.setFullscreen(); @@ -150,12 +209,11 @@ Player.toggle3DEffectMode = function () { if( 1 == Player.screenObj.Flag3DTVConnect() ) { Main.logToServer("BDPlayer connected to 3D TV"); Player.setNew3DEffectMode(); - + } else { Main.logToServer("BDPlayer connected to 2D TV"); - Notify.showNotify("No 3DTV connected, sorry", true); - + Notify.showNotify("No 3DTV connected, sorry", true); } } else { @@ -174,22 +232,22 @@ Player.setNew3DEffectMode = function () { this.effectMode ++; if (this.effectMode > 7) this.effectMode = 0; - + Main.logToServer("New 3D Effect effectMode= " + this.effectMode ); Player.screenObj.Set3DEffectMode(this.effectMode); -/* if( 2 == Player.screenObj.Get3DEffectMode() ) { - Player.screenObj.Set3DEffectMode(0); - } - else { - Player.screenObj.Set3DEffectMode(2); - }; - */ + /* if( 2 == Player.screenObj.Get3DEffectMode() ) { + Player.screenObj.Set3DEffectMode(0); + } + else { + Player.screenObj.Set3DEffectMode(2); + }; + */ var mode = Player.screenObj.Get3DEffectMode(); - + Main.logToServer("New 3D Effect effectMode= " + this.effectMode + " plgMode= " + mode); -// switch (Player.screenObj.Get3DEffectMode()) { +// switch (Player.screenObj.Get3DEffectMode()) { if (this.effectMode == mode ) { switch (this.effectMode) { case 0: @@ -223,111 +281,10 @@ Player.setNew3DEffectMode = function () { } }; -Player.setWindow = function() { -// this.plugin.SetDisplayArea(458, 58, 472, 270); -}; - -Player.setFullscreen = function() { -// this.plugin.SetDisplayArea(0, 0, 960, 540); - - var resolution = Player.AVPlayerObj.getVideoResolution().split("|"); - - var w = resolution[0]; - var h = resolution[1]; - Main.logToServer ("Player.setFullscreen: Resolution= " + w + " x " + h ); - Main.log ("Resolution= " + w + " x " + h ); - - switch (this.aspectRatio) { - case this.eASP16to9: -// this.plugin.SetDisplayArea(0, 0, 960, 540); -// this.plugin.SetCropArea(0, 0, w, h); - Player.AVPlayerObj.setDisplayArea({left: 0, top:0, width:960, height:540 }); - Player.AVPlayerObj.setCropArea(Player.onCropSuccess, Player.onError, {left: 0, top:0, width:w, height:h }); - - Main.logToServer("Player.setFullscreen: 16 by 9 Now"); - break; - case this.eASP4to3: - // it is 4 to 3. do cropped do 16 to 9 -// this.plugin.SetDisplayArea(120, 0, 720, 540); -// this.plugin.SetCropArea(0, 0, w, h); - Player.AVPlayerObj.setDisplayArea({left: 120, top:0, width:720, height:540 }); - Player.AVPlayerObj.setCropArea(Player.onCropSuccess, Player.onError, {left: 0, top:0, width:w, height:h }); - // 4/3 = x/540 - Main.logToServer("Player.setFullscreen: 4 by 3 Now"); - break; - case this.eASPcrop16to9: - // it is cropped 16 to 9 - var z = Math.ceil(w*w*27 /(h*64)); - Main.logToServer("Player.setFullscreen: Crop 16 by 9 Now: z= " + z); -// this.plugin.SetDisplayArea(0, 0, 960, 540); -// this.plugin.SetCropArea(0, Math.round((h-z)/2), w, z); - Player.AVPlayerObj.setDisplayArea({left: 0, top:0, width:960, height:540 }); - Player.AVPlayerObj.setCropArea(Player.onCropSuccess, Player.onError, {left: 0, top:Math.round((h-z)/2), width:w, height:z }); - break; - } -}; - -//successcallback -//function onAVPlayObtained(avplay) { -Player.onAVPlayObtained = function (avplay) { - Player.AVPlayerObj = avplay; - Player.AVPlayerObj.hide(); - Main.logToServer("onAVPlayObtained: sName= " + avplay.sName+ " sVersion: " + avplay.sVersion); - var cb = new Object(); - cb.containerID = 'webapiplayer'; - cb.zIndex = 0; - cb.bufferingCallback = new Object(); - cb.bufferingCallback.onbufferingstart= Player.onBufferingStart; - cb.bufferingCallback.onbufferingprogress = Player.onBufferingProgress; - cb.bufferingCallback.onbufferingcomplete = Player.onBufferingComplete; - - cb.playCallback = new Object; - cb.playCallback.oncurrentplaytime = Player.OnCurrentPlayTime; - cb.playCallback.onresolutionchanged = Player.onResolutionChanged; - cb.playCallback.onstreamcompleted = Player.OnRenderingComplete; - cb.playCallback.onerror = Player.onError; - - cb.displayRect= new Object(); - cb.displayRect.top = 0; - cb.displayRect.left = 0; - cb.displayRect.width = 960; - cb.displayRect.height = 540; - cb.autoRatio = false; - - try { - Player.AVPlayerObj.init(cb); - } - catch (e) { - Main.log("Player: Error during init: " + e.message); - Main.logToServer("Player: Error during init: " + e.message); - }; -}; - -//errorcallback -//function onGetAVPlayError(error) { -Player.onGetAVPlayError = function (error) { - Main.log('Player.onGetAVPlayError: ' + error.message); - Main.logToServer('Player.onGetAVPlayError: ' + error.message); -}; - - - -Player.deinit = function() { - Main.log("Player deinit !!! " ); - Main.logToServer("Player deinit !!! " ); - - if (Player.AVPlayerObj != null) { - Player.AVPlayerObj.stop(); - } -}; - Player.getNumOfAudioTracks = function () { return (Player.AVPlayerObj.totalNumOfAudio != null) ? Player.AVPlayerObj.totalNumOfAudio : "Unknown"; }; -Player.getNumOfSubtitleTracks = function () { - return (Player.AVPlayerObj.totalNumOfSubtitle != null) ? Player.AVPlayerObj.totalNumOfSubtitle : "Unknown"; -}; Player.nextAudioTrack = function () { @@ -343,7 +300,10 @@ Player.nextAudioTrack = function () { else { Player.curAudioTrack = new_track; Main.logToServer("Player.nextAudioTrack: Track= " + Player.curAudioTrack); - Notify.showNotify("Audio Track " + Player.curAudioTrack, true); + if(Player.audioLanguages[Player.curAudioTrack] == "") + Notify.showNotify("Audio Track " + Player.curAudioTrack, true); + else + Notify.showNotify("Audio Track " + Player.curAudioTrack + ": " + Player.audioLanguages[Player.curAudioTrack], true); } } @@ -353,6 +313,10 @@ Player.nextAudioTrack = function () { } }; +Player.getNumOfSubtitleTracks = function () { + return (Player.AVPlayerObj.totalNumOfSubtitle != null) ? Player.AVPlayerObj.totalNumOfSubtitle : "Unknown"; +}; + Player.nextSubtitleTrack = function () { if (!Player.AVPlayerObj.getSubtitleAvailable() ) { return; @@ -378,45 +342,21 @@ Player.nextSubtitleTrack = function () { }; -Player.getBuffer = function (){ - var res = {}; - var buffer_byte = (Config.totalBufferDuration * Config.tgtBufferBitrate) / 8.0; - var initial_buf = Config.initialBuffer; - if (Player.isLive == true) - initial_buf = initial_buf *4; - - res.totalBufferSize = Math.round(buffer_byte); - res.initialBufferSize = Math.round( buffer_byte * initial_buf/ 100.0); - res.pendingBufferSize = Math.round(buffer_byte * Config.pendingBuffer /100.0); - Main.logToServer("Setting totalBufferSize= " + res.totalBufferSize +"Byte initialBufferSize= " +res.initialBufferSize + "byte pendingBufferSize= " +res.pendingBufferSize +"byte " ); - - return res; -}; - -Player.setVideoURL = function(url) { - this.url = url; - Main.log("Player.setVideoURL: URL = " + this.url); -}; - - -Player.setCurrentPlayTimeOffset = function(val) { - // val in milli sec - this.cptOffset = val; -// Display.showPopup("CurrentPlayTimeOffset= " + this.cptOffset); -}; - -Player.setDuration = function () { - Player.totalTime = Data.getCurrentItem().childs[Main.selectedVideo].payload.dur * 1000; - Player.totalTimeStr =Display.durationString(Player.totalTime / 1000.0); -}; - -Player.getDuration = function () { - return Player.totalTime; -}; - -Player.getDurationStr = function () { - return Player.totalTimeStr; +Player.numKeyJump = function (key) { + Display.showProgress(); + + switch (Config.playKeyBehavior) { + case 1: + var cur_skip_duration = this.skipDuration; + this.skipDuration = key * 60; + this.skipForwardVideo(); + this.skipDuration = cur_skip_duration; + break; + default: + Player.jumpToVideo(key * 10); + break; + } }; Player.playVideo = function(resume_pos) { @@ -432,6 +372,7 @@ Player.playVideo = function(resume_pos) { Display.bufferUpdate(); Player.AVPlayerObj.show(); + Main.logToServer("Player.playVideo - Spinner.show()"); Spinner.show(); Display.updatePlayTime(); @@ -447,7 +388,8 @@ Player.playVideo = function(resume_pos) { Main.log ("Player.playVideo: StartPlayback for " + this.url); - this.requestStartTime = new Date().getTime(); + this.requestStartTime = Display.GetUtcTime(); +// this.requestStartTime = new MyDate().getTime(); if (Player.isRecording == false) { if (resume_pos == -1) resume_pos = 0; @@ -455,14 +397,18 @@ Player.playVideo = function(resume_pos) { try { Main.logToServer("Player.play Start playback of url= " + this.url + " resume= " + resume_pos + " sec"); - // Player.AVPlayerObj.open (this.url, Player.getBuffer()); - Player.AVPlayerObj.open (this.url); + if (Config.useDefaultBuffer || ( !Player.isLive && !Config.usePdlForRecordings)) { + Main.logToServer("Player.play using default buffer!"); + Player.AVPlayerObj.open (this.url); + } + else + Player.AVPlayerObj.open (this.url, Player.getBuffer()); Player.AVPlayerObj.play(Player.onPlaySuccess, Player.onError, resume_pos); } catch (e) { - Main.log("Player.play: Error caugth " + e.msg); - Main.logToServer("Player.play: Error caugth " + e.msg); - Display.showPopup("Player.play: Error caugth " + e.msg); + Main.log("Player.play: Error caught " + e.msg); + Main.logToServer("Player.play: Error caught " + e.msg); + Display.showPopup("Player.play: Error caught " + e.msg); } } @@ -473,8 +419,15 @@ Player.playVideo = function(resume_pos) { try { Main.logToServer("Player.play Start playback of url= " + this.url + " time= " + resume_pos + " sec"); - // Player.AVPlayerObj.open(this.url+ "?time=" + resume_pos, Player.getBuffer() ); - Player.AVPlayerObj.open(this.url+ "?time=" + resume_pos ); + if (Config.usePdlForRecordings) { + if (Config.useDefaultBuffer) + Player.AVPlayerObj.open(this.url+ "?time=" + resume_pos); + else + Player.AVPlayerObj.open(this.url+ "?time=" + resume_pos, Player.getBuffer() ); + } + else { + Player.AVPlayerObj.open (this.url); + } Player.AVPlayerObj.play(Player.onPlaySuccess , Player.onError); } catch(e) { @@ -484,6 +437,7 @@ Player.playVideo = function(resume_pos) { }; Main.logToServer("Player.play with ?time=" + resume_pos); } + Main.logToServer("Player.play Started"); if ((this.mFormat == this.eHLS) && (this.isLive == false)){ Notify.showNotify("No Trickplay", true); @@ -542,6 +496,43 @@ Player.stopVideo = function() { } }; +//This function is called when Stop was pressed +Player.resetAtStop = function () { + // the default is for plain on-demand recording + // should be called with the Diplayer overlay Reset + + if (this.state != Player.STOPPED) { + Main.log("ERROR in Player.reset: should not be here"); + return; + } + this.aspectRatio = this.eASP16to9; + if (this.effectMode != 0) { + Player.screenObj.Set3DEffectMode(0); + } + this.effectMode = 0; + this.bufferState = 0; + + Player.ResetTrickPlay(); // is the GUI resetted as well? + Player.adjustSkipDuration (0); + + this.cptOffset = 0; + this.curPlayTime = 0; + this.reportCurPlayTime = true; + this.totalTime = -1; // negative on purpose + this.totalTimeStr = "0:00:00"; + this.curPlayTimeStr = "0:00:00"; + + this.isLive =false; + this.isRecording = false; + this.mFormat =Player.eUND; + this.urlExtensionurlExtension = ""; + this.curAudioTrack =0; + this.audioLanguages = []; + this.curSubtitleTrack = 0; +}; + + + Player.resumeVideo = function() { Main.logToServer("resumeVideo"); Display.showProgress(); @@ -559,73 +550,39 @@ Player.resumeVideo = function() { // pluginObj.setOffScreenSaver(); }; -Player.numKeyJump = function (key) { - Display.showProgress(); - - switch (Config.playKeyBehavior) { - case 1: - var cur_skip_duration = this.skipDuration; - this.skipDuration = key * 60; - this.skipForwardVideo(); - this.skipDuration = cur_skip_duration; - break; - default: - Player.jumpToVideo(key * 10); - break; - } -}; - -Player.jumpToVideo = function(percent) { - Spinner.show(); - if (this.isLive == true) { +Player.adjustSkipDuration = function (dir) { + if (Player.isLive == true) { return; } - if (this.state != this.PLAYING) { - Main.logToServer ("Player.jumpToVideo: Player not Playing"); - return; - } - Player.bufferState = 0; - Display.showProgress(); - - //TODO: the totalTime should be set already - if (this.totalTime == -1 && this.isLive == false) - this.totalTime = Player.AVPlayerObj.getDuration(); - var tgt = Math.round(((percent-2)/100.0) * this.totalTime/ 1000.0); - var res = false; - - this.requestStartTime = new Date().getTime(); - - if (Player.isRecording == false) { - if (tgt > (Player.curPlayTime/1000.0)) - res = Player.AVPlayerObj.jumpForward(tgt - (Player.curPlayTime/1000.0)); - else - res = Player.AVPlayerObj.jumpBackward( (Player.curPlayTime/1000.0)- tgt); - } - else { - Player.AVPlayerObj.stop(); - var old = Player.curPlayTime; - - Player.setCurrentPlayTimeOffset(tgt * 1000.0); - -// Player.AVPlayerObj.open(this.url+ "?time=" + tgt, Player.getBuffer() ); - Player.AVPlayerObj.open(this.url+ "?time=" + tgt); - res = Player.AVPlayerObj.play(Player.onPlaySuccess , Player.onError); - - Main.logToServer("Player.play with ?time=" + tgt); - if (res == false) - Player.setCurrentPlayTimeOffset(old); - } - Main.logToServer("Player.jumpToVideo: jumpTo= " + percent + "% of " + (this.totalTime/1000) + "sec tgt = " + tgt + "sec cpt= " + (this.curPlayTime/1000) +"sec" + " res = " + res); - - if (res == false) - Display.showPopup("ResumePlay ret= " + ((res == true) ? "True" : "False")); + switch (dir) { + case 0: + // Reset + Player.skipDuration = Config.skipDuration; + Display.setSkipDuration(Player.skipDuration ); + break; + case 1: + // Increase + Player.skipDuration += Config.skipDuration; + Display.setSkipDuration(Player.skipDuration ); + break; + case 2: + // Decrease + Player.skipDuration -= Config.skipDuration; + if (Player.skipDuration < Config.skipDuration) + Player.skipDuration = Config.skipDuration; + Display.setSkipDuration(Player.skipDuration ); + break; + }; }; Player.skipForwardVideo = function() { - this.requestStartTime = new Date().getTime(); + Main.logToServer ("Player.skipForwardVideo: cpt= " + (Player.curPlayTime / 1000.0) + " sec skipDur= " + Player.skipDuration + " isRec= " + ((Player.isRecording == true) ? "true" : "false")); + + this.requestStartTime = Display.GetUtcTime();; +// this.requestStartTime = new MyDate().getTime(); Display.showProgress(); var res = false; - if (Player.isRecording == false) + if (Player.isRecording == false || !Config.usePdlForRecordings) res = Player.AVPlayerObj.jumpForward(Player.skipDuration); else { Spinner.show(); @@ -634,8 +591,12 @@ Player.skipForwardVideo = function() { var old = Player.curPlayTime; var tgt = (Player.curPlayTime/1000.0) + Player.skipDuration; Player.setCurrentPlayTimeOffset(tgt * 1000.0); -// Player.AVPlayerObj.open(this.url+ "?time=" + tgt, Player.getBuffer()); - Player.AVPlayerObj.open(this.url+ "?time=" + tgt); + + if (Config.useDefaultBuffer) + Player.AVPlayerObj.open(this.url+ "?time=" + tgt); + else + Player.AVPlayerObj.open(this.url+ "?time=" + tgt, Player.getBuffer()); + res = Player.AVPlayerObj.play(Player.onPlaySuccess , Player.onError); Main.logToServer("Player.skipForwardVideo with ?time=" + tgt); @@ -648,10 +609,13 @@ Player.skipForwardVideo = function() { }; Player.skipBackwardVideo = function() { - this.requestStartTime = new Date().getTime(); + Main.logToServer ("Player.skipBackwardVideo: cpt= " + (Player.curPlayTime / 1000.0) + " sec skipDur= " + Player.skipDuration + " isRec= " + ((Player.isRecording == true) ? "true" : "false")); + + this.requestStartTime = Display.GetUtcTime();; +// this.requestStartTime = new MyDate().getTime(); Display.showProgress(); var res = false; - if (Player.isRecording == false) + if (Player.isRecording == false || !Config.usePdlForRecordings) res = Player.AVPlayerObj.jumpBackward(Player.skipDuration); else { Spinner.show(); @@ -661,8 +625,11 @@ Player.skipBackwardVideo = function() { if (tgt < 0) tgt = 0; Player.setCurrentPlayTimeOffset(tgt * 1000.0); -// Player.AVPlayerObj.open(this.url+ "?time=" + tgt, Player.getBuffer()); - Player.AVPlayerObj.open(this.url+ "?time=" + tgt); + if (Config.useDefaultBuffer) + Player.AVPlayerObj.open(this.url+ "?time=" + tgt); + else + Player.AVPlayerObj.open(this.url+ "?time=" + tgt, Player.getBuffer()); + res = Player.AVPlayerObj.play(Player.onPlaySuccess , Player.onError); Main.logToServer("Player.skipBackwardVideo with ?time=" + tgt); @@ -675,35 +642,33 @@ Player.skipBackwardVideo = function() { } }; -Player.adjustSkipDuration = function (dir) { - if (Player.isLive == true) { - return; + + +Player.ResetTrickPlay = function() { + if (this.trickPlaySpeed != 1) { + this.trickPlaySpeed = 1; + this.trickPlayDirection = 1; + Main.log("Reset Trickplay " ); + if (Player.AVPlayerObj.setSpeed(this.trickPlaySpeed * this.trickPlayDirection) == false) { + Display.showPopup("trick play returns false. Reset Trick-Play" ); + this.trickPlaySpeed = 1; + this.trickPlayDirection = 1; + } + + } + if (Player.skipDuration != 30) { + Display.setSkipDuration(Player.skipDuration ); + } + else { + Display.resetStartStop(); } - switch (dir) { - case 0: - // Reset - Player.skipDuration = Config.skipDuration; - Display.setSkipDuration(Player.skipDuration ); - break; - case 1: - // Increase - Player.skipDuration += Config.skipDuration; - Display.setSkipDuration(Player.skipDuration ); - break; - case 2: - // Decrease - Player.skipDuration -= Config.skipDuration; - if (Player.skipDuration < Config.skipDuration) - Player.skipDuration = Config.skipDuration; - Display.setSkipDuration(Player.skipDuration ); - break; - }; }; Player.isInTrickplay = function() { return (this.trickPlaySpeed != 1) ? true: false; }; + Player.fastForwardVideo = function() { if (this.trickPlayDirection == 1) { this.trickPlaySpeed = this.trickPlaySpeed * 2; @@ -784,40 +749,231 @@ Player.RewindVideo = function() { }; -Player.ResetTrickPlay = function() { - if (this.trickPlaySpeed != 1) { - this.trickPlaySpeed = 1; - this.trickPlayDirection = 1; - Main.log("Reset Trickplay " ); - if (Player.AVPlayerObj.setSpeed(this.trickPlaySpeed * this.trickPlayDirection) == false) { - Display.showPopup("trick play returns false. Reset Trick-Play" ); - this.trickPlaySpeed = 1; - this.trickPlayDirection = 1; - } + + +// used to reset ProgressBar +Player.OnCurrentPlayTime = function(time) { + Main.log ("Player.OnCurrentPlayTime " + time.millisecond); + + if (typeof time == "number") + Player.curPlayTime = parseInt(time) + parseInt(Player.cptOffset); + else + Player.curPlayTime = parseInt(time.millisecond) + parseInt(Player.cptOffset); + + if (Player.reportCurPlayTime == true) { + Player.reportCurPlayTime = false; + Main.logToServer ("Player.OnCurrentPlayTime cpt= " + (Player.curPlayTime/1000.0) + "sec dur= " + (Player.getDuration() /1000.0) + "sec"); } - if (Player.skipDuration != 30) { - Display.setSkipDuration(Player.skipDuration ); + + // Update the Current Play Progress Bar + Display.updateProgressBar(); + + if (Player.isRecording == true) { + Display.updateRecBar(Player.startTime, Player.duration); + } + Main.log ("Player.OnCurrentPlayTime: curPlayTimeStr= " + Player.curPlayTimeStr); + Player.curPlayTimeStr = Display.durationString(Player.curPlayTime / 1000.0); + + Display.updatePlayTime(); +}; + + +// ------------------------------------------------------ +// Player Internal Functions +//------------------------------------------------------ + + +Player.setWindow = function() { +// this.plugin.SetDisplayArea(458, 58, 472, 270); +}; + +Player.setFullscreen = function() { +// this.plugin.SetDisplayArea(0, 0, 960, 540); + + var resolution = Player.AVPlayerObj.getVideoResolution().split("|"); + + var w = resolution[0]; + var h = resolution[1]; + Main.logToServer ("Player.setFullscreen: Resolution= " + w + " x " + h ); + Main.log ("Resolution= " + w + " x " + h ); + + switch (this.aspectRatio) { + case this.eASP16to9: +// this.plugin.SetDisplayArea(0, 0, 960, 540); +// this.plugin.SetCropArea(0, 0, w, h); + Player.AVPlayerObj.setDisplayArea({left: 0, top:0, width:960, height:540 }); + Player.AVPlayerObj.setCropArea(Player.onCropSuccess, Player.onError, {left: 0, top:0, width:w, height:h }); + + Main.logToServer("Player.setFullscreen: 16 by 9 Now"); + break; + case this.eASP4to3: + // it is 4 to 3. do cropped do 16 to 9 +// this.plugin.SetDisplayArea(120, 0, 720, 540); +// this.plugin.SetCropArea(0, 0, w, h); + Player.AVPlayerObj.setDisplayArea({left: 120, top:0, width:720, height:540 }); + Player.AVPlayerObj.setCropArea(Player.onCropSuccess, Player.onError, {left: 0, top:0, width:w, height:h }); + // 4/3 = x/540 + Main.logToServer("Player.setFullscreen: 4 by 3 Now"); + break; + case this.eASPcrop16to9: + // it is cropped 16 to 9 + var z = Math.ceil(w*w*27 /(h*64)); + Main.logToServer("Player.setFullscreen: Crop 16 by 9 Now: z= " + z); +// this.plugin.SetDisplayArea(0, 0, 960, 540); +// this.plugin.SetCropArea(0, Math.round((h-z)/2), w, z); + Player.AVPlayerObj.setDisplayArea({left: 0, top:0, width:960, height:540 }); + Player.AVPlayerObj.setCropArea(Player.onCropSuccess, Player.onError, {left: 0, top:Math.round((h-z)/2), width:w, height:z }); + break; + case this.eASP21to9: + Player.AVPlayerObj.setDisplayArea({left: 0, top:64, width:960, height:412 }); + Player.AVPlayerObj.setCropArea(Player.onCropSuccess, Player.onError, {left: 0, top:0, width:w, height:h }); + Main.logToServer("Player.setFullscreen: 21 by 9 Now"); + + break; + } +}; + +//successcallback +//function onAVPlayObtained(avplay) { +Player.onAVPlayObtained = function (avplay) { + Player.AVPlayerObj = avplay; + Player.AVPlayerObj.hide(); + Main.logToServer("onAVPlayObtained: sName= " + avplay.sName+ " sVersion: " + avplay.sVersion); + var cb = new Object(); + cb.containerID = 'webapiplayer'; + cb.zIndex = 0; + cb.bufferingCallback = new Object(); + cb.bufferingCallback.onbufferingstart= Player.onBufferingStart; + cb.bufferingCallback.onbufferingprogress = Player.onBufferingProgress; + cb.bufferingCallback.onbufferingcomplete = Player.onBufferingComplete; + + cb.playCallback = new Object; + cb.playCallback.oncurrentplaytime = Player.OnCurrentPlayTime; + cb.playCallback.onresolutionchanged = Player.onResolutionChanged; + cb.playCallback.onstreamcompleted = Player.OnRenderingComplete; + cb.playCallback.onerror = Player.onError; + + cb.displayRect= new Object(); + cb.displayRect.top = 0; + cb.displayRect.left = 0; + cb.displayRect.width = 960; + cb.displayRect.height = 540; + cb.autoRatio = false; // thlo: Test Aspect ratio + + try { + Player.AVPlayerObj.init(cb); + } + catch (e) { + Main.log("Player: Error during init: " + e.message); + Main.logToServer("Player: Error during init: " + e.message); + }; +}; + +//errorcallback +//function onGetAVPlayError(error) { +Player.onGetAVPlayError = function (error) { + Main.log('Player.onGetAVPlayError: ' + error.message); + Main.logToServer('Player.onGetAVPlayError: ' + error.message); +}; + +Player.getBuffer = function () { + var res = {}; + /* + var buffer_byte = (Config.totalBufferDuration * Config.tgtBufferBitrate) / 8.0; + var initial_buf = Config.initialBuffer; +// if (Player.isLive == true) +// initial_buf = initial_buf *4; + + res.totalBufferSize = Math.round(buffer_byte); + res.initialBufferSize = Math.round( buffer_byte * initial_buf/ 100.0); + res.pendingBufferSize = Math.round(buffer_byte * Config.pendingBuffer /100.0); +*/ + if (Player.isLive == true) { + res.totalBufferSize = Config.totalBufferSize; + res.initialBufferSize = Config.initialBufferSize; + res.pendingBufferSize = Config.pendingBufferSize; } else { - Display.resetStartStop(); + res.totalBufferSize = (Config.totalBufferSize ); + res.initialBufferSize = (Config.initialBufferSize /2); + res.pendingBufferSize = (Config.pendingBufferSize ); } + Main.logToServer("Setting Buffer " + ((Player.isLive == true)? "Live" : "VOD") + " total= " + res.totalBufferSize +" Byte initial= " +res.initialBufferSize + " Byte pending= " +res.pendingBufferSize +" Byte " ); + + return res; }; -Player.getState = function() { - return this.state; + + +Player.jumpToVideo = function(percent) { + if (this.isLive == true) { + return; + } + + if (this.state != this.PLAYING) { + Main.logToServer ("Player.jumpToVideo: Player not Playing"); + return; + } + + Main.logToServer ("Player.jumpToVideo: cpt= " + (Player.curPlayTime / 1000.0) + " sec target= " + percent + "% isRec= " + ((Player.isRecording == true) ? "true" : "false")); + Spinner.show(); + + Player.bufferState = 0; + Display.showProgress(); + + //TODO: the totalTime should be set already + if (this.totalTime == -1 && this.isLive == false) + this.totalTime = Player.AVPlayerObj.getDuration(); + var tgt = Math.round(((percent-2)/100.0) * this.totalTime/ 1000.0); + var res = false; + + this.requestStartTime = Display.GetUtcTime();; +// this.requestStartTime = new MyDate().getTime(); + + if (Player.isRecording == false || !Config.usePdlForRecordings) { + if (tgt > (Player.curPlayTime/1000.0)) + res = Player.AVPlayerObj.jumpForward(tgt - (Player.curPlayTime/1000.0)); + else + res = Player.AVPlayerObj.jumpBackward( (Player.curPlayTime/1000.0)- tgt); + } + else { + Player.AVPlayerObj.stop(); + var old = Player.curPlayTime; + + Player.setCurrentPlayTimeOffset(tgt * 1000.0); + + if (Config.useDefaultBuffer) + Player.AVPlayerObj.open(this.url+ "?time=" + tgt); + else + Player.AVPlayerObj.open(this.url+ "?time=" + tgt, Player.getBuffer()); + + res = Player.AVPlayerObj.play(Player.onPlaySuccess , Player.onError); + + Main.logToServer("Player.play with ?time=" + tgt); + if (res == false) + Player.setCurrentPlayTimeOffset(old); + } + Main.logToServer("Player.jumpToVideo: jumpTo= " + percent + "% of " + (this.totalTime/1000) + "sec tgt = " + tgt + "sec cpt= " + (this.curPlayTime/1000) +"sec" + " res = " + res); + + if (res == false) + Display.showPopup("ResumePlay ret= " + ((res == true) ? "True" : "False")); }; + + + // ------------------------------------------------ // Global functions called directly by the player //------------------------------------------------ Player.onResolutionChanged = function () { Main.log('Player.onResolutionChanged : '); + Main.logToServer('Player.onResolutionChanged : '); }; -Player.onError = function () { - Main.log('Player.onError: ' ); - Main.logToServer('Player.onError: ' ); +Player.onError = function (error) { + Main.log('Player.onError: ' + error.name); + Main.logToServer('Player.onError: ' + error.name); }; @@ -832,23 +988,33 @@ Player.onCropSuccess = function () { Player.onBufferingStart = function() { -// Main.logToServer("Buffer Start: cpt= " + (Player.curPlayTime/1000.0) +"sec"); + Main.logToServer("Buffer Start: cpt= " + (Player.curPlayTime/1000.0) +"sec"); Main.log("Buffer Start: cpt= " + (Player.curPlayTime/1000.0) +"sec"); - Player.bufferStartTime = new Date().getTime(); + Player.reportCurPlayTime = true; + +// Player.bufferStartTime = new MyDate().getTime(); + Player.bufferStartTime = Display.GetUtcTime(); if (this.requestStartTime != 0) { this.requestStartTime = 0; } + Spinner.show(); Player.bufferState = 0; Display.bufferUpdate(); Display.showProgress(); Display.status("Buffering..."); + + Main.logToServer("BufferSize: total= " + Player.AVPlayerObj.totalBufferSize + " initial= " + + Player.AVPlayerObj.initialBufferSize + " pending= " + Player.AVPlayerObj.pendingBufferSize); + }; Player.onBufferingProgress = function(percent) { + Main.logToServer("Player.onBufferingProgress: " +percent +" %"); + Player.bufferState = percent; Display.bufferUpdate(); Display.showProgress(); @@ -859,8 +1025,11 @@ Player.onBufferingComplete = function() { Display.hideStatus(); Spinner.hide(); - Main.logToServer("onBufferingComplete cpt= " +(Player.curPlayTime/1000.0) +"sec - Buffering Duration= " + (new Date().getTime() - Player.bufferStartTime) + " ms"); - Main.log("onBufferingComplete cpt= " +(Player.curPlayTime/1000.0) +"sec - Buffering Duration= " + (new Date().getTime() - Player.bufferStartTime) + " ms"); + + Main.logToServer("onBufferingComplete cpt= " +(Player.curPlayTime/1000.0) +"sec - Buffering Duration= " + (Display.GetUtcTime() - Player.bufferStartTime) + " ms"); + Main.log("onBufferingComplete cpt= " +(Player.curPlayTime/1000.0) +"sec - Buffering Duration= " + (Display.GetUtcTime() - Player.bufferStartTime) + " ms"); +// Main.logToServer("onBufferingComplete cpt= " +(Player.curPlayTime/1000.0) +"sec - Buffering Duration= " + (new MyDate().getTime() - Player.bufferStartTime) + " ms"); +// Main.log("onBufferingComplete cpt= " +(Player.curPlayTime/1000.0) +"sec - Buffering Duration= " + (new MyDate().getTime() - Player.bufferStartTime) + " ms"); Player.bufferState = 100; Display.bufferUpdate(); @@ -869,30 +1038,31 @@ Player.onBufferingComplete = function() { // Player.setFullscreen(); // or I should set it according to the aspect ratio Display.hide(); + Main.logToServer("BufferSize: total= " + Player.AVPlayerObj.totalBufferSize + " initial= " + + Player.AVPlayerObj.initialBufferSize + " pending= " + Player.AVPlayerObj.pendingBufferSize); }; -Player.OnCurrentPlayTime = function(time) { - Main.log ("Player.OnCurrentPlayTime " + time.millisecond); - - if (typeof time == "number") - Player.curPlayTime = parseInt(time) + parseInt(Player.cptOffset); - else - Player.curPlayTime = parseInt(time.millisecond) + parseInt(Player.cptOffset); + +Player.langCodeToString = function (code) { + if (code <0) + return ""; - // Update the Current Play Progress Bar - Display.updateProgressBar(); - - if (Player.isRecording == true) { - Display.updateRecBar(Player.startTime, Player.duration); - } - Main.log ("Player.OnCurrentPlayTime: curPlayTimeStr= " + Player.curPlayTimeStr); - Player.curPlayTimeStr = Display.durationString(Player.curPlayTime / 1000.0); + var code_str = code.toString(16); + var res = ""; - Display.updatePlayTime(); -}; + if ((code_str.length % 2) != 0) + res = "0" + res; + + // even chars + while (code_str.length >= 2) { + res += String.fromCharCode(parseInt(code_str.substring(0, 2), 16)); + code_str = code_str.substring(2, code_str.length); + } + return res; +}; Player.OnStreamInfoReady = function() { Main.log("*** OnStreamInfoReady ***"); @@ -903,7 +1073,28 @@ Player.OnStreamInfoReady = function() { } Player.totalTimeStr =Display.durationString(Player.totalTime / 1000.0); Main.log("Player.totalTimeStr= " + Player.totalTimeStr); + + if (Player.audioLanguages.length == 0) { + for (var i = 0; i < Player.AVPlayerObj.totalNumOfAudio; i++) { + var lang_no = Player.AVPlayerObj.getStreamLanguageInfo(1,i); + Player.audioLanguages.push(Player.langCodeToString(lang_no)); + }; + } + // here I am + var no_audio = Player.AVPlayerObj.totalNumOfAudio; + for (var i = 0; i < no_audio; i++) { + var lang_no = Player.AVPlayerObj.getStreamLanguageInfo(1,i); + var extra_no = Player.AVPlayerObj.getStreamExtraData(1,i); + Main.logToServer( "Audio lang ("+i+") lang= " + lang_no.toString(16) + "h -> \"" + Player.langCodeToString(lang_no) + "\" extra= " + extra_no.toString(16) + "h -> \"" + Player.langCodeToString(extra_no) + "\""); + }; + + var no_sub = Player.AVPlayerObj.totalNumOfSubtitle; + for (var i = 0; i < no_sub; i++) { + var lang_no = Player.AVPlayerObj.getStreamLanguageInfo(5,i); + var extra_no = Player.AVPlayerObj.getStreamExtraData(5,i); + Main.logToServer( "Audio lang ("+i+") lang= " + lang_no.toString(16) + "h -> \"" + Player.langCodeToString(lang_no) + "\" extra= " + extra_no.toString(16) + "h -> \"" + Player.langCodeToString(extra_no) + "\""); + }; }; Player.OnRenderingComplete = function() { diff --git a/smarttv-client/Javascript/SelectScreen.js b/smarttv-client/Javascript/SelectScreen.js index f7cb631..a817f81 100644 --- a/smarttv-client/Javascript/SelectScreen.js +++ b/smarttv-client/Javascript/SelectScreen.js @@ -28,9 +28,13 @@ SelectScreen.init = function() { parent.append($("
", {id : "selectItem"+idx, text:idx+": You Tube", class : "style_menuItem"})); // Main.selectMenuKeyHndl.selectMax++; } - + if (Config.haveCmds) { + this.keyToStateMap[++idx] = Main.eCMDS; + parent.append($("
", {id : "selectItem"+idx, text:idx+": Commands", class : "style_menuItem"})); + } this.keyToStateMap[++idx] = Main.eSRVR; parent.append($("
", {id : "selectItem"+idx, text:idx+": Select Server", class : "style_menuItem"})); + this.keyToStateMap[++idx] = Main.eOPT; parent.append($("
", {id : "selectItem"+idx, text:idx+": Options", class : "style_menuItem"})); @@ -122,9 +126,26 @@ cSelectMenuKeyHndl.prototype.handleKeyDown = function (keyCode) { case tvKey.KEY_6: Main.log("KEY_6 pressed"); + if (SelectScreen.keyToStateMap.length < 6) + return; this.select = 6; Main.changeState (SelectScreen.keyToStateMap[this.select]); break; + case tvKey.KEY_7: + Main.log("KEY_7 pressed"); + if (SelectScreen.keyToStateMap.length < 7) + return; + this.select = 7; + Main.changeState (SelectScreen.keyToStateMap[this.select]); + break; + + case tvKey.KEY_8: + Main.log("KEY_8 pressed"); + if (SelectScreen.keyToStateMap.length < 8) + return; + this.select = 8; + Main.changeState (SelectScreen.keyToStateMap[this.select]); + break; case tvKey.KEY_ENTER: case tvKey.KEY_PLAY: diff --git a/smarttv-client/Javascript/Server.js b/smarttv-client/Javascript/Server.js index a141f5d..209b603 100755 --- a/smarttv-client/Javascript/Server.js +++ b/smarttv-client/Javascript/Server.js @@ -26,6 +26,7 @@ Server.setSort = function (val) { }; //--------------------------------------------- Server.fetchVideoList = function(url) { +//Server.retries is set to zero in Main! $.ajax({ url: url, @@ -67,8 +68,15 @@ Server.fetchVideoList = function(url) { }, error : function (jqXHR, status, error) { + this.statusCode = jqXHR.status; + this.status = status; + this.errno = Number(jqXHR.responseText.slice(0, 3)); + var res = Server.getErrorText(jqXHR.status, jqXHR.responseText); Main.logToServer("Server.fetchVideoList Error Response - status= " + status + " error= "+ error); - Display.showPopup("Error with XML File: " + status); + + Notify.showNotify( res, true); + Main.changeState(0); + Server.retries ++; }, parsererror : function () { @@ -87,31 +95,51 @@ Server.fetchVideoList = function(url) { //--------------------------------------------- Server.updateVdrStatus = function (){ - Main.log ("get VDR Status"); + Main.log ("get VDR Status from " + Config.serverUrl + "/vdrstatus.xml"); $.ajax({ url: Config.serverUrl + "/vdrstatus.xml", type : "GET", success : function(data, status, XHR){ var ts_vdr = $(data).find('vdrTime').text(); + var ts_vdr_utc = parseInt($(data).find('vdrUtcTime').text()); + Main.log("ts_vdr= " + ts_vdr+ " vdr_utc= " + ts_vdr_utc + " locUtc= " + Display.GetUtcTime()); +// Main.logToServer("ts_vdr= " + ts_vdr+ " vdr_utc= " + ts_vdr_utc + " locUtc= " + Display.GetUtcTime()); + Config.useVdrTime = false; + if (isNaN(ts_vdr_utc)) { + ts_vdr_utc = -1; + } + else { + if (Math.abs(Display.GetUtcTime() - ts_vdr_utc) > 30) { + // use Vdr Time + Config.uvtUtcTime = ts_vdr_utc; + // Safer + if (Config.deviceType == 0) + Config.uvtlocRefTime = Display.pluginTime.GetEpochTime(); + else + Config.uvtlocRefTime = ((new Date()).getTime()) / 1000.0; + Config.useVdrTime = true; + Main.log("using Vdr Time uvtUtcTime= " + Config.uvtUtcTime + " uvtlocRefTime= " + Config.uvtlocRefTime + " d= " + (Config.uvtUtcTime - Config.uvtlocRefTime)); + Main.logToServer("using Vdr Time uvtUtcTime= " + Config.uvtUtcTime + " uvtlocRefTime= " + Config.uvtlocRefTime + " d= " + (Config.uvtUtcTime - Config.uvtlocRefTime)); + } + else + Config.useVdrTime = false; + } + + var bits = ts_vdr.split(/[-T:]/g); try { - var ts = ts_vdr.split("T")[1]; - var s = ts.split(":"); - if (s.length == 3) { - var now = ((new Date).getHours()); - Config.tzCorrection = now - s[0]; - // if Config.tzCorrection larger zero, then TV is ahead - // thus, I need to substract Config.tzCorrection from the TV time + var now = ((new Date(Display.GetUtcTime()*1000)).getHours()); + Config.tzCorrection = now - bits[3]; + // if Config.tzCorrection larger zero, then TV is ahead + // thus, I need to substract Config.tzCorrection from the TV time // Config.tzCorrection = 1; - Main.logToServer("Server.updateVdrStatus: tzCor= " + Config.tzCorrection); - } - else - Main.logToServer("tzCor WARNING"); - + Main.logToServer("Server.updateVdrStatus: tzCor= " + Config.tzCorrection); + Main.log("Server.updateVdrStatus: tzCor= " + Config.tzCorrection); } catch (e) { Main.log ("ERROR in tzCor (Old plugin?): " + e); } + var free = $(data).find('free').text() / 1024.0; // var used = $(data).find('used').text() / 1024.0; @@ -181,9 +209,44 @@ Server.fetchRecCmdsList = function() { }); }; +Server.fetchCmdsList = function() { + var url = Config.serverUrl + "/cmds.xml"; + $.ajax({ + url: url, + type : "GET", + success : function(data, status, XHR ) { + Main.logToServer("Server.fetchCmdsList Success Response - status= " + status + " mime= " + XHR.responseType + " data= "+ data); + + $(data).find("item").each(function () { + var title = $(this).text(); + var confirm = (($(this).attr("confirm") == "true") ? true : false); + var cmd = parseInt($(this).attr("cmd")); + + var title_list = title.split("~"); + RecCmds.addItem( title_list, {cmd : cmd, confirm: confirm }); + }); // each + +// RecCmds.dumpFolderStruct(); + RecCmds.completed(); + CmdHandler.createCmdOverlay(); + }, + error : function (jqXHR, status, error) { + Main.logToServer("Server.fetchCmdsList Error Response - status= " + status + " error= "+ error); + Display.showPopup("Error with XML File: " + status); + Main.changeState(0); + Main.enableKeys(); + }, + parsererror : function () { + Main.logToServer("Server.fetchCmdsList parserError " ); + Display.showPopup("Error in XML File"); + Main.changeState(0); + Main.enableKeys(); + } + }); +}; + + Server.getErrorText = function (status, input) { -// var errno_str = input.slice(0, 3); -// var errno = parseInt(errno_str, 10); var errno = Number(input.slice(0, 3)); var res = ""; @@ -360,6 +423,10 @@ Server.execRecCmd = function (cmd, guid) { var obj = new execRestCmd(RestCmds.CMD_ExecRecCmd, guid, { cmd:cmd }); }; +Server.execCmd = function (cmd) { + var obj = new execRestCmd(RestCmds.CMD_ExecCmd, 0, { cmd:cmd }); +}; + Server.deleteMedFile = function(guid) { var obj = new execRestCmd(RestCmds.CMD_DelMedFile, guid); }; @@ -379,9 +446,10 @@ var RestCmds = { CMD_GetResume : 5, CMD_GetRecCmds : 6, CMD_ExecRecCmd : 7, - CMD_ActTimer : 8, - CMD_DelTimer : 9, - CMD_UpdateEntry : 10 + CMD_ExecCmd : 8, + CMD_ActTimer : 9, + CMD_DelTimer : 10, + CMD_UpdateEntry : 11 }; @@ -594,10 +662,30 @@ function execRestCmd(cmd, guid, args) { this.parms.success = function(data, status, XHR ) { Main.logToServer("Server.execRecCmd OK" ) ; + Notify.showNotify("Ok.", true); Display.handleDescription(Main.selectedVideo); }; break; + case RestCmds.CMD_ExecCmd : + // Execute a command + + Main.logToServer("Server.execCmd cmd="+this.args.cmd); + + this.cmd = cmd; + this.parms.url = Config.serverUrl + "/execcmd?cmd="+this.args.cmd; + this.parms.type = "GET"; +// this.parms.timeout = 500; + + this.parms.success = function(data, status, XHR ) { + Main.logToServer("Server.execCmd OK" ) ; + //TODO: What to do on success? +// Display.handleDescription(Main.selectedVideo); + Notify.showNotify("Ok.", true); + Main.changeState(0); + }; + break; + case RestCmds.CMD_ActTimer : // Activate or Deactivate a timer diff --git a/smarttv-client/Javascript/Timers.js b/smarttv-client/Javascript/Timers.js index a90eedf..742f5f0 100644 --- a/smarttv-client/Javascript/Timers.js +++ b/smarttv-client/Javascript/Timers.js @@ -148,7 +148,7 @@ Timers.createMenu= function () { }; Timers.getPrintDate = function (day) { - var d = new Date (day * 1000); + var d = new MyDate (day * 1000); return d.getDate() + "." + (d.getMonth() +1) + "." + d.getFullYear(); }; diff --git a/smarttv-client/Javascript/Urls.js b/smarttv-client/Javascript/Urls.js index 3df8f3e..79dda05 100644 --- a/smarttv-client/Javascript/Urls.js +++ b/smarttv-client/Javascript/Urls.js @@ -1,3 +1,28 @@ +/* +function onYouTubePlayerReady(playerId) { + Yt.ytPlyr = document.getElementById(playerId); + + Main.debug("onYouTubePlayerReady() playerId: " + playerId + ", player: " + Main.ytPlyr); + player.addEventListener("onStateChange", "onPlayerStateChange"); + player.addEventListener("onError", "onPlayerError"); + player.setSize(960, 540); +// player.cueVideoById(videoId); + //player.loadVideoById(videoId); + +}; + +var Yt = { + ytPlyr : null +}; +Yt.onPlayerError= function (error) { + +}; + +Yt.onPlayerStateChange = function (state) { + +}; +*/ + var UrlsFetcher = { qualities : {17 : "144p", 36 : "240p", 18 : "360p", 22 : "720p", 37 : "1080p" }, preference : [36, 18, 22, 37], diff --git a/smarttv-client/config.xml b/smarttv-client/config.xml index 0ed982b..cd046ad 100755 --- a/smarttv-client/config.xml +++ b/smarttv-client/config.xml @@ -9,10 +9,11 @@ Images/icon/SmartTvWeb_115.png Images/icon/SmartTvWeb_85.png Images/icon/SmartTvWeb_95.png - 0.95 + 1.00.0 y y + y y n n diff --git a/smarttv-client/index.html b/smarttv-client/index.html index 6760353..1032638 100755 --- a/smarttv-client/index.html +++ b/smarttv-client/index.html @@ -51,6 +51,7 @@ + @@ -176,7 +177,7 @@
- +
-- cgit v1.2.3