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 iPlayableService, eTimer, eServiceCenter, iServiceInformation, loadPic
4 from ServiceReference import ServiceReference
5 from Screens.Screen import Screen
6 from Screens.HelpMenu import HelpableScreen
7 from Screens.MessageBox import MessageBox
8 from Screens.InputBox import InputBox
9 from Screens.ChoiceBox import ChoiceBox
10 from Screens.InfoBarGenerics import InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSupport, InfoBarNotifications, InfoBarSubtitleSupport
11 from Components.ActionMap import NumberActionMap, HelpableActionMap
12 from Components.Label import Label
13 from Components.Pixmap import Pixmap,MultiPixmap
14 from Components.FileList import FileList
15 from Components.MediaPlayer import PlayList
16 from Components.ServicePosition import ServicePositionGauge
17 from Components.ServiceEventTracker import ServiceEventTracker, InfoBarBase
18 from Components.Playlist import PlaylistIOInternal, PlaylistIOM3U, PlaylistIOPLS
19 from Components.AVSwitch import AVSwitch
20 from Components.Harddisk import harddiskmanager
21 from Components.config import config
22 from Tools.Directories import fileExists, pathExists, resolveFilename, SCOPE_CONFIG, SCOPE_PLAYLIST, SCOPE_SKIN_IMAGE
23 from settings import MediaPlayerSettings
24 from Plugins.SystemPlugins.Hotplug.plugin import hotplugNotifier
27 class MyPlayList(PlayList):
29 PlayList.__init__(self)
31 def PlayListShuffle(self):
32 random.shuffle(self.list)
33 self.l.setList(self.list)
35 self.oldCurrPlaying = -1
37 class MediaPixmap(Pixmap):
38 def applySkin(self, desktop, screen):
39 self.default_pixmap = None
40 if self.skinAttributes is not None:
41 for (attrib, value) in self.skinAttributes:
42 if attrib == "pixmap":
43 self.default_pixmap = value
45 if self.default_pixmap is None:
46 self.default_pixmap = resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/no_coverArt.png")
47 self.coverFileNames = ["folder.png", "folder.jpg"]
48 return Pixmap.applySkin(self, desktop, screen)
50 class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSupport, InfoBarNotifications, InfoBarSubtitleSupport, HelpableScreen):
52 ENABLE_RESUME_SUPPORT = True
54 def __init__(self, session, args = None):
55 Screen.__init__(self, session)
56 InfoBarAudioSelection.__init__(self)
57 InfoBarCueSheetSupport.__init__(self, actionmap = "MediaPlayerCueSheetActions")
58 InfoBarNotifications.__init__(self)
59 InfoBarBase.__init__(self)
60 InfoBarSubtitleSupport.__init__(self)
61 HelpableScreen.__init__(self)
63 self.oldService = self.session.nav.getCurrentlyPlayingServiceReference()
64 self.session.nav.stopService()
66 self.playlistparsers = {}
67 self.addPlaylistParser(PlaylistIOM3U, "m3u")
68 self.addPlaylistParser(PlaylistIOPLS, "pls")
69 self.addPlaylistParser(PlaylistIOInternal, "e2pls")
71 # 'None' is magic to start at the list of mountpoints
72 defaultDir = config.mediaplayer.defaultDir.getValue()
73 self.filelist = FileList(defaultDir, matchingPattern = "(?i)^.*\.(mp2|mp3|ogg|ts|wav|wave|m3u|pls|e2pls|mpg|vob|avi|mkv|mp4|dat|flac)", useServiceRef = True, additionalExtensions = "4098:m3u 4098:e2pls 4098:pls")
74 self["filelist"] = self.filelist
76 self.playlist = MyPlayList()
77 #self.playlist = PlayList()
78 self.is_closing = False
80 self["playlist"] = self.playlist
82 self["PositionGauge"] = ServicePositionGauge(self.session.nav)
84 self["currenttext"] = Label("")
86 self["artisttext"] = Label(_("Artist:"))
87 self["artist"] = Label("")
88 self["titletext"] = Label(_("Title:"))
89 self["title"] = Label("")
90 self["albumtext"] = Label(_("Album:"))
91 self["album"] = Label("")
92 self["yeartext"] = Label(_("Year:"))
93 self["year"] = Label("")
94 self["genretext"] = Label(_("Genre:"))
95 self["genre"] = Label("")
96 self["coverArt"] = MediaPixmap()
97 self["repeat"] = MultiPixmap()
99 self.seek_target = None
100 hotplugNotifier.append(self.hotplugCB)
102 class MoviePlayerActionMap(NumberActionMap):
103 def __init__(self, player, contexts = [ ], actions = { }, prio=0):
104 NumberActionMap.__init__(self, contexts, actions, prio)
107 def action(self, contexts, action):
109 return NumberActionMap.action(self, contexts, action)
112 self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions",
114 "ok": (self.ok, _("add file to playlist")),
115 "cancel": (self.exit, _("exit mediaplayer")),
118 self["MediaPlayerActions"] = HelpableActionMap(self, "MediaPlayerActions",
120 "play": (self.xplayEntry, _("play entry")),
121 "pause": (self.pauseEntry, _("pause")),
122 "stop": (self.stopEntry, _("stop entry")),
123 "previous": (self.previousMarkOrEntry, _("play from previous mark or playlist entry")),
124 "next": (self.nextMarkOrEntry, _("play from next mark or playlist entry")),
125 "menu": (self.showMenu, _("menu")),
126 "skipListbegin": (self.skip_listbegin, _("jump to listbegin")),
127 "skipListend": (self.skip_listend, _("jump to listend")),
128 "prevBouquet": (self.switchToPlayList, _("switch to playlist")),
129 "nextBouquet": (self.switchToFileList, _("switch to filelist")),
130 "delete": (self.deletePlaylistEntry, _("delete playlist entry")),
131 "shift_stop": (self.clear_playlist, _("clear playlist")),
132 "shift_record": (self.playlist.PlayListShuffle, _("shuffle playlist")),
133 "subtitles": (self.subtitleSelection, _("Subtitle selection")),
136 self["InfobarEPGActions"] = HelpableActionMap(self, "InfobarEPGActions",
138 "showEventInfo": (self.showEventInformation, _("show event details")),
141 self["actions"] = MoviePlayerActionMap(self, ["DirectionActions"],
143 "right": self.rightDown,
144 "rightRepeated": self.doNothing,
145 "rightUp": self.rightUp,
146 "left": self.leftDown,
147 "leftRepeated": self.doNothing,
148 "leftUp": self.leftUp,
151 "upRepeated": self.up,
152 "upUp": self.doNothing,
154 "downRepeated": self.down,
155 "downUp": self.doNothing,
158 InfoBarSeek.__init__(self, actionmap = "MediaPlayerSeekActions")
160 self.onClose.append(self.delMPTimer)
161 self.onClose.append(self.__onClose)
163 self.righttimer = False
164 self.rightKeyTimer = eTimer()
165 self.rightKeyTimer.callback.append(self.rightTimerFire)
167 self.lefttimer = False
168 self.leftKeyTimer = eTimer()
169 self.leftKeyTimer.callback.append(self.leftTimerFire)
171 self.currList = "filelist"
173 self.coverArtFileName = ""
174 self.isAudioCD = False
175 self.AudioCD_albuminfo = {}
176 self.cdAudioTrackFiles = []
179 self.playlistIOInternal = PlaylistIOInternal()
180 list = self.playlistIOInternal.open(resolveFilename(SCOPE_CONFIG, "playlist.e2pls"))
183 self.playlist.addFile(x.ref)
184 self.playlist.updateList()
186 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
188 iPlayableService.evUpdatedInfo: self.__evUpdatedInfo,
189 iPlayableService.evUser+11: self.__evDecodeError,
190 iPlayableService.evUser+12: self.__evPluginError
196 def createSummary(self):
197 return MediaPlayerLCDScreen
200 self.playlistIOInternal.clear()
201 for x in self.playlist.list:
202 self.playlistIOInternal.addService(ServiceReference(x[0]))
203 if self.savePlaylistOnExit:
204 self.playlistIOInternal.save(resolveFilename(SCOPE_CONFIG, "playlist.e2pls"))
205 if config.mediaplayer.saveDirOnExit.getValue():
206 config.mediaplayer.defaultDir.setValue(self.filelist.getCurrentDirectory())
207 config.mediaplayer.defaultDir.save()
208 hotplugNotifier.remove(self.hotplugCB)
211 def checkSkipShowHideLock(self):
212 self.updatedSeekState()
214 def doEofInternal(self, playing):
221 self.session.nav.playService(self.oldService)
223 def __evUpdatedInfo(self):
224 currPlay = self.session.nav.getCurrentService()
225 currenttitle = currPlay.info().getInfo(iServiceInformation.sCurrentTitle)
226 totaltitles = currPlay.info().getInfo(iServiceInformation.sTotalTitles)
227 sTitle = currPlay.info().getInfoString(iServiceInformation.sTitle)
228 print "[__evUpdatedInfo] title %d of %d (%s)" % (currenttitle, totaltitles, sTitle)
229 self.readTitleInformation()
231 def __evDecodeError(self):
232 currPlay = self.session.nav.getCurrentService()
233 sVideoType = currPlay.info().getInfoString(iServiceInformation.sVideoType)
234 print "[__evDecodeError] video-codec %s can't be decoded by hardware" % (sVideoType)
235 self.session.open(MessageBox, _("This Dreambox can't decode %s video streams!") % sVideoType, type = MessageBox.TYPE_INFO,timeout = 20 )
237 def __evPluginError(self):
238 currPlay = self.session.nav.getCurrentService()
239 message = currPlay.info().getInfoString(iServiceInformation.sUser+12)
240 print "[__evPluginError]" , message
241 self.session.open(MessageBox, message, type = MessageBox.TYPE_INFO,timeout = 20 )
243 def delMPTimer(self):
244 del self.rightKeyTimer
245 del self.leftKeyTimer
247 def readTitleInformation(self):
248 currPlay = self.session.nav.getCurrentService()
249 if currPlay is not None:
250 sTitle = currPlay.info().getInfoString(iServiceInformation.sTitle)
251 sAlbum = currPlay.info().getInfoString(iServiceInformation.sAlbum)
252 sGenre = currPlay.info().getInfoString(iServiceInformation.sGenre)
253 sArtist = currPlay.info().getInfoString(iServiceInformation.sArtist)
254 sYear = currPlay.info().getInfoString(iServiceInformation.sTimeCreate)
257 if not self.isAudioCD:
258 sTitle = currPlay.info().getName().split('/')[-1]
260 sTitle = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()].getName()
262 if self.AudioCD_albuminfo:
263 if sAlbum == "" and "title" in self.AudioCD_albuminfo:
264 sAlbum = self.AudioCD_albuminfo["title"]
265 if sGenre == "" and "genre" in self.AudioCD_albuminfo:
266 sGenre = self.AudioCD_albuminfo["genre"]
267 if sArtist == "" and "artist" in self.AudioCD_albuminfo:
268 sArtist = self.AudioCD_albuminfo["artist"]
269 if "year" in self.AudioCD_albuminfo:
270 sYear = self.AudioCD_albuminfo["year"]
272 self.updateMusicInformation( sArtist, sTitle, sAlbum, sYear, sGenre, clear = True )
274 self.updateMusicInformation()
276 def updateMusicInformation(self, artist = "", title = "", album = "", year = "", genre = "", clear = False):
277 self.updateSingleMusicInformation("artist", artist, clear)
278 self.updateSingleMusicInformation("title", title, clear)
279 self.updateSingleMusicInformation("album", album, clear)
280 self.updateSingleMusicInformation("year", year, clear)
281 self.updateSingleMusicInformation("genre", genre, clear)
283 def updateSingleMusicInformation(self, name, info, clear):
284 if info != "" or clear:
285 if self[name].getText() != info:
286 self[name].setText(info)
288 def updateCoverArtPixmap(self, path):
289 while not path.endswith("/"):
291 new_coverArtFileName = self["coverArt"].default_pixmap
292 for filename in self["coverArt"].coverFileNames:
293 if fileExists(path + filename):
294 new_coverArtFileName = path + filename
295 if self.coverArtFileName != new_coverArtFileName:
296 self.coverArtFileName = new_coverArtFileName
297 pixmap = loadPic(self.coverArtFileName, 116, 116, AVSwitch().getAspectRatioSetting()/2,1,0,0)
298 if pixmap is not None:
299 self["coverArt"].instance.setPixmap(pixmap.__deref__())
302 self.lefttimer = True
303 self.leftKeyTimer.start(1000)
306 self.righttimer = True
307 self.rightKeyTimer.start(1000)
311 self.leftKeyTimer.stop()
312 self.lefttimer = False
313 self[self.currList].pageUp()
314 self.updateCurrentInfo()
318 self.rightKeyTimer.stop()
319 self.righttimer = False
320 self[self.currList].pageDown()
321 self.updateCurrentInfo()
323 def leftTimerFire(self):
324 self.leftKeyTimer.stop()
325 self.lefttimer = False
326 self.switchToFileList()
328 def rightTimerFire(self):
329 self.rightKeyTimer.stop()
330 self.righttimer = False
331 self.switchToPlayList()
333 def switchToFileList(self):
334 self.currList = "filelist"
335 self.filelist.selectionEnabled(1)
336 self.playlist.selectionEnabled(0)
337 self.updateCurrentInfo()
339 def switchToPlayList(self):
340 if len(self.playlist) != 0:
341 self.currList = "playlist"
342 self.filelist.selectionEnabled(0)
343 self.playlist.selectionEnabled(1)
344 self.updateCurrentInfo()
347 self[self.currList].up()
348 self.updateCurrentInfo()
351 self[self.currList].down()
352 self.updateCurrentInfo()
354 def showAfterSeek(self):
357 def showAfterCuesheetOperation(self):
360 def hideAfterResume(self):
363 def getIdentifier(self, ref):
368 return text.split('/')[-1]
370 # FIXME: maybe this code can be optimized
371 def updateCurrentInfo(self):
373 if self.currList == "filelist":
374 idx = self.filelist.getSelectionIndex()
375 r = self.filelist.list[idx]
382 self.summaries.setText(text,1)
385 if idx < len(self.filelist.list):
386 r = self.filelist.list[idx]
390 self.summaries.setText(text,3)
392 self.summaries.setText(" ",3)
395 if idx < len(self.filelist.list):
396 r = self.filelist.list[idx]
400 self.summaries.setText(text,4)
402 self.summaries.setText(" ",4)
405 if not self.filelist.canDescent():
406 r = self.filelist.getServiceRef()
410 self["currenttext"].setText(os_path.basename(text))
412 if self.currList == "playlist":
413 t = self.playlist.getSelection()
416 #display current selected entry on LCD
417 text = self.getIdentifier(t)
418 self.summaries.setText(text,1)
419 self["currenttext"].setText(text)
420 idx = self.playlist.getSelectionIndex()
422 if idx < len(self.playlist):
423 currref = self.playlist.getServiceRefList()[idx]
424 text = self.getIdentifier(currref)
425 self.summaries.setText(text,3)
427 self.summaries.setText(" ",3)
430 if idx < len(self.playlist):
431 currref = self.playlist.getServiceRefList()[idx]
432 text = self.getIdentifier(currref)
433 self.summaries.setText(text,4)
435 self.summaries.setText(" ",4)
438 if self.currList == "filelist":
439 if self.filelist.canDescent():
440 self.filelist.descent()
441 self.updateCurrentInfo()
445 if self.currList == "playlist":
446 selection = self["playlist"].getSelection()
447 self.changeEntry(self.playlist.getSelectionIndex())
451 if len(self.cdAudioTrackFiles):
452 menu.insert(0,(_("Play Audio-CD..."), "audiocd"))
453 if self.currList == "filelist":
454 if self.filelist.canDescent():
455 menu.append((_("add directory to playlist"), "copydir"))
457 menu.append((_("add files to playlist"), "copyfiles"))
458 menu.append((_("switch to playlist"), "playlist"))
459 menu.append((_("delete file"), "deletefile"))
461 menu.append((_("switch to filelist"), "filelist"))
462 menu.append((_("shuffle playlist"), "shuffle"))
463 menu.append((_("Delete entry"), "deleteentry"))
464 menu.append((_("clear playlist"), "clear"))
465 menu.append((_("hide player"), "hide"));
466 menu.append((_("save playlist"), "saveplaylist"));
467 menu.append((_("load playlist"), "loadplaylist"));
468 menu.append((_("delete saved playlist"), "deleteplaylist"));
469 menu.append((_("Edit settings"), "settings"))
470 self.session.openWithCallback(self.menuCallback, ChoiceBox, title="", list=menu)
472 def menuCallback(self, choice):
476 if choice[1] == "copydir":
477 self.copyDirectory(self.filelist.getSelection()[0])
478 elif choice[1] == "copyfiles":
480 self.playlist.clear()
481 self.isAudioCD = False
482 self.copyDirectory(os_path.dirname(self.filelist.getSelection()[0].getPath()) + "/", recursive = False)
483 self.playServiceRefEntry(self.filelist.getServiceRef())
484 elif choice[1] == "playlist":
485 self.switchToPlayList()
486 elif choice[1] == "filelist":
487 self.switchToFileList()
488 elif choice[1] == "deleteentry":
489 if self.playlist.getSelectionIndex() == self.playlist.getCurrentIndex():
492 elif choice[1] == "clear":
493 self.clear_playlist()
494 elif choice[1] == "hide":
496 elif choice[1] == "saveplaylist":
498 elif choice[1] == "loadplaylist":
500 elif choice[1] == "deleteplaylist":
501 self.delete_saved_playlist()
502 elif choice[1] == "shuffle":
503 self.playlist.PlayListShuffle()
504 elif choice[1] == "deletefile":
506 elif choice[1] == "settings":
507 self.session.openWithCallback(self.applySettings, MediaPlayerSettings, self)
508 elif choice[1] == "audiocd":
511 def playAudioCD(self):
512 from enigma import eServiceReference
513 from Plugins.Extensions.CDInfo.plugin import Query
515 if len(self.cdAudioTrackFiles):
516 self.playlist.clear()
517 self.savePlaylistOnExit = False
518 self.isAudioCD = True
519 for file in self.cdAudioTrackFiles:
520 ref = eServiceReference(4097, 0, file)
521 self.playlist.addFile(ref)
525 self.switchToPlayList()
527 def applySettings(self):
528 self.savePlaylistOnExit = config.mediaplayer.savePlaylistOnExit.getValue()
529 if config.mediaplayer.repeat.getValue() == True:
530 self["repeat"].setPixmapNum(1)
532 self["repeat"].setPixmapNum(0)
534 def showEventInformation(self):
535 from Screens.EventView import EventViewSimple
536 from ServiceReference import ServiceReference
537 evt = self[self.currList].getCurrentEvent()
539 self.session.open(EventViewSimple, evt, ServiceReference(self.getCurrent()))
541 # also works on filelist (?)
542 def getCurrent(self):
543 return self["playlist"].getCurrent()
545 def deletePlaylistEntry(self):
546 if self.currList == "playlist":
547 if self.playlist.getSelectionIndex() == self.playlist.getCurrentIndex():
551 def skip_listbegin(self):
552 if self.currList == "filelist":
553 self.filelist.moveToIndex(0)
555 self.playlist.moveToIndex(0)
556 self.updateCurrentInfo()
558 def skip_listend(self):
559 if self.currList == "filelist":
560 idx = len(self.filelist.list)
561 self.filelist.moveToIndex(idx - 1)
563 self.playlist.moveToIndex(len(self.playlist)-1)
564 self.updateCurrentInfo()
566 def save_playlist(self):
567 self.session.openWithCallback(self.save_playlist2,InputBox, title=_("Please enter filename (empty = use current date)"),windowTitle = _("Save Playlist"))
569 def save_playlist2(self, name):
573 name = strftime("%y%m%d_%H%M%S")
575 self.playlistIOInternal.clear()
576 for x in self.playlist.list:
577 self.playlistIOInternal.addService(ServiceReference(x[0]))
578 self.playlistIOInternal.save(resolveFilename(SCOPE_PLAYLIST) + name)
580 def load_playlist(self):
582 playlistdir = resolveFilename(SCOPE_PLAYLIST)
584 for i in os_listdir(playlistdir):
585 listpath.append((i,playlistdir + i))
587 print "Error while scanning subdirs ",e
588 self.session.openWithCallback(self.PlaylistSelected, ChoiceBox, title=_("Please select a playlist..."), list = listpath)
590 def PlaylistSelected(self,path):
592 self.clear_playlist()
593 extension = path[0].rsplit('.',1)[-1]
594 if self.playlistparsers.has_key(extension):
595 playlist = self.playlistparsers[extension]()
596 list = playlist.open(path[1])
598 self.playlist.addFile(x.ref)
599 self.playlist.updateList()
601 def delete_saved_playlist(self):
603 playlistdir = resolveFilename(SCOPE_PLAYLIST)
605 for i in os_listdir(playlistdir):
606 listpath.append((i,playlistdir + i))
608 print "Error while scanning subdirs ",e
609 self.session.openWithCallback(self.DeletePlaylistSelected, ChoiceBox, title=_("Please select a playlist to delete..."), list = listpath)
611 def DeletePlaylistSelected(self,path):
613 self.delname = path[1]
614 self.session.openWithCallback(self.deleteConfirmed, MessageBox, _("Do you really want to delete %s?") % (path[1]))
616 def deleteConfirmed(self, confirmed):
619 os_remove(self.delname)
621 print "delete failed:", e
622 self.session.open(MessageBox, _("Delete failed!"), MessageBox.TYPE_ERROR)
624 def clear_playlist(self):
625 self.isAudioCD = False
627 self.playlist.clear()
628 self.switchToFileList()
630 def copyDirectory(self, directory, recursive = True):
631 print "copyDirectory", directory
632 filelist = FileList(directory, useServiceRef = True, isTop = True)
634 for x in filelist.getFileList():
635 if x[0][1] == True: #isDir
637 self.copyDirectory(x[0][0])
638 elif filelist.getServiceRef() and filelist.getServiceRef().type == 4097:
639 self.playlist.addFile(x[0][0])
640 self.playlist.updateList()
642 def deleteFile(self):
643 if self.currList == "filelist":
644 self.service = self.filelist.getServiceRef()
646 self.service = self.playlist.getSelection()
647 if self.service is None:
649 if self.service.type != 4098 and self.session.nav.getCurrentlyPlayingServiceReference() is not None:
650 if self.service == self.session.nav.getCurrentlyPlayingServiceReference():
653 serviceHandler = eServiceCenter.getInstance()
654 offline = serviceHandler.offlineOperations(self.service)
655 info = serviceHandler.info(self.service)
656 name = info and info.getName(self.service)
658 if offline is not None:
660 if not offline.deleteFromDisk(1):
663 self.session.openWithCallback(self.deleteConfirmed_offline, MessageBox, _("Do you really want to delete %s?") % (name))
665 self.session.openWithCallback(self.close, MessageBox, _("You cannot delete this!"), MessageBox.TYPE_ERROR)
667 def deleteConfirmed_offline(self, confirmed):
669 serviceHandler = eServiceCenter.getInstance()
670 offline = serviceHandler.offlineOperations(self.service)
672 if offline is not None:
674 if not offline.deleteFromDisk(0):
677 self.session.open(MessageBox, _("Delete failed!"), MessageBox.TYPE_ERROR)
679 self.removeListEntry()
681 def removeListEntry(self):
682 currdir = self.filelist.getCurrentDirectory()
683 self.filelist.changeDir(currdir)
688 if len(self.playlist) > 0:
689 for x in self.playlist.list:
690 if self.service == x[0]:
691 self.playlist.deleteFile(index)
695 self.playlist.updateList()
696 if self.currList == "playlist":
697 if len(self.playlist) == 0:
698 self.switchToFileList()
701 if self.filelist.getServiceRef().type == 4098: # playlist
702 ServiceRef = self.filelist.getServiceRef()
703 extension = ServiceRef.getPath()[ServiceRef.getPath().rfind('.') + 1:]
704 if self.playlistparsers.has_key(extension):
705 playlist = self.playlistparsers[extension]()
706 list = playlist.open(ServiceRef.getPath())
708 self.playlist.addFile(x.ref)
709 self.playlist.updateList()
711 self.playlist.addFile(self.filelist.getServiceRef())
712 self.playlist.updateList()
713 if len(self.playlist) == 1:
716 def addPlaylistParser(self, parser, extension):
717 self.playlistparsers[extension] = parser
720 next = self.playlist.getCurrentIndex() + 1
721 if next < len(self.playlist):
722 self.changeEntry(next)
723 elif ( len(self.playlist) > 0 ) and ( config.mediaplayer.repeat.getValue() == True ):
727 def nextMarkOrEntry(self):
728 if not self.jumpPreviousNextMark(lambda x: x):
729 next = self.playlist.getCurrentIndex() + 1
730 if next < len(self.playlist):
731 self.changeEntry(next)
735 def previousMarkOrEntry(self):
736 if not self.jumpPreviousNextMark(lambda x: -x-5*90000, start=True):
737 next = self.playlist.getCurrentIndex() - 1
739 self.changeEntry(next)
741 def deleteEntry(self):
742 self.playlist.deleteFile(self.playlist.getSelectionIndex())
743 self.playlist.updateList()
744 if len(self.playlist) == 0:
745 self.switchToFileList()
747 def changeEntry(self, index):
748 self.playlist.setCurrentPlaying(index)
751 def playServiceRefEntry(self, serviceref):
752 serviceRefList = self.playlist.getServiceRefList()
753 for count in range(len(serviceRefList)):
754 if serviceRefList[count] == serviceref:
755 self.changeEntry(count)
758 def xplayEntry(self):
759 if self.currList == "playlist":
763 self.playlist.clear()
764 self.isAudioCD = False
765 sel = self.filelist.getSelection()
767 if sel[1]: # can descent
768 # add directory to playlist
769 self.copyDirectory(sel[0])
771 # add files to playlist
772 self.copyDirectory(os_path.dirname(sel[0].getPath()) + "/", recursive = False)
773 if len(self.playlist) > 0:
777 if len(self.playlist.getServiceRefList()):
778 needsInfoUpdate = False
779 currref = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()]
780 if self.session.nav.getCurrentlyPlayingServiceReference() is None or currref != self.session.nav.getCurrentlyPlayingServiceReference():
781 self.session.nav.playService(self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()])
782 info = eServiceCenter.getInstance().info(currref)
783 description = info and info.getInfoString(currref, iServiceInformation.sDescription) or ""
784 self["title"].setText(description)
785 # display just playing musik on LCD
786 idx = self.playlist.getCurrentIndex()
787 currref = self.playlist.getServiceRefList()[idx]
788 text = self.getIdentifier(currref)
790 ext = text[-4:].lower()
792 # FIXME: the information if the service contains video (and we should hide our window) should com from the service instead
793 if ext not in [".mp2", ".mp3", ".wav", ".ogg", "flac"] and not self.isAudioCD:
796 needsInfoUpdate = True
797 self.summaries.setText(text,1)
799 # get the next two entries
801 if idx < len(self.playlist):
802 currref = self.playlist.getServiceRefList()[idx]
803 text = self.getIdentifier(currref)
804 self.summaries.setText(text,3)
806 self.summaries.setText(" ",3)
809 if idx < len(self.playlist):
810 currref = self.playlist.getServiceRefList()[idx]
811 text = self.getIdentifier(currref)
812 self.summaries.setText(text,4)
814 self.summaries.setText(" ",4)
816 idx = self.playlist.getCurrentIndex()
817 currref = self.playlist.getServiceRefList()[idx]
818 text = currref.getPath()
819 ext = text[-4:].lower()
820 if ext not in [".mp2", ".mp3", ".wav", ".ogg", "flac"] and not self.isAudioCD:
823 needsInfoUpdate = True
825 self.unPauseService()
826 if needsInfoUpdate == True:
827 path = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()].getPath()
828 self.updateCoverArtPixmap(path)
830 pngname = self["coverArt"].default_pixmap
831 self.coverArtFileName = pngname
832 self["coverArt"].instance.setPixmapFromFile(self.coverArtFileName)
833 self.readTitleInformation()
835 def updatedSeekState(self):
836 if self.seekstate == self.SEEK_STATE_PAUSE:
837 self.playlist.pauseFile()
838 elif self.seekstate == self.SEEK_STATE_PLAY:
839 self.playlist.playFile()
840 elif self.isStateForward(self.seekstate):
841 self.playlist.forwardFile()
842 elif self.isStateBackward(self.seekstate):
843 self.playlist.rewindFile()
845 def pauseEntry(self):
847 if self.seekstate == self.SEEK_STATE_PAUSE:
853 self.playlist.stopFile()
854 self.session.nav.playService(None)
855 self.updateMusicInformation(clear=True)
858 def unPauseService(self):
859 self.setSeekState(self.SEEK_STATE_PLAY)
861 def subtitleSelection(self):
862 from Screens.Subtitles import Subtitles
863 self.session.open(Subtitles)
865 def hotplugCB(self, dev, media_state):
866 if dev == harddiskmanager.getCD():
867 from Components.Scanner import scanDevice
868 devpath = harddiskmanager.getAutofsMountpoint(harddiskmanager.getCD())
869 self.cdAudioTrackFiles = []
870 res = scanDevice(devpath)
871 list = [ (r.description, r, res[r], self.session) for r in res ]
873 (desc, scanner, files, session) = list[0]
875 if file.mimetype == "audio/x-cda":
876 self.cdAudioTrackFiles.append(file.path)
878 class MediaPlayerLCDScreen(Screen):
880 <screen position="0,0" size="132,64" title="LCD Text">
881 <widget name="text1" position="4,0" size="132,35" font="Regular;16"/>
882 <widget name="text3" position="4,36" size="132,14" font="Regular;10"/>
883 <widget name="text4" position="4,49" size="132,14" font="Regular;10"/>
886 def __init__(self, session, parent):
887 Screen.__init__(self, session)
888 self["text1"] = Label("Mediaplayer")
889 self["text3"] = Label("")
890 self["text4"] = Label("")
892 def setText(self, text, line):
894 if text[-4:] == ".mp3":
897 text = text + textleer*10
899 self["text1"].setText(text)
901 self["text3"].setText(text)
903 self["text4"].setText(text)
905 def main(session, **kwargs):
906 session.open(MediaPlayer)
908 def menu(menuid, **kwargs):
909 if menuid == "mainmenu":
910 return [(_("Media player"), main, "media_player", 45)]
913 def filescan_open(list, session, **kwargs):
914 from enigma import eServiceReference
916 mp = session.open(MediaPlayer)
918 mp.savePlaylistOnExit = False
921 if file.mimetype == "video/MP2T":
925 ref = eServiceReference(stype, 0, file.path)
926 mp.playlist.addFile(ref)
929 mp.switchToPlayList()
931 def audioCD_open(list, session, **kwargs):
932 from enigma import eServiceReference
934 mp = session.open(MediaPlayer)
935 mp.cdAudioTrackFiles = []
937 mp.cdAudioTrackFiles.append(file.path)
940 def filescan(**kwargs):
941 from Components.Scanner import Scanner, ScanPath
943 Scanner(mimetypes = ["video/mpeg", "video/MP2T", "video/x-msvideo"],
946 ScanPath(path = "", with_subdirs = False),
949 description = "View Movies...",
950 openfnc = filescan_open,
952 Scanner(mimetypes = ["video/x-vcd"],
955 ScanPath(path = "mpegav", with_subdirs = False),
956 ScanPath(path = "MPEGAV", with_subdirs = False),
959 description = "View Video CD...",
960 openfnc = filescan_open,
962 Scanner(mimetypes = ["audio/mpeg", "audio/x-wav", "application/ogg", "audio/x-flac"],
965 ScanPath(path = "", with_subdirs = False),
968 description = "Play Music...",
969 openfnc = filescan_open,
972 from Plugins.Extensions.CDInfo.plugin import Query
974 Scanner(mimetypes = ["audio/x-cda"],
977 ScanPath(path = "", with_subdirs = False),
980 description = "Play Audio-CD...",
981 openfnc = audioCD_open,
987 from Plugins.Plugin import PluginDescriptor
988 def Plugins(**kwargs):
990 PluginDescriptor(name = "MediaPlayer", description = "Play back media files", where = PluginDescriptor.WHERE_MENU, fnc = menu),
991 PluginDescriptor(name = "MediaPlayer", where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan)