Remember playback resume points in RAM for filetypes without cue support
authorMike Looijmans <milo-software@users.sourceforge.net>
Sun, 5 Jun 2011 08:11:53 +0000 (10:11 +0200)
committerMike Looijmans <milo-software@users.sourceforge.net>
Sun, 5 Jun 2011 08:15:32 +0000 (10:15 +0200)
This remembers the resume positions for the last 100 played files that
are not recordings until you restart Enigma.

Navigation.py
lib/python/Screens/InfoBar.py
lib/python/Screens/InfoBarGenerics.py

index f491d28..5128bb6 100644 (file)
@@ -73,8 +73,12 @@ class Navigation:
                                        return 0
                        else:
                                playref = ref
                                        return 0
                        else:
                                playref = ref
-                       if self.pnav and not self.pnav.playService(playref):
+                       if self.pnav:
+                               self.pnav.stopService()
                                self.currentlyPlayingServiceReference = playref
                                self.currentlyPlayingServiceReference = playref
+                               if self.pnav.playService(playref):
+                                       print "Failed to start", playref
+                                       self.currentlyPlayingServiceReference = None
                                return 0
                else:
                        self.stopService()
                                return 0
                else:
                        self.stopService()
@@ -109,7 +113,6 @@ class Navigation:
                return self.currentlyPlayingService
 
        def stopService(self):
                return self.currentlyPlayingService
 
        def stopService(self):
-               print "stopService"
                if self.pnav:
                        self.pnav.stopService()
 
                if self.pnav:
                        self.pnav.stopService()
 
index fd10d93..0a99344 100644 (file)
@@ -16,7 +16,8 @@ from Screens.InfoBarGenerics import InfoBarShowHide, \
        InfoBarSubserviceSelection, InfoBarShowMovies, InfoBarTimeshift,  \
        InfoBarServiceNotifications, InfoBarPVRState, InfoBarCueSheetSupport, InfoBarSimpleEventView, \
        InfoBarSummarySupport, InfoBarMoviePlayerSummarySupport, InfoBarTimeshiftState, InfoBarTeletextPlugin, InfoBarExtensions, \
        InfoBarSubserviceSelection, InfoBarShowMovies, InfoBarTimeshift,  \
        InfoBarServiceNotifications, InfoBarPVRState, InfoBarCueSheetSupport, InfoBarSimpleEventView, \
        InfoBarSummarySupport, InfoBarMoviePlayerSummarySupport, InfoBarTimeshiftState, InfoBarTeletextPlugin, InfoBarExtensions, \
-       InfoBarSubtitleSupport, InfoBarPiP, InfoBarPlugins, InfoBarServiceErrorPopupSupport, InfoBarJobman
+       InfoBarSubtitleSupport, InfoBarPiP, InfoBarPlugins, InfoBarServiceErrorPopupSupport, InfoBarJobman, \
+       setResumePoint
 
 profile("LOAD:InitBar_Components")
 from Components.ActionMap import HelpableActionMap
 
 profile("LOAD:InitBar_Components")
 from Components.ActionMap import HelpableActionMap
@@ -195,6 +196,7 @@ class MoviePlayer(InfoBarBase, InfoBarShowHide, \
                        self.leavePlayerConfirmed([True, how])
 
        def leavePlayer(self):
                        self.leavePlayerConfirmed([True, how])
 
        def leavePlayer(self):
+               setResumePoint(self.session)
                self.handleLeave(config.usage.on_movie_stop.value)
 
        def deleteConfirmed(self, answer):
                self.handleLeave(config.usage.on_movie_stop.value)
 
        def deleteConfirmed(self, answer):
index 93459da..705d512 100644 (file)
@@ -44,6 +44,39 @@ from RecordTimer import RecordTimerEntry, RecordTimer
 # hack alert!
 from Menu import MainMenu, mdom
 
 # hack alert!
 from Menu import MainMenu, mdom
 
+resumePointCache = {}
+
+def setResumePoint(session):
+       global resumePointCache
+       service = session.nav.getCurrentService()
+       ref = session.nav.getCurrentlyPlayingServiceReference()
+       if (service is not None) and (ref is not None) and (ref.type != 1):
+               # ref type 1 has its own memory...
+               seek = service.seek()
+               if seek:
+                       pos = seek.getPlayPosition()
+                       if not pos[0]:
+                               key = ref.toString()
+                               lru = time()
+                               resumePointCache[key] = [lru, pos[1]]
+                               if len(resumePointCache) > 100:
+                                       candidate = key
+                                       for k,v in resumePointCache.items():
+                                               if v[0] < lru:
+                                                       candidate = k
+                                       del resumePointCache[candidate]
+
+def getResumePoint(session):
+       global resumePointCache
+       ref = session.nav.getCurrentlyPlayingServiceReference()
+       if (ref is not None) and (ref.type != 1):
+               try:
+                       entry = resumePointCache[ref.toString()]
+                       entry[0] = time() # update LRU timestamp
+                       return entry[1]
+               except KeyError:
+                       return None
+
 class InfoBarDish:
        def __init__(self):
                self.dishDialog = self.session.instantiateDialog(Dish)
 class InfoBarDish:
        def __init__(self):
                self.dishDialog = self.session.instantiateDialog(Dish)
@@ -1920,6 +1953,8 @@ class InfoBarCueSheetSupport:
                                        last = pts
                                        break
                        else:
                                        last = pts
                                        break
                        else:
+                               last = getResumePoint(self.session)
+                       if last is None:
                                return
                        # only resume if at least 10 seconds ahead, or <10 seconds before the end.
                        seekable = self.__getSeekable()
                                return
                        # only resume if at least 10 seconds ahead, or <10 seconds before the end.
                        seekable = self.__getSeekable()
@@ -1928,7 +1963,7 @@ class InfoBarCueSheetSupport:
                        length = seekable.getLength() or (None,0)
                        print "seekable.getLength() returns:", length
                        # Hmm, this implies we don't resume if the length is unknown...
                        length = seekable.getLength() or (None,0)
                        print "seekable.getLength() returns:", length
                        # Hmm, this implies we don't resume if the length is unknown...
-                       if last is not None and (last > 900000) and (last < length[1] - 900000):
+                       if (last > 900000) and (last < length[1] - 900000):
                                self.resume_point = last
                                
                                l = last / 90000
                                self.resume_point = last
                                
                                l = last / 90000