Exemple #1
0
def netease_download(music):
    ''' 从网易云音乐下载 '''
    eparams = {
        'method': 'POST',
        'url': 'http://music.163.com/api/song/enhance/player/url',
        'params': {
            'ids': [music['id']],
            'br': 320000,
        }
    }
    data = {'eparams': encode_netease_data(eparams)}

    s = requests.Session()
    s.headers.update(glovar.FAKE_HEADERS)
    s.headers.update({
        'referer': 'http://music.163.com/',
    })
    if glovar.get_option('proxies'):
        s.proxies.update(glovar.get_option('proxies'))

    r = s.post('http://music.163.com/api/linux/forward', data=data)

    if r.status_code != requests.codes.ok:
        raise RequestError(r.text)
    j = r.json()
    if j['code'] != 200:
        raise ResponseError(j)

    music['url'] = j['data'][0]['url']
    music['rate'] = int(j['data'][0]['br'] / 1000)
    music['size'] = round(j['data'][0]['size'] / 1048576, 2)
    music['name'] = '%s - %s.mp3' % (music['singer'], music['title'])

    music_download(music)
Exemple #2
0
def main():
    music_list = []

    if not glovar.get_option('keyword'):
        # 如果未设置关键词
        keyword = input('请输入要搜索的歌曲,名称和歌手一起输入可以提高匹配(如 空帆船 朴树):\n > ')
        glovar.set_option('keyword', keyword)

    for source in glovar.get_option('source').split():
        try:
            echo.notice(source=source)
            music_list += addons.get(source).search(
                glovar.get_option('keyword'))
        except Exception as e:
            logger.error('Get %s music list failed.' % source.upper())
            logger.error(e)

    if glovar.get_option('merge'):
        # 对搜索结果排序和去重
        music_list = music_list_merge(music_list)

    echo.menu(music_list)
    choices = input('请输入要下载的歌曲序号,多个序号用空格隔开:')

    downloadByIndexList(choices.split(), music_list)

    # 下载完后继续搜索
    keyword = input('请输入要搜索的歌曲,或Ctrl+C退出:\n > ')
    glovar.set_option('keyword', keyword)
    main()
Exemple #3
0
def music_download(music):
    ''' 下载音乐保存到本地 '''
    echo.info(music)
    outfile = get_unique_outfile(glovar.get_option('outdir'), music['name'])
    try:
        r = requests.get(music['url'],
                         stream=True,
                         headers=glovar.WGET_HEADERS,
                         proxies=glovar.get_option('proxies'))
        total_size = int(r.headers['content-length'])
        with click.progressbar(length=total_size,
                               label='Downloading...') as bar:
            with open(outfile, 'wb') as f:
                for chunk in r.iter_content(chunk_size=1024):
                    if chunk:
                        f.write(chunk)
                        bar.update(len(chunk))
        print('已保存到:%s\n' % outfile)
    except Exception as e:
        print('')
        logger.error('下载音乐失败:')
        logger.error('URL:%s' % music['url'])
        logger.error('位置:%s\n' % outfile)
        if glovar.get_option('verbose'):
            logger.error(e)
Exemple #4
0
def music_search(source, music_list, errors):
    ''' 音乐搜索,music_list是搜索结果 '''
    try:
        addon = importlib.import_module('.' + source, 'core.extractors')
        music_list += addon.search(glovar.get_option('keyword'))
    except (RequestError, ResponseError, DataError) as e:
        errors.append((source, e))
    except Exception as e:
        err = traceback.format_exc() if glovar.get_option('verbose') else str(e)
        errors.append((source, err))
    finally:
        # 放在搜索后输出是为了营造出搜索很快的假象
        echo.brand(source=source)
Exemple #5
0
def baidu_search(keyword) -> list:
    ''' 搜索音乐 '''
    count = glovar.get_option('count') or 5
    params = {
        'query': keyword,
        'method': 'baidu.ting.search.common',
        'format': 'json',
        'page_no': 1,
        'page_size': count
    }
    s = requests.Session()
    s.headers.update(glovar.FAKE_HEADERS)
    s.headers.update({'referer': 'http://music.baidu.com/'})
    if glovar.get_option('proxies'):
        s.proxies.update(glovar.get_option('proxies'))

    music_list = []
    r = s.get('http://musicapi.qianqian.com/v1/restserver/ting', params=params)
    if r.status_code != requests.codes.ok:
        raise RequestError(r.text)
    j = r.json()

    for m in j['song_list']:
        music = {
            'title': m['title'].replace('<em>', '').replace('</em>', ''),
            'id': m['song_id'],
            'singer': m['author'].replace('<em>', '').replace('</em>', ''),
            'album': m['album_title'].replace('<em>', '').replace('</em>', ''),
            'source': 'baidu'
        }
        s.headers.update({'referer': 'http://music.baidu.com/song/' + m['song_id']})
        m_params = {'songIds': m['song_id']}
        mr = s.get('http://music.baidu.com/data/music/links', params=m_params)
        if mr.status_code != requests.codes.ok:
            raise RequestError(mr.text)
        mj = mr.json()
        if not mj['data']['songList']:
            continue
        mj_music = mj['data']['songList'][0]
        music['duration'] = str(datetime.timedelta(seconds=mj_music['time']))
        size = mj_music['size'] or 0
        music['size'] = round(size / 1048576, 2)
        music['rate'] = mj_music['rate']
        music['ext'] = mj_music['format']
        music['url'] = mj_music['songLink']
        music['name'] = '%s - %s.%s' % (mj_music['artistName'], mj_music['songName'], mj_music['format'])

        music_list.append(music)

    return music_list
Exemple #6
0
def music_download(music):
    ''' 下载音乐保存到本地 '''
    echo.info(music)
    outfile = os.path.abspath(
        os.path.join(glovar.get_option('outdir'), music['name']))
    try:
        wget.download(music['url'], out=outfile)
        print('\n已保存到:%s\n' % outfile)
    except Exception as e:
        print('')
        logger.error('下载音乐失败:')
        logger.error('URL:%s' % music['url'])
        logger.error('位置:%s\n' % outfile)
        if glovar.get_option('verbose'):
            logger.error(e)
Exemple #7
0
def xiami_search(keyword) -> list:
    ''' 搜索音乐 '''
    count = glovar.get_option('count') or 5
    params = {
        'key': keyword,
        'v': '2.0',
        'app_key': '1',
        'r': 'search/songs',
        'page': 1,
        'limit': count
    }
    s = requests.Session()
    s.headers.update(glovar.FAKE_HEADERS)
    # 获取cookie
    s.head('http://m.xiami.com')
    s.headers.update({'referer': 'http://m.xiami.com/'})
    if glovar.get_option('proxies'):
        s.proxies.update(glovar.get_option('proxies'))

    music_list = []
    r = s.get('http://api.xiami.com/web', params=params)
    if r.status_code != requests.codes.ok:
        raise RequestError(r.text)
    j = r.json()

    thread_pool = []

    for m in j['data']['songs']:
        # 如果无版权则不显示
        if not m['listen_file']: continue
        music = {
            'title': m['song_name'],
            'id': m['song_id'],
            'singer': m['artist_name'],
            'album': m['album_name'],
            'url': m['listen_file'],
            'source': 'xiami'
        }

        t = threading.Thread(target=xiami_music_info,
                             args=(music, music_list, s))
        thread_pool.append(t)
        t.start()

    for t in thread_pool:
        t.join()

    return music_list
Exemple #8
0
def music_download(music):
    ''' 下载音乐保存到本地 '''
    echo.info(music)
    outfile = os.path.abspath(
        os.path.join(glovar.get_option('outdir'), music['name']))
    wget.download(music['url'], out=outfile)
    print('\n已保存到:%s\n' % outfile)
Exemple #9
0
def info(music):
    ''' 打印歌曲信息 '''
    if not glovar.get_option('verbose'):
        return
    s = '\n ------------ \n -> 歌曲:%s\n -> 歌手:%s\n -> 时长: %s\n -> 大小: %s\n -> 比特率: %s\n -> URL: %s\n' % \
        (music['title'], music['singer'], music['duration'], music['size'], music['rate'], music['url'])
    print(s)
Exemple #10
0
def xiami_search(keyword) -> list:
    ''' 搜索音乐 '''
    count = glovar.get_option('count') or 5
    params = {
        'key': keyword,
        'v': '2.0',
        'app_key': '1',
        'r': 'search/songs',
        'page': 1,
        'limit': count
    }
    s = requests.Session()
    s.headers.update(glovar.FAKE_HEADERS)
    # 获取cookie
    s.get('http://m.xiami.com')
    s.headers.update({'referer': 'http://m.xiami.com/'})

    music_list = []
    r = s.get('http://api.xiami.com/web', params=params)
    if r.status_code != requests.codes.ok:
        raise RequestError(r.text)
    j = r.json()

    for m in j['data']['songs']:
        # 如果无版权则不显示
        if not m['listen_file']: continue
        music = {
            'title': m['song_name'],
            'id': m['song_id'],
            'singer': m['artist_name'],
            'album': m['album_name'],
            'url': m['listen_file'],
            'source': 'xiami'
        }

        mr = s.get('http://www.xiami.com/song/playlist/id/%s/type/0/cat/json' %
                   m['song_id'])
        if mr.status_code != requests.codes.ok:
            raise RequestError(mr.text)
        mj = mr.json()
        mj_music = mj['data']['trackList'][0]
        music['duration'] = str(datetime.timedelta(seconds=mj_music['length']))
        music['rate'] = 128
        music['ext'] = 'mp3'
        music['name'] = '%s - %s.%s' % (music['singer'], music['title'],
                                        music['ext'])

        # 尝试获取虾米高品质音乐(320K)
        url = music['url'].replace('m128.xiami.net', 'm320.xiami.net')
        size = content_length(url)
        if size:
            music['size'] = round(size / 1048576, 2)
            music['url'] = url
            music['rate'] = 320
        else:
            music['size'] = round(content_length(music['url']) / 1048576, 2)

        music_list.append(music)

    return music_list
Exemple #11
0
def qq_search(keyword) -> list:
    ''' 搜索音乐 '''
    count = glovar.get_option('count') or 5
    params = {'w': keyword, 'format': 'json', 'p': 1, 'n': count}
    s = requests.Session()
    s.headers.update(glovar.FAKE_HEADERS)
    s.headers.update({
        'referer': 'http://m.y.qq.com',
        'User-Agent': glovar.IOS_USERAGENT
    })
    if glovar.get_option('proxies'):
        s.proxies.update(glovar.get_option('proxies'))

    music_list = []
    r = s.get('http://c.y.qq.com/soso/fcgi-bin/search_for_qq_cp',
              params=params)
    if r.status_code != requests.codes.ok:
        raise RequestError(r.text)
    j = r.json()
    if j['code'] != 0:
        raise ResponseError(j)

    for m in j['data']['song']['list']:
        # 获得歌手名字
        singers = []
        for singer in m['singer']:
            singers.append(singer['name'])

        # size = m['size320'] or m['size128']
        size = m['size128']
        music = {
            'title': m['songname'],
            'id': m['songid'],
            'mid': m['songmid'],
            'duration': str(datetime.timedelta(seconds=m['interval'])),
            'singer': '、'.join(singers),
            'album': m['albumname'],
            # 'ext': m['ExtName'],
            'size': round(size / 1048576, 2),
            'source': 'qq'
        }

        music_list.append(music)

    return music_list
Exemple #12
0
def main():
    music_list = []
    thread_pool = []
    errors = []

    if not glovar.get_option('keyword'):
        # 如果未设置关键词
        keyword = input('请输入要搜索的歌曲,名称和歌手一起输入可以提高匹配(如 空帆船 朴树):\n > ')
        glovar.set_option('keyword', keyword)

    echo.notice(glovar.get_option('keyword'))

    for source in glovar.get_option('source').split():
        t = threading.Thread(target=music_search, args=(source, music_list, errors))
        thread_pool.append(t)
        t.start()

    for t in thread_pool:
        t.join()

    echo.line()

    for err in errors:
        logger.error('Get %s music list failed.' % err[0].upper())
        logger.error(err[1])

    if glovar.get_option('merge'):
        # 对搜索结果排序和去重
        music_list = music_list_merge(music_list)

    echo.menu(music_list)
    choices = input('请输入要下载的歌曲序号,多个序号用空格隔开:')

    for choice in choices.split():
        start, _, end = choice.partition('-')
        if end:
            for i in range(int(start), int(end)+1):
                music_download(i, music_list)
        else:
            music_download(start, music_list)

    # 下载完后继续搜索
    keyword = input('请输入要搜索的歌曲,或Ctrl+C退出:\n > ')
    glovar.set_option('keyword', keyword)
    main()
Exemple #13
0
def netease_search(keyword) -> list:
    ''' 从网易云音乐搜索 '''
    count = glovar.get_option('count') or 5
    eparams = {
        'method': 'POST',
        'url': 'http://music.163.com/api/cloudsearch/pc',
        'params': {
            's': keyword,
            'type': 1,
            'offset': 0,
            'limit': count
        }
    }
    data = {'eparams': encode_netease_data(eparams)}

    s = requests.Session()
    s.headers.update(glovar.FAKE_HEADERS)
    s.headers.update({
        'referer': 'http://music.163.com/',
    })
    r = s.post('http://music.163.com/api/linux/forward', data=data)

    if r.status_code != requests.codes.ok:
        raise RequestError(r.text)
    j = r.json()
    if j['code'] != 200:
        raise ResponseError(j)

    music_list = []
    for m in j['result']['songs']:
        if m['privilege']['fl'] == 0:
            # 没有版权
            continue
        # 获得歌手名字
        singers = []
        for singer in m['ar']:
            singers.append(singer['name'])
        # 获得最优音质的文件大小
        if m['privilege']['fl'] >= 320000:
            size = m['h']['size']
        elif m['privilege']['fl'] >= 192000:
            size = m['m']['size']
        else:
            size = m['l']['size']

        music = {
            'title': m['name'],
            'id': m['id'],
            'duration': str(datetime.timedelta(seconds=int(m['dt']/1000))),
            'singer': '、'.join(singers),
            'album': m['al']['name'],
            'size': round(size / 1048576, 2),
            'source': 'netease'
        }
        music_list.append(music)

    return music_list
Exemple #14
0
def music_search(source, music_list, errors):
    ''' 音乐搜索,music_list是搜索结果 '''
    try:
        music_list += addons.get(source).search(glovar.get_option('keyword'))
    except Exception as e:
        errors.append((source, e))
    finally:
        # 放在搜索后输出是为了营造出搜索很快的假象
        echo.brand(source=source)
Exemple #15
0
def music_download(idx, music_list):
    ''' 音乐下载,music_list是搜索结果 '''
    music = music_list[int(idx)]
    try:
        addon = importlib.import_module('.' + music['source'], 'core.extractors')
        addon.download(music)
    except Exception as e:
        logger.error('下载音乐失败')
        err = traceback.format_exc() if glovar.get_option('verbose') else str(e)
        logger.error(err)
Exemple #16
0
def main():
    music_list = []
    thread_pool = []
    errors = []

    if not glovar.get_option('keyword'):
        # 如果未设置关键词
        cli.set_music_keyword('请输入要搜索的歌曲,名称和歌手一起输入可以提高匹配(如 空帆船 朴树):\n > ')

    echo.notice(glovar.get_option('keyword'))

    # 多线程搜索
    for source in glovar.get_option('source').split():
        t = threading.Thread(target=music_search,
                             args=(source, music_list, errors))
        thread_pool.append(t)
        t.start()
    for t in thread_pool:
        t.join()

    # 分割线
    echo.line()
    # 输出错误信息
    for err in errors:
        logger.error('Get %s music list failed.' % err[0].upper())
        logger.error(err[1])

    if glovar.get_option('merge'):
        # 对搜索结果排序和去重
        music_list = music_list_merge(music_list)

    echo.menu(music_list)

    selected = cli.get_music_select()
    for idx in selected:
        music_download(idx, music_list)

    # 下载完后继续搜索
    cli.set_music_keyword()
    main()
Exemple #17
0
def qq_download(music):
    ''' 根据songmid等信息获得下载链接 '''
    # 计算vkey
    guid = str(random.randrange(1000000000, 10000000000))
    params = {'guid': guid, 'format': 'json', 'json': 3}
    s = requests.Session()
    s.headers.update(glovar.FAKE_HEADERS)
    s.headers.update({
        'referer': 'http://y.qq.com',
        'User-Agent': glovar.IOS_USERAGENT
    })
    if glovar.get_option('proxies'):
        s.proxies.update(glovar.get_option('proxies'))

    r = s.get('http://base.music.qq.com/fcgi-bin/fcg_musicexpress.fcg',
              params=params)
    if r.status_code != requests.codes.ok:
        raise RequestError(r.text)
    j = r.json()
    if j['code'] != 0:
        raise ResponseError(j)

    vkey = j['key']

    for prefix in ['M800', 'M500', 'C400']:
        url = 'http://dl.stream.qqmusic.qq.com/%s%s.mp3?vkey=%s&guid=%s&fromtag=1' % \
              (prefix, music['mid'], vkey, guid)
        size = content_length(url)
        if size > 0:
            music['url'] = url
            music['rate'] = 320 if prefix == 'M800' else 128
            music['size'] = round(size / 1048576, 2)
            break

    music['name'] = '%s - %s.mp3' % (music['singer'], music['title'])

    music_download(music)
Exemple #18
0
def kugou_search(keyword) -> list:
    ''' 搜索音乐 '''
    count = glovar.get_option('count') or 5
    params = {
        'keyword': keyword,
        'platform': 'WebFilter',
        'format': 'json',
        'page': 1,
        'pagesize': count
    }
    s = requests.Session()
    s.headers.update(glovar.FAKE_HEADERS)
    s.headers.update({'referer': 'http://www.kugou.com'})

    music_list = []
    r = s.get('http://songsearch.kugou.com/song_search_v2', params=params)
    if r.status_code != requests.codes.ok:
        raise RequestError(r.text)
    j = r.json()
    if j['status'] != 1:
        raise ResponseError(j)

    for m in j['data']['lists']:
        music = {
            'title': m['SongName'],
            'id': m['Scid'],
            'hash': m['FileHash'],
            'duration': str(datetime.timedelta(seconds=m['Duration'])),
            'singer': m['SingerName'],
            'album': m['AlbumName'],
            # 'ext': m['ExtName'],
            'size': round(m['FileSize'] / 1048576, 2),
            'source': 'kugou'
        }
        # 如果有更高品质的音乐选择高品质(尽管好像没什么卵用)
        if m['SQFileHash'] and m[
                'SQFileHash'] != '00000000000000000000000000000000':
            music['hash'] = m['SQFileHash']
        elif m['HQFileHash'] and m[
                'HQFileHash'] != '00000000000000000000000000000000':
            music['hash'] = m['HQFileHash']

        music_list.append(music)

    return music_list