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, ePicLoad
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):
40 self.coverArtFileName = ""
41 self.picload = ePicLoad()
42 self.picload.PictureData.get().append(self.paintCoverArtPixmapCB)
43 self.coverFileNames = ["folder.png", "folder.jpg"]
45 def applySkin(self, desktop, screen):
46 from Tools.LoadPixmap import LoadPixmap
47 if self.skinAttributes is not None:
48 for (attrib, value) in self.skinAttributes:
49 if attrib == "pixmap":
52 if noCoverFile is None:
53 noCoverFile = resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/no_coverArt.png")
54 self.noCoverPixmap = LoadPixmap(noCoverFile)
55 return Pixmap.applySkin(self, desktop, screen)
59 sc = AVSwitch().getFramebufferScale()
60 #0=Width 1=Height 2=Aspect 3=use_cache 4=resize_type 5=Background(#AARRGGBB)
61 self.picload.setPara((self.instance.size().width(), self.instance.size().height(), sc[0], sc[1], False, 1, "#00000000"))
63 def paintCoverArtPixmapCB(self, picInfo=None):
64 ptr = self.picload.getData()
66 self.instance.setPixmap(ptr.__deref__())
68 def updateCoverArt(self, path):
69 while not path.endswith("/"):
71 new_coverArtFileName = None
72 for filename in self.coverFileNames:
73 if fileExists(path + filename):
74 new_coverArtFileName = path + filename
75 if self.coverArtFileName != new_coverArtFileName:
76 self.coverArtFileName = new_coverArtFileName
77 if new_coverArtFileName:
78 self.picload.startDecode(self.coverArtFileName)
80 self.showDefaultCover()
82 def showDefaultCover(self):
83 self.instance.setPixmap(self.noCoverPixmap)
85 def embeddedCoverArt(self):
86 print "[embeddedCoverArt] found"
87 self.coverArtFileName = "/tmp/.id3coverart"
88 self.picload.startDecode(self.coverArtFileName)
90 class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSupport, InfoBarNotifications, InfoBarSubtitleSupport, HelpableScreen):
92 ENABLE_RESUME_SUPPORT = True
94 def __init__(self, session, args = None):
95 Screen.__init__(self, session)
96 InfoBarAudioSelection.__init__(self)
97 InfoBarCueSheetSupport.__init__(self, actionmap = "MediaPlayerCueSheetActions")
98 InfoBarNotifications.__init__(self)
99 InfoBarBase.__init__(self)
100 InfoBarSubtitleSupport.__init__(self)
101 HelpableScreen.__init__(self)
103 self.oldService = self.session.nav.getCurrentlyPlayingServiceReference()
104 self.session.nav.stopService()
106 self.playlistparsers = {}
107 self.addPlaylistParser(PlaylistIOM3U, "m3u")
108 self.addPlaylistParser(PlaylistIOPLS, "pls")
109 self.addPlaylistParser(PlaylistIOInternal, "e2pls")
111 # 'None' is magic to start at the list of mountpoints
112 defaultDir = config.mediaplayer.defaultDir.getValue()
113 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")
114 self["filelist"] = self.filelist
116 self.playlist = MyPlayList()
117 self.is_closing = False
119 self["playlist"] = self.playlist
121 self["PositionGauge"] = ServicePositionGauge(self.session.nav)
123 self["currenttext"] = Label("")
125 self["artisttext"] = Label(_("Artist:"))
126 self["artist"] = Label("")
127 self["titletext"] = Label(_("Title:"))
128 self["title"] = Label("")
129 self["albumtext"] = Label(_("Album:"))
130 self["album"] = Label("")
131 self["yeartext"] = Label(_("Year:"))
132 self["year"] = Label("")
133 self["genretext"] = Label(_("Genre:"))
134 self["genre"] = Label("")
135 self["coverArt"] = MediaPixmap()
136 self["repeat"] = MultiPixmap()
138 self.seek_target = None
139 hotplugNotifier.append(self.hotplugCB)
141 class MoviePlayerActionMap(NumberActionMap):
142 def __init__(self, player, contexts = [ ], actions = { }, prio=0):
143 NumberActionMap.__init__(self, contexts, actions, prio)
146 def action(self, contexts, action):
148 return NumberActionMap.action(self, contexts, action)
151 self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions",
153 "ok": (self.ok, _("add file to playlist")),
154 "cancel": (self.exit, _("exit mediaplayer")),
157 self["MediaPlayerActions"] = HelpableActionMap(self, "MediaPlayerActions",
159 "play": (self.xplayEntry, _("play entry")),
160 "pause": (self.pauseEntry, _("pause")),
161 "stop": (self.stopEntry, _("stop entry")),
162 "previous": (self.previousMarkOrEntry, _("play from previous mark or playlist entry")),
163 "next": (self.nextMarkOrEntry, _("play from next mark or playlist entry")),
164 "menu": (self.showMenu, _("menu")),
165 "skipListbegin": (self.skip_listbegin, _("jump to listbegin")),
166 "skipListend": (self.skip_listend, _("jump to listend")),
167 "prevBouquet": (self.switchToPlayList, _("switch to playlist")),
168 "nextBouquet": (self.switchToFileList, _("switch to filelist")),
169 "delete": (self.deletePlaylistEntry, _("delete playlist entry")),
170 "shift_stop": (self.clear_playlist, _("clear playlist")),
171 "shift_record": (self.playlist.PlayListShuffle, _("shuffle playlist")),
172 "subtitles": (self.subtitleSelection, _("Subtitle selection")),
175 self["InfobarEPGActions"] = HelpableActionMap(self, "InfobarEPGActions",
177 "showEventInfo": (self.showEventInformation, _("show event details")),
180 self["actions"] = MoviePlayerActionMap(self, ["DirectionActions"],
182 "right": self.rightDown,
183 "rightRepeated": self.doNothing,
184 "rightUp": self.rightUp,
185 "left": self.leftDown,
186 "leftRepeated": self.doNothing,
187 "leftUp": self.leftUp,
190 "upRepeated": self.up,
191 "upUp": self.doNothing,
193 "downRepeated": self.down,
194 "downUp": self.doNothing,
197 InfoBarSeek.__init__(self, actionmap = "MediaPlayerSeekActions")
199 self.onClose.append(self.delMPTimer)
200 self.onClose.append(self.__onClose)
202 self.righttimer = False
203 self.rightKeyTimer = eTimer()
204 self.rightKeyTimer.callback.append(self.rightTimerFire)
206 self.lefttimer = False
207 self.leftKeyTimer = eTimer()
208 self.leftKeyTimer.callback.append(self.leftTimerFire)
210 self.currList = "filelist"
211 self.isAudioCD = False
212 self.AudioCD_albuminfo = {}
213 self.cdAudioTrackFiles = []
216 self.playlistIOInternal = PlaylistIOInternal()
217 list = self.playlistIOInternal.open(resolveFilename(SCOPE_CONFIG, "playlist.e2pls"))
220 self.playlist.addFile(x.ref)
221 self.playlist.updateList()
223 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
225 iPlayableService.evUpdatedInfo: self.__evUpdatedInfo,
226 iPlayableService.evUser+11: self.__evDecodeError,
227 iPlayableService.evUser+12: self.__evPluginError,
228 iPlayableService.evUser+13: self["coverArt"].embeddedCoverArt
234 def createSummary(self):
235 return MediaPlayerLCDScreen
238 self.playlistIOInternal.clear()
239 for x in self.playlist.list:
240 self.playlistIOInternal.addService(ServiceReference(x[0]))
241 if self.savePlaylistOnExit:
242 self.playlistIOInternal.save(resolveFilename(SCOPE_CONFIG, "playlist.e2pls"))
243 if config.mediaplayer.saveDirOnExit.getValue():
244 config.mediaplayer.defaultDir.setValue(self.filelist.getCurrentDirectory())
245 config.mediaplayer.defaultDir.save()
246 hotplugNotifier.remove(self.hotplugCB)
247 del self["coverArt"].picload
250 def checkSkipShowHideLock(self):
251 self.updatedSeekState()
253 def doEofInternal(self, playing):
260 self.session.nav.playService(self.oldService)
262 def __evUpdatedInfo(self):
263 currPlay = self.session.nav.getCurrentService()
264 currenttitle = currPlay.info().getInfo(iServiceInformation.sCurrentTitle)
265 totaltitles = currPlay.info().getInfo(iServiceInformation.sTotalTitles)
266 sTitle = currPlay.info().getInfoString(iServiceInformation.sTitle)
267 print "[__evUpdatedInfo] title %d of %d (%s)" % (currenttitle, totaltitles, sTitle)
268 self.readTitleInformation()
270 def __evDecodeError(self):
271 currPlay = self.session.nav.getCurrentService()
272 sVideoType = currPlay.info().getInfoString(iServiceInformation.sVideoType)
273 print "[__evDecodeError] video-codec %s can't be decoded by hardware" % (sVideoType)
274 self.session.open(MessageBox, _("This Dreambox can't decode %s video streams!") % sVideoType, type = MessageBox.TYPE_INFO,timeout = 20 )
276 def __evPluginError(self):
277 currPlay = self.session.nav.getCurrentService()
278 message = currPlay.info().getInfoString(iServiceInformation.sUser+12)
279 print "[__evPluginError]" , message
280 self.session.open(MessageBox, message, type = MessageBox.TYPE_INFO,timeout = 20 )
282 def delMPTimer(self):
283 del self.rightKeyTimer
284 del self.leftKeyTimer
286 def readTitleInformation(self):
287 currPlay = self.session.nav.getCurrentService()
288 if currPlay is not None:
289 sTitle = currPlay.info().getInfoString(iServiceInformation.sTitle)
290 sAlbum = currPlay.info().getInfoString(iServiceInformation.sAlbum)
291 sGenre = currPlay.info().getInfoString(iServiceInformation.sGenre)
292 sArtist = currPlay.info().getInfoString(iServiceInformation.sArtist)
293 sYear = currPlay.info().getInfoString(iServiceInformation.sTimeCreate)
296 if not self.isAudioCD:
297 sTitle = currPlay.info().getName().split('/')[-1]
299 sTitle = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()].getName()
301 if self.AudioCD_albuminfo:
302 if sAlbum == "" and "title" in self.AudioCD_albuminfo:
303 sAlbum = self.AudioCD_albuminfo["title"]
304 if sGenre == "" and "genre" in self.AudioCD_albuminfo:
305 sGenre = self.AudioCD_albuminfo["genre"]
306 if sArtist == "" and "artist" in self.AudioCD_albuminfo:
307 sArtist = self.AudioCD_albuminfo["artist"]
308 if "year" in self.AudioCD_albuminfo:
309 sYear = self.AudioCD_albuminfo["year"]
311 self.updateMusicInformation( sArtist, sTitle, sAlbum, sYear, sGenre, clear = True )
313 self.updateMusicInformation()
315 def updateMusicInformation(self, artist = "", title = "", album = "", year = "", genre = "", clear = False):
316 self.updateSingleMusicInformation("artist", artist, clear)
317 self.updateSingleMusicInformation("title", title, clear)
318 self.updateSingleMusicInformation("album", album, clear)
319 self.updateSingleMusicInformation("year", year, clear)
320 self.updateSingleMusicInformation("genre", genre, clear)
322 def updateSingleMusicInformation(self, name, info, clear):
323 if info != "" or clear:
324 if self[name].getText() != info:
325 self[name].setText(info)
328 self.lefttimer = True
329 self.leftKeyTimer.start(1000)
332 self.righttimer = True
333 self.rightKeyTimer.start(1000)
337 self.leftKeyTimer.stop()
338 self.lefttimer = False
339 self[self.currList].pageUp()
340 self.updateCurrentInfo()
344 self.rightKeyTimer.stop()
345 self.righttimer = False
346 self[self.currList].pageDown()
347 self.updateCurrentInfo()
349 def leftTimerFire(self):
350 self.leftKeyTimer.stop()
351 self.lefttimer = False
352 self.switchToFileList()
354 def rightTimerFire(self):
355 self.rightKeyTimer.stop()
356 self.righttimer = False
357 self.switchToPlayList()
359 def switchToFileList(self):
360 self.currList = "filelist"
361 self.filelist.selectionEnabled(1)
362 self.playlist.selectionEnabled(0)
363 self.updateCurrentInfo()
365 def switchToPlayList(self):
366 if len(self.playlist) != 0:
367 self.currList = "playlist"
368 self.filelist.selectionEnabled(0)
369 self.playlist.selectionEnabled(1)
370 self.updateCurrentInfo()
373 self[self.currList].up()
374 self.updateCurrentInfo()
377 self[self.currList].down()
378 self.updateCurrentInfo()
380 def showAfterSeek(self):
383 def showAfterCuesheetOperation(self):
386 def hideAfterResume(self):
389 def getIdentifier(self, ref):
394 return text.split('/')[-1]
396 # FIXME: maybe this code can be optimized
397 def updateCurrentInfo(self):
399 if self.currList == "filelist":
400 idx = self.filelist.getSelectionIndex()
401 r = self.filelist.list[idx]
408 self.summaries.setText(text,1)
411 if idx < len(self.filelist.list):
412 r = self.filelist.list[idx]
416 self.summaries.setText(text,3)
418 self.summaries.setText(" ",3)
421 if idx < len(self.filelist.list):
422 r = self.filelist.list[idx]
426 self.summaries.setText(text,4)
428 self.summaries.setText(" ",4)
431 if not self.filelist.canDescent():
432 r = self.filelist.getServiceRef()
436 self["currenttext"].setText(os_path.basename(text))
438 if self.currList == "playlist":
439 t = self.playlist.getSelection()
442 #display current selected entry on LCD
443 text = self.getIdentifier(t)
444 self.summaries.setText(text,1)
445 self["currenttext"].setText(text)
446 idx = self.playlist.getSelectionIndex()
448 if idx < len(self.playlist):
449 currref = self.playlist.getServiceRefList()[idx]
450 text = self.getIdentifier(currref)
451 self.summaries.setText(text,3)
453 self.summaries.setText(" ",3)
456 if idx < len(self.playlist):
457 currref = self.playlist.getServiceRefList()[idx]
458 text = self.getIdentifier(currref)
459 self.summaries.setText(text,4)
461 self.summaries.setText(" ",4)
464 if self.currList == "filelist":
465 if self.filelist.canDescent():
466 self.filelist.descent()
467 self.updateCurrentInfo()
471 if self.currList == "playlist":
472 selection = self["playlist"].getSelection()
473 self.changeEntry(self.playlist.getSelectionIndex())
477 if len(self.cdAudioTrackFiles):
478 menu.insert(0,(_("Play Audio-CD..."), "audiocd"))
479 if self.currList == "filelist":
480 if self.filelist.canDescent():
481 menu.append((_("add directory to playlist"), "copydir"))
483 menu.append((_("add files to playlist"), "copyfiles"))
484 menu.append((_("switch to playlist"), "playlist"))
485 if config.usage.setup_level.index >= 1: # intermediate+
486 menu.append((_("delete file"), "deletefile"))
488 menu.append((_("switch to filelist"), "filelist"))
489 menu.append((_("clear playlist"), "clear"))
490 menu.append((_("Delete entry"), "deleteentry"))
491 if config.usage.setup_level.index >= 1: # intermediate+
492 menu.append((_("shuffle playlist"), "shuffle"))
493 menu.append((_("hide player"), "hide"));
494 menu.append((_("load playlist"), "loadplaylist"));
495 if config.usage.setup_level.index >= 1: # intermediate+
496 menu.append((_("save playlist"), "saveplaylist"));
497 menu.append((_("delete saved playlist"), "deleteplaylist"));
498 menu.append((_("Edit settings"), "settings"))
499 self.session.openWithCallback(self.menuCallback, ChoiceBox, title="", list=menu)
501 def menuCallback(self, choice):
505 if choice[1] == "copydir":
506 self.copyDirectory(self.filelist.getSelection()[0])
507 elif choice[1] == "copyfiles":
509 self.playlist.clear()
510 self.isAudioCD = False
511 self.copyDirectory(os_path.dirname(self.filelist.getSelection()[0].getPath()) + "/", recursive = False)
512 self.playServiceRefEntry(self.filelist.getServiceRef())
513 elif choice[1] == "playlist":
514 self.switchToPlayList()
515 elif choice[1] == "filelist":
516 self.switchToFileList()
517 elif choice[1] == "deleteentry":
518 if self.playlist.getSelectionIndex() == self.playlist.getCurrentIndex():
521 elif choice[1] == "clear":
522 self.clear_playlist()
523 elif choice[1] == "hide":
525 elif choice[1] == "saveplaylist":
527 elif choice[1] == "loadplaylist":
529 elif choice[1] == "deleteplaylist":
530 self.delete_saved_playlist()
531 elif choice[1] == "shuffle":
532 self.playlist.PlayListShuffle()
533 elif choice[1] == "deletefile":
535 elif choice[1] == "settings":
536 self.session.openWithCallback(self.applySettings, MediaPlayerSettings, self)
537 elif choice[1] == "audiocd":
540 def playAudioCD(self):
541 from enigma import eServiceReference
542 from Plugins.Extensions.CDInfo.plugin import Query
544 if len(self.cdAudioTrackFiles):
545 self.playlist.clear()
546 self.savePlaylistOnExit = False
547 self.isAudioCD = True
548 for file in self.cdAudioTrackFiles:
549 ref = eServiceReference(4097, 0, file)
550 self.playlist.addFile(ref)
554 self.switchToPlayList()
556 def applySettings(self):
557 self.savePlaylistOnExit = config.mediaplayer.savePlaylistOnExit.getValue()
558 if config.mediaplayer.repeat.getValue() == True:
559 self["repeat"].setPixmapNum(1)
561 self["repeat"].setPixmapNum(0)
563 def showEventInformation(self):
564 from Screens.EventView import EventViewSimple
565 from ServiceReference import ServiceReference
566 evt = self[self.currList].getCurrentEvent()
568 self.session.open(EventViewSimple, evt, ServiceReference(self.getCurrent()))
570 # also works on filelist (?)
571 def getCurrent(self):
572 return self["playlist"].getCurrent()
574 def deletePlaylistEntry(self):
575 if self.currList == "playlist":
576 if self.playlist.getSelectionIndex() == self.playlist.getCurrentIndex():
580 def skip_listbegin(self):
581 if self.currList == "filelist":
582 self.filelist.moveToIndex(0)
584 self.playlist.moveToIndex(0)
585 self.updateCurrentInfo()
587 def skip_listend(self):
588 if self.currList == "filelist":
589 idx = len(self.filelist.list)
590 self.filelist.moveToIndex(idx - 1)
592 self.playlist.moveToIndex(len(self.playlist)-1)
593 self.updateCurrentInfo()
595 def save_playlist(self):
596 self.session.openWithCallback(self.save_playlist2,InputBox, title=_("Please enter filename (empty = use current date)"),windowTitle = _("Save Playlist"))
598 def save_playlist2(self, name):
602 name = strftime("%y%m%d_%H%M%S")
604 self.playlistIOInternal.clear()
605 for x in self.playlist.list:
606 self.playlistIOInternal.addService(ServiceReference(x[0]))
607 self.playlistIOInternal.save(resolveFilename(SCOPE_PLAYLIST) + name)
609 def load_playlist(self):
611 playlistdir = resolveFilename(SCOPE_PLAYLIST)
613 for i in os_listdir(playlistdir):
614 listpath.append((i,playlistdir + i))
616 print "Error while scanning subdirs ",e
617 self.session.openWithCallback(self.PlaylistSelected, ChoiceBox, title=_("Please select a playlist..."), list = listpath)
619 def PlaylistSelected(self,path):
621 self.clear_playlist()
622 extension = path[0].rsplit('.',1)[-1]
623 if self.playlistparsers.has_key(extension):
624 playlist = self.playlistparsers[extension]()
625 list = playlist.open(path[1])
627 self.playlist.addFile(x.ref)
628 self.playlist.updateList()
630 def delete_saved_playlist(self):
632 playlistdir = resolveFilename(SCOPE_PLAYLIST)
634 for i in os_listdir(playlistdir):
635 listpath.append((i,playlistdir + i))
637 print "Error while scanning subdirs ",e
638 self.session.openWithCallback(self.DeletePlaylistSelected, ChoiceBox, title=_("Please select a playlist to delete..."), list = listpath)
640 def DeletePlaylistSelected(self,path):
642 self.delname = path[1]
643 self.session.openWithCallback(self.deleteConfirmed, MessageBox, _("Do you really want to delete %s?") % (path[1]))
645 def deleteConfirmed(self, confirmed):
648 os_remove(self.delname)
650 print "delete failed:", e
651 self.session.open(MessageBox, _("Delete failed!"), MessageBox.TYPE_ERROR)
653 def clear_playlist(self):
654 self.isAudioCD = False
656 self.playlist.clear()
657 self.switchToFileList()
659 def copyDirectory(self, directory, recursive = True):
660 print "copyDirectory", directory
661 filelist = FileList(directory, useServiceRef = True, isTop = True)
663 for x in filelist.getFileList():
664 if x[0][1] == True: #isDir
666 self.copyDirectory(x[0][0])
667 elif filelist.getServiceRef() and filelist.getServiceRef().type == 4097:
668 self.playlist.addFile(x[0][0])
669 self.playlist.updateList()
671 def deleteFile(self):
672 if self.currList == "filelist":
673 self.service = self.filelist.getServiceRef()
675 self.service = self.playlist.getSelection()
676 if self.service is None:
678 if self.service.type != 4098 and self.session.nav.getCurrentlyPlayingServiceReference() is not None:
679 if self.service == self.session.nav.getCurrentlyPlayingServiceReference():
682 serviceHandler = eServiceCenter.getInstance()
683 offline = serviceHandler.offlineOperations(self.service)
684 info = serviceHandler.info(self.service)
685 name = info and info.getName(self.service)
687 if offline is not None:
689 if not offline.deleteFromDisk(1):
692 self.session.openWithCallback(self.deleteConfirmed_offline, MessageBox, _("Do you really want to delete %s?") % (name))
694 self.session.openWithCallback(self.close, MessageBox, _("You cannot delete this!"), MessageBox.TYPE_ERROR)
696 def deleteConfirmed_offline(self, confirmed):
698 serviceHandler = eServiceCenter.getInstance()
699 offline = serviceHandler.offlineOperations(self.service)
701 if offline is not None:
703 if not offline.deleteFromDisk(0):
706 self.session.open(MessageBox, _("Delete failed!"), MessageBox.TYPE_ERROR)
708 self.removeListEntry()
710 def removeListEntry(self):
711 currdir = self.filelist.getCurrentDirectory()
712 self.filelist.changeDir(currdir)
717 if len(self.playlist) > 0:
718 for x in self.playlist.list:
719 if self.service == x[0]:
720 self.playlist.deleteFile(index)
724 self.playlist.updateList()
725 if self.currList == "playlist":
726 if len(self.playlist) == 0:
727 self.switchToFileList()
730 if self.filelist.getServiceRef().type == 4098: # playlist
731 ServiceRef = self.filelist.getServiceRef()
732 extension = ServiceRef.getPath()[ServiceRef.getPath().rfind('.') + 1:]
733 if self.playlistparsers.has_key(extension):
734 playlist = self.playlistparsers[extension]()
735 list = playlist.open(ServiceRef.getPath())
737 self.playlist.addFile(x.ref)
738 self.playlist.updateList()
740 self.playlist.addFile(self.filelist.getServiceRef())
741 self.playlist.updateList()
742 if len(self.playlist) == 1:
745 def addPlaylistParser(self, parser, extension):
746 self.playlistparsers[extension] = parser
749 next = self.playlist.getCurrentIndex() + 1
750 if next < len(self.playlist):
751 self.changeEntry(next)
752 elif ( len(self.playlist) > 0 ) and ( config.mediaplayer.repeat.getValue() == True ):
756 def nextMarkOrEntry(self):
757 if not self.jumpPreviousNextMark(lambda x: x):
758 next = self.playlist.getCurrentIndex() + 1
759 if next < len(self.playlist):
760 self.changeEntry(next)
764 def previousMarkOrEntry(self):
765 if not self.jumpPreviousNextMark(lambda x: -x-5*90000, start=True):
766 next = self.playlist.getCurrentIndex() - 1
768 self.changeEntry(next)
770 def deleteEntry(self):
771 self.playlist.deleteFile(self.playlist.getSelectionIndex())
772 self.playlist.updateList()
773 if len(self.playlist) == 0:
774 self.switchToFileList()
776 def changeEntry(self, index):
777 self.playlist.setCurrentPlaying(index)
780 def playServiceRefEntry(self, serviceref):
781 serviceRefList = self.playlist.getServiceRefList()
782 for count in range(len(serviceRefList)):
783 if serviceRefList[count] == serviceref:
784 self.changeEntry(count)
787 def xplayEntry(self):
788 if self.currList == "playlist":
792 self.playlist.clear()
793 self.isAudioCD = False
794 sel = self.filelist.getSelection()
796 if sel[1]: # can descent
797 # add directory to playlist
798 self.copyDirectory(sel[0])
800 # add files to playlist
801 self.copyDirectory(os_path.dirname(sel[0].getPath()) + "/", recursive = False)
802 if len(self.playlist) > 0:
806 if len(self.playlist.getServiceRefList()):
807 needsInfoUpdate = False
808 currref = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()]
809 if self.session.nav.getCurrentlyPlayingServiceReference() is None or currref != self.session.nav.getCurrentlyPlayingServiceReference():
810 self.session.nav.playService(self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()])
811 info = eServiceCenter.getInstance().info(currref)
812 description = info and info.getInfoString(currref, iServiceInformation.sDescription) or ""
813 self["title"].setText(description)
814 # display just playing musik on LCD
815 idx = self.playlist.getCurrentIndex()
816 currref = self.playlist.getServiceRefList()[idx]
817 text = self.getIdentifier(currref)
819 ext = text[-4:].lower()
821 # FIXME: the information if the service contains video (and we should hide our window) should com from the service instead
822 if ext not in [".mp2", ".mp3", ".wav", ".ogg", "flac"] and not self.isAudioCD:
825 needsInfoUpdate = True
826 self.summaries.setText(text,1)
828 # get the next two entries
830 if idx < len(self.playlist):
831 currref = self.playlist.getServiceRefList()[idx]
832 text = self.getIdentifier(currref)
833 self.summaries.setText(text,3)
835 self.summaries.setText(" ",3)
838 if idx < len(self.playlist):
839 currref = self.playlist.getServiceRefList()[idx]
840 text = self.getIdentifier(currref)
841 self.summaries.setText(text,4)
843 self.summaries.setText(" ",4)
845 idx = self.playlist.getCurrentIndex()
846 currref = self.playlist.getServiceRefList()[idx]
847 text = currref.getPath()
848 ext = text[-4:].lower()
849 if ext not in [".mp2", ".mp3", ".wav", ".ogg", "flac"] and not self.isAudioCD:
852 needsInfoUpdate = True
854 self.unPauseService()
855 if needsInfoUpdate == True:
856 path = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()].getPath()
857 self["coverArt"].updateCoverArt(path)
859 self["coverArt"].showDefaultCover()
860 self.readTitleInformation()
862 def updatedSeekState(self):
863 if self.seekstate == self.SEEK_STATE_PAUSE:
864 self.playlist.pauseFile()
865 elif self.seekstate == self.SEEK_STATE_PLAY:
866 self.playlist.playFile()
867 elif self.isStateForward(self.seekstate):
868 self.playlist.forwardFile()
869 elif self.isStateBackward(self.seekstate):
870 self.playlist.rewindFile()
872 def pauseEntry(self):
874 if self.seekstate == self.SEEK_STATE_PAUSE:
880 self.playlist.stopFile()
881 self.session.nav.playService(None)
882 self.updateMusicInformation(clear=True)
885 def unPauseService(self):
886 self.setSeekState(self.SEEK_STATE_PLAY)
888 def subtitleSelection(self):
889 from Screens.Subtitles import Subtitles
890 self.session.open(Subtitles)
892 def hotplugCB(self, dev, media_state):
893 if dev == harddiskmanager.getCD():
894 if media_state == "1":
895 from Components.Scanner import scanDevice
896 devpath = harddiskmanager.getAutofsMountpoint(harddiskmanager.getCD())
897 self.cdAudioTrackFiles = []
898 res = scanDevice(devpath)
899 list = [ (r.description, r, res[r], self.session) for r in res ]
901 (desc, scanner, files, session) = list[0]
903 if file.mimetype == "audio/x-cda":
904 self.cdAudioTrackFiles.append(file.path)
906 self.cdAudioTrackFiles = []
908 self.clear_playlist()
910 class MediaPlayerLCDScreen(Screen):
912 <screen position="0,0" size="132,64" title="LCD Text">
913 <widget name="text1" position="4,0" size="132,35" font="Regular;16"/>
914 <widget name="text3" position="4,36" size="132,14" font="Regular;10"/>
915 <widget name="text4" position="4,49" size="132,14" font="Regular;10"/>
918 def __init__(self, session, parent):
919 Screen.__init__(self, session)
920 self["text1"] = Label("Mediaplayer")
921 self["text3"] = Label("")
922 self["text4"] = Label("")
924 def setText(self, text, line):
926 if text[-4:] == ".mp3":
929 text = text + textleer*10
931 self["text1"].setText(text)
933 self["text3"].setText(text)
935 self["text4"].setText(text)
937 def main(session, **kwargs):
938 session.open(MediaPlayer)
940 def menu(menuid, **kwargs):
941 if menuid == "mainmenu":
942 return [(_("Media player"), main, "media_player", 45)]
945 def filescan_open(list, session, **kwargs):
946 from enigma import eServiceReference
948 mp = session.open(MediaPlayer)
950 mp.savePlaylistOnExit = False
953 if file.mimetype == "video/MP2T":
957 ref = eServiceReference(stype, 0, file.path)
958 mp.playlist.addFile(ref)
961 mp.switchToPlayList()
963 def audioCD_open(list, session, **kwargs):
964 from enigma import eServiceReference
966 mp = session.open(MediaPlayer)
967 mp.cdAudioTrackFiles = []
969 mp.cdAudioTrackFiles.append(file.path)
972 def filescan(**kwargs):
973 from Components.Scanner import Scanner, ScanPath
975 Scanner(mimetypes = ["video/mpeg", "video/MP2T", "video/x-msvideo"],
978 ScanPath(path = "", with_subdirs = False),
981 description = "View Movies...",
982 openfnc = filescan_open,
984 Scanner(mimetypes = ["video/x-vcd"],
987 ScanPath(path = "mpegav", with_subdirs = False),
988 ScanPath(path = "MPEGAV", with_subdirs = False),
991 description = "View Video CD...",
992 openfnc = filescan_open,
994 Scanner(mimetypes = ["audio/mpeg", "audio/x-wav", "application/ogg", "audio/x-flac"],
997 ScanPath(path = "", with_subdirs = False),
1000 description = "Play Music...",
1001 openfnc = filescan_open,
1004 from Plugins.Extensions.CDInfo.plugin import Query
1006 Scanner(mimetypes = ["audio/x-cda"],
1009 ScanPath(path = "", with_subdirs = False),
1012 description = "Play Audio-CD...",
1013 openfnc = audioCD_open,
1019 from Plugins.Plugin import PluginDescriptor
1020 def Plugins(**kwargs):
1022 PluginDescriptor(name = "MediaPlayer", description = "Play back media files", where = PluginDescriptor.WHERE_MENU, fnc = menu),
1023 PluginDescriptor(name = "MediaPlayer", where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan)