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 __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()
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'
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'