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)", 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.AudioSelection import SubtitleSelection
912 self.session.open(SubtitleSelection, 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 name="MediaPlayerLCDScreen" position="0,0" size="132,64" id="1">
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"/>
939 """<screen name="MediaPlayerLCDScreen" position="0,0" size="96,64" id="2">
940 <widget name="text1" position="0,0" size="96,35" font="Regular;14"/>
941 <widget name="text3" position="0,36" size="96,14" font="Regular;10"/>
942 <widget name="text4" position="0,49" size="96,14" font="Regular;10"/>
945 def __init__(self, session, parent):
946 Screen.__init__(self, session)
947 self["text1"] = Label("Mediaplayer")
948 self["text3"] = Label("")
949 self["text4"] = Label("")
951 def setText(self, text, line):
953 if text[-4:] == ".mp3":
956 text = text + textleer*10
958 self["text1"].setText(text)
960 self["text3"].setText(text)
962 self["text4"].setText(text)
964 def main(session, **kwargs):
965 session.open(MediaPlayer)
967 def menu(menuid, **kwargs):
968 if menuid == "mainmenu":
969 return [(_("Media player"), main, "media_player", 45)]
972 def filescan_open(list, session, **kwargs):
973 from enigma import eServiceReference
975 mp = session.open(MediaPlayer)
977 mp.savePlaylistOnExit = False
980 if file.mimetype == "video/MP2T":
984 ref = eServiceReference(stype, 0, file.path)
985 mp.playlist.addFile(ref)
988 mp.switchToPlayList()
990 def audioCD_open(list, session, **kwargs):
991 from enigma import eServiceReference
993 mp = session.open(MediaPlayer)
994 mp.cdAudioTrackFiles = []
996 mp.cdAudioTrackFiles.append(file.path)
999 def filescan(**kwargs):
1000 from Components.Scanner import Scanner, ScanPath
1002 Scanner(mimetypes = ["video/mpeg", "video/MP2T", "video/x-msvideo"],
1005 ScanPath(path = "", with_subdirs = False),
1008 description = _("View Movies..."),
1009 openfnc = filescan_open,
1011 Scanner(mimetypes = ["video/x-vcd"],
1014 ScanPath(path = "mpegav", with_subdirs = False),
1015 ScanPath(path = "MPEGAV", with_subdirs = False),
1018 description = _("View Video CD..."),
1019 openfnc = filescan_open,
1021 Scanner(mimetypes = ["audio/mpeg", "audio/x-wav", "application/ogg", "audio/x-flac"],
1024 ScanPath(path = "", with_subdirs = False),
1027 description = _("Play Music..."),
1028 openfnc = filescan_open,
1031 from Plugins.Extensions.CDInfo.plugin import Query
1033 Scanner(mimetypes = ["audio/x-cda"],
1036 ScanPath(path = "", with_subdirs = False),
1039 description = _("Play Audio-CD..."),
1040 openfnc = audioCD_open,
1046 from Plugins.Plugin import PluginDescriptor
1047 def Plugins(**kwargs):
1049 PluginDescriptor(name = "MediaPlayer", description = "Play back media files", where = PluginDescriptor.WHERE_MENU, needsRestart = False, fnc = menu),
1050 PluginDescriptor(name = "MediaPlayer", where = PluginDescriptor.WHERE_FILESCAN, needsRestart = False, fnc = filescan)