相关的解释,代码里有,这里就不解释了
注释:写时没有对代码进行优化。
窗体部分
from __future__ import print_function,unicode_literals
from tkinter import *
from tkinter import font
from wcwidth import wcswidth as ww
from Music import SearchMusic
from tkinter.ttk import Progressbar
from tkinter import ttk
import tkinter as tk
import os
# 定义对齐函数
def rpad(string,width,replace_char=" "):
return string+(width-ww(string))*replace_char
class Window(object):
# 初始化窗口
def __init__(self):
# 创建窗体
self.win = Tk()
# 给窗体命名
self.win.title("网易云音乐播放器——Taurus\t version -1.0.0")
# 设置窗体大小
self.win.geometry("400x500")
# 设置按钮文字大小
self.font_button = font.Font(size=10)
# 初始化头部
self.init_head()
# 初始化列表
self.init_body()
self.init_list_box()
# 初始化控制部件
self.init_footer()
# 引入音乐库
self.music=SearchMusic()
# 头部
def init_head(self):
# 标签
self.label_search = Label(self.win,text="请输入名称:")
self.label_search.place(x=10,y=10)
# 搜索框
self.input_search = Entry(self.win,width="30")
self.input_search.place(x=80,y=10)
# 搜索按钮
self.button_search = Button(self.win,text="搜索",font=self.font_button,width=12,command=self.search_muisc)
self.button_search.place(x=300,y=8)
# 中部
def init_body(self):
self.music_list_box = Listbox(self.win,selectmode=tk.SINGLE,width="47",height='20',font="YaHei")
self.music_list_box.place(x=10,y=40)
# 底部
def init_footer(self):
# 播放进度栏提示
self.time_label = Label(self.win,text="time:")
self.time_label.place(x=10,y=400)
# 进度条设置样式
style = ttk.Style()
style.theme_use("default")
style.configure("black.Horizontal.TProgressbar",background = "green")
# 设置进度条
self.playbar = Progressbar(self.win,length=340,style="black.Horizontal.TProgressbar",)
self.playbar.place(x=50,y=400)
# 设置音量样式,并设置初始值(移动,不会改变机器的播放音量)
self.voicebar = StringVar()
self.scalebar = Scale(self.win,orient="horizontal",variable=self.voicebar,resolution=1,command=self.voiceset)
self.scalebar.place(x=10,y=420)
self.scalebar.set(30)
# 上一首音乐,目前在本地音乐中不能使用)
self.prev_button = Button(self.win,text="上一首",font=self.font_button,command=self.prevsong)
self.prev_button.place(x=150,y=440)
#暂停音乐,联网与本地皆可用
self.pause_button = Button(self.win,text="暂停",font=self.font_button,command=self.pause)
self.pause_button.place(x=220,y=440)
#播放音乐,联网与本地皆可用,但没有点击列表时,回报错【没写】)
self.play_button = Button(self.win,text="播放",font=self.font_button,command=self.unpause)
self.play_button.place(x=270,y=440)
# 下一首按钮设置(目前本地播放音乐没有此功能)
self.next_button = Button(self.win,text="下一首",font=self.font_button,command=self.nextsong)
self.next_button.place(x=320,y=440)
# 用于初始化本地音乐
def init_list_box(self):
path = "./music/"
if os.path.exists(path):
if os.listdir(path):
self.local_list = []
for filename in os.listdir(path):
self.music_list_box.insert(tk.END,filename)
self.local_list.append(filename)
self.music_list_box.bind("<Double-Button-1>",self.play_localmusic)
# 播放本地音乐
def play_localmusic(self,event):
self.index = self.music_list_box.curselection()[0]
filename = self.local_list[self.index]
self.music.playlocalmusic(filename)
#播放上一首音乐,本地音乐无效
def prevsong(self):
if self.index >=0:
self.index-=1
self.music.download(self.index)
self.music.playmusic(self.index)
#播放下一首音乐,本地音乐无效
def nextsong(self):
if self.index<len(self.music_list):
self.index+=1
self.music.download(self.index)
self.music.playmusic(self.index)
# 暂停
def pause(self):
self.music.pausemusic()
# 取消暂停
def unpause(self):
self.music.unpausemusic()
# 音量设置
def voiceset(self,text):
v = self.voicebar.get()
v = int(v)/100.
self.music.setvoicemusic(v)
#接受搜索内容,并传递给listbox
def search_muisc(self):
# 发送到Music类中
if self.input_search.get()!="":
self.music.search(self.input_search.get())
self.music_list_box.delete(0,len(self.local_list))
# 获取列表
self.music_list = self.music.musicList
# 添加到列表中
for item in ["{}{}".format(rpad(self.music_list[i][0][:16],30),rpad(self.music_list[i][1],20)) for i in range(len(self.music_list))]:
self.music_list_box.insert(tk.END,item)
self.music_list_box.bind("<Double-Button-1>",self.click_list_box)
# 搜索后点击
def click_list_box(self,event):
self.index = self.music_list_box.curselection()[0]
self.music.download(self.index)
self.music.playmusic(self.index)
if __name__=="__main__":
# 创建窗体对象
player = Window()
# 调用搜索
player.search_muisc()
# 打开窗体
player.win.mainloop()
音乐部分
from urllib import parse
# 用于请求数据
from urllib.request import urlopen
# 转URL编码
from urllib.parse import quote
# 解释json文件
import json
# 用于创建目录,判断目录,文件等
import os
# 用于播放操作
import pygame
# 用于控制时间
import time
# 用于请求下载内容
import requests
# 删除目录缓存
import shutil
class SearchMusic:
# 查找音乐
def search(self,name):
self.name = quote(name)
self.html = urlopen("https://s.music.163.com/search/get/?type=1&s=%s&limit=20"%self.name).read()
self.data = json.loads(self.html)["result"]["songs"]
self.musicList = []
for i in range(len(self.data)):
# 只有歌名,歌星,id
self.musicList.append([self.data[i]["name"],self.data[i]["artists"][0]["name"],self.data[i]["id"]])
return self.musicList
def download(self,id_index):
if not os.path.exists("./music/"):
os.mkdir("./music/")
if os.path.exists("./music/"+self.musicList[id_index][0]+self.musicList[id_index][1]+".mp3"):
return
self.download_music = requests.get(url = f"http://music.163.com/song/media/outer/url?id={self.musicList[id_index][2]}.mp3",headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36'}).content
with open("./music/"+self.musicList[id_index][0]+self.musicList[id_index][1]+".mp3","wb") as f:
f.write(self.download_music)
f.close()
# 播放
def playmusic(self,id_index):
path = r"./music/"+self.musicList[id_index][0]+self.musicList[id_index][1]+".mp3"
pygame.mixer.init()
pygame.mixer.music.load(path)
pygame.mixer.music.play(start=0.0)
def playlocalmusic(self,listname):
path = r"./music/"+listname
pygame.mixer.init()
pygame.mixer.music.load(path)
pygame.mixer.music.play(start=0.0)
def pausemusic(self):
pygame.mixer.music.pause()
def rmdir(self):
shutil.rmtree6("./music/")
def unpausemusic(self):
pygame.mixer.music.unpause()
def setvoicemusic(self,voice):
pygame.mixer.music.set_volume(voice)
if __name__ == "__main__":
musics = SearchMusic()
musics.search(name="孤勇者")
i = 0
for music in musics.musicList:
print(i,music)
i+=1
index = int(input("请输入下载编号:"))
musics.download(index)
question = input("是否播放?(y/n):")
if question =="y":
musics.playmusic(index)
question = input("是否清空缓存?(y/n):")
if question == "y":
musics.rmdir()