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)", 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
141 # from Plugins.SystemPlugins.Hotplug.plugin import hotplugNotifier
142 # hotplugNotifier.append(self.hotplugCB)
144 class MoviePlayerActionMap(NumberActionMap):
145 def __init__(self, player, contexts = [ ], actions = { }, prio=0):
146 NumberActionMap.__init__(self, contexts, actions, prio)
149 def action(self, contexts, action):
151 return NumberActionMap.action(self, contexts, action)
153 self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions",
155 "ok": (self.ok, _("add file to playlist")),
156 "cancel": (self.exit, _("exit mediaplayer")),
159 self["MediaPlayerActions"] = HelpableActionMap(self, "MediaPlayerActions",
161 "play": (self.xplayEntry, _("play entry")),
162 "pause": (self.pauseEntry, _("pause")),
163 "stop": (self.stopEntry, _("stop entry")),
164 "previous": (self.previousMarkOrEntry, _("play from previous mark or playlist entry")),
165 "next": (self.nextMarkOrEntry, _("play from next mark or playlist entry")),
166 "menu": (self.showMenu, _("menu")),
167 "skipListbegin": (self.skip_listbegin, _("jump to listbegin")),
168 "skipListend": (self.skip_listend, _("jump to listend")),
169 "prevBouquet": (self.switchToPlayList, _("switch to playlist")),
170 "nextBouquet": (self.switchToFileList, _("switch to filelist")),
171 "delete": (self.deletePlaylistEntry, _("delete playlist entry")),
173 # "shift_stop": (self.clear_playlist, _("clear playlist")),
174 # "shift_record": (self.playlist.PlayListShuffle, _("shuffle playlist")),
175 "shift_stop": self.clear_playlist,
176 "shift_record": self.playlist.PlayListShuffle,
177 "subtitles": (self.subtitleSelection, _("Subtitle selection")),
180 self["InfobarEPGActions"] = HelpableActionMap(self, "InfobarEPGActions",
182 "showEventInfo": (self.showEventInformation, _("show event details")),
185 self["actions"] = MoviePlayerActionMap(self, ["DirectionActions"],
187 "right": self.rightDown,
188 "rightRepeated": self.doNothing,
189 "rightUp": self.rightUp,
190 "left": self.leftDown,
191 "leftRepeated": self.doNothing,
192 "leftUp": self.leftUp,
195 "upRepeated": self.up,
196 "upUp": self.doNothing,
198 "downRepeated": self.down,
199 "downUp": self.doNothing,
202 InfoBarSeek.__init__(self, actionmap = "MediaPlayerSeekActions")
204 self.onClose.append(self.delMPTimer)
205 self.onClose.append(self.__onClose)
207 self.righttimer = False
208 self.rightKeyTimer = eTimer()
209 self.rightKeyTimer.callback.append(self.rightTimerFire)
211 self.lefttimer = False
212 self.leftKeyTimer = eTimer()
213 self.leftKeyTimer.callback.append(self.leftTimerFire)
215 self.currList = "filelist"
216 self.isAudioCD = False
217 self.AudioCD_albuminfo = {}
218 self.cdAudioTrackFiles = []
219 self.onShown.append(self.applySettings)
221 self.playlistIOInternal = PlaylistIOInternal()
222 list = self.playlistIOInternal.open(resolveFilename(SCOPE_CONFIG, "playlist.e2pls"))
225 self.playlist.addFile(x.ref)
226 self.playlist.updateList()
228 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
230 iPlayableService.evUpdatedInfo: self.__evUpdatedInfo,
231 iPlayableService.evUser+10: self.__evAudioDecodeError,
232 iPlayableService.evUser+11: self.__evVideoDecodeError,
233 iPlayableService.evUser+12: self.__evPluginError,
234 iPlayableService.evUser+13: self["coverArt"].embeddedCoverArt
240 def createSummary(self):
241 return MediaPlayerLCDScreen
244 self.playlistIOInternal.clear()
245 for x in self.playlist.list:
246 self.playlistIOInternal.addService(ServiceReference(x[0]))
247 if self.savePlaylistOnExit:
249 self.playlistIOInternal.save(resolveFilename(SCOPE_CONFIG, "playlist.e2pls"))
251 print "couldn't save playlist.e2pls"
252 if config.mediaplayer.saveDirOnExit.getValue():
253 config.mediaplayer.defaultDir.setValue(self.filelist.getCurrentDirectory())
254 config.mediaplayer.defaultDir.save()
256 # from Plugins.SystemPlugins.Hotplug.plugin import hotplugNotifier
257 # hotplugNotifier.remove(self.hotplugCB)
258 del self["coverArt"].picload
261 def checkSkipShowHideLock(self):
262 self.updatedSeekState()
264 def doEofInternal(self, playing):
271 self.session.nav.playService(self.oldService)
273 def __evUpdatedInfo(self):
274 currPlay = self.session.nav.getCurrentService()
275 sTagTrackNumber = currPlay.info().getInfo(iServiceInformation.sTagTrackNumber)
276 sTagTrackCount = currPlay.info().getInfo(iServiceInformation.sTagTrackCount)
277 sTagTitle = currPlay.info().getInfoString(iServiceInformation.sTagTitle)
278 print "[__evUpdatedInfo] title %d of %d (%s)" % (sTagTrackNumber, sTagTrackCount, sTagTitle)
279 self.readTitleInformation()
281 def __evAudioDecodeError(self):
282 currPlay = self.session.nav.getCurrentService()
283 sTagAudioCodec = currPlay.info().getInfoString(iServiceInformation.sTagAudioCodec)
284 print "[__evAudioDecodeError] audio-codec %s can't be decoded by hardware" % (sTagAudioCodec)
285 self.session.open(MessageBox, _("This STB can't decode %s streams!") % sTagAudioCodec, type = MessageBox.TYPE_INFO,timeout = 20 )
287 def __evVideoDecodeError(self):
288 currPlay = self.session.nav.getCurrentService()
289 sTagVideoCodec = currPlay.info().getInfoString(iServiceInformation.sTagVideoCodec)
290 print "[__evVideoDecodeError] video-codec %s can't be decoded by hardware" % (sTagVideoCodec)
291 self.session.open(MessageBox, _("This STB can't decode %s streams!") % sTagVideoCodec, type = MessageBox.TYPE_INFO,timeout = 20 )
293 def __evPluginError(self):
294 currPlay = self.session.nav.getCurrentService()
295 message = currPlay.info().getInfoString(iServiceInformation.sUser+12)
296 print "[__evPluginError]" , message
297 self.session.open(MessageBox, message, type = MessageBox.TYPE_INFO,timeout = 20 )
299 def delMPTimer(self):
300 del self.rightKeyTimer
301 del self.leftKeyTimer
303 def readTitleInformation(self):
304 currPlay = self.session.nav.getCurrentService()
305 if currPlay is not None:
306 sTitle = currPlay.info().getInfoString(iServiceInformation.sTagTitle)
307 sAlbum = currPlay.info().getInfoString(iServiceInformation.sTagAlbum)
308 sGenre = currPlay.info().getInfoString(iServiceInformation.sTagGenre)
309 sArtist = currPlay.info().getInfoString(iServiceInformation.sTagArtist)
310 sYear = currPlay.info().getInfoString(iServiceInformation.sTagDate)
313 if not self.isAudioCD:
314 sTitle = currPlay.info().getName().split('/')[-1]
316 sTitle = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()].getName()
318 if self.AudioCD_albuminfo:
319 if sAlbum == "" and "title" in self.AudioCD_albuminfo:
320 sAlbum = self.AudioCD_albuminfo["title"]
321 if sGenre == "" and "genre" in self.AudioCD_albuminfo:
322 sGenre = self.AudioCD_albuminfo["genre"]
323 if sArtist == "" and "artist" in self.AudioCD_albuminfo:
324 sArtist = self.AudioCD_albuminfo["artist"]
325 if "year" in self.AudioCD_albuminfo:
326 sYear = self.AudioCD_albuminfo["year"]
328 self.updateMusicInformation( sArtist, sTitle, sAlbum, sYear, sGenre, clear = True )
330 self.updateMusicInformation()
332 def updateMusicInformation(self, artist = "", title = "", album = "", year = "", genre = "", clear = False):
333 self.updateSingleMusicInformation("artist", artist, clear)
334 self.updateSingleMusicInformation("title", title, clear)
335 self.updateSingleMusicInformation("album", album, clear)
336 self.updateSingleMusicInformation("year", year, clear)
337 self.updateSingleMusicInformation("genre", genre, clear)
339 def updateSingleMusicInformation(self, name, info, clear):
340 if info != "" or clear:
341 if self[name].getText() != info:
342 self[name].setText(info)
345 self.lefttimer = True
346 self.leftKeyTimer.start(1000)
349 self.righttimer = True
350 self.rightKeyTimer.start(1000)
354 self.leftKeyTimer.stop()
355 self.lefttimer = False
356 self[self.currList].pageUp()
357 self.updateCurrentInfo()
361 self.rightKeyTimer.stop()
362 self.righttimer = False
363 self[self.currList].pageDown()
364 self.updateCurrentInfo()
366 def leftTimerFire(self):
367 self.leftKeyTimer.stop()
368 self.lefttimer = False
369 self.switchToFileList()
371 def rightTimerFire(self):
372 self.rightKeyTimer.stop()
373 self.righttimer = False
374 self.switchToPlayList()
376 def switchToFileList(self):
377 self.currList = "filelist"
378 self.filelist.selectionEnabled(1)
379 self.playlist.selectionEnabled(0)
380 self.updateCurrentInfo()
382 def switchToPlayList(self):
383 if len(self.playlist) != 0:
384 self.currList = "playlist"
385 self.filelist.selectionEnabled(0)
386 self.playlist.selectionEnabled(1)
387 self.updateCurrentInfo()
390 self[self.currList].up()
391 self.updateCurrentInfo()
394 self[self.currList].down()
395 self.updateCurrentInfo()
397 def showAfterSeek(self):
400 def showAfterCuesheetOperation(self):
403 def hideAfterResume(self):
406 def getIdentifier(self, ref):
411 return text.split('/')[-1]
413 # FIXME: maybe this code can be optimized
414 def updateCurrentInfo(self):
416 if self.currList == "filelist":
417 idx = self.filelist.getSelectionIndex()
418 r = self.filelist.list[idx]
425 self.summaries.setText(text,1)
428 if idx < len(self.filelist.list):
429 r = self.filelist.list[idx]
433 self.summaries.setText(text,3)
435 self.summaries.setText(" ",3)
438 if idx < len(self.filelist.list):
439 r = self.filelist.list[idx]
443 self.summaries.setText(text,4)
445 self.summaries.setText(" ",4)
448 if not self.filelist.canDescent():
449 r = self.filelist.getServiceRef()
453 self["currenttext"].setText(os_path.basename(text))
455 if self.currList == "playlist":
456 t = self.playlist.getSelection()
459 #display current selected entry on LCD
460 text = self.getIdentifier(t)
461 self.summaries.setText(text,1)
462 self["currenttext"].setText(text)
463 idx = self.playlist.getSelectionIndex()
465 if idx < len(self.playlist):
466 currref = self.playlist.getServiceRefList()[idx]
467 text = self.getIdentifier(currref)
468 self.summaries.setText(text,3)
470 self.summaries.setText(" ",3)
473 if idx < len(self.playlist):
474 currref = self.playlist.getServiceRefList()[idx]
475 text = self.getIdentifier(currref)
476 self.summaries.setText(text,4)
478 self.summaries.setText(" ",4)
481 if self.currList == "filelist":
482 if self.filelist.canDescent():
483 self.filelist.descent()
484 self.updateCurrentInfo()
488 if self.currList == "playlist":
489 selection = self["playlist"].getSelection()
490 self.changeEntry(self.playlist.getSelectionIndex())
494 if len(self.cdAudioTrackFiles):
495 menu.insert(0,(_("Play Audio-CD..."), "audiocd"))
496 if self.currList == "filelist":
497 if self.filelist.canDescent():
498 menu.append((_("add directory to playlist"), "copydir"))
500 menu.append((_("add files to playlist"), "copyfiles"))
501 menu.append((_("switch to playlist"), "playlist"))
502 if config.usage.setup_level.index >= 1: # intermediate+
503 menu.append((_("delete file"), "deletefile"))
505 menu.append((_("switch to filelist"), "filelist"))
506 menu.append((_("clear playlist"), "clear"))
507 menu.append((_("Delete entry"), "deleteentry"))
508 if config.usage.setup_level.index >= 1: # intermediate+
509 menu.append((_("shuffle playlist"), "shuffle"))
510 menu.append((_("hide player"), "hide"));
511 menu.append((_("load playlist"), "loadplaylist"));
512 if config.usage.setup_level.index >= 1: # intermediate+
513 menu.append((_("save playlist"), "saveplaylist"));
514 menu.append((_("delete saved playlist"), "deleteplaylist"));
515 menu.append((_("Edit settings"), "settings"))
516 self.session.openWithCallback(self.menuCallback, ChoiceBox, title="", list=menu)
518 def menuCallback(self, choice):
522 if choice[1] == "copydir":
523 self.copyDirectory(self.filelist.getSelection()[0])
524 elif choice[1] == "copyfiles":
526 self.playlist.clear()
527 self.isAudioCD = False
528 self.copyDirectory(os_path.dirname(self.filelist.getSelection()[0].getPath()) + "/", recursive = False)
529 self.playServiceRefEntry(self.filelist.getServiceRef())
530 elif choice[1] == "playlist":
531 self.switchToPlayList()
532 elif choice[1] == "filelist":
533 self.switchToFileList()
534 elif choice[1] == "deleteentry":
535 if self.playlist.getSelectionIndex() == self.playlist.getCurrentIndex():
538 elif choice[1] == "clear":
539 self.clear_playlist()
540 elif choice[1] == "hide":
542 elif choice[1] == "saveplaylist":
544 elif choice[1] == "loadplaylist":
546 elif choice[1] == "deleteplaylist":
547 self.delete_saved_playlist()
548 elif choice[1] == "shuffle":
549 self.playlist.PlayListShuffle()
550 elif choice[1] == "deletefile":
552 elif choice[1] == "settings":
553 self.session.openWithCallback(self.applySettings, MediaPlayerSettings, self)
554 elif choice[1] == "audiocd":
557 def playAudioCD(self):
558 from enigma import eServiceReference
559 from Plugins.Extensions.CDInfo.plugin import Query
561 if len(self.cdAudioTrackFiles):
562 self.playlist.clear()
563 self.savePlaylistOnExit = False
564 self.isAudioCD = True
565 for file in self.cdAudioTrackFiles:
566 ref = eServiceReference(4097, 0, file)
567 self.playlist.addFile(ref)
571 self.switchToPlayList()
573 def applySettings(self):
574 self.savePlaylistOnExit = config.mediaplayer.savePlaylistOnExit.getValue()
575 if config.mediaplayer.repeat.getValue() == True:
576 self["repeat"].setPixmapNum(1)
578 self["repeat"].setPixmapNum(0)
580 def showEventInformation(self):
581 from Screens.EventView import EventViewSimple
582 from ServiceReference import ServiceReference
583 evt = self[self.currList].getCurrentEvent()
585 self.session.open(EventViewSimple, evt, ServiceReference(self.getCurrent()))
587 # also works on filelist (?)
588 def getCurrent(self):
589 return self["playlist"].getCurrent()
591 def deletePlaylistEntry(self):
592 if self.currList == "playlist":
593 if self.playlist.getSelectionIndex() == self.playlist.getCurrentIndex():
597 def skip_listbegin(self):
598 if self.currList == "filelist":
599 self.filelist.moveToIndex(0)
601 self.playlist.moveToIndex(0)
602 self.updateCurrentInfo()
604 def skip_listend(self):
605 if self.currList == "filelist":
606 idx = len(self.filelist.list)
607 self.filelist.moveToIndex(idx - 1)
609 self.playlist.moveToIndex(len(self.playlist)-1)
610 self.updateCurrentInfo()
612 def save_playlist(self):
613 self.session.openWithCallback(self.save_playlist2,InputBox, title=_("Please enter filename (empty = use current date)"),windowTitle = _("Save Playlist"))
615 def save_playlist2(self, name):
619 name = strftime("%y%m%d_%H%M%S")
621 self.playlistIOInternal.clear()
622 for x in self.playlist.list:
623 self.playlistIOInternal.addService(ServiceReference(x[0]))
624 self.playlistIOInternal.save(resolveFilename(SCOPE_PLAYLIST) + name)
626 def load_playlist(self):
628 playlistdir = resolveFilename(SCOPE_PLAYLIST)
630 for i in os_listdir(playlistdir):
631 listpath.append((i,playlistdir + i))
633 print "Error while scanning subdirs ",e
634 self.session.openWithCallback(self.PlaylistSelected, ChoiceBox, title=_("Please select a playlist..."), list = listpath)
636 def PlaylistSelected(self,path):
638 self.clear_playlist()
639 extension = path[0].rsplit('.',1)[-1]
640 if self.playlistparsers.has_key(extension):
641 playlist = self.playlistparsers[extension]()
642 list = playlist.open(path[1])
644 self.playlist.addFile(x.ref)
645 self.playlist.updateList()
647 def delete_saved_playlist(self):
649 playlistdir = resolveFilename(SCOPE_PLAYLIST)
651 for i in os_listdir(playlistdir):
652 listpath.append((i,playlistdir + i))
654 print "Error while scanning subdirs ",e
655 self.session.openWithCallback(self.DeletePlaylistSelected, ChoiceBox, title=_("Please select a playlist to delete..."), list = listpath)
657 def DeletePlaylistSelected(self,path):
659 self.delname = path[1]
660 self.session.openWithCallback(self.deleteConfirmed, MessageBox, _("Do you really want to delete %s?") % (path[1]))
662 def deleteConfirmed(self, confirmed):
665 os_remove(self.delname)
667 print "delete failed:", e
668 self.session.open(MessageBox, _("Delete failed!"), MessageBox.TYPE_ERROR)
670 def clear_playlist(self):
671 self.isAudioCD = False
673 self.playlist.clear()
674 self.switchToFileList()
676 def copyDirectory(self, directory, recursive = True):
677 print "copyDirectory", directory
679 print "refusing to operate on /"
681 filelist = FileList(directory, useServiceRef = True, showMountpoints = False, isTop = True)
683 for x in filelist.getFileList():
684 if x[0][1] == True: #isDir
686 if x[0][0] != directory:
687 self.copyDirectory(x[0][0])
688 elif filelist.getServiceRef() and filelist.getServiceRef().type == 4097:
689 self.playlist.addFile(x[0][0])
690 self.playlist.updateList()
692 def deleteFile(self):
693 if self.currList == "filelist":
694 self.service = self.filelist.getServiceRef()
696 self.service = self.playlist.getSelection()
697 if self.service is None:
699 if self.service.type != 4098 and self.session.nav.getCurrentlyPlayingServiceReference() is not None:
700 if self.service == self.session.nav.getCurrentlyPlayingServiceReference():
703 serviceHandler = eServiceCenter.getInstance()
704 offline = serviceHandler.offlineOperations(self.service)
705 info = serviceHandler.info(self.service)
706 name = info and info.getName(self.service)
708 if offline is not None:
710 if not offline.deleteFromDisk(1):
713 self.session.openWithCallback(self.deleteConfirmed_offline, MessageBox, _("Do you really want to delete %s?") % (name))
715 self.session.openWithCallback(self.close, MessageBox, _("You cannot delete this!"), MessageBox.TYPE_ERROR)
717 def deleteConfirmed_offline(self, confirmed):
719 serviceHandler = eServiceCenter.getInstance()
720 offline = serviceHandler.offlineOperations(self.service)
722 if offline is not None:
724 if not offline.deleteFromDisk(0):
727 self.session.open(MessageBox, _("Delete failed!"), MessageBox.TYPE_ERROR)
729 self.removeListEntry()
731 def removeListEntry(self):
732 currdir = self.filelist.getCurrentDirectory()
733 self.filelist.changeDir(currdir)
738 if len(self.playlist) > 0:
739 for x in self.playlist.list:
740 if self.service == x[0]:
741 self.playlist.deleteFile(index)
745 self.playlist.updateList()
746 if self.currList == "playlist":
747 if len(self.playlist) == 0:
748 self.switchToFileList()
751 if self.filelist.getServiceRef().type == 4098: # playlist
752 ServiceRef = self.filelist.getServiceRef()
753 extension = ServiceRef.getPath()[ServiceRef.getPath().rfind('.') + 1:]
754 if self.playlistparsers.has_key(extension):
755 playlist = self.playlistparsers[extension]()
756 list = playlist.open(ServiceRef.getPath())
758 self.playlist.addFile(x.ref)
759 self.playlist.updateList()
761 self.playlist.addFile(self.filelist.getServiceRef())
762 self.playlist.updateList()
763 if len(self.playlist) == 1:
766 def addPlaylistParser(self, parser, extension):
767 self.playlistparsers[extension] = parser
770 next = self.playlist.getCurrentIndex() + 1
771 if next < len(self.playlist):
772 self.changeEntry(next)
773 elif ( len(self.playlist) > 0 ) and ( config.mediaplayer.repeat.getValue() == True ):
777 def nextMarkOrEntry(self):
778 if not self.jumpPreviousNextMark(lambda x: x):
779 next = self.playlist.getCurrentIndex() + 1
780 if next < len(self.playlist):
781 self.changeEntry(next)
785 def previousMarkOrEntry(self):
786 if not self.jumpPreviousNextMark(lambda x: -x-5*90000, start=True):
787 next = self.playlist.getCurrentIndex() - 1
789 self.changeEntry(next)
791 def deleteEntry(self):
792 self.playlist.deleteFile(self.playlist.getSelectionIndex())
793 self.playlist.updateList()
794 if len(self.playlist) == 0:
795 self.switchToFileList()
797 def changeEntry(self, index):
798 self.playlist.setCurrentPlaying(index)
801 def playServiceRefEntry(self, serviceref):
802 serviceRefList = self.playlist.getServiceRefList()
803 for count in range(len(serviceRefList)):
804 if serviceRefList[count] == serviceref:
805 self.changeEntry(count)
808 def xplayEntry(self):
809 if self.currList == "playlist":
813 self.playlist.clear()
814 self.isAudioCD = False
815 sel = self.filelist.getSelection()
817 if sel[1]: # can descent
818 # add directory to playlist
819 self.copyDirectory(sel[0])
821 # add files to playlist
822 self.copyDirectory(os_path.dirname(sel[0].getPath()) + "/", recursive = False)
823 if len(self.playlist) > 0:
827 if len(self.playlist.getServiceRefList()):
828 audio_extensions = (".mp2", ".mp3", ".wav", ".ogg", "flac", "m4a")
829 needsInfoUpdate = False
830 currref = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()]
831 if self.session.nav.getCurrentlyPlayingServiceReference() is None or currref != self.session.nav.getCurrentlyPlayingServiceReference():
832 self.session.nav.playService(self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()])
833 info = eServiceCenter.getInstance().info(currref)
834 description = info and info.getInfoString(currref, iServiceInformation.sDescription) or ""
835 self["title"].setText(description)
836 # display just playing musik on LCD
837 idx = self.playlist.getCurrentIndex()
838 currref = self.playlist.getServiceRefList()[idx]
839 text = self.getIdentifier(currref)
841 ext = text[-4:].lower()
843 # FIXME: the information if the service contains video (and we should hide our window) should com from the service instead
844 if ext not in audio_extensions and not self.isAudioCD:
847 needsInfoUpdate = True
848 self.summaries.setText(text,1)
850 # get the next two entries
852 if idx < len(self.playlist):
853 currref = self.playlist.getServiceRefList()[idx]
854 text = self.getIdentifier(currref)
855 self.summaries.setText(text,3)
857 self.summaries.setText(" ",3)
860 if idx < len(self.playlist):
861 currref = self.playlist.getServiceRefList()[idx]
862 text = self.getIdentifier(currref)
863 self.summaries.setText(text,4)
865 self.summaries.setText(" ",4)
867 idx = self.playlist.getCurrentIndex()
868 currref = self.playlist.getServiceRefList()[idx]
869 text = currref.getPath()
870 ext = text[-4:].lower()
871 if ext not in audio_extensions and not self.isAudioCD:
874 needsInfoUpdate = True
876 self.unPauseService()
877 if needsInfoUpdate == True:
878 path = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()].getPath()
879 self["coverArt"].updateCoverArt(path)
881 self["coverArt"].showDefaultCover()
882 self.readTitleInformation()
884 def updatedSeekState(self):
885 if self.seekstate == self.SEEK_STATE_PAUSE:
886 self.playlist.pauseFile()
887 elif self.seekstate == self.SEEK_STATE_PLAY:
888 self.playlist.playFile()
889 elif self.isStateForward(self.seekstate):
890 self.playlist.forwardFile()
891 elif self.isStateBackward(self.seekstate):
892 self.playlist.rewindFile()
894 def pauseEntry(self):
896 if self.seekstate == self.SEEK_STATE_PAUSE:
902 self.playlist.stopFile()
903 self.session.nav.playService(None)
904 self.updateMusicInformation(clear=True)
907 def unPauseService(self):
908 self.setSeekState(self.SEEK_STATE_PLAY)
910 def subtitleSelection(self):
911 from Screens.Subtitles import Subtitles
912 self.session.open(Subtitles, self)
914 def hotplugCB(self, dev, media_state):
915 if dev == harddiskmanager.getCD():
916 if media_state == "1":
917 from Components.Scanner import scanDevice
918 devpath = harddiskmanager.getAutofsMountpoint(harddiskmanager.getCD())
919 self.cdAudioTrackFiles = []
920 res = scanDevice(devpath)
921 list = [ (r.description, r, res[r], self.session) for r in res ]
923 (desc, scanner, files, session) = list[0]
925 if file.mimetype == "audio/x-cda":
926 self.cdAudioTrackFiles.append(file.path)
928 self.cdAudioTrackFiles = []
930 self.clear_playlist()
932 class MediaPlayerLCDScreen(Screen):
934 <screen position="0,0" size="132,64" title="LCD Text">
935 <widget name="text1" position="4,0" size="132,35" font="Regular;16"/>
936 <widget name="text3" position="4,36" size="132,14" font="Regular;10"/>
937 <widget name="text4" position="4,49" size="132,14" font="Regular;10"/>
940 def __init__(self, session, parent):
941 Screen.__init__(self, session)
942 self["text1"] = Label("Mediaplayer")
943 self["text3"] = Label("")
944 self["text4"] = Label("")
946 def setText(self, text, line):
948 if text[-4:] == ".mp3":
951 text = text + textleer*10
953 self["text1"].setText(text)
955 self["text3"].setText(text)
957 self["text4"].setText(text)
959 def main(session, **kwargs):
960 session.open(MediaPlayer)
962 def menu(menuid, **kwargs):
963 if menuid == "mainmenu":
964 return [(_("Media player"), main, "media_player", 45)]
967 def filescan_open(list, session, **kwargs):
968 from enigma import eServiceReference
970 mp = session.open(MediaPlayer)
972 mp.savePlaylistOnExit = False
975 if file.mimetype == "video/MP2T":
979 ref = eServiceReference(stype, 0, file.path)
980 mp.playlist.addFile(ref)
983 mp.switchToPlayList()
985 def audioCD_open(list, session, **kwargs):
986 from enigma import eServiceReference
988 mp = session.open(MediaPlayer)
989 mp.cdAudioTrackFiles = []
991 mp.cdAudioTrackFiles.append(file.path)
994 def filescan(**kwargs):
995 from Components.Scanner import Scanner, ScanPath
997 Scanner(mimetypes = ["video/mpeg", "video/MP2T", "video/x-msvideo"],
1000 ScanPath(path = "", with_subdirs = False),
1003 description = _("View Movies..."),
1004 openfnc = filescan_open,
1006 Scanner(mimetypes = ["video/x-vcd"],
1009 ScanPath(path = "mpegav", with_subdirs = False),
1010 ScanPath(path = "MPEGAV", with_subdirs = False),
1013 description = _("View Video CD..."),
1014 openfnc = filescan_open,
1016 Scanner(mimetypes = ["audio/mpeg", "audio/x-wav", "application/ogg", "audio/x-flac"],
1019 ScanPath(path = "", with_subdirs = False),
1022 description = _("Play Music..."),
1023 openfnc = filescan_open,
1026 from Plugins.Extensions.CDInfo.plugin import Query
1028 Scanner(mimetypes = ["audio/x-cda"],
1031 ScanPath(path = "", with_subdirs = False),
1034 description = _("Play Audio-CD..."),
1035 openfnc = audioCD_open,
1041 from Plugins.Plugin import PluginDescriptor
1042 def Plugins(**kwargs):
1044 PluginDescriptor(name = "MediaPlayer", description = "Play back media files", where = PluginDescriptor.WHERE_MENU, fnc = menu),
1045 PluginDescriptor(name = "MediaPlayer", where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan)