python实现在线音乐播放器(懒皮鼠音乐)
利用qt设计requests库实现在线音乐播放
前言
本文主要提供使用python各种库的注意事项,内容仅供参考。
提示:以下是本篇文章正文内容,下面案例可供参考
一、qt设计师设计界面
将设计的ui生成py文件
可以参照:https://blog.csdn.net/zq1391345114/article/details/120104695
二、使用步骤
1.引入库
代码如下(示例):
from PySide2.QtWidgets import QApplication,QWidget
from PySide2.QtCore import QTimer#定时器
from PySide2.QtGui import QColor,QIcon
import os
import re
import requests
import json
import urllib
from ui_ma import Ui_Form
from PySide2.QtWidgets import QMessageBox
2.读入数据
代码如下(示例):
def __init__(self):
#if not os.path.exists('data'):#判断文件夹是否存在
os.makedirs('data\music',exist_ok=True)
super().__init__()
# 使用ui文件导入定义界面类
self.ui = Ui_Form()
# 初始化界面
self.ui.setupUi(self)
该处省略绑定使用界
3.控件信号函数绑定相应槽函数
代码如下(示例):
self.ui.pushButton.clicked.connect(self.sousuo)#sousuo不可以带括号否则调试调用
self.ui.pushButton_2.clicked.connect(self.my_love)
self.ui.pushButton_3.clicked.connect(self.xiazai)
self.ui.pushButton_4.clicked.connect(lambda :self.xia(0))
self.ui.pushButton_5.clicked.connect(lambda :self.shang(0))
self.ui.pushButton_6.clicked.connect(self.no_love)
self.ui.pushButton_7.clicked.connect(lambda: self.shang(1))
self.ui.pushButton_8.clicked.connect(lambda: self.xia(1))
self.ui.pushButton_9.clicked.connect(self.exit)
self.ui.lineEdit.returnPressed.connect(self.sousuo)
"""************************************************"""
self.ui.listWidget_2.currentItemChanged.connect(self.change)#列表选中行修改信号
self.ui.listWidget.currentItemChanged.connect(self.change)
self.ui.listWidget.itemClicked.connect(lambda: self.bofang(0)) # 单击播放
#self.ui.listWidget.itemDoubleClicked.connect(self.my_love) # 双击喜欢
#self.ui.listWidget_2.setCurrentRow(0)
#self.ui.listWidget_2.itemDoubleClicked.connect(self.no_love)#双击取消收藏
self.ui.listWidget_2.itemPressed.connect(lambda: self.bofang(1)) # 单击播放
提示:该处使用了lambda表达式表示匿名函数传参数
4.搜索获取音乐链接并播放
在各个音乐网站获取歌曲播放链接及时长,采用定时的方式播放下一曲音乐,这里是采用qt中的QwebEngineView实现在线播放
代码如下(示例):
def bofang(self,m):
if m==0:
self.ui.web.setUrl("")#暂停第二界面播放
i = self.ui.listWidget.currentRow() # 获取选中序号
m, s = self.music[i][2].strip().split(":")
Time = int(m) * 60 + int(s) # 获取歌曲时长
rid = self.music[i][1]
url = self.huoqu(rid)
self.ui.webview.setUrl(url)
self.timer = QTimer()
#timer.stop()
self.timer.timeout.connect(lambda:self.xia(0))#定时器绑定函数
#timer.setSingleShot(True)#设置单次定时
#QTimer.singleShot((Time+1)*1000, self.xia)#定时器
self.timer.start((Time+2)*1000)#启动或重新启动定时器
else:
self.ui.webview.setUrl("")#暂停第一界面播放
i = self.ui.listWidget_2.currentRow() # 获取选中序号
m, s = self.mylove[i][2].strip().split(":")
Time = int(m) * 60 + int(s) # 获取歌曲时长
rid = self.mylove[i][1]
url = self.huoqu(rid)
self.ui.web.setUrl(url)
self.timer = QTimer()
self.timer.timeout.connect(lambda:self.xia(1)) # 定时器绑定函数
self.timer.start((Time + 2) * 1000) # 启动或重新启动定时器
这里可以看到
这里注意我注释了很多代码,他们都是不能正常之执行的。
我的本意是设置定时,歌曲播放完成后自动播放下一曲。那么有以下方法:
- sleep睡眠机制,很显然是行不通的,程序睡眠,歌曲也就不能播放。
- 多线程机制sleep单个线程,pyqt是不允许多线程机制的,我百度了下早期的python会直接报错,但是我这里没有报错,即使不用sleep睡眠,程序也会直接卡死。但是创建的子线程能够正常输出结果。
- threading定时器,这个定时器的原理也是创建一个子线程,所以它仍然不可用。
- QTimer定时器,它是pyqt中的定时器,可用。在我的代码中有注释掉一个QTimer,是因为他是一个成员变量,当点下一曲后上一个定时器还存在,所以后面就会出现歌曲没有播放完就下一曲的情况,解决方法是采用类变量。所有定时器共用一个内存。
其次播放过程中实现动态突出正在播放的歌曲那么就要采用currentItemChanged信号
def change(self,item2,item1):
item2.setBackgroundColor(QColor("red"))#设置选中行背景颜色
if item1:
item1.setBackgroundColor(QColor(0,0,0,0)) # 设置选中行背景颜色
这里设置了判断上一个item是否被选中。
## 5.下载
代码如下(示例):
def xiazai(self):
i = self.ui.listWidget.currentRow() # 获取选中序号
rid =self.music[i][1]
downloadurl=self.huoqu(rid) # 根据rid获取url
try:
urllib.request.urlretrieve(url=downloadurl, filename='data/music/{}.mp3'.format(self.music[i][0]))
QMessageBox.information(self,"消息", "下载成功.")
except:
QMessageBox.information(self,"消息", "下载错误,产生异常.")
提示:这里下载路径不存在就会下载失败,所以我们在开始就要判断下载路径是否存在,不存在就要利用代码os.makedirs('data\music',exist_ok=True)
新建。
完整代码
提示:源码仅供参考。
from PySide2.QtWidgets import QApplication,QWidget
from PySide2.QtCore import QTimer#定时器
from PySide2.QtGui import QColor,QIcon
import os
import re
import requests
import json
import urllib
from ui_ma import Ui_Form
from PySide2.QtWidgets import QMessageBox
class MainWindow(QWidget):
music={}
mylove={}
def __init__(self):
#if not os.path.exists('data'):#判断文件夹是否存在
os.makedirs('data\music',exist_ok=True)
super().__init__()
# 使用ui文件导入定义界面类
self.ui = Ui_Form()
# 初始化界面
self.ui.setupUi(self)
self.shuaxin()
# 使用界面定义的控件,也是从ui里面访问
self.ui.pushButton.clicked.connect(self.sousuo)#sousuo不可以带括号否则调试调用
self.ui.pushButton_2.clicked.connect(self.my_love)
self.ui.pushButton_3.clicked.connect(self.xiazai)
self.ui.pushButton_4.clicked.connect(lambda :self.xia(0))
self.ui.pushButton_5.clicked.connect(lambda :self.shang(0))
self.ui.pushButton_6.clicked.connect(self.no_love)
self.ui.pushButton_7.clicked.connect(lambda: self.shang(1))
self.ui.pushButton_8.clicked.connect(lambda: self.xia(1))
self.ui.pushButton_9.clicked.connect(self.exit)
self.ui.lineEdit.returnPressed.connect(self.sousuo)
"""************************************************"""
self.ui.listWidget_2.currentItemChanged.connect(self.change)#列表选中行修改信号
self.ui.listWidget.currentItemChanged.connect(self.change)
self.ui.listWidget.itemClicked.connect(lambda: self.bofang(0)) # 单击播放
#self.ui.listWidget.itemDoubleClicked.connect(self.my_love) # 双击喜欢
#self.ui.listWidget_2.setCurrentRow(0)
#self.ui.listWidget_2.itemDoubleClicked.connect(self.no_love)#双击取消收藏
self.ui.listWidget_2.itemPressed.connect(lambda: self.bofang(1)) # 单击播放
def change(self,item2,item1):
item2.setBackgroundColor(QColor("red"))#设置选中行背景颜色
if item1:
item1.setBackgroundColor(QColor(0,0,0,0)) # 设置选中行背景颜色
def exit(self):
self.ui.webview.setUrl("")
self.ui.web.setUrl("")
self.timer.stop()
def no_love(self):
i=self.ui.listWidget_2.currentRow()
for j in range(len(self.mylove)-i-1):
self.mylove[i]=self.mylove[i+1]
i+=1
del self.mylove[i]
s=open("data/my_love(保存收藏音乐信息,请勿随意修改).txt","w")
for j in range(len(self.mylove)):
s.write(str(self.mylove[j]))
s.close()
self.shuaxin()
def my_love(self):
i = self.ui.listWidget.currentRow() # 获取选中序号
j=len(self.mylove)
self.mylove[j]=self.music[i]
s=open("data/my_love(保存收藏音乐信息,请勿随意修改).txt",'a')
s.write(str(self.music[i]))
s.close()
self.ui.listWidget_2.addItem('【{}】'.format(j+1) + self.mylove[j][0])
def shuaxin(self):
self.ui.listWidget_2.clear()
if os.path.exists("data/my_love(保存收藏音乐信息,请勿随意修改).txt"):
s=open("data/my_love(保存收藏音乐信息,请勿随意修改).txt",'r')
content=s.read()
s.close()
p = re.compile(r'\[.*?\]')
i=0
for one in p.findall(content):
self.mylove[i]=eval(one)#将字符串转换成列表
self.ui.listWidget_2.addItem('【{}】'.format(i + 1)+self.mylove[i][0])
i+=1
def sousuo(self): # 获取下载rid
musicname = self.ui.lineEdit.text()
encodename = urllib.parse.quote(musicname) # 对字符串进行编码
url = 'https://www.kuwo.cn/api/www/search/searchMusicBykeyWord'
headers = {
"Cookie": "Hm_lvt_cdb524f42f0ce19b169a8071123a4797=1611813721; _ga=GA1.2.1711987833.1611813721; _gid=GA1.2.1936491096.1611813721; Hm_lpvt_cdb524f42f0ce19b169a8071123a4797=1611813751; _gat=1; kw_token=AMJKSZZ014",
"csrf": "AMJKSZZ014", "Host": "www.kuwo.cn",
"Referer": "http://www.kuwo.cn/search/list?key={}".format(encodename),
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36 Edg/88.0.705.53", }
data = {"key": "{}".format(musicname), 'pn': 1, "rn": 30, "httpsStatus": 1,
"reqId": " f1b198b0-612e-11eb-b682-25ec8c838219"} # 加入后会自动编码
res = requests.request('get', url, headers=headers, params=data, timeout=1)
dict = json.loads(res.text)
if dict['code'] != 200:
misicinfo = [{'name': '获取失败,请重试!', 'artist': ''}]
else:
misicinfo = dict['data']['list']
self.ui.listWidget.clear()
for i in range(len(misicinfo)):
name = misicinfo[i]['name'] + '-' + misicinfo[i]['artist']
self.music[i] = [name,misicinfo[i]['rid'],misicinfo[i]['songTimeMinutes']]#组建歌曲信息:名字,rid,时长
self.ui.listWidget.addItem( '【{}】'.format(i + 1) + name)
#self.ui.listWidget.setCurrentRow(0)#默认选中第一行
#self.ui.listWidget.item(1).setBackgroundColor(QColor('red'))#设置颜色
def huoqu(self,rid): # 获取url
url = 'http://www.kuwo.cn/url?'
data1 = {"format": "mp3",
"rid": "{}".format(rid),
"response": "url",
"type": "convert_url3",
"br": "128kmp3",
"from": "web",
"t": 1611821852163,
"httpsStatus": 1}
header1 = {
"User-Agent": "ozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36 Edg/88.0.705.53"}
res1 = requests.get(url, headers=header1, params=data1, timeout=1)
return json.loads(res1.text)['url']
def xiazai(self):
i = self.ui.listWidget.currentRow() # 获取选中序号
rid =self.music[i][1]
downloadurl=self.huoqu(rid) # 根据rid获取url
try:
urllib.request.urlretrieve(url=downloadurl, filename='data/music/{}.mp3'.format(self.music[i][0]))
QMessageBox.information(self,"消息", "下载成功.")
except:
QMessageBox.information(self,"消息", "下载错误,产生异常.")
def bofang(self,m):
if m==0:
self.ui.web.setUrl("")#暂停第二界面播放
i = self.ui.listWidget.currentRow() # 获取选中序号
m, s = self.music[i][2].strip().split(":")
Time = int(m) * 60 + int(s) # 获取歌曲时长
rid = self.music[i][1]
url = self.huoqu(rid)
self.ui.webview.setUrl(url)
self.timer = QTimer()
#timer.stop()
self.timer.timeout.connect(lambda:self.xia(0))#定时器绑定函数
#timer.setSingleShot(True)#设置单次定时
#QTimer.singleShot((Time+1)*1000, self.xia)#定时器
self.timer.start((Time+2)*1000)#启动或重新启动定时器
else:
self.ui.webview.setUrl("")#暂停第一界面播放
i = self.ui.listWidget_2.currentRow() # 获取选中序号
m, s = self.mylove[i][2].strip().split(":")
Time = int(m) * 60 + int(s) # 获取歌曲时长
rid = self.mylove[i][1]
url = self.huoqu(rid)
self.ui.web.setUrl(url)
self.timer = QTimer()
self.timer.timeout.connect(lambda:self.xia(1)) # 定时器绑定函数
self.timer.start((Time + 2) * 1000) # 启动或重新启动定时器
def xia(self,m):
if m==0:
i = self.ui.listWidget.currentRow()+1 # 获取选中序号
if i>=self.ui.listWidget.count():#判断是否是最后一曲
i=0
self.ui.listWidget.setCurrentRow(i)
else:
i=self.ui.listWidget_2.currentRow()+1
if i>=self.ui.listWidget_2.count():#判断是否是最后一曲
i=0
self.ui.listWidget_2.setCurrentRow(i)
self.bofang(m)
def shang(self,m):
if m==0:
i = self.ui.listWidget.currentRow()-1 # 获取选中序号
if i<0:#判断是否是第一曲
i=self.ui.listWidget.count()-1
self.ui.listWidget.setCurrentRow(i)#修改选中项
else:
i = self.ui.listWidget_2.currentRow() - 1 # 获取选中序号
if i < 0: # 判断是否是第一曲
i = self.ui.listWidget_2.count() - 1
self.ui.listWidget_2.setCurrentRow(i) # 修改选中项
self.bofang(m)
app = QApplication([])
mainw = MainWindow()
mainw.show()
app.exec_()
微信关注公众号懒皮鼠