3783ddd4a47aa97619424d8a8d0ced3c005108b8
[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.infoTimer = eTimer()
168                 self.infoTimer.timeout.get().append(self.infoTimerFire)
169                 self.infoTimer.start(500)
170
171                 self.currList = "filelist"
172
173                 self.coverArtFileName = ""
174
175                 self.playlistIOInternal = PlaylistIOInternal()
176                 list = self.playlistIOInternal.open(resolveFilename(SCOPE_CONFIG, "playlist.e2pls"))
177                 if list:
178                         for x in list:
179                                 self.playlist.addFile(x.ref)
180                         self.playlist.updateList()
181
182         def doNothing(self):
183                 pass
184
185         def createSummary(self):
186                 return MediaPlayerLCDScreen
187
188         def exit(self):
189                 self.session.openWithCallback(self.exitCB, MessageBox, _("Do you really want to exit?"), timeout=5)
190
191         def exitCB(self, answer):
192                 if answer == True:
193                         self.playlistIOInternal.clear()
194                         for x in self.playlist.list:
195                                 self.playlistIOInternal.addService(ServiceReference(x[0]))
196                         self.playlistIOInternal.save(resolveFilename(SCOPE_CONFIG, "playlist.e2pls"))
197                         self.close()
198
199         def checkSkipShowHideLock(self):
200                 self.updatedSeekState()
201
202         def __evEOF(self):
203                 self.nextEntry()
204
205         def __onClose(self):
206                 self.session.nav.playService(self.oldService)
207
208         def delMPTimer(self):
209                 del self.rightKeyTimer
210                 del self.leftKeyTimer
211                 del self.infoTimer
212
213         def infoTimerFire(self):
214                 currPlay = self.session.nav.getCurrentService()
215                 if currPlay is not None:
216                         stitle = currPlay.info().getInfoString(iServiceInformation.sTitle)
217                         if stitle == "":
218                                 stitle = currPlay.info().getName().split('/')[-1]
219
220                         self.updateMusicInformation( artist = currPlay.info().getInfoString(iServiceInformation.sArtist),
221                                                                                  title = stitle,
222                                                                                  album = currPlay.info().getInfoString(iServiceInformation.sAlbum),
223                                                                                  genre = currPlay.info().getInfoString(iServiceInformation.sGenre),
224                                                                                  clear = True)
225                         self.updateCoverArtPixmap( currPlay.info().getName() )
226                 else:
227                         self.updateMusicInformation()
228                         self.updateCoverArtPixmap( "" )
229
230         def updateMusicInformation(self, artist = "", title = "", album = "", year = "", genre = "", clear = False):
231                 self.updateSingleMusicInformation("artist", artist, clear)
232                 self.updateSingleMusicInformation("title", title, clear)
233                 self.updateSingleMusicInformation("album", album, clear)
234                 self.updateSingleMusicInformation("year", year, clear)
235                 self.updateSingleMusicInformation("genre", genre, clear)
236
237         def updateSingleMusicInformation(self, name, info, clear):
238                 if info != "" or clear:
239                         if self[name].getText() != info:
240                                 self[name].setText(info)
241
242         def updateCoverArtPixmap(self, currentServiceName):
243                 filename = currentServiceName
244                 # The "getName" usually adds something like "MP3 File:" infront of filename
245                 # Get rid of this...by finding the first "/"
246                 # FIXME: this should be fixed in the servicemp3.cpp handler
247                 filename = filename[filename.find("/"):]
248                 path = os_path.dirname(filename)
249                 pngname = path + "/" + "folder.png"
250                 if not os_path.exists(pngname):
251                         pngname = self["coverArt"].default_pixmap
252                 if self.coverArtFileName != pngname:
253                         self.coverArtFileName = pngname
254                         self["coverArt"].instance.setPixmapFromFile(self.coverArtFileName)
255
256         def leftDown(self):
257                 self.lefttimer = True
258                 self.leftKeyTimer.start(1000)
259
260         def rightDown(self):
261                 self.righttimer = True
262                 self.rightKeyTimer.start(1000)
263
264         def leftUp(self):
265                 if self.lefttimer:
266                         self.leftKeyTimer.stop()
267                         self.lefttimer = False
268                         self[self.currList].pageUp()
269                         self.updateCurrentInfo()
270
271         def rightUp(self):
272                 if self.righttimer:
273                         self.rightKeyTimer.stop()
274                         self.righttimer = False
275                         self[self.currList].pageDown()
276                         self.updateCurrentInfo()
277
278         def leftTimerFire(self):
279                 self.leftKeyTimer.stop()
280                 self.lefttimer = False
281                 self.switchToFileList()
282
283         def rightTimerFire(self):
284                 self.rightKeyTimer.stop()
285                 self.righttimer = False
286                 self.switchToPlayList()
287
288         def switchToFileList(self):
289                 self.currList = "filelist"
290                 self.filelist.selectionEnabled(1)
291                 self.playlist.selectionEnabled(0)
292                 self.updateCurrentInfo()
293
294         def switchToPlayList(self):
295                 if len(self.playlist) != 0:
296                         self.currList = "playlist"
297                         self.filelist.selectionEnabled(0)
298                         self.playlist.selectionEnabled(1)
299                         self.updateCurrentInfo()
300
301         def up(self):
302                 self[self.currList].up()
303                 self.updateCurrentInfo()
304
305         def down(self):
306                 self[self.currList].down()
307                 self.updateCurrentInfo()
308
309         def showAfterSeek(self):
310                 self.show()
311
312         def showAfterCuesheetOperation(self):
313                 self.show()
314
315         def hideAfterResume(self):
316                 self.hide()
317
318         # FIXME: maybe this code can be optimized 
319         def updateCurrentInfo(self):
320                 text = ""
321                 if self.currList == "filelist":
322                         idx = self.filelist.getSelectionIndex()
323                         r = self.filelist.list[idx]
324                         text = r[1][7]
325                         if r[0][1] == True:
326                                 if len(text) < 2:
327                                         text += " "
328                                 if text[:2] != "..":
329                                         text = "/" + text
330                         self.summaries.setText(text,1)
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,3)
339                         else:
340                                 self.summaries.setText(" ",3)
341
342                         idx += 1
343                         if idx < len(self.filelist.list):
344                                 r = self.filelist.list[idx]
345                                 text = r[1][7]
346                                 if r[0][1] == True:
347                                         text = "/" + text
348                                 self.summaries.setText(text,4)
349                         else:
350                                 self.summaries.setText(" ",4)
351
352                         text = ""
353                         if not self.filelist.canDescent():
354                                 r = self.filelist.getServiceRef()
355                                 if r is None:
356                                         return
357                                 text = r.getPath()
358                                 self["currenttext"].setText(os_path.basename(text))
359
360                 if self.currList == "playlist":
361                         t = self.playlist.getSelection()
362                         if t is None:
363                                 return
364                         #display current selected entry on LCD
365                         text = t.getPath()
366                         text = text.split('/')[-1]
367                         self.summaries.setText(text,1)
368                         self["currenttext"].setText(text)
369                         idx = self.playlist.getSelectionIndex()
370                         idx += 1
371                         if idx < len(self.playlist):
372                                 currref = self.playlist.getServiceRefList()[idx]
373                                 text = currref.getPath()
374                                 text = text.split('/')[-1]
375                                 self.summaries.setText(text,3)
376                         else:
377                                 self.summaries.setText(" ",3)
378
379                         idx += 1
380                         if idx < len(self.playlist):
381                                 currref = self.playlist.getServiceRefList()[idx]
382                                 text = currref.getPath()
383                                 text = text.split('/')[-1]
384                                 self.summaries.setText(text,4)
385                         else:
386                                 self.summaries.setText(" ",4)
387
388         def ok(self):
389                 if self.currList == "filelist":
390                         if self.filelist.canDescent():
391                                 self.filelist.descent()
392                                 self.updateCurrentInfo()
393                         else:
394                                 self.copyFile()
395
396                 if self.currList == "playlist":
397                         selection = self["playlist"].getSelection()
398                         self.changeEntry(self.playlist.getSelectionIndex())
399
400         def showMenu(self):
401                 menu = []
402                 if self.currList == "filelist":
403                         if self.filelist.canDescent():
404                                 menu.append((_("add directory to playlist"), "copydir"))
405                         else:
406                                 menu.append((_("add files to playlist"), "copyfiles"))
407                         menu.append((_("switch to playlist"), "playlist"))
408                 else:
409                         menu.append((_("switch to filelist"), "filelist"))
410
411                         menu.append((_("shuffle playlist"), "shuffle"))
412
413                         menu.append((_("delete"), "delete"))
414                         menu.append((_("clear playlist"), "clear"))
415                 menu.append((_("hide player"), "hide"));
416                 menu.append((_("save playlist"), "saveplaylist"));
417                 menu.append((_("load playlist"), "loadplaylist"));
418                 menu.append((_("delete saved playlist"), "deleteplaylist"));
419                 self.session.openWithCallback(self.menuCallback, ChoiceBox, title="", list=menu)
420
421         def menuCallback(self, choice):
422                 if choice is None:
423                         return
424
425                 if choice[1] == "copydir":
426                         self.copyDirectory(self.filelist.getSelection()[0])
427                 elif choice[1] == "copyfiles":
428                         self.stopEntry()
429                         self.playlist.clear()
430                         self.copyDirectory(os_path.dirname(self.filelist.getSelection()[0].getPath()) + "/", recursive = False)
431                         self.playServiceRefEntry(self.filelist.getServiceRef())
432                 elif choice[1] == "playlist":
433                         self.switchToPlayList()
434                 elif choice[1] == "filelist":
435                         self.switchToFileList()
436                 elif choice[1] == "delete":
437                         if self.playlist.getSelectionIndex() == self.playlist.getCurrentIndex():
438                                 self.stopEntry()
439                         self.deleteEntry()
440                 elif choice[1] == "clear":
441                         self.stopEntry()
442                         self.playlist.clear()
443                         self.switchToFileList()
444                 elif choice[1] == "hide":
445                         self.hide()
446                 elif choice[1] == "saveplaylist":
447                         self.save_playlist()
448                 elif choice[1] == "loadplaylist":
449                         self.load_playlist()
450                 elif choice[1] == "deleteplaylist":
451                         self.delete_saved_playlist()
452                 elif choice[1] == "shuffle":
453                         self.playlist.PlayListShuffle()
454
455
456         def showEventInformation(self):
457                 from Screens.EventView import EventViewSimple
458                 from ServiceReference import ServiceReference
459                 evt = self[self.currList].getCurrentEvent()
460                 if evt:
461                         self.session.open(EventViewSimple, evt, ServiceReference(self.getCurrent()))
462
463         # also works on filelist (?)
464         def getCurrent(self):
465                 return self["playlist"].getCurrent()
466
467         def deletePlaylistEntry(self):
468                 if self.currList == "playlist":
469                         if self.playlist.getSelectionIndex() == self.playlist.getCurrentIndex():
470                                 self.stopEntry()
471                         self.deleteEntry()
472
473         def skip_listbegin(self):
474                 if self.currList == "filelist":
475                         self.filelist.moveToIndex(0)
476                 else:
477                         self.playlist.moveToIndex(0)
478                 self.updateCurrentInfo()
479
480         def skip_listend(self):
481                 if self.currList == "filelist":
482                         idx = len(self.filelist.list)
483                         self.filelist.moveToIndex(idx - 1)
484                 else:
485                         self.playlist.moveToIndex(len(self.playlist)-1)
486                 self.updateCurrentInfo()
487
488         def save_playlist(self):
489                 self.session.openWithCallback(self.save_playlist2,InputBox, title=_("Please enter filename (empty = use current date)"),windowTitle = _("Save Playlist"))
490
491         def save_playlist2(self, name):
492                 if name is not None:
493                         name = name.strip()
494                         if name == "":
495                                 name = strftime("%y%m%d_%H%M%S")
496                         name += ".e2pls"
497                         self.playlistIOInternal.clear()
498                         for x in self.playlist.list:
499                                 self.playlistIOInternal.addService(ServiceReference(x[0]))
500                         self.playlistIOInternal.save(resolveFilename(SCOPE_PLAYLIST) + name)
501
502         def load_playlist(self):
503                 listpath = []
504                 playlistdir = resolveFilename(SCOPE_PLAYLIST)
505                 try:
506                         for i in os_listdir(playlistdir):
507                                 listpath.append((i,playlistdir + i))
508                 except IOError,e:
509                         print "Error while scanning subdirs ",e
510                 self.session.openWithCallback(self.PlaylistSelected, ChoiceBox, title=_("Please select a playlist..."), list = listpath)
511
512         def PlaylistSelected(self,path):
513                 if path is not None:
514                         self.clear_playlist()
515                         self.playlistIOInternal = PlaylistIOInternal()
516                         list = self.playlistIOInternal.open(path[1])
517                         if list:
518                                 for x in list:
519                                         self.playlist.addFile(x.ref)
520                                 self.playlist.updateList()
521
522         def delete_saved_playlist(self):
523                 listpath = []
524                 playlistdir = resolveFilename(SCOPE_PLAYLIST)
525                 try:
526                         for i in os_listdir(playlistdir):
527                                 listpath.append((i,playlistdir + i))
528                 except IOError,e:
529                         print "Error while scanning subdirs ",e
530                 self.session.openWithCallback(self.DeletePlaylistSelected, ChoiceBox, title=_("Please select a playlist to delete..."), list = listpath)
531
532         def DeletePlaylistSelected(self,path):
533                 if path is not None:
534                         self.delname = path[1]
535                         self.session.openWithCallback(self.deleteConfirmed, MessageBox, _("Do you really want to delete %s?") % (path[1]))
536
537         def deleteConfirmed(self, confirmed):
538                 if confirmed:
539                         os_remove(self.delname)
540
541         def clear_playlist(self):
542                 self.stopEntry()
543                 self.playlist.clear()
544                 self.switchToFileList()
545
546         def copyDirectory(self, directory, recursive = True):
547                 print "copyDirectory", directory
548                 filelist = FileList(directory, useServiceRef = True, isTop = True)
549
550                 for x in filelist.getFileList():
551                         if x[0][1] == True: #isDir
552                                 if recursive:
553                                         self.copyDirectory(x[0][0])
554                         else:
555                                 self.playlist.addFile(x[0][0])
556                 self.playlist.updateList()
557
558         def copyFile(self):
559                 if self.filelist.getServiceRef().type == 4098: # playlist
560                         ServiceRef = self.filelist.getServiceRef()
561                         extension = ServiceRef.getPath()[ServiceRef.getPath().rfind('.') + 1:]
562                         print "extension:", extension
563                         if self.playlistparsers.has_key(extension):
564                                 playlist = self.playlistparsers[extension]()
565                                 list = playlist.open(ServiceRef.getPath())
566                                 for x in list:
567                                         self.playlist.addFile(x.ref)
568                 else:
569                         self.playlist.addFile(self.filelist.getServiceRef())
570                         self.playlist.updateList()
571                         if len(self.playlist) == 1:
572                                 self.changeEntry(0)
573
574         def addPlaylistParser(self, parser, extension):
575                 self.playlistparsers[extension] = parser
576
577         def nextEntry(self):
578                 next = self.playlist.getCurrentIndex() + 1
579                 if next < len(self.playlist):
580                         self.changeEntry(next)
581
582         def previousEntry(self):
583                 next = self.playlist.getCurrentIndex() - 1
584                 if next >= 0:
585                         self.changeEntry(next)
586
587         def deleteEntry(self):
588                 self.playlist.deleteFile(self.playlist.getSelectionIndex())
589                 self.playlist.updateList()
590                 if len(self.playlist) == 0:
591                         self.switchToFileList()
592
593         def changeEntry(self, index):
594                 self.playlist.setCurrentPlaying(index)
595                 self.playEntry()
596
597         def playServiceRefEntry(self, serviceref):
598                 serviceRefList = self.playlist.getServiceRefList()
599                 for count in range(len(serviceRefList)):
600                         if serviceRefList[count] == serviceref:
601                                 self.changeEntry(count)
602                                 break
603
604         def playEntry(self):
605                 if len(self.playlist.getServiceRefList()):
606                         currref = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()]
607                         if self.session.nav.getCurrentlyPlayingServiceReference() is None or currref != self.session.nav.getCurrentlyPlayingServiceReference():
608                                 self.session.nav.playService(self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()])
609                                 info = eServiceCenter.getInstance().info(currref)
610                                 description = info and info.getInfoString(currref, iServiceInformation.sDescription) or ""
611                                 self["title"].setText(description)
612                                 # display just playing musik on LCD
613                                 idx = self.playlist.getCurrentIndex()
614                                 currref = self.playlist.getServiceRefList()[idx]
615                                 text = currref.getPath()
616                                 text = text.split('/')[-1]
617                                 text = ">"+text
618                                 ext = text[-3:].lower()
619
620                                 # FIXME: the information if the service contains video (and we should hide our window) should com from the service instead 
621                                 if ext not in ["mp3", "wav", "ogg"]:
622                                         self.hide()
623                                 self.summaries.setText(text,1)
624
625                                 # get the next two entries
626                                 idx += 1
627                                 if idx < len(self.playlist):
628                                         currref = self.playlist.getServiceRefList()[idx]
629                                         text = currref.getPath()
630                                         text = text.split('/')[-1]
631                                         self.summaries.setText(text,3)
632                                 else:
633                                         self.summaries.setText(" ",3)
634
635                                 idx += 1
636                                 if idx < len(self.playlist):
637                                         currref = self.playlist.getServiceRefList()[idx]
638                                         text = currref.getPath()
639                                         text = text.split('/')[-1]
640                                         self.summaries.setText(text,4)
641                                 else:
642                                         self.summaries.setText(" ",4)
643                         else:
644                                 idx = self.playlist.getCurrentIndex()
645                                 currref = self.playlist.getServiceRefList()[idx]
646                                 text = currref.getPath()
647                                 ext = text[-3:].lower()
648                                 if ext not in ["mp3", "wav", "ogg"]:
649                                         self.hide()
650                         self.unPauseService()
651
652         def updatedSeekState(self):
653                 if self.seekstate == self.SEEK_STATE_PAUSE:
654                         self.playlist.pauseFile()
655                 elif self.seekstate == self.SEEK_STATE_PLAY:
656                         self.playlist.playFile()
657                 elif self.seekstate in ( self.SEEK_STATE_FF_2X,
658                                                                  self.SEEK_STATE_FF_4X,
659                                                                  self.SEEK_STATE_FF_8X,
660                                                                  self.SEEK_STATE_FF_16X,
661                                                                  self.SEEK_STATE_FF_32X,
662                                                                  self.SEEK_STATE_FF_48X,
663                                                                  self.SEEK_STATE_FF_64X,
664                                                                  self.SEEK_STATE_FF_128X):
665                         self.playlist.forwardFile()
666                 elif self.seekstate in ( self.SEEK_STATE_BACK_8X,
667                                                                  self.SEEK_STATE_BACK_16X,
668                                                                  self.SEEK_STATE_BACK_32X,
669                                                                  self.SEEK_STATE_BACK_48X,
670                                                                  self.SEEK_STATE_BACK_64X,
671                                                                  self.SEEK_STATE_BACK_128X):
672                         self.playlist.rewindFile()
673
674         def pauseEntry(self):
675                 self.pauseService()
676                 self.show()
677
678         def stopEntry(self):
679                 self.playlist.stopFile()
680                 self.session.nav.playService(None)
681                 self.updateMusicInformation(clear=True)
682                 self.show()
683
684         def unPauseService(self):
685                 self.setSeekState(self.SEEK_STATE_PLAY)
686
687
688 class MediaPlayerLCDScreen(Screen):
689         skin = """
690         <screen position="0,0" size="132,64" title="LCD Text">
691                 <widget name="text1" position="4,0" size="132,35" font="Regular;16"/>
692                 <widget name="text3" position="4,36" size="132,14" font="Regular;10"/>
693                 <widget name="text4" position="4,49" size="132,14" font="Regular;10"/>
694         </screen>"""
695
696         def __init__(self, session, parent):
697                 Screen.__init__(self, session)
698                 self["text1"] = Label("Mediaplayer")
699                 self["text3"] = Label("")
700                 self["text4"] = Label("")
701
702         def setText(self, text, line):
703                 print "lcd set text:", text, line
704                 if len(text) > 10:
705                         if text[-4:] == ".mp3":
706                                 text = text[:-4]
707                 textleer = "    "
708                 text = text + textleer*10
709                 if line == 1:
710                         self["text1"].setText(text)
711                 elif line == 3:
712                         self["text3"].setText(text)
713                 elif line == 4:
714                         self["text4"].setText(text)
715
716 def main(session, **kwargs):
717         session.open(MediaPlayer)
718
719 def menu(menuid, **kwargs):
720         if menuid == "mainmenu":
721                 return [(_("Media player"), main, "media_player", 45)]
722         return []
723
724 def filescan_open(list, session, **kwargs):
725         from enigma import eServiceReference
726
727         mp = session.open(MediaPlayer)
728
729         mp.switchToPlayList()
730         for file in list:
731                 ref = eServiceReference(4097, 0, file.path)
732                 mp.playlist.addFile(ref)
733
734         # TODO: rather play first than last file?
735         mp.playServiceRefEntry(ref)
736         mp.playlist.updateList()
737
738 def filescan(**kwargs):
739         from Components.Scanner import Scanner, ScanPath
740         return [
741                 Scanner(mimetypes = ["video/mpeg"],
742                         paths_to_scan =
743                                 [
744                                         ScanPath(path = "", with_subdirs = False),
745                                 ],
746                         name = "Movie",
747                         description = "View Movies...",
748                         openfnc = filescan_open,
749                 ),
750                 Scanner(mimetypes = ["audio/mpeg", "audio/x-wav", "application/ogg"],
751                         paths_to_scan =
752                                 [
753                                         ScanPath(path = "", with_subdirs = False),
754                                 ],
755                         name = "Music",
756                         description = "Play Music...",
757                         openfnc = filescan_open,
758                 )
759         ]
760
761 from Plugins.Plugin import PluginDescriptor
762 def Plugins(**kwargs):
763         return [
764                 PluginDescriptor(name = "MediaPlayer", description = "Play back media files", where = PluginDescriptor.WHERE_MENU, fnc = menu),
765                 PluginDescriptor(name = "MediaPlayer", where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan)
766         ]