You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何将Moviepy视频调整为全屏适配640x400的Pygame游戏窗口?

How to Resize MoviePy Video to Fit 640x400 Pygame Window

Great question—since Pygame’s old movie module is long deprecated, MoviePy is the right replacement for video playback, but I totally get the frustration with sparse documentation. Let’s get that video fitting your 640x400 window properly, whether you want to maintain aspect ratio (no distortion) or stretch it to fill the screen. Here’s a complete, tested solution:

Step 1: Resize the Video Clip in MoviePy

First, you’ll need to adjust your video clip to match your window dimensions. You have two main options:

Option 1: Fit to Window (Maintain Aspect Ratio)

This keeps the video’s original proportions, adding small black bars (letterboxing/pillarboxing) if the video’s aspect ratio doesn’t match 640x400 (16:10). This is the recommended approach to avoid distortion:

from moviepy.editor import VideoFileClip
import pygame

# Load your video
clip = VideoFileClip("your_cutscene.mp4")

# Target window dimensions
TARGET_W, TARGET_H = 640, 400

# Calculate scaling factor to fit within the window
scale_factor = min(TARGET_W / clip.size[0], TARGET_H / clip.size[1])
resized_clip = clip.resize(scale_factor)

Option 2: Stretch to Exact Window Size

If you don’t mind distorting the video to fill the entire window, use this instead:

resized_clip = clip.resize((TARGET_W, TARGET_H))

Bonus: Fill Window Without Black Bars

To fill the entire window while maintaining aspect ratio (cropping excess video), use a combination of resize and crop:

# Resize to fill the window height, then crop the width to 640
resized_for_height = clip.resize(height=TARGET_H)
cropped_clip = resized_for_height.crop(x_center=resized_for_height.size[0]/2, width=TARGET_W)

# Or resize to fill the window width, then crop the height
resized_for_width = clip.resize(width=TARGET_W)
cropped_clip = resized_for_width.crop(y_center=resized_for_width.size[1]/2, height=TARGET_H)

Step 2: Integrate with Pygame

Now you need to render the resized video frames to your Pygame window. The key here is converting MoviePy’s numpy frame arrays to Pygame surfaces and syncing the frame rate correctly:

# Initialize Pygame
pygame.init()
screen = pygame.display.set_mode((TARGET_W, TARGET_H))
clock = pygame.time.Clock()

video_fps = resized_clip.fps
frame_delay = 1000 / video_fps  # Milliseconds per frame
last_frame_time = pygame.time.get_ticks()
current_video_time = 0.0

# Main game loop
running = True
while running and current_video_time < resized_clip.duration:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    # Update frame when enough time has passed
    now = pygame.time.get_ticks()
    if now - last_frame_time >= frame_delay:
        # Get current frame from the video
        frame = resized_clip.get_frame(current_video_time)
        # Convert numpy frame to Pygame surface (swap axes: MoviePy uses (height, width) vs Pygame's (width, height))
        frame_surface = pygame.surfarray.make_surface(frame.swapaxes(0, 1))
        
        # Calculate position to center the frame (only needed for Option 1)
        x_pos = (TARGET_W - resized_clip.size[0]) // 2
        y_pos = (TARGET_H - resized_clip.size[1]) // 2
        
        # Blit to screen and update display
        screen.blit(frame_surface, (x_pos, y_pos))
        pygame.display.flip()
        
        # Update time tracking
        current_video_time += 1 / video_fps
        last_frame_time = now

    clock.tick(60)  # Keep the loop running smoothly

# Cleanup resources
resized_clip.close()
pygame.quit()

Key Tips

  • swapaxes(0,1) is critical: MoviePy returns frames as (height, width, channels) arrays, but Pygame expects (width, height)—this fixes the orientation.
  • Frame rate sync: Using pygame.time.get_ticks() ensures the video plays at its native speed, avoiding choppy playback.
  • Resource cleanup: Always call clip.close() to free up memory after the video finishes.

内容的提问来源于stack exchange,提问作者Moe

火山引擎 最新活动