예제 #1
0
    def _play_from_playlist(self, song_list):
        if self.playing == True:
            self.interrupt = True
            self.player.terminate()

        self.playing = True
        self.player = mpv.MPV(ytdl=True)

        for song in song_list:
            if song['source'] == 'migu':
                url = song['url']
            elif song['source'] == 'qq':
                url = QQMusicApi().get_url(song['song_mid'])
            elif song['source'] == 'netease':
                url = NeteaseCloudMusicAPI().get_url(song['song_mid'])
            if url == '':
                print('You need {} vip to listen {}.'.format(
                    song['source'], song['song_name']))
                continue

            self.event_pl = threading.Event()
            play_thread = threading.Thread(target=self.__play_pl_base,
                                           args=(url, ))
            play_thread.start()
            self.current_song = song
            self.event_pl.wait()

            # interrupt by playing search
            if self.interrupt == True:
                self.interrupt = False
                return

        self.playing = False
        self.player.terminate()
예제 #2
0
    def _play_from_search(self, song):
        # song url
        if song['source'] == 'migu':
            url = song['url']
        elif song['source'] == 'qq':
            url = QQMusicApi().get_url(song['song_mid'])
        elif song['source'] == 'netease':
            url = NeteaseCloudMusicAPI().get_url(song['song_mid'])

        # check url
        if url == '':
            print('You need {} vip to listen {}.'.format(
                self.search_result['source'], play_song['song_name']))
            return

        # player is occupied by playing pl
        if self.playing == True:
            self.interrupt = True
            self.player.terminate()
        self.playing = True

        self.player = mpv.MPV(ytdl=True)
        self.event_s = threading.Event()
        play_thread = threading.Thread(target=self.__play_search_base,
                                       args=(url, ))
        play_thread.start()
        self.current_song = song
        self.event_s.wait()

        if self.interrupt == True:
            self.interrupt = False
            return

        self.playing = False
        self.player.terminate()
예제 #3
0
 def do_cs(self, arg):
     ''' change search source
     arg must be in 'qq', 'netease', 'migu'
     '''
     if arg == '':
         # stay current api
         return
     if arg == 'qq':
         self.api = QQMusicApi()
         print('Source is changed to qq music.')
     elif arg == 'netease':
         self.api = NeteaseCloudMusicAPI()
         print('Source is changed to netease cloud music.')
     elif arg == 'migu':
         self.api = MiguMusicAPI()
         print('Source is changed to migu music.')
     else:
         print('Music source must be in qq, netease or migu.')
예제 #4
0
    def _play_music(self, qtree_item):
        ''' double click or right mouse button to play music
        If local exists, find the local path,
        if not, download according to song mid
        '''

        # pause music player
        self.pause_signal.emit()
        self.parent.player.song_info.setText('加载中...')

        song_name = qtree_item.text(0)
        song_mid = qtree_item.text(4)
        source = qtree_item.text(6)

        local_exist = False
        for music_file in os.listdir(self.music_dir):
            if song_mid in music_file:
                music_path = os.path.join(self.music_dir, music_file)
                local_exist = True

        if not local_exist:
            if source == 'qq':
                api = QQMusicApi()
            elif source == 'netease':
                api = NeteaseCloudMusicAPI()

            if source != 'migu':
                url = api.get_url(song_mid)
                if url is None:
                    self.parent.player.song_info.setText('该歌曲需要vip')
                    return
            else:  # if migu, qtreeitem.text(5) is url
                url = qtree_item.text(5)
            music_path = 'userdata/music/{}_{}.m4a'.format(song_name, song_mid)
            urllib.request.urlretrieve(url, music_path)

        self.play_global_signal.emit(qtree_item, music_path, self.display_mode)
예제 #5
0
    def next_song(self, direction=None):
        ''' when current music play end, continue to next song '''

        if self.current_music == None:
            return

        index = self.play_list.index(self.current_music)
        # next song mid
        if direction == 'next' or direction is None:
            if index == len(self.play_list) - 1:
                next_song_dict = self.play_list[0]
            else:
                next_song_dict = self.play_list[index + 1]
        elif direction == 'prev':
            if index == 0:
                next_song_dict = self.play_list[len(self.play_list) - 1]
            else:
                next_song_dict = self.play_list[index - 1]
        else:
            raise valueError('direction error.')

        self.pause()
        self.slider.setValue(0)

        # if local exists
        for music_file in os.listdir('userdata/music'):
            if next_song_dict['song_mid'] in music_file:
                next_path = os.path.join('userdata/music', music_file)
                self.player.setMedia(
                    QMediaContent(QUrl.fromLocalFile(next_path)))
                self.play()

                # get true interval
                media_info = json.loads(
                    MediaInfo.parse(next_path).to_json())['tracks'][0]
                interval = convert_interval(
                    math.floor(media_info['duration'] / 1000))

                # set song name, singer, interval display
                if next_song_dict['singers'] != '':
                    self.song_info.setText(next_song_dict['song_name'] + '-' +
                                           next_song_dict['singers'])
                else:
                    self.song_info.setText(next_song_dict['song_name'])
                self.time.setText(self.time.text().split('/')[0] + '/' +
                                  interval)
                self.current_music = next_song_dict

                iterator = QTreeWidgetItemIterator(
                    self.parent.main_list.music_list)
                while iterator.value():
                    item = iterator.value()
                    if item.text(4) == next_song_dict['song_mid']:
                        self.parent.main_list.music_list.setCurrentItem(item)
                        break
                    iterator.__iadd__(1)
                return

        # local not exists, download according to song mid
        if next_song_dict['source'] == 'migu':
            url = next_song_dict['url']
        elif next_song_dict['source'] == 'qq':
            url = QQMusicApi().get_url(next_song_dict['song_mid'])
        elif next_song_didct['source'] == 'netease':
            url = NeteaseCloudMusicAPI().get_url(next_song_dict['song_mid'])

        next_path = 'userdata/music/{}_{}.m4a'.format(
            next_song_dict['song_name'], next_song_dict['song_mid'])
        urllib.request.urlretrieve(url, next_path)
        self.player.setMedia(QMediaContent(QUrl.fromLocalFile(next_path)))
        self.play()

        # get true interval
        media_info = json.loads(
            MediaInfo.parse(next_path).to_json())['tracks'][0]
        interval = convert_interval(math.floor(media_info['duration'] / 1000))

        # set song name, singer, interval display
        if next_song_dict['singers'] != '':
            self.song_info.setText(next_song_dict['song_name'] + '-' +
                                   next_song_dict['singers'])
        else:
            self.song_info.setText(next_song_dict['song_name'])
        self.time.setText(self.time.text().split('/')[0] + '/' + interval)
        self.current_music = next_song_dict

        iterator = QTreeWidgetItemIterator(self.parent.main_list.music_list)
        while iterator.value():
            item = iterator.value()
            if item.text(4) == next_song_dict['song_mid']:
                self.parent.main_list.music_list.setCurrentItem(item)
                break
            iterator.__iadd__(1)
예제 #6
0
    def search(self):
        self.parent.main_list.music_list.clear()
        self.parent.navigation.local_list.setCurrentItem(None)
        self.parent.navigation.play_list.setCurrentItem(None)

        self.parent.main_list.display_mode = 'global'

        keywords = self.search_line.text()
        if keywords == '':
            return

        if self.music_source == 'qq':
            self.parent.navigation.navigation_list.setCurrentRow(0)
            api = QQMusicApi()
        elif self.music_source == 'netease':
            self.parent.navigation.navigation_list.setCurrentRow(1)
            api = NeteaseCloudMusicAPI()
        elif self.music_source == 'migu':
            self.parent.navigation.navigation_list.setCurrentRow(2)
            api = MiguMusicAPI()
        else:
            raise ValueError(
                'music sources only contain qq, netease and migu.')

        search_result = []
        if api.name == 'qq':
            for page in [1, 2]:
                search_result += api.search(page, keywords)
        elif api.name == 'netease':
            search_result += api.search(keywords, 1)
        elif api.name == 'migu':
            search_result += api.search(keywords)
        else:
            raise ValueError('api.name not in qq, netease and migu')

        for item in search_result:
            qt_item = QTreeWidgetItem()
            qt_item.setText(0, item['song_name'])

            if api.name == 'migu':
                singers = item['singer_list']
            else:
                singers = ''
                for singer in item['singer_list']:
                    singers += singer
                    singers += '/'
                singers = singers.strip('/')

            qt_item.setText(1, singers)
            qt_item.setText(2, item['album_name'])

            if api.name == 'migu':
                qt_item.setText(3, '')
            else:
                qt_item.setText(3, convert_interval(item['interval']))

            qt_item.setText(4, str(item['song_mid']))

            if api.name == 'migu':
                qt_item.setText(5, item['url'])
            else:
                qt_item.setText(5, '')
            qt_item.setText(6, api.name)

            self.parent.main_list.music_list.addTopLevelItem(qt_item)
예제 #7
0
from flask import Flask, redirect, url_for, request
from api import MiguMusicAPI, NeteaseCloudMusicAPI, QQMusicApi

API_DICT = {
    'qq': QQMusicApi(),
    'netease': NeteaseCloudMusicAPI(),
    'migu': MiguMusicAPI()
}

app = Flask(__name__)


@app.route('/')
def main():
    return redirect(url_for('music'))


@app.route('/music')
def music():
    return 'Welcome to BowenMusic'


@app.route('/music/search', methods=['GET', 'POST'])
def search():
    if request.method == 'GET':
        api = request.args.get('api')
        keywords = request.args.get('keywords')
    elif request.method == 'POST':
        api = request.form.get('api')
        keywords = request.form.get('keywords')