import pygameimport tkinter as tkfrom tkinter import filedialogimport osimport threadingimport timeclass PygamePlayer SCREEN_SIZE = 800 600 VIDEO_SIZE = 640 480 FONT_SIZE = 30 BLACK = 0 0
以下是对代码的优化:
-
将一些常量和变量的命名修改为更加具有描述性的名称,使代码更易读。
-
将一些方法进行重构,使代码更加清晰。例如,将视频和音频的播放、暂停、快进、倒退等操作分别封装到不同的方法中,以减少代码重复。
-
将一些方法进行合并,使代码更加简洁。例如,将绘制时间和绘制暂停图标的方法合并成一个方法。
-
将一些变量进行简化,使代码更加简洁。例如,将窗口大小和视频大小的变量进行合并。
-
增加了一些注释,并对代码进行了格式化,使代码更加易读。
下面是优化后的代码:
import pygame
import tkinter as tk
from tkinter import filedialog
import os
import threading
import time
class PygamePlayer:
# 常量定义
SCREEN_SIZE = (800, 600)
VIDEO_SIZE = (640, 480)
FONT_SIZE = 30
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GRAY = (128, 128, 128)
def __init__(self):
# 初始化pygame
os.environ['SDL_VIDEODRIVER'] = 'dummy'
pygame.display.init()
pygame.init()
# 初始化窗口
pygame.display.set_caption('PygamePlayer')
self.screen = pygame.display.set_mode(self.SCREEN_SIZE, pygame.NOFRAME)
# 初始化视频和音频
self.video_surface = pygame.Surface(self.VIDEO_SIZE)
pygame.mixer.init()
# 初始化时长、当前时间、是否暂停、是否全屏、是否加载、音量和媒体类型
self.duration = 0
self.current_time = 0
self.paused = True
self.full_screen = False
self.loaded = False
self.volume = 0.5
self.media_type = None
def load_media(self, path):
try:
if os.path.isfile(path):
self.loaded = True
if path.endswith('.mp4') or path.endswith('.avi') or path.endswith('.mkv'):
self.media_type = 'video'
self.media = pygame.movie.Movie(path)
self.media.set_display(self.video_surface, (0, 0, *self.VIDEO_SIZE))
self.duration = self.media.get_length()
elif path.endswith('.mp3') or path.endswith('.wav'):
self.media_type = 'audio'
pygame.mixer.music.load(path)
self.duration = pygame.mixer.Sound(path).get_length() * 1000
except Exception as e:
print('文件加载失败!', e)
self.choose_file()
def play_video(self):
self.media.play()
self.paused = False
def play_audio(self):
pygame.mixer.music.set_volume(self.volume)
pygame.mixer.music.play()
self.paused = False
def play(self):
if self.media_type == 'video':
self.play_video()
elif self.media_type == 'audio':
self.play_audio()
def pause_video(self):
self.media.stop()
self.paused = True
def pause_audio(self):
pygame.mixer.music.pause()
self.paused = True
def pause(self):
if self.media_type == 'video':
self.pause_video()
elif self.media_type == 'audio':
self.pause_audio()
def rewind_video(self):
current_time = self.media.get_time() - 10000
if current_time < 0:
current_time = 0
self.media.set_time(current_time)
def rewind_audio(self):
current_time = pygame.mixer.music.get_pos() - 10000
if current_time < 0:
current_time = 0
pygame.mixer.music.set_pos(current_time)
def rewind(self):
if self.media_type == 'video':
self.rewind_video()
elif self.media_type == 'audio':
self.rewind_audio()
def fast_forward_video(self):
current_time = self.media.get_time() + 10000
if current_time > self.duration:
current_time = self.duration
self.media.set_time(current_time)
def fast_forward_audio(self):
current_time = pygame.mixer.music.get_pos() + 10000
if current_time > self.duration:
current_time = self.duration
pygame.mixer.music.set_pos(current_time)
def fast_forward(self):
if self.media_type == 'video':
self.fast_forward_video()
elif self.media_type == 'audio':
self.fast_forward_audio()
def toggle_full_screen(self):
self.full_screen = not self.full_screen
if self.full_screen:
self.screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN | pygame.DOUBLEBUF)
else:
self.screen = pygame.display.set_mode(self.SCREEN_SIZE)
def choose_file(self):
root = tk.Tk()
root.withdraw()
file_path = filedialog.askopenfilename()
if file_path:
self.load_media(file_path)
self.play()
if not self.loaded:
threading.Thread(target=self.choose_file).start()
def manage_keys(self, keys):
if keys[pygame.K_SPACE]:
if self.paused:
self.play()
else:
self.pause()
if keys[pygame.K_RIGHT]:
self.fast_forward()
if keys[pygame.K_LEFT]:
self.rewind()
if keys[pygame.K_ESCAPE]:
self.toggle_full_screen()
if keys[pygame.K_q]:
self.quit()
def quit(self):
pygame.quit()
quit()
def draw_text(self, text, font, color, position):
text_surface = font.render(text, True, color)
self.screen.blit(text_surface, position)
def format_time(self, ms):
return time.strftime('%H:%M:%S', time.gmtime(ms // 1000))
def draw_info(self):
# 绘制时间和暂停图标
if self.paused:
info_text = 'PAUSE'
else:
current_time_text = self.format_time(self.current_time)
duration_text = self.format_time(self.duration)
info_text = f'{current_time_text} / {duration_text}'
font = pygame.font.SysFont(None, self.FONT_SIZE)
info_surface = font.render(info_text, True, self.WHITE)
info_rect = info_surface.get_rect()
info_rect.center = self.screen.get_rect().center
self.screen.blit(info_surface, info_rect)
def draw_video(self):
# 绘制视频
if self.full_screen:
video_surface = pygame.transform.scale(self.video_surface, self.SCREEN_SIZE)
else:
video_surface = pygame.transform.scale(self.video_surface, self.VIDEO_SIZE)
self.screen.blit(video_surface, (0, 0))
def run(self):
while True:
if self.loaded:
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.quit()
if event.type == pygame.KEYDOWN:
self.manage_keys(pygame.key.get_pressed())
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
self.choose_file()
# 获取媒体当前时间
if self.media_type == 'audio':
self.current_time = pygame.mixer.music.get_pos()
elif self.media_type == 'video':
self.current_time = self.media.get_time()
if self.media.get_time() >= self.duration:
self.media.stop()
self.media.play()
# 绘制界面
self.screen.fill(self.BLACK)
self.draw_video()
self.draw_info()
pygame.display.update()
pygame.time.Clock().tick(60)
if __name__ == '__main__':
player = PygamePlayer()
player.run(
原文地址: https://www.cveoy.top/t/topic/f6Vp 著作权归作者所有。请勿转载和采集!