Пример #1
0
    def __init__(self, uid, uname, token, expire):

        self.logger = logging.getLogger('douban-fmd.player')

        self.channel = 0

        self.radioAPI = RadioAPI(uid, uname, token, expire)

        self.play_list = []
        self.play_history = []
        self.current_song_index = -1

        self.mpg321_pid = None

        self.status = PlayerStatus.INIT

        self.pid = os.getpid()
        self.logger.debug("main process pid is %d" % self.pid)

        self.inputQueue = multiprocessing.Queue()
        self.outputQueue = multiprocessing.Queue()

        self.play_proc = multiprocessing.Process(target=self.__call_mpg321,
                                                 name="douban-fmd-player",
                                                 args=(
                                                     self.inputQueue,
                                                     self.outputQueue,
                                                 ))

        self.play_proc.start()
Пример #2
0
    def __init__(self, uid, uname, token, expire):
    
        self.logger = logging.getLogger('douban-fmd.player')

        self.channel = 0

        self.radioAPI = RadioAPI(uid, uname, token, expire)

        self.play_list = []
        self.play_history = []
        self.current_song_index = -1

        self.mpg321_pid = None

        self.status = PlayerStatus.INIT
        
        self.pid = os.getpid()
        self.logger.debug("main process pid is %d" % self.pid)
        
        self.inputQueue = multiprocessing.Queue()
        self.outputQueue = multiprocessing.Queue()
        
        self.play_proc = multiprocessing.Process(
            target=self.__call_mpg321, 
            name="douban-fmd-player", 
            args=(self.inputQueue, self.outputQueue, ))
        
        self.play_proc.start()
Пример #3
0
class Player:
    def __init__(self, uid, uname, token, expire):

        self.logger = logging.getLogger('douban-fmd.player')

        self.channel = 0

        self.radioAPI = RadioAPI(uid, uname, token, expire)

        self.play_list = []
        self.play_history = []
        self.current_song_index = -1

        self.mpg321_pid = None

        self.status = PlayerStatus.INIT

        self.pid = os.getpid()
        self.logger.debug("main process pid is %d" % self.pid)

        self.inputQueue = multiprocessing.Queue()
        self.outputQueue = multiprocessing.Queue()

        self.play_proc = multiprocessing.Process(target=self.__call_mpg321,
                                                 name="douban-fmd-player",
                                                 args=(
                                                     self.inputQueue,
                                                     self.outputQueue,
                                                 ))

        self.play_proc.start()

    def close(self):
        self.play_proc.terminate()

    def __login(self):
        pass

    def __call_mpg321(self, inputQueue, outputQueue):

        while True:
            song_url, main_pid = inputQueue.get()

            mpg321_proc = subprocess.Popen(
                ['mpg123', '-q', song_url.replace('\\', '')])

            self.logger.debug("mpg321's pid is %d" % mpg321_proc.pid)
            outputQueue.put(mpg321_proc.pid)

            self.logger.debug("will block here")

            mpg321_proc.wait()

            self.logger.debug("mpg321 stopped: returncode=%d" %
                              mpg321_proc.returncode)

            if mpg321_proc.returncode != -signal.SIGKILL:  # not stop

                self.logger.info("play next song")
                try:
                    os.kill(main_pid, signal.SIGUSR1)
                    self.logger.debug("send SIGUSR1 to %d" % main_pid)
                except OSError:
                    pass

    def __play(self):

        if self.current_song_index in range(len(self.play_list)):

            song_url = self.play_list[self.current_song_index]['url']

            self.inputQueue.put((song_url, self.pid))
            self.mpg321_pid = self.outputQueue.get()

        else:
            self.logger.debug("invalid song index %d" %
                              self.current_song_index)

    def __stop(self):

        self.logger.debug("current mpg321 pid is %d" % self.mpg321_pid)

        try:
            os.kill(self.mpg321_pid, signal.SIGKILL)
        except OSError:
            self.logger.debug("failed to kill mpg123 process, signal %d" %
                              signal.SIGKILL)

        self.logger.debug("stop at index: %d" % self.current_song_index)

    def __pause(self):

        self.logger.debug("current mpg321 pid is %d" % self.mpg321_pid)

        try:
            os.kill(self.mpg321_pid, signal.SIGSTOP)
        except OSError:
            self.logger.debug("failed to kill mpg123 process, signal: %d" %
                              signal.SIGSTOP)

    def __get_next_song(self):

        self.logger.debug("playlist's len %d, current %d" %
                          (len(self.play_list), self.current_song_index))

        if self.current_song_index == -1:

            self.logger.debug("no playlist, request new")

            self.play_list = self.radioAPI.sendLongReport(
                self.channel, 0, ReportType.NEW, self.play_history)
            self.current_song_index = 0

        elif self.current_song_index >= len(self.play_list) - 1:

            self.logger.debug("playlist end, request new")

            self.play_list = self.radioAPI.sendLongReport(
                self.channel, self.play_list[-2:-1][0]['sid'], ReportType.PLAY,
                self.play_history)
            self.current_song_index = 0
        else:

            self.logger.debug("playlist playing, no need to request")
            self.current_song_index = self.current_song_index + 1

        self.logger.debug("playlist's len %d, next %d" %
                          (len(self.play_list), self.current_song_index))

    def playNextSong(self, signum, frame):

        self.__opCurrentSong(ReportType.END)
        self.__get_next_song()
        self.__play()

    def play(self):
        self.logger.info("play")

        if self.status == PlayerStatus.INIT:

            self.__get_next_song()
            self.__play()

        elif self.status == PlayerStatus.STOP:

            self.__play()

        elif self.status == PlayerStatus.PAUSE:
            try:
                os.kill(self.mpg321_pid, signal.SIGCONT)
            except OSError:
                pass

        self.status = PlayerStatus.PLAY

        return self.__current_song_info()

    def stop(self):
        self.logger.info("stop")

        if self.status == PlayerStatus.PLAY or self.status == PlayerStatus.PAUSE:

            self.__stop()
            self.status = PlayerStatus.STOP

    def pause(self):
        self.logger.info("pause")

        self.__pause()
        self.status = PlayerStatus.PAUSE

    def toggle(self):
        self.logger.info("toggle")

        if self.status == PlayerStatus.PLAY:
            self.pause()
        else:
            self.play()

    def skip(self):
        self.logger.info("skip")

        self.__opCurrentSong(ReportType.SKIP)

        self.__stop()
        self.__get_next_song()
        self.__play()

        return self.__current_song_info()

    def ban(self):
        self.logger.info("ban")

        self.__opCurrentSong(ReportType.BAN)

        self.__stop()
        self.__get_next_song()
        self.__play()

        return self.__current_song_info()

    def rate(self):
        self.logger.info("rate")

        self.__opCurrentSong(ReportType.RATE)

        return self.__current_song_info()

    def unrate(self):
        self.logger.info("unrate")

        self.__opCurrentSong(ReportType.UNRATE)

        return self.__current_song_info()

    def info(self):
        self.logger.info("info")

        return self.__current_song_info()

    def setch(self, ch):
        self.logger.info("setch %d" % ch)

        self.channel = ch

        self.current_song_index = -1
        del self.play_list[:]

        if self.status != PlayerStatus.STOP:
            self.__stop()

        self.__get_next_song()
        self.__play()

        return self.__current_song_info()

    def __current_song_info(self):

        if self.current_song_index in range(len(self.play_list)):

            song = self.play_list[self.current_song_index]

            return (u"Album: %s\nTitle: %s\nArtist: %s\nLike:%s\n" % (
                song['albumtitle'],
                song['title'],
                song['artist'],
                song['like'],
            )).encode('utf-8')

        return ""

    def __maintainPlayHistory(self, songId, op):

        self.play_history.append({'sid': songId, 'type': op})

        if len(self.play_history) > 20:
            del self.play_history[0]

    def __opCurrentSong(self, op):

        if self.current_song_index in range(len(self.play_list)):

            songId = self.play_list[self.current_song_index]['sid']

            self.radioAPI.sendShortReport(self.channel, songId, op)

            if op in [ReportType.END, ReportType.SKIP, ReportType.BAN]:
                self.__maintainPlayHistory(songId, op)

            if op in [ReportType.RATE, ReportType.UNRATE]:
                if op == ReportType.RATE:

                    self.play_list[self.current_song_index]['like'] = '1'

                else:

                    self.play_list[self.current_song_index]['like'] = '0'
Пример #4
0
class Player:

    def __init__(self, uid, uname, token, expire):
    
        self.logger = logging.getLogger('douban-fmd.player')

        self.channel = 0

        self.radioAPI = RadioAPI(uid, uname, token, expire)

        self.play_list = []
        self.play_history = []
        self.current_song_index = -1

        self.mpg321_pid = None

        self.status = PlayerStatus.INIT
        
        self.pid = os.getpid()
        self.logger.debug("main process pid is %d" % self.pid)
        
        self.inputQueue = multiprocessing.Queue()
        self.outputQueue = multiprocessing.Queue()
        
        self.play_proc = multiprocessing.Process(
            target=self.__call_mpg321, 
            name="douban-fmd-player", 
            args=(self.inputQueue, self.outputQueue, ))
        
        self.play_proc.start()

    def close(self):
        self.play_proc.terminate()

    def __login(self):
        pass
        
        
    def __call_mpg321(self, inputQueue, outputQueue):
    
        while True:
            song_url, main_pid = inputQueue.get()
    
            mpg321_proc = subprocess.Popen(['mpg123', '-q', song_url.replace('\\', '')])
        
            self.logger.debug("mpg321's pid is %d" % mpg321_proc.pid)     
            outputQueue.put(mpg321_proc.pid)
            
            self.logger.debug("will block here")
        
            mpg321_proc.wait() 
        
            self.logger.debug("mpg321 stopped: returncode=%d" % mpg321_proc.returncode)            
        
            if mpg321_proc.returncode != -signal.SIGKILL: # not stop
            
                self.logger.info("play next song")
                try:
                    os.kill(main_pid, signal.SIGUSR1) 
                    self.logger.debug("send SIGUSR1 to %d" % main_pid)  
                except OSError:
                    pass  
    
    
    def __play(self):                  
        
        if self.current_song_index in range(len(self.play_list)):

            song_url = self.play_list[self.current_song_index]['url']
            
            self.inputQueue.put((song_url, self.pid))
            self.mpg321_pid = self.outputQueue.get()
            
        else:
            self.logger.debug("invalid song index %d" % self.current_song_index)        
            
            
    def __stop(self):
        
        self.logger.debug("current mpg321 pid is %d" % self.mpg321_pid)
        
        try:
            os.kill(self.mpg321_pid, signal.SIGKILL)
        except OSError:
            self.logger.debug("failed to kill mpg123 process, signal %d" % signal.SIGKILL)        
                    
        self.logger.debug("stop at index: %d" % self.current_song_index)        
        
        
        
    def __pause(self):
    
        self.logger.debug("current mpg321 pid is %d" % self.mpg321_pid)
        
        try:
            os.kill(self.mpg321_pid, signal.SIGSTOP)  
        except OSError:
            self.logger.debug("failed to kill mpg123 process, signal: %d" % signal.SIGSTOP)          
            
    
    def __get_next_song(self):
    
        self.logger.debug("playlist's len %d, current %d" % (len(self.play_list), self.current_song_index))
        
        if self.current_song_index == -1:

            self.logger.debug("no playlist, request new")
            
            self.play_list = self.radioAPI.sendLongReport(
                self.channel,
                0,
                ReportType.NEW,
                self.play_history
            )
            self.current_song_index = 0

        elif self.current_song_index >= len(self.play_list)-1:

            self.logger.debug("playlist end, request new")
            
            self.play_list = self.radioAPI.sendLongReport(
                self.channel,
                self.play_list[-2:-1][0]['sid'],
                ReportType.PLAY,
                self.play_history
            )
            self.current_song_index = 0
        else:
            
            self.logger.debug("playlist playing, no need to request")
            self.current_song_index = self.current_song_index + 1 
            
        self.logger.debug("playlist's len %d, next %d" % (len(self.play_list), self.current_song_index))
              
    
    def playNextSong(self, signum, frame):
    
        self.__opCurrentSong(ReportType.END)
        self.__get_next_song()
        self.__play()  
           

    def play(self):
        self.logger.info("play")

        if self.status == PlayerStatus.INIT:
        
            self.__get_next_song()
            self.__play()
            
        elif self.status == PlayerStatus.STOP:        
            
            self.__play()

        elif self.status == PlayerStatus.PAUSE:
            try:
                os.kill(self.mpg321_pid, signal.SIGCONT)
            except OSError:
                pass

        self.status = PlayerStatus.PLAY
        
        return self.__current_song_info()
        

    def stop(self):
        self.logger.info("stop")

        if self.status == PlayerStatus.PLAY or self.status == PlayerStatus.PAUSE:            
            
            self.__stop()
            self.status = PlayerStatus.STOP
            
        


    def pause(self):
        self.logger.info("pause")
        
        self.__pause()
        self.status = PlayerStatus.PAUSE
        

    def toggle(self):
        self.logger.info("toggle")

        if self.status == PlayerStatus.PLAY:
            self.pause()
        else:
            self.play()
            

    def skip(self):
        self.logger.info("skip")

        self.__opCurrentSong(ReportType.SKIP)

        self.__stop()
        self.__get_next_song()
        self.__play()
        
        return self.__current_song_info()



    def ban(self):
        self.logger.info("ban")

        self.__opCurrentSong(ReportType.BAN)

        self.__stop()
        self.__get_next_song()
        self.__play()
        
        return self.__current_song_info()


    def rate(self):
        self.logger.info("rate")

        self.__opCurrentSong(ReportType.RATE)
        
        return self.__current_song_info()


    def unrate(self):
        self.logger.info("unrate")

        self.__opCurrentSong(ReportType.UNRATE)
        
        return self.__current_song_info()



    def info(self):
        self.logger.info("info")
        
        return self.__current_song_info()
        
           

    def setch(self, ch):
        self.logger.info("setch %d" % ch)

        self.channel = ch

        self.current_song_index = -1
        del self.play_list[:]

        if self.status != PlayerStatus.STOP:
            self.__stop()

        
        self.__get_next_song()
        self.__play()
        
        return self.__current_song_info()
    
    def __current_song_info(self):
        
        if self.current_song_index in range(len(self.play_list)):
                        
            song = self.play_list[self.current_song_index]
                        
            return (u"Album: %s\nTitle: %s\nArtist: %s\nLike:%s\n" % (
                    song['albumtitle'], 
                    song['title'], 
                    song['artist'], 
                    song['like'],
                )
            ).encode('utf-8')
            
        return "" 
        
            

    def __maintainPlayHistory(self, songId, op):

        self.play_history.append({
                'sid': songId,
                'type': op
            })

        if len(self.play_history) > 20:
            del self.play_history[0]
            

    def __opCurrentSong(self, op):

        if self.current_song_index in range(len(self.play_list)):

            songId = self.play_list[self.current_song_index]['sid']

            self.radioAPI.sendShortReport(
                    self.channel,
                    songId,
                    op
                )

            if op in [ReportType.END, ReportType.SKIP, ReportType.BAN]:
                self.__maintainPlayHistory(songId, op)
                
            if op in [ReportType.RATE, ReportType.UNRATE]:
                if op == ReportType.RATE:
                    
                    self.play_list[self.current_song_index]['like'] = '1'
                    
                else:
                
                    self.play_list[self.current_song_index]['like'] = '0'