def test_same_song(self):
        md1=Metadata("artist1","song1")
        md2=Metadata("artist1","song1", albumTitle="album1")
        md3=Metadata("artist1","song1", albumTitle="album2")
        md4=Metadata("artist2","song1")
        md5=Metadata("","song1")
        
        self.assertTrue(md1.sameSong(md2))
        self.assertTrue(md1.sameSong(md3))
        self.assertTrue(md2.sameSong(md3))

        self.assertFalse(md1.sameSong(md4))
        self.assertFalse(md1.sameSong(md5))
Esempio n. 2
0
    def main_loop(self):
        """
        Main loop:
        - monitors state of all players
        - pauses players if a new player starts playback
        """

        finished = False
        md = Metadata()
        active_players = []

        MAX_FAIL = 3

        # Workaround for spotifyd problems
        #        spotify_stopped = 0

        # Workaround for squeezelite mute
        squeezelite_active = 0

        previous_state = ""
        ts = datetime.datetime.now()

        while not (finished):
            additional_delay = 0
            new_player_started = None
            metadata_notified = False
            playing = False
            new_song = False
            state = "unknown"
            last_ts = ts
            ts = datetime.datetime.now()
            duration = (ts - last_ts).total_seconds()

            for p in self.all_players():

                if self.playername(p) in self.ignore_players:
                    continue

                if p not in self.state_table:
                    ps = PlayerState()
                    ps.supported_commands = self.get_supported_commands(p)
                    logging.debug("Player %s supports %s", p,
                                  ps.supported_commands)
                    self.state_table[p] = ps

                thisplayer_state = "unknown"
                try:
                    thisplayer_state = self.get_player_state(p).lower()
                    self.state_table[p].failed = 0
                except:
                    logging.info("Got no state from " + p)
                    state = "unknown"
                    self.state_table[p].failed = \
                        self.state_table[p].failed + 1
                    if self.state_table[p].failed >= MAX_FAIL:
                        playername = self.playername(p)
                        logging.warning("%s failed, trying to restart",
                                        playername)
                        watchdog.restart_service(playername)
                        self.state_table[p].failed = 0

                self.state_table[p].state = thisplayer_state

                # Check if playback started on a player that wasn't
                # playing before
                if thisplayer_state == STATE_PLAYING:
                    playing = True
                    state = "playing"

                    #                    if self.playername(p) == SPOTIFY_NAME:
                    #                        spotify_stopped = 0

                    if self.playername(p) == LMS_NAME:
                        squeezelite_active = 2

                    report_usage(
                        "audiocontrol_playing_{}".format(self.playername(p)),
                        duration)

                    md = self.get_meta(p)

                    if (p not in active_players):
                        new_player_started = p
                        active_players.insert(0, p)

                    md.playerState = thisplayer_state

                    # MPRIS delivers only very few metadata, these will be
                    # enriched with external sources
                    if (md.sameSong(self.metadata)):
                        md.fill_undefined(self.metadata)
                    else:
                        new_song = True

                    self.state_table[p].metadata = md
                    if not (md.sameSong(self.metadata)):
                        logging.debug("updated metadata: \nold %s\nnew %s",
                                      self.metadata, md)
                        # Store this as "current"
                        with self.metadata_lock:
                            self.metadata = md

                        self.metadata_notify(md)
                        logging.debug("notifications about new metadata sent")
                    elif state != previous_state:
                        logging.debug("changed state to playing")
                        self.metadata_notify(md)

                    # Some players deliver artwork after initial metadata
                    if md.artUrl != self.metadata.artUrl:
                        logging.debug("artwork changes from %s to %s",
                                      self.metadata.artUrl, md.artUrl)
                        self.metadata_notify(md)

                    # Add metadata if this is a new song
                    if new_song:
                        enrich_metadata_bg(md, callback=self)
                        logging.debug("metadata updater thread started")

                    # Even if we din't send metadata, this is still
                    # flagged
                    metadata_notified = True
                else:

                    # always keep one player in the active_players
                    # list
                    if len(active_players) > 1:
                        if p in active_players:
                            active_players.remove(p)

                    # update metadata for stopped players from time to time
                    i = randint(0, 600)
                    if (i == 0):
                        md = self.get_meta(p)
                        md.playerState = thisplayer_state
                        self.state_table[p].metadata = md

            self.playing = playing

            # Find active (or last paused) player
            if len(active_players) > 0:
                self.active_player = active_players[0]
            else:
                self.active_player = None

#             # Workaround for wrong state messages by Spotify
#             # Assume Spotify is still playing for 10 seconds if it's the
#             # active (or last stopped) player
#             if self.playername(self.active_player) == SPOTIFY_NAME:
#                 # Less aggressive metadata polling on Spotify as each polling will
#                 # result in an API request
#                 additional_delay = 4
#                 if not(playing):
#                     spotify_stopped += 1 + additional_delay
#                     if spotify_stopped < 26:
#                         if (spotify_stopped % 5) == 0:
#                             logging.debug("spotify workaround %s", spotify_stopped)
#                         playing = True
#

# Workaround for LMS muting the output after stopping the
# player
            if self.volume_control is not None:
                if self.playername(self.active_player) != LMS_NAME:
                    if squeezelite_active > 0:
                        squeezelite_active = squeezelite_active - 1
                        logging.debug(
                            "squeezelite was active before, unmuting")
                        self.volume_control.set_mute(False)

                if not (playing) and squeezelite_active > 0:
                    squeezelite_active = squeezelite_active - 1
                    logging.debug("squeezelite was active before, unmuting")
                    self.volume_control.set_mute(False)

            # There might be no active player, but one that is paused
            # or stopped
            if not (playing) and len(active_players) > 0:
                p = active_players[0]
                md = self.get_meta(p)
                md.playerState = self.state_table[p].state
                state = md.playerState

            if state != previous_state:
                logging.debug("state transition %s -> %s", previous_state,
                              state)
                if not metadata_notified:
                    self.metadata_notify(md)
                for sd in self.state_displays:
                    sd.update_playback_state(state)

            previous_state = state

            if new_player_started is not None:
                if self.auto_pause:
                    logging.info(
                        "new player %s started, pausing other active players",
                        self.playername(active_players[0]))
                    self.pause_inactive(new_player_started)
                else:
                    logging.debug("auto-pause disabled")

            self.last_update = datetime.datetime.now()

            time.sleep(self.loop_delay + additional_delay)