python 基於wx實現音樂播放
阿新 • • 發佈:2020-11-26
# -*- coding: utf-8 -*- """ Created on Sat Apr 25 18:15:36 2020 @author: Administrator """ import requests import binascii import json import datetime import traceback from Crypto.Cipher import AES from tkinter import * FAKE_HEADERS = { 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',# noqa 'Accept-Charset': 'UTF-8,*;q=0.5','Accept-Encoding': 'gzip,deflate,sdch','Accept-Language': 'en-US,en;q=0.8','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:60.0) Gecko/20100101 Firefox/60.0',# noqa 'referer': 'https://www.google.com' } def netease_search(keyword) -> list: ''' 從網易雲音樂搜尋 ''' count = 30 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(FAKE_HEADERS) s.headers.update({ 'referer': 'http://music.163.com/',}) r = s.post('http://music.163.com/api/linux/forward',data=data) j = r.json() music_list = [] ID=0 try: 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 and 'h' in m.keys() and m['h']: # 有時候即使>=320000,h屬性依然為None size = m['h']['size'] elif m['privilege']['fl'] >= 192000 and 'm' in m.keys() and m['m']: 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=[] print(m['name']) music.append(ID) music.append(m['name']) music.append('、'.join(singers)) href="http://music.163.com/song/media/outer/url?id=" rel="external nofollow" +str(m['id'])+".mp3" print(href) music.append(href) music.append(m['id']) music_list.append(music) ID=ID+1 except Exception: # 如果是詳細模式則輸出詳細錯誤資訊 # err = traceback.format_exc() if glovar.get_option('verbose') else str(e) # raise DataError(err) pass return music_list def encode_netease_data(data) -> str: data = json.dumps(data) key = binascii.unhexlify('7246674226682325323F5E6544673A51') encryptor = AES.new(key,AES.MODE_ECB) # 補足data長度,使其是16的倍數 pad = 16 - len(data) % 16 fix = chr(pad) * pad byte_data = (data + fix).encode('utf-8') return binascii.hexlify(encryptor.encrypt(byte_data)).upper().decode() def QQ_search(keyword): import urllib.parse as parse from urllib.request import urlretrieve import requests import json import os import time import sys w=parse.urlencode({'w':keyword}) url='https://c.y.qq.com/soso/fcgi-bin/client_search_cp?ct=24&qqmusic_ver=1298&new_json=1&remoteplace=txt.yqq.song&searchid=63229658163010696&t=0&aggr=1&cr=1&catZhida=1&lossless=0&flag_qc=0&p=1&n=30&%s&g_tk=5381&loginUin=0&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8¬ice=0&platform=yqq.json&needNewCode=0'%(w) content=requests.get(url=url) str_1=content.text dict_1=json.loads(str_1) song_list=dict_1['data']['song']['list'] str_3='''https://u.y.qq.com/cgi-bin/musicu.fcg?-=getplaysongvkey5559460738919986&g_tk=5381&loginUin=0&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8¬ice=0&platform=yqq.json&needNewCode=0&data={"req":{"module":"CDN.SrfCdnDispatchServer","method":"GetCdnDispatch","param":{"guid":"1825194589","calltype":0,"userip":""}},"req_0":{"module":"vkey.GetVkeyServer","method":"CgiGetVkey","songmid":["%s"],"songtype":[0],"uin":"0","loginflag":1,"platform":"20"}},"comm":{"uin":0,"format":"json","ct":24,"cv":0}}''' ID=0 music_list=[] url_list=[] for i in range(len(song_list)): # music_name.append(song_list[i]['name']+'-'+song_list[i]['singer'][0]['name']) # print('{}.{}-{}'.format(i+1,song_list[i]['name'],song_list[i]['singer'][0]['name'])) url_list.append(str_3 % (song_list[i]['mid'])) # # print(url_list[id-1]) music=[] # print(m['songname']) music.append(ID) music.append(song_list[i]['name']) music.append(song_list[i]['singer'][0]['name']) content_json=requests.get(url=url_list[ID]) dict_2=json.loads(content_json.text) url_ip=dict_2['req']['data']['freeflowsip'][1] purl=dict_2['req_0']['data']['midurlinfo'][0]['purl'] href=url_ip+purl music.append(href) music.append(song_list[i]['mid']) music_list.append(music) ID=ID+1 return music_list import wx import time def music_play(arr): print("雙擊函式已啟動") # 必須加上全域性變數,否則不唱歌 global mp3 import mp3play path="http://m10.music.126.net/20200414222927/e509cfbb086d358e701e6bb5cfedfeaa/ymusic/0759/030f/540b/039ace5c004ebd382de4ca163145cf9b.mp3" path=arr[3] print("path:-->"+path) mp3 = mp3play.load(path) mp3.play() def music_pyplay(arr): import os import time import pygame source_file_path=arr[3] pygame.mixer.init() pygame.mixer.music.load(source_file_path) pygame.mixer.music.set_volume(0.5) pygame.mixer.music.play(-1) class MyFrame(wx.Frame): def __init__(self): wx.Frame.__init__(self,None,-1,'Button Example',size=(1300,700),pos=(-10,0)) panel = wx.Panel(self,-1) panel.SetSize(1300,700) panel.SetBackgroundColour("#D2B48C") self.sousuotxt = wx.TextCtrl(panel,pos=(0,0),size = (100,30)) lblList = ['網易','QQ','酷狗'] self.rbox = wx.RadioBox(panel,label = '',pos = (100,-15),30),choices = lblList,majorDimension = 1,style = wx.RA_SPECIFY_ROWS) self.rbox.Bind(wx.EVT_RADIOBOX,self.onRadioBox) self.button = wx.Button(panel,"搜尋",pos=(350,0)) self.Bind(wx.EVT_BUTTON,self.OnClick,self.button) self.mylove = wx.Button(panel,"同步我喜歡的音樂",pos=(500,self.Dmylove,self.mylove) languages = [] for i in range(1000): languages.append(str(i)) self.choice = wx.Choice(panel,choices = languages,30)) self.choice.SetStringSelection("0") self.button5 = wx.Button(panel,"本地檔案",pos=(50,30)) self.Bind(wx.EVT_BUTTON,self.OnButton,self.button5) self.button1 = wx.Button(panel,"播放",pos=(150,self.OnClick1,self.button1) self.button2 = wx.Button(panel,"暫停",pos=(250,self.OnClick2,self.button2) self.button3 = wx.Button(panel,"下載",self.OnClick3,self.button3) font = wx.Font(15,wx.DEFAULT,wx.FONTSTYLE_NORMAL,wx.NORMAL) self.music_ID = wx.StaticText(panel,label = "ID",pos = (0,100),size=(30,500),style=wx.ALIGN_CENTER) self.music_ID.SetBackgroundColour("#D2B48C") self.music_ID.SetFont(font) self.music_name = wx.StaticText(panel,label = "歌名",pos = (30,size=(400,style=wx.ALIGN_CENTER) self.music_name.SetBackgroundColour("#D2B48C") self.music_name.SetFont(font) languages = [] for i in range(1,100): languages.append("第"+str(i)+"頁") self.pagenum = wx.Choice(panel,600)) self.pagenum.SetStringSelection("第1頁") self.button4 = wx.Button(panel,"跳轉",600)) self.Bind(wx.EVT_BUTTON,self.OnClick4,self.button4) self.prepage = wx.Button(panel,"上一頁",self.PrePage,self.prepage) self.nextpage = wx.Button(panel,"下一頁",self.NextPage,self.nextpage) self.path="D://downmusic/歌曲" self.music_arr=[] self.getfile() self.setData() self.key1="本地音樂" def onRadioBox(self,event): # print (self.rbox.GetStringSelection(),' is clicked from Radio Box' ) pass def OnClick(self,event): self.rbox.GetStringSelection() print(self.rbox.GetStringSelection()) rboxtext=self.rbox.GetStringSelection() if rboxtext=="網易": s=self.sousuotxt.GetValue() self.music_arr=netease_search(s) print(self.music_arr) self.setData() print("搜尋") self.key1="線上音樂" elif rboxtext=="QQ": s=self.sousuotxt.GetValue() self.music_arr=QQ_search(s) print(self.music_arr) self.setData() print("搜尋") self.key1="線上音樂" else: pass #播放 def OnClick1(self,event): # self.button1.SetLabel("Clicked") print("播放") y=self.choice.GetStringSelection() for i in self.music_arr: if y==str(i[0]): if self.key1=="線上音樂": music_play(i) else: self.music_pyplay(i) def music_pyplay(self,arr): import os import time import pygame source_file_path=arr[3] pygame.mixer.init() pygame.mixer.music.load(source_file_path) pygame.mixer.music.set_volume(0.5) pygame.mixer.music.play(-1) import os path="D://downmusic/歌詞/" import pygame import time import os f_url="" if arr[2]=="sen": f_url=path+str(arr[1])+".lrc" else: f_url=path+str(arr[1])+"-"+str(arr[2])+".lrc" f=open(f_url) s="" for i in f.readlines(): if i[1]!="0": pass else: s=s+i print(s) f.close() strLrc=s f.close() dictLrc = {} # 對歌詞進行按行切割 lineListLrc = strLrc.splitlines() # 遍歷每一行歌詞 geci="" for lineLrc in lineListLrc: # 時間和歌詞分開 listLrc = lineLrc.split("]") timeLrc = listLrc[0][1:].split(':') # 轉換時間格式 times = float(timeLrc[0]) * 60 + float(timeLrc[1]) # 把時間當做key,歌詞當做value存放在字典中 dictLrc[times] = listLrc[1] geci=geci+listLrc[1]+"\n" tempTime = 0 # 音訊初始化 root = Tk() # 初始化Tk() root.overrideredirect(True)#隱藏標題欄 root.title("label-test") # 設定視窗標題 root.geometry("1300x800+0+0") # 設定視窗大小 注意:是x 不是* root.resizable(width=True,height=True) # 設定視窗是否可以變化長/寬,False不可變,True可變,預設為True l = Label(root,text="label",bg="pink",font=("Arial",60),width=300,height=800) l["text"]="wusen" # 載入音訊檔案路徑 (路徑必須真實存在,音訊檔案格式支援mp3/ogg等格式) for key in dictLrc.keys(): tempTime = key - tempTime # 判斷是否在播放音樂 if not pygame.mixer.music.get_busy(): pygame.mixer.music.play() # 歌詞顯示的時間 time.sleep(tempTime) # 顯示歌詞 print(dictLrc[key]) tempTime = key import time # time.sleep(1) # music_IRC.SetLabel(time.strftime("%H:%M:%S",time.localtime(time.time()))) print(time.strftime("%H:%M:%S",time.localtime(time.time()))) # l["text"]=time.strftime("%H:%M:%S",time.localtime(time.time())) l["text"]=dictLrc[key] l.pack(side=TOP) l.update() root.destroy() # print(s) # 暫停 def OnClick2(self,event): # self.button2.SetLabel("Clicked") print("暫停") # 下載 def OnClick3(self,event): y=self.choice.GetStringSelection() # self.button3.SetLabel("Clicked") print("下載") print(y) for i in self.music_arr: if y==str(i[0]): self.down_music(i) # 跳轉 def down_music(self,arr): self.rbox.GetStringSelection() print(self.rbox.GetStringSelection()) rboxtext=self.rbox.GetStringSelection() if rboxtext=="網易": headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/79.0.3945.130 Safari/537.36'} import requests url=arr[3] name=str(arr[1])+"-"+str(arr[2]) res=requests.get(url,headers=headers) print(res) m=res.content mv=open("D://downmusic/歌曲/"+name+".mp3","wb") mv.write(m) mv.close() # 下載歌詞 import requests import json import os url = 'http://music.163.com/api/song/lyric?'+ 'id=' + str(arr[4])+ '&lv=1&kv=1&tv=-1' r = requests.get(url,headers=headers) json_obj = r.text print(r.text) print(url) j = json.loads(json_obj) print(j['lrc']['lyric']) f=open("D://downmusic/歌詞/"+name+".lrc","w") f.write(j['lrc']['lyric']) f.close() elif rboxtext=="QQ": headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML,headers=headers) print(res) m=res.content QQmusicpath="D://downmusic/歌曲/"+name+".mp3" mv=open(QQmusicpath,"wb") mv.write(m) mv.close() import os s="e://python/ffmpeg-20200403-52523b6-win64-static/bin/ffmpeg -i D://downmusic/歌曲/a.mp3 "+QQmusicpath os.system(s) os.remove("D://downmusic/歌曲/a.mp3") # 下載歌詞 pass else: pass def OnClick4(self,event): self.setData() #重新整理頁面賦值內容 def setData(self): y=self.pagenum.GetStringSelection() # self.button4.SetLabel("Clicked") print("跳轉") print(y) ID="" name="" singer="" for i in self.music_arr[(int(y[1:-1])-1)*10:(int(y[1:-1])-1)*10+10]: ID=ID+str(i[0])+"\n"+"----\n" name=name+str(i[1])+"-"+str(i[2])+"\n"+"------------------------------------------------------------------------------------------\n" # singer=singer+str(i[2])+"\n"+"----------\n" self.music_ID.SetLabel(ID) self.music_name.SetLabel(name) # self.music_singer.SetLabel(singer) def getfile(self): self.music_arr.clear() import os local_url=self.path+"/" if os.path.isdir(local_url): pass else: os.mkdir(local_url) print("路徑已建立") file = os.listdir(self.path) j=0 for i in file: k=[] music_name=i[:-4].split("-",1)[0] try: music_singer=i[:-4].split("-",1)[1] except: music_singer="sen" music_ID="0" music_edition="本地歌曲" music_url=self.path+"/"+i k.append(j) k.append(music_name) k.append(music_singer) k.append(music_url) k.append(music_edition) print(j) print(music_name) print(music_singer) print(music_url) print(music_edition) print("----------") self.music_arr.append(k) j=j+1 self.key1="本地音樂" # 選擇本地檔案 def OnButton(self,event): """""" dlg = wx.DirDialog(self,u"選擇資料夾",style=wx.DD_DEFAULT_STYLE) if dlg.ShowModal() == wx.ID_OK: print(dlg.GetPath()) #資料夾路徑 self.path=dlg.GetPath() dlg.Destroy() self.getfile() self.setData() # 下一頁 def NextPage(self,event): y=self.pagenum.GetStringSelection() self.pagenum.SetStringSelection("第"+str(int(y[1:-1])+1)+"頁") self.setData() # 上一頁 def PrePage(self,event): y=self.pagenum.GetStringSelection() self.pagenum.SetStringSelection("第"+str(int(y[1:-1])-1)+"頁") self.setData() def Dmylove(self,event): # 同步網易雲音樂 import requests from bs4 import BeautifulSoup import urllib.request from lxml import html etree = html.etree #這裡是設定請求頭 headers = { 'Referer': 'http://music.163.com/','Host': 'music.163.com','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/62.0.3202.75 Safari/537.36','Accept': 'text/html,image/webp,image/apng,} # 歌單的url地址這裡改id play_url = 'http://music.163.com/playlist?id=587771511' s = requests.session() response = s.get(play_url,headers=headers).content # 使用bs4匹配出對應的歌曲名稱和地址 s = BeautifulSoup(response,'lxml') main = s.find('ul',{'class': 'f-hide'}) #print(main.find_all('a')) lists = [] for music in main.find_all('a'): list = [] # print('{} : {}'.format(music.text,music['href'])) musicUrl = 'http://music.163.com/song/media/outer/url' + music['href'][5:] + '.mp3' musicName = music.text # 單首歌曲的名字和地址放在list列表中 list.append(musicName) list.append(musicUrl) list.append(music['href'][9:]) # 全部歌曲資訊放在lists列表中 lists.append(list) # 下載列表中的全部歌曲,並以歌曲名命名下載後的檔案,檔案位置為當前資料夾 for i in lists: url = i[1] name = i[0] try: import os if os.path.exists("d:/downmusic/歌曲/"+name+".mp3"): pass else: print('正在下載',name) #這裡修改路徑,隨便指定碟符,但是得存在 urllib.request.urlretrieve(url,'d:/downmusic/歌曲/%s.mp3' % name) import requests import json url = 'http://music.163.com/api/song/lyric?'+ 'id=' + str(i[2])+ '&lv=1&kv=1&tv=-1' r = requests.get(url,headers=headers) json_obj = r.text print(r.text) print(url) j = json.loads(json_obj) print(j['lrc']['lyric']) f=open("d://downmusic/歌詞/"+name+".lrc","w") f.write(j['lrc']['lyric']) f.close() print('下載成功') except: print('下載失敗') if __name__ == '__main__': app = wx.PySimpleApp() frame = MyFrame() frame.Show() app.MainLoop() # #pyinstaller -D -w WX音樂播放器.py -p D:/anaconda/Lib/site-packages # pyinstaller -D WX音樂播放器.py -p D:/anaconda/Lib/site-packages # #pyinstaller -D WX音樂播放器.py
以上就是python 基於wx實現音樂播放的詳細內容,更多關於python 音樂播放的資料請關注我們其它相關文章!