Python Pygame 音视频播放器 - 使用 Tkinter 选择文件
import pygame
import tkinter as tk
from tkinter import filedialog
import os
import threading
import time
# 定义一些常量
SCREEN_SIZE = (800, 600)
VIDEO_SIZE = (640, 480)
FONT_SIZE = 30
WHITE = (255, 255, 255)
class PygamePlayer:
"""
Pygame 音视频播放器类
"""
def __init__(self, font_size=FONT_SIZE):
"""
初始化播放器
Args:
font_size (int, optional): 字体大小. Defaults to FONT_SIZE.
"""
os.environ['SDL_VIDEODRIVER'] = 'dummy'
pygame.display.init()
pygame.init() # 初始化pygame模块
pygame.display.set_caption('PygamePlayer') # 设置窗口标题
self.screen = pygame.display.set_mode(SCREEN_SIZE, pygame.NOFRAME) # 设置pygame显示屏幕
self.video_surface = pygame.Surface(VIDEO_SIZE) # 创建视频界面
self.clock = pygame.time.Clock() # 创建一个pygame时间对象
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 # 媒体类型,音频或视频
self.font = pygame.font.SysFont(None, font_size) # 设置字体和字体大小
def load_media(self, path):
"""
加载媒体文件
Args:
path (str): 媒体文件路径
"""
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, VIDEO_SIZE[0], VIDEO_SIZE[1])) # 设置视频显示区域
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(f'文件加载失败!{e}')
self.choose_file()
def play(self):
"""
播放媒体文件
"""
if self.media_type == 'video':
self.media.play() # 播放视频
self.paused = False
elif self.media_type == 'audio':
self.set_volume(self.volume)
pygame.mixer.music.play() # 播放音频
self.paused = False
def pause(self):
"""
暂停媒体文件
"""
if self.media_type == 'video':
self.media.stop() # 停止视频
self.paused = True
elif self.media_type == 'audio':
pygame.mixer.music.pause() # 暂停音频
self.paused = True
def rewind(self):
"""
后退10秒
"""
self.set_current_time(self.current_time - 10000)
def fast_forward(self):
"""
快进10秒
"""
self.set_current_time(self.current_time + 10000)
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(SCREEN_SIZE) # 恢复原来的窗口大小
def choose_file(self):
"""
选择媒体文件
"""
root = tk.Tk()
root.withdraw() # 隐藏tk窗口
file_path = filedialog.askopenfilename()
if file_path:
self.load_media(file_path)
self.play()
def set_volume(self, volume):
"""
设置音量
Args:
volume (float): 音量值,范围为0.0到1.0
"""
if self.media_type == 'audio':
pygame.mixer.music.set_volume(volume)
def set_current_time(self, current_time):
"""
设置当前播放时间
Args:
current_time (int): 当前播放时间,单位为毫秒
"""
if self.media_type == 'audio':
if current_time < 0:
current_time = 0
elif current_time > self.duration:
current_time = self.duration
pygame.mixer.music.set_pos(current_time)
elif self.media_type == 'video':
if current_time < 0:
current_time = 0
elif current_time > self.duration:
current_time = self.duration
self.media.set_time(current_time)
def manage_keys(self, keys):
"""
处理键盘事件
Args:
keys (list): 键盘按键状态
"""
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 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()
# 绘制
if self.full_screen:
self.video_surface = pygame.transform.scale(self.video_surface, SCREEN_SIZE)
else:
self.video_surface = pygame.transform.scale(self.video_surface, VIDEO_SIZE)
self.screen.blit(self.video_surface, (0, 0))
# 在屏幕上绘制当前时间和总时间
time_text = time.strftime('%H:%M:%S', time.gmtime(self.current_time / 1000)) + ' / ' + time.strftime('%H:%M:%S', time.gmtime(self.duration / 1000))
time_surface = self.font.render(time_text, True, WHITE) # 创建时间显示surface
self.screen.blit(time_surface, (10, 10)) # 在屏幕上绘制时间
pygame.display.update() # 更新屏幕
self.clock.tick(60) # 设置帧率为60
if __name__ == '__main__':
player = PygamePlayer() # 创建播放器对象
player.run() # 运行播放器
原文地址: https://www.cveoy.top/t/topic/otA2 著作权归作者所有。请勿转载和采集!