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