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|wav|wave|m3u|pls|e2pls|mpg|vob|avi|divx|m4v|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 = []
215 self.onShown.append(self.applySettings)
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:
245 self.playlistIOInternal.save(resolveFilename(SCOPE_CONFIG, "playlist.e2pls"))
247 print "couldn't save playlist.e2pls"
248 if config.mediaplayer.saveDirOnExit.getValue():
249 config.mediaplayer.defaultDir.setValue(self.filelist.getCurrentDirectory())
250 config.mediaplayer.defaultDir.save()
251 from Plugins.SystemPlugins.Hotplug.plugin import hotplugNotifier
252 hotplugNotifier.remove(self.hotplugCB)
253 del self["coverArt"].picload
256 def checkSkipShowHideLock(self):
257 self.updatedSeekState()
259 def doEofInternal(self, playing):
266 self.session.nav.playService(self.oldService)
268 def __evUpdatedInfo(self):
269 currPlay = self.session.nav.getCurrentService()
270 sTagTrackNumber = currPlay.info().getInfo(iServiceInformation.sTagTrackNumber)
271 sTagTrackCount = currPlay.info().getInfo(iServiceInformation.sTagTrackCount)
272 sTagTitle = currPlay.info().getInfoString(iServiceInformation.sTagTitle)
273 print "[__evUpdatedInfo] title %d of %d (%s)" % (sTagTrackNumber, sTagTrackCount, sTagTitle)
274 self.readTitleInformation()
276 def __evAudioDecodeError(self):
277 currPlay = self.session.nav.getCurrentService()
278 sTagAudioCodec = currPlay.info().getInfoString(iServiceInformation.sTagAudioCodec)
279 print "[__evAudioDecodeError] audio-codec %s can't be decoded by hardware" % (sTagAudioCodec)
280 self.session.open(MessageBox, _("This Dreambox can't decode %s streams!") % sTagAudioCodec, type = MessageBox.TYPE_INFO,timeout = 20 )
282 def __evVideoDecodeError(self):
283 currPlay = self.session.nav.getCurrentService()
284 sTagVideoCodec = currPlay.info().getInfoString(iServiceInformation.sTagVideoCodec)
285 print "[__evVideoDecodeError] video-codec %s can't be decoded by hardware" % (sTagVideoCodec)
286 self.session.open(MessageBox, _("This Dreambox can't decode %s streams!") % sTagVideoCodec, type = MessageBox.TYPE_INFO,timeout = 20 )
288 def __evPluginError(self):
289 currPlay = self.session.nav.getCurrentService()
290 message = currPlay.info().getInfoString(iServiceInformation.sUser+12)
291 print "[__evPluginError]" , message
292 self.session.open(MessageBox, message, type = MessageBox.TYPE_INFO,timeout = 20 )
294 def delMPTimer(self):
295 del self.rightKeyTimer
296 del self.leftKeyTimer
298 def readTitleInformation(self):
299 currPlay = self.session.nav.getCurrentService()
300 if currPlay is not None:
301 sTitle = currPlay.info().getInfoString(iServiceInformation.sTagTitle)
302 sAlbum = currPlay.info().getInfoString(iServiceInformation.sTagAlbum)
303 sGenre = currPlay.info().getInfoString(iServiceInformation.sTagGenre)
304 sArtist = currPlay.info().getInfoString(iServiceInformation.sTagArtist)
305 sYear = currPlay.info().getInfoString(iServiceInformation.sTagDate)
308 if not self.isAudioCD:
309 sTitle = currPlay.info().getName().split('/')[-1]
311 sTitle = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()].getName()
313 if self.AudioCD_albuminfo:
314 if sAlbum == "" and "title" in self.AudioCD_albuminfo:
315 sAlbum = self.AudioCD_albuminfo["title"]
316 if sGenre == "" and "genre" in self.AudioCD_albuminfo:
317 sGenre = self.AudioCD_albuminfo["genre"]
318 if sArtist == "" and "artist" in self.AudioCD_albuminfo:
319 sArtist = self.AudioCD_albuminfo["artist"]
320 if "year" in self.AudioCD_albuminfo:
321 sYear = self.AudioCD_albuminfo["year"]
323 self.updateMusicInformation( sArtist, sTitle, sAlbum, sYear, sGenre, clear = True )
325 self.updateMusicInformation()
327 def updateMusicInformation(self, artist = "", title = "", album = "", year = "", genre = "", clear = False):
328 self.updateSingleMusicInformation("artist", artist, clear)
329 self.updateSingleMusicInformation("title", title, clear)
330 self.updateSingleMusicInformation("album", album, clear)
331 self.updateSingleMusicInformation("year", year, clear)
332 self.updateSingleMusicInformation("genre", genre, clear)
334 def updateSingleMusicInformation(self, name, info, clear):
335 if info != "" or clear:
336 if self[name].getText() != info:
337 self[name].setText(info)
340 self.lefttimer = True
341 self.leftKeyTimer.start(1000)
344 self.righttimer = True
345 self.rightKeyTimer.start(1000)
349 self.leftKeyTimer.stop()
350 self.lefttimer = False
351 self[self.currList].pageUp()
352 self.updateCurrentInfo()
356 self.rightKeyTimer.stop()
357 self.righttimer = False
358 self[self.currList].pageDown()
359 self.updateCurrentInfo()
361 def leftTimerFire(self):
362 self.leftKeyTimer.stop()
363 self.lefttimer = False
364 self.switchToFileList()
366 def rightTimerFire(self):
367 self.rightKeyTimer.stop()
368 self.righttimer = False
369 self.switchToPlayList()
371 def switchToFileList(self):
372 self.currList = "filelist"
373 self.filelist.selectionEnabled(1)
374 self.playlist.selectionEnabled(0)
375 self.updateCurrentInfo()
377 def switchToPlayList(self):
378 if len(self.playlist) != 0:
379 self.currList = "playlist"
380 self.filelist.selectionEnabled(0)
381 self.playlist.selectionEnabled(1)
382 self.updateCurrentInfo()
385 self[self.currList].up()
386 self.updateCurrentInfo()
389 self[self.currList].down()
390 self.updateCurrentInfo()
392 def showAfterSeek(self):
395 def showAfterCuesheetOperation(self):
398 def hideAfterResume(self):
401 def getIdentifier(self, ref):
406 return text.split('/')[-1]
408 # FIXME: maybe this code can be optimized
409 def updateCurrentInfo(self):
411 if self.currList == "filelist":
412 idx = self.filelist.getSelectionIndex()
413 r = self.filelist.list[idx]
420 self.summaries.setText(text,1)
423 if idx < len(self.filelist.list):
424 r = self.filelist.list[idx]
428 self.summaries.setText(text,3)
430 self.summaries.setText(" ",3)
433 if idx < len(self.filelist.list):
434 r = self.filelist.list[idx]
438 self.summaries.setText(text,4)
440 self.summaries.setText(" ",4)
443 if not self.filelist.canDescent():
444 r = self.filelist.getServiceRef()
448 self["currenttext"].setText(os_path.basename(text))
450 if self.currList == "playlist":
451 t = self.playlist.getSelection()
454 #display current selected entry on LCD
455 text = self.getIdentifier(t)
456 self.summaries.setText(text,1)
457 self["currenttext"].setText(text)
458 idx = self.playlist.getSelectionIndex()
460 if idx < len(self.playlist):
461 currref = self.playlist.getServiceRefList()[idx]
462 text = self.getIdentifier(currref)
463 self.summaries.setText(text,3)
465 self.summaries.setText(" ",3)
468 if idx < len(self.playlist):
469 currref = self.playlist.getServiceRefList()[idx]
470 text = self.getIdentifier(currref)
471 self.summaries.setText(text,4)
473 self.summaries.setText(" ",4)
476 if self.currList == "filelist":
477 if self.filelist.canDescent():
478 self.filelist.descent()
479 self.updateCurrentInfo()
483 if self.currList == "playlist":
484 selection = self["playlist"].getSelection()
485 self.changeEntry(self.playlist.getSelectionIndex())
489 if len(self.cdAudioTrackFiles):
490 menu.insert(0,(_("Play Audio-CD..."), "audiocd"))
491 if self.currList == "filelist":
492 if self.filelist.canDescent():
493 menu.append((_("add directory to playlist"), "copydir"))
495 menu.append((_("add files to playlist"), "copyfiles"))
496 menu.append((_("switch to playlist"), "playlist"))
497 if config.usage.setup_level.index >= 1: # intermediate+
498 menu.append((_("delete file"), "deletefile"))
500 menu.append((_("switch to filelist"), "filelist"))
501 menu.append((_("clear playlist"), "clear"))
502 menu.append((_("Delete entry"), "deleteentry"))
503 if config.usage.setup_level.index >= 1: # intermediate+
504 menu.append((_("shuffle playlist"), "shuffle"))
505 menu.append((_("hide player"), "hide"));
506 menu.append((_("load playlist"), "loadplaylist"));
507 if config.usage.setup_level.index >= 1: # intermediate+
508 menu.append((_("save playlist"), "saveplaylist"));
509 menu.append((_("delete saved playlist"), "deleteplaylist"));
510 menu.append((_("Edit settings"), "settings"))
511 self.session.openWithCallback(self.menuCallback, ChoiceBox, title="", list=menu)
513 def menuCallback(self, choice):
517 if choice[1] == "copydir":
518 self.copyDirectory(self.filelist.getSelection()[0])
519 elif choice[1] == "copyfiles":
521 self.playlist.clear()
522 self.isAudioCD = False
523 self.copyDirectory(os_path.dirname(self.filelist.getSelection()[0].getPath()) + "/", recursive = False)
524 self.playServiceRefEntry(self.filelist.getServiceRef())
525 elif choice[1] == "playlist":
526 self.switchToPlayList()
527 elif choice[1] == "filelist":
528 self.switchToFileList()
529 elif choice[1] == "deleteentry":
530 if self.playlist.getSelectionIndex() == self.playlist.getCurrentIndex():
533 elif choice[1] == "clear":
534 self.clear_playlist()
535 elif choice[1] == "hide":
537 elif choice[1] == "saveplaylist":
539 elif choice[1] == "loadplaylist":
541 elif choice[1] == "deleteplaylist":
542 self.delete_saved_playlist()
543 elif choice[1] == "shuffle":
544 self.playlist.PlayListShuffle()
545 elif choice[1] == "deletefile":
547 elif choice[1] == "settings":
548 self.session.openWithCallback(self.applySettings, MediaPlayerSettings, self)
549 elif choice[1] == "audiocd":
552 def playAudioCD(self):
553 from enigma import eServiceReference
554 from Plugins.Extensions.CDInfo.plugin import Query
556 if len(self.cdAudioTrackFiles):
557 self.playlist.clear()
558 self.savePlaylistOnExit = False
559 self.isAudioCD = True
560 for file in self.cdAudioTrackFiles:
561 ref = eServiceReference(4097, 0, file)
562 self.playlist.addFile(ref)
566 self.switchToPlayList()
568 def applySettings(self):
569 self.savePlaylistOnExit = config.mediaplayer.savePlaylistOnExit.getValue()
570 if config.mediaplayer.repeat.getValue() == True:
571 self["repeat"].setPixmapNum(1)
573 self["repeat"].setPixmapNum(0)
575 def showEventInformation(self):
576 from Screens.EventView import EventViewSimple
577 from ServiceReference import ServiceReference
578 evt = self[self.currList].getCurrentEvent()
580 self.session.open(EventViewSimple, evt, ServiceReference(self.getCurrent()))
582 # also works on filelist (?)
583 def getCurrent(self):
584 return self["playlist"].getCurrent()
586 def deletePlaylistEntry(self):
587 if self.currList == "playlist":
588 if self.playlist.getSelectionIndex() == self.playlist.getCurrentIndex():
592 def skip_listbegin(self):
593 if self.currList == "filelist":
594 self.filelist.moveToIndex(0)
596 self.playlist.moveToIndex(0)
597 self.updateCurrentInfo()
599 def skip_listend(self):
600 if self.currList == "filelist":
601 idx = len(self.filelist.list)
602 self.filelist.moveToIndex(idx - 1)
604 self.playlist.moveToIndex(len(self.playlist)-1)
605 self.updateCurrentInfo()
607 def save_playlist(self):
608 self.session.openWithCallback(self.save_playlist2,InputBox, title=_("Please enter filename (empty = use current date)"),windowTitle = _("Save Playlist"))
610 def save_playlist2(self, name):
614 name = strftime("%y%m%d_%H%M%S")
616 self.playlistIOInternal.clear()
617 for x in self.playlist.list:
618 self.playlistIOInternal.addService(ServiceReference(x[0]))
619 self.playlistIOInternal.save(resolveFilename(SCOPE_PLAYLIST) + name)
621 def load_playlist(self):
623 playlistdir = resolveFilename(SCOPE_PLAYLIST)
625 for i in os_listdir(playlistdir):
626 listpath.append((i,playlistdir + i))
628 print "Error while scanning subdirs ",e
629 self.session.openWithCallback(self.PlaylistSelected, ChoiceBox, title=_("Please select a playlist..."), list = listpath)
631 def PlaylistSelected(self,path):
633 self.clear_playlist()
634 extension = path[0].rsplit('.',1)[-1]
635 if self.playlistparsers.has_key(extension):
636 playlist = self.playlistparsers[extension]()
637 list = playlist.open(path[1])
639 self.playlist.addFile(x.ref)
640 self.playlist.updateList()
642 def delete_saved_playlist(self):
644 playlistdir = resolveFilename(SCOPE_PLAYLIST)
646 for i in os_listdir(playlistdir):
647 listpath.append((i,playlistdir + i))
649 print "Error while scanning subdirs ",e
650 self.session.openWithCallback(self.DeletePlaylistSelected, ChoiceBox, title=_("Please select a playlist to delete..."), list = listpath)
652 def DeletePlaylistSelected(self,path):
654 self.delname = path[1]
655 self.session.openWithCallback(self.deleteConfirmed, MessageBox, _("Do you really want to delete %s?") % (path[1]))
657 def deleteConfirmed(self, confirmed):
660 os_remove(self.delname)
662 print "delete failed:", e
663 self.session.open(MessageBox, _("Delete failed!"), MessageBox.TYPE_ERROR)
665 def clear_playlist(self):
666 self.isAudioCD = False
668 self.playlist.clear()
669 self.switchToFileList()
671 def copyDirectory(self, directory, recursive = True):
672 print "copyDirectory", directory
674 print "refusing to operate on /"
676 filelist = FileList(directory, useServiceRef = True, showMountpoints = False, isTop = True)
678 for x in filelist.getFileList():
679 if x[0][1] == True: #isDir
681 if x[0][0] != directory:
682 self.copyDirectory(x[0][0])
683 elif filelist.getServiceRef() and filelist.getServiceRef().type == 4097:
684 self.playlist.addFile(x[0][0])
685 self.playlist.updateList()
687 def deleteFile(self):
688 if self.currList == "filelist":
689 self.service = self.filelist.getServiceRef()
691 self.service = self.playlist.getSelection()
692 if self.service is None:
694 if self.service.type != 4098 and self.session.nav.getCurrentlyPlayingServiceReference() is not None:
695 if self.service == self.session.nav.getCurrentlyPlayingServiceReference():
698 serviceHandler = eServiceCenter.getInstance()
699 offline = serviceHandler.offlineOperations(self.service)
700 info = serviceHandler.info(self.service)
701 name = info and info.getName(self.service)
703 if offline is not None:
705 if not offline.deleteFromDisk(1):
708 self.session.openWithCallback(self.deleteConfirmed_offline, MessageBox, _("Do you really want to delete %s?") % (name))
710 self.session.openWithCallback(self.close, MessageBox, _("You cannot delete this!"), MessageBox.TYPE_ERROR)
712 def deleteConfirmed_offline(self, confirmed):
714 serviceHandler = eServiceCenter.getInstance()
715 offline = serviceHandler.offlineOperations(self.service)
717 if offline is not None:
719 if not offline.deleteFromDisk(0):
722 self.session.open(MessageBox, _("Delete failed!"), MessageBox.TYPE_ERROR)
724 self.removeListEntry()
726 def removeListEntry(self):
727 currdir = self.filelist.getCurrentDirectory()
728 self.filelist.changeDir(currdir)
733 if len(self.playlist) > 0:
734 for x in self.playlist.list:
735 if self.service == x[0]:
736 self.playlist.deleteFile(index)
740 self.playlist.updateList()
741 if self.currList == "playlist":
742 if len(self.playlist) == 0:
743 self.switchToFileList()
746 if self.filelist.getServiceRef().type == 4098: # playlist
747 ServiceRef = self.filelist.getServiceRef()
748 extension = ServiceRef.getPath()[ServiceRef.getPath().rfind('.') + 1:]
749 if self.playlistparsers.has_key(extension):
750 playlist = self.playlistparsers[extension]()
751 list = playlist.open(ServiceRef.getPath())
753 self.playlist.addFile(x.ref)
754 self.playlist.updateList()
756 self.playlist.addFile(self.filelist.getServiceRef())
757 self.playlist.updateList()
758 if len(self.playlist) == 1:
761 def addPlaylistParser(self, parser, extension):
762 self.playlistparsers[extension] = parser
765 next = self.playlist.getCurrentIndex() + 1
766 if next < len(self.playlist):
767 self.changeEntry(next)
768 elif ( len(self.playlist) > 0 ) and ( config.mediaplayer.repeat.getValue() == True ):
772 def nextMarkOrEntry(self):
773 if not self.jumpPreviousNextMark(lambda x: x):
774 next = self.playlist.getCurrentIndex() + 1
775 if next < len(self.playlist):
776 self.changeEntry(next)
780 def previousMarkOrEntry(self):
781 if not self.jumpPreviousNextMark(lambda x: -x-5*90000, start=True):
782 next = self.playlist.getCurrentIndex() - 1
784 self.changeEntry(next)
786 def deleteEntry(self):
787 self.playlist.deleteFile(self.playlist.getSelectionIndex())
788 self.playlist.updateList()
789 if len(self.playlist) == 0:
790 self.switchToFileList()
792 def changeEntry(self, index):
793 self.playlist.setCurrentPlaying(index)
796 def playServiceRefEntry(self, serviceref):
797 serviceRefList = self.playlist.getServiceRefList()
798 for count in range(len(serviceRefList)):
799 if serviceRefList[count] == serviceref:
800 self.changeEntry(count)
803 def xplayEntry(self):
804 if self.currList == "playlist":
808 self.playlist.clear()
809 self.isAudioCD = False
810 sel = self.filelist.getSelection()
812 if sel[1]: # can descent
813 # add directory to playlist
814 self.copyDirectory(sel[0])
816 # add files to playlist
817 self.copyDirectory(os_path.dirname(sel[0].getPath()) + "/", recursive = False)
818 if len(self.playlist) > 0:
822 if len(self.playlist.getServiceRefList()):
823 audio_extensions = (".mp2", ".mp3", ".wav", ".ogg", "flac", "m4a")
824 needsInfoUpdate = False
825 currref = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()]
826 if self.session.nav.getCurrentlyPlayingServiceReference() is None or currref != self.session.nav.getCurrentlyPlayingServiceReference():
827 self.session.nav.playService(self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()])
828 info = eServiceCenter.getInstance().info(currref)
829 description = info and info.getInfoString(currref, iServiceInformation.sDescription) or ""
830 self["title"].setText(description)
831 # display just playing musik on LCD
832 idx = self.playlist.getCurrentIndex()
833 currref = self.playlist.getServiceRefList()[idx]
834 text = self.getIdentifier(currref)
836 ext = text[-4:].lower()
838 # FIXME: the information if the service contains video (and we should hide our window) should com from the service instead
839 if ext not in audio_extensions and not self.isAudioCD:
842 needsInfoUpdate = True
843 self.summaries.setText(text,1)
845 # get the next two entries
847 if idx < len(self.playlist):
848 currref = self.playlist.getServiceRefList()[idx]
849 text = self.getIdentifier(currref)
850 self.summaries.setText(text,3)
852 self.summaries.setText(" ",3)
855 if idx < len(self.playlist):
856 currref = self.playlist.getServiceRefList()[idx]
857 text = self.getIdentifier(currref)
858 self.summaries.setText(text,4)
860 self.summaries.setText(" ",4)
862 idx = self.playlist.getCurrentIndex()
863 currref = self.playlist.getServiceRefList()[idx]
864 text = currref.getPath()
865 ext = text[-4:].lower()
866 if ext not in audio_extensions and not self.isAudioCD:
869 needsInfoUpdate = True
871 self.unPauseService()
872 if needsInfoUpdate == True:
873 path = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()].getPath()
874 self["coverArt"].updateCoverArt(path)
876 self["coverArt"].showDefaultCover()
877 self.readTitleInformation()
879 def updatedSeekState(self):
880 if self.seekstate == self.SEEK_STATE_PAUSE:
881 self.playlist.pauseFile()
882 elif self.seekstate == self.SEEK_STATE_PLAY:
883 self.playlist.playFile()
884 elif self.isStateForward(self.seekstate):
885 self.playlist.forwardFile()
886 elif self.isStateBackward(self.seekstate):
887 self.playlist.rewindFile()
889 def pauseEntry(self):
891 if self.seekstate == self.SEEK_STATE_PAUSE:
897 self.playlist.stopFile()
898 self.session.nav.playService(None)
899 self.updateMusicInformation(clear=True)
902 def unPauseService(self):
903 self.setSeekState(self.SEEK_STATE_PLAY)
905 def subtitleSelection(self):
906 from Screens.Subtitles import Subtitles
907 self.session.open(Subtitles, self)
909 def hotplugCB(self, dev, media_state):
910 if dev == harddiskmanager.getCD():
911 if media_state == "1":
912 from Components.Scanner import scanDevice
913 devpath = harddiskmanager.getAutofsMountpoint(harddiskmanager.getCD())
914 self.cdAudioTrackFiles = []
915 res = scanDevice(devpath)
916 list = [ (r.description, r, res[r], self.session) for r in res ]
918 (desc, scanner, files, session) = list[0]
920 if file.mimetype == "audio/x-cda":
921 self.cdAudioTrackFiles.append(file.path)
923 self.cdAudioTrackFiles = []
925 self.clear_playlist()
927 class MediaPlayerLCDScreen(Screen):
929 <screen position="0,0" size="132,64" title="LCD Text">
930 <widget name="text1" position="4,0" size="132,35" font="Regular;16"/>
931 <widget name="text3" position="4,36" size="132,14" font="Regular;10"/>
932 <widget name="text4" position="4,49" size="132,14" font="Regular;10"/>
935 def __init__(self, session, parent):
936 Screen.__init__(self, session)
937 self["text1"] = Label("Mediaplayer")
938 self["text3"] = Label("")
939 self["text4"] = Label("")
941 def setText(self, text, line):
943 if text[-4:] == ".mp3":
946 text = text + textleer*10
948 self["text1"].setText(text)
950 self["text3"].setText(text)
952 self["text4"].setText(text)
954 def main(session, **kwargs):
955 session.open(MediaPlayer)
957 def menu(menuid, **kwargs):
958 if menuid == "mainmenu":
959 return [(_("Media player"), main, "media_player", 45)]
962 def filescan_open(list, session, **kwargs):
963 from enigma import eServiceReference
965 mp = session.open(MediaPlayer)
967 mp.savePlaylistOnExit = False
970 if file.mimetype == "video/MP2T":
974 ref = eServiceReference(stype, 0, file.path)
975 mp.playlist.addFile(ref)
978 mp.switchToPlayList()
980 def audioCD_open(list, session, **kwargs):
981 from enigma import eServiceReference
983 mp = session.open(MediaPlayer)
984 mp.cdAudioTrackFiles = []
986 mp.cdAudioTrackFiles.append(file.path)
989 def filescan(**kwargs):
990 from Components.Scanner import Scanner, ScanPath
992 Scanner(mimetypes = ["video/mpeg", "video/MP2T", "video/x-msvideo"],
995 ScanPath(path = "", with_subdirs = False),
998 description = _("View Movies..."),
999 openfnc = filescan_open,
1001 Scanner(mimetypes = ["video/x-vcd"],
1004 ScanPath(path = "mpegav", with_subdirs = False),
1005 ScanPath(path = "MPEGAV", with_subdirs = False),
1008 description = _("View Video CD..."),
1009 openfnc = filescan_open,
1011 Scanner(mimetypes = ["audio/mpeg", "audio/x-wav", "application/ogg", "audio/x-flac"],
1014 ScanPath(path = "", with_subdirs = False),
1017 description = _("Play Music..."),
1018 openfnc = filescan_open,
1021 from Plugins.Extensions.CDInfo.plugin import Query
1023 Scanner(mimetypes = ["audio/x-cda"],
1026 ScanPath(path = "", with_subdirs = False),
1029 description = _("Play Audio-CD..."),
1030 openfnc = audioCD_open,
1036 from Plugins.Plugin import PluginDescriptor
1037 def Plugins(**kwargs):
1039 PluginDescriptor(name = "MediaPlayer", description = "Play back media files", where = PluginDescriptor.WHERE_MENU, fnc = menu),
1040 PluginDescriptor(name = "MediaPlayer", where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan)