Example #1
0
class AsyncMusicPlayer(threading.Thread):
    '''Music Player.
    
    MusicPlayer가 동기적이기 때문에 이것을 비동기적으로 명령을 처리
    하기 위해서 Thread로 만듬

    외부와의 데이터 교환:
    - playlist        : 플레이 리스트
    - command_list    : 명령 수행
    '''

    def __init__(self):
        threading.Thread.__init__(self)

        # 현재 플레이 중인 Url
        self.url = ''
        # 현재 플레이 되고 있는 노래
        self.current_song = None

        # webbrowser player 인스턴스
        self.player = MusicPlayer()

        # DB
        self.store = Store()

    def run(self):
        '이 쓰레드에서 수행할 로직'

        while True:
            try:
                # 0.5초를 주기로 명령 수행
                time.sleep(0.5)

                # 광고가 나오는지 확인해서 넘긴다.
                # 보통 youtube 광고는 5초다.
                # TODO: 광고가 나오면 volume을 줄이도록 한다.
                self.player.skip_if_exists_ad()

                if self.url == '':
                    self.play_next_song()
                
                # URL이 변경되었으면 표시한다.
                url = self.player.current_url()
                if( self.url != url ):
                    self.url = url
                    # TODO:
                    #   - 여기에서 곡을 추가하는 로직을 넣으면
                    #   - 내가 듣는 링크를 플레이 리스트로 만들 수 있다.
                    print(self.url)
                    
                # 노래가 중지되면 다음 노래
                if self.player.is_finished() :

                    # played_count 수를 하나 증가 시킨다.
                    if self.current_song:
                        self.current_song.played_count += 1
                        self.store.update(self.current_song)

                    self.play_next_song()
                elif self.player.is_unplable():
                    self.play_next_song()
                self.handle_cmd();
            except queue.Empty:
                pass
            except KeyboardInterrupt:
                break
            except Exception as e:
                # 에러가 발생하면 에러의 종료를 출력
                #print('----')
                #print(type(e))
                #print(e)
                break
                

    def play_next_song(self):
        " 다음 곡 "

        # 플레이 리스트에서 하나 꺼낸다.
        playlist_lock.acquire()
        try:
            song = playlist.pop(0)
            url = song.url
        except:
            url = None
        playlist_lock.release()

        # url이 있으면 다음곡 플레이
        if url:
            self.current_song = song
            self.player.play_url(song.url)

    def stop(self):
        " 일시 정지 "
        self.player.stop()

    def play(self):
        " 다시 플레이"
        self.player.play()

    def handle_cmd(self):
        "명령 처리"
        data = command_list.get(block=False)
        if data:
            cmd, param = data
            if cmd == 'forward':
                self.play_next_song()
            elif cmd == 'stop':
                self.stop()
            elif cmd == 'play':
                self.play()
Example #2
0
class AsyncMusicPlayer(threading.Thread):
    '''Music Player.
    
    MusicPlayer가 동기적이기 때문에 이것을 비동기적으로 명령을 처리
    하기 위해서 Thread로 만듬

    외부와의 데이터 교환:
    - playlist        : 플레이 리스트
    - command_list    : 명령 수행
    '''
    def __init__(self):
        threading.Thread.__init__(self)

        # 현재 플레이 중인 Url
        self.url = ''
        # 현재 플레이 되고 있는 노래
        self.current_song = None

        # webbrowser player 인스턴스
        self.player = MusicPlayer()

        # DB
        self.store = Store()

    def run(self):
        '이 쓰레드에서 수행할 로직'

        while True:
            try:
                # 0.5초를 주기로 명령 수행
                time.sleep(0.5)

                # 광고가 나오는지 확인해서 넘긴다.
                # 보통 youtube 광고는 5초다.
                # TODO: 광고가 나오면 volume을 줄이도록 한다.
                self.player.skip_if_exists_ad()

                if self.url == '':
                    self.play_next_song()

                # URL이 변경되었으면 표시한다.
                url = self.player.current_url()
                if (self.url != url):
                    self.url = url
                    # TODO:
                    #   - 여기에서 곡을 추가하는 로직을 넣으면
                    #   - 내가 듣는 링크를 플레이 리스트로 만들 수 있다.
                    print(self.url)

                # 노래가 중지되면 다음 노래
                if self.player.is_finished():

                    # played_count 수를 하나 증가 시킨다.
                    if self.current_song:
                        self.current_song.played_count += 1
                        self.store.update(self.current_song)

                    self.play_next_song()
                elif self.player.is_unplable():
                    self.play_next_song()
                self.handle_cmd()
            except queue.Empty:
                pass
            except KeyboardInterrupt:
                break
            except Exception as e:
                # 에러가 발생하면 에러의 종료를 출력
                #print('----')
                #print(type(e))
                #print(e)
                break

    def play_next_song(self):
        " 다음 곡 "

        # 플레이 리스트에서 하나 꺼낸다.
        playlist_lock.acquire()
        try:
            song = playlist.pop(0)
            url = song.url
        except:
            url = None
        playlist_lock.release()

        # url이 있으면 다음곡 플레이
        if url:
            self.current_song = song
            self.player.play_url(song.url)

    def stop(self):
        " 일시 정지 "
        self.player.stop()

    def play(self):
        " 다시 플레이"
        self.player.play()

    def handle_cmd(self):
        "명령 처리"
        data = command_list.get(block=False)
        if data:
            cmd, param = data
            if cmd == 'forward':
                self.play_next_song()
            elif cmd == 'stop':
                self.stop()
            elif cmd == 'play':
                self.play()