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_CURRENT_SKIN
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_CURRENT_SKIN, "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|m2ts|flv|dts|3gp|3g2|mts|wmv|asf|wma)", 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 "shift_stop": self.clear_playlist,
174 "shift_record": self.playlist.PlayListShuffle,
175 "subtitles": (self.subtitleSelection, _("Subtitle selection")),
178 self["InfobarEPGActions"] = HelpableActionMap(self, "InfobarEPGActions",
180 "showEventInfo": (self.showEventInformation, _("show event details")),
183 self["actions"] = MoviePlayerActionMap(self, ["DirectionActions"],
185 "right": self.rightDown,
186 "rightRepeated": self.doNothing,
187 "rightUp": self.rightUp,
188 "left": self.leftDown,
189 "leftRepeated": self.doNothing,
190 "leftUp": self.leftUp,
193 "upRepeated": self.up,
194 "upUp": self.doNothing,
196 "downRepeated": self.down,
197 "downUp": self.doNothing,
200 InfoBarSeek.__init__(self, actionmap = "MediaPlayerSeekActions")
202 self.onClose.append(self.delMPTimer)
203 self.onClose.append(self.__onClose)
205 self.righttimer = False
206 self.rightKeyTimer = eTimer()
207 self.rightKeyTimer.callback.append(self.rightTimerFire)
209 self.lefttimer = False
210 self.leftKeyTimer = eTimer()
211 self.leftKeyTimer.callback.append(self.leftTimerFire)
213 self.currList = "filelist"
214 self.isAudioCD = False
215 self.AudioCD_albuminfo = {}
216 self.cdAudioTrackFiles = []
217 self.onShown.append(self.applySettings)
219 self.playlistIOInternal = PlaylistIOInternal()
220 list = self.playlistIOInternal.open(resolveFilename(SCOPE_CONFIG, "playlist.e2pls"))
223 self.playlist.addFile(x.ref)
224 self.playlist.updateList()
226 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
228 iPlayableService.evUpdatedInfo: self.__evUpdatedInfo,
229 iPlayableService.evUser+10: self.__evAudioDecodeError,
230 iPlayableService.evUser+11: self.__evVideoDecodeError,
231 iPlayableService.evUser+12: self.__evPluginError,
232 iPlayableService.evUser+13: self["coverArt"].embeddedCoverArt
238 def createSummary(self):
239 return MediaPlayerLCDScreen
242 self.playlistIOInternal.clear()
243 for x in self.playlist.list:
244 self.playlistIOInternal.addService(ServiceReference(x[0]))
245 if self.savePlaylistOnExit:
247 self.playlistIOInternal.save(resolveFilename(SCOPE_CONFIG, "playlist.e2pls"))
249 print "couldn't save playlist.e2pls"
250 if config.mediaplayer.saveDirOnExit.getValue():
251 config.mediaplayer.defaultDir.setValue(self.filelist.getCurrentDirectory())
252 config.mediaplayer.defaultDir.save()
253 # from Plugins.SystemPlugins.Hotplug.plugin import hotplugNotifier
254 # hotplugNotifier.remove(self.hotplugCB)
255 del self["coverArt"].picload
258 def checkSkipShowHideLock(self):
259 self.updatedSeekState()
261 def doEofInternal(self, playing):
268 self.session.nav.playService(self.oldService)
270 def __evUpdatedInfo(self):
271 currPlay = self.session.nav.getCurrentService()
272 sTagTrackNumber = currPlay.info().getInfo(iServiceInformation.sTagTrackNumber)
273 sTagTrackCount = currPlay.info().getInfo(iServiceInformation.sTagTrackCount)
274 sTagTitle = currPlay.info().getInfoString(iServiceInformation.sTagTitle)
275 print "[__evUpdatedInfo] title %d of %d (%s)" % (sTagTrackNumber, sTagTrackCount, sTagTitle)
276 self.readTitleInformation()
278 def __evAudioDecodeError(self):
279 currPlay = self.session.nav.getCurrentService()
280 sTagAudioCodec = currPlay.info().getInfoString(iServiceInformation.sTagAudioCodec)
281 print "[__evAudioDecodeError] audio-codec %s can't be decoded by hardware" % (sTagAudioCodec)
282 self.session.open(MessageBox, _("This STB can't decode %s streams!") % sTagAudioCodec, type = MessageBox.TYPE_INFO,timeout = 20 )
284 def __evVideoDecodeError(self):
285 currPlay = self.session.nav.getCurrentService()
286 sTagVideoCodec = currPlay.info().getInfoString(iServiceInformation.sTagVideoCodec)
287 print "[__evVideoDecodeError] video-codec %s can't be decoded by hardware" % (sTagVideoCodec)
288 self.session.open(MessageBox, _("This STB can't decode %s streams!") % sTagVideoCodec, type = MessageBox.TYPE_INFO,timeout = 20 )
290 def __evPluginError(self):
291 currPlay = self.session.nav.getCurrentService()
292 message = currPlay.info().getInfoString(iServiceInformation.sUser+12)
293 print "[__evPluginError]" , message
294 self.session.open(MessageBox, message, type = MessageBox.TYPE_INFO,timeout = 20 )
296 def delMPTimer(self):
297 del self.rightKeyTimer
298 del self.leftKeyTimer
300 def readTitleInformation(self):
301 currPlay = self.session.nav.getCurrentService()
302 if currPlay is not None:
303 sTitle = currPlay.info().getInfoString(iServiceInformation.sTagTitle)
304 sAlbum = currPlay.info().getInfoString(iServiceInformation.sTagAlbum)
305 sGenre = currPlay.info().getInfoString(iServiceInformation.sTagGenre)
306 sArtist = currPlay.info().getInfoString(iServiceInformation.sTagArtist)
307 sYear = currPlay.info().getInfoString(iServiceInformation.sTagDate)
310 if not self.isAudioCD:
311 sTitle = currPlay.info().getName().split('/')[-1]
313 sTitle = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()].getName()
315 if self.AudioCD_albuminfo:
316 if sAlbum == "" and "title" in self.AudioCD_albuminfo:
317 sAlbum = self.AudioCD_albuminfo["title"]
318 if sGenre == "" and "genre" in self.AudioCD_albuminfo:
319 sGenre = self.AudioCD_albuminfo["genre"]
320 if sArtist == "" and "artist" in self.AudioCD_albuminfo:
321 sArtist = self.AudioCD_albuminfo["artist"]
322 if "year" in self.AudioCD_albuminfo:
323 sYear = self.AudioCD_albuminfo["year"]
325 self.updateMusicInformation( sArtist, sTitle, sAlbum, sYear, sGenre, clear = True )
327 self.updateMusicInformation()
329 def updateMusicInformation(self, artist = "", title = "", album = "", year = "", genre = "", clear = False):
330 self.updateSingleMusicInformation("artist", artist, clear)
331 self.updateSingleMusicInformation("title", title, clear)
332 self.updateSingleMusicInformation("album", album, clear)
333 self.updateSingleMusicInformation("year", year, clear)
334 self.updateSingleMusicInformation("genre", genre, clear)
336 def updateSingleMusicInformation(self, name, info, clear):
337 if info != "" or clear:
338 if self[name].getText() != info:
339 self[name].setText(info)
342 self.lefttimer = True
343 self.leftKeyTimer.start(1000)
346 self.righttimer = True
347 self.rightKeyTimer.start(1000)
351 self.leftKeyTimer.stop()
352 self.lefttimer = False
353 self[self.currList].pageUp()
354 self.updateCurrentInfo()
358 self.rightKeyTimer.stop()
359 self.righttimer = False
360 self[self.currList].pageDown()
361 self.updateCurrentInfo()
363 def leftTimerFire(self):
364 self.leftKeyTimer.stop()
365 self.lefttimer = False
366 self.switchToFileList()
368 def rightTimerFire(self):
369 self.rightKeyTimer.stop()
370 self.righttimer = False
371 self.switchToPlayList()
373 def switchToFileList(self):
374 self.currList = "filelist"
375 self.filelist.selectionEnabled(1)
376 self.playlist.selectionEnabled(0)
377 self.updateCurrentInfo()
379 def switchToPlayList(self):
380 if len(self.playlist) != 0:
381 self.currList = "playlist"
382 self.filelist.selectionEnabled(0)
383 self.playlist.selectionEnabled(1)
384 self.updateCurrentInfo()
387 self[self.currList].up()
388 self.updateCurrentInfo()
391 self[self.currList].down()
392 self.updateCurrentInfo()
394 def showAfterSeek(self):
397 def showAfterCuesheetOperation(self):
400 def hideAfterResume(self):
403 def getIdentifier(self, ref):
408 return text.split('/')[-1]
410 # FIXME: maybe this code can be optimized
411 def updateCurrentInfo(self):
413 if self.currList == "filelist":
414 idx = self.filelist.getSelectionIndex()
415 r = self.filelist.list[idx]
422 self.summaries.setText(text,1)
425 if idx < len(self.filelist.list):
426 r = self.filelist.list[idx]
430 self.summaries.setText(text,3)
432 self.summaries.setText(" ",3)
435 if idx < len(self.filelist.list):
436 r = self.filelist.list[idx]
440 self.summaries.setText(text,4)
442 self.summaries.setText(" ",4)
445 if not self.filelist.canDescent():
446 r = self.filelist.getServiceRef()
450 self["currenttext"].setText(os_path.basename(text))
452 if self.currList == "playlist":
453 t = self.playlist.getSelection()
456 #display current selected entry on LCD
457 text = self.getIdentifier(t)
458 self.summaries.setText(text,1)
459 self["currenttext"].setText(text)
460 idx = self.playlist.getSelectionIndex()
462 if idx < len(self.playlist):
463 currref = self.playlist.getServiceRefList()[idx]
464 text = self.getIdentifier(currref)
465 self.summaries.setText(text,3)
467 self.summaries.setText(" ",3)
470 if idx < len(self.playlist):
471 currref = self.playlist.getServiceRefList()[idx]
472 text = self.getIdentifier(currref)
473 self.summaries.setText(text,4)
475 self.summaries.setText(" ",4)
478 if self.currList == "filelist":
479 if self.filelist.canDescent():
480 self.filelist.descent()
481 self.updateCurrentInfo()
485 if self.currList == "playlist":
486 selection = self["playlist"].getSelection()
487 self.changeEntry(self.playlist.getSelectionIndex())
491 if len(self.cdAudioTrackFiles):
492 menu.insert(0,(_("Play Audio-CD..."), "audiocd"))
493 if self.currList == "filelist":
494 if self.filelist.canDescent():
495 menu.append((_("add directory to playlist"), "copydir"))
497 menu.append((_("add files to playlist"), "copyfiles"))
498 menu.append((_("switch to playlist"), "playlist"))
499 if config.usage.setup_level.index >= 1: # intermediate+
500 menu.append((_("delete file"), "deletefile"))
502 menu.append((_("switch to filelist"), "filelist"))
503 menu.append((_("clear playlist"), "clear"))
504 menu.append((_("Delete entry"), "deleteentry"))
505 if config.usage.setup_level.index >= 1: # intermediate+
506 menu.append((_("shuffle playlist"), "shuffle"))
507 menu.append((_("hide player"), "hide"));
508 menu.append((_("load playlist"), "loadplaylist"));
509 if config.usage.setup_level.index >= 1: # intermediate+
510 menu.append((_("save playlist"), "saveplaylist"));
511 menu.append((_("delete saved playlist"), "deleteplaylist"));
512 menu.append((_("Edit settings"), "settings"))
513 self.session.openWithCallback(self.menuCallback, ChoiceBox, title="", list=menu)
515 def menuCallback(self, choice):
519 if choice[1] == "copydir":
520 self.copyDirectory(self.filelist.getSelection()[0])
521 elif choice[1] == "copyfiles":
523 self.playlist.clear()
524 self.isAudioCD = False
525 self.copyDirectory(os_path.dirname(self.filelist.getSelection()[0].getPath()) + "/", recursive = False)
526 self.playServiceRefEntry(self.filelist.getServiceRef())
527 elif choice[1] == "playlist":
528 self.switchToPlayList()
529 elif choice[1] == "filelist":
530 self.switchToFileList()
531 elif choice[1] == "deleteentry":
532 if self.playlist.getSelectionIndex() == self.playlist.getCurrentIndex():
535 elif choice[1] == "clear":
536 self.clear_playlist()
537 elif choice[1] == "hide":
539 elif choice[1] == "saveplaylist":
541 elif choice[1] == "loadplaylist":
543 elif choice[1] == "deleteplaylist":
544 self.delete_saved_playlist()
545 elif choice[1] == "shuffle":
546 self.playlist.PlayListShuffle()
547 elif choice[1] == "deletefile":
549 elif choice[1] == "settings":
550 self.session.openWithCallback(self.applySettings, MediaPlayerSettings, self)
551 elif choice[1] == "audiocd":
554 def playAudioCD(self):
555 from enigma import eServiceReference
556 from Plugins.Extensions.CDInfo.plugin import Query
558 if len(self.cdAudioTrackFiles):
559 self.playlist.clear()
560 self.savePlaylistOnExit = False
561 self.isAudioCD = True
562 for file in self.cdAudioTrackFiles:
563 ref = eServiceReference(4097, 0, file)
564 self.playlist.addFile(ref)
568 self.switchToPlayList()
570 def applySettings(self):
571 self.savePlaylistOnExit = config.mediaplayer.savePlaylistOnExit.getValue()
572 if config.mediaplayer.repeat.getValue() == True:
573 self["repeat"].setPixmapNum(1)
575 self["repeat"].setPixmapNum(0)
577 def showEventInformation(self):
578 from Screens.EventView import EventViewSimple
579 from ServiceReference import ServiceReference
580 evt = self[self.currList].getCurrentEvent()
582 self.session.open(EventViewSimple, evt, ServiceReference(self.getCurrent()))
584 # also works on filelist (?)
585 def getCurrent(self):
586 return self["playlist"].getCurrent()
588 def deletePlaylistEntry(self):
589 if self.currList == "playlist":
590 if self.playlist.getSelectionIndex() == self.playlist.getCurrentIndex():
594 def skip_listbegin(self):
595 if self.currList == "filelist":
596 self.filelist.moveToIndex(0)
598 self.playlist.moveToIndex(0)
599 self.updateCurrentInfo()
601 def skip_listend(self):
602 if self.currList == "filelist":
603 idx = len(self.filelist.list)
604 self.filelist.moveToIndex(idx - 1)
606 self.playlist.moveToIndex(len(self.playlist)-1)
607 self.updateCurrentInfo()
609 def save_playlist(self):
610 self.session.openWithCallback(self.save_playlist2,InputBox, title=_("Please enter filename (empty = use current date)"),windowTitle = _("Save Playlist"))
612 def save_playlist2(self, name):
616 name = strftime("%y%m%d_%H%M%S")
618 self.playlistIOInternal.clear()
619 for x in self.playlist.list:
620 self.playlistIOInternal.addService(ServiceReference(x[0]))
621 self.playlistIOInternal.save(resolveFilename(SCOPE_PLAYLIST) + name)
623 def load_playlist(self):
625 playlistdir = resolveFilename(SCOPE_PLAYLIST)
627 for i in os_listdir(playlistdir):
628 listpath.append((i,playlistdir + i))
630 print "Error while scanning subdirs ",e
631 self.session.openWithCallback(self.PlaylistSelected, ChoiceBox, title=_("Please select a playlist..."), list = listpath)
633 def PlaylistSelected(self,path):
635 self.clear_playlist()
636 extension = path[0].rsplit('.',1)[-1]
637 if self.playlistparsers.has_key(extension):
638 playlist = self.playlistparsers[extension]()
639 list = playlist.open(path[1])
641 self.playlist.addFile(x.ref)
642 self.playlist.updateList()
644 def delete_saved_playlist(self):
646 playlistdir = resolveFilename(SCOPE_PLAYLIST)
648 for i in os_listdir(playlistdir):
649 listpath.append((i,playlistdir + i))
651 print "Error while scanning subdirs ",e
652 self.session.openWithCallback(self.DeletePlaylistSelected, ChoiceBox, title=_("Please select a playlist to delete..."), list = listpath)
654 def DeletePlaylistSelected(self,path):
656 self.delname = path[1]
657 self.session.openWithCallback(self.deleteConfirmed, MessageBox, _("Do you really want to delete %s?") % (path[1]))
659 def deleteConfirmed(self, confirmed):
662 os_remove(self.delname)
664 print "delete failed:", e
665 self.session.open(MessageBox, _("Delete failed!"), MessageBox.TYPE_ERROR)
667 def clear_playlist(self):
668 self.isAudioCD = False
670 self.playlist.clear()
671 self.switchToFileList()
673 def copyDirectory(self, directory, recursive = True):
674 print "copyDirectory", directory
676 print "refusing to operate on /"
678 filelist = FileList(directory, useServiceRef = True, showMountpoints = False, isTop = True)
680 for x in filelist.getFileList():
685 if data != directory:
686 self.copyDirectory(x[0][0])
687 elif data and data.type in (2, 3, 4097):
688 self.playlist.addFile(data)
689 self.playlist.updateList()
691 def deleteFile(self):
692 if self.currList == "filelist":
693 self.service = self.filelist.getServiceRef()
695 self.service = self.playlist.getSelection()
696 if self.service is None:
698 if self.service.type != 4098 and self.session.nav.getCurrentlyPlayingServiceReference() is not None:
699 if self.service == self.session.nav.getCurrentlyPlayingServiceReference():
702 serviceHandler = eServiceCenter.getInstance()
703 offline = serviceHandler.offlineOperations(self.service)
704 info = serviceHandler.info(self.service)
705 name = info and info.getName(self.service)
707 if offline is not None:
709 if not offline.deleteFromDisk(1):
712 self.session.openWithCallback(self.deleteConfirmed_offline, MessageBox, _("Do you really want to delete %s?") % (name))
714 self.session.openWithCallback(self.close, MessageBox, _("You cannot delete this!"), MessageBox.TYPE_ERROR)
716 def deleteConfirmed_offline(self, confirmed):
718 serviceHandler = eServiceCenter.getInstance()
719 offline = serviceHandler.offlineOperations(self.service)
721 if offline is not None:
723 if not offline.deleteFromDisk(0):
726 self.session.open(MessageBox, _("Delete failed!"), MessageBox.TYPE_ERROR)
728 self.removeListEntry()
730 def removeListEntry(self):
731 currdir = self.filelist.getCurrentDirectory()
732 self.filelist.changeDir(currdir)
737 if len(self.playlist) > 0:
738 for x in self.playlist.list:
739 if self.service == x[0]:
740 self.playlist.deleteFile(index)
744 self.playlist.updateList()
745 if self.currList == "playlist":
746 if len(self.playlist) == 0:
747 self.switchToFileList()
750 if self.filelist.getServiceRef().type == 4098: # playlist
751 ServiceRef = self.filelist.getServiceRef()
752 extension = ServiceRef.getPath()[ServiceRef.getPath().rfind('.') + 1:]
753 if self.playlistparsers.has_key(extension):
754 playlist = self.playlistparsers[extension]()
755 list = playlist.open(ServiceRef.getPath())
757 self.playlist.addFile(x.ref)
758 self.playlist.updateList()
760 self.playlist.addFile(self.filelist.getServiceRef())
761 self.playlist.updateList()
762 if len(self.playlist) == 1:
765 def addPlaylistParser(self, parser, extension):
766 self.playlistparsers[extension] = parser
769 next = self.playlist.getCurrentIndex() + 1
770 if next < len(self.playlist):
771 self.changeEntry(next)
772 elif ( len(self.playlist) > 0 ) and ( config.mediaplayer.repeat.getValue() == True ):
776 def nextMarkOrEntry(self):
777 if not self.jumpPreviousNextMark(lambda x: x):
778 next = self.playlist.getCurrentIndex() + 1
779 if next < len(self.playlist):
780 self.changeEntry(next)
784 def previousMarkOrEntry(self):
785 if not self.jumpPreviousNextMark(lambda x: -x-5*90000, start=True):
786 next = self.playlist.getCurrentIndex() - 1
788 self.changeEntry(next)
790 def deleteEntry(self):
791 self.playlist.deleteFile(self.playlist.getSelectionIndex())
792 self.playlist.updateList()
793 if len(self.playlist) == 0:
794 self.switchToFileList()
796 def changeEntry(self, index):
797 self.playlist.setCurrentPlaying(index)
800 def playServiceRefEntry(self, serviceref):
801 serviceRefList = self.playlist.getServiceRefList()
802 for count in range(len(serviceRefList)):
803 if serviceRefList[count] == serviceref:
804 self.changeEntry(count)
807 def xplayEntry(self):
808 if self.currList == "playlist":
812 self.playlist.clear()
813 self.isAudioCD = False
814 sel = self.filelist.getSelection()
816 if sel[1]: # can descent
817 # add directory to playlist
818 self.copyDirectory(sel[0])
820 # add files to playlist
821 self.copyDirectory(os_path.dirname(sel[0].getPath()) + "/", recursive = False)
822 if len(self.playlist) > 0:
826 if len(self.playlist.getServiceRefList()):
827 audio_extensions = (".mp2", ".mp3", ".wav", ".ogg", ".flac", ".m4a", ".dts")
828 needsInfoUpdate = False
829 currref = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()]
830 if self.session.nav.getCurrentlyPlayingServiceReference() is None or currref != self.session.nav.getCurrentlyPlayingServiceReference():
831 self.session.nav.playService(self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()])
832 info = eServiceCenter.getInstance().info(currref)
833 description = info and info.getInfoString(currref, iServiceInformation.sDescription) or ""
834 self["title"].setText(description)
835 # display just playing musik on LCD
836 idx = self.playlist.getCurrentIndex()
837 currref = self.playlist.getServiceRefList()[idx]
838 text = self.getIdentifier(currref)
842 nameext = os.path.splitext(text)
844 except: ext = text[-4:].lower()
846 # FIXME: the information if the service contains video (and we should hide our window) should com from the service instead
847 if ext not in audio_extensions and not self.isAudioCD:
850 needsInfoUpdate = True
851 self.summaries.setText(text,1)
853 # get the next two entries
855 if idx < len(self.playlist):
856 currref = self.playlist.getServiceRefList()[idx]
857 text = self.getIdentifier(currref)
858 self.summaries.setText(text,3)
860 self.summaries.setText(" ",3)
863 if idx < len(self.playlist):
864 currref = self.playlist.getServiceRefList()[idx]
865 text = self.getIdentifier(currref)
866 self.summaries.setText(text,4)
868 self.summaries.setText(" ",4)
870 idx = self.playlist.getCurrentIndex()
871 currref = self.playlist.getServiceRefList()[idx]
872 text = currref.getPath()
873 ext = text[-4:].lower()
874 if ext not in audio_extensions and not self.isAudioCD:
877 needsInfoUpdate = True
879 self.unPauseService()
880 if needsInfoUpdate == True:
881 path = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()].getPath()
882 self["coverArt"].updateCoverArt(path)
884 self["coverArt"].showDefaultCover()
885 self.readTitleInformation()
887 def updatedSeekState(self):
888 if self.seekstate == self.SEEK_STATE_PAUSE:
889 self.playlist.pauseFile()
890 elif self.seekstate == self.SEEK_STATE_PLAY:
891 self.playlist.playFile()
892 elif self.isStateForward(self.seekstate):
893 self.playlist.forwardFile()
894 elif self.isStateBackward(self.seekstate):
895 self.playlist.rewindFile()
897 def pauseEntry(self):
899 if self.seekstate == self.SEEK_STATE_PAUSE:
905 self.playlist.stopFile()
906 self.session.nav.playService(None)
907 self.updateMusicInformation(clear=True)
910 def unPauseService(self):
911 self.setSeekState(self.SEEK_STATE_PLAY)
913 def subtitleSelection(self):
914 from Screens.AudioSelection import SubtitleSelection
915 self.session.open(SubtitleSelection, self)
917 def hotplugCB(self, dev, media_state):
918 if dev == harddiskmanager.getCD():
919 if media_state == "1":
920 from Components.Scanner import scanDevice
921 devpath = harddiskmanager.getAutofsMountpoint(harddiskmanager.getCD())
922 self.cdAudioTrackFiles = []
923 res = scanDevice(devpath)
924 list = [ (r.description, r, res[r], self.session) for r in res ]
926 (desc, scanner, files, session) = list[0]
928 if file.mimetype == "audio/x-cda":
929 self.cdAudioTrackFiles.append(file.path)
931 self.cdAudioTrackFiles = []
933 self.clear_playlist()
935 class MediaPlayerLCDScreen(Screen):
937 """<screen name="MediaPlayerLCDScreen" position="0,0" size="132,64" id="1">
938 <widget name="text1" position="4,0" size="132,35" font="Regular;16"/>
939 <widget name="text3" position="4,36" size="132,14" font="Regular;10"/>
940 <widget name="text4" position="4,49" size="132,14" font="Regular;10"/>
942 """<screen name="MediaPlayerLCDScreen" position="0,0" size="96,64" id="2">
943 <widget name="text1" position="0,0" size="96,35" font="Regular;14"/>
944 <widget name="text3" position="0,36" size="96,14" font="Regular;10"/>
945 <widget name="text4" position="0,49" size="96,14" font="Regular;10"/>
948 def __init__(self, session, parent):
949 Screen.__init__(self, session)
950 self["text1"] = Label("Mediaplayer")
951 self["text3"] = Label("")
952 self["text4"] = Label("")
954 def setText(self, text, line):
956 if text[-4:] == ".mp3":
959 text = text + textleer*10
961 self["text1"].setText(text)
963 self["text3"].setText(text)
965 self["text4"].setText(text)
967 def main(session, **kwargs):
968 session.open(MediaPlayer)
970 def menu(menuid, **kwargs):
971 if menuid == "mainmenu":
972 return [(_("Media player"), main, "media_player", 45)]
975 def filescan_open(list, session, **kwargs):
976 from enigma import eServiceReference
978 mp = session.open(MediaPlayer)
980 mp.savePlaylistOnExit = False
983 if file.mimetype == "video/MP2T":
987 ref = eServiceReference(stype, 0, file.path)
988 mp.playlist.addFile(ref)
991 mp.switchToPlayList()
993 def audioCD_open(list, session, **kwargs):
994 from enigma import eServiceReference
996 mp = session.open(MediaPlayer)
997 mp.cdAudioTrackFiles = []
999 mp.cdAudioTrackFiles.append(file.path)
1002 def filescan(**kwargs):
1003 from Components.Scanner import Scanner, ScanPath
1005 Scanner(mimetypes = ["video/mpeg", "video/MP2T", "video/x-msvideo"],
1008 ScanPath(path = "", with_subdirs = False),
1011 description = _("View Movies..."),
1012 openfnc = filescan_open,
1014 Scanner(mimetypes = ["video/x-vcd"],
1017 ScanPath(path = "mpegav", with_subdirs = False),
1018 ScanPath(path = "MPEGAV", with_subdirs = False),
1021 description = _("View Video CD..."),
1022 openfnc = filescan_open,
1024 Scanner(mimetypes = ["audio/mpeg", "audio/x-wav", "application/ogg", "audio/x-flac"],
1027 ScanPath(path = "", with_subdirs = False),
1030 description = _("Play Music..."),
1031 openfnc = filescan_open,
1034 from Plugins.Extensions.CDInfo.plugin import Query
1036 Scanner(mimetypes = ["audio/x-cda"],
1039 ScanPath(path = "", with_subdirs = False),
1042 description = _("Play Audio-CD..."),
1043 openfnc = audioCD_open,
1049 from Plugins.Plugin import PluginDescriptor
1050 def Plugins(**kwargs):
1052 PluginDescriptor(name = "MediaPlayer", description = "Play back media files", where = PluginDescriptor.WHERE_MENU, needsRestart = False, fnc = menu),
1053 PluginDescriptor(name = "MediaPlayer", where = PluginDescriptor.WHERE_FILESCAN, needsRestart = False, fnc = filescan)