DreamMediathek Play Web and ipTV streams, example xml
authornixkoenner <nixkoenner@newnigma2.to>
Mon, 31 Jan 2011 20:34:36 +0000 (21:34 +0100)
committernixkoenner <nixkoenner@newnigma2.to>
Mon, 31 Jan 2011 20:34:36 +0000 (21:34 +0100)
dreammediathek/CONTROL/control [new file with mode: 0644]
dreammediathek/Makefile.am [new file with mode: 0644]
dreammediathek/src/LICENSE [new file with mode: 0644]
dreammediathek/src/Makefile.am [new file with mode: 0644]
dreammediathek/src/MoviePlayer.py [new file with mode: 0644]
dreammediathek/src/ServiceXML.py [new file with mode: 0644]
dreammediathek/src/__init__.py [new file with mode: 0644]
dreammediathek/src/maintainer.info [new file with mode: 0644]
dreammediathek/src/plugin.py [new file with mode: 0644]
dreammediathek/src/webtv_stations.xml [new file with mode: 0644]

diff --git a/dreammediathek/CONTROL/control b/dreammediathek/CONTROL/control
new file mode 100644 (file)
index 0000000..20a5b16
--- /dev/null
@@ -0,0 +1,6 @@
+Package: enigma2-plugin-extensions-dreammediathek
+Version: 20110131
+Description: Play rtp Stream on your Dreambox 
+Maintainer: nixkoenner@newnigma2.to
+Homepage: http://www.newnigma2.to
+Depends: enigma2 (>> 2.6git20090409), twisted-web
diff --git a/dreammediathek/Makefile.am b/dreammediathek/Makefile.am
new file mode 100644 (file)
index 0000000..af437a6
--- /dev/null
@@ -0,0 +1 @@
+SUBDIRS = src
diff --git a/dreammediathek/src/LICENSE b/dreammediathek/src/LICENSE
new file mode 100644 (file)
index 0000000..b81fd7d
--- /dev/null
@@ -0,0 +1,12 @@
+All Files of this Software are licensed under the Creative Commons 
+Attribution-NonCommercial-ShareAlike 3.0 Unported 
+License if not stated otherwise in a files head. To view a copy of this license, visit
+http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to Creative
+Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
+
+Alternatively, this plugin may be distributed and executed on hardware which
+is licensed by Dream Multimedia GmbH.
+
+This plugin is NOT free software. It is open source, you are allowed to
+modify it (if you keep the license), but it may not be commercially 
+distributed other than under the conditions noted above.
diff --git a/dreammediathek/src/Makefile.am b/dreammediathek/src/Makefile.am
new file mode 100644 (file)
index 0000000..6b4e937
--- /dev/null
@@ -0,0 +1,3 @@
+installdir = $(libdir)/enigma2/python/Plugins/Extensions/dreamMediathek
+install_PYTHON = *.py
+install_DATA = *.png LICENSE maintainer.info *.xml
diff --git a/dreammediathek/src/MoviePlayer.py b/dreammediathek/src/MoviePlayer.py
new file mode 100644 (file)
index 0000000..2738ddd
--- /dev/null
@@ -0,0 +1,311 @@
+# -*- coding: UTF-8 -*-
+from Plugins.Plugin import PluginDescriptor
+from Tools.BoundFunction import boundFunction
+from Screens.MessageBox import MessageBox
+from Screens.Screen import Screen
+from Screens.ChoiceBox import ChoiceBox
+from Components.ActionMap import ActionMap, NumberActionMap
+from Components.Sources.StaticText import StaticText
+from Components.Sources.List import List
+from Components.AVSwitch import AVSwitch
+from Components.config import config, Config, ConfigSelection, ConfigSubsection, ConfigText, getConfigListEntry, ConfigYesNo, ConfigIP, ConfigNumber,ConfigLocations
+from Components.config import KEY_DELETE, KEY_BACKSPACE, KEY_LEFT, KEY_RIGHT, KEY_HOME, KEY_END, KEY_TOGGLEOW, KEY_ASCII, KEY_TIMEOUT
+from Components.ConfigList import ConfigListScreen
+from Components.ServiceEventTracker import ServiceEventTracker, InfoBarBase
+
+from Tools.Directories import pathExists, fileExists, resolveFilename, SCOPE_PLUGINS, SCOPE_SKIN_IMAGE, SCOPE_HDD, SCOPE_CURRENT_PLUGIN, SCOPE_CURRENT_SKIN
+from Tools.LoadPixmap import LoadPixmap
+from enigma import eTimer, quitMainloop,eListbox,ePoint, RT_HALIGN_LEFT, RT_HALIGN_RIGHT, RT_VALIGN_CENTER, eListboxPythonMultiContent, eListbox, gFont, getDesktop, ePicLoad, eServiceCenter, iServiceInformation, eServiceReference,iSeekableService,iServiceInformation, iPlayableService, iPlayableServicePtr
+from os import path as os_path, system as os_system, unlink, stat, mkdir, popen, makedirs, listdir, access, rename, remove, W_OK, R_OK, F_OK
+from twisted.web import client
+from twisted.internet import reactor
+from time import time
+
+from Screens.InfoBarGenerics import InfoBarShowHide, InfoBarSeek, InfoBarNotifications, InfoBarServiceNotifications
+
+from ServiceXML import iWebTVStations
+
+config.plugins.dreamMediathek = ConfigSubsection()
+config.plugins.dreamMediathek.general = ConfigSubsection()
+config.plugins.dreamMediathek.general.on_movie_stop = ConfigSelection(default = "ask", choices = [
+       ("ask", _("Ask user")), ("quit", _("Return to movie list")), ("playnext", _("Play next video")), ("playagain", _("Play video again")) ])
+config.plugins.dreamMediathek.general.on_exit = ConfigSelection(default = "ask", choices = [
+       ("ask", _("Ask user")), ("quit", _("Return to movie list"))])
+
+
+class dreamMediathekPlayer(Screen, InfoBarNotifications):
+       STATE_IDLE = 0
+       STATE_PLAYING = 1
+       STATE_PAUSED = 2
+       ENABLE_RESUME_SUPPORT = True
+       ALLOW_SUSPEND = True
+
+       skin = """<screen name="dreamMediathekPlayer" flags="wfNoBorder" position="0,380" size="720,160" title="dreamMediathekPlayer" backgroundColor="transparent">
+               <ePixmap position="0,0" pixmap="skin_default/info-bg_mp.png" zPosition="-1" size="720,160" />
+               <ePixmap position="29,40" pixmap="skin_default/screws_mp.png" size="665,104" alphatest="on" />
+               <ePixmap position="48,70" pixmap="skin_default/icons/mp_buttons.png" size="108,13" alphatest="on" />
+               <ePixmap pixmap="skin_default/icons/icon_event.png" position="207,78" size="15,10" alphatest="on" />
+               <widget source="session.CurrentService" render="Label" position="230,73" size="360,40" font="Regular;20" backgroundColor="#263c59" shadowColor="#1d354c" shadowOffset="-1,-1" transparent="1">
+                       <convert type="ServiceName">Name</convert>
+               </widget>
+               <widget source="session.CurrentService" render="Label" position="580,73" size="90,24" font="Regular;20" halign="right" backgroundColor="#4e5a74" transparent="1">
+                       <convert type="ServicePosition">Length</convert>
+               </widget>
+               <widget source="session.CurrentService" render="Label" position="205,129" size="100,20" font="Regular;18" halign="center" valign="center" backgroundColor="#06224f" shadowColor="#1d354c" shadowOffset="-1,-1" transparent="1">
+                       <convert type="ServicePosition">Position</convert>
+               </widget>
+               <widget source="session.CurrentService" render="PositionGauge" position="300,133" size="270,10" zPosition="2" pointer="skin_default/position_pointer.png:540,0" transparent="1" foregroundColor="#20224f">
+                       <convert type="ServicePosition">Gauge</convert>
+               </widget>
+               <widget source="session.CurrentService" render="Label" position="576,129" size="100,20" font="Regular;18" halign="center" valign="center" backgroundColor="#06224f" shadowColor="#1d354c" shadowOffset="-1,-1" transparent="1">
+                       <convert type="ServicePosition">Remaining</convert>
+               </widget>
+               </screen>"""
+
+       def __init__(self, session, service, lastservice, infoCallback = None, nextCallback = None, prevCallback = None):
+               Screen.__init__(self, session)
+               InfoBarNotifications.__init__(self)
+               self.session = session
+               self.service = service
+               self.infoCallback = infoCallback
+               self.nextCallback = nextCallback
+               self.prevCallback = prevCallback
+               self.screen_timeout = 5000
+               self.nextservice = None
+
+               print "evEOF=%d" % iPlayableService.evEOF
+               self.__event_tracker = ServiceEventTracker(screen = self, eventmap =
+                       {
+                               iPlayableService.evSeekableStatusChanged: self.__seekableStatusChanged,
+                               iPlayableService.evStart: self.__serviceStarted,
+                               iPlayableService.evEOF: self.__evEOF,
+                       })
+               
+               self["actions"] = ActionMap(["OkCancelActions", "InfobarSeekActions", "MediaPlayerActions", "MovieSelectionActions"],
+               {
+                               "ok": self.ok,
+                               "cancel": self.leavePlayer,
+                               "stop": self.leavePlayer,
+                               "playpauseService": self.playpauseService,
+                               "seekFwd": self.playNextFile,
+                               "seekBack": self.playPrevFile,
+                               "showEventInfo": self.showVideoInfo,
+                       }, -2)
+
+
+               self.lastservice = lastservice
+
+               self.hidetimer = eTimer()
+               self.hidetimer.timeout.get().append(self.ok)
+               self.returning = False
+
+               self.state = self.STATE_PLAYING
+               self.lastseekstate = self.STATE_PLAYING
+
+               self.onPlayStateChanged = [ ]
+               self.__seekableStatusChanged()
+       
+               self.play()
+               self.onClose.append(self.__onClose)
+               
+       def __onClose(self):
+               self.session.nav.stopService()
+
+       def __evEOF(self):
+               print "evEOF=%d" % iPlayableService.evEOF
+               print "Event EOF"
+               self.handleLeave(config.plugins.dreamMediathek.general.on_movie_stop.value)
+
+       def __setHideTimer(self):
+               self.hidetimer.start(self.screen_timeout)
+
+       def showInfobar(self):
+               self.show()
+               if self.state == self.STATE_PLAYING:
+                       self.__setHideTimer()
+               else:
+                       pass
+
+       def hideInfobar(self):
+               self.hide()
+               self.hidetimer.stop()
+
+       def ok(self):
+               if self.shown:
+                       self.hideInfobar()
+               else:
+                       self.showInfobar()
+
+       def showVideoInfo(self):
+               if self.shown:
+                       self.hideInfobar()
+               if self.infoCallback is not None:       
+                       self.infoCallback()
+
+
+       def playNextFile(self):
+               print "playNextFile"
+               if self.nextCallback() is not None:
+                       nextservice,error = self.nextCallback()
+                       print "nextservice--->",nextservice
+                       if nextservice is None:
+                               self.handleLeave(config.plugins.dreamMediathek.general.on_movie_stop.value, error)
+                       else:
+                               self.playService(nextservice)
+                               self.showInfobar()
+
+       def playPrevFile(self):
+               print "playPrevFile"
+               if self.prevCallback() is not None:
+                       prevservice,error = self.prevCallback()
+                       if prevservice is None:
+                               self.handleLeave(config.plugins.dreamMediathek.general.on_movie_stop.value, error)
+                       else:
+                               self.playService(prevservice)
+                               self.showInfobar()
+
+       def playagain(self):
+               print "playagain"
+               if self.state != self.STATE_IDLE:
+                       self.stopCurrent()
+               self.play()
+       
+       def playService(self, newservice):
+               if self.state != self.STATE_IDLE:
+                       self.stopCurrent()
+               self.service = newservice
+               self.play()
+
+       def play(self):
+               if self.state == self.STATE_PAUSED:
+                       if self.shown:
+                               self.__setHideTimer()   
+               self.state = self.STATE_PLAYING
+               self.session.nav.playService(self.service)
+               if self.shown:
+                       self.__setHideTimer()
+
+       def stopCurrent(self):
+               print "stopCurrent"
+               self.session.nav.stopService()
+               self.state = self.STATE_IDLE
+
+       def playpauseService(self):
+               print "playpauseService"
+               if self.state == self.STATE_PLAYING:
+                       self.pauseService()
+               elif self.state == self.STATE_PAUSED:
+                       self.unPauseService()
+
+       def pauseService(self):
+               print "pauseService"
+               if self.state == self.STATE_PLAYING:
+                       self.setSeekState(self.STATE_PAUSED)
+               
+       def unPauseService(self):
+               print "unPauseService"
+               if self.state == self.STATE_PAUSED:
+                       self.setSeekState(self.STATE_PLAYING)
+
+
+       def getSeek(self):
+               service = self.session.nav.getCurrentService()
+               if service is None:
+                       return None
+
+               seek = service.seek()
+
+               if seek is None or not seek.isCurrentlySeekable():
+                       return None
+
+               return seek
+
+       def isSeekable(self):
+               if self.getSeek() is None:
+                       return False
+               return True
+
+       def __seekableStatusChanged(self):
+               print "seekable status changed!"
+               if not self.isSeekable():
+                       self.setSeekState(self.STATE_PLAYING)
+               else:
+                       print "seekable"
+
+       def __serviceStarted(self):
+               self.state = self.STATE_PLAYING
+               self.__seekableStatusChanged()
+
+       def setSeekState(self, wantstate):
+               print "setSeekState"
+               if wantstate == self.STATE_PAUSED:
+                       print "trying to switch to Pause- state:",self.STATE_PAUSED
+               elif wantstate == self.STATE_PLAYING:
+                       print "trying to switch to playing- state:",self.STATE_PLAYING
+               service = self.session.nav.getCurrentService()
+               if service is None:
+                       print "No Service found"
+                       return False
+               pauseable = service.pause()
+               if pauseable is None:
+                       print "not pauseable."
+                       self.state = self.STATE_PLAYING
+
+               if pauseable is not None:
+                       print "service is pausable"
+                       if wantstate == self.STATE_PAUSED:
+                               print "WANT TO PAUSE"
+                               pauseable.pause()
+                               self.state = self.STATE_PAUSED
+                               if not self.shown:
+                                       self.hidetimer.stop()
+                                       self.show()
+                       elif wantstate == self.STATE_PLAYING:
+                               print "WANT TO PLAY"
+                               pauseable.unpause()
+                               self.state = self.STATE_PLAYING
+                               if self.shown:
+                                       self.__setHideTimer()
+
+               for c in self.onPlayStateChanged:
+                       c(self.state)
+               
+               return True
+
+       def handleLeave(self, how, error = False):
+               self.is_closing = True
+               if how == "ask":
+                       list = (
+                               (_("Yes"), "quit"),
+                               (_("No, but play video again"), "playagain"),
+                               (_("Yes, but play next video"), "playnext"),
+                               (_("Yes, but play previous video"), "playprev"),
+                       )
+                       if error is False:
+                               self.session.openWithCallback(self.leavePlayerConfirmed, ChoiceBox, title=_("Stop playing this movie?"), list = list)
+                       else:
+                               self.session.openWithCallback(self.leavePlayerConfirmed, ChoiceBox, title=_("No playable video found! Stop playing this movie?"), list = list)
+               else:
+                       self.leavePlayerConfirmed([True, how])
+
+       def leavePlayer(self):
+               self.handleLeave(config.plugins.dreamMediathek.general.on_movie_stop.value)
+
+       def leavePlayerConfirmed(self, answer):
+               answer = answer and answer[1]
+               if answer == "quit":
+                       self.close()
+               elif answer == "playnext":
+                       self.playNextFile()
+               elif answer == "playprev":
+                       self.playPrevFile()
+               elif answer == "playagain":
+                       self.playagain()
+                       
+       def doEofInternal(self, playing):
+               if not self.execing:
+                       return
+               if not playing :
+                       return
+               self.handleLeave(config.usage.on_movie_eof.value)
+
diff --git a/dreammediathek/src/ServiceXML.py b/dreammediathek/src/ServiceXML.py
new file mode 100644 (file)
index 0000000..aa5f247
--- /dev/null
@@ -0,0 +1,45 @@
+# -*- coding: utf-8 -*-
+from re import compile as re_compile
+from os import path as os_path, symlink, listdir, unlink, readlink, remove
+
+from xml.etree.cElementTree import parse as cet_parse
+from Tools.Directories import pathExists, fileExists, resolveFilename, SCOPE_PLUGINS, SCOPE_SKIN_IMAGE, SCOPE_HDD, SCOPE_CURRENT_PLUGIN, SCOPE_CURRENT_SKIN
+#WEBTV_STATIONS = "/etc/enigma2/webtv_stations.xml"
+WEBTV_STATIONS = resolveFilename(SCOPE_CURRENT_PLUGIN, "Extensions/dreamMediathek/webtv_stations.xml")
+
+class WebTVStations():
+       """Manages WebTVStations declared in a XML-Document."""
+       def __init__(self):
+               print "[WebTVStations] INIT"
+               self.webtv_stations = {}
+
+       def getWebTVStations(self, callback = None):
+               webtv_stations = []
+               self.webtv_stations = {}
+
+               if not os_path.exists(WEBTV_STATIONS):
+                       return
+               tree = cet_parse(WEBTV_STATIONS).getroot()
+
+               def getValue(definitions, default):
+                       ret = ""
+                       Len = len(definitions)
+                       return Len > 0 and definitions[Len-1].text or default
+
+               for tvstation in tree.findall("tvstation"):
+                       data = { 'provider': None, 'title': None, 'streamurl': None }
+                       try:
+                               data['provider'] = getValue(tvstation.findall("provider"), False).encode("UTF-8")
+                               data['title'] = getValue(tvstation.findall("title"), False).encode("UTF-8")
+                               data['streamurl'] = getValue(tvstation.findall("streamurl"), False).encode("UTF-8")
+
+                               print "TVSTATION--->",data
+                               self.webtv_stations[data['title']] = data
+                       except Exception, e:
+                               print "[WebTVStations] Error reading Stations:", e
+
+       def getWebTVStationsList(self):
+               return sorted(self.webtv_stations.iterkeys())
+
+iWebTVStations = WebTVStations()
+
diff --git a/dreammediathek/src/__init__.py b/dreammediathek/src/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/dreammediathek/src/maintainer.info b/dreammediathek/src/maintainer.info
new file mode 100644 (file)
index 0000000..539ab63
--- /dev/null
@@ -0,0 +1,2 @@
+nixkoenner@newnigma2.to\r
+dreamMediathek\r
diff --git a/dreammediathek/src/plugin.py b/dreammediathek/src/plugin.py
new file mode 100644 (file)
index 0000000..b1b503c
--- /dev/null
@@ -0,0 +1,190 @@
+from Plugins.Plugin import PluginDescriptor
+from Tools.BoundFunction import boundFunction
+from Screens.MessageBox import MessageBox
+from Screens.Screen import Screen
+from Screens.ChoiceBox import ChoiceBox
+from Components.ActionMap import ActionMap, NumberActionMap
+from Components.Sources.StaticText import StaticText
+from Components.Sources.List import List
+from Components.AVSwitch import AVSwitch
+from Components.config import config, Config, ConfigSelection, ConfigSubsection, ConfigText, getConfigListEntry, ConfigYesNo, ConfigIP, ConfigNumber,ConfigLocations
+from Components.config import KEY_DELETE, KEY_BACKSPACE, KEY_LEFT, KEY_RIGHT, KEY_HOME, KEY_END, KEY_TOGGLEOW, KEY_ASCII, KEY_TIMEOUT
+from Components.ConfigList import ConfigListScreen
+from Components.ServiceEventTracker import ServiceEventTracker, InfoBarBase
+
+from Tools.Directories import pathExists, fileExists, resolveFilename, SCOPE_PLUGINS, SCOPE_SKIN_IMAGE, SCOPE_HDD, SCOPE_CURRENT_PLUGIN, SCOPE_CURRENT_SKIN
+from Tools.LoadPixmap import LoadPixmap
+from enigma import eTimer, quitMainloop,eListbox,ePoint, RT_HALIGN_LEFT, RT_HALIGN_RIGHT, RT_VALIGN_CENTER, eListboxPythonMultiContent, eListbox, gFont, getDesktop, ePicLoad, eServiceCenter, iServiceInformation, eServiceReference,iSeekableService,iServiceInformation, iPlayableService, iPlayableServicePtr
+from os import path as os_path, system as os_system, unlink, stat, mkdir, popen, makedirs, listdir, access, rename, remove, W_OK, R_OK, F_OK
+from twisted.web import client
+from twisted.internet import reactor
+from time import time
+
+from Screens.InfoBarGenerics import InfoBarShowHide, InfoBarSeek, InfoBarNotifications, InfoBarServiceNotifications
+
+from ServiceXML import iWebTVStations
+from MoviePlayer import dreamMediathekPlayer
+
+config.plugins.dreamMediathek = ConfigSubsection()
+config.plugins.dreamMediathek.general = ConfigSubsection()
+config.plugins.dreamMediathek.general.on_movie_stop = ConfigSelection(default = "ask", choices = [
+       ("ask", _("Ask user")), ("quit", _("Return to movie list")), ("playnext", _("Play next video")), ("playagain", _("Play video again")) ])
+config.plugins.dreamMediathek.general.on_exit = ConfigSelection(default = "ask", choices = [
+       ("ask", _("Ask user")), ("quit", _("Return to movie list"))])
+
+
+class dreamMediathekStationsScreen(Screen):
+       Details = {}
+       skin = """
+               <screen name="dreamMediathekStationsScreen" position="center,center" size="560,440" title="dreamMediathekStationsScreen" >
+                       <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" alphatest="on" />
+                       <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
+                       <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
+                       <widget source="key_yellow" render="Label" position="280,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" transparent="1" />
+                       <widget source="key_blue" render="Label" position="420,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#18188b" transparent="1" />
+                       <widget source="streamlist" render="Listbox" position="5,50" size="550,280" zPosition="1" scrollbarMode="showOnDemand" transparent="1" >
+                               <convert type="TemplatedMultiContent">
+                               {"templates":
+                                       {"default": (55,[
+                                                       MultiContentEntryText(pos = (5, 1), size = (540, 28), font=2, flags = RT_HALIGN_LEFT | RT_VALIGN_TOP| RT_WRAP, text = 1), # provider, title, streamurl
+                                                       MultiContentEntryText(pos = (5, 28), size = (540, 18), font=3, flags = RT_HALIGN_LEFT | RT_VALIGN_TOP| RT_WRAP, text = 0), # provider, title, streamurl
+                                               ]),
+                                       "state": (55,[
+                                                       MultiContentEntryText(pos = (10, 1), size = (560, 28), font=2, flags = RT_HALIGN_LEFT | RT_VALIGN_TOP| RT_WRAP, text = 0), # index 0 is the name
+                                                       MultiContentEntryText(pos = (10, 22), size = (560, 46), font=3, flags = RT_HALIGN_LEFT | RT_VALIGN_TOP| RT_WRAP, text = 1), # index 2 is the description
+                                               ])
+                                       },
+                                       "fonts": [gFont("Regular", 22),gFont("Regular", 18),gFont("Regular", 26),gFont("Regular", 20)],
+                                       "itemHeight": 55
+                               }
+                               </convert>
+                       </widget>
+               </screen>"""
+               
+       def __init__(self, session, skin_path = None):
+               Screen.__init__(self, session)
+               self.session = session
+               self.skin_path = skin_path
+               if self.skin_path == None:
+                       self.skin_path = resolveFilename(SCOPE_CURRENT_PLUGIN, "Extensions/dreamMediathek")
+
+               self.lastservice = session.nav.getCurrentlyPlayingServiceReference()
+               self.streamlist = []
+               self.currentList = "streamlist"
+               self.oldList = None
+               self.tvstations = None
+
+               self["streamlist"] = List(self.streamlist)
+               self["key_red"] = StaticText(_("Cancel"))
+               self["key_green"] = StaticText(_("OK"))
+               self["key_yellow"] = StaticText()
+               self["key_blue"] = StaticText() 
+
+               self["FredMainActions"] = ActionMap(["ShortcutActions", "WizardActions"],
+               {
+                       "ok": self.keyOK,
+                       "back": self.leavePlayer,
+                       "red": self.leavePlayer,
+               }, -1)
+
+               #self["videoactions"].setEnabled(True)
+               self.onLayoutFinish.append(self.layoutFinished)
+               self.onShown.append(self.setWindowTitle)
+               self.onClose.append(self.__onClose)
+               
+       def __onClose(self):
+               self.Details = {}
+               self.session.nav.playService(self.lastservice)
+               
+       def layoutFinished(self):
+               self.currentList = "streamlist"
+               self.getStationsList()
+               #self["videoactions"].setEnabled(False)
+               
+       def setWindowTitle(self):
+               self.setTitle(_("dreamMediathek TV Stations"))
+
+       def handleLeave(self, how):
+               self.is_closing = True
+               if how == "ask":
+                       list = (
+                               (_("Yes"), "quit"),
+                               (_("No"), "continue")
+                       )                                       
+                       self.session.openWithCallback(self.leavePlayerConfirmed, ChoiceBox, title=_("Really quit dreamMediathek ?"), list = list)
+               else:
+                       self.leavePlayerConfirmed([True, how])
+
+       def leavePlayer(self):
+               print "leavePlayer"
+               self.handleLeave(config.plugins.dreamMediathek.general.on_exit.value)
+
+       def leavePlayerConfirmed(self, answer):
+               answer = answer and answer[1]
+               if answer == "quit":
+                       self.doQuit()
+               else:
+                       return
+
+       def doQuit(self):
+               config.plugins.dreamMediathek.general.save()
+               config.plugins.dreamMediathek.save()
+               self.close()
+                       
+       def keyOK(self):
+               print "self.currentList im KeyOK",self.currentList
+               if self.currentList == "streamlist":
+                       current = self["streamlist"].getCurrent()
+                       if current:
+                               print current
+                               url = current[2]
+                               title = current[1]
+                               myreference = eServiceReference(4097,0,url)
+                               myreference.setName(title)
+                               #self.session.open(dreamMediathekPlayer, myreference, self.lastservice, infoCallback = self.showVideoInfo, nextCallback = self.getNextEntry, prevCallback = self.getPrevEntry )
+                               self.session.open(dreamMediathekPlayer, myreference, self.lastservice)
+
+       def getStationsList(self):
+               print "getStationsList"
+               iWebTVStations.getWebTVStations()
+               self.buildStationsList()
+
+       def buildStationsComponent(self, station):
+               provider = None
+               title = None
+               streamurl = None
+               if iWebTVStations.webtv_stations[station].has_key("provider"):
+                       provider = iWebTVStations.webtv_stations[station]["provider"]
+               if iWebTVStations.webtv_stations[station].has_key("title"):
+                       title = iWebTVStations.webtv_stations[station]["title"]
+               if iWebTVStations.webtv_stations[station].has_key("streamurl"):
+                       streamurl = iWebTVStations.webtv_stations[station]["streamurl"]                 
+               return((provider, title, streamurl ))   
+
+       def buildStationsList(self):
+               self.tvstations = None
+               self.tvstations = iWebTVStations.getWebTVStationsList()
+               if self.tvstations and len(self.tvstations):
+                       self.streamlist = []
+                       for station in self.tvstations:
+                               print "GOT station:",station
+                               self.streamlist.append(self.buildStationsComponent(station))
+                       if len(self.streamlist):
+                               self["streamlist"].setList(self.streamlist)
+                               self["streamlist"].style = "default"
+
+def dreamMediathekMain(session, **kwargs):
+       session.open(dreamMediathekStationsScreen)
+
+
+def Plugins(path, **kwargs):
+       global plugin_path
+       plugin_path = path
+       return PluginDescriptor(
+               name=_("DreamMediathek"),
+               description=_("Play Web and ipTV streams"),
+               where = [ PluginDescriptor.WHERE_EXTENSIONSMENU, PluginDescriptor.WHERE_PLUGINMENU ],
+               fnc = dreamMediathekMain)
diff --git a/dreammediathek/src/webtv_stations.xml b/dreammediathek/src/webtv_stations.xml
new file mode 100644 (file)
index 0000000..7d74377
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<webtvstations>
+       <tvstation>
+               <provider>americafree.tv</provider>
+               <title>AFTVHD</title>
+               <streamurl>rtsp://video1.americafree.tv/AFTVHDVarietyH2642000.sdp</streamurl>
+       </tvstation>
+       <tvstation>
+               <provider>cctv.ws</provider>
+               <title>VH1 Classic</title>
+               <streamurl>http://cctv.ws/1/ssic01/VH1classic</streamurl>
+       </tvstation>
+       <tvstation>
+               <provider>americafree.tv</provider>
+               <title>AFTVHDVariety</title>
+               <streamurl>rtsp://video1.americafree.tv/AFTVHDVarietyH2642000.sdp</streamurl>
+       </tvstation>
+</webtvstations>