[hbbtv/youtubetv] fixed volume control bug.
[vuplus_dvbapp] / lib / python / Plugins / Extensions / HbbTV / plugin.py
index ddeb2cb..70a2ec3 100644 (file)
@@ -20,7 +20,7 @@ from Components.Label import Label, MultiColorLabel
 from Components.ConfigList import ConfigListScreen
 from Components.VolumeControl import VolumeControl
 from Components.Pixmap import Pixmap
-from Components.config import config, ConfigSubsection, ConfigPosition, getConfigListEntry, ConfigBoolean, ConfigInteger, ConfigText, ConfigSelection, configfile, getCharValue
+from Components.config import config, ConfigYesNo, ConfigSubsection, ConfigPosition, getConfigListEntry, ConfigBoolean, ConfigInteger, ConfigText, ConfigSelection, configfile
 
 from enigma import eTimer, eConsoleAppContainer, getDesktop, eServiceReference, iPlayableService, iServiceInformation, RT_HALIGN_LEFT, RT_HALIGN_RIGHT, RT_HALIGN_CENTER, RT_VALIGN_CENTER, getPrevAsciiCode, eRCInput, fbClass, eServiceCenter
 
@@ -171,54 +171,6 @@ def _pack(opcode, params=None, reserved=0):
        packed_data = struct.pack(h, m, opcode, len(params), reserved)
        return packed_data + params
 
-class MMSStreamURL:
-       headers = [
-                   'GET %s HTTP/1.0'
-                  ,'Accept: */* '
-                  ,'User-Agent: NSPlayer/7.10.0.3059 '
-                  ,'Host: %s '
-                  ,'Connection: Close '
-                 ]
-
-       def __init__(self):
-               self.sendmsg = ''
-               for m in self.headers:
-                       self.sendmsg += m + '\n'
-               self.sendmsg += '\n\n'
-
-       def request(self, host, port=80, location='/'):
-               sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
-               sock.connect((host, port))
-               sock.send(self.sendmsg%(location, host))
-               print "Request."
-               print self.sendmsg%(location, host)
-               fullydata = ''
-               while 1:
-                       res = sock.recv(1024)
-                       if res == '': break
-                       fullydata += res
-               sock.close()
-               return fullydata
-
-       def parse(self, data):
-               for d in data.splitlines():
-                       if d.startswith('Location: '):
-                               return d[9:]
-               return None
-
-       def getLocationData(self, url):
-               url_list,host,location = None,None,None
-               try:
-                       url = url[url.find(':')+3:]
-                       url_list = url.split('/')
-                       host = url_list[0]
-                       location = url[len(url_list[0]):]
-               except Exception, err_msg:
-                       print err_msg
-                       return None
-               html = self.request(host=host, location=location)
-               return self.parse(html)
-
 class OpCodeSet:
        def __init__(self):
                self._opcode_ = {
@@ -254,8 +206,12 @@ class OpCodeSet:
                        ,"OP_BROWSER_NEED_RELOAD_KEYMAP": 0x0313
                        ,"OP_DVBAPP_VOL_UP"             : 0x0401
                        ,"OP_DVBAPP_VOL_DOWN"           : 0x0402
+                       ,"OP_DVBAPP_SET_VOL"            : 0x0403
                        ,"OP_SYSTEM_OUT_OF_MEMORY"      : 0x0501
                        ,"OP_SYSTEM_NOTIFY_MY_PID"      : 0x0502
+                       ,"OP_VIDEOBACKEND_ENABLE"       : 0x0601
+                       ,"OP_VIDEOBACKEND_DISABLE"      : 0x0602
+                       ,"OP_BROWSER_OPEN_YOUTUBETV"    : 0x0603
                }
                self._opstr_ = {
                         0x0000 : "OP_UNKNOWN"
@@ -290,8 +246,12 @@ class OpCodeSet:
                        ,0x0313 : "OP_BROWSER_NEED_RELOAD_KEYMAP"
                        ,0x0401 : "OP_DVBAPP_VOL_UP"
                        ,0x0402 : "OP_DVBAPP_VOL_DOWN"
+                       ,0x0403 : "OP_DVBAPP_SET_VOL"
                        ,0x0501 : "OP_SYSTEM_OUT_OF_MEMORY"
                        ,0x0502 : "OP_SYSTEM_NOTIFY_MY_PID"
+                       ,0x0601 : "OP_VIDEOBACKEND_ENABLE"
+                       ,0x0602 : "OP_VIDEOBACKEND_DISABLE"
+                       ,0x0603 : "OP_BROWSER_OPEN_YOUTUBETV"
                }
 
        def get(self, opstr):
@@ -499,6 +459,7 @@ class HandlerHbbTV(Handler):
                        ,0x0204 : self._cb_handleVODPlayerPlayPause
                        ,0x0401 : self._cb_handleDVBAppVolUp
                        ,0x0402 : self._cb_handleDVBAppVolDown
+                       ,0x0403 : self._cb_handleDVBAppSetVol
                        ,0x0208 : self._cb_handleVODSpeedCtrl
                        ,0x0209 : self._cb_handleVODSeekCtrl
                        ,0x0501 : self._cb_handleSystemOutOfMemory
@@ -506,6 +467,8 @@ class HandlerHbbTV(Handler):
                        ,0x0309 : self._cb_handleShowVirtualKeyboard
                        ,0x030B : self._cb_handlePasteVirtualKeyboard
                        ,0x030E : self._cb_handleBrowserMenuReq
+                       ,0x0601 : self._cb_handleVideobackendEnable
+                       ,0x0602 : self._cb_handleVideobackendDisable
                }
                self._on_close_cb = None
                self._on_set_title_cb = None
@@ -516,6 +479,8 @@ class HandlerHbbTV(Handler):
                self._timer_retry_open = eTimer()
                self._timer_paste_vkbd = eTimer()
                self._curren_title = None
+               self._max_volume  = -1
+               self._soft_volume = -1
 
        def _handle_dump(self, handle, opcode, data=None):
                if True: return
@@ -553,6 +518,20 @@ class HandlerHbbTV(Handler):
                self._on_set_title_cb = None
                return self.doPack(opcode, params, reserved)
 
+       def _cb_handleVideobackendEnable(self, opcode, data):
+               self._handle_dump(self._cb_handleVideobackendEnable, opcode, data)
+               service = self._session.nav.getCurrentlyPlayingServiceReference()
+               setBeforeService(service)
+               self._session.nav.stopService()
+               return (0, "OK")
+
+       def _cb_handleVideobackendDisable(self, opcode, data):
+               self._handle_dump(self._cb_handleVideobackendDisable, opcode, data)
+               before_service = getBeforeService()
+               if before_service is not None:
+                       self._session.nav.playService(before_service)
+               return (0, "OK")
+
        def _cb_handleHbbTVChangeChannel(self, opcode, data):
                self._handle_dump(self._cb_handleHbbTVChangeChannel, opcode, data)
                global _g_helper
@@ -567,7 +546,7 @@ class HandlerHbbTV(Handler):
 
        def _cb_handleBrowserMenuReq(self, opcode, data):
                self._handle_dump(self._cb_handleBrowserMenuReq, opcode, data)
-               restoreResolution()
+               #restoreResolution()
                fbClass.getInstance().unlock()
                eRCInput.getInstance().unlock()
                browser = getPluginBrowser()
@@ -611,12 +590,13 @@ class HandlerHbbTV(Handler):
        def _cb_virtualKeyboardClosed(self, data=None):
                fbClass.getInstance().lock()
                eRCInput.getInstance().lock()
-               setResolution(1280, 720)
+               #setResolution(1280, 720)
                command_util = getCommandUtil()
                command_util.sendCommand('OP_BROWSER_VKBD_RES', data)
+
        def _cb_handleShowVirtualKeyboard(self, opcode, data):
                self._handle_dump(self._cb_handleShowVirtualKeyboard, opcode, data)
-               restoreResolution()
+               #restoreResolution()
                fbClass.getInstance().unlock()
                eRCInput.getInstance().unlock()
                if data == 0 or strIsEmpty(data):
@@ -681,16 +661,41 @@ class HandlerHbbTV(Handler):
                        raise Exception("This stream is not support trick play.")
                return (0, "OK")
 
+       def SetVolume(self, volume):
+               if self._max_volume < 0:
+                       self._max_volume = VolumeControl.instance.volctrl.getVolume()
+
+               self._max_volume += volume
+               if self._max_volume > 100:
+                       self._max_volume = 100
+               elif self._max_volume < 0:
+                       self._max_volume = 0
+
+               if self._soft_volume > 0:
+                       v = int((self._max_volume * self._soft_volume) / 100)
+                       VolumeControl.instance.volctrl.setVolume(v, v)
+               else:   VolumeControl.instance.volctrl.setVolume(self._max_volume, self._max_volume)
+
        def _cb_handleDVBAppVolUp(self, opcode, data):
                self._handle_dump(self._cb_handleDVBAppVolUp, opcode, data)
-               vcm = VolumeControl.instance
-               vcm.volUp()
+               self.SetVolume(5)
                return (0, "OK")
 
        def _cb_handleDVBAppVolDown(self, opcode, data):
                self._handle_dump(self._cb_handleDVBAppVolDown, opcode, data)
-               vcm = VolumeControl.instance
-               vcm.volDown()
+               self.SetVolume(-5)
+               return (0, "OK")
+
+       def _cb_handleDVBAppSetVol(self, opcode, data):
+               self._handle_dump(self._cb_handleDVBAppSetVol, opcode, data)
+               if self._max_volume < 0:
+                       self._max_volume = VolumeControl.instance.volctrl.getVolume()
+               self._soft_volume = int(data)
+
+               v = 0
+               if self._soft_volume > 0 and self._max_volume > 0:
+                       v = int((self._max_volume * self._soft_volume) / 100)
+               VolumeControl.instance.volctrl.setVolume(v, v)
                return (0, "OK")
 
        def _cb_handleGetChannelInfoForUrl(self, opcode, data):
@@ -749,7 +754,7 @@ class HandlerHbbTV(Handler):
                        self._session.nav.playService(before_service)
                        self._vod_uri = None
 
-               restoreResolution()
+               #restoreResolution()
                return (0, "OK")
 
        def _cb_handleVODPlayerURI(self, opcode, data):
@@ -780,7 +785,8 @@ class HandlerHbbTV(Handler):
                for ii in range(5):
                        self._vod_service = None
                        try:
-                               print "Try to open vod [%d] : %s" % (ii, url)
+                               #print "Try to open vod [%d] : %s" % (ii, url)
+                               print "Try to open vod"
                                self._vod_service = eServiceReference(4097, 0, url)
                                self._session.nav.playService(self._vod_service)
                                if self._vod_service is not None:
@@ -832,7 +838,6 @@ class HbbTVWindow(Screen, InfoBarNotifications):
                Screen.__init__(self, session)
                InfoBarNotifications.__init__(self)
                self.__event_tracker = ServiceEventTracker(screen = self, eventmap = {
-                       iPlayableService.evUser+20: self._serviceForbiden,
                        iPlayableService.evStart: self._serviceStarted,
                        iPlayableService.evEOF: self._serviceEOF,
                })
@@ -867,8 +872,9 @@ class HbbTVWindow(Screen, InfoBarNotifications):
                        seek = service and service.seek()
                        l = seek.getLength()
                        p = seek.getPlayPosition()
-                       #return (p[1]/90000, l[1]/90000)
-                       return (p[1], l[1])
+                       if(not l[0] and not p[0]):
+                               return (p[1], l[1])
+                       return (90000,90000)
                except: pass
                return (-1,-1)
 
@@ -902,6 +908,8 @@ class HbbTVWindow(Screen, InfoBarNotifications):
                self._currentServicePositionTimer.stop()
 
        def _layoutFinished(self):
+               global __gval__
+               __gval__.hbbtv_handelr._soft_volume = -1
                self.setTitle(_('HbbTV Plugin'))
                command_util = getCommandUtil()
                profile = self._profile
@@ -939,30 +947,22 @@ class HbbTVWindow(Screen, InfoBarNotifications):
                eRCInput.getInstance().unlock()
                self.close()
 
-       def _serviceForbiden(self):
-               global __gval__
-               real_url = MMSStreamURL().getLocationData(__gval__.hbbtv_handelr.getUrl())
-               print "Received URI :\n", real_url
-
-               if real_url is not None:
-                       __gval__.hbbtv_handelr.doRetryOpen(real_url.strip())
-
        def _cb_set_page_title(self, title=None):
                print "page title :",title
                if title is None:
                        return
                self.setTitle(title)
 
-class HbbTVHelper(Screen):
+class HbbTVHelper(Screen, InfoBarNotifications):
        skin =  """<screen name="HbbTVHelper" position="0,0" size="0,0" backgroundColor="transparent" flags="wfNoBorder" title=" "></screen>"""
        def __init__(self, session):
                global __gval__
                __gval__.hbbtv_handelr = HandlerHbbTV(session)
                __gval__.command_server = ServerFactory().doListenUnixTCP('/tmp/.sock.hbbtv.url', __gval__.hbbtv_handelr)
 
-               self._urls = None
-
                Screen.__init__(self, session)
+               InfoBarNotifications.__init__(self)
+
                self._session = session
 
                self._restart_opera()
@@ -983,20 +983,39 @@ class HbbTVHelper(Screen):
 
                self._callbackStartStop = None
 
+               self.__et = ServiceEventTracker(screen=self, eventmap={
+                               iPlayableService.evHBBTVInfo: self._cb_detectedAIT,
+                               iPlayableService.evUpdatedInfo: self._cb_updateInfo
+                       })
+               self._applicationList = None
+
+               self.mVuplusBox = False
+               issue = open("/etc/issue").read()
+               if(issue.startswith("Vuplus")):
+                       self.mVuplusBox = True
+
+       def _cb_detectedAIT(self):
+               name = self._cb_ready_for_ait()
+               if name is not None and self.mVuplusBox:
+                       from Screens.InfoBarGenerics import gHbbtvApplication
+                       gHbbtvApplication.setApplicationName(str(name))
+
+       def _cb_updateInfo(self):
+               if not self._excuted_browser:
+                       command_util = getCommandUtil()
+                       command_util.sendCommand('OP_HBBTV_UNLOAD_AIT')
+               if self.mVuplusBox:
+                       from Screens.InfoBarGenerics import gHbbtvApplication
+                       gHbbtvApplication.setApplicationName("")
+               #self._applicationList = None
+
        def _cb_registrate_infobar(self):
                if InfoBar.instance:
                        self._timer_infobar.stop()
-                       if self._cb_ready_for_ait not in InfoBar.instance.onReadyForAIT:
-                               InfoBar.instance.onReadyForAIT.append(self._cb_ready_for_ait)
                        if self._cb_hbbtv_activated not in InfoBar.instance.onHBBTVActivation:
                                InfoBar.instance.onHBBTVActivation.append(self._cb_hbbtv_activated)
 
-       def _cb_ready_for_ait(self, orgId=0):
-               if orgId == 0:
-                       if not self._excuted_browser:
-                               command_util = getCommandUtil()
-                               command_util.sendCommand('OP_HBBTV_UNLOAD_AIT')
-                       return
+       def _cb_ready_for_ait(self):
                setChannelInfo(None, None, None, None, None)
 
                service = self._session.nav.getCurrentService()
@@ -1008,13 +1027,25 @@ class HbbTVHelper(Screen):
                        name = info.getName()
                        if name is None:
                                name = ""
-                       orgid   = 0
-                       namelen = len(name)
-                       for x in info.getInfoObject(iServiceInformation.sHBBTVUrl):
-                               if x[0] in (1, -1) :
-                                       orgid = x[3]
-                                       break
-                       setChannelInfo(sid, onid, tsid, name, orgid)
+
+                       pmtid = info.getInfo(iServiceInformation.sPMTPID)
+                       demux = info.getInfoString(iServiceInformation.sLiveStreamDemuxId)
+
+                       from aitreader import eAITSectionReader
+                       reader = eAITSectionReader(demux, pmtid, sid)
+                       if reader.doOpen(info, self.mVuplusBox):
+                               reader.doParseApplications()
+                               reader.doDump()
+                       else:   print "no data!!"
+
+                       try:
+                               self._applicationList = reader.getApplicationList()
+                               if len(self._applicationList) > 0:
+                                       orgid = int(self._applicationList[0]["orgid"])
+                                       setChannelInfo(sid, onid, tsid, name, orgid)
+                                       return self._applicationList[0]["name"]
+                       except: pass
+               return None
 
        def _cb_hbbtv_activated(self, title=None, url=None):
                if not self._is_browser_running():
@@ -1043,9 +1074,9 @@ class HbbTVHelper(Screen):
                        time.sleep(2)
                        setNeedRestart(False)
 
-               for x in self._urls:
-                       control_code = x[0]
-                       tmp_url = x[2]
+               for x in self._applicationList:
+                       control_code = int(x["control"])
+                       tmp_url = x["url"]
                        if tmp_url == url and control_code == 1:
                                use_ait = True
                self._excuted_browser = True
@@ -1057,7 +1088,8 @@ class HbbTVHelper(Screen):
        def _start_opera(self):
                if not self._is_browser_running():
                        global HBBTVAPP_PATH
-                       start_command = '%s/launcher start'%(HBBTVAPP_PATH)
+                       global __gval__
+                       start_command = '%s/launcher start %d %d'%(HBBTVAPP_PATH, __gval__.resX, __gval__.resY)
                        os.system(start_command)
                return True
 
@@ -1068,21 +1100,19 @@ class HbbTVHelper(Screen):
 
        def _restart_opera(self):
                global HBBTVAPP_PATH
-               try:    os.system('%s/launcher restart'%(HBBTVAPP_PATH))
+               global __gval__
+               try:    os.system('%s/launcher restart %d %d'%(HBBTVAPP_PATH, __gval__.resX, __gval__.resY))
                except: pass
                return True
 
        def getStartHbbTVUrl(self):
-               url, self._urls, self._profile = None, None, 0
-                service = self._session.nav.getCurrentService()
-                info = service and service.info()
-                if not info: return None
-                self._urls = info.getInfoObject(iServiceInformation.sHBBTVUrl)
-               for u in self._urls:
-                       if u[0] in (1, -1): # 0:control code, 1:name, 2:url, 3:orgid, 4:appid, 5:profile code
-                               url = u[2]
-                               self._profile = u[5]
+               url, self._profile = None, 0
+               if self._applicationList is not None:
+                       self._profile = self._applicationList[0]["profile"]
+                       url = self._applicationList[0]["url"]
                if url is None:
+                       service = self._session.nav.getCurrentService()
+                       info = service and service.info()
                        url = info.getInfoString(iServiceInformation.sHBBTVUrl)
                return url
 
@@ -1090,15 +1120,16 @@ class HbbTVHelper(Screen):
                applications = []
 
                if self.getStartHbbTVUrl():
-                       for x in self._urls:
-                               applications.append((x[1], x))
+                       for x in self._applicationList:
+                               applications.append((x["name"], x))
                else: applications.append((_("No detected HbbTV applications."), None))
                self._session.openWithCallback(self._application_selected, ChoiceBox, title=_("Please choose an HbbTV application."), list=applications)
 
        def _application_selected(self, selected):
+               print selected
                try:
                        if selected[1] is None: return
-                       self._cb_hbbtv_activated(selected[1][1], selected[1][2])
+                       self._cb_hbbtv_activated(selected[1]["name"], selected[1]["url"])
                except Exception, ErrMsg: print ErrMsg
 
        def showBrowserConfigBox(self, callback=None):
@@ -1789,7 +1820,7 @@ class OperaBrowser(Screen):
 
        COMMAND_MAP = {}
        MENUITEMS_LIST =[]
-       def __init__(self, session, url=None):
+       def __init__(self, session, url=None, isWebAppMode=False):
                Screen.__init__(self, session)
                self["actions"] = ActionMap(["DirectionActions", "MenuActions", "OkCancelActions"], {
                         "cancel"      : self.keyCancel
@@ -1832,6 +1863,7 @@ class OperaBrowser(Screen):
                self._onCloseTimer.callback.append(self._cb_onClose)
 
                self.paramUrl = url
+               self.paramIsWebAppMode = isWebAppMode
                language.addCallback(self.UpdateLanguageCB)
 
        def UpdateLanguageCB(self):
@@ -1870,7 +1902,9 @@ class OperaBrowser(Screen):
 
                if self.paramUrl is not None:
                        self.keyMenu()
-                       self.cbUrlText(self.paramUrl, 1)
+                       if self.paramIsWebAppMode:
+                               self.cbUrlText(data=self.paramUrl, mode=1, opcode='OP_BROWSER_OPEN_YOUTUBETV')
+                       else:   self.cbUrlText(data=self.paramUrl, mode=1)
 
        def selectMenuitem(self):
                tmp = [self["menuitemFile"], self["menuitemTool"], self["menuitemHelp"]]# modify menu
@@ -1961,7 +1995,7 @@ class OperaBrowser(Screen):
                        return
                self.setTitle(title)
 
-       def cbUrlText(self, data=None, mode=0):
+       def cbUrlText(self, data=None, mode=0, opcode='OP_BROWSER_OPEN_URL'):
                global _g_helper
                if not _g_helper._is_browser_running():
                        return
@@ -1980,13 +2014,16 @@ class OperaBrowser(Screen):
                fbClass.getInstance().lock()
                eRCInput.getInstance().lock()
 
-               setResolution(1280, 720)
+               #setResolution(1280, 720)
 
                command_util = getCommandUtil()
-               command_util.sendCommand('OP_BROWSER_OPEN_URL', data, mode)
+               command_util.sendCommand(opcode, data, mode)
                self._terminatedBrowser = False
                self._enableKeyEvent = False
 
+               global __gval__
+               __gval__.hbbtv_handelr._soft_volume = -1
+
        def _on_close_window(self):
                self._onCloseTimer.start(1000)
 
@@ -2145,7 +2182,7 @@ class OperaBrowser(Screen):
                        #self._session.openWithCallback(self._cb_virtualKeyboardClosed, VirtualKeyBoard, title=("Please enter URL here"), text="")
                        fbClass.getInstance().lock()
                        eRCInput.getInstance().lock()
-                       setResolution(1280, 720)
+                       #setResolution(1280, 720)
                        if self.toggleListViewFlag:
                                self.toggleMainScreen()
                        self._currentPageUrl   = None
@@ -2174,6 +2211,153 @@ class OperaBrowser(Screen):
                self.currentListView.pageUp()
                self.keyUp()
 
+config.plugins.youtubetv = ConfigSubsection()
+config.plugins.youtubetv.showhelp = ConfigYesNo(default = False)
+config.plugins.youtubetv.uri = ConfigText(default = "http://www.youtube.com/tv", visible_width = 50, fixed_size = False)
+class YoutubeTVWindow(Screen, HelpableScreen):
+        skin = """
+                <screen name="YoutubeTVWindow" position="center,center" size="550,160" title="Start YouTube TV" >
+                       <widget name="infomation" position="5,0" size="540,80" valign="center" halign="center" font="Regular;20" />
+                       <widget name="startdesc" position="10,80" size="395,40" valign="center" font="Regular;20" />
+                       <widget name="helpdesc" position="10,120" size="395,40" valign="center" font="Regular;20" />
+                       <ePixmap pixmap="skin_default/buttons/green.png" position="400,80" size="140,40" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/yellow.png" position="400,120" size="140,40" alphatest="on" />
+                       <widget source="key_green" render="Label" position="400,80" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" foregroundColor="#ffffff" transparent="1" />
+                       <widget source="key_yellow" render="Label" position="400,120" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" foregroundColor="#ffffff" transparent="1" />
+                </screen>
+               """
+        def __init__(self, session):
+                Screen.__init__(self, session)
+               HelpableScreen.__init__(self)
+
+               self["actions"] = ActionMap(["WizardActions", "DirectionActions", "OkCancelActions","ColorActions", "EPGSelectActions",], {
+                               "cancel": self.keyCancel,
+                               "red"   : self.keyCancel,
+                               "green" : self.keyGreen,
+                               "yellow": self.keyYellow,
+                       },-2)
+
+               self["key_green"]  = StaticText(_("Start"))
+               self["key_yellow"] = StaticText(_("Help"))
+
+               self["infomation"] = Label()
+               self["startdesc"]  = Label()
+               self["helpdesc"]   = Label()
+
+               self.onLayoutFinish.append(self.layoutFinished)
+
+       def layoutFinished(self):
+               self.setTitle(_('Start YouTube TV'))
+               self["infomation"].setText(_("YouTube TV is a new way to watch YouTube videos on Vu+"))
+               self["startdesc" ].setText(_("* Start YouTube TV"))
+               self["helpdesc"  ].setText(_("* RC Help"))
+
+       def setHelpModeActions(self):
+               self.helpList = []
+               self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions", {
+                       "ok"    : (self.keyPass, _("Play ther selected the video")),
+                       "cancel": (self.keyPass, _("Exit the YouTube TV")),
+               })
+               self["EventViewActions"] = HelpableActionMap(self, "EventViewActions", {
+                       "pageUp"    : (self.keyPass, _("Move up")),
+                       "pageDown"  : (self.keyPass, _("Move down")),
+                       "prevEvent" : (self.keyPass, _("Move left")),
+                       "nextEvent" : (self.keyPass, _("Move right")),
+               })
+               self["EPGSelectActions"] = HelpableActionMap(self, "EPGSelectActions", {
+                       "info"        : (self.keyPass, _("Search a video")),
+                       "nextService" : (self.keyPass, _("Skip forward 10 sec")),
+                       "prevService" : (self.keyPass, _("Skip backward 10 sec")),
+               })
+               self["MediaPlayerActions"] = HelpableActionMap(self, "MediaPlayerActions", {
+                       "play"  : (self.keyPass, _("Play current video")),
+                       "pause" : (self.keyPass, _("Pause current video")),
+                       "stop"  : (self.keyPass, _("Stop current video")),
+               })
+               self["ColorActions"] = HelpableActionMap(self, "ColorActions", {
+                       "red"   : (self.keyPass, _("Back")),
+               })
+               self.showHelp()
+
+       def keyPass(self):
+               pass
+       def keyCancel(self):
+               config.plugins.youtubetv.showhelp.cancel()
+               self.close(False)
+       def keyGreen(self):
+               config.plugins.youtubetv.showhelp.save()
+               config.plugins.youtubetv.save()
+               config.plugins.save()
+               self.close(True)
+       def keyYellow(self):
+               self.setHelpModeActions()
+       def keyBlue(self):
+               if config.plugins.youtubetv.showhelp.value == True :
+                       config.plugins.youtubetv.showhelp.setValue(False)
+               else:   config.plugins.youtubetv.showhelp.setValue(True)
+
+class YoutubeTVSettings(ConfigListScreen, Screen):
+    skin=   """
+       <screen position="center,center" size="600,140" title="YouTube TV Settings">
+           <widget name="config" position="0,0" size="600,100" scrollbarMode="showOnDemand" />
+
+           <ePixmap pixmap="skin_default/buttons/red.png" position="310,100" size="140,40" alphatest="on" />
+           <ePixmap pixmap="skin_default/buttons/green.png" position="150,100" size="140,40" alphatest="on" />
+
+           <widget source="key_red" render="Label" position="310,100" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" foregroundColor="#ffffff" transparent="1" />
+           <widget source="key_green" render="Label" position="150,100" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" foregroundColor="#ffffff" transparent="1" />
+       </screen>
+       """
+    def __init__(self, session):
+       self.session = session
+       Screen.__init__(self, session)
+
+       self.menulist = []
+       ConfigListScreen.__init__(self, self.menulist)
+
+       self["actions"] = ActionMap(["OkCancelActions", "ColorActions",], {
+           "ok"     : self.keyGreen,
+           "green"  : self.keyGreen,
+           "red"    : self.keyRed,
+           "cancel" : self.keyRed,
+               }, -2)
+
+       self["key_red"]   = StaticText(_("Cancel"))
+       self["key_green"] = StaticText(_("Save"))
+
+       self.makeConfigList()
+       self.onLayoutFinish.append(self.layoutFinished)
+
+    def layoutFinished(self):
+       self.setTitle(_('YouTube TV Settings'))
+
+    def keyGreen(self):
+       config.plugins.youtubetv.showhelp.save()
+       config.plugins.youtubetv.uri.save()
+       config.plugins.youtubetv.save()
+       config.plugins.save()
+       self.close()
+    def keyRed(self):
+       config.plugins.youtubetv.showhelp.cancel()
+       config.plugins.youtubetv.uri.cancel()
+       self.close()
+
+    def keyLeft(self):
+       ConfigListScreen.keyLeft(self)
+
+    def keyRight(self):
+       ConfigListScreen.keyRight(self)
+
+    def makeConfigList(self):
+       self.menulist = []
+       entryUri = getConfigListEntry(_("YouTube TV URL"), config.plugins.youtubetv.uri)
+       entryShowHelp = getConfigListEntry(_("Do not show YouTube TV Stater again"), config.plugins.youtubetv.showhelp)
+       self.menulist.append(entryUri)
+       self.menulist.append(entryShowHelp)
+
+       self["config"].list = self.menulist
+       self["config"].l.setList(self.menulist)
+
 def auto_start_main(reason, **kwargs):
        if reason:
                command_server = getCommandServer()
@@ -2225,6 +2409,44 @@ def showManual(self):
                _g_clearBrowserDataTimer.start(50)
        setPluginBrowser(self.session.openWithCallback(clearBrowserData, OperaBrowser, url))
 
+_g_backupSession = None
+def showYoutubeTV(session, **kwargs):
+       def _do_clean():
+               _g_clearBrowserDataTimer.stop()
+               try:    _g_clearBrowserDataTimer.callback.remove(_do_clean)
+               except: pass
+               setPluginBrowser(None)
+               global _g_backupSession
+               
+               service = getBeforeService()
+               if service is not None:
+                       _g_backupSession.nav.playService(eServiceReference(service))
+                       _g_backupSession = None
+       def clearBrowserData():
+               _g_clearBrowserDataTimer.callback.append(_do_clean)
+               _g_clearBrowserDataTimer.start(50)
+       def cbYoutubeTVClose(ret):
+               if ret:
+                       global _g_backupSession
+                       _g_backupSession = session
+                       service = session.nav.getCurrentlyPlayingServiceReference()
+                       if service is not None:
+                               setBeforeService(service.toString())
+                               session.nav.stopService()
+                       else:   setBeforeService(service)
+                       setPluginBrowser(session.openWithCallback(clearBrowserData, OperaBrowser, config.plugins.youtubetv.uri.value, True))
+       if config.plugins.youtubetv.showhelp.value == True:
+               cbYoutubeTVClose(True)
+       else:   session.openWithCallback(cbYoutubeTVClose, YoutubeTVWindow)
+
+def youtube_setting_main(session, **kwargs):
+       session.open(YoutubeTVSettings)
+
+def start_menu_main(menuid, **kwargs):
+       if menuid == "mainmenu":
+               return [(_("YouTube TV"), showYoutubeTV, "youtube_tv", 46)]
+       return []
+
 def plugin_start_main(session, **kwargs):
        #session.open(OperaBrowser)
        def _do_clean():
@@ -2252,6 +2474,8 @@ def plugin_extension_browser_config(session, **kwargs):
 def Plugins(path, **kwargs):
        l = []
        l.append(PluginDescriptor(where=PluginDescriptor.WHERE_AUTOSTART, fnc=auto_start_main))
+       l.append(PluginDescriptor(name=_("YouTube TV"), where=PluginDescriptor.WHERE_MENU, fnc=start_menu_main))
+       l.append(PluginDescriptor(name=_("YouTube TV Settings"), where=PluginDescriptor.WHERE_PLUGINMENU, fnc=youtube_setting_main))
        l.append(PluginDescriptor(where=PluginDescriptor.WHERE_SESSIONSTART, needsRestart=True, fnc=session_start_main, weight=-10))
        l.append(PluginDescriptor(name=_("HbbTV Applications"), where=PluginDescriptor.WHERE_EXTENSIONSMENU, needsRestart=True, fnc=plugin_extension_start_application))
        l.append(PluginDescriptor(name=_("Browser Start/Stop"), where=PluginDescriptor.WHERE_EXTENSIONSMENU, needsRestart=True, fnc=plugin_extension_browser_config))