温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

python如何实现可下载音乐的音乐播放器

发布时间:2021-03-23 12:49:02 来源:亿速云 阅读:302 作者:小新 栏目:开发技术

小编给大家分享一下python如何实现可下载音乐的音乐播放器,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

1.确定页面

SongSheet ------ 显示歌单
MusicCtrl ------显示音乐一些控件(播放,跳转,音量调节)
SearchWindows ------搜索栏(搜索歌曲默认显示20条,可下载)

songSheet.py

#!/usr/bin/env python # -*- coding:utf-8 -*- # @Author: Minions # @Date: 2019-11-24 19:51:16 # @Last Modified by: Minions # @Last Modified time: 2019-12-17 10:01:53 import tkinter import os from tkinter import ttk import time class SongSheet(tkinter.Frame):  def __init__(self, master):  self.frame = tkinter.Frame(master, height=230, width=300, bd=1,      bg="SkyBlue")  self.frame.place(x=0, y=0)  self.filePath = "C:\Musics"  self.music = "" # 点击歌曲获得更新的路径  self.count = 0 # 计数,共多少歌曲  def run(self):  # 搜索按钮  searchBtn = tkinter.Button(self.frame, text="更新", bg="SkyBlue",      command=self.showSheet, width=10,      height=1)  searchBtn.place(x=0, y=200)  # 显示歌单  def showSheet(self):  self.count = 0  musics = os.listdir(self.filePath)  tree = ttk.Treeview(self.frame)  # 定义列  tree["columns"] = ("song")  # 设置列,列还不显示  tree.column("song", width=95)  # 设置表头 和上面一一对应  tree.heading("song", text="song")  # 添加数据 往第0行添加  for music in musics:   # 去除空格   music = "".join(music.split(" "))   tree.insert("", 0, text=self.count, values=(music))   self.count += 1  # 鼠标选中一行回调  def selectTree(event):   for item in tree.selection():   item_text = tree.item(item, "values")   self.music = "".join(item_text)   # print(self.music)  # 选中行  tree.bind('<<TreeviewSelect>>', selectTree)  tree.place(width=300, height=200, x=0, y=0)  # 添加滚动条  sy = tkinter.Scrollbar(tree)  sy.pack(side=tkinter.RIGHT, fill=tkinter.Y)  sy.config(command=tree.yview)  tree.config(yscrollcommand=sy.set)

python如何实现可下载音乐的音乐播放器

2.写出音乐控件

musicCtrl.py

#!/usr/bin/env python # -*- coding:utf-8 -*- # @Author: Minions # @Date: 2019-11-24 16:28:18 # @Last Modified by: Minions # @Last Modified time: 2019-12-17 10:25:31 import tkinter from tkinter import ttk import os import time import pygame from mutagen.mp3 import MP3 import random from songSheet import SongSheet class MusicCtrl(object):  def __init__(self, master):  self.frame = tkinter.Frame(master,height=150, width=700, bd=1,      bg="MediumSeaGreen")  self.frame.place(height=150, width=700, x=0, y=250)  self.nowPaly = True # 是否正在播放音乐  self.filePath = r"C:\Musics" # 从该文件夹读取  self.musicPath = "" # 用于拼接音乐的路径  self.songSheet = SongSheet(master)  self.songSheet.run()  self.music = os.path.join(self.filePath,self.musicPath) # 音乐的路径  # 整合功能  def run(self):  self.playMusic()  self.refreshName()  self.pauseMusic()  self.volume()  try:   self.songPos()  except:   print("暂无歌曲载入!")  # 播放音乐按钮  def playMusic(self):  playBtn = tkinter.Button(self.frame, text="播放", command=self.playFunc,      width=10,height=2)  playBtn.place(x=300,y=10)  # 实现播放功能  def playFunc(self):  pygame.mixer.init()  track = pygame.mixer.music.load(self.music) # 载入一个音乐文件用于播放  pygame.mixer.music.play() # 开始播放音乐流  # 暂停播放按钮  def pauseMusic(self):  pauseBtn = tkinter.Button(self.frame, text="暂停/继续",      command=self.pauseFunc,      width=10, height=2)  pauseBtn.place(x=400, y=10)  # 暂停播放功能  def pauseFunc(self):  # pygame.mixer.music.get_busy() # 检测是否正在播放音乐  if self.nowPaly:   pygame.mixer.music.pause()   self.nowPaly = False  else:   pygame.mixer.music.unpause() # 恢复音乐播放   self.nowPaly = True  # 显示歌曲名称以及歌手  def showName(self):  songName = tkinter.Label(self.frame,    fg="white",font=("华文行楷", 10),bg="MediumSeaGreen",      width=25, height=1)  songName['text'] = self.songSheet.music.split('.')[0]  songName.place(x=35,y=15)  self.music = os.path.join(self.filePath,self.songSheet.music)  # 更换音乐后应该继续播放,并且更换音乐时长  self.playFunc()  self.songPos()  # 音量调节  def volume(self):  volumeNum = tkinter.Label(self.frame, text="volume", fg="Aquamarine",      font=("华文行楷", 10), bg="MediumSeaGreen",      width=5, height=1)  volumeNum.place(x=500, y=70)  volume = tkinter.Scale(self.frame, from_=0, to=100,     orient=tkinter.HORIZONTAL)  volume.place(x=550,y=50)  def showNum():   pygame.mixer.music.set_volume(volume.get()*0.01) # 参数值范围为 0.0~1.0  tkinter.Button(self.frame, text="设置", command=showNum, bg="Aqua").place(   x=550, y=100)  # 音乐绝对定位  def songPos(self):  # print(self.music.info.length)  pos = tkinter.Scale(self.frame, from_=0, to=round(   MP3(self.music).info.length),    orient=tkinter.HORIZONTAL, tickinterval=50, length=300)  pos.place(x=180, y=60)  def showNum():   # 为了对一个 MP3 文件的进行绝对定位,建议首先调用 rewind()函数,不然会一直往后走   pygame.mixer.music.rewind()   if pygame.mixer.music.get_busy():   self.curDuration = pos.get()   pygame.mixer.music.set_pos(self.curDuration)   else:   print("请先播放音乐!")  tkinter.Button(self.frame, text="设置", command=showNum, bg="Aqua").place(   x=490, y=90)  # 点击歌单的歌更新名称  def refreshName(self):  refreshNameBtn = tkinter.Button(self.frame, text="update",command=self.showName,      width=10, height=2)  refreshNameBtn.place(x=45, y=50)

python如何实现可下载音乐的音乐播放器

3.核心爬取音乐

music.py

# -*- coding:utf-8 -*- import requests, hashlib, sys, click, re, base64, binascii, json, os from Cryptodome.Cipher import AES from http import cookiejar class Encrypyed():  """  解密算法  """  def __init__(self):  self.modulus = '00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7'  self.nonce = '0CoJUm6Qyw8W8jud'  self.pub_key = '010001'  # 登录加密算法, 基于https://github.com/stkevintan/nw_musicbox脚本实现  def encrypted_request(self, text):  text = json.dumps(text)  sec_key = self.create_secret_key(16)  enc_text = self.aes_encrypt(self.aes_encrypt(text, self.nonce), sec_key.decode('utf-8'))  enc_sec_key = self.rsa_encrpt(sec_key, self.pub_key, self.modulus)  data = {'params': enc_text, 'encSecKey': enc_sec_key}  return data  def aes_encrypt(self, text, secKey):  pad = 16 - len(text) % 16  text = text + chr(pad) * pad  encryptor = AES.new(secKey.encode('utf-8'), AES.MODE_CBC, b'0102030405060708')  ciphertext = encryptor.encrypt(text.encode('utf-8'))  ciphertext = base64.b64encode(ciphertext).decode('utf-8')  return ciphertext  def rsa_encrpt(self, text, pubKey, modulus):  text = text[::-1]  rs = pow(int(binascii.hexlify(text), 16), int(pubKey, 16), int(modulus, 16))  return format(rs, 'x').zfill(256)  def create_secret_key(self, size):  return binascii.hexlify(os.urandom(size))[:16] class Song():  """  歌曲对象,用于存储歌曲的信息  """  def __init__(self, song_id, song_name, song_num, picUrl, singer_name,    song_url=None):  self.song_id = song_id  self.song_name = song_name  self.song_num = song_num  self.singer_name = singer_name  self.picUrl = picUrl  self.song_url = '' if song_url is None else song_url class Crawler():  """  网易云爬取API  """  def __init__(self, timeout=60, cookie_path='.'):  self.headers = {   'Accept': '*/*',   'Accept-Encoding': 'gzip,deflate,sdch',   'Accept-Language': 'zh-CN,zh;q=0.8,gl;q=0.6,zh-TW;q=0.4',   'Connection': 'keep-alive',   'Content-Type': 'application/x-www-form-urlencoded',   'Host': 'music.163.com',   'Referer': 'http://music.163.com/search/',   'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'  }  self.session = requests.Session()  self.session.headers.update(self.headers)  self.session.cookies = cookiejar.LWPCookieJar(cookie_path)  self.download_session = requests.Session()  self.timeout = timeout  self.ep = Encrypyed()  self.result =[]  def post_request(self, url, params):  """  Post请求  :return: 字典  """  data = self.ep.encrypted_request(params)  resp = self.session.post(url, data=data, timeout=self.timeout)  result = resp.json()  if result['code'] != 200:   click.echo('post_request error')  else:   return result  def search(self, search_content, search_type, limit=9):  """  搜索API  :params search_content: 搜索内容  :params search_type: 搜索类型  :params limit: 返回结果数量  :return: 字典.  """  url = 'http://music.163.com/weapi/cloudsearch/get/web?csrf_token='  params = {'s': search_content, 'type': search_type, 'offset': 0, 'sub': 'false', 'limit': limit}  result = self.post_request(url, params)  # print(result['result']['songs'][3]['ar'][0]['name'])  return result  def search_song(self, song_name, song_num, quiet=True, limit=20):  """  根据音乐名搜索  :params song_name: 音乐名  :params song_num: 下载的歌曲数  :params quiet: 自动选择匹配最优结果  :params limit: 返回结果数量  :return: Song独享  """  result = self.search(song_name, search_type=1, limit=limit)  if result['result']['songCount'] <= 0:   click.echo('Song {} not existed.'.format(song_name))  else:   songs = result['result']['songs']   if quiet:   self.result = [] # 更新result   for song in songs:    singers = []    # """    picUrl = song['al']['picUrl']    # """    for name in song['ar']:    singers.append(name['name'])    song_id, song_name = song['id'], song['name']    singer_name = "_".join(singers)    song = Song(song_id=song_id, song_name=song_name,     song_num=song_num, singer_name=singer_name,picUrl=picUrl)    self.result.append(song)   picUrl = songs[0]['al']['picUrl']   # """   song_id, song_name = songs[0]['id'], songs[0]['name']   song = Song(song_id=song_id, song_name=song_name,    song_num=song_num, singer_name=self.result[0].singer_name,     picUrl=picUrl)   return song  def get_song_url(self, song_id, bit_rate=320000):  """  获得歌曲的下载地址  :params song_id: 音乐ID<int>.  :params bit_rate: {'MD 128k': 128000, 'HD 320k': 320000}  :return: 歌曲下载地址  """  url = 'http://music.163.com/weapi/song/enhance/player/url?csrf_token='  csrf = ''  params = {'ids': [song_id], 'br': bit_rate, 'csrf_token': csrf}  result = self.post_request(url, params)  # 歌曲下载地址  song_url = result['data'][0]['url']  # 歌曲不存在  if song_url is None:   click.echo('Song {} is not available due to copyright issue.'.format(song_id))  else:   return song_url  def get_song_by_url(self, song_url, song_name, song_num, singer_name,    folder):  """  下载歌曲到本地  :params song_url: 歌曲下载地址  :params song_name: 歌曲名字  :params song_num: 下载的歌曲数  :params folder: 保存路径  """  # for res in self.result:  # print(res.song_name, res.song_id, res.singer_name)  # print("--------")  # print(song_url, song_name, singer_name) class Netease():  """  网易云音乐下载  """  def __init__(self, timeout, folder, quiet, cookie_path):  self.crawler = Crawler(timeout, cookie_path)  self.folder = '.' if folder is None else folder  self.quiet = quiet  self.url = ''  self.pic = ''  def download_song_by_search(self, song_name):  """  根据歌曲名进行搜索  :params song_name: 歌曲名字  :params song_num: 下载的歌曲数  """  try:   song = self.crawler.search_song(song_name, self.quiet)  except:   click.echo('download_song_by_serach error')  # 如果找到了音乐, 则下载  if song != None:   self.download_song_by_id(song.song_id, song.song_name,     song.song_num, song.singer_name, self.folder)   self.pic = song.picUrl  def download_song_by_id(self, song_id, song_name, song_num, singer_name,     folder='.'):  """  通过歌曲的ID下载  :params song_id: 歌曲ID  :params song_name: 歌曲名  :params song_num: 下载的歌曲数  :params folder: 保存地址  """  try:   url = self.crawler.get_song_url(song_id)   # 去掉非法字符   song_name = song_name.replace('/', '')   song_name = song_name.replace('.', '')   self.crawler.get_song_by_url(url, song_name, song_num,       singer_name, folder)  except:   click.echo('download_song_by_id error')

4.将爬取音乐搜索栏整合

searchWindows.py

#!/usr/bin/env python # -*- coding:utf-8 -*- # @Author: Minions # @Date: 2019-11-25 10:31:56 # @Last Modified by: Minions # @Last Modified time: 2019-12-17 12:40:31 import tkinter from tkinter import ttk import os from urllib import request from music import Netease,Crawler import requests class SearchWindows(tkinter.Frame):  def __init__(self, master):  self.frame = tkinter.Frame(master, height=240, width=500, bd=1,      bg="Purple")  self.songs = None # 搜索到的所有歌曲(20)的信息  self.frame.place(x=300,y=0)  self.info = None # 当前歌曲的信息  self.fileName = "C:\Musics\\"  timeout = 60  output = 'Musics'  quiet = True  cookie_path = 'Cookie'  self.netease = Netease(timeout, output, quiet, cookie_path)  def run(self):  self.searchBar()  self.download()  # 搜索框  def searchBar(self):  entry = tkinter.Entry(self.frame)  entry.place(width=200, height=30, x=50, y=10)  def getValue():   self.netease.download_song_by_search(entry.get())   self.songs = self.netease.crawler.result   self.showSong()  searchBtn = tkinter.Button(self.frame, text="搜索", bg="DarkOrchid",      command=getValue, width=10, height=1)  searchBtn.place(x=270, y=10)  # 显示搜索到的歌曲  def showSong(self):  tree = ttk.Treeview(self.frame)  # 定义列  tree["columns"] = ("song", "singer", "url")  # 设置列,列还不显示  tree.column("song", width=50)  tree.column("singer", width=50)  tree.column("url", width=50)  # 设置表头 和上面一一对应  tree.heading("song", text="song")  tree.heading("singer", text="singer")  tree.heading("url", text="url")  count = len(self.songs)  for song in reversed(self.songs):   url = self.netease.crawler.get_song_url(song.song_id)   tree.insert("", 0, text=count, values=(song.song_name,        song.singer_name, url))   count -= 1  # 鼠标选中一行回调  def selectTree(event):   for item in tree.selection():   item_text = tree.item(item, "values")   self.info = item_text  # 滚动条  sy = tkinter.Scrollbar(tree)  sy.pack(side=tkinter.RIGHT, fill=tkinter.Y)  sy.config(command=tree.yview)  tree.config(yscrollcommand=sy.set)  # 选中行  tree.bind('<<TreeviewSelect>>', selectTree)  tree.place(width=300, height=200, x=50, y=50)  # 下载选中的歌曲  def download(self):  def downloadSong():   if self.info is None:   print("该歌曲下载失败")   else:   request.urlretrieve(self.info[2],     self.fileName+self.info[1]+'-'+self.info[0]+'.mp3')   print("%s-%s下载成功" %(self.info[1], self.info[0]))    # 下载按钮  downloadBtn = tkinter.Button(self.frame, text="下载", bg="DarkOrchid",      command=downloadSong, width=6, height=1)  downloadBtn.place(x=345, y=200)

python如何实现可下载音乐的音乐播放器

5.整合所有部分

main.py

#!/usr/bin/env python # -*- coding:utf-8 -*- # @Author: Minions # @Date: 2019-11-24 20:10:15 # @Last Modified by: Minions # @Last Modified time: 2019-12-17 9:55:31 import tkinter from searchWindows import SearchWindows from musicCtrl import MusicCtrl from songSheet import SongSheet import os win = tkinter.Tk() win.title("Minions音乐播放器") win.geometry("700x400") if os.path.exists("C:/Musics"):  print("xxx") else:  os.mkdir("C:/Musics") searchWin = SearchWindows(win) searchWin.run() songSheetWin = SongSheet(win) songSheetWin.run() musicWin = MusicCtrl(win) musicWin.run() win.mainloop()

python如何实现可下载音乐的音乐播放器

以上是“python如何实现可下载音乐的音乐播放器”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI