change handling of non-mp2 hotplugged videos
[enigma2.git] / lib / python / Plugins / Extensions / MediaPlayer / plugin.py
index fa7f164303ca295b0592c09bd6b23c1e66652b4b..b0384eabd2e80ad0137f15534ae26c21c5545fb4 100644 (file)
@@ -1,18 +1,18 @@
-from os import path as os_path, remove as os_remove, listdir as os_listdir
+from os import path as os_path, remove as os_remove, listdir as os_listdir, popen
 from time import strftime
 from time import strftime
-from enigma import eTimer, iPlayableService, eServiceCenter, iServiceInformation
+from enigma import iPlayableService, eTimer, eServiceCenter, iServiceInformation
 from Screens.Screen import Screen
 from Screens.MessageBox import MessageBox
 from Screens.InputBox import InputBox
 from Components.ActionMap import NumberActionMap, HelpableActionMap
 from Components.Label import Label
 from Screens.Screen import Screen
 from Screens.MessageBox import MessageBox
 from Screens.InputBox import InputBox
 from Components.ActionMap import NumberActionMap, HelpableActionMap
 from Components.Label import Label
-from Components.Pixmap import Pixmap
+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.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
+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 Components.Playlist import PlaylistIOInternal, PlaylistIOM3U, PlaylistIOPLS
 from Screens.InfoBarGenerics import InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSupport, InfoBarNotifications
 from ServiceReference import ServiceReference
@@ -31,7 +31,7 @@ class MyPlayList(PlayList):
                self.oldCurrPlaying = -1
 
 class MediaPixmap(Pixmap):
                self.oldCurrPlaying = -1
 
 class MediaPixmap(Pixmap):
-       def applySkin(self, desktop):
+       def applySkin(self, desktop, screen):
                self.default_pixmap = None
                if self.skinAttributes is not None:
                        for (attrib, value) in self.skinAttributes:
                self.default_pixmap = None
                if self.skinAttributes is not None:
                        for (attrib, value) in self.skinAttributes:
@@ -39,10 +39,10 @@ class MediaPixmap(Pixmap):
                                        self.default_pixmap = value
                                        break
                if self.default_pixmap is None:
                                        self.default_pixmap = value
                                        break
                if self.default_pixmap is None:
-                       self.default_pixmap = resolveFilename(SCOPE_SKIN_IMAGE, "no_coverArt.png")
-               return Pixmap.applySkin(self, desktop)
+                       self.default_pixmap = resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/no_coverArt.png")
+               return Pixmap.applySkin(self, desktop, screen)
 
 
-class MediaPlayer(Screen, InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSupport, InfoBarNotifications, HelpableScreen):
+class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSupport, InfoBarNotifications, HelpableScreen):
        ALLOW_SUSPEND = True
        ENABLE_RESUME_SUPPORT = True
 
        ALLOW_SUSPEND = True
        ENABLE_RESUME_SUPPORT = True
 
@@ -51,6 +51,7 @@ class MediaPlayer(Screen, InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSup
                InfoBarAudioSelection.__init__(self)
                InfoBarCueSheetSupport.__init__(self, actionmap = "MediaPlayerCueSheetActions")
                InfoBarNotifications.__init__(self)
                InfoBarAudioSelection.__init__(self)
                InfoBarCueSheetSupport.__init__(self, actionmap = "MediaPlayerCueSheetActions")
                InfoBarNotifications.__init__(self)
+               InfoBarBase.__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()
@@ -62,7 +63,7 @@ class MediaPlayer(Screen, InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSup
                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)", useServiceRef = True)
+               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")
                self["filelist"] = self.filelist
 
                self.playlist = MyPlayList()
                self["filelist"] = self.filelist
 
                self.playlist = MyPlayList()
@@ -86,7 +87,9 @@ class MediaPlayer(Screen, InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSup
                self["genretext"] = Label(_("Genre:"))
                self["genre"] = Label("")
                self["coverArt"] = MediaPixmap()
                self["genretext"] = Label(_("Genre:"))
                self["genre"] = Label("")
                self["coverArt"] = MediaPixmap()
+               self["repeat"] = MultiPixmap()
 
 
+               self.repeat = False
                self.seek_target = None
 
                class MoviePlayerActionMap(NumberActionMap):
                self.seek_target = None
 
                class MoviePlayerActionMap(NumberActionMap):
@@ -160,6 +163,9 @@ class MediaPlayer(Screen, InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSup
                self.currList = "filelist"
 
                self.coverArtFileName = ""
                self.currList = "filelist"
 
                self.coverArtFileName = ""
+               self.isAudioCD = False
+               self.AudioCD_albuminfo = {}
+               self.savePlaylistOnExit = False
 
                self.playlistIOInternal = PlaylistIOInternal()
                list = self.playlistIOInternal.open(resolveFilename(SCOPE_CONFIG, "playlist.e2pls"))
 
                self.playlistIOInternal = PlaylistIOInternal()
                list = self.playlistIOInternal.open(resolveFilename(SCOPE_CONFIG, "playlist.e2pls"))
@@ -168,6 +174,11 @@ class MediaPlayer(Screen, InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSup
                                self.playlist.addFile(x.ref)
                        self.playlist.updateList()
 
                                self.playlist.addFile(x.ref)
                        self.playlist.updateList()
 
+               self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
+                       {
+                               iPlayableService.evUpdatedInfo: self.__evUpdatedInfo
+                       })
+
        def doNothing(self):
                pass
 
        def doNothing(self):
                pass
 
@@ -182,7 +193,8 @@ class MediaPlayer(Screen, InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSup
                        self.playlistIOInternal.clear()
                        for x in self.playlist.list:
                                self.playlistIOInternal.addService(ServiceReference(x[0]))
                        self.playlistIOInternal.clear()
                        for x in self.playlist.list:
                                self.playlistIOInternal.addService(ServiceReference(x[0]))
-                       self.playlistIOInternal.save(resolveFilename(SCOPE_CONFIG, "playlist.e2pls"))
+                       if self.savePlaylistOnExit:
+                               self.playlistIOInternal.save(resolveFilename(SCOPE_CONFIG, "playlist.e2pls"))
                        self.close()
 
        def checkSkipShowHideLock(self):
                        self.close()
 
        def checkSkipShowHideLock(self):
@@ -197,6 +209,14 @@ class MediaPlayer(Screen, InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSup
        def __onClose(self):
                self.session.nav.playService(self.oldService)
 
        def __onClose(self):
                self.session.nav.playService(self.oldService)
 
+       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)
+               self.readTitleInformation()
+
        def delMPTimer(self):
                del self.rightKeyTimer
                del self.leftKeyTimer
        def delMPTimer(self):
                del self.rightKeyTimer
                del self.leftKeyTimer
@@ -204,15 +224,29 @@ class MediaPlayer(Screen, InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSup
        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)
-                       if stitle == "":
-                               stitle = currPlay.info().getName().split('/')[-1]
-
-                       self.updateMusicInformation( artist = currPlay.info().getInfoString(iServiceInformation.sArtist),
-                                                                                title = stitle,
-                                                                                album = currPlay.info().getInfoString(iServiceInformation.sAlbum),
-                                                                                genre = currPlay.info().getInfoString(iServiceInformation.sGenre),
-                                                                                clear = True)
+                       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 = ""
+
+                       if sTitle == "":
+                               if not self.isAudioCD:
+                                       sTitle = currPlay.info().getName().split('/')[-1]
+                               else:
+                                       sTitle = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()].getName()
+
+                       if self.AudioCD_albuminfo:
+                               if sAlbum == "" and "title" in self.AudioCD_albuminfo:
+                                       sAlbum = self.AudioCD_albuminfo["title"]
+                               if sGenre == "" and "genre" in self.AudioCD_albuminfo:
+                                       sGenre = self.AudioCD_albuminfo["genre"]
+                               if sArtist == "" and "artist" in self.AudioCD_albuminfo:
+                                       sArtist = self.AudioCD_albuminfo["artist"]
+                               if "year" in self.AudioCD_albuminfo:
+                                       sYear = self.AudioCD_albuminfo["year"]
+
+                       self.updateMusicInformation( sArtist, sTitle, sAlbum, sYear, sGenre, clear = True )
                else:
                        self.updateMusicInformation()
 
                else:
                        self.updateMusicInformation()
 
@@ -301,6 +335,13 @@ class MediaPlayer(Screen, InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSup
        def hideAfterResume(self):
                self.hide()
 
        def hideAfterResume(self):
                self.hide()
 
+       def getIdentifier(self, ref):
+               if self.isAudioCD:
+                       return ref.getName()
+               else:
+                       text = ref.getPath()
+                       return text.split('/')[-1]
+
        # FIXME: maybe this code can be optimized 
        def updateCurrentInfo(self):
                text = ""
        # FIXME: maybe this code can be optimized 
        def updateCurrentInfo(self):
                text = ""
@@ -348,16 +389,14 @@ class MediaPlayer(Screen, InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSup
                        if t is None:
                                return
                        #display current selected entry on LCD
                        if t is None:
                                return
                        #display current selected entry on LCD
-                       text = t.getPath()
-                       text = text.split('/')[-1]
+                       text = self.getIdentifier(t)
                        self.summaries.setText(text,1)
                        self["currenttext"].setText(text)
                        idx = self.playlist.getSelectionIndex()
                        idx += 1
                        if idx < len(self.playlist):
                                currref = self.playlist.getServiceRefList()[idx]
                        self.summaries.setText(text,1)
                        self["currenttext"].setText(text)
                        idx = self.playlist.getSelectionIndex()
                        idx += 1
                        if idx < len(self.playlist):
                                currref = self.playlist.getServiceRefList()[idx]
-                               text = currref.getPath()
-                               text = text.split('/')[-1]
+                               text = self.getIdentifier(currref)
                                self.summaries.setText(text,3)
                        else:
                                self.summaries.setText(" ",3)
                                self.summaries.setText(text,3)
                        else:
                                self.summaries.setText(" ",3)
@@ -365,8 +404,7 @@ class MediaPlayer(Screen, InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSup
                        idx += 1
                        if idx < len(self.playlist):
                                currref = self.playlist.getServiceRefList()[idx]
                        idx += 1
                        if idx < len(self.playlist):
                                currref = self.playlist.getServiceRefList()[idx]
-                               text = currref.getPath()
-                               text = text.split('/')[-1]
+                               text = self.getIdentifier(currref)
                                self.summaries.setText(text,4)
                        else:
                                self.summaries.setText(" ",4)
                                self.summaries.setText(text,4)
                        else:
                                self.summaries.setText(" ",4)
@@ -402,6 +440,7 @@ class MediaPlayer(Screen, InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSup
                menu.append((_("save playlist"), "saveplaylist"));
                menu.append((_("load playlist"), "loadplaylist"));
                menu.append((_("delete saved playlist"), "deleteplaylist"));
                menu.append((_("save playlist"), "saveplaylist"));
                menu.append((_("load playlist"), "loadplaylist"));
                menu.append((_("delete saved playlist"), "deleteplaylist"));
+               menu.append((_("repeat playlist"), "repeat"));
                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):
@@ -437,7 +476,13 @@ class MediaPlayer(Screen, InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSup
                        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)
 
        def showEventInformation(self):
                from Screens.EventView import EventViewSimple
 
        def showEventInformation(self):
                from Screens.EventView import EventViewSimple
@@ -564,6 +609,9 @@ class MediaPlayer(Screen, InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSup
                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 ):
+                       self.stopEntry()
+                       self.changeEntry(0)
 
        def nextMarkOrEntry(self):
                if not self.jumpPreviousNextMark(lambda x: x):
 
        def nextMarkOrEntry(self):
                if not self.jumpPreviousNextMark(lambda x: x):
@@ -625,13 +673,12 @@ class MediaPlayer(Screen, InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSup
                                # display just playing musik on LCD
                                idx = self.playlist.getCurrentIndex()
                                currref = self.playlist.getServiceRefList()[idx]
                                # display just playing musik on LCD
                                idx = self.playlist.getCurrentIndex()
                                currref = self.playlist.getServiceRefList()[idx]
-                               text = currref.getPath()
-                               text = text.split('/')[-1]
+                               text = self.getIdentifier(currref)
                                text = ">"+text
                                ext = text[-3:].lower()
 
                                # FIXME: the information if the service contains video (and we should hide our window) should com from the service instead 
                                text = ">"+text
                                ext = text[-3:].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 ["mp3", "wav", "ogg"]:
+                               if ext not in ["mp3", "wav", "ogg"] and not self.isAudioCD:
                                        self.hide()
                                else:
                                        needsInfoUpdate = True
                                        self.hide()
                                else:
                                        needsInfoUpdate = True
@@ -641,8 +688,7 @@ class MediaPlayer(Screen, InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSup
                                idx += 1
                                if idx < len(self.playlist):
                                        currref = self.playlist.getServiceRefList()[idx]
                                idx += 1
                                if idx < len(self.playlist):
                                        currref = self.playlist.getServiceRefList()[idx]
-                                       text = currref.getPath()
-                                       text = text.split('/')[-1]
+                                       text = self.getIdentifier(currref)
                                        self.summaries.setText(text,3)
                                else:
                                        self.summaries.setText(" ",3)
                                        self.summaries.setText(text,3)
                                else:
                                        self.summaries.setText(" ",3)
@@ -650,8 +696,7 @@ class MediaPlayer(Screen, InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSup
                                idx += 1
                                if idx < len(self.playlist):
                                        currref = self.playlist.getServiceRefList()[idx]
                                idx += 1
                                if idx < len(self.playlist):
                                        currref = self.playlist.getServiceRefList()[idx]
-                                       text = currref.getPath()
-                                       text = text.split('/')[-1]
+                                       text = self.getIdentifier(currref)
                                        self.summaries.setText(text,4)
                                else:
                                        self.summaries.setText(" ",4)
                                        self.summaries.setText(text,4)
                                else:
                                        self.summaries.setText(" ",4)
@@ -660,7 +705,7 @@ class MediaPlayer(Screen, InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSup
                                currref = self.playlist.getServiceRefList()[idx]
                                text = currref.getPath()
                                ext = text[-3:].lower()
                                currref = self.playlist.getServiceRefList()[idx]
                                text = currref.getPath()
                                ext = text[-3:].lower()
-                               if ext not in ["mp3", "wav", "ogg"]:
+                               if ext not in ["mp3", "wav", "ogg"] and not self.isAudioCD:
                                        self.hide()
                                else:
                                        needsInfoUpdate = True
                                        self.hide()
                                else:
                                        needsInfoUpdate = True
@@ -697,7 +742,6 @@ class MediaPlayer(Screen, InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSup
        def unPauseService(self):
                self.setSeekState(self.SEEK_STATE_PLAY)
 
        def unPauseService(self):
                self.setSeekState(self.SEEK_STATE_PLAY)
 
-
 class MediaPlayerLCDScreen(Screen):
        skin = """
        <screen position="0,0" size="132,64" title="LCD Text">
 class MediaPlayerLCDScreen(Screen):
        skin = """
        <screen position="0,0" size="132,64" title="LCD Text">
@@ -727,7 +771,7 @@ class MediaPlayerLCDScreen(Screen):
                        self["text4"].setText(text)
 
 def main(session, **kwargs):
                        self["text4"].setText(text)
 
 def main(session, **kwargs):
-        session.open(MediaPlayer)
+       session.open(MediaPlayer)
 
 def menu(menuid, **kwargs):
        if menuid == "mainmenu":
 
 def menu(menuid, **kwargs):
        if menuid == "mainmenu":
@@ -738,20 +782,43 @@ def filescan_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
+
+       for file in list:
+               if file.mimetype.startswith("video"):
+                       stype = 1
+               else:
+                       stype = 4097
+               ref = eServiceReference(stype, 0, file.path)
+               mp.playlist.addFile(ref)
 
 
+       mp.changeEntry(0)
        mp.switchToPlayList()
        mp.switchToPlayList()
+
+def audioCD_open(list, session, **kwargs):
+       from enigma import eServiceReference
+
+       mp = session.open(MediaPlayer)
+
+       mp.playlist.clear()
+       mp.savePlaylistOnExit = False
+       mp.isAudioCD = True
+
        for file in list:
                ref = eServiceReference(4097, 0, file.path)
                mp.playlist.addFile(ref)
        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()
 
 
-       # TODO: rather play first than last file?
-       mp.playServiceRefEntry(ref)
-       mp.playlist.updateList()
+       mp.changeEntry(0)
+       mp.switchToPlayList()
 
 def filescan(**kwargs):
        from Components.Scanner import Scanner, ScanPath
 
 def filescan(**kwargs):
        from Components.Scanner import Scanner, ScanPath
-       return [
-               Scanner(mimetypes = ["video/mpeg"],
+       mediatypes = [
+               Scanner(mimetypes = ["video/mpeg", "video/MP2T", "video/x-msvideo"],
                        paths_to_scan =
                                [
                                        ScanPath(path = "", with_subdirs = False),
                        paths_to_scan =
                                [
                                        ScanPath(path = "", with_subdirs = False),
@@ -768,8 +835,21 @@ def filescan(**kwargs):
                        name = "Music",
                        description = "Play Music...",
                        openfnc = filescan_open,
                        name = "Music",
                        description = "Play Music...",
                        openfnc = filescan_open,
-               )
-       ]
+               )]
+       try:
+               from Plugins.Extensions.CDInfo.plugin import Query
+               mediatypes.insert(0,Scanner(mimetypes = ["audio/x-cda", "audio/x-wav"],
+                       paths_to_scan =
+                               [
+                                       ScanPath(path = "", with_subdirs = False),
+                               ],
+                       name = "Audio-CD",
+                       description = "Play Audio-CD...",
+                       openfnc = audioCD_open,
+               ))
+               return mediatypes
+       except ImportError:
+               return mediatypes
 
 from Plugins.Plugin import PluginDescriptor
 def Plugins(**kwargs):
 
 from Plugins.Plugin import PluginDescriptor
 def Plugins(**kwargs):