作为一个重度音乐爱好者,我的电脑里存了上千首喜欢的歌。但现在的音乐软件要么广告满天飞,要么强制联网,找个歌还得翻半天。于是我心一横:干脆自己写一个纯本地的Windows版音乐播放器!
今天就把这个“私人定制”播放器的开发思路、踩过的Bug以及核心代码分享给大家,希望能给有同样需求的朋友一点灵感。
一、 核心需求:我的播放器必须长这样
在动手写代码前,我给自己定了几个死规矩:
1.
绝对不联网:纯本地运行,保护隐私,没网也能听。
2.
按语言和场景分区:我把歌单分成了英文区、粤语区、国语区、日韩区、小众语言区、动漫区和影视区。
3.
颜值即正义:必须能换主题颜色,还能自己上传图片当皮肤!
二、 开发思路与工具选择
考虑到开发效率和打包成exe的便利性,我选择了Python + PyQt5。
●
PyQt5:用来画界面,做按钮、列表和背景图非常方便。
●
pygame:专门用来处理音频播放,稳定且轻量。
●
PyInstaller:最后用来把代码打包成独立的exe文件。
三、 迭代与Bug血泪史(重点!)
写代码的过程并不是一帆风顺的,这里分享几个我踩过的坑:
Bug 1:中文路径播放没声音?现象:英文歌一切正常,一放周杰伦就卡住。解决:pygame对中文路径支持不好。我加了一个判断,如果路径包含中文,就先把文件复制到系统临时目录,播放完再删掉,完美解决!
Bug 2:切歌时界面卡死?现象:点击下一首,整个播放器会顿一下。解决:音频加载需要时间,不能放在主线程。我用QThread把加载音乐的动作放到了后台,界面瞬间丝滑。
Bug 3:自定义皮肤怎么加?思路:我写了一个配置文件config.json。每次启动时读取配置,如果用户选了自定义图片,就用setStyleSheet把背景图铺满,并加上半透明黑色遮罩,不然字都看不清。
四、 核心代码大公开
下面是播放器的核心框架代码,大家可以拿去跑跑看:
代码
图标/24_new/复制
import sys import os import json from PyQt5.QtWidgets import * from PyQt5.QtGui import * from PyQt5.QtCore import * import pygame # 初始化pygame混音器 pygame.mixer.init() class LocalMusicPlayer(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("我的专属本地播放器") self.resize(800, 600) # 初始化分区 self.zones = ["国语区", "粤语区", "英文区", "日韩区", "小众语言区", "动漫区", "影视区"] self.current_zone = "国语区" # 界面布局 self.init_ui() self.load_theme() # 加载主题 def init_ui(self): # 左侧:分区列表 self.zone_list = QListWidget() self.zone_list.addItems(self.zones) self.zone_list.currentItemChanged.connect(self.change_zone) # 中间:歌曲列表 self.song_list = QListWidget() # 底部:播放控制 self.play_btn = QPushButton("播放") self.next_btn = QPushButton("下一首") self.skin_btn = QPushButton("更换皮肤") self.skin_btn.clicked.connect(self.change_skin) # 组装布局 layout = QHBoxLayout() layout.addWidget(self.zone_list, 1) layout.addWidget(self.song_list, 3) bottom_layout = QHBoxLayout() bottom_layout.addWidget(self.play_btn) bottom_layout.addWidget(self.next_btn) bottom_layout.addWidget(self.skin_btn) main_widget = QWidget() main_layout = QVBoxLayout(main_widget) main_layout.addLayout(layout) main_layout.addLayout(bottom_layout) self.setCentralWidget(main_widget) def change_skin(self): """更换自定义皮肤""" file_path, _ = QFileDialog.getOpenFileName(self, "选择背景图片", "", "Images (*.png *.jpg)") if file_path: config = {"bg_image": file_path, "theme_color": "#333333"} with open("config.json", "w") as f: json.dump(config, f) self.load_theme() def load_theme(self): """加载主题配置""" try: with open("config.json", "r") as f: config = json.load(f) bg = config.get("bg_image", "") color = config.get("theme_color", "#2b2b2b") self.setStyleSheet(f""" QMainWindow {{ background-color: {color}; }} QListWidget {{ background: rgba(0,0,0,0.5); color: white; border: none; }} QPushButton {{ background: rgba(255,255,255,0.2); color: white; padding: 8px; border-radius: 4px; }} """) if bg and os.path.exists(bg): self.setStyleSheet(f""" QMainWindow {{ background-image: url({bg}); background-repeat: no-repeat; background-position: center; }} """) except FileNotFoundError: pass # 使用默认主题 if __name__ == "__main__": app = QApplication(sys.argv) player = LocalMusicPlayer() player.show() sys.exit(app.exec_())五、 如何打包成exe?
代码写好后,在命令行运行:
代码
图标/24_new/复制
pip install pyinstaller pyinstaller -F -w --add-data "config.json;." main.py生成的main.exe就可以发给朋友,或者放在U盘里随时听了!