实现效果如下
我们可以根据输入的关键字和音乐来源进行音乐爬取。这里我们需要通过多线程 将歌曲、歌手、歌曲url地址全都获取。核心代码如下
def run(self):
qmut.lock()
try:
global paing
global stop
global lrcs
global urls
global songs
global name
global songid
global proxies
global pic
global tryed
paing True
print( 搜索软件{} .format(type))
print( 开始搜索 )
name name
headers {
User-Agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.110.430.128 Safari/537.36 ,
X-Requested-With : XMLHttpRequest
urls []
songs []
pic []
lrcs []
pages 5
print(pages)
for a in range(0, pages):
if not stop:
urlss [ http://music.9q4.cn/ , https://defcon.cn/dmusic/ , http://www.xmsj.org/ ,
http://music.laomao.me/ ]
print (tryed)
if tryed 3:
tryed 0
url urlss[tryed]
else:
url urlss[tryed]
print (urlss[tryed])
params { input : name,
filter : name ,
type : type,
page : a
if not stop:
try:
res post(url, params, headers headers, proxies proxies)
html res.json()
for i in range(0, 10):
try:
title jsonpath(html, $..title )[i]
author jsonpath(html, $..author )[i]
url1 jsonpath(html, $..url )[i] # 取下载网址
pick jsonpath(html, $..pic )[i] # 取歌词
lrc jsonpath(html, $..lrc )[i]
print(title, author)
lrcs.append(lrc)
urls.append(url1)
pic.append(pick)
songs.append(str(title) - str(author))
except:
pass
except:
stop False
paing False
self.trigger.emit(str( finish ))
else:
self.trigger.emit(str( finish ))
else:
self.trigger.emit(str( clear ))
pass
stop False
paing False
except:
print( 爬取歌曲出错 )
self.trigger.emit(str( unfinish ))
stop False
paing False
qmut.unlock()
爬取代码写好了 我们还需要将爬取的这些音乐数据列表显示到画面中搜索页面中。代码如下
def repite(self, name, type): global tryed global paing global stop self.listwidget.clear() self.listwidget.addItem( 搜索中 ) self.listwidget.item(0).setForeground(Qt.white) try: if paing: stop True self.listwidget.clear() self.work2 PAThread() self.work2.start() self.work2.trigger.connect(self.seafinish) else: self.work2 PAThread() self.work2.start() self.work2.trigger.connect(self.seafinish) except: tryed tryed 1 get_info( https://www.kuaidaili.com/free/inha ) self.listwidget.addItem( 貌似没网了呀 (* ﹏ *)′,再试一遍吧~ ) self.listwidget.item(0).setForeground(Qt.white)
效果如下
关键字搜索音乐列表完成之后 接下来我们需要实现音乐播放功能。首先需要从爬取的url下载待播放的歌曲 这里还是通过多线程进行。核心代码如下
class WorkThread(QThread):
trigger pyqtSignal(str)
def __int__(self):
# 初始化函数
super(WorkThread, self).__init__()
# 进度条
def cbk(self, a, b, c):
回调函数
a:已经下载的数据块
b:数据块的大小
c:远程文件的大小
per 100.0 * a * b / c
if per 100:
per 100
# print ( %.2f%% % per)
self.trigger.emit(str( %.2f%% % per))
def run(self):
try:
global number
global path
global downloading
try:
proxies {
http : http://124.72.109.183:8118 ,
Shttp : http://49.85.1.79:31666
headers {
User-Agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36 ,
X-Requested-With : XMLHttpRequest }
try:
try:
try:
aq pic[num]
aqq aq.split( / )
except:
pass
if type kugou and len(aqq) - 1 6:
aqqe str(aqq[0]) str( // ) str(aqq[2]) str( / ) str(aqq[3]) str( / ) str(
400 ) str( / ) str(aqq[5]) str( / ) str(aqq[6])
print(aqqe)
elif type netease and len(aqq) - 1 4:
aqn aq.split( ? )
b ?param 500x500
aqqe (str(aqn[0]) str(b))
print(aqqe)
else:
aqqe pic[num]
req get(aqqe)
checkfile open(str(data /ls1.png ), w b )
for i in req.iter_content(100000):
checkfile.write(i)
checkfile.close()
lsfile str(data /ls1.png )
safile str(data /back.png )
draw(lsfile, safile)
except:
pass
url1 urls[num]
print(url1)
number number 1
path str(data {}.临时文件 .format(number))
headers {
User-Agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.110.430.128 Safari/537.36 ,
X-Requested-With : XMLHttpRequest
with get(url1, stream True, headers headers) as r, open(path, wb ) as file:
total_size int(r.headers[ content-length ])
content_size 0
for content in r.iter_content(chunk_size 1024):
file.write(content)
content_size len(content)
plan (content_size / total_size) * 100
# print(int(plan))
develop str(int(plan)) str( % )
self.trigger.emit(str(develop))
to downloadmusic{}.mp3 .format(songs[num])
makedirs( downloadmusic , exist_ok True)
except:
pass
try:
copyfile(path, to)
except:
pass
downloading False
self.trigger.emit(str( finish ))
except:
self.trigger.emit(str( nofinish ))
音乐播放模块
def bofang(self, num, bo):
print( 尝试进行播放 )
try:
import urllib
global pause
global songs
global music
global downloading
downloading True
self.console_button_3.setIcon(icon( fa.pause , color #F76677 , font 18))
pause False
try:
mixer.stop()
except:
pass
mixer.init()
try:
self.Timer QTimer()
self.Timer.start(500)
except:
pass
try:
self.label.setText( 正在寻找文件... )
self.work WorkThread()
self.work.start()
self.work.trigger.connect(self.display)
except:
print( 无法播放 歌曲下载错误 )
downloading False
pass
except:
sleep(0.1)
print( 播放系统错误 )
# self.next()
pass
def display(self, sd):
global pause
global songed
global urled
global lrcd
global timenum
if sd finish :
try:
if bo boing :
self.label.setText(songs[num])
elif bo boed :
self.label.setText(songed[num])
elif bo love :
self.label.setText(loves[num])
try:
pix_img QPixmap(str(data /back.png ))
pix pix_img.scaled(300, 300, Qt.KeepAspectRatio)
self.label5.setPixmap(pix)
except:
pix_img QPixmap(str(data /backdown.png ))
pix pix_img.scaled(300, 300, Qt.KeepAspectRatio)
self.label5.setPixmap(pix)
print(str(data {}.临时文件 .format(number)))
mixer.music.load(str(data {}.临时文件 .format(number))) # 载入音乐
mixer.music.play()
self.console_button_3.setIcon(icon( fa.pause , color #F76677 , font 18))
pause False
try:
mp3 str(data {}.临时文件 .format(number))
xx load(mp3)
timenum xx.info.time_secs
global start
start True
except:
print( MP3错误 播放失败 )
if bo boing :
songed.append(songs[num])
urled.append(urls[num])
picd.append(pic[num])
lrcd.append(lrcs[num])
self.listwidget2.clear()
for i in songed:
# self.listwidget.addItem(i)#将文件名添加到listWidget
self.listwidget2.addItem(i)
self.listwidget2.item(r).setForeground(Qt.white)
r r 1
else:
pass
# 播放音乐
except:
pass
elif sd nofinish :
self.label.setText( 下载错误 )
elif sd lrcfinish :
for i in lrct:
if not i r :
r r 1
else:
pass
elif sd lrcnofinish :
pass
else:
self.label.setText( 加速下载中,已完成{} .format(sd))
至此 我们的音乐播放器已经可以正常播放音乐了。
主要功能已经完成了 下面我们还可以添加一些附加功能 例如播放方式列表循环、单曲循环、随机播放 当前上一首下一首播放 播放暂停开始 音量增加减少等等。
播放模式
1 随机播放
def shui(self): global num global songs if bo boing : q int(len(songs) - 1) num int(randint(1, q)) elif bo love : q int(len(loves) - 1) num int(randint(1, q)) else: q int(len(songed) - 1) num int(randint(0, q)) try: print( 随机播放下一首 ) mixer.init() self.Timer QTimer() self.Timer.start(500) # self.Timer.timeout.connect(self.timercontorl)#时间函数 与下面的进度条和时间显示有关 if bo boing : self.label.setText(songs[num]) elif bo love : self.label.setText(loves[num]) else: self.label.setText(songed[num]) self.bofang(num, bo) # 播放音乐 except: pass
2 上一首、下一首
def last(self): global num global songs if num 0: print( 冇 ) num len(songs) - 1 else: num num - 1 try: self.bofang(num) self.label.setText(songs[num]) except: pass def next(self): print ( nexting ) global num global songs if num len(songs) - 1: print( 冇 ) num 0 else: num num 1 try: self.label.setText(songs[num]) self.bofang(num) except: print ( next error ) pass
3 单曲循环
def always(self): try: if bo boing : self.label.setText(songs[num]) else: self.label.setText(songed[num]) self.bofang(num, bo) # 播放音乐 except: pass
4 播放模式选择
def playmode(self): global play try: if play shun : play shui print( 切换到随机播放 ) self.label2.setText( 当前为随机播放 ) try: self.console_button_6.setIcon(icon( fa.random , color #3FC89C , font 18)) print( done ) except: print( none ) pass # self.left_shui.setText( 切换为单曲循环 ) elif play shui : play always print( 切换到单曲循环 ) self.label2.setText( 当前为单曲循环 ) try: self.console_button_6.setIcon(icon( fa.retweet , color #3FC89C , font 18)) print( done ) except: print( none ) # self.left_shui.setText( 切换为顺序播放 ) elif play always : play shun print( 切换到顺序播放 ) self.label2.setText( 当前为顺序播放 ) try: self.console_button_6.setIcon(icon( fa.align-center , color #3FC89C , font 18)) print( done ) except: print( none ) # self.left_shui.setText( 切换为随机播放 ) except: print( 模式选择错误 ) pass
播放暂停/开始
def pause(self): global pause if pause: try: mixer.music.unpause() except: pass self.console_button_3.setIcon(icon( fa.pause , color #3FC89C , font 18)) pause False else: try: mixer.music.pause() except: pass self.console_button_3.setIcon(icon( fa.play , color #F76677 , font 18)) pause True
音量提高/降低
def voiceup(self):
try:
print( 音量加大 )
global voice
voice 0.1
if voice 1:
voice 1
mixer.music.set_volume(voice)
k Decimal(voice).quantize(Decimal( 0.00 ))
self.label3.setText( 音量 {} .format(str(k * 100) % ))
except:
pass
def voicedown(self):
try:
print( 音量减少 )
global voice
voice - 0.1
if voice 0:
voice 0
mixer.music.set_volume(voice)
k Decimal(voice).quantize(Decimal( 0.00 ))
self.label3.setText( 音量 {} .format(str(k * 100) % ))
except:
pass
至此 这款音乐播放器就基本完成啦~ 一起来看看效果吧



