Revert "disable m2ts support for release 2.6"
[enigma2.git] / lib / python / Plugins / Extensions / MediaPlayer / plugin.py
index 3736898e6050e1e58c449d345413c9a00dcb8477..596f2d5abd8e9dd7e45d30ff0e5bb583ad086043 100644 (file)
@@ -1,23 +1,26 @@
-from os import path as os_path, remove as os_remove, listdir as os_listdir, popen
+from os import path as os_path, remove as os_remove, listdir as os_listdir
 from time import strftime
 from time import strftime
-from enigma import iPlayableService, eTimer, eServiceCenter, iServiceInformation
+from enigma import iPlayableService, eTimer, eServiceCenter, iServiceInformation, ePicLoad
+from ServiceReference import ServiceReference
 from Screens.Screen import Screen
 from Screens.Screen import Screen
+from Screens.HelpMenu import HelpableScreen
 from Screens.MessageBox import MessageBox
 from Screens.InputBox import InputBox
 from Screens.MessageBox import MessageBox
 from Screens.InputBox import InputBox
+from Screens.ChoiceBox import ChoiceBox
+from Screens.InfoBarGenerics import InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSupport, InfoBarNotifications, InfoBarSubtitleSupport
 from Components.ActionMap import NumberActionMap, HelpableActionMap
 from Components.Label import Label
 from Components.Pixmap import Pixmap,MultiPixmap
 from Components.ActionMap import NumberActionMap, HelpableActionMap
 from Components.Label import Label
 from Components.Pixmap import Pixmap,MultiPixmap
-from Components.Label import Label
 from Components.FileList import FileList
 from Components.MediaPlayer import PlayList
 from Components.FileList import FileList
 from Components.MediaPlayer import PlayList
-from Tools.Directories import resolveFilename, SCOPE_CONFIG, SCOPE_PLAYLIST, SCOPE_SKIN_IMAGE
 from Components.ServicePosition import ServicePositionGauge
 from Components.ServiceEventTracker import ServiceEventTracker, InfoBarBase
 from Components.Playlist import PlaylistIOInternal, PlaylistIOM3U, PlaylistIOPLS
 from Components.ServicePosition import ServicePositionGauge
 from Components.ServiceEventTracker import ServiceEventTracker, InfoBarBase
 from Components.Playlist import PlaylistIOInternal, PlaylistIOM3U, PlaylistIOPLS
-from Screens.InfoBarGenerics import InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSupport, InfoBarNotifications
-from ServiceReference import ServiceReference
-from Screens.ChoiceBox import ChoiceBox
-from Screens.HelpMenu import HelpableScreen
+from Components.AVSwitch import AVSwitch
+from Components.Harddisk import harddiskmanager
+from Components.config import config
+from Tools.Directories import fileExists, pathExists, resolveFilename, SCOPE_CONFIG, SCOPE_PLAYLIST, SCOPE_SKIN_IMAGE
+from settings import MediaPlayerSettings
 import random
 
 class MyPlayList(PlayList):
 import random
 
 class MyPlayList(PlayList):
@@ -31,18 +34,60 @@ class MyPlayList(PlayList):
                self.oldCurrPlaying = -1
 
 class MediaPixmap(Pixmap):
                self.oldCurrPlaying = -1
 
 class MediaPixmap(Pixmap):
+       def __init__(self):
+               Pixmap.__init__(self)
+               self.coverArtFileName = ""
+               self.picload = ePicLoad()
+               self.picload.PictureData.get().append(self.paintCoverArtPixmapCB)
+               self.coverFileNames = ["folder.png", "folder.jpg"]
+
        def applySkin(self, desktop, screen):
        def applySkin(self, desktop, screen):
-               self.default_pixmap = None
+               from Tools.LoadPixmap import LoadPixmap
+               noCoverFile = None
                if self.skinAttributes is not None:
                        for (attrib, value) in self.skinAttributes:
                                if attrib == "pixmap":
                if self.skinAttributes is not None:
                        for (attrib, value) in self.skinAttributes:
                                if attrib == "pixmap":
-                                       self.default_pixmap = value
+                                       noCoverFile = value
                                        break
                                        break
-               if self.default_pixmap is None:
-                       self.default_pixmap = resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/no_coverArt.png")
+               if noCoverFile is None:
+                       noCoverFile = resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/no_coverArt.png")
+               self.noCoverPixmap = LoadPixmap(noCoverFile)
                return Pixmap.applySkin(self, desktop, screen)
 
                return Pixmap.applySkin(self, desktop, screen)
 
-class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSupport, InfoBarNotifications, HelpableScreen):
+       def onShow(self):
+               Pixmap.onShow(self)
+               sc = AVSwitch().getFramebufferScale()
+               #0=Width 1=Height 2=Aspect 3=use_cache 4=resize_type 5=Background(#AARRGGBB)
+               self.picload.setPara((self.instance.size().width(), self.instance.size().height(), sc[0], sc[1], False, 1, "#00000000"))
+
+       def paintCoverArtPixmapCB(self, picInfo=None):
+               ptr = self.picload.getData()
+               if ptr != None:
+                       self.instance.setPixmap(ptr.__deref__())
+
+       def updateCoverArt(self, path):
+               while not path.endswith("/"):
+                       path = path[:-1]
+               new_coverArtFileName = None
+               for filename in self.coverFileNames:
+                       if fileExists(path + filename):
+                               new_coverArtFileName = path + filename
+               if self.coverArtFileName != new_coverArtFileName:
+                       self.coverArtFileName = new_coverArtFileName
+                       if new_coverArtFileName:
+                               self.picload.startDecode(self.coverArtFileName)
+                       else:
+                               self.showDefaultCover()
+
+       def showDefaultCover(self):
+               self.instance.setPixmap(self.noCoverPixmap)
+
+       def embeddedCoverArt(self):
+               print "[embeddedCoverArt] found"
+               self.coverArtFileName = "/tmp/.id3coverart"
+               self.picload.startDecode(self.coverArtFileName)
+
+class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSupport, InfoBarNotifications, InfoBarSubtitleSupport, HelpableScreen):
        ALLOW_SUSPEND = True
        ENABLE_RESUME_SUPPORT = True
 
        ALLOW_SUSPEND = True
        ENABLE_RESUME_SUPPORT = True
 
@@ -52,6 +97,7 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
                InfoBarCueSheetSupport.__init__(self, actionmap = "MediaPlayerCueSheetActions")
                InfoBarNotifications.__init__(self)
                InfoBarBase.__init__(self)
                InfoBarCueSheetSupport.__init__(self, actionmap = "MediaPlayerCueSheetActions")
                InfoBarNotifications.__init__(self)
                InfoBarBase.__init__(self)
+               InfoBarSubtitleSupport.__init__(self)
                HelpableScreen.__init__(self)
                self.summary = None
                self.oldService = self.session.nav.getCurrentlyPlayingServiceReference()
                HelpableScreen.__init__(self)
                self.summary = None
                self.oldService = self.session.nav.getCurrentlyPlayingServiceReference()
@@ -63,11 +109,11 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
                self.addPlaylistParser(PlaylistIOInternal, "e2pls")
 
                # 'None' is magic to start at the list of mountpoints
                self.addPlaylistParser(PlaylistIOInternal, "e2pls")
 
                # 'None' is magic to start at the list of mountpoints
-               self.filelist = FileList(None, matchingPattern = "(?i)^.*\.(mp3|ogg|ts|wav|wave|m3u|pls|e2pls|mpg|vob|avi)", useServiceRef = True, additionalExtensions = "4098:m3u 4098:e2pls 4098:pls")
+               defaultDir = config.mediaplayer.defaultDir.getValue()
+               self.filelist = FileList(defaultDir, matchingPattern = "(?i)^.*\.(mp2|mp3|ogg|ts|m2ts|wav|wave|m3u|pls|e2pls|mpg|vob|avi|divx|mkv|mp4|m4a|dat|flac|mov)", useServiceRef = True, additionalExtensions = "4098:m3u 4098:e2pls 4098:pls")
                self["filelist"] = self.filelist
 
                self.playlist = MyPlayList()
                self["filelist"] = self.filelist
 
                self.playlist = MyPlayList()
-               #self.playlist = PlayList()
                self.is_closing = False
                self.delname = ""
                self["playlist"] = self.playlist
                self.is_closing = False
                self.delname = ""
                self["playlist"] = self.playlist
@@ -76,22 +122,24 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
 
                self["currenttext"] = Label("")
 
 
                self["currenttext"] = Label("")
 
-               self["artisttext"] = Label(_("Artist:"))
+               self["artisttext"] = Label(_("Artist")+':')
                self["artist"] = Label("")
                self["artist"] = Label("")
-               self["titletext"] = Label(_("Title:"))
+               self["titletext"] = Label(_("Title")+':')
                self["title"] = Label("")
                self["title"] = Label("")
-               self["albumtext"] = Label(_("Album:"))
+               self["albumtext"] = Label(_("Album")+':')
                self["album"] = Label("")
                self["album"] = Label("")
-               self["yeartext"] = Label(_("Year:"))
+               self["yeartext"] = Label(_("Year")+':')
                self["year"] = Label("")
                self["year"] = Label("")
-               self["genretext"] = Label(_("Genre:"))
+               self["genretext"] = Label(_("Genre")+':')
                self["genre"] = Label("")
                self["coverArt"] = MediaPixmap()
                self["repeat"] = MultiPixmap()
 
                self["genre"] = Label("")
                self["coverArt"] = MediaPixmap()
                self["repeat"] = MultiPixmap()
 
-               self.repeat = False
                self.seek_target = None
 
                self.seek_target = None
 
+               from Plugins.SystemPlugins.Hotplug.plugin import hotplugNotifier
+               hotplugNotifier.append(self.hotplugCB)
+
                class MoviePlayerActionMap(NumberActionMap):
                        def __init__(self, player, contexts = [ ], actions = { }, prio=0):
                                NumberActionMap.__init__(self, contexts, actions, prio)
                class MoviePlayerActionMap(NumberActionMap):
                        def __init__(self, player, contexts = [ ], actions = { }, prio=0):
                                NumberActionMap.__init__(self, contexts, actions, prio)
@@ -101,7 +149,6 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
                                self.player.show()
                                return NumberActionMap.action(self, contexts, action)
 
                                self.player.show()
                                return NumberActionMap.action(self, contexts, action)
 
-
                self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions", 
                        {
                                "ok": (self.ok, _("add file to playlist")),
                self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions", 
                        {
                                "ok": (self.ok, _("add file to playlist")),
@@ -123,6 +170,7 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
                                "delete": (self.deletePlaylistEntry, _("delete playlist entry")),
                                "shift_stop": (self.clear_playlist, _("clear playlist")),
                                "shift_record": (self.playlist.PlayListShuffle, _("shuffle playlist")),
                                "delete": (self.deletePlaylistEntry, _("delete playlist entry")),
                                "shift_stop": (self.clear_playlist, _("clear playlist")),
                                "shift_record": (self.playlist.PlayListShuffle, _("shuffle playlist")),
+                               "subtitles": (self.subtitleSelection, _("Subtitle selection")),
                        }, -2)
 
                self["InfobarEPGActions"] = HelpableActionMap(self, "InfobarEPGActions", 
                        }, -2)
 
                self["InfobarEPGActions"] = HelpableActionMap(self, "InfobarEPGActions", 
@@ -161,11 +209,10 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
                self.leftKeyTimer.callback.append(self.leftTimerFire)
 
                self.currList = "filelist"
                self.leftKeyTimer.callback.append(self.leftTimerFire)
 
                self.currList = "filelist"
-
-               self.coverArtFileName = ""
                self.isAudioCD = False
                self.AudioCD_albuminfo = {}
                self.isAudioCD = False
                self.AudioCD_albuminfo = {}
-               self.savePlaylistOnExit = True
+               self.cdAudioTrackFiles = []
+               self.onShown.append(self.applySettings)
 
                self.playlistIOInternal = PlaylistIOInternal()
                list = self.playlistIOInternal.open(resolveFilename(SCOPE_CONFIG, "playlist.e2pls"))
 
                self.playlistIOInternal = PlaylistIOInternal()
                list = self.playlistIOInternal.open(resolveFilename(SCOPE_CONFIG, "playlist.e2pls"))
@@ -176,7 +223,11 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
 
                self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
                        {
 
                self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
                        {
-                               iPlayableService.evUpdatedInfo: self.__evUpdatedInfo
+                               iPlayableService.evUpdatedInfo: self.__evUpdatedInfo,
+                               iPlayableService.evUser+10: self.__evAudioDecodeError,
+                               iPlayableService.evUser+11: self.__evVideoDecodeError,
+                               iPlayableService.evUser+12: self.__evPluginError,
+                               iPlayableService.evUser+13: self["coverArt"].embeddedCoverArt
                        })
 
        def doNothing(self):
                        })
 
        def doNothing(self):
@@ -186,16 +237,21 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
                return MediaPlayerLCDScreen
 
        def exit(self):
                return MediaPlayerLCDScreen
 
        def exit(self):
-               self.session.openWithCallback(self.exitCB, MessageBox, _("Do you really want to exit?"), timeout=5)
-
-       def exitCB(self, answer):
-               if answer == True:
-                       self.playlistIOInternal.clear()
-                       for x in self.playlist.list:
-                               self.playlistIOInternal.addService(ServiceReference(x[0]))
-                       if self.savePlaylistOnExit:
+               self.playlistIOInternal.clear()
+               for x in self.playlist.list:
+                       self.playlistIOInternal.addService(ServiceReference(x[0]))
+               if self.savePlaylistOnExit:
+                       try:
                                self.playlistIOInternal.save(resolveFilename(SCOPE_CONFIG, "playlist.e2pls"))
                                self.playlistIOInternal.save(resolveFilename(SCOPE_CONFIG, "playlist.e2pls"))
-                       self.close()
+                       except IOError:
+                               print "couldn't save playlist.e2pls"
+               if config.mediaplayer.saveDirOnExit.getValue():
+                       config.mediaplayer.defaultDir.setValue(self.filelist.getCurrentDirectory())
+                       config.mediaplayer.defaultDir.save()
+               from Plugins.SystemPlugins.Hotplug.plugin import hotplugNotifier
+               hotplugNotifier.remove(self.hotplugCB)
+               del self["coverArt"].picload
+               self.close()
 
        def checkSkipShowHideLock(self):
                self.updatedSeekState()
 
        def checkSkipShowHideLock(self):
                self.updatedSeekState()
@@ -211,12 +267,30 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
 
        def __evUpdatedInfo(self):
                currPlay = self.session.nav.getCurrentService()
 
        def __evUpdatedInfo(self):
                currPlay = self.session.nav.getCurrentService()
-               currenttitle = currPlay.info().getInfo(iServiceInformation.sCurrentTitle)
-               totaltitles = currPlay.info().getInfo(iServiceInformation.sTotalTitles)
-               sTitle = currPlay.info().getInfoString(iServiceInformation.sTitle)
-               print "[__evUpdatedInfo] title %d of %d (%s)" % (currenttitle, totaltitles, sTitle)
+               sTagTrackNumber = currPlay.info().getInfo(iServiceInformation.sTagTrackNumber)
+               sTagTrackCount = currPlay.info().getInfo(iServiceInformation.sTagTrackCount)
+               sTagTitle = currPlay.info().getInfoString(iServiceInformation.sTagTitle)
+               print "[__evUpdatedInfo] title %d of %d (%s)" % (sTagTrackNumber, sTagTrackCount, sTagTitle)
                self.readTitleInformation()
 
                self.readTitleInformation()
 
+       def __evAudioDecodeError(self):
+               currPlay = self.session.nav.getCurrentService()
+               sTagAudioCodec = currPlay.info().getInfoString(iServiceInformation.sTagAudioCodec)
+               print "[__evAudioDecodeError] audio-codec %s can't be decoded by hardware" % (sTagAudioCodec)
+               self.session.open(MessageBox, _("This Dreambox can't decode %s streams!") % sTagAudioCodec, type = MessageBox.TYPE_INFO,timeout = 20 )
+
+       def __evVideoDecodeError(self):
+               currPlay = self.session.nav.getCurrentService()
+               sTagVideoCodec = currPlay.info().getInfoString(iServiceInformation.sTagVideoCodec)
+               print "[__evVideoDecodeError] video-codec %s can't be decoded by hardware" % (sTagVideoCodec)
+               self.session.open(MessageBox, _("This Dreambox can't decode %s streams!") % sTagVideoCodec, type = MessageBox.TYPE_INFO,timeout = 20 )
+
+       def __evPluginError(self):
+               currPlay = self.session.nav.getCurrentService()
+               message = currPlay.info().getInfoString(iServiceInformation.sUser+12)
+               print "[__evPluginError]" , message
+               self.session.open(MessageBox, message, type = MessageBox.TYPE_INFO,timeout = 20 )
+
        def delMPTimer(self):
                del self.rightKeyTimer
                del self.leftKeyTimer
        def delMPTimer(self):
                del self.rightKeyTimer
                del self.leftKeyTimer
@@ -224,11 +298,11 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
        def readTitleInformation(self):
                currPlay = self.session.nav.getCurrentService()
                if currPlay is not None:
        def readTitleInformation(self):
                currPlay = self.session.nav.getCurrentService()
                if currPlay is not None:
-                       sTitle = currPlay.info().getInfoString(iServiceInformation.sTitle)
-                       sAlbum = currPlay.info().getInfoString(iServiceInformation.sAlbum)
-                       sGenre = currPlay.info().getInfoString(iServiceInformation.sGenre)
-                       sArtist = currPlay.info().getInfoString(iServiceInformation.sArtist)
-                       sYear = ""
+                       sTitle = currPlay.info().getInfoString(iServiceInformation.sTagTitle)
+                       sAlbum = currPlay.info().getInfoString(iServiceInformation.sTagAlbum)
+                       sGenre = currPlay.info().getInfoString(iServiceInformation.sTagGenre)
+                       sArtist = currPlay.info().getInfoString(iServiceInformation.sTagArtist)
+                       sYear = currPlay.info().getInfoString(iServiceInformation.sTagDate)
 
                        if sTitle == "":
                                if not self.isAudioCD:
 
                        if sTitle == "":
                                if not self.isAudioCD:
@@ -262,17 +336,6 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
                        if self[name].getText() != info:
                                self[name].setText(info)
 
                        if self[name].getText() != info:
                                self[name].setText(info)
 
-       def updateCoverArtPixmap(self, path):
-               while not path.endswith("/"):
-                       path = path[:-1]
-               pngname = path + "folder.png"
-               
-               if not os_path.exists(pngname):
-                       pngname = self["coverArt"].default_pixmap
-               if self.coverArtFileName != pngname:
-                       self.coverArtFileName = pngname
-                       self["coverArt"].instance.setPixmapFromFile(self.coverArtFileName)
-
        def leftDown(self):
                self.lefttimer = True
                self.leftKeyTimer.start(1000)
        def leftDown(self):
                self.lefttimer = True
                self.leftKeyTimer.start(1000)
@@ -327,7 +390,7 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
                self.updateCurrentInfo()
 
        def showAfterSeek(self):
                self.updateCurrentInfo()
 
        def showAfterSeek(self):
-               self.show()
+               pass
 
        def showAfterCuesheetOperation(self):
                self.show()
 
        def showAfterCuesheetOperation(self):
                self.show()
@@ -423,24 +486,28 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
 
        def showMenu(self):
                menu = []
 
        def showMenu(self):
                menu = []
+               if len(self.cdAudioTrackFiles):
+                       menu.insert(0,(_("Play Audio-CD..."), "audiocd"))
                if self.currList == "filelist":
                        if self.filelist.canDescent():
                                menu.append((_("add directory to playlist"), "copydir"))
                        else:
                                menu.append((_("add files to playlist"), "copyfiles"))
                        menu.append((_("switch to playlist"), "playlist"))
                if self.currList == "filelist":
                        if self.filelist.canDescent():
                                menu.append((_("add directory to playlist"), "copydir"))
                        else:
                                menu.append((_("add files to playlist"), "copyfiles"))
                        menu.append((_("switch to playlist"), "playlist"))
+                       if config.usage.setup_level.index >= 1: # intermediate+
+                               menu.append((_("delete file"), "deletefile"))
                else:
                        menu.append((_("switch to filelist"), "filelist"))
                else:
                        menu.append((_("switch to filelist"), "filelist"))
-
-                       menu.append((_("shuffle playlist"), "shuffle"))
-
-                       menu.append((_("delete"), "delete"))
                        menu.append((_("clear playlist"), "clear"))
                        menu.append((_("clear playlist"), "clear"))
+                       menu.append((_("Delete entry"), "deleteentry"))
+                       if config.usage.setup_level.index >= 1: # intermediate+
+                               menu.append((_("shuffle playlist"), "shuffle"))
                menu.append((_("hide player"), "hide"));
                menu.append((_("hide player"), "hide"));
-               menu.append((_("save playlist"), "saveplaylist"));
                menu.append((_("load playlist"), "loadplaylist"));
                menu.append((_("load playlist"), "loadplaylist"));
-               menu.append((_("delete saved playlist"), "deleteplaylist"));
-               menu.append((_("repeat playlist"), "repeat"));
+               if config.usage.setup_level.index >= 1: # intermediate+
+                       menu.append((_("save playlist"), "saveplaylist"));
+                       menu.append((_("delete saved playlist"), "deleteplaylist"));
+                       menu.append((_("Edit settings"), "settings"))
                self.session.openWithCallback(self.menuCallback, ChoiceBox, title="", list=menu)
 
        def menuCallback(self, choice):
                self.session.openWithCallback(self.menuCallback, ChoiceBox, title="", list=menu)
 
        def menuCallback(self, choice):
@@ -452,20 +519,19 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
                elif choice[1] == "copyfiles":
                        self.stopEntry()
                        self.playlist.clear()
                elif choice[1] == "copyfiles":
                        self.stopEntry()
                        self.playlist.clear()
+                       self.isAudioCD = False
                        self.copyDirectory(os_path.dirname(self.filelist.getSelection()[0].getPath()) + "/", recursive = False)
                        self.playServiceRefEntry(self.filelist.getServiceRef())
                elif choice[1] == "playlist":
                        self.switchToPlayList()
                elif choice[1] == "filelist":
                        self.switchToFileList()
                        self.copyDirectory(os_path.dirname(self.filelist.getSelection()[0].getPath()) + "/", recursive = False)
                        self.playServiceRefEntry(self.filelist.getServiceRef())
                elif choice[1] == "playlist":
                        self.switchToPlayList()
                elif choice[1] == "filelist":
                        self.switchToFileList()
-               elif choice[1] == "delete":
+               elif choice[1] == "deleteentry":
                        if self.playlist.getSelectionIndex() == self.playlist.getCurrentIndex():
                                self.stopEntry()
                        self.deleteEntry()
                elif choice[1] == "clear":
                        if self.playlist.getSelectionIndex() == self.playlist.getCurrentIndex():
                                self.stopEntry()
                        self.deleteEntry()
                elif choice[1] == "clear":
-                       self.stopEntry()
-                       self.playlist.clear()
-                       self.switchToFileList()
+                       self.clear_playlist()
                elif choice[1] == "hide":
                        self.hide()
                elif choice[1] == "saveplaylist":
                elif choice[1] == "hide":
                        self.hide()
                elif choice[1] == "saveplaylist":
@@ -476,13 +542,35 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
                        self.delete_saved_playlist()
                elif choice[1] == "shuffle":
                        self.playlist.PlayListShuffle()
                        self.delete_saved_playlist()
                elif choice[1] == "shuffle":
                        self.playlist.PlayListShuffle()
-               elif choice[1] == "repeat":
-                       if self.repeat == True:
-                               self.repeat = False
-                               self["repeat"].setPixmapNum(0)
-                       else:
-                               self.repeat = True
-                               self["repeat"].setPixmapNum(1)
+               elif choice[1] == "deletefile":
+                       self.deleteFile()
+               elif choice[1] == "settings":
+                       self.session.openWithCallback(self.applySettings, MediaPlayerSettings, self)
+               elif choice[1] == "audiocd":
+                       self.playAudioCD()
+
+       def playAudioCD(self):
+               from enigma import eServiceReference
+               from Plugins.Extensions.CDInfo.plugin import Query
+
+               if len(self.cdAudioTrackFiles):
+                       self.playlist.clear()
+                       self.savePlaylistOnExit = False
+                       self.isAudioCD = True
+                       for file in self.cdAudioTrackFiles:
+                               ref = eServiceReference(4097, 0, file)
+                               self.playlist.addFile(ref)
+                       cdinfo = Query(self)
+                       cdinfo.scan()
+                       self.changeEntry(0)
+                       self.switchToPlayList()
+
+       def applySettings(self):
+               self.savePlaylistOnExit = config.mediaplayer.savePlaylistOnExit.getValue()
+               if config.mediaplayer.repeat.getValue() == True:
+                       self["repeat"].setPixmapNum(1)
+               else:
+                       self["repeat"].setPixmapNum(0)
 
        def showEventInformation(self):
                from Screens.EventView import EventViewSimple
 
        def showEventInformation(self):
                from Screens.EventView import EventViewSimple
@@ -543,12 +631,13 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
        def PlaylistSelected(self,path):
                if path is not None:
                        self.clear_playlist()
        def PlaylistSelected(self,path):
                if path is not None:
                        self.clear_playlist()
-                       self.playlistIOInternal = PlaylistIOInternal()
-                       list = self.playlistIOInternal.open(path[1])
-                       if list:
+                       extension = path[0].rsplit('.',1)[-1]
+                       if self.playlistparsers.has_key(extension):
+                               playlist = self.playlistparsers[extension]()
+                               list = playlist.open(path[1])
                                for x in list:
                                        self.playlist.addFile(x.ref)
                                for x in list:
                                        self.playlist.addFile(x.ref)
-                               self.playlist.updateList()
+                       self.playlist.updateList()
 
        def delete_saved_playlist(self):
                listpath = []
 
        def delete_saved_playlist(self):
                listpath = []
@@ -567,35 +656,102 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
 
        def deleteConfirmed(self, confirmed):
                if confirmed:
 
        def deleteConfirmed(self, confirmed):
                if confirmed:
-                       os_remove(self.delname)
+                       try:
+                               os_remove(self.delname)
+                       except OSError,e:
+                               print "delete failed:", e
+                               self.session.open(MessageBox, _("Delete failed!"), MessageBox.TYPE_ERROR)
 
        def clear_playlist(self):
 
        def clear_playlist(self):
+               self.isAudioCD = False
                self.stopEntry()
                self.playlist.clear()
                self.switchToFileList()
 
        def copyDirectory(self, directory, recursive = True):
                print "copyDirectory", directory
                self.stopEntry()
                self.playlist.clear()
                self.switchToFileList()
 
        def copyDirectory(self, directory, recursive = True):
                print "copyDirectory", directory
-               filelist = FileList(directory, useServiceRef = True, isTop = True)
+               if directory == '/':
+                       print "refusing to operate on /"
+                       return
+               filelist = FileList(directory, useServiceRef = True, showMountpoints = False, isTop = True)
 
                for x in filelist.getFileList():
                        if x[0][1] == True: #isDir
                                if recursive:
 
                for x in filelist.getFileList():
                        if x[0][1] == True: #isDir
                                if recursive:
-                                       self.copyDirectory(x[0][0])
-                       else:
+                                       if x[0][0] != directory:
+                                               self.copyDirectory(x[0][0])
+                       elif filelist.getServiceRef() and filelist.getServiceRef().type == 4097:
                                self.playlist.addFile(x[0][0])
                self.playlist.updateList()
 
                                self.playlist.addFile(x[0][0])
                self.playlist.updateList()
 
+       def deleteFile(self):
+               if self.currList == "filelist":
+                       self.service = self.filelist.getServiceRef()
+               else:
+                       self.service = self.playlist.getSelection()
+               if self.service is None:
+                       return
+               if self.service.type != 4098 and self.session.nav.getCurrentlyPlayingServiceReference() is not None:
+                       if self.service == self.session.nav.getCurrentlyPlayingServiceReference():
+                               self.stopEntry()
+
+               serviceHandler = eServiceCenter.getInstance()
+               offline = serviceHandler.offlineOperations(self.service)
+               info = serviceHandler.info(self.service)
+               name = info and info.getName(self.service)
+               result = False
+               if offline is not None:
+                       # simulate first
+                       if not offline.deleteFromDisk(1):
+                               result = True
+               if result == True:
+                       self.session.openWithCallback(self.deleteConfirmed_offline, MessageBox, _("Do you really want to delete %s?") % (name))
+               else:
+                       self.session.openWithCallback(self.close, MessageBox, _("You cannot delete this!"), MessageBox.TYPE_ERROR)      
+
+       def deleteConfirmed_offline(self, confirmed):
+               if confirmed:
+                       serviceHandler = eServiceCenter.getInstance()
+                       offline = serviceHandler.offlineOperations(self.service)
+                       result = False
+                       if offline is not None:
+                               # really delete!
+                               if not offline.deleteFromDisk(0):
+                                       result = True
+                       if result == False:
+                               self.session.open(MessageBox, _("Delete failed!"), MessageBox.TYPE_ERROR)
+                       else:
+                               self.removeListEntry()
+
+       def removeListEntry(self):
+               currdir = self.filelist.getCurrentDirectory()
+               self.filelist.changeDir(currdir)
+               deleteend = False
+               while not deleteend:
+                       index = 0
+                       deleteend = True
+                       if len(self.playlist) > 0:
+                               for x in self.playlist.list:
+                                       if self.service == x[0]:
+                                               self.playlist.deleteFile(index)
+                                               deleteend = False
+                                               break
+                                       index += 1
+               self.playlist.updateList()
+               if self.currList == "playlist":
+                       if len(self.playlist) == 0:
+                               self.switchToFileList()
+
        def copyFile(self):
                if self.filelist.getServiceRef().type == 4098: # playlist
                        ServiceRef = self.filelist.getServiceRef()
                        extension = ServiceRef.getPath()[ServiceRef.getPath().rfind('.') + 1:]
        def copyFile(self):
                if self.filelist.getServiceRef().type == 4098: # playlist
                        ServiceRef = self.filelist.getServiceRef()
                        extension = ServiceRef.getPath()[ServiceRef.getPath().rfind('.') + 1:]
-                       print "extension:", extension
                        if self.playlistparsers.has_key(extension):
                                playlist = self.playlistparsers[extension]()
                                list = playlist.open(ServiceRef.getPath())
                                for x in list:
                                        self.playlist.addFile(x.ref)
                        if self.playlistparsers.has_key(extension):
                                playlist = self.playlistparsers[extension]()
                                list = playlist.open(ServiceRef.getPath())
                                for x in list:
                                        self.playlist.addFile(x.ref)
+                       self.playlist.updateList()
                else:
                        self.playlist.addFile(self.filelist.getServiceRef())
                        self.playlist.updateList()
                else:
                        self.playlist.addFile(self.filelist.getServiceRef())
                        self.playlist.updateList()
@@ -609,7 +765,7 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
                next = self.playlist.getCurrentIndex() + 1
                if next < len(self.playlist):
                        self.changeEntry(next)
                next = self.playlist.getCurrentIndex() + 1
                if next < len(self.playlist):
                        self.changeEntry(next)
-               elif ( len(self.playlist) > 0 ) and ( self.repeat == True ):
+               elif ( len(self.playlist) > 0 ) and ( config.mediaplayer.repeat.getValue() == True ):
                        self.stopEntry()
                        self.changeEntry(0)
 
                        self.stopEntry()
                        self.changeEntry(0)
 
@@ -650,6 +806,7 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
                else:
                        self.stopEntry()
                        self.playlist.clear()
                else:
                        self.stopEntry()
                        self.playlist.clear()
+                       self.isAudioCD = False
                        sel = self.filelist.getSelection()
                        if sel:
                                if sel[1]: # can descent
                        sel = self.filelist.getSelection()
                        if sel:
                                if sel[1]: # can descent
@@ -663,6 +820,7 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
        
        def playEntry(self):
                if len(self.playlist.getServiceRefList()):
        
        def playEntry(self):
                if len(self.playlist.getServiceRefList()):
+                       audio_extensions = (".mp2", ".mp3", ".wav", ".ogg", "flac", "m4a")
                        needsInfoUpdate = False
                        currref = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()]
                        if self.session.nav.getCurrentlyPlayingServiceReference() is None or currref != self.session.nav.getCurrentlyPlayingServiceReference():
                        needsInfoUpdate = False
                        currref = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()]
                        if self.session.nav.getCurrentlyPlayingServiceReference() is None or currref != self.session.nav.getCurrentlyPlayingServiceReference():
@@ -675,10 +833,10 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
                                currref = self.playlist.getServiceRefList()[idx]
                                text = self.getIdentifier(currref)
                                text = ">"+text
                                currref = self.playlist.getServiceRefList()[idx]
                                text = self.getIdentifier(currref)
                                text = ">"+text
-                               ext = text[-3:].lower()
+                               ext = text[-4:].lower()
 
                                # FIXME: the information if the service contains video (and we should hide our window) should com from the service instead 
 
                                # FIXME: the information if the service contains video (and we should hide our window) should com from the service instead 
-                               if ext not in ["mp3", "wav", "ogg"] and not self.isAudioCD:
+                               if ext not in audio_extensions and not self.isAudioCD:
                                        self.hide()
                                else:
                                        needsInfoUpdate = True
                                        self.hide()
                                else:
                                        needsInfoUpdate = True
@@ -704,19 +862,18 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
                                idx = self.playlist.getCurrentIndex()
                                currref = self.playlist.getServiceRefList()[idx]
                                text = currref.getPath()
                                idx = self.playlist.getCurrentIndex()
                                currref = self.playlist.getServiceRefList()[idx]
                                text = currref.getPath()
-                               ext = text[-3:].lower()
-                               if ext not in ["mp3", "wav", "ogg"] and not self.isAudioCD:
+                               ext = text[-4:].lower()
+                               if ext not in audio_extensions and not self.isAudioCD:
                                        self.hide()
                                else:
                                        needsInfoUpdate = True
 
                        self.unPauseService()
                        if needsInfoUpdate == True:
                                        self.hide()
                                else:
                                        needsInfoUpdate = True
 
                        self.unPauseService()
                        if needsInfoUpdate == True:
-                               self.updateCoverArtPixmap(currref.getPath())
+                               path = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()].getPath()
+                               self["coverArt"].updateCoverArt(path)
                        else:
                        else:
-                               pngname = self["coverArt"].default_pixmap
-                               self.coverArtFileName = pngname
-                               self["coverArt"].instance.setPixmapFromFile(self.coverArtFileName)
+                               self["coverArt"].showDefaultCover()
                        self.readTitleInformation()
 
        def updatedSeekState(self):
                        self.readTitleInformation()
 
        def updatedSeekState(self):
@@ -731,7 +888,10 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
 
        def pauseEntry(self):
                self.pauseService()
 
        def pauseEntry(self):
                self.pauseService()
-               self.show()
+               if self.seekstate == self.SEEK_STATE_PAUSE:
+                       self.show()
+               else:
+                       self.hide()
 
        def stopEntry(self):
                self.playlist.stopFile()
 
        def stopEntry(self):
                self.playlist.stopFile()
@@ -741,6 +901,28 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
 
        def unPauseService(self):
                self.setSeekState(self.SEEK_STATE_PLAY)
 
        def unPauseService(self):
                self.setSeekState(self.SEEK_STATE_PLAY)
+               
+       def subtitleSelection(self):
+               from Screens.Subtitles import Subtitles
+               self.session.open(Subtitles, self)
+       
+       def hotplugCB(self, dev, media_state):
+               if dev == harddiskmanager.getCD():
+                       if media_state == "1":
+                               from Components.Scanner import scanDevice
+                               devpath = harddiskmanager.getAutofsMountpoint(harddiskmanager.getCD())
+                               self.cdAudioTrackFiles = []
+                               res = scanDevice(devpath)
+                               list = [ (r.description, r, res[r], self.session) for r in res ]
+                               if list:
+                                       (desc, scanner, files, session) = list[0]
+                                       for file in files:
+                                               if file.mimetype == "audio/x-cda":
+                                                       self.cdAudioTrackFiles.append(file.path)
+                       else:
+                               self.cdAudioTrackFiles = []
+                               if self.isAudioCD:
+                                       self.clear_playlist()
 
 class MediaPlayerLCDScreen(Screen):
        skin = """
 
 class MediaPlayerLCDScreen(Screen):
        skin = """
@@ -757,7 +939,6 @@ class MediaPlayerLCDScreen(Screen):
                self["text4"] = Label("")
 
        def setText(self, text, line):
                self["text4"] = Label("")
 
        def setText(self, text, line):
-               print "lcd set text:", text, line
                if len(text) > 10:
                        if text[-4:] == ".mp3":
                                text = text[:-4]
                if len(text) > 10:
                        if text[-4:] == ".mp3":
                                text = text[:-4]
@@ -786,7 +967,7 @@ def filescan_open(list, session, **kwargs):
        mp.savePlaylistOnExit = False
 
        for file in list:
        mp.savePlaylistOnExit = False
 
        for file in list:
-               if file.mimetype.startswith("video"):
+               if file.mimetype == "video/MP2T":
                        stype = 1
                else:
                        stype = 4097
                        stype = 1
                else:
                        stype = 4097
@@ -800,20 +981,10 @@ def audioCD_open(list, session, **kwargs):
        from enigma import eServiceReference
 
        mp = session.open(MediaPlayer)
        from enigma import eServiceReference
 
        mp = session.open(MediaPlayer)
-
-       mp.playlist.clear()
-       mp.savePlaylistOnExit = False
-       mp.isAudioCD = True
-
+       mp.cdAudioTrackFiles = []
        for file in list:
        for file in list:
-               ref = eServiceReference(4097, 0, file.path)
-               mp.playlist.addFile(ref)
-       from Plugins.Extensions.CDInfo.plugin import Query
-       cdinfo = Query(mp)
-       cdinfo.scan()
-
-       mp.changeEntry(0)
-       mp.switchToPlayList()
+               mp.cdAudioTrackFiles.append(file.path)
+       mp.playAudioCD()
 
 def filescan(**kwargs):
        from Components.Scanner import Scanner, ScanPath
 
 def filescan(**kwargs):
        from Components.Scanner import Scanner, ScanPath
@@ -824,27 +995,38 @@ def filescan(**kwargs):
                                        ScanPath(path = "", with_subdirs = False),
                                ],
                        name = "Movie",
                                        ScanPath(path = "", with_subdirs = False),
                                ],
                        name = "Movie",
-                       description = "View Movies...",
+                       description = _("View Movies..."),
+                       openfnc = filescan_open,
+               ),
+               Scanner(mimetypes = ["video/x-vcd"],
+                       paths_to_scan =
+                               [
+                                       ScanPath(path = "mpegav", with_subdirs = False),
+                                       ScanPath(path = "MPEGAV", with_subdirs = False),
+                               ],
+                       name = "Video CD",
+                       description = _("View Video CD..."),
                        openfnc = filescan_open,
                ),
                        openfnc = filescan_open,
                ),
-               Scanner(mimetypes = ["audio/mpeg", "audio/x-wav", "application/ogg"],
+               Scanner(mimetypes = ["audio/mpeg", "audio/x-wav", "application/ogg", "audio/x-flac"],
                        paths_to_scan =
                                [
                                        ScanPath(path = "", with_subdirs = False),
                                ],
                        name = "Music",
                        paths_to_scan =
                                [
                                        ScanPath(path = "", with_subdirs = False),
                                ],
                        name = "Music",
-                       description = "Play Music...",
+                       description = _("Play Music..."),
                        openfnc = filescan_open,
                )]
        try:
                from Plugins.Extensions.CDInfo.plugin import Query
                        openfnc = filescan_open,
                )]
        try:
                from Plugins.Extensions.CDInfo.plugin import Query
-               mediatypes.insert(0,Scanner(mimetypes = ["audio/x-cda", "audio/x-wav"],
+               mediatypes.append(
+               Scanner(mimetypes = ["audio/x-cda"],
                        paths_to_scan =
                                [
                                        ScanPath(path = "", with_subdirs = False),
                                ],
                        name = "Audio-CD",
                        paths_to_scan =
                                [
                                        ScanPath(path = "", with_subdirs = False),
                                ],
                        name = "Audio-CD",
-                       description = "Play Audio-CD...",
+                       description = _("Play Audio-CD..."),
                        openfnc = audioCD_open,
                ))
                return mediatypes
                        openfnc = audioCD_open,
                ))
                return mediatypes