Hi!

I've updated the mplayervis plugin:
- Don't set the render in realtime. Seems it didn't do much good.
  Capped to 100fps for now.
- Keep aspect ratio for cover images and center it in visualization
  (looks much nicer now)
- Don't use cinemascope in fullscreen, hardcoded 16:9 format.
  This should save some blit() and update() time.
- Added a mode to stop visualizations.

mikeruelle: Could you check if this patch fixes the doubleposting
            of events you were seeing? (I think it should, but not
            100% sure).

Regards
Viggo Fredriksen
diff -Naur freevo/src/audio/plugins/mplayervis.py freevo_devel/src/audio/plugins/mplayervis.py
--- freevo/src/audio/plugins/mplayervis.py	2004-05-14 23:31:27.000000000 +0200
+++ freevo_devel/src/audio/plugins/mplayervis.py	2004-05-16 17:33:10.801157952 +0200
@@ -61,7 +61,7 @@
     def __init__(self, x, y, width, height, coverfile=None):
         self.coverfile = coverfile
 
-        BaseAnimation.__init__(self, (x, y, width, height), fps=40,
+        BaseAnimation.__init__(self, (x, y, width, height), fps=100,
                                bg_update=False, bg_redraw=False)
         pygoom.set_exportfile(mmap_file)
         pygoom.set_resolution(width, height, 0)
@@ -87,8 +87,8 @@
         font = skin.get_font('detachbar')
         w = font.stringsize(message)
         h = font.height
-        x = config.OSD_OVERSCAN_X + 10
-        y = config.OSD_OVERSCAN_Y + 10
+        x = 10
+        y = 10
 
         s = Surface((w,h), 0, 32)
 
@@ -113,21 +113,38 @@
 
         # change the cover if neceserry
         if self.coverfile:
-            self.coversurf = transform.scale(image.load(self.coverfile),
-                                             (self.rect.width, self.rect.height))
+            s = image.load(self.coverfile)
 
-        self.max_blend = 250
-        self.c_timer = time.time()
-
-        if clear:
-            skin.clear()
+            # scale and fit to the rect
+            w, h   = s.get_size()
+            aspect = float(w)/float(h)
+
+            if aspect < 1.0:
+                w = self.rect.width
+                h = float(w) / aspect
+                x = 0
+                y = (self.rect.height - h) / 2
+            else:
+                h = self.rect.height
+                w = float(h) * aspect
+                y = 0
+                x = (self.rect.width - w)  / 2
+
+            self.coversurf = (transform.scale(s,(w, h)), x, y)
+            self.max_blend = 250
+            self.c_timer   = time.time()
 
 
     def set_fullscreen(self):
-        self.set_resolution(config.OSD_OVERSCAN_X, config.OSD_OVERSCAN_Y,
-                            config.CONF.width-2*config.OSD_OVERSCAN_X,
-                            config.CONF.height-2*config.OSD_OVERSCAN_Y,
-                            1, False)
+        t_h = config.CONF.height-2*config.OSD_OVERSCAN_Y
+        w   = config.CONF.width-2*config.OSD_OVERSCAN_X
+
+        # ~16:9
+        h   = int(9.0*float(w)/16.0)
+        y   = ((t_h-h)/2) + config.OSD_OVERSCAN_Y
+        x   = config.OSD_OVERSCAN_X
+
+        self.set_resolution(x, y, w, h, 0)
         self.max_blend = 80
 
 
@@ -161,8 +178,9 @@
                     self.blend_step = - self.blend_step
 
                 if self.blend > 0:
-                    self.coversurf.set_alpha(self.blend)
-                    gooms.blit(self.coversurf, (0,0))
+                    s, x, y = self.coversurf
+                    s.set_alpha(self.blend)
+                    gooms.blit(s, (x, y))
 
             # draw message
             if self.message:
@@ -177,6 +195,10 @@
             osd.putsurface(gooms, self.rect.left, self.rect.top)
             osd.update(self.rect)
 
+### MODE definitions
+DOCK = 0 # dock ( default )
+FULL = 1 # fullscreen
+NOVI = 2 # no view
 
 class PluginInterface(plugin.Plugin):
     """
@@ -186,87 +208,138 @@
 
     Activate with:
      plugin.activate('audio.mplayervis')
-    """
 
-    start  = False
+    When activated one can change between view-modes
+    with the 0 (zero) button.
+    """
     player = None
     visual = None
-    view   = 0
+    view   = DOCK
     passed_event = False
     detached = False
 
     def __init__(self):
         plugin.Plugin.__init__(self)
-        self._type    = "mplayer_audio"
+        self._type    = 'mplayer_audio'
+        self.app_mode = 'audio'
 
         # Event for changing between viewmodes
-        config.EVENTS['audio']['0'] = TOGGLE_OSD
+        config.EVENTS['audio']['0'] = Event('CHANGE_MODE')
 
-        self.plugin_name = "audio.mplayervis"
+        self.plugin_name = 'audio.mplayervis'
         plugin.register(self, self.plugin_name)
 
+        self.view_func = [self.dock,
+                          self.fullscreen,
+                          self.noview]
+
 
     def play( self, command, player ):
         self.player = player
+        self.item   = player.playerGUI.item
 
         return command + [ "-af", "export=" + mmap_file ]
 
 
+    def toggle_view(self):
+        """
+        Toggle between view modes
+        """
+        self.view += 1
+        if self.view > 2:
+            self.view = DOCK
+
+        if not self.visual:
+            self.start_visual()
+        else:
+            self.view_func[self.view]()
+
+
     def eventhandler( self, event=None, arg=None ):
         """
         eventhandler to simulate hide/show of mpav
         """
-        if self.visual:
-            if event == TOGGLE_OSD and self.view in [0, 1]:
-                if self.view == 1:
-                    self.dock()
 
-                elif self.view == 0:
-                    self.fullscreen()
+        if event == 'CHANGE_MODE':
+            self.toggle_view()
+            return True
+
+        if self.visual and self.view == FULL:
 
-            elif event == OSD_MESSAGE and self.view == 1:
+            if event == OSD_MESSAGE:
                 self.visual.set_message(event.arg)
+                return True
 
-            elif self.player:
-                if self.passed_event:
-                    self.passed_event = False
-                    return False
-                self.passed_event = True
-
-                # XXX Sending MIXER stuff messes up fullscreen
-                if self.view == 1 and event in (STOP, PLAY_END, USER_END, PAUSE,
-                                                AUDIO_SEND_MPLAYER_CMD, PLAY,
-                                                SEEK,PLAYLIST_PREV, PLAYLIST_NEXT ):
+            if self.passed_event:
+                self.passed_event = False
+                return False
 
-                    return self.player.eventhandler(event)
+            self.passed_event = True
 
-                else:
-                    return self.player.eventhandler(event)
+            if event != PLAY_END:
+                return self.player.eventhandler(event)
 
-            return True
+        return False
+
+
+    def item_info(self, fmt=None):
+        """
+        Returns info about the current running song
+        """
 
+        if not fmt:
+            fmt = u'%(a)s : %(l)s  %(n)s.  %(t)s (%(y)s)   [%(s)s]'
 
-    def check_image(self):
-        if self.player:
-            img = self.player.item.image
+        item    = self.item
+        info    = item.info
+        name    = item.name
+        length  = None
+        elapsed = '0'
+
+        if info['title']:
+            name = info['title']
+
+        if item.elapsed:
+            elapsed = '%i:%02i' % (int(item.elapsed/60), int(item.elapsed%60))
+
+        if item.length:
+            length = '%i:%02i' % (int(item.length/60), int(item.length%60))
+
+        song = { 'a' : info['artist'],
+                 'l' : info['album'],
+                 'n' : info['trackno'],
+                 't' : name,
+                 'e' : elapsed,
+                 'i' : item.image,
+                 'y' : info['year'],
+                 's' : length }
 
-        if img:
-            self.visual.set_cover(img)
+        return fmt % song
 
 
     def fullscreen(self):
-        if self.player:
+        if self.player.playerGUI.visible:
             self.player.playerGUI.hide()
 
         self.visual.set_fullscreen()
-
+        self.visual.set_message(self.item_info())
+        skin.clear()
         rc.app(self)
-        rc.set_context('audio')
-        self.view = 1
+
+    def noview(self):
+
+        if rc.app() != self.player.eventhandler:
+            rc.app(self.player)
+
+        if self.visual:
+            self.stop_visual()
+
+        if not self.player.playerGUI.visible:
+            self.player.playerGUI.show()
 
 
     def dock(self):
-        if self.player:
+        if rc.app() != self.player.eventhandler:
             rc.app(self.player)
 
         # get the rect from skin
@@ -289,81 +362,46 @@
         except:
             pass
 
+        self.visual.set_resolution(x, y, w, h, 0, False)
 
-        if self.view == 1:
-            self.player.playerGUI.show()
-            self.visual.set_resolution(x, y, w, h, 0, True)
-
-        else:
-            self.visual.set_resolution(x, y, w, h, 0, False)
-
-        self.view = 0
-
-
-    def detach(self):
-        rc.app(None)
-        self.view = 3
-
-
-    def stdout(self, line):
-        """
-        get information from mplayer stdout
-        """
-        if self.visual:
-            return
-
-        try:
-            if line.find( "[export] Memory mapped to file: "+mmap_file ) == 0:
-                self.start = True
-                _debug_( "Detected MPlayer 'export' audio filter! Using MPAV." )
-        except:
-            pass
-
-
-    def elapsed(self, elapsed):
-        # Be sure mplayer started playing, it need to setup mmap first.
-        if self.start and elapsed > 0 and self.player and self.player.playerGUI.visible:
-            self.start_visual()
-            self.start = False
 
 
     def start_visual(self):
-        if not self.visual:
-            self.visual = mpv_Goom(300, 300, 150, 150)
-
-            if self.player and self.view == 1:
-                self.visual.set_message(self.player.item.name, 10)
-
-            self.check_image()
+        if self.visual or self.view == NOVI:
+            return
 
-            # plain docked in playergui
-            if self.view == 0:
-                self.dock()
+        if rc.app() == self.player.eventhandler:
 
-            # plain fullscreen
-            elif self.view == 1:
-                self.fullscreen()
+            self.visual = mpv_Goom(300, 300, 150, 150, self.item.image)
 
-            # previously detached
-            elif self.view == 3 and self.player.playerGUI.visible:
-                skin.clear()
-                self.view = 0
-                self.dock()
+            if self.view == FULL:
+                self.visual.set_message(self.item.name, 10)
 
-            render.get_singleton().set_realtime(True)
+            self.view_func[self.view]()
             self.visual.start()
 
+
     def stop_visual(self):
         if self.visual:
             self.visual.remove()
-            render.get_singleton().set_realtime(False)
-            pygoom.quit()
             self.visual = None
+            pygoom.quit()
 
-            # XXX this is hackish()
-            if self.view == 3 and self.player.playerGUI.visible:
-                skin.clear()
 
     def stop(self):
         self.stop_visual()
 
+
+    def stdout(self, line):
+        """
+        get information from mplayer stdout
+
+        It should be safe to do call start() from here
+        since this is now a callback from main.
+        """
+        if self.visual:
+            return
+
+        if line.find( "[export] Memory mapped to file: " + mmap_file ) == 0:
+            _debug_( "Detected MPlayer 'export' audio filter! Using MPAV." )
+            self.start_visual()

Reply via email to