当python遇上付费音乐时,你会自己弄一个简单的音乐下载器嘛?
导语:
哈喽,哈喽~在许多音乐软件开始进行付费的模式下,大家是如何进行听歌的呢?
今天呢,小编用 python制造一个简单的音乐下载器 ,解决要下载多个音乐App和听歌需要vip的情况!
正文:
Python版本:3.7.8
相关模块:
- PyQt5模块;
- musicdl模块;
- 以及一些python自带的模块。
环境搭建:
安装Python并添加到环境变量,pip安装需要的相关模块即可。
原理简介:
这里介绍一下实现原理,先给大家看一下最终的效果:(后附运行视频展示)
首先我们安装一下必要的库文件:
pip install musicdl, pyqt5
然后初始化我们的音乐下载器界面:
'''音乐下载器GUI界面'''
class MusicdlGUI(QWidget):
def __init__(self, parent=None):
super(MusicdlGUI, self).__init__()
# 初始化
config = {'logfilepath': 'musicdl.log', 'savedir': 'downloaded', 'search_size_per_source': 2, 'proxies': {}}
self.music_api = musicdl.musicdl(config=config)
self.setWindowTitle('音乐下载器GUI界面')
self.setWindowIcon(QIcon(os.path.join(os.path.dirname(__file__), 'icon.ico')))
self.setFixedSize(900, 480)
self.initialize()
效果是这样子的:
接下来我们需要做的就是一点点往界面上添加我们需要的组件。先添加音乐下载器的搜索源相关的组件:
self.src_names = ['QQ音乐', '酷我音乐', '咪咕音乐', '千千音乐', '酷狗音乐', '网易云音乐']
self.label_src = QLabel('搜索源:')
self.check_boxes = []
for src in self.src_names:
cb = QCheckBox(src, self)
cb.setCheckState(QtCore.Qt.Checked)
self.check_boxes.append(cb)
效果如下:
然后添加搜索框:
self.label_keyword = QLabel('搜索关键字:')
self.lineedit_keyword = QLineEdit('音乐下载器GUI界面')
self.button_keyword = QPushButton('搜索')
效果如下:
接着添加进度条和搜索结果框等组件:
# 搜索结果表格
self.results_table = QTableWidget()
self.results_table.setColumnCount(7)
self.results_table.setHorizontalHeaderLabels(['序号', '歌手', '歌名', '大小', '时长', '专辑', '来源'])
self.results_table.horizontalHeader().setStyleSheet("QHeaderView::section{background:skyblue;color:black;}")
self.results_table.setEditTriggers(QAbstractItemView.NoEditTriggers)
self.results_table.setSelectionBehavior(QAbstractItemView.SelectRows)
# 鼠标右键点击的菜单
self.context_menu = QMenu(self)
self.action_download = self.context_menu.addAction('下载')
# 进度条
self.bar_download = QProgressBar(self)
self.label_download = QLabel('歌曲下载进度:')
就可以得到如下结果了:
最后,我们来实现一些必要的响应函数,比如搜索按钮:
'''搜索'''
def search(self):
self.initialize()
target_srcs_dict = {
'QQ音乐': 'qqmusic',
'酷我音乐': 'kuwo',
'咪咕音乐': 'migu',
'千千音乐': 'qianqian',
'酷狗音乐': 'kugou',
'网易云音乐': 'netease',
selected_src_names = []
for cb in self.check_boxes:
if cb.isChecked():
selected_src_names.append(cb.text())
target_srcs = [target_srcs_dict.get(name) for name in selected_src_names]
keyword = self.lineedit_keyword.text()
self.search_results = self.music_api.search(keyword, target_srcs)
count, row = 0, 0
for value in self.search_results.values():
count += len(value)
self.results_table.setRowCount(count)
for _, (key, values) in enumerate(self.search_results.items()):
for _, value in enumerate(values):
for column, item in enumerate([str(row), value['singers'], value['songname'], value['filesize'], value['duration'], value['album'], value['source']]):
self.results_table.setItem(row, column, QTableWidgetItem(item))
self.results_table.item(row, column).setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
self.music_records.update({str(row): value})
row += 1
return self.search_results
鼠标右键选中下载:
'''鼠标右键点击事件'''
def mouseclick(self):
self.context_menu.move(QCursor().pos())
self.context_menu.show()
以及下载功能:
'''下载'''
def download(self):
self.selected_music_idx = str(self.results_table.selectedItems()[0].row())
songinfo = self.music_records.get(self.selected_music_idx)
headers = Downloader(songinfo).headers
checkDir(songinfo['savedir'])
with requests.get(songinfo['download_url'], headers=headers, stream=True, verify=False) as response:
if response.status_code == 200:
total_size, chunk_size, download_size = int(response.headers['content-length']), 1024, 0
with open(os.path.join(songinfo['savedir'], songinfo['savename']+'.'+songinfo['ext']), 'wb') as fp:
for chunk in response.iter_content(chunk_size=chunk_size):