用Pygame做的一个简易的音乐播放器。为什么用Pygame呢?谁叫它自带了音乐播放的函数,可以轻松实现音乐的暂停、恢复播放。先贴一张成品效果图:
下面我简要介绍一下这个程序里的几个要点。
在Pygame库里的pygame.mixer.music给出了一长串控制音乐的函数,功能非常齐全,可以自行挑选使用。
pygame.mixer.music.load() | 载入一个音乐文件用于播放 |
pygame.mixer.music.play() | 开始播放音乐流 |
pygame.mixer.music.pause() | 暂停音乐播放 |
pygame.mixer.music.unpause() | 恢复音乐播放 |
pygame.mixer.music.stop() | 结束音乐播放 |
pygame.mixer.music.rewind() | 重新开始播放音乐 |
pygame.mixer.music.fadeout() | 以淡出效果结束音乐播放 |
pygame.mixer.music.set_volume() | 设置音量 |
pygame.mixer.music.get_volume() | 获取音量 |
pygame.mixer.music.get_busy() | 检查是否正在播放音乐 |
pygame.mixer.music.set_pos() | 设置播放的位置 |
pygame.mixer.music.get_pos() | 获取播放的位置 |
pygame.mixer.music.queue() | 将一个音乐文件放入队列中,并排在当前播放的音乐之后 |
pygame.mixer.music.set_endevent() | 当播放结束时发出一个事件 |
pygame.mixer.music.get_endevent() | 获取播放结束时发送的事件 |
我使用了这个表中的前四个函数来控制音乐的载入、播放、暂停和恢复。
关于切歌的部分,我建了一个列表list_song来存储读入的音乐文件名,这就是程序里的歌单。然后用一个变量flag_song存储当前播放音乐在歌单中的索引。通过Pygame的鼠标点击事件判断按下上一首/下一首按钮时,将flag_song减1/加1并取余即可。
if (width/2-200<=locd[0]<=width/2-100) and (height*2/3<=locd[1]<=height*2/3+100): #上一首
flag_song = (flag_song+len(list_song)-1)%len(list_song)
if (width/2+100<=locd[0]<=width/2+200) and (height*2/3<=locd[1]<=height*2/3+100): #下一首
flag_song = (flag_song+1)%len(list_song)
要做这样一个软件,必不可少地要使用到Pygame里的鼠标点击事件,来定义各个按钮被按下时应该触发的事件。
while True:
for event in pygame.event.get():
if event.type==pygame.MOUSEBUTTONDOWN:
#在这里判断鼠标点击位置
鼠标按下事件会在这里被捕捉到,需要使用pygame.mouse.get_pos()函数获取鼠标点击的坐标,判断它是否在某个按钮的坐标范围内。比如:
播放/暂停按钮的图片我插入在这个位置:
screen.blit(image_play,[width/2-50,height*3/4])
则播放/暂停按钮被点击的判断应该是这么写的:
locd=pygame.mouse.get_pos()
if (width/2-50<=locd[0]<=width/2+50) and (height*2/3<=locd[1]<=height*2/3+100): #播放/暂停
#在这里写当该按钮被点击时执行的代码
一般mp3文件里都会带着一张专辑图片,这张图片存在文件的ID3信息里。可以使用mutagen库把这张图片读取出来,插入到我们的音乐播放器里。
由于mutagen读取出来的图片大小为500x500,对于我们播放器来说太大了,所以还要转换一下格式,用cv2里的resize()函数修改一下图片大小,比较复杂。我将它封装成了一个函数:
def get_pic_mp3(file):
import numpy as np
import cv2
from mutagen import File
afile = File(file)
artwork = afile.tags['APIC:'].data
img = cv2.imdecode(np.asarray(bytearray(artwork),dtype='uint8'), cv2.IMREAD_COLOR)
img = cv2.resize(img, (300,300))
success, encoded_image = cv2.imencode(".jpg", img)
img_bytes = encoded_image.tostring()
with open(file+'.jpg', 'wb') as img:
img.write(img_bytes)
return pygame.image.load(file+'.jpg')
需要源码可以在这里取:【Pygame小作品】简易音乐播放器