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