朋友们大家好!
我们在之前就已经完成过一个简易的音乐播放器,但它也有许多需要完善的地方:
1. 没有进度条,无法得知和调整歌曲进度。
2. 音乐播放完后就结束了,不会重复播放或是切换下一个。
3. 界面颜色过于单调。
那么,在文章中将会改进这些缺点。
这张图片是改进后的结果:
1. 增加进度条
首先需要获取播放音频长度的功能。
在这里我们使用Python第三方库 eyed3 里面的 load 函数。
from eyed3 import load
music = load("音频文件路径")
print(music.info.time_secs) # 该属性可以获取音频的长度(单位: 秒)
我们就可以写一个函数来获取音频长度
def getLength(music, all_music, all_music_path): # 获取音乐时长
music = load(all_music_path[all_music.index(music)])
return music.info.time_secs
用变量存储音频播放时间
我们可以定义一个 time 变量来存储音频播放的时间,当开始播放音频时先将 time 赋值为0
如何让窗口上的进度条时刻更新 time 变量的值呢?
我们可以在 window.read() 里面添加一个参数 timeout,这样就可以每隔 timeout 毫秒 执行一次窗口事件处理。
window = Window(...)
while 1:
event, values = window.read(timeout = 100) # 这里表示每隔 100 毫秒执行一次读取
...
最后我们在循环中增加 time 变量,在窗口中更新进度即可。
2. 添加音乐播放模式
我们可以定义一个变量来存储当前播放的模式。
play_setting = 'Loop' # 循环播放: Loop 重复播放: Repeat
然后在窗口上添加菜单,用于设置播放模式。
然后再事件处理里面增加条件判断。
if event == '重复播放':
play_setting = 'Repeat'
if event == '循环播放':
play_setting = 'Loop'
3. 界面设置
在 PySimpleGUI 中可以通过 theme() 函数 设置窗口主题
import PySimpleGUI as sg
# 在这里使用 LightGray1 主题
# 注: 如果填入的主题不存在,PySimpleGUI 会随机抽取一个主题
sg.theme("LightGray1")
最后在循环中添加以下代码以用于处理进度条拖动等以上功能。
if mixer.music.get_busy():
time += 0.1 # 将 time 变量的值加 0.1 秒
else:
if music != '' and (not pause):
if not len(values['-music_list-']):
continue
time = 0
if play_setting == 'Loop':
choice_index += 1
# 如果索引大于音乐项目数则要从第一项开始播放
if choice_index == len(all_music):
choice_index = 0
LoadMusic(all_music[choice_index], all_music, all_music_path)
# 获取音乐信息变量
length = getLength(music, all_music, all_music_path)
# 播放进度条修改时长
window['-rate-'].update(0, range = [0, length])
window['-music_list-'].update(all_music, scroll_to_index = choice_index, set_to_index = choice_index) # 更新屏幕选择音乐
window['-playing-'].update(showMusic(all_music[choice_index])) # 显示正在播放的音乐
else:
LoadMusic(music, all_music, all_music_path)
mixer.music.play()
if event == '-rate-':
if mixer.music.get_busy():
# 如果用户拖动则要更新 time 变量和屏幕上的进度条
mixer.music.set_pos(values['-rate-'])
time = values['-rate-']
以下就是全部代码:
from pygame import mixer
from PySimpleGUI import Window, Slider, B, T, LB, Frame, Menu, popup, theme, popup_get_folder
from os import listdir
from eyed3 import load
from time import sleep
def tip():
print()
print('=' * 45)
for i in ['', '提示:', ' 1. 该音乐播放器仅支持 MP3 格式。', '', ' 2. 该音乐播放器只能播放计算机上', ' 的音频。', ' ', ' 3. 添加音乐需要选择含有音乐的', ' 文件夹, 这样程序会从该文件', ' 夹中筛选出音频添加到音乐列', ' 表中。', '', ' 4. 由于该播放器音量较大, 播放', ' 音乐音量建议在 20% - 30%之间。', '', '感谢用户的支持!', '']:
print(i)
sleep(0.05)
print('=' * 45)
print()
def getLength(music, all_music, all_music_path): # 获取音乐时长
music = load(all_music_path[all_music.index(music)])
return music.info.time_secs
def showMusic(music):
if len(music) > 23:
return '正在播放: {}...'.format(music[:23])
else:
return '正在播放: {}'.format(music)
def LoadMusic(music, all_music, all_music_path): # 加载音乐函数
global time, window
# 加载音乐
mixer.music.load(all_music_path[all_music.index(music)])
time = 0
theme('LightGray1')
mixer.init()
mixer.music.set_volume(1)
all_music = [] # 全部音乐名称
all_music_path = [] # 全部音乐对应路径
play_setting = 'Loop' # 循环播放: Loop 重复播放: Repeat
layout = [
[Menu([
['操作', ['清空列表', '---', '退出']],
['播放设置', ['重复播放', '循环播放']]
])],
[Frame('播放列表',
[
[T('音频播放列表', font = ('楷体', 15))],
[LB(all_music, size = (40, 10), key = '-music_list-', font = ('黑体', 13))],
[T('正在播放: 空', font = ('楷体', 12), key = '-playing-')]
], font = ('楷体', 16), grab = True )],
[T('音量设置', font = ('楷体', 14)), Slider(range = [0, 100], key = '-volume-', default_value = 100, orientation = 'h', enable_events = 1, resolution = 5, size = [23, 20])],
[T('播放进度', font = ('楷体', 14)), Slider(range = [0, 100], key = '-rate-', default_value = 100, orientation = 'h', enable_events = 1, size = [23, 20])],
[B('添加音频', font = ('楷体', 14)),
B('开始播放', font = ('楷体', 14), bind_return_key = True),
B('暂停', font = ('楷体', 14))]
]
tip()
window = Window('音乐播放器', layout)
pause = False # 标记是否暂停的变量
choice = ''
music = ''
time = 0 # 音频播放进度变量
choice_index = 0 # 音频选择的索引变量
length = 1.1
while 1:
event, values = window.read(timeout = 100)
window['-rate-'].update(time) # 每次更新 time 变量
if event in (None, '退出'):
mixer.music.stop() #结束所有播放
break
if event == '重复播放':
play_setting = 'Repeat'
if event == '循环播放':
play_setting = 'Loop'
if mixer.music.get_busy():
time += 0.1 # 将 time 变量的值加 0.1 秒
else:
if music != '' and (not pause):
if not len(values['-music_list-']):
continue
time = 0
if play_setting == 'Loop':
choice_index += 1
# 如果索引大于音乐项目数则要从第一项开始播放
if choice_index == len(all_music):
choice_index = 0
LoadMusic(all_music[choice_index], all_music, all_music_path)
# 获取音乐信息变量
length = getLength(music, all_music, all_music_path)
# 播放进度条修改时长
window['-rate-'].update(0, range = [0, length])
window['-music_list-'].update(all_music, scroll_to_index = choice_index, set_to_index = choice_index) # 更新屏幕选择音乐
window['-playing-'].update(showMusic(all_music[choice_index])) # 显示正在播放的音乐
else:
LoadMusic(music, all_music, all_music_path)
mixer.music.play()
if event == '-rate-':
if mixer.music.get_busy():
# 如果用户拖动则要更新 time 变量和屏幕上的进度条
mixer.music.set_pos(values['-rate-'])
time = values['-rate-']
elif event == '清空列表':
all_music.clear()
all_music_path.clear()
window['-music_list-'].update(all_music)
elif event == '-volume-':
mixer.music.set_volume(values['-volume-'] / 100)
elif event == '开始播放':
music = values['-music_list-']
if pause:
music = music[0]
# 如果音乐暂停重新开始后切换了音乐则要重新加载
if music != choice:
choice = music
LoadMusic(music, all_music, all_music_path)
choice_index = all_music.index(music)
try:
# 获取音乐信息变量
length = getLength(music, all_music, all_music_path)
# 播放进度条修改时长
window['-rate-'].update(0, range = [0, length])
mixer.music.play()
except:
# 如果音频无法播放就应该从列表里删除该音乐
all_music_path.pop(choice_index)
all_music.remove(music)
popup('音频解析错误或音频格式错误', font = '楷体 14', title = '播放错误')
window['-music_list-'].update(all_music)
music = ''
else:
window['-playing-'].update(showMusic(music)) # 显示正在播放的音乐
# 如果没有切换就继续播放
else:
mixer.music.unpause() #继续播放
pause = False
else:
# 如果音乐列表为空, 则不播放音乐
if len(music) == 0:continue
music = music[0]
choice = music
LoadMusic(music, all_music, all_music_path)
choice_index = all_music.index(music)
try:
# 获取音乐信息变量
length = getLength(music, all_music, all_music_path)
# 播放进度条修改时长
window['-rate-'].update(0, range = [0, length])
mixer.music.play()
except:
# 如果音频无法播放就应该从列表里删除该音乐
all_music_path.pop(choice_index)
all_music.remove(music)
popup('音频解析错误或音频格式错误', font = '楷体 14', title = '播放错误')
window['-music_list-'].update(all_music)
music = ''
else:
window['-playing-'].update(showMusic(music)) # 显示正在播放的音乐
elif event == '添加音频':
music_file = popup_get_folder('打开音频文件夹', no_window = True) # 打开文件夹获取音频
if music_file == '':continue
files = [music_file + '\\' + i for i in listdir(music_file) if i.endswith('.mp3')]
all_music_path.extend(files) # 从文件夹中筛选出音频并加入路径
all_music.extend([i.split('\\')[-1] for i in files]) # 要在屏幕上显示的音乐名
window['-music_list-'].update(all_music, set_to_index = choice_index, scroll_to_index = choice_index) # 从屏幕上显示
elif event == '暂停':
# 如果正在播放
if mixer.music.get_busy():
mixer.music.pause() # 暂停
pause = True # 更新 pause 变量
window.close()
以上就是全部内容,感谢大家观看!