1 from Plugins.Plugin import PluginDescriptor
4 from xml.etree.cElementTree import fromstring, ElementTree
6 from enigma import gFont, eTimer, eConsoleAppContainer, ePicLoad, loadPNG, getDesktop, eServiceReference, iPlayableService, eListboxPythonMultiContent, RT_HALIGN_LEFT, RT_HALIGN_RIGHT, RT_HALIGN_CENTER, RT_VALIGN_CENTER
8 from Screens.Screen import Screen
9 from Screens.ChoiceBox import ChoiceBox
10 from Screens.MessageBox import MessageBox
11 from Screens.InfoBarGenerics import InfoBarNotifications
13 from Components.Button import Button
14 from Components.Label import Label
15 from Components.ConfigList import ConfigListScreen
16 from Components.Sources.StaticText import StaticText
17 from Components.ActionMap import NumberActionMap, ActionMap
18 from Components.config import config, ConfigSelection, getConfigListEntry, ConfigText, ConfigDirectory, ConfigYesNo, ConfigSelection
19 from Components.FileList import FileList, FileEntryComponent
20 from Components.MenuList import MenuList
21 from Components.Pixmap import Pixmap, MovingPixmap
22 from Components.AVSwitch import AVSwitch
23 from Components.ServiceEventTracker import ServiceEventTracker
25 from Tools.Directories import fileExists, resolveFilename, SCOPE_PLUGINS
27 PLUGIN_PATH = resolveFilename(SCOPE_PLUGINS, "Extensions/StreamTV")
29 class StreamTVPlayer(Screen, InfoBarNotifications):
31 <screen name="StreamTVPlayer" flags="wfNoBorder" position="0,570" size="1280,190" title="StreamTV Player" backgroundColor="#41000000" >
32 <ePixmap position="80,25" size="117,72" pixmap="%s/channel_background.png" zPosition="-1" transparent="1" alphatest="blend" />
33 <widget name="channel_icon" position="121,43" zPosition="10" size="35,35" backgroundColor="#41000000" />
34 <widget name="channel_name" position="250,20" size="650,40" font="Regular;36" halign="left" valign="center" foregroundColor="#ffffff" backgroundColor="#41000000" />
35 <widget name="channel_uri" position="250,70" size="950,60" font="Regular;22" halign="left" valign="top" foregroundColor="#ffffff" backgroundColor="#41000000" />
36 <widget source="session.CurrentService" render="Label" position="805,20" size="300,40" font="Regular;30" halign="right" valign="center" foregroundColor="#f4df8d" backgroundColor="#41000000" transparent="1" >
37 <convert type="ServicePosition">Position</convert>
45 def __init__(self, session, service, cbServiceCommand, chName, chURL, chIcon):
46 Screen.__init__(self, session)
47 InfoBarNotifications.__init__(self)
49 isEmpty = lambda x: x is None or len(x)==0 or x == 'None'
50 if isEmpty(chName): chName = 'Unknown'
51 if isEmpty(chURL): chURL = 'Unknown'
52 if isEmpty(chIcon): chIcon = 'default.png'
53 chIcon = '%s/icons/%s'%(PLUGIN_PATH,chIcon)
54 self.session = session
55 self.service = service
56 self.cbServiceCommand = cbServiceCommand
57 self["actions"] = ActionMap(["OkCancelActions", "InfobarSeekActions", "MediaPlayerActions", "MovieSelectionActions"], {
58 "ok": self.doInfoAction,
59 "cancel": self.doExit,
61 "playpauseService": self.playpauseService,
64 self.__event_tracker = ServiceEventTracker(screen = self, eventmap = {
65 iPlayableService.evSeekableStatusChanged: self.__seekableStatusChanged,
66 iPlayableService.evStart: self.__serviceStarted,
67 iPlayableService.evEOF: self.__evEOF,
70 self.hidetimer = eTimer()
71 self.hidetimer.timeout.get().append(self.doInfoAction)
73 self.state = self.PLAYER_PLAYING
74 self.lastseekstate = self.PLAYER_PLAYING
75 self.__seekableStatusChanged()
77 self.onClose.append(self.__onClose)
80 self['channel_icon'] = Pixmap()
81 self['channel_name'] = Label(chName)
82 self['channel_uri'] = Label(chURL)
84 self.picload = ePicLoad()
85 self.scale = AVSwitch().getFramebufferScale()
86 self.picload.PictureData.get().append(self.cbDrawChannelIcon)
89 self.picload.setPara((35, 35, self.scale[0], self.scale[1], False, 0, "#00000000"))
90 self.picload.startDecode(chIcon)
92 self.bypassExit = False
93 self.cbServiceCommand(('docommand',self.doCommand))
95 def doCommand(self, cmd):
96 if cmd == 'bypass_exit':
97 self.bypassExit = True
99 def cbDrawChannelIcon(self, picInfo=None):
100 ptr = self.picload.getData()
102 self["channel_icon"].instance.setPixmap(ptr.__deref__())
103 self["channel_icon"].show()
106 self.session.nav.stopService()
108 def __seekableStatusChanged(self):
109 service = self.session.nav.getCurrentService()
110 if service is not None:
111 seek = service.seek()
112 if seek is None or not seek.isCurrentlySeekable():
113 self.setSeekState(self.PLAYER_PLAYING)
115 def __serviceStarted(self):
116 self.state = self.PLAYER_PLAYING
117 self.__seekableStatusChanged()
124 def __setHideTimer(self):
125 self.hidetimer.start(5000)
128 list = ((_("Yes"), "y"), (_("No"), "n"),)
129 self.session.openWithCallback(self.cbDoExit, ChoiceBox, title=_("Stop playing this stream?"), list=list)
131 def cbDoExit(self, answer):
132 answer = answer and answer[1]
134 self.cbServiceCommand()
137 def setSeekState(self, wantstate):
138 service = self.session.nav.getCurrentService()
140 print "No Service found"
143 pauseable = service.pause()
144 if pauseable is not None:
145 if wantstate == self.PLAYER_PAUSED:
147 self.state = self.PLAYER_PAUSED
149 self.hidetimer.stop()
151 elif wantstate == self.PLAYER_PLAYING:
153 self.state = self.PLAYER_PLAYING
155 self.__setHideTimer()
157 self.state = self.PLAYER_PLAYING
159 def doInfoAction(self):
161 self.hidetimer.stop()
165 if self.state == self.PLAYER_PLAYING:
166 self.__setHideTimer()
169 if self.state == self.PLAYER_PAUSED:
171 self.__setHideTimer()
172 self.state = self.PLAYER_PLAYING
173 self.session.nav.playService(self.service)
175 self.__setHideTimer()
177 def playpauseService(self):
178 if self.state == self.PLAYER_PLAYING:
179 self.setSeekState(self.PLAYER_PAUSED)
180 elif self.state == self.PLAYER_PAUSED:
181 self.setSeekState(self.PLAYER_PLAYING)
183 def parseStreamDB(filename):
188 for iptv in tree.findall('iptv'):
189 n = str(iptv.findtext('name'))
190 i = str(iptv.findtext('icon'))
191 u = str(iptv.findtext('uri'))
192 t = str(iptv.findtext('type'))
193 tvlist.append({'name':n, 'icon':i, 'type':t, 'uri':u})
196 def streamListEntry(entry):
198 (eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, 5, 1, 35, 35, loadPNG('%s/icons/%s' % (PLUGIN_PATH, str(entry[1].get('icon'))) )),
199 (eListboxPythonMultiContent.TYPE_TEXT,45,7,550,37,0,RT_HALIGN_LEFT,entry[0])
201 #(eListboxPythonMultiContent.TYPE_TEXT,250,7,310,37,1,RT_HALIGN_LEFT,entry[1].get('uri'))
202 class StreamTVList(Screen):
204 <screen name="StreamTVList" position="center,120" size="600,380" title="StreamTV List">
205 <widget name="streamlist" position="0,0" size="600,350" backgroundColor="#000000" zPosition="10" scrollbarMode="showOnDemand" />
206 <widget name="infolabel" position="0,360" size="50,20" font="Regular;18" halign="left" />
207 <widget name="infomation" position="50,360" size="550,20" font="Regular;18" halign="left" />
210 def __init__(self, session):
211 self.session = session
212 Screen.__init__(self, session)
213 self["actions"] = ActionMap(["OkCancelActions", "ShortcutActions", "WizardActions", "ColorActions", "SetupActions", "NumberActions", "MenuActions"], {
215 "cancel": self.keyCancel,
217 "down" : self.keyDown,
218 "left" : self.keyLeft,
219 "right" : self.keyRight,
222 self.streamFile = resolveFilename(SCOPE_PLUGINS, "Extensions/StreamTV/stream.xml")
225 self.makeStreamList()
227 self.streamMenuList = MenuList([], enableWrapAround=True, content=eListboxPythonMultiContent)
228 self.streamMenuList.l.setFont(0, gFont('Regular', 22))
229 self.streamMenuList.l.setFont(1, gFont('Regular', 18))
230 self.streamMenuList.l.setItemHeight(37)
231 self['streamlist'] = self.streamMenuList
232 self.streamMenuList.setList(map(streamListEntry, self.streamList))
234 self["infolabel"] = Label("URL :")
235 self["infomation"] = Label(" ")
236 self.updateInfomation()
238 self.onLayoutFinish.append(self.layoutFinished)
240 self.beforeService = None
241 self.currentService = None
242 self.playerStoped = False
243 self.serviceDoCommand = None
245 self.keyLocked = False
247 def layoutFinished(self):
248 rc = os.popen('ps -ef | grep rtmpdump | grep -v grep').read()
249 print "a process already running :", rc
252 os.system('killall -INT rtmpdump')
254 def updateInfomation(self):
257 streamInfo = self["streamlist"].getCurrent()[0][1]
258 infomation = streamInfo.get('uri').split()[0]
259 except: infomation = ' '
260 self["infomation"].setText(infomation)
265 self['streamlist'].pageUp()
266 self.updateInfomation()
271 self['streamlist'].pageDown()
272 self.updateInfomation()
277 self['streamlist'].up()
278 self.updateInfomation()
283 self['streamlist'].down()
284 self.updateInfomation()
292 self.keyLocked = True
293 self.beforeService = None
294 self.currentService = None
295 self.playerStoped = False
296 self.serviceDoCommand = None
298 streamInfo = self["streamlist"].getCurrent()[0][1]
299 uri = streamInfo.get('uri')
300 typeInfo = streamInfo.get('type').split(':')
302 serviceType = typeInfo[1]
303 bufferSize = typeInfo[2]
304 self.doStreamAction(uri, serviceType, bufferSize)
306 def doStreamAction(self, uri=None, serviceType='4097', bufferSize=None):
308 serviceType = int(serviceType)
309 except: serviceType = 4097
311 bufferSize = int(bufferSize)
312 except: bufferSize = None
314 streamInfo = self["streamlist"].getCurrent()[0][1]
315 serviceRef = "%(TYPE)d:0:1:0:0:0:0:0:0:0:%(URI)s:%(NAME)s" % {
317 'URI' :uri.replace(':','%3a'),
318 'NAME' :streamInfo.get('name')
320 service = eServiceReference(serviceRef)
321 #if bufferSize is not None:
322 # service.setData(2, bufferSize*1024)
324 self.beforeService = self.session.nav.getCurrentlyPlayingServiceReference()
325 self.currentService = self.session.openWithCallback(self.cbFinishedStream,
328 cbServiceCommand=self.cbServiceCommand,
329 chName=str(streamInfo.get('name')),
330 chURL =str(streamInfo.get('uri')),
331 chIcon=str(streamInfo.get('icon'))
334 def cbServiceCommand(self, params=None):
336 self.playerStoped = True
338 if params[0] == 'docommand':
339 self.serviceDoCommand = params[1]
341 def cbFinishedStream(self):
342 self.keyLocked = False
343 self.session.nav.playService(self.beforeService)
344 print 'player done!!'
346 def makeStreamList(self):
347 streamDB = parseStreamDB(self.streamFile)
350 self.streamList.append((x.get('name'), x))
352 def main(session, **kwargs):
353 session.open(StreamTVList)
355 def Plugins(**kwargs):
356 return PluginDescriptor(name=_("StreamTVPlayer"), description="Watching IPTV implemented by RTSP/RTMP protocol.", where = PluginDescriptor.WHERE_PLUGINMENU, fnc=main)