Example #1
0
 def __init__ (self):
     self.spcb=None
     self.activated=False
     self.volume=0
     self.playing=False
     self.current_pos=0
     self.this_dir=os.path.dirname(__file__)
     
     self.last_seek=None
     
     ## the last captured SB state
     self.last_sb_state=None
     
     self.scc=SqueezeCenterControl()
     self.skip_time_adjust=False
     
     Bus.subscribe(self, "__tick__", self.h_tick)
Example #2
0
class PluginAgent(object):
    
    BUSNAME="__main__"
    MOUNTS_REFRESH_INTERVAL=2 #minutes
    
    ADJUST_INTERVAL=5 ##seconds
    
    def __init__ (self):
        self.spcb=None
        self.activated=False
        self.volume=0
        self.playing=False
        self.current_pos=0
        self.this_dir=os.path.dirname(__file__)
        
        self.last_seek=None
        
        ## the last captured SB state
        self.last_sb_state=None
        
        self.scc=SqueezeCenterControl()
        self.skip_time_adjust=False
        
        Bus.subscribe(self, "__tick__", self.h_tick)

    def init_toolbar(self):
        self.action = ('ActivateSqueezeboxMode',None, _('SqueezeboxTools'),
                None, _('Activate Squeezebox mode'),
                self.activate_button_press, True)

        self.action_group = gtk.ActionGroup('SqueezeboxPluginActions')
        self.action_group.add_toggle_actions([self.action])
        action=self.action_group.get_action("ActivateSqueezeboxMode")
        action.set_gicon(self.get_icon())
        
        #print dir(action)
        #action.do_add_child(image)
        
        uim = self.shell.get_ui_manager()
        uim.insert_action_group (self.action_group, 0)
        self.ui_id = uim.add_ui_from_string(context_ui)
        #self.ui_id.insert_item("Text", "Tooltip", "Private", image, None, None, -1)
        uim.ensure_update()
        
    def get_icon(self):
        path=os.path.join(self.this_dir, "squeezecenter.gif" )
        file=gio.File(path)
        icon=gio.FileIcon(file)
        return icon
    
        
    def remove_toolbar(self):
        uim = self.shell.get_ui_manager()
        uim.remove_ui (self.ui_id)
        uim.remove_action_group (self.action_group)

        
    def activate_button_press(self, action):
        #print "!!! Mode activated: %s" % action
        self.activated = not self.activated
        if self.activated:
            self.do_activation()
        else:
            self.do_deactivation()
            
    def do_activation(self):
        """
        When the user requests activation of the Squeezebox mode
        
        * Mute volume but keep current setting
        """
        print "SqueezeBox: activation, version: %s" % __VERSION__
        self.refresh_mounts()
        self.volume=self.sp.get_volume()
        self.sp.set_volume(0)
         
    def do_deactivation(self):
        """
        Deactivation...
        """
        self.sp.set_volume(self.volume)
        

    def activate (self, shell):
        """
        Called by Rhythmbox when the plugin is activated
        """
        print ">> Squeezebox activated"
        self.active=True
        self.shell = shell
        self.sp = shell.get_player()
        self.db=self.shell.props.db
        
        ##
        self.spcb = (
                     self.sp.connect("playing-changed",        self.on_playing_changed),
                     self.sp.connect("playing-song-changed",   self.on_playing_song_changed),
                     self.sp.connect("elapsed-changed",         self.on_elapsed_changed),
                     )
        
        ## Distribute the vital RB objects around
        Bus.publish("__pluging__", "rb_shell", self.shell, self.db, self.sp)
        
        #self._reconnect()
        self.init_toolbar()
        
    def deactivate (self, shell):
        """
        Called by RB when the plugin is about to get deactivated
        """
        self.active=False
        print ">> Squeezebox de-activated"
        self.remove_toolbar()
            
        for id in self.spcb:
            self.sp.disconnect(id)
            
        self.scc.pause()
        """
        self._maybe_reconnect()
                
        try:      self.player.pause()
        except:   pass
        """

    ## ================================================  rb signal handlers

    def on_elapsed_changed(self, pl, pos_seconds, *_):
        """
        When the use 'seeks' during track playback
        
        Since this signal is sent on every second, we need to
        implement a filter to determine when the user is actually
        seeking into the track.
        
        NOTE: RB sends more than one of this signal when starting
              a new track playback... debounce.
        """
        if not self.activated:
            return
        if not self.playing:
            return
        
        ## debounce...
        if self.last_seek==pos_seconds:
            return
        self.last_seek=pos_seconds
        
        #self._maybe_reconnect()
        
        ## skip one time adjustment upon re-sync
        ## of SB <--> RB            
        if self.skip_time_adjust:
            self.skip_time_adjust=False
            return
        
        if pos_seconds != self.current_pos+1:
            print ">> seeking to: %s" % pos_seconds
            self.scc.seekTo(pos_seconds)
            """
            try:
                
                self.player.seek_to(pos_seconds)
            except:
                print "! Unable to seek to :%s" % pos_seconds
            """
        self.current_pos=pos_seconds

    def on_playing_changed(self, player, playing, *_):
        """
        Easy condition to deal with since we consider RB
        to be the 'master' of the play state
        """
        if not self.activated:
            return
        
        #self._maybe_reconnect()
                    
        #print "playing: %s" % playing
        self.playing=playing
        self.scc.setMode(playing)
        """
        try:
            if playing:
                self.player.play()
            else:
                self.player.pause()
        except:
            print "! Unable to play/pause"
        """

    def on_playing_song_changed(self, player, entry, *_):
        """
        We also need to check if the Squeezebox was paused/stopped
        through other means during playback: we need to reflect 
        this state here back on RB.
        
        The tough part:  the 2 aren't perfectly synchronized so it is
        possible that the SB finishes playing the current track before
        RB and vice-versa.  In this case, we need to check the difference
        between the 2 'time markers' in order to assess if the SB was
        paused/stopped before the end of the current track.
        """
        if not self.activated:
            return
        
        if entry is None:
            return
        
        self.current_pos=0
        
        td=EntryHelper.track_details2(self.db, entry)

        print "> resolving path: %s" % td["path"]
        
        path=self.resolve_path(td["path"])
        if path is None:
            print "*** ERROR resolving path"
            return
            
        print "** resolved path: %s" % path
        self.scc.setPlayPath(path)
        
        #self._maybe_reconnect()
        """
        try:
            self.player.playlist_play(path)
        except:
            print "! Unable to set playing path to: %s" % path
        """

    ## ================================================ helpers
    def on_sb_change(self, mode):
        """
        Triggered when the state of remote SqueezeBox changes
        
        Adjust time tracker based on SB
        
        SB paused:  adjust RB time marker,  pause RB
        SB play:    adjust RB time marker,  play  RB
        """
        
        ## if RB is already playing, no big deal...
        if mode=="play":
            if self.sp.get_playing():
                return
        
        #self._maybe_reconnect()
        self.skip_time_adjust=True
        
        try:
            #sb_tm=self.player.get_time_elapsed()
            sb_tm=self.scc.getPos()
            self.sp.set_playing_time(int(sb_tm))
            print "* On SB change: time marker: %s" % sb_tm
        except Exception, _e:
            print "! Unable to seek RB to SB's time marker... "
    
        try:
            if mode=="pause":
                self.sp.pause()
            else:
                self.sp.play()
        except:
            print "! RB issue: Can't switch to mode(%s) right now" % mode