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):
        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)
        self.clock = pygame.time.Clock()
        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(self):
        if self.media_type == 'video':
            self.media.play()
            self.paused = False
        elif self.media_type == 'audio':
            pygame.mixer.music.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):
        if self.media_type == 'audio':
            current_time = pygame.mixer.music.get_pos() - 10000
            if current_time < 0:
                current_time = 0
            pygame.mixer.music.set_pos(current_time)
        elif self.media_type == 'video':
            current_time = self.media.get_time() - 10000
            if current_time < 0:
                current_time = 0
            self.media.set_time(current_time)

    def fast_forward(self):
        if self.media_type == 'audio':
            current_time = pygame.mixer.music.get_pos() + 10000
            if current_time > self.duration:
                current_time = self.duration
            pygame.mixer.music.set_pos(current_time)
        elif self.media_type == 'video':
            current_time = self.media.get_time() + 10000
            if current_time > self.duration:
                current_time = self.duration
            self.media.set_time(current_time)

    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_time(self):
        current_time_text = self.format_time(self.current_time)
        duration_text = self.format_time(self.duration)
        time_text = f'{current_time_text} / {duration_text}'
        font = pygame.font.SysFont(None, self.FONT_SIZE)
        self.draw_text(time_text, font, self.WHITE, (10, 10))

    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 draw_pause_icon(self):
        if self.paused:
            font = pygame.font.SysFont(None, self.FONT_SIZE)
            pause_surface = font.render('PAUSE', True, self.GRAY)
            self.screen.blit(pause_surface, ((self.SCREEN_SIZE[0] - pause_surface.get_width()) // 2, (self.SCREEN_SIZE[1] - pause_surface.get_height()) // 2))

    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_time()
                self.draw_pause_icon()
                pygame.display.update()
            self.clock.tick(60)


if __name__ == '__main__':
    player = PygamePlayer()
    player.run()
Pygame 媒体播放器:功能丰富、易于使用

原文地址: https://www.cveoy.top/t/topic/otBj 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录