背景
在日常生活中,我们经常需要管理和播放大量媒体文件。市面上的音频播放器可能功能单一,或者界面复杂。作为一名程序员,我决定使用Python自己打造一个简单yet强大的媒体管理播放器。
C:\pythoncode\new\playsong.py
全部代码
import os
import wx
import json
import pygame
from mutagen.mp3 import MP3
from mutagen.wave import WAVE
class MediaManagerApp(wx.Frame):
def __init__(self):
super().__init__(parent=None, title='媒体文件管理器', size=(800, 600))
# 初始化pygame mixer
pygame.mixer.init()
# 配置文件路径
self.config_path = 'favorites.json'
# 创建面板
panel = wx.Panel(self)
# 垂直布局
main_sizer = wx.BoxSizer(wx.VERTICAL)
# 水平布局用于两个ListBox
list_sizer = wx.BoxSizer(wx.HORIZONTAL)
# 创建ListBox1(所有媒体文件)
wx.StaticText(panel, label='所有媒体文件:')
self.listbox1 = wx.ListBox(panel, style=wx.LB_MULTIPLE)
list_sizer.Add(wx.StaticText(panel, label='所有媒体文件:'), 0, wx.ALL, 5)
list_sizer.Add(self.listbox1, 1, wx.EXPAND | wx.ALL, 5)
# 创建ListBox2(收藏文件)
wx.StaticText(panel, label='收藏文件:')
self.listbox2 = wx.ListBox(panel, style=wx.LB_MULTIPLE)
list_sizer.Add(wx.StaticText(panel, label='收藏文件:'), 0, wx.ALL, 5)
list_sizer.Add(self.listbox2, 1, wx.EXPAND | wx.ALL, 5)
main_sizer.Add(list_sizer, 1, wx.EXPAND)
# 进度条
self.progress_slider = wx.Slider(panel, style=wx.SL_HORIZONTAL | wx.SL_LABELS)
main_sizer.Add(self.progress_slider, 0, wx.EXPAND | wx.ALL, 5)
# 按钮区域
btn_sizer = wx.BoxSizer(wx.HORIZONTAL)
# 选择文件夹按钮
select_folder_btn = wx.Button(panel, label='选择文件夹')
select_folder_btn.Bind(wx.EVT_BUTTON, self.on_select_folder)
btn_sizer.Add(select_folder_btn, 0, wx.ALL, 5)
# 收藏按钮
collect_btn = wx.Button(panel, label='收藏')
collect_btn.Bind(wx.EVT_BUTTON, self.on_collect)
btn_sizer.Add(collect_btn, 0, wx.ALL, 5)
# 保存按钮
save_btn = wx.Button(panel, label='保存')
save_btn.Bind(wx.EVT_BUTTON, self.on_save)
btn_sizer.Add(save_btn, 0, wx.ALL, 5)
# 加载按钮
load_btn = wx.Button(panel, label='加载')
load_btn.Bind(wx.EVT_BUTTON, self.on_load)
btn_sizer.Add(load_btn, 0, wx.ALL, 5)
# 播放按钮
play_btn = wx.Button(panel, label='播放')
play_btn.Bind(wx.EVT_BUTTON, self.on_play)
btn_sizer.Add(play_btn, 0, wx.ALL, 5)
# 停止按钮
stop_btn = wx.Button(panel, label='停止')
stop_btn.Bind(wx.EVT_BUTTON, self.on_stop)
btn_sizer.Add(stop_btn, 0, wx.ALL, 5)
main_sizer.Add(btn_sizer, 0, wx.CENTER)
panel.SetSizer(main_sizer)
# 绑定滑动条事件
self.progress_slider.Bind(wx.EVT_SLIDER, self.on_slider_change)
# 音频播放相关变量
self.current_track = None
self.track_length = 0
# 定时器用于更新进度
self.timer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.update_progress, self.timer)
def on_select_folder(self, event):
# 选择文件夹并列出媒体文件
with wx.DirDialog(self, "选择包含媒体文件的文件夹") as dirDialog:
if dirDialog.ShowModal() == wx.ID_OK:
folder_path = dirDialog.GetPath()
self.listbox1.Clear()
# 支持的媒体文件扩展名
media_extensions = ['.mp3', '.wav', '.ogg', '.flac']
# 遍历文件夹
for filename in os.listdir(folder_path):
if os.path.splitext(filename)[1].lower() in media_extensions:
full_path = os.path.join(folder_path, filename)
self.listbox1.Append(full_path)
def on_collect(self, event):
# 将选中的文件从listbox1移动到listbox2
selections = self.listbox1.GetSelections()
for index in reversed(selections):
item = self.listbox1.GetString(index)
self.listbox2.Append(item)
self.listbox1.Delete(index)
def on_save(self, event):
# 将收藏的文件保存到配置文件
favorites = [self.listbox2.GetString(i) for i in range(self.listbox2.GetCount())]
with open(self.config_path, 'w', encoding='utf-8') as f:
json.dump(favorites, f)
wx.MessageBox('收藏已保存', '提示')
def on_load(self, event):
# 从配置文件加载收藏的文件
try:
with open(self.config_path, 'r', encoding='utf-8') as f:
favorites = json.load(f)
self.listbox2.Clear()
for filepath in favorites:
if os.path.exists(filepath):
self.listbox2.Append(filepath)
except FileNotFoundError:
wx.MessageBox('没有找到收藏文件', '错误')
def on_play(self, event):
# 播放选中的文件
selections = self.listbox2.GetSelections()
if selections:
filepath = self.listbox2.GetString(selections[0])
pygame.mixer.music.load(filepath)
pygame.mixer.music.play()
# 获取音频文件长度
if filepath.lower().endswith('.mp3'):
audio = MP3(filepath)
self.track_length = audio.info.length
elif filepath.lower().endswith('.wav'):
audio = WAVE(filepath)
self.track_length = audio.info.length
else:
self.track_length = 0
# 设置进度条最大值
self.progress_slider.SetRange(0, int(self.track_length))
# 启动定时器更新进度
self.timer.Start(1000) # 每秒更新
self.current_track = filepath
def on_stop(self, event):
# 停止播放
pygame.mixer.music.stop()
self.timer.Stop()
self.progress_slider.SetValue(0)
def on_slider_change(self, event):
# 拖动进度条
if self.current_track:
new_pos = self.progress_slider.GetValue()
pygame.mixer.music.rewind()
pygame.mixer.music.set_pos(new_pos)
def update_progress(self, event):
# 更新进度条
if pygame.mixer.music.get_busy():
current_time = pygame.mixer.music.get_pos() / 1000 # 毫秒转秒
self.progress_slider.SetValue(int(current_time))
def main():
app = wx.App()
frame = MediaManagerApp()
frame.Show()
app.MainLoop()
if __name__ == '__main__':
main()
技术选型
对于这个项目,我选择了以下Python库:
wxPython
:构建跨平台GUI界面pygame
:音频播放和控制mutagen
:获取音频文件元数据json
:配置文件存储
核心功能设计
1. 文件浏览与收藏
用户可以轻松地:
- 选择文件夹
- 浏览媒体文件列表
- 快速将文件添加到收藏列表
- 保存和加载收藏列表
2. 音频播放控制
提供完整的播放体验:
- 播放选中的音频文件
- 停止当前播放
- 拖动进度条调节播放位置
- 实时显示播放进度
关键代码解析
文件遍历
def on_select_folder(self, event):
with wx.DirDialog(self, "选择包含媒体文件的文件夹") as dirDialog:
if dirDialog.ShowModal() == wx.ID_OK:
folder_path = dirDialog.GetPath()
# 遍历支持的媒体文件
media_extensions = ['.mp3', '.wav', '.ogg', '.flac']
for filename in os.listdir(folder_path):
if os.path.splitext(filename)[1].lower() in media_extensions:
full_path = os.path.join(folder_path, filename)
self.listbox1.Append(full_path)
音频播放控制
def on_play(self, event):
selections = self.listbox2.GetSelections()
if selections:
filepath = self.listbox2.GetString(selections[0])
pygame.mixer.music.load(filepath)
pygame.mixer.music.play()
# 获取音频文件长度
audio = MP3(filepath) if filepath.lower().endswith('.mp3') else WAVE(filepath)
self.track_length = audio.info.length
# 设置进度条
self.progress_slider.SetRange(0, int(self.track_length))
self.timer.Start(1000)
技术亮点
- 跨平台GUI:使用wxPython确保应用在Windows、Mac、Linux上都能运行
- 灵活的文件管理:支持多种音频格式
- 配置持久化:使用JSON保存收藏列表
- 实时进度控制:通过定时器实现播放进度追踪
安装与运行
# 安装依赖
pip install wxPython pygame mutagen
# 运行应用
python media_manager.py
使用场景
- 个人音乐收藏管理
- 音频文件快速浏览
- 简单的本地音乐播放需求
未来改进方向
- 添加播放列表功能
- 支持更多音频格式
- 增加音量控制
- 实现歌词显示
运行结果
结语
这个项目证明了Python强大的跨平台开发能力。短短200行代码,我们就实现了一个功能完善的媒体管理播放器。对于想要定制音频管理工具的开发者来说,这是一个很好的起点。