mediaplayer: allow playback of flv files
[enigma2.git] / lib / python / Plugins / Extensions / MediaPlayer / plugin.py
index 841ad61468ae84649d22e7ed8096789263077fff..c69dd28eaa7c0eda63abfb08be2ee07e8526c89e 100644 (file)
@@ -1,25 +1,26 @@
 from os import path as os_path, remove as os_remove, listdir as os_listdir
 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.HelpMenu import HelpableScreen
 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.Label import Label
 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 Screens.InfoBarGenerics import InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSupport, InfoBarNotifications, InfoBarSubtitleSupport
-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 Tools.Directories import fileExists, pathExists
+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):
@@ -33,17 +34,59 @@ class MyPlayList(PlayList):
                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):
-               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":
-                                       self.default_pixmap = value
+                                       noCoverFile = value
                                        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)
 
+       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
@@ -66,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.filelist = FileList(None, matchingPattern = "(?i)^.*\.(mp2|mp3|ogg|ts|wav|wave|m3u|pls|e2pls|mpg|vob|avi|mkv|mp4|dat|flac)", useServiceRef = True, additionalExtensions = "4098:m3u 4098:e2pls 4098:pls")
+               defaultDir = config.mediaplayer.defaultDir.getValue()
+               self.filelist = FileList(defaultDir, matchingPattern = "(?i)^.*\.(mp2|mp3|ogg|ts|wav|wave|m3u|pls|e2pls|mpg|vob|avi|divx|mkv|mp4|m4a|dat|flac|mov|flv)", useServiceRef = True, additionalExtensions = "4098:m3u 4098:e2pls 4098:pls")
                self["filelist"] = self.filelist
 
                self.playlist = MyPlayList()
-               #self.playlist = PlayList()
                self.is_closing = False
                self.delname = ""
                self["playlist"] = self.playlist
@@ -79,22 +122,24 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
 
                self["currenttext"] = Label("")
 
-               self["artisttext"] = Label(_("Artist:"))
+               self["artisttext"] = Label(_("Artist")+':')
                self["artist"] = Label("")
-               self["titletext"] = Label(_("Title:"))
+               self["titletext"] = Label(_("Title")+':')
                self["title"] = Label("")
-               self["albumtext"] = Label(_("Album:"))
+               self["albumtext"] = Label(_("Album")+':')
                self["album"] = Label("")
-               self["yeartext"] = Label(_("Year:"))
+               self["yeartext"] = Label(_("Year")+':')
                self["year"] = Label("")
-               self["genretext"] = Label(_("Genre:"))
+               self["genretext"] = Label(_("Genre")+':')
                self["genre"] = Label("")
                self["coverArt"] = MediaPixmap()
                self["repeat"] = MultiPixmap()
 
-               self.repeat = False
                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)
@@ -104,7 +149,6 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
                                self.player.show()
                                return NumberActionMap.action(self, contexts, action)
 
-
                self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions", 
                        {
                                "ok": (self.ok, _("add file to playlist")),
@@ -165,11 +209,10 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
                self.leftKeyTimer.callback.append(self.leftTimerFire)
 
                self.currList = "filelist"
-
-               self.coverArtFileName = ""
                self.isAudioCD = False
                self.AudioCD_albuminfo = {}
-               self.savePlaylistOnExit = True
+               self.cdAudioTrackFiles = []
+               self.applySettings()
 
                self.playlistIOInternal = PlaylistIOInternal()
                list = self.playlistIOInternal.open(resolveFilename(SCOPE_CONFIG, "playlist.e2pls"))
@@ -181,8 +224,10 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
                self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
                        {
                                iPlayableService.evUpdatedInfo: self.__evUpdatedInfo,
-                               iPlayableService.evUser+11: self.__evDecodeError,
-                               iPlayableService.evUser+12: self.__evPluginError
+                               iPlayableService.evUser+10: self.__evAudioDecodeError,
+                               iPlayableService.evUser+11: self.__evVideoDecodeError,
+                               iPlayableService.evUser+12: self.__evPluginError,
+                               iPlayableService.evUser+13: self["coverArt"].embeddedCoverArt
                        })
 
        def doNothing(self):
@@ -192,16 +237,18 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
                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.save(resolveFilename(SCOPE_CONFIG, "playlist.e2pls"))
-                       self.close()
+               self.playlistIOInternal.clear()
+               for x in self.playlist.list:
+                       self.playlistIOInternal.addService(ServiceReference(x[0]))
+               if self.savePlaylistOnExit:
+                       self.playlistIOInternal.save(resolveFilename(SCOPE_CONFIG, "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()
@@ -217,17 +264,23 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
 
        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()
 
-       def __evDecodeError(self):
+       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()
-               sVideoType = currPlay.info().getInfoString(iServiceInformation.sVideoType)
-               print "[__evDecodeError] video-codec %s can't be decoded by hardware" % (sVideoType)
-               self.session.open(MessageBox, _("This Dreambox can't decode %s video streams!") % sVideoType, type = MessageBox.TYPE_INFO,timeout = 20 )
+               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()
@@ -242,11 +295,11 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
        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 = currPlay.info().getInfoString(iServiceInformation.sTimeCreate)
+                       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:
@@ -280,17 +333,6 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
                        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 fileExists(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)
@@ -345,7 +387,7 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
                self.updateCurrentInfo()
 
        def showAfterSeek(self):
-               self.show()
+               pass
 
        def showAfterCuesheetOperation(self):
                self.show()
@@ -441,27 +483,28 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
 
        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 config.usage.setup_level.index >= 1: # intermediate+
+                               menu.append((_("delete file"), "deletefile"))
                else:
                        menu.append((_("switch to filelist"), "filelist"))
-
-                       menu.append((_("shuffle playlist"), "shuffle"))
-
-                       menu.append((_("delete"), "delete"))
                        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((_("save playlist"), "saveplaylist"));
                menu.append((_("load playlist"), "loadplaylist"));
-               menu.append((_("delete saved playlist"), "deleteplaylist"));
-               menu.append((_("repeat playlist"), "repeat"));
-               drivepath = harddiskmanager.getAutofsMountpoint(harddiskmanager.getCD())
-               if pathExists(drivepath):
-                       menu.insert(0,(_("Play Audio-CD..."), "audiocd"))
+               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):
@@ -473,20 +516,19 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
                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()
-               elif choice[1] == "delete":
+               elif choice[1] == "deleteentry":
                        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":
@@ -497,24 +539,11 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
                        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":
-                       from Components.Scanner import scanDevice
-                       drivepath = harddiskmanager.getAutofsMountpoint(harddiskmanager.getCD())
-                       self.cdAudioTrackFiles = []
-                       res = scanDevice(drivepath)
-                       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)
                        self.playAudioCD()
 
        def playAudioCD(self):
@@ -533,6 +562,13 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
                        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
                from ServiceReference import ServiceReference
@@ -592,12 +628,13 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
        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)
-                               self.playlist.updateList()
+                       self.playlist.updateList()
 
        def delete_saved_playlist(self):
                listpath = []
@@ -616,35 +653,102 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
 
        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):
+               self.isAudioCD = False
                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:
-                                       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()
 
+       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:]
-                       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)
+                       self.playlist.updateList()
                else:
                        self.playlist.addFile(self.filelist.getServiceRef())
                        self.playlist.updateList()
@@ -658,7 +762,7 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
                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)
 
@@ -699,6 +803,7 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
                else:
                        self.stopEntry()
                        self.playlist.clear()
+                       self.isAudioCD = False
                        sel = self.filelist.getSelection()
                        if sel:
                                if sel[1]: # can descent
@@ -712,6 +817,7 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
        
        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():
@@ -727,7 +833,7 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
                                ext = text[-4:].lower()
 
                                # FIXME: the information if the service contains video (and we should hide our window) should com from the service instead 
-                               if ext not in [".mp2", ".mp3", ".wav", ".ogg", "flac"] and not self.isAudioCD:
+                               if ext not in audio_extensions and not self.isAudioCD:
                                        self.hide()
                                else:
                                        needsInfoUpdate = True
@@ -754,18 +860,17 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
                                currref = self.playlist.getServiceRefList()[idx]
                                text = currref.getPath()
                                ext = text[-4:].lower()
-                               if ext not in [".mp2", ".mp3", ".wav", ".ogg", "flac"] and not self.isAudioCD:
+                               if ext not in audio_extensions and not self.isAudioCD:
                                        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:
-                               pngname = self["coverArt"].default_pixmap
-                               self.coverArtFileName = pngname
-                               self["coverArt"].instance.setPixmapFromFile(self.coverArtFileName)
+                               self["coverArt"].showDefaultCover()
                        self.readTitleInformation()
 
        def updatedSeekState(self):
@@ -796,7 +901,25 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
                
        def subtitleSelection(self):
                from Screens.Subtitles import Subtitles
-               self.session.open(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 = """
@@ -813,7 +936,6 @@ class MediaPlayerLCDScreen(Screen):
                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]
@@ -870,7 +992,7 @@ def filescan(**kwargs):
                                        ScanPath(path = "", with_subdirs = False),
                                ],
                        name = "Movie",
-                       description = "View Movies...",
+                       description = _("View Movies..."),
                        openfnc = filescan_open,
                ),
                Scanner(mimetypes = ["video/x-vcd"],
@@ -880,7 +1002,7 @@ def filescan(**kwargs):
                                        ScanPath(path = "MPEGAV", with_subdirs = False),
                                ],
                        name = "Video CD",
-                       description = "View Video CD...",
+                       description = _("View Video CD..."),
                        openfnc = filescan_open,
                ),
                Scanner(mimetypes = ["audio/mpeg", "audio/x-wav", "application/ogg", "audio/x-flac"],
@@ -889,7 +1011,7 @@ def filescan(**kwargs):
                                        ScanPath(path = "", with_subdirs = False),
                                ],
                        name = "Music",
-                       description = "Play Music...",
+                       description = _("Play Music..."),
                        openfnc = filescan_open,
                )]
        try:
@@ -901,7 +1023,7 @@ def filescan(**kwargs):
                                        ScanPath(path = "", with_subdirs = False),
                                ],
                        name = "Audio-CD",
-                       description = "Play Audio-CD...",
+                       description = _("Play Audio-CD..."),
                        openfnc = audioCD_open,
                ))
                return mediatypes