optimize linked tuner handling
[enigma2.git] / lib / python / Plugins / Extensions / MediaPlayer / plugin.py
1 from os import path as os_path, remove as os_remove, listdir as os_listdir
2 from time import strftime
3 from enigma import eTimer, eServiceCenter, iServiceInformation
4 from Screens.Screen import Screen
5 from Screens.MessageBox import MessageBox
6 from Screens.InputBox import InputBox
7 from Components.ActionMap import NumberActionMap, HelpableActionMap
8 from Components.Label import Label
9 from Components.Pixmap import Pixmap
10 from Components.Label import Label
11 from Components.FileList import FileList
12 from Components.MediaPlayer import PlayList
13 from Tools.Directories import resolveFilename, SCOPE_CONFIG, SCOPE_PLAYLIST, SCOPE_SKIN_IMAGE
14 from Components.ServicePosition import ServicePositionGauge
15 from Components.ServiceEventTracker import InfoBarBase
16 from Components.Playlist import PlaylistIOInternal, PlaylistIOM3U, PlaylistIOPLS
17 from Screens.InfoBarGenerics import InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSupport, InfoBarNotifications
18 from ServiceReference import ServiceReference
19 from Screens.ChoiceBox import ChoiceBox
20 from Screens.HelpMenu import HelpableScreen
21 import random
22
23 class MyPlayList(PlayList):
24         def __init__(self):
25                 PlayList.__init__(self)
26
27         def PlayListShuffle(self):
28                 random.shuffle(self.list)
29                 self.l.setList(self.list)
30                 self.currPlaying = -1
31                 self.oldCurrPlaying = -1
32
33 class MediaPixmap(Pixmap):
34         def applySkin(self, desktop, screen):
35                 self.default_pixmap = None
36                 if self.skinAttributes is not None:
37                         for (attrib, value) in self.skinAttributes:
38                                 if attrib == "pixmap":
39                                         self.default_pixmap = value
40                                         break
41                 if self.default_pixmap is None:
42                         self.default_pixmap = resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/no_coverArt.png")
43                 return Pixmap.applySkin(self, desktop, screen)
44
45 class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSupport, InfoBarNotifications, HelpableScreen):
46         ALLOW_SUSPEND = True
47         ENABLE_RESUME_SUPPORT = True
48
49         def __init__(self, session, args = None):
50                 Screen.__init__(self, session)
51                 InfoBarAudioSelection.__init__(self)
52                 InfoBarCueSheetSupport.__init__(self, actionmap = "MediaPlayerCueSheetActions")
53                 InfoBarNotifications.__init__(self)
54                 InfoBarBase.__init__(self)
55                 HelpableScreen.__init__(self)
56                 self.summary = None
57                 self.oldService = self.session.nav.getCurrentlyPlayingServiceReference()
58                 self.session.nav.stopService()
59
60                 self.playlistparsers = {}
61                 self.addPlaylistParser(PlaylistIOM3U, "m3u")
62                 self.addPlaylistParser(PlaylistIOPLS, "pls")
63                 self.addPlaylistParser(PlaylistIOInternal, "e2pls")
64
65                 # 'None' is magic to start at the list of mountpoints
66                 self.filelist = FileList(None, matchingPattern = "(?i)^.*\.(mp3|ogg|ts|wav|wave|m3u|pls|e2pls|mpg|vob)", useServiceRef = True, additionalExtensions = "4098:m3u 4098:e2pls 4098:pls")
67                 self["filelist"] = self.filelist
68
69                 self.playlist = MyPlayList()
70                 #self.playlist = PlayList()
71                 self.is_closing = False
72                 self.delname = ""
73                 self["playlist"] = self.playlist
74
75                 self["PositionGauge"] = ServicePositionGauge(self.session.nav)
76
77                 self["currenttext"] = Label("")
78
79                 self["artisttext"] = Label(_("Artist:"))
80                 self["artist"] = Label("")
81                 self["titletext"] = Label(_("Title:"))
82                 self["title"] = Label("")
83                 self["albumtext"] = Label(_("Album:"))
84                 self["album"] = Label("")
85                 self["yeartext"] = Label(_("Year:"))
86                 self["year"] = Label("")
87                 self["genretext"] = Label(_("Genre:"))
88                 self["genre"] = Label("")
89                 self["coverArt"] = MediaPixmap()
90
91                 self.seek_target = None
92
93                 class MoviePlayerActionMap(NumberActionMap):
94                         def __init__(self, player, contexts = [ ], actions = { }, prio=0):
95                                 NumberActionMap.__init__(self, contexts, actions, prio)
96                                 self.player = player
97
98                         def action(self, contexts, action):
99                                 self.player.show()
100                                 return NumberActionMap.action(self, contexts, action)
101
102
103                 self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions", 
104                         {
105                                 "ok": (self.ok, _("add file to playlist")),
106                                 "cancel": (self.exit, _("exit mediaplayer")),
107                         }, -2)
108
109                 self["MediaPlayerActions"] = HelpableActionMap(self, "MediaPlayerActions", 
110                         {
111                                 "play": (self.xplayEntry, _("play entry")),
112                                 "pause": (self.pauseEntry, _("pause")),
113                                 "stop": (self.stopEntry, _("stop entry")),
114                                 "previous": (self.previousMarkOrEntry, _("play from previous mark or playlist entry")),
115                                 "next": (self.nextMarkOrEntry, _("play from next mark or playlist entry")),
116                                 "menu": (self.showMenu, _("menu")),
117                                 "skipListbegin": (self.skip_listbegin, _("jump to listbegin")),
118                                 "skipListend": (self.skip_listend, _("jump to listend")),
119                                 "prevBouquet": (self.switchToPlayList, _("switch to playlist")),
120                                 "nextBouquet": (self.switchToFileList, _("switch to filelist")),
121                                 "delete": (self.deletePlaylistEntry, _("delete playlist entry")),
122                                 "shift_stop": (self.clear_playlist, _("clear playlist")),
123                                 "shift_record": (self.playlist.PlayListShuffle, _("shuffle playlist")),
124                         }, -2)
125
126                 self["InfobarEPGActions"] = HelpableActionMap(self, "InfobarEPGActions", 
127                         {
128                                 "showEventInfo": (self.showEventInformation, _("show event details")),
129                         })
130
131                 self["actions"] = MoviePlayerActionMap(self, ["DirectionActions"], 
132                 {
133                         "right": self.rightDown,
134                         "rightRepeated": self.doNothing,
135                         "rightUp": self.rightUp,
136                         "left": self.leftDown,
137                         "leftRepeated": self.doNothing,
138                         "leftUp": self.leftUp,
139
140                         "up": self.up,
141                         "upRepeated": self.up,
142                         "upUp": self.doNothing,
143                         "down": self.down,
144                         "downRepeated": self.down,
145                         "downUp": self.doNothing,
146                 }, -2)
147
148                 InfoBarSeek.__init__(self, actionmap = "MediaPlayerSeekActions")
149
150                 self.onClose.append(self.delMPTimer)
151                 self.onClose.append(self.__onClose)
152
153                 self.righttimer = False
154                 self.rightKeyTimer = eTimer()
155                 self.rightKeyTimer.callback.append(self.rightTimerFire)
156
157                 self.lefttimer = False
158                 self.leftKeyTimer = eTimer()
159                 self.leftKeyTimer.callback.append(self.leftTimerFire)
160
161                 self.currList = "filelist"
162
163                 self.coverArtFileName = ""
164
165                 self.playlistIOInternal = PlaylistIOInternal()
166                 list = self.playlistIOInternal.open(resolveFilename(SCOPE_CONFIG, "playlist.e2pls"))
167                 if list:
168                         for x in list:
169                                 self.playlist.addFile(x.ref)
170                         self.playlist.updateList()
171
172         def doNothing(self):
173                 pass
174
175         def createSummary(self):
176                 return MediaPlayerLCDScreen
177
178         def exit(self):
179                 self.session.openWithCallback(self.exitCB, MessageBox, _("Do you really want to exit?"), timeout=5)
180
181         def exitCB(self, answer):
182                 if answer == True:
183                         self.playlistIOInternal.clear()
184                         for x in self.playlist.list:
185                                 self.playlistIOInternal.addService(ServiceReference(x[0]))
186                         self.playlistIOInternal.save(resolveFilename(SCOPE_CONFIG, "playlist.e2pls"))
187                         self.close()
188
189         def checkSkipShowHideLock(self):
190                 self.updatedSeekState()
191
192         def doEofInternal(self, playing):
193                 if playing:
194                         self.nextEntry()
195                 else:
196                         self.show()
197
198         def __onClose(self):
199                 self.session.nav.playService(self.oldService)
200
201         def delMPTimer(self):
202                 del self.rightKeyTimer
203                 del self.leftKeyTimer
204
205         def readTitleInformation(self):
206                 currPlay = self.session.nav.getCurrentService()
207                 if currPlay is not None:
208                         stitle = currPlay.info().getInfoString(iServiceInformation.sTitle)
209                         if stitle == "":
210                                 stitle = currPlay.info().getName().split('/')[-1]
211
212                         self.updateMusicInformation( artist = currPlay.info().getInfoString(iServiceInformation.sArtist),
213                                                                                  title = stitle,
214                                                                                  album = currPlay.info().getInfoString(iServiceInformation.sAlbum),
215                                                                                  genre = currPlay.info().getInfoString(iServiceInformation.sGenre),
216                                                                                  clear = True)
217                 else:
218                         self.updateMusicInformation()
219
220         def updateMusicInformation(self, artist = "", title = "", album = "", year = "", genre = "", clear = False):
221                 self.updateSingleMusicInformation("artist", artist, clear)
222                 self.updateSingleMusicInformation("title", title, clear)
223                 self.updateSingleMusicInformation("album", album, clear)
224                 self.updateSingleMusicInformation("year", year, clear)
225                 self.updateSingleMusicInformation("genre", genre, clear)
226
227         def updateSingleMusicInformation(self, name, info, clear):
228                 if info != "" or clear:
229                         if self[name].getText() != info:
230                                 self[name].setText(info)
231
232         def updateCoverArtPixmap(self, path):
233                 while not path.endswith("/"):
234                         path = path[:-1]
235                 pngname = path + "folder.png"
236                 
237                 if not os_path.exists(pngname):
238                         pngname = self["coverArt"].default_pixmap
239                 if self.coverArtFileName != pngname:
240                         self.coverArtFileName = pngname
241                         self["coverArt"].instance.setPixmapFromFile(self.coverArtFileName)
242
243         def leftDown(self):
244                 self.lefttimer = True
245                 self.leftKeyTimer.start(1000)
246
247         def rightDown(self):
248                 self.righttimer = True
249                 self.rightKeyTimer.start(1000)
250
251         def leftUp(self):
252                 if self.lefttimer:
253                         self.leftKeyTimer.stop()
254                         self.lefttimer = False
255                         self[self.currList].pageUp()
256                         self.updateCurrentInfo()
257
258         def rightUp(self):
259                 if self.righttimer:
260                         self.rightKeyTimer.stop()
261                         self.righttimer = False
262                         self[self.currList].pageDown()
263                         self.updateCurrentInfo()
264
265         def leftTimerFire(self):
266                 self.leftKeyTimer.stop()
267                 self.lefttimer = False
268                 self.switchToFileList()
269
270         def rightTimerFire(self):
271                 self.rightKeyTimer.stop()
272                 self.righttimer = False
273                 self.switchToPlayList()
274
275         def switchToFileList(self):
276                 self.currList = "filelist"
277                 self.filelist.selectionEnabled(1)
278                 self.playlist.selectionEnabled(0)
279                 self.updateCurrentInfo()
280
281         def switchToPlayList(self):
282                 if len(self.playlist) != 0:
283                         self.currList = "playlist"
284                         self.filelist.selectionEnabled(0)
285                         self.playlist.selectionEnabled(1)
286                         self.updateCurrentInfo()
287
288         def up(self):
289                 self[self.currList].up()
290                 self.updateCurrentInfo()
291
292         def down(self):
293                 self[self.currList].down()
294                 self.updateCurrentInfo()
295
296         def showAfterSeek(self):
297                 self.show()
298
299         def showAfterCuesheetOperation(self):
300                 self.show()
301
302         def hideAfterResume(self):
303                 self.hide()
304
305         # FIXME: maybe this code can be optimized 
306         def updateCurrentInfo(self):
307                 text = ""
308                 if self.currList == "filelist":
309                         idx = self.filelist.getSelectionIndex()
310                         r = self.filelist.list[idx]
311                         text = r[1][7]
312                         if r[0][1] == True:
313                                 if len(text) < 2:
314                                         text += " "
315                                 if text[:2] != "..":
316                                         text = "/" + text
317                         self.summaries.setText(text,1)
318
319                         idx += 1
320                         if idx < len(self.filelist.list):
321                                 r = self.filelist.list[idx]
322                                 text = r[1][7]
323                                 if r[0][1] == True:
324                                         text = "/" + text
325                                 self.summaries.setText(text,3)
326                         else:
327                                 self.summaries.setText(" ",3)
328
329                         idx += 1
330                         if idx < len(self.filelist.list):
331                                 r = self.filelist.list[idx]
332                                 text = r[1][7]
333                                 if r[0][1] == True:
334                                         text = "/" + text
335                                 self.summaries.setText(text,4)
336                         else:
337                                 self.summaries.setText(" ",4)
338
339                         text = ""
340                         if not self.filelist.canDescent():
341                                 r = self.filelist.getServiceRef()
342                                 if r is None:
343                                         return
344                                 text = r.getPath()
345                                 self["currenttext"].setText(os_path.basename(text))
346
347                 if self.currList == "playlist":
348                         t = self.playlist.getSelection()
349                         if t is None:
350                                 return
351                         #display current selected entry on LCD
352                         text = t.getPath()
353                         text = text.split('/')[-1]
354                         self.summaries.setText(text,1)
355                         self["currenttext"].setText(text)
356                         idx = self.playlist.getSelectionIndex()
357                         idx += 1
358                         if idx < len(self.playlist):
359                                 currref = self.playlist.getServiceRefList()[idx]
360                                 text = currref.getPath()
361                                 text = text.split('/')[-1]
362                                 self.summaries.setText(text,3)
363                         else:
364                                 self.summaries.setText(" ",3)
365
366                         idx += 1
367                         if idx < len(self.playlist):
368                                 currref = self.playlist.getServiceRefList()[idx]
369                                 text = currref.getPath()
370                                 text = text.split('/')[-1]
371                                 self.summaries.setText(text,4)
372                         else:
373                                 self.summaries.setText(" ",4)
374
375         def ok(self):
376                 if self.currList == "filelist":
377                         if self.filelist.canDescent():
378                                 self.filelist.descent()
379                                 self.updateCurrentInfo()
380                         else:
381                                 self.copyFile()
382
383                 if self.currList == "playlist":
384                         selection = self["playlist"].getSelection()
385                         self.changeEntry(self.playlist.getSelectionIndex())
386
387         def showMenu(self):
388                 menu = []
389                 if self.currList == "filelist":
390                         if self.filelist.canDescent():
391                                 menu.append((_("add directory to playlist"), "copydir"))
392                         else:
393                                 menu.append((_("add files to playlist"), "copyfiles"))
394                         menu.append((_("switch to playlist"), "playlist"))
395                 else:
396                         menu.append((_("switch to filelist"), "filelist"))
397
398                         menu.append((_("shuffle playlist"), "shuffle"))
399
400                         menu.append((_("delete"), "delete"))
401                         menu.append((_("clear playlist"), "clear"))
402                 menu.append((_("hide player"), "hide"));
403                 menu.append((_("save playlist"), "saveplaylist"));
404                 menu.append((_("load playlist"), "loadplaylist"));
405                 menu.append((_("delete saved playlist"), "deleteplaylist"));
406                 self.session.openWithCallback(self.menuCallback, ChoiceBox, title="", list=menu)
407
408         def menuCallback(self, choice):
409                 if choice is None:
410                         return
411
412                 if choice[1] == "copydir":
413                         self.copyDirectory(self.filelist.getSelection()[0])
414                 elif choice[1] == "copyfiles":
415                         self.stopEntry()
416                         self.playlist.clear()
417                         self.copyDirectory(os_path.dirname(self.filelist.getSelection()[0].getPath()) + "/", recursive = False)
418                         self.playServiceRefEntry(self.filelist.getServiceRef())
419                 elif choice[1] == "playlist":
420                         self.switchToPlayList()
421                 elif choice[1] == "filelist":
422                         self.switchToFileList()
423                 elif choice[1] == "delete":
424                         if self.playlist.getSelectionIndex() == self.playlist.getCurrentIndex():
425                                 self.stopEntry()
426                         self.deleteEntry()
427                 elif choice[1] == "clear":
428                         self.stopEntry()
429                         self.playlist.clear()
430                         self.switchToFileList()
431                 elif choice[1] == "hide":
432                         self.hide()
433                 elif choice[1] == "saveplaylist":
434                         self.save_playlist()
435                 elif choice[1] == "loadplaylist":
436                         self.load_playlist()
437                 elif choice[1] == "deleteplaylist":
438                         self.delete_saved_playlist()
439                 elif choice[1] == "shuffle":
440                         self.playlist.PlayListShuffle()
441
442
443         def showEventInformation(self):
444                 from Screens.EventView import EventViewSimple
445                 from ServiceReference import ServiceReference
446                 evt = self[self.currList].getCurrentEvent()
447                 if evt:
448                         self.session.open(EventViewSimple, evt, ServiceReference(self.getCurrent()))
449
450         # also works on filelist (?)
451         def getCurrent(self):
452                 return self["playlist"].getCurrent()
453
454         def deletePlaylistEntry(self):
455                 if self.currList == "playlist":
456                         if self.playlist.getSelectionIndex() == self.playlist.getCurrentIndex():
457                                 self.stopEntry()
458                         self.deleteEntry()
459
460         def skip_listbegin(self):
461                 if self.currList == "filelist":
462                         self.filelist.moveToIndex(0)
463                 else:
464                         self.playlist.moveToIndex(0)
465                 self.updateCurrentInfo()
466
467         def skip_listend(self):
468                 if self.currList == "filelist":
469                         idx = len(self.filelist.list)
470                         self.filelist.moveToIndex(idx - 1)
471                 else:
472                         self.playlist.moveToIndex(len(self.playlist)-1)
473                 self.updateCurrentInfo()
474
475         def save_playlist(self):
476                 self.session.openWithCallback(self.save_playlist2,InputBox, title=_("Please enter filename (empty = use current date)"),windowTitle = _("Save Playlist"))
477
478         def save_playlist2(self, name):
479                 if name is not None:
480                         name = name.strip()
481                         if name == "":
482                                 name = strftime("%y%m%d_%H%M%S")
483                         name += ".e2pls"
484                         self.playlistIOInternal.clear()
485                         for x in self.playlist.list:
486                                 self.playlistIOInternal.addService(ServiceReference(x[0]))
487                         self.playlistIOInternal.save(resolveFilename(SCOPE_PLAYLIST) + name)
488
489         def load_playlist(self):
490                 listpath = []
491                 playlistdir = resolveFilename(SCOPE_PLAYLIST)
492                 try:
493                         for i in os_listdir(playlistdir):
494                                 listpath.append((i,playlistdir + i))
495                 except IOError,e:
496                         print "Error while scanning subdirs ",e
497                 self.session.openWithCallback(self.PlaylistSelected, ChoiceBox, title=_("Please select a playlist..."), list = listpath)
498
499         def PlaylistSelected(self,path):
500                 if path is not None:
501                         self.clear_playlist()
502                         self.playlistIOInternal = PlaylistIOInternal()
503                         list = self.playlistIOInternal.open(path[1])
504                         if list:
505                                 for x in list:
506                                         self.playlist.addFile(x.ref)
507                                 self.playlist.updateList()
508
509         def delete_saved_playlist(self):
510                 listpath = []
511                 playlistdir = resolveFilename(SCOPE_PLAYLIST)
512                 try:
513                         for i in os_listdir(playlistdir):
514                                 listpath.append((i,playlistdir + i))
515                 except IOError,e:
516                         print "Error while scanning subdirs ",e
517                 self.session.openWithCallback(self.DeletePlaylistSelected, ChoiceBox, title=_("Please select a playlist to delete..."), list = listpath)
518
519         def DeletePlaylistSelected(self,path):
520                 if path is not None:
521                         self.delname = path[1]
522                         self.session.openWithCallback(self.deleteConfirmed, MessageBox, _("Do you really want to delete %s?") % (path[1]))
523
524         def deleteConfirmed(self, confirmed):
525                 if confirmed:
526                         os_remove(self.delname)
527
528         def clear_playlist(self):
529                 self.stopEntry()
530                 self.playlist.clear()
531                 self.switchToFileList()
532
533         def copyDirectory(self, directory, recursive = True):
534                 print "copyDirectory", directory
535                 filelist = FileList(directory, useServiceRef = True, isTop = True)
536
537                 for x in filelist.getFileList():
538                         if x[0][1] == True: #isDir
539                                 if recursive:
540                                         self.copyDirectory(x[0][0])
541                         else:
542                                 self.playlist.addFile(x[0][0])
543                 self.playlist.updateList()
544
545         def copyFile(self):
546                 if self.filelist.getServiceRef().type == 4098: # playlist
547                         ServiceRef = self.filelist.getServiceRef()
548                         extension = ServiceRef.getPath()[ServiceRef.getPath().rfind('.') + 1:]
549                         print "extension:", extension
550                         if self.playlistparsers.has_key(extension):
551                                 playlist = self.playlistparsers[extension]()
552                                 list = playlist.open(ServiceRef.getPath())
553                                 for x in list:
554                                         self.playlist.addFile(x.ref)
555                 else:
556                         self.playlist.addFile(self.filelist.getServiceRef())
557                         self.playlist.updateList()
558                         if len(self.playlist) == 1:
559                                 self.changeEntry(0)
560
561         def addPlaylistParser(self, parser, extension):
562                 self.playlistparsers[extension] = parser
563
564         def nextEntry(self):
565                 next = self.playlist.getCurrentIndex() + 1
566                 if next < len(self.playlist):
567                         self.changeEntry(next)
568
569         def nextMarkOrEntry(self):
570                 if not self.jumpPreviousNextMark(lambda x: x):
571                         next = self.playlist.getCurrentIndex() + 1
572                         if next < len(self.playlist):
573                                 self.changeEntry(next)
574                         else:
575                                 self.doSeek(-1)
576
577         def previousMarkOrEntry(self):
578                 if not self.jumpPreviousNextMark(lambda x: -x-5*90000, start=True):
579                         next = self.playlist.getCurrentIndex() - 1
580                         if next >= 0:
581                                 self.changeEntry(next)
582
583         def deleteEntry(self):
584                 self.playlist.deleteFile(self.playlist.getSelectionIndex())
585                 self.playlist.updateList()
586                 if len(self.playlist) == 0:
587                         self.switchToFileList()
588
589         def changeEntry(self, index):
590                 self.playlist.setCurrentPlaying(index)
591                 self.playEntry()
592
593         def playServiceRefEntry(self, serviceref):
594                 serviceRefList = self.playlist.getServiceRefList()
595                 for count in range(len(serviceRefList)):
596                         if serviceRefList[count] == serviceref:
597                                 self.changeEntry(count)
598                                 break
599                         
600         def xplayEntry(self):
601                 if self.currList == "playlist":
602                         self.playEntry()
603                 else:
604                         self.stopEntry()
605                         self.playlist.clear()
606                         sel = self.filelist.getSelection()
607                         if sel:
608                                 if sel[1]: # can descent
609                                         # add directory to playlist
610                                         self.copyDirectory(sel[0])
611                                 else:
612                                         # add files to playlist
613                                         self.copyDirectory(os_path.dirname(sel[0].getPath()) + "/", recursive = False)
614                         if len(self.playlist) > 0:
615                                 self.changeEntry(0)
616         
617         def playEntry(self):
618                 if len(self.playlist.getServiceRefList()):
619                         needsInfoUpdate = False
620                         currref = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()]
621                         if self.session.nav.getCurrentlyPlayingServiceReference() is None or currref != self.session.nav.getCurrentlyPlayingServiceReference():
622                                 self.session.nav.playService(self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()])
623                                 info = eServiceCenter.getInstance().info(currref)
624                                 description = info and info.getInfoString(currref, iServiceInformation.sDescription) or ""
625                                 self["title"].setText(description)
626                                 # display just playing musik on LCD
627                                 idx = self.playlist.getCurrentIndex()
628                                 currref = self.playlist.getServiceRefList()[idx]
629                                 text = currref.getPath()
630                                 text = text.split('/')[-1]
631                                 text = ">"+text
632                                 ext = text[-3:].lower()
633
634                                 # FIXME: the information if the service contains video (and we should hide our window) should com from the service instead 
635                                 if ext not in ["mp3", "wav", "ogg"]:
636                                         self.hide()
637                                 else:
638                                         needsInfoUpdate = True
639                                 self.summaries.setText(text,1)
640
641                                 # get the next two entries
642                                 idx += 1
643                                 if idx < len(self.playlist):
644                                         currref = self.playlist.getServiceRefList()[idx]
645                                         text = currref.getPath()
646                                         text = text.split('/')[-1]
647                                         self.summaries.setText(text,3)
648                                 else:
649                                         self.summaries.setText(" ",3)
650
651                                 idx += 1
652                                 if idx < len(self.playlist):
653                                         currref = self.playlist.getServiceRefList()[idx]
654                                         text = currref.getPath()
655                                         text = text.split('/')[-1]
656                                         self.summaries.setText(text,4)
657                                 else:
658                                         self.summaries.setText(" ",4)
659                         else:
660                                 idx = self.playlist.getCurrentIndex()
661                                 currref = self.playlist.getServiceRefList()[idx]
662                                 text = currref.getPath()
663                                 ext = text[-3:].lower()
664                                 if ext not in ["mp3", "wav", "ogg"]:
665                                         self.hide()
666                                 else:
667                                         needsInfoUpdate = True
668
669                         self.unPauseService()
670                         if needsInfoUpdate == True:
671                                 self.updateCoverArtPixmap(currref.getPath())
672                         else:
673                                 pngname = self["coverArt"].default_pixmap
674                                 self.coverArtFileName = pngname
675                                 self["coverArt"].instance.setPixmapFromFile(self.coverArtFileName)
676                         self.readTitleInformation()
677
678         def updatedSeekState(self):
679                 if self.seekstate == self.SEEK_STATE_PAUSE:
680                         self.playlist.pauseFile()
681                 elif self.seekstate == self.SEEK_STATE_PLAY:
682                         self.playlist.playFile()
683                 elif self.isStateForward(self.seekstate):
684                         self.playlist.forwardFile()
685                 elif self.isStateBackward(self.seekstate):
686                         self.playlist.rewindFile()
687
688         def pauseEntry(self):
689                 self.pauseService()
690                 self.show()
691
692         def stopEntry(self):
693                 self.playlist.stopFile()
694                 self.session.nav.playService(None)
695                 self.updateMusicInformation(clear=True)
696                 self.show()
697
698         def unPauseService(self):
699                 self.setSeekState(self.SEEK_STATE_PLAY)
700
701
702 class MediaPlayerLCDScreen(Screen):
703         skin = """
704         <screen position="0,0" size="132,64" title="LCD Text">
705                 <widget name="text1" position="4,0" size="132,35" font="Regular;16"/>
706                 <widget name="text3" position="4,36" size="132,14" font="Regular;10"/>
707                 <widget name="text4" position="4,49" size="132,14" font="Regular;10"/>
708         </screen>"""
709
710         def __init__(self, session, parent):
711                 Screen.__init__(self, session)
712                 self["text1"] = Label("Mediaplayer")
713                 self["text3"] = Label("")
714                 self["text4"] = Label("")
715
716         def setText(self, text, line):
717                 print "lcd set text:", text, line
718                 if len(text) > 10:
719                         if text[-4:] == ".mp3":
720                                 text = text[:-4]
721                 textleer = "    "
722                 text = text + textleer*10
723                 if line == 1:
724                         self["text1"].setText(text)
725                 elif line == 3:
726                         self["text3"].setText(text)
727                 elif line == 4:
728                         self["text4"].setText(text)
729
730 def main(session, **kwargs):
731         session.open(MediaPlayer)
732
733 def menu(menuid, **kwargs):
734         if menuid == "mainmenu":
735                 return [(_("Media player"), main, "media_player", 45)]
736         return []
737
738 def filescan_open(list, session, **kwargs):
739         from enigma import eServiceReference
740
741         mp = session.open(MediaPlayer)
742
743         mp.switchToPlayList()
744         for file in list:
745                 ref = eServiceReference(4097, 0, file.path)
746                 mp.playlist.addFile(ref)
747
748         # TODO: rather play first than last file?
749         mp.playServiceRefEntry(ref)
750         mp.playlist.updateList()
751
752 def filescan(**kwargs):
753         from Components.Scanner import Scanner, ScanPath
754         return [
755                 Scanner(mimetypes = ["video/mpeg"],
756                         paths_to_scan =
757                                 [
758                                         ScanPath(path = "", with_subdirs = False),
759                                 ],
760                         name = "Movie",
761                         description = "View Movies...",
762                         openfnc = filescan_open,
763                 ),
764                 Scanner(mimetypes = ["audio/mpeg", "audio/x-wav", "application/ogg"],
765                         paths_to_scan =
766                                 [
767                                         ScanPath(path = "", with_subdirs = False),
768                                 ],
769                         name = "Music",
770                         description = "Play Music...",
771                         openfnc = filescan_open,
772                 )
773         ]
774
775 from Plugins.Plugin import PluginDescriptor
776 def Plugins(**kwargs):
777         return [
778                 PluginDescriptor(name = "MediaPlayer", description = "Play back media files", where = PluginDescriptor.WHERE_MENU, fnc = menu),
779                 PluginDescriptor(name = "MediaPlayer", where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan)
780         ]