1 # -*- coding: UTF-8 -*-
2 from Plugins.Plugin import PluginDescriptor
3 from Tools.BoundFunction import boundFunction
4 from Screens.MessageBox import MessageBox
5 from Screens.Screen import Screen
6 from Screens.ChoiceBox import ChoiceBox
7 from Components.ActionMap import ActionMap, NumberActionMap
8 from Components.Sources.StaticText import StaticText
9 from Components.Sources.List import List
10 from Components.AVSwitch import AVSwitch
11 from Components.config import config, Config, ConfigSelection, ConfigSubsection, ConfigText, getConfigListEntry, ConfigYesNo, ConfigIP, ConfigNumber,ConfigLocations
12 from Components.config import KEY_DELETE, KEY_BACKSPACE, KEY_LEFT, KEY_RIGHT, KEY_HOME, KEY_END, KEY_TOGGLEOW, KEY_ASCII, KEY_TIMEOUT
13 from Components.ConfigList import ConfigListScreen
14 from Components.ServiceEventTracker import ServiceEventTracker, InfoBarBase
16 from Tools.Directories import pathExists, fileExists, resolveFilename, SCOPE_PLUGINS, SCOPE_SKIN_IMAGE, SCOPE_HDD, SCOPE_CURRENT_PLUGIN, SCOPE_CURRENT_SKIN
17 from Tools.LoadPixmap import LoadPixmap
18 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
19 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
20 from twisted.web import client
21 from twisted.internet import reactor
24 from Screens.InfoBarGenerics import InfoBarShowHide, InfoBarSeek, InfoBarNotifications, InfoBarServiceNotifications
26 from ServiceXML import iWebTVStations
28 config.plugins.dreamMediathek = ConfigSubsection()
29 config.plugins.dreamMediathek.general = ConfigSubsection()
30 config.plugins.dreamMediathek.general.on_movie_stop = ConfigSelection(default = "ask", choices = [
31 ("ask", _("Ask user")), ("quit", _("Return to movie list")), ("playnext", _("Play next video")), ("playagain", _("Play video again")) ])
32 config.plugins.dreamMediathek.general.on_exit = ConfigSelection(default = "ask", choices = [
33 ("ask", _("Ask user")), ("quit", _("Return to movie list"))])
36 class dreamMediathekPlayer(Screen, InfoBarNotifications):
40 ENABLE_RESUME_SUPPORT = True
43 skin = """<screen name="dreamMediathekPlayer" flags="wfNoBorder" position="0,380" size="720,160" title="dreamMediathekPlayer" backgroundColor="transparent">
44 <ePixmap position="0,0" pixmap="skin_default/info-bg_mp.png" zPosition="-1" size="720,160" />
45 <ePixmap position="29,40" pixmap="skin_default/screws_mp.png" size="665,104" alphatest="on" />
46 <ePixmap position="48,70" pixmap="skin_default/icons/mp_buttons.png" size="108,13" alphatest="on" />
47 <ePixmap pixmap="skin_default/icons/icon_event.png" position="207,78" size="15,10" alphatest="on" />
48 <widget source="session.CurrentService" render="Label" position="230,73" size="360,40" font="Regular;20" backgroundColor="#263c59" shadowColor="#1d354c" shadowOffset="-1,-1" transparent="1">
49 <convert type="ServiceName">Name</convert>
51 <widget source="session.CurrentService" render="Label" position="580,73" size="90,24" font="Regular;20" halign="right" backgroundColor="#4e5a74" transparent="1">
52 <convert type="ServicePosition">Length</convert>
54 <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">
55 <convert type="ServicePosition">Position</convert>
57 <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">
58 <convert type="ServicePosition">Gauge</convert>
60 <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">
61 <convert type="ServicePosition">Remaining</convert>
65 def __init__(self, session, service, lastservice, infoCallback = None, nextCallback = None, prevCallback = None):
66 Screen.__init__(self, session)
67 InfoBarNotifications.__init__(self)
68 self.session = session
69 self.service = service
70 self.infoCallback = infoCallback
71 self.nextCallback = nextCallback
72 self.prevCallback = prevCallback
73 self.screen_timeout = 5000
74 self.nextservice = None
76 print "evEOF=%d" % iPlayableService.evEOF
77 self.__event_tracker = ServiceEventTracker(screen = self, eventmap =
79 iPlayableService.evSeekableStatusChanged: self.__seekableStatusChanged,
80 iPlayableService.evStart: self.__serviceStarted,
81 iPlayableService.evEOF: self.__evEOF,
84 self["actions"] = ActionMap(["OkCancelActions", "InfobarSeekActions", "MediaPlayerActions", "MovieSelectionActions"],
87 "cancel": self.leavePlayer,
88 "stop": self.leavePlayer,
89 "playpauseService": self.playpauseService,
90 "seekFwd": self.playNextFile,
91 "seekBack": self.playPrevFile,
92 "showEventInfo": self.showVideoInfo,
96 self.lastservice = lastservice
98 self.hidetimer = eTimer()
99 self.hidetimer.timeout.get().append(self.ok)
100 self.returning = False
102 self.state = self.STATE_PLAYING
103 self.lastseekstate = self.STATE_PLAYING
105 self.onPlayStateChanged = [ ]
106 self.__seekableStatusChanged()
109 self.onClose.append(self.__onClose)
112 self.session.nav.stopService()
115 print "evEOF=%d" % iPlayableService.evEOF
117 self.handleLeave(config.plugins.dreamMediathek.general.on_movie_stop.value)
119 def __setHideTimer(self):
120 self.hidetimer.start(self.screen_timeout)
122 def showInfobar(self):
124 if self.state == self.STATE_PLAYING:
125 self.__setHideTimer()
129 def hideInfobar(self):
131 self.hidetimer.stop()
139 def showVideoInfo(self):
142 if self.infoCallback is not None:
146 def playNextFile(self):
148 if self.nextCallback() is not None:
149 nextservice,error = self.nextCallback()
150 print "nextservice--->",nextservice
151 if nextservice is None:
152 self.handleLeave(config.plugins.dreamMediathek.general.on_movie_stop.value, error)
154 self.playService(nextservice)
157 def playPrevFile(self):
159 if self.prevCallback() is not None:
160 prevservice,error = self.prevCallback()
161 if prevservice is None:
162 self.handleLeave(config.plugins.dreamMediathek.general.on_movie_stop.value, error)
164 self.playService(prevservice)
169 if self.state != self.STATE_IDLE:
173 def playService(self, newservice):
174 if self.state != self.STATE_IDLE:
176 self.service = newservice
180 if self.state == self.STATE_PAUSED:
182 self.__setHideTimer()
183 self.state = self.STATE_PLAYING
184 self.session.nav.playService(self.service)
186 self.__setHideTimer()
188 def stopCurrent(self):
190 self.session.nav.stopService()
191 self.state = self.STATE_IDLE
193 def playpauseService(self):
194 print "playpauseService"
195 if self.state == self.STATE_PLAYING:
197 elif self.state == self.STATE_PAUSED:
198 self.unPauseService()
200 def pauseService(self):
202 if self.state == self.STATE_PLAYING:
203 self.setSeekState(self.STATE_PAUSED)
205 def unPauseService(self):
206 print "unPauseService"
207 if self.state == self.STATE_PAUSED:
208 self.setSeekState(self.STATE_PLAYING)
212 service = self.session.nav.getCurrentService()
216 seek = service.seek()
218 if seek is None or not seek.isCurrentlySeekable():
223 def isSeekable(self):
224 if self.getSeek() is None:
228 def __seekableStatusChanged(self):
229 print "seekable status changed!"
230 if not self.isSeekable():
231 self.setSeekState(self.STATE_PLAYING)
235 def __serviceStarted(self):
236 self.state = self.STATE_PLAYING
237 self.__seekableStatusChanged()
239 def setSeekState(self, wantstate):
241 if wantstate == self.STATE_PAUSED:
242 print "trying to switch to Pause- state:",self.STATE_PAUSED
243 elif wantstate == self.STATE_PLAYING:
244 print "trying to switch to playing- state:",self.STATE_PLAYING
245 service = self.session.nav.getCurrentService()
247 print "No Service found"
249 pauseable = service.pause()
250 if pauseable is None:
251 print "not pauseable."
252 self.state = self.STATE_PLAYING
254 if pauseable is not None:
255 print "service is pausable"
256 if wantstate == self.STATE_PAUSED:
257 print "WANT TO PAUSE"
259 self.state = self.STATE_PAUSED
261 self.hidetimer.stop()
263 elif wantstate == self.STATE_PLAYING:
266 self.state = self.STATE_PLAYING
268 self.__setHideTimer()
270 for c in self.onPlayStateChanged:
275 def handleLeave(self, how, error = False):
276 self.is_closing = True
280 (_("No, but play video again"), "playagain"),
281 (_("Yes, but play next video"), "playnext"),
282 (_("Yes, but play previous video"), "playprev"),
285 self.session.openWithCallback(self.leavePlayerConfirmed, ChoiceBox, title=_("Stop playing this movie?"), list = list)
287 self.session.openWithCallback(self.leavePlayerConfirmed, ChoiceBox, title=_("No playable video found! Stop playing this movie?"), list = list)
289 self.leavePlayerConfirmed([True, how])
291 def leavePlayer(self):
292 self.handleLeave(config.plugins.dreamMediathek.general.on_movie_stop.value)
294 def leavePlayerConfirmed(self, answer):
295 answer = answer and answer[1]
298 elif answer == "playnext":
300 elif answer == "playprev":
302 elif answer == "playagain":
305 def doEofInternal(self, playing):
310 self.handleLeave(config.usage.on_movie_eof.value)