本作业为一个播放本地音乐的音乐播放器,实现了基本音乐播放器的操作,如多种顺手播放,暂停等。
1.引言
近期的热门的音乐播放器如酷狗等越来越卡,无关的进程也越来越多,所以就做了个本地音乐的播放器。
2.系统结构
本播放器的结构图如图1,共有4个模块。其中Music_Player是主模块,主要实现其余3子模块的方法,整合3个子模块的函数进行参数传递。Load_Music模块主要负责后台音乐的实现,butto模块实现点击的参数传递和点击后调用Load_Music的方法,function模块实现点击的事件。
图1结构图
3. 实现代码
3.1. Load_Music模块
首先实现Load_Music模块,这个模块包含了实现音乐相关的操作以及下两个模块也要使用相关的函数。首先了解pygame.mixer函数的一些操作:
pygame.mixe.init() 或者只初始化音频部分
pygame.mixer.music.load(‘xx.mp3’) 使用文件名作为参数载入音乐 ,音乐可以是ogg、mp3等格式。载入的音乐不会全部放到内容中,而是以流的形式播放的,即在播放的时候才会一点点从文件中读取。
pygame.mixer.music.play()播放载入的音乐。该函数立即返回,音乐播放在后台进行。
play方法还可以使用两个参数
pygame.mixer.music.play(loops=0, start=0.0) loops和start分别代表重复的次数和开始播放的位置。
pygame.mixer.music.stop() 停止播放,
pygame.mixer.music.pause() 暂停播放。
pygame.mixer.music.unpause() 取消暂停。
pygame.mixer.music.fadeout(time) 用来进行淡出,在time毫秒的时间内音量由初始值渐变为0,最后停止播放。
pygame.mixer.music.set_volume(value) 来设置播放的音量,音量value的范围为0.0到1.0。
pygame.mixer.music.get_busy() 判断是否在播放音乐,返回1为正在播放。
然后就可以编写加载音乐的模块了,代码如下:
import os
import pygame
class Music_List():
def init(self):
# 播放列表
self.play_list = []
# 默认文件夹
self.file_dir = ‘music’
def get_play_list(self):
# 开始遍历目录
for root, dirs, files in os.walk(self.file_dir):
for file in files:
if '.mp3' in file:
self.play_list.append(self.file_dir + "/" + file)
return self.play_list
def load_music(titlt):#加载音乐
try:
pygame.mixer.music.load(titlt)
except :
pass
def play_music():
pygame.mixer.music.play()
return True
def stop_music():
pygame.mixer.music.stop()
def pause_music():
“”“暂停音乐”""
if pygame.mixer.music.get_busy():
pygame.mixer.music.pause()
return False
def unpause_music():
“”“解除暂停”""
if pygame.mixer.music.get_busy():
pygame.mixer.music.unpause()
return True
def next_music(music_num, Music_list):
#下一曲.
music_num[0] += 1
check_music(music_num, Music_list)
try:
load_music(Music_list[music_num[0]])
play_music()
except:
pass
def previous_music(music_num, Music_list):
#上一曲
music_num[0] -= 1
check_music(music_num, Music_list)
try:
load_music(Music_list[music_num[0]])
play_music()
except:
pass
def volume_music(volume):
#调节音量
pygame.mixer.music.set_volume(volume[0])
print(“音量:”+str(100*volume[0]))
def check_music(music_num, Music_List):
if abs(music_num[0]) < len(Music_List):
pass
else:
music_num[0] = 0
return music_num
3.2 button模块
本模块主要负责点击按钮的显示,在本作业中,点击事件分两部分,一个是主窗体的音乐相关操作,包括开始,暂停等,第二部分就是音乐的播放顺序选择。所以在本作业中有两个类来进行,第一个是Button类,是用来显示按钮和判断按钮的位置,用screen.blit方法进行显示按钮图片,还需要新增一个click_button来返回点击按钮的事件,最后再加个ro_img来显示个旋转的图片.第二个类是Music_Mode类来定义各种播放方式。
代码如下:
import random
import pygame
import Load_Music
class Button():
def __init__(self, screen, add, name, place):
self.screen = screen
self.add = add#路径
self.name = name#按钮功能(没卵用....)
self.place = place#按钮绘制位置
self.mybt = pygame.image.load(r''+self.add)#图片地址
self.rect = self.mybt.get_rect()#获取图案矩形
self.angle = 1#图像旋转角度
def click_button(self,mouse_x,mouse_y):
"""判定点击按钮"""
if (mouse_x > self.place[0] and mouse_x < self.rect.width+(self.place[0])
and mouse_y > self.place[1] and mouse_y < self.rect.height+(self.place[1])):
return True
def show_button(self):
"""显示按钮"""
self.screen.blit(self.mybt, self.place)
def ro_img(self):#旋转图像
newimg = pygame.transform.rotozoom(self.mybt, self.angle, 1.0)
newrect = newimg.get_rect(center=(300,248))#固定图像中心
self.screen.blit(newimg, newrect)
self.angle += 1
class Music_Mode(Button):
def change_img(self, add):
self.add = add
self.mybt = pygame.image.load(r''+self.add)#图片地址
super().show_button()
def order_play(self, music_num, music_list):#顺序播放
if not pygame.mixer.music.get_busy():
Load_Music.next_music(music_num, music_list)
def Single_cycle(self):#单曲循环
if not pygame.mixer.music.get_busy():
Load_Music.play_music()
def random_play(self, music_num, music_list):#随机播放
if not pygame.mixer.music.get_busy():
music_num[0] = random.randint(0, len(music_list)-1)
Load_Music.load_music(music_list[music_num[0]])
Load_Music.play_music()
3.3function模块
在本模块中,要实现点击按钮事件,要有两方法,def check_events(music_num, volume, Music_List): """响应按键事件""" 和def get_click(get_mouse, play_bt, pause_bt, next_bt, previous_bt, show_bt, music_num, Music_list, music_run, play_mode, mode)
检测鼠标点击事件。
import sys
import pygame
from button import Button
import Load_Music
def check_events(music_num, volume, Music_List):
“”“响应按键”""
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
Load_Music.next_music(music_num, Music_List)
if event.key == pygame.K_LEFT:
Load_Music.previous_music(music_num, Music_List)
if event.key == pygame.K_p:
Load_Music.pause_music()
if event.key == pygame.K_SPACE:
Load_Music.unpause_music()
if event.key == pygame.K_KP_ENTER:
Load_Music.load_music(Music_List[music_num[0]])
Load_Music.play_music()
if event.key == pygame.K_UP:
volume[0] += 0.1
Load_Music.volume_music(volume)
if event.key == pygame.K_DOWN:
volume[0] -= 0.1
Load_Music.volume_music(volume)
if event.type == pygame.MOUSEBUTTONDOWN:
mouse_x, mouse_y = pygame.mouse.get_pos()
mouse = [mouse_x, mouse_y]
return mouse
def get_click(get_mouse, play_bt, pause_bt, next_bt, previous_bt, show_bt, music_num, Music_list, music_run, play_mode, mode):
“”“检测鼠标点击”""
if get_mouse != None :#是否有点击事件
mouse = get_mouse
if play_bt.click_button(mouse[0], mouse[1]):
music_run[0] = Load_Music.play_music()
elif pause_bt.click_button(mouse[0], mouse[1]):
if music_run[0] and pygame.mixer.music.get_busy():
music_run[0] = Load_Music.pause_music()
else:
music_run[0] = Load_Music.unpause_music()
elif next_bt.click_button(mouse[0], mouse[1]):
Load_Music.next_music(music_num, Music_list)
elif previous_bt.click_button(mouse[0], mouse[1]):
Load_Music.previous_music(music_num, Music_list)
elif show_bt.click_button(mouse[0], mouse[1]):
music_run[0] = Load_Music.unpause_music()
elif play_mode.click_button(mouse[0], mouse[1]):
mode[0] += 1
if mode[0] > 3:
mode[0] = 1
3.4主模块Music_Player
在本模块中,要先进行窗口的创建,然后进行各个变量的初始化,包括音乐序号,音量,音乐列表和播放顺序。并且创建点击按钮的对象。之后对左上的顺序进行获取与实现。
代码如下:
import pygame
import Load_Music
import function
from button import Button
from button import Music_Mode
def player_run():
pygame.init()
screen = pygame.display.set_mode((630, 892))
pygame.display.set_caption(“Music Player”)
background=pygame.image.load(r"./img/bg.jpg")#背景图
screen.blit(background,(0,0))
music_num = [0]#音乐序号
volume = [1] #初始化音量
Music_list = Load_Music.Music_List().get_play_list()#获取音乐列表
Load_Music.load_music(Music_list[music_num[0]])
music_run = [True]#音乐是否被暂停
pygame.time.Clock().tick(30)#限制30帧
mode = [1] #初始化播放模式为顺序播放
#创建按钮对象
play_bt = Button(screen=screen, add="./img/play.png", name="play_music", place=[250, 600])
next_bt = Button(screen=screen, add="./img/next.png", name="next_music", place=[400, 600])
previous_bt = Button(screen=screen, add="./img/previous.png", name="previous_music", place=[100, 600])
pause_bt = Button(screen=screen, add="./img/pause.png", name="pause_music", place=[250, 450])
show_bt = Button(screen=screen, add="./img/show.png", name="show_music", place=[150, 100])
play_mode = Music_Mode(screen=screen, add="./img/order.png", name="play_mode", place=[0, 0])
while True:
get_mouse = function.check_events(music_num, volume, Music_list)
function.get_click(get_mouse, play_bt, pause_bt, next_bt, previous_bt,
show_bt, music_num, Music_list, music_run, play_mode, mode)
show_bt.show_button()
play_bt.show_button()
next_bt.show_button()
previous_bt.show_button()
pause_bt.show_button()
if mode[0] == 1:
play_mode.change_img(add="./img/order.png")
play_mode.order_play(music_num, Music_list)
elif mode[0] == 2:
play_mode.change_img(add="./img/single.png")
play_mode.Single_cycle()
elif mode[0] == 3:
play_mode.change_img(add="./img/random.png")
play_mode.random_play(music_num, Music_list)
else:
play_mode.change_img(add="./img/order.png")
play_mode.order_play(music_num, Music_list)
mode[0] = 1
if pygame.mixer.music.get_busy() and music_run[0]:#音乐播放图片开始转动
show_bt.ro_img()
pygame.display.flip()
player_run()
4.实验结果
5.总结和展望
通过这次作业,我掌握了pygame的基本使用技巧,掌握了基于pygame的播放器的写法
本系统的缺陷也是明显的,如安全性,效率问题等等。由于时间,能力,国内JAVA,JSP技术资料有限等原因,有些功能实现的并不完美,在已经完成的程序中,也存在许多不尽人意的算法,也没有统一优化,系统有待进一步改善,而这些问题也让我充分认识到了软件开发的困难。
通过作业,我学会了如何去了解一种新型的技术,去掌握一种技术。以及软件开发的基本流程。在学习过程中,我们遇到问题经常上网求助,去商品店查询资料,扩大了自己的知识面。
总之,这次作业为我今后继续学习、深造奠定了基础,我非常感谢各位老师、同学的支持与帮助。