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
26 class MyPlayList(PlayList):
28 PlayList.__init__(self)
30 def PlayListShuffle(self):
31 random.shuffle(self.list)
32 self.l.setList(self.list)
34 self.oldCurrPlaying = -1
36 class MediaPixmap(Pixmap):
39 self.coverArtFileName = ""
40 self.picload = ePicLoad()
41 self.picload.PictureData.get().append(self.paintCoverArtPixmapCB)
42 self.coverFileNames = ["folder.png", "folder.jpg"]
44 def applySkin(self, desktop, screen):
45 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|m2ts|wav|wave|m3u|pls|e2pls|mpg|vob|avi|divx|mkv|mp4|m4a|dat|flac|mov)", 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
140 from Plugins.SystemPlugins.Hotplug.plugin import hotplugNotifier
141 hotplugNotifier.append(self.hotplugCB)
143 class MoviePlayerActionMap(NumberActionMap):
144 def __init__(self, player, contexts = [ ], actions = { }, prio=0):
145 NumberActionMap.__init__(self, contexts, actions, prio)
148 def action(self, contexts, action):
150 return NumberActionMap.action(self, contexts, action)
152 self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions",
154 "ok": (self.ok, _("add file to playlist")),
155 "cancel": (self.exit, _("exit mediaplayer")),
158 self["MediaPlayerActions"] = HelpableActionMap(self, "MediaPlayerActions",
160 "play": (self.xplayEntry, _("play entry")),
161 "pause": (self.pauseEntry, _("pause")),
162 "stop": (self.stopEntry, _("stop entry")),
163 "previous": (self.previousMarkOrEntry, _("play from previous mark or playlist entry")),
164 "next": (self.nextMarkOrEntry, _("play from next mark or playlist entry")),
165 "menu": (self.showMenu, _("menu")),
166 "skipListbegin": (self.skip_listbegin, _("jump to listbegin")),
167 "skipListend": (self.skip_listend, _("jump to listend")),
168 "prevBouquet": (self.switchToPlayList, _("switch to playlist")),
169 "nextBouquet": (self.switchToFileList, _("switch to filelist")),
170 "delete": (self.deletePlaylistEntry, _("delete playlist entry")),
171 "shift_stop": (self.clear_playlist, _("clear playlist")),
172 "shift_record": (self.playlist.PlayListShuffle, _("shuffle playlist")),
173 "subtitles": (self.subtitleSelection, _("Subtitle selection")),
176 self["InfobarEPGActions"] = HelpableActionMap(self, "InfobarEPGActions",
178 "showEventInfo": (self.showEventInformation, _("show event details")),
181 self["actions"] = MoviePlayerActionMap(self, ["DirectionActions"],
183 "right": self.rightDown,
184 "rightRepeated": self.doNothing,
185 "rightUp": self.rightUp,
186 "left": self.leftDown,
187 "leftRepeated": self.doNothing,
188 "leftUp": self.leftUp,
191 "upRepeated": self.up,
192 "upUp": self.doNothing,
194 "downRepeated": self.down,
195 "downUp": self.doNothing,
198 InfoBarSeek.__init__(self, actionmap = "MediaPlayerSeekActions")
200 self.onClose.append(self.delMPTimer)
201 self.onClose.append(self.__onClose)
203 self.righttimer = False
204 self.rightKeyTimer = eTimer()
205 self.rightKeyTimer.callback.append(self.rightTimerFire)
207 self.lefttimer = False
208 self.leftKeyTimer = eTimer()
209 self.leftKeyTimer.callback.append(self.leftTimerFire)
211 self.currList = "filelist"
212 self.isAudioCD = False
213 self.AudioCD_albuminfo = {}
214 self.cdAudioTrackFiles = []
217 self.playlistIOInternal = PlaylistIOInternal()
218 list = self.playlistIOInternal.open(resolveFilename(SCOPE_CONFIG, "playlist.e2pls"))
221 self.playlist.addFile(x.ref)
222 self.playlist.updateList()
224 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
226 iPlayableService.evUpdatedInfo: self.__evUpdatedInfo,
227 iPlayableService.evUser+10: self.__evAudioDecodeError,
228 iPlayableService.evUser+11: self.__evVideoDecodeError,
229 iPlayableService.evUser+12: self.__evPluginError,
230 iPlayableService.evUser+13: self["coverArt"].embeddedCoverArt
236 def createSummary(self):
237 return MediaPlayerLCDScreen
240 self.playlistIOInternal.clear()
241 for x in self.playlist.list:
242 self.playlistIOInternal.addService(ServiceReference(x[0]))
243 if self.savePlaylistOnExit:
244 self.playlistIOInternal.save(resolveFilename(SCOPE_CONFIG, "playlist.e2pls"))
245 if config.mediaplayer.saveDirOnExit.getValue():
246 config.mediaplayer.defaultDir.setValue(self.filelist.getCurrentDirectory())
247 config.mediaplayer.defaultDir.save()
248 from Plugins.SystemPlugins.Hotplug.plugin import hotplugNotifier
249 hotplugNotifier.remove(self.hotplugCB)
250 del self["coverArt"].picload
253 def checkSkipShowHideLock(self):
254 self.updatedSeekState()
256 def doEofInternal(self, playing):
263 self.session.nav.playService(self.oldService)
265 def __evUpdatedInfo(self):
266 currPlay = self.session.nav.getCurrentService()
267 sTagTrackNumber = currPlay.info().getInfo(iServiceInformation.sTagTrackNumber)
268 sTagTrackCount = currPlay.info().getInfo(iServiceInformation.sTagTrackCount)
269 sTagTitle = currPlay.info().getInfoString(iServiceInformation.sTagTitle)
270 print "[__evUpdatedInfo] title %d of %d (%s)" % (sTagTrackNumber, sTagTrackCount, sTagTitle)
271 self.readTitleInformation()
273 def __evAudioDecodeError(self):
274 currPlay = self.session.nav.getCurrentService()
275 sTagAudioCodec = currPlay.info().getInfoString(iServiceInformation.sTagAudioCodec)
276 print "[__evAudioDecodeError] audio-codec %s can't be decoded by hardware" % (sTagAudioCodec)
277 self.session.open(MessageBox, _("This Dreambox can't decode %s streams!") % sTagAudioCodec, type = MessageBox.TYPE_INFO,timeout = 20 )
279 def __evVideoDecodeError(self):
280 currPlay = self.session.nav.getCurrentService()
281 sTagVideoCodec = currPlay.info().getInfoString(iServiceInformation.sTagVideoCodec)
282 print "[__evVideoDecodeError] video-codec %s can't be decoded by hardware" % (sTagVideoCodec)
283 self.session.open(MessageBox, _("This Dreambox can't decode %s streams!") % sTagVideoCodec, type = MessageBox.TYPE_INFO,timeout = 20 )
285 def __evPluginError(self):
286 currPlay = self.session.nav.getCurrentService()
287 message = currPlay.info().getInfoString(iServiceInformation.sUser+12)
288 print "[__evPluginError]" , message
289 self.session.open(MessageBox, message, type = MessageBox.TYPE_INFO,timeout = 20 )
291 def delMPTimer(self):
292 del self.rightKeyTimer
293 del self.leftKeyTimer
295 def readTitleInformation(self):
296 currPlay = self.session.nav.getCurrentService()
297 if currPlay is not None:
298 sTitle = currPlay.info().getInfoString(iServiceInformation.sTagTitle)
299 sAlbum = currPlay.info().getInfoString(iServiceInformation.sTagAlbum)
300 sGenre = currPlay.info().getInfoString(iServiceInformation.sTagGenre)
301 sArtist = currPlay.info().getInfoString(iServiceInformation.sTagArtist)
302 sYear = currPlay.info().getInfoString(iServiceInformation.sTagDate)
305 if not self.isAudioCD:
306 sTitle = currPlay.info().getName().split('/')[-1]
308 sTitle = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()].getName()
310 if self.AudioCD_albuminfo:
311 if sAlbum == "" and "title" in self.AudioCD_albuminfo:
312 sAlbum = self.AudioCD_albuminfo["title"]
313 if sGenre == "" and "genre" in self.AudioCD_albuminfo:
314 sGenre = self.AudioCD_albuminfo["genre"]
315 if sArtist == "" and "artist" in self.AudioCD_albuminfo:
316 sArtist = self.AudioCD_albuminfo["artist"]
317 if "year" in self.AudioCD_albuminfo:
318 sYear = self.AudioCD_albuminfo["year"]
320 self.updateMusicInformation( sArtist, sTitle, sAlbum, sYear, sGenre, clear = True )
322 self.updateMusicInformation()
324 def updateMusicInformation(self, artist = "", title = "", album = "", year = "", genre = "", clear = False):
325 self.updateSingleMusicInformation("artist", artist, clear)
326 self.updateSingleMusicInformation("title", title, clear)
327 self.updateSingleMusicInformation("album", album, clear)
328 self.updateSingleMusicInformation("year", year, clear)
329 self.updateSingleMusicInformation("genre", genre, clear)
331 def updateSingleMusicInformation(self, name, info, clear):
332 if info != "" or clear:
333 if self[name].getText() != info:
334 self[name].setText(info)
337 self.lefttimer = True
338 self.leftKeyTimer.start(1000)
341 self.righttimer = True
342 self.rightKeyTimer.start(1000)
346 self.leftKeyTimer.stop()
347 self.lefttimer = False
348 self[self.currList].pageUp()
349 self.updateCurrentInfo()
353 self.rightKeyTimer.stop()
354 self.righttimer = False
355 self[self.currList].pageDown()
356 self.updateCurrentInfo()
358 def leftTimerFire(self):
359 self.leftKeyTimer.stop()
360 self.lefttimer = False
361 self.switchToFileList()
363 def rightTimerFire(self):
364 self.rightKeyTimer.stop()
365 self.righttimer = False
366 self.switchToPlayList()
368 def switchToFileList(self):
369 self.currList = "filelist"
370 self.filelist.selectionEnabled(1)
371 self.playlist.selectionEnabled(0)
372 self.updateCurrentInfo()
374 def switchToPlayList(self):
375 if len(self.playlist) != 0:
376 self.currList = "playlist"
377 self.filelist.selectionEnabled(0)
378 self.playlist.selectionEnabled(1)
379 self.updateCurrentInfo()
382 self[self.currList].up()
383 self.updateCurrentInfo()
386 self[self.currList].down()
387 self.updateCurrentInfo()
389 def showAfterSeek(self):
392 def showAfterCuesheetOperation(self):
395 def hideAfterResume(self):
398 def getIdentifier(self, ref):
403 return text.split('/')[-1]
405 # FIXME: maybe this code can be optimized
406 def updateCurrentInfo(self):
408 if self.currList == "filelist":
409 idx = self.filelist.getSelectionIndex()
410 r = self.filelist.list[idx]
417 self.summaries.setText(text,1)
420 if idx < len(self.filelist.list):
421 r = self.filelist.list[idx]
425 self.summaries.setText(text,3)
427 self.summaries.setText(" ",3)
430 if idx < len(self.filelist.list):
431 r = self.filelist.list[idx]
435 self.summaries.setText(text,4)
437 self.summaries.setText(" ",4)
440 if not self.filelist.canDescent():
441 r = self.filelist.getServiceRef()
445 self["currenttext"].setText(os_path.basename(text))
447 if self.currList == "playlist":
448 t = self.playlist.getSelection()
451 #display current selected entry on LCD
452 text = self.getIdentifier(t)
453 self.summaries.setText(text,1)
454 self["currenttext"].setText(text)
455 idx = self.playlist.getSelectionIndex()
457 if idx < len(self.playlist):
458 currref = self.playlist.getServiceRefList()[idx]
459 text = self.getIdentifier(currref)
460 self.summaries.setText(text,3)
462 self.summaries.setText(" ",3)
465 if idx < len(self.playlist):
466 currref = self.playlist.getServiceRefList()[idx]
467 text = self.getIdentifier(currref)
468 self.summaries.setText(text,4)
470 self.summaries.setText(" ",4)
473 if self.currList == "filelist":
474 if self.filelist.canDescent():
475 self.filelist.descent()
476 self.updateCurrentInfo()
480 if self.currList == "playlist":
481 selection = self["playlist"].getSelection()
482 self.changeEntry(self.playlist.getSelectionIndex())
486 if len(self.cdAudioTrackFiles):
487 menu.insert(0,(_("Play Audio-CD..."), "audiocd"))
488 if self.currList == "filelist":
489 if self.filelist.canDescent():
490 menu.append((_("add directory to playlist"), "copydir"))
492 menu.append((_("add files to playlist"), "copyfiles"))
493 menu.append((_("switch to playlist"), "playlist"))
494 if config.usage.setup_level.index >= 1: # intermediate+
495 menu.append((_("delete file"), "deletefile"))
497 menu.append((_("switch to filelist"), "filelist"))
498 menu.append((_("clear playlist"), "clear"))
499 menu.append((_("Delete entry"), "deleteentry"))
500 if config.usage.setup_level.index >= 1: # intermediate+
501 menu.append((_("shuffle playlist"), "shuffle"))
502 menu.append((_("hide player"), "hide"));
503 menu.append((_("load playlist"), "loadplaylist"));
504 if config.usage.setup_level.index >= 1: # intermediate+
505 menu.append((_("save playlist"), "saveplaylist"));
506 menu.append((_("delete saved playlist"), "deleteplaylist"));
507 menu.append((_("Edit settings"), "settings"))
508 self.session.openWithCallback(self.menuCallback, ChoiceBox, title="", list=menu)
510 def menuCallback(self, choice):
514 if choice[1] == "copydir":
515 self.copyDirectory(self.filelist.getSelection()[0])
516 elif choice[1] == "copyfiles":
518 self.playlist.clear()
519 self.isAudioCD = False
520 self.copyDirectory(os_path.dirname(self.filelist.getSelection()[0].getPath()) + "/", recursive = False)
521 self.playServiceRefEntry(self.filelist.getServiceRef())
522 elif choice[1] == "playlist":
523 self.switchToPlayList()
524 elif choice[1] == "filelist":
525 self.switchToFileList()
526 elif choice[1] == "deleteentry":
527 if self.playlist.getSelectionIndex() == self.playlist.getCurrentIndex():
530 elif choice[1] == "clear":
531 self.clear_playlist()
532 elif choice[1] == "hide":
534 elif choice[1] == "saveplaylist":
536 elif choice[1] == "loadplaylist":
538 elif choice[1] == "deleteplaylist":
539 self.delete_saved_playlist()
540 elif choice[1] == "shuffle":
541 self.playlist.PlayListShuffle()
542 elif choice[1] == "deletefile":
544 elif choice[1] == "settings":
545 self.session.openWithCallback(self.applySettings, MediaPlayerSettings, self)
546 elif choice[1] == "audiocd":
549 def playAudioCD(self):
550 from enigma import eServiceReference
551 from Plugins.Extensions.CDInfo.plugin import Query
553 if len(self.cdAudioTrackFiles):
554 self.playlist.clear()
555 self.savePlaylistOnExit = False
556 self.isAudioCD = True
557 for file in self.cdAudioTrackFiles:
558 ref = eServiceReference(4097, 0, file)
559 self.playlist.addFile(ref)
563 self.switchToPlayList()
565 def applySettings(self):
566 self.savePlaylistOnExit = config.mediaplayer.savePlaylistOnExit.getValue()
567 if config.mediaplayer.repeat.getValue() == True:
568 self["repeat"].setPixmapNum(1)
570 self["repeat"].setPixmapNum(0)
572 def showEventInformation(self):
573 from Screens.EventView import EventViewSimple
574 from ServiceReference import ServiceReference
575 evt = self[self.currList].getCurrentEvent()
577 self.session.open(EventViewSimple, evt, ServiceReference(self.getCurrent()))
579 # also works on filelist (?)
580 def getCurrent(self):
581 return self["playlist"].getCurrent()
583 def deletePlaylistEntry(self):
584 if self.currList == "playlist":
585 if self.playlist.getSelectionIndex() == self.playlist.getCurrentIndex():
589 def skip_listbegin(self):
590 if self.currList == "filelist":
591 self.filelist.moveToIndex(0)
593 self.playlist.moveToIndex(0)
594 self.updateCurrentInfo()
596 def skip_listend(self):
597 if self.currList == "filelist":
598 idx = len(self.filelist.list)
599 self.filelist.moveToIndex(idx - 1)
601 self.playlist.moveToIndex(len(self.playlist)-1)
602 self.updateCurrentInfo()
604 def save_playlist(self):
605 self.session.openWithCallback(self.save_playlist2,InputBox, title=_("Please enter filename (empty = use current date)"),windowTitle = _("Save Playlist"))
607 def save_playlist2(self, name):
611 name = strftime("%y%m%d_%H%M%S")
613 self.playlistIOInternal.clear()
614 for x in self.playlist.list:
615 self.playlistIOInternal.addService(ServiceReference(x[0]))
616 self.playlistIOInternal.save(resolveFilename(SCOPE_PLAYLIST) + name)
618 def load_playlist(self):
620 playlistdir = resolveFilename(SCOPE_PLAYLIST)
622 for i in os_listdir(playlistdir):
623 listpath.append((i,playlistdir + i))
625 print "Error while scanning subdirs ",e
626 self.session.openWithCallback(self.PlaylistSelected, ChoiceBox, title=_("Please select a playlist..."), list = listpath)
628 def PlaylistSelected(self,path):
630 self.clear_playlist()
631 extension = path[0].rsplit('.',1)[-1]
632 if self.playlistparsers.has_key(extension):
633 playlist = self.playlistparsers[extension]()
634 list = playlist.open(path[1])
636 self.playlist.addFile(x.ref)
637 self.playlist.updateList()
639 def delete_saved_playlist(self):
641 playlistdir = resolveFilename(SCOPE_PLAYLIST)
643 for i in os_listdir(playlistdir):
644 listpath.append((i,playlistdir + i))
646 print "Error while scanning subdirs ",e
647 self.session.openWithCallback(self.DeletePlaylistSelected, ChoiceBox, title=_("Please select a playlist to delete..."), list = listpath)
649 def DeletePlaylistSelected(self,path):
651 self.delname = path[1]
652 self.session.openWithCallback(self.deleteConfirmed, MessageBox, _("Do you really want to delete %s?") % (path[1]))
654 def deleteConfirmed(self, confirmed):
657 os_remove(self.delname)
659 print "delete failed:", e
660 self.session.open(MessageBox, _("Delete failed!"), MessageBox.TYPE_ERROR)
662 def clear_playlist(self):
663 self.isAudioCD = False
665 self.playlist.clear()
666 self.switchToFileList()
668 def copyDirectory(self, directory, recursive = True):
669 print "copyDirectory", directory
671 print "refusing to operate on /"
673 filelist = FileList(directory, useServiceRef = True, showMountpoints = False, isTop = True)
675 for x in filelist.getFileList():
676 if x[0][1] == True: #isDir
678 if x[0][0] != directory:
679 self.copyDirectory(x[0][0])
680 elif filelist.getServiceRef() and filelist.getServiceRef().type == 4097:
681 self.playlist.addFile(x[0][0])
682 self.playlist.updateList()
684 def deleteFile(self):
685 if self.currList == "filelist":
686 self.service = self.filelist.getServiceRef()
688 self.service = self.playlist.getSelection()
689 if self.service is None:
691 if self.service.type != 4098 and self.session.nav.getCurrentlyPlayingServiceReference() is not None:
692 if self.service == self.session.nav.getCurrentlyPlayingServiceReference():
695 serviceHandler = eServiceCenter.getInstance()
696 offline = serviceHandler.offlineOperations(self.service)
697 info = serviceHandler.info(self.service)
698 name = info and info.getName(self.service)
700 if offline is not None:
702 if not offline.deleteFromDisk(1):
705 self.session.openWithCallback(self.deleteConfirmed_offline, MessageBox, _("Do you really want to delete %s?") % (name))
707 self.session.openWithCallback(self.close, MessageBox, _("You cannot delete this!"), MessageBox.TYPE_ERROR)
709 def deleteConfirmed_offline(self, confirmed):
711 serviceHandler = eServiceCenter.getInstance()
712 offline = serviceHandler.offlineOperations(self.service)
714 if offline is not None:
716 if not offline.deleteFromDisk(0):
719 self.session.open(MessageBox, _("Delete failed!"), MessageBox.TYPE_ERROR)
721 self.removeListEntry()
723 def removeListEntry(self):
724 currdir = self.filelist.getCurrentDirectory()
725 self.filelist.changeDir(currdir)
730 if len(self.playlist) > 0:
731 for x in self.playlist.list:
732 if self.service == x[0]:
733 self.playlist.deleteFile(index)
737 self.playlist.updateList()
738 if self.currList == "playlist":
739 if len(self.playlist) == 0:
740 self.switchToFileList()
743 if self.filelist.getServiceRef().type == 4098: # playlist
744 ServiceRef = self.filelist.getServiceRef()
745 extension = ServiceRef.getPath()[ServiceRef.getPath().rfind('.') + 1:]
746 if self.playlistparsers.has_key(extension):
747 playlist = self.playlistparsers[extension]()
748 list = playlist.open(ServiceRef.getPath())
750 self.playlist.addFile(x.ref)
751 self.playlist.updateList()
753 self.playlist.addFile(self.filelist.getServiceRef())
754 self.playlist.updateList()
755 if len(self.playlist) == 1:
758 def addPlaylistParser(self, parser, extension):
759 self.playlistparsers[extension] = parser
762 next = self.playlist.getCurrentIndex() + 1
763 if next < len(self.playlist):
764 self.changeEntry(next)
765 elif ( len(self.playlist) > 0 ) and ( config.mediaplayer.repeat.getValue() == True ):
769 def nextMarkOrEntry(self):
770 if not self.jumpPreviousNextMark(lambda x: x):
771 next = self.playlist.getCurrentIndex() + 1
772 if next < len(self.playlist):
773 self.changeEntry(next)
777 def previousMarkOrEntry(self):
778 if not self.jumpPreviousNextMark(lambda x: -x-5*90000, start=True):
779 next = self.playlist.getCurrentIndex() - 1
781 self.changeEntry(next)
783 def deleteEntry(self):
784 self.playlist.deleteFile(self.playlist.getSelectionIndex())
785 self.playlist.updateList()
786 if len(self.playlist) == 0:
787 self.switchToFileList()
789 def changeEntry(self, index):
790 self.playlist.setCurrentPlaying(index)
793 def playServiceRefEntry(self, serviceref):
794 serviceRefList = self.playlist.getServiceRefList()
795 for count in range(len(serviceRefList)):
796 if serviceRefList[count] == serviceref:
797 self.changeEntry(count)
800 def xplayEntry(self):
801 if self.currList == "playlist":
805 self.playlist.clear()
806 self.isAudioCD = False
807 sel = self.filelist.getSelection()
809 if sel[1]: # can descent
810 # add directory to playlist
811 self.copyDirectory(sel[0])
813 # add files to playlist
814 self.copyDirectory(os_path.dirname(sel[0].getPath()) + "/", recursive = False)
815 if len(self.playlist) > 0:
819 if len(self.playlist.getServiceRefList()):
820 audio_extensions = (".mp2", ".mp3", ".wav", ".ogg", "flac", "m4a")
821 needsInfoUpdate = False
822 currref = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()]
823 if self.session.nav.getCurrentlyPlayingServiceReference() is None or currref != self.session.nav.getCurrentlyPlayingServiceReference():
824 self.session.nav.playService(self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()])
825 info = eServiceCenter.getInstance().info(currref)
826 description = info and info.getInfoString(currref, iServiceInformation.sDescription) or ""
827 self["title"].setText(description)
828 # display just playing musik on LCD
829 idx = self.playlist.getCurrentIndex()
830 currref = self.playlist.getServiceRefList()[idx]
831 text = self.getIdentifier(currref)
833 ext = text[-4:].lower()
835 # FIXME: the information if the service contains video (and we should hide our window) should com from the service instead
836 if ext not in audio_extensions and not self.isAudioCD:
839 needsInfoUpdate = True
840 self.summaries.setText(text,1)
842 # get the next two entries
844 if idx < len(self.playlist):
845 currref = self.playlist.getServiceRefList()[idx]
846 text = self.getIdentifier(currref)
847 self.summaries.setText(text,3)
849 self.summaries.setText(" ",3)
852 if idx < len(self.playlist):
853 currref = self.playlist.getServiceRefList()[idx]
854 text = self.getIdentifier(currref)
855 self.summaries.setText(text,4)
857 self.summaries.setText(" ",4)
859 idx = self.playlist.getCurrentIndex()
860 currref = self.playlist.getServiceRefList()[idx]
861 text = currref.getPath()
862 ext = text[-4:].lower()
863 if ext not in audio_extensions and not self.isAudioCD:
866 needsInfoUpdate = True
868 self.unPauseService()
869 if needsInfoUpdate == True:
870 path = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()].getPath()
871 self["coverArt"].updateCoverArt(path)
873 self["coverArt"].showDefaultCover()
874 self.readTitleInformation()
876 def updatedSeekState(self):
877 if self.seekstate == self.SEEK_STATE_PAUSE:
878 self.playlist.pauseFile()
879 elif self.seekstate == self.SEEK_STATE_PLAY:
880 self.playlist.playFile()
881 elif self.isStateForward(self.seekstate):
882 self.playlist.forwardFile()
883 elif self.isStateBackward(self.seekstate):
884 self.playlist.rewindFile()
886 def pauseEntry(self):
888 if self.seekstate == self.SEEK_STATE_PAUSE:
894 self.playlist.stopFile()
895 self.session.nav.playService(None)
896 self.updateMusicInformation(clear=True)
899 def unPauseService(self):
900 self.setSeekState(self.SEEK_STATE_PLAY)
902 def subtitleSelection(self):
903 from Screens.Subtitles import Subtitles
904 self.session.open(Subtitles, self)
906 def hotplugCB(self, dev, media_state):
907 if dev == harddiskmanager.getCD():
908 if media_state == "1":
909 from Components.Scanner import scanDevice
910 devpath = harddiskmanager.getAutofsMountpoint(harddiskmanager.getCD())
911 self.cdAudioTrackFiles = []
912 res = scanDevice(devpath)
913 list = [ (r.description, r, res[r], self.session) for r in res ]
915 (desc, scanner, files, session) = list[0]
917 if file.mimetype == "audio/x-cda":
918 self.cdAudioTrackFiles.append(file.path)
920 self.cdAudioTrackFiles = []
922 self.clear_playlist()
924 class MediaPlayerLCDScreen(Screen):
926 <screen position="0,0" size="132,64" title="LCD Text">
927 <widget name="text1" position="4,0" size="132,35" font="Regular;16"/>
928 <widget name="text3" position="4,36" size="132,14" font="Regular;10"/>
929 <widget name="text4" position="4,49" size="132,14" font="Regular;10"/>
932 def __init__(self, session, parent):
933 Screen.__init__(self, session)
934 self["text1"] = Label("Mediaplayer")
935 self["text3"] = Label("")
936 self["text4"] = Label("")
938 def setText(self, text, line):
940 if text[-4:] == ".mp3":
943 text = text + textleer*10
945 self["text1"].setText(text)
947 self["text3"].setText(text)
949 self["text4"].setText(text)
951 def main(session, **kwargs):
952 session.open(MediaPlayer)
954 def menu(menuid, **kwargs):
955 if menuid == "mainmenu":
956 return [(_("Media player"), main, "media_player", 45)]
959 def filescan_open(list, session, **kwargs):
960 from enigma import eServiceReference
962 mp = session.open(MediaPlayer)
964 mp.savePlaylistOnExit = False
967 if file.mimetype == "video/MP2T":
971 ref = eServiceReference(stype, 0, file.path)
972 mp.playlist.addFile(ref)
975 mp.switchToPlayList()
977 def audioCD_open(list, session, **kwargs):
978 from enigma import eServiceReference
980 mp = session.open(MediaPlayer)
981 mp.cdAudioTrackFiles = []
983 mp.cdAudioTrackFiles.append(file.path)
986 def filescan(**kwargs):
987 from Components.Scanner import Scanner, ScanPath
989 Scanner(mimetypes = ["video/mpeg", "video/MP2T", "video/x-msvideo"],
992 ScanPath(path = "", with_subdirs = False),
995 description = _("View Movies..."),
996 openfnc = filescan_open,
998 Scanner(mimetypes = ["video/x-vcd"],
1001 ScanPath(path = "mpegav", with_subdirs = False),
1002 ScanPath(path = "MPEGAV", with_subdirs = False),
1005 description = _("View Video CD..."),
1006 openfnc = filescan_open,
1008 Scanner(mimetypes = ["audio/mpeg", "audio/x-wav", "application/ogg", "audio/x-flac"],
1011 ScanPath(path = "", with_subdirs = False),
1014 description = _("Play Music..."),
1015 openfnc = filescan_open,
1018 from Plugins.Extensions.CDInfo.plugin import Query
1020 Scanner(mimetypes = ["audio/x-cda"],
1023 ScanPath(path = "", with_subdirs = False),
1026 description = _("Play Audio-CD..."),
1027 openfnc = audioCD_open,
1033 from Plugins.Plugin import PluginDescriptor
1034 def Plugins(**kwargs):
1036 PluginDescriptor(name = "MediaPlayer", description = "Play back media files", where = PluginDescriptor.WHERE_MENU, fnc = menu),
1037 PluginDescriptor(name = "MediaPlayer", where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan)