How to load and play a video in pygame

I'm having a problem. I want to load and play a video in pygame but it doesn't start. The only thing that I am seeing is a black screen. Here is my code:

import pygame
from pygame import display,movie
pygame.init()
screen = pygame.display.set_mode((1024, 768))
background = pygame.Surface((1024, 768))

screen.blit(background, (0, 0))
pygame.display.update()

movie = pygame.movie.Movie('C:\Python27\1.mpg')
mrect = pygame.Rect(0,0,140,113)
movie.set_display(screen, mrect.move(65, 150))
movie.set_volume(0)
movie.play()

Can you help me??


You are not actually blitting it to a screen. You are also not utilizing a clock object so it will play as fast as possible. Try this:

# http://www.fileformat.info/format/mpeg/sample/index.dir
import pygame

FPS = 60

pygame.init()
clock = pygame.time.Clock()
movie = pygame.movie.Movie('MELT.MPG')
screen = pygame.display.set_mode(movie.get_size())
movie_screen = pygame.Surface(movie.get_size()).convert()

movie.set_display(movie_screen)
movie.play()


playing = True
while playing:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            movie.stop()
            playing = False

    screen.blit(movie_screen,(0,0))
    pygame.display.update()
    clock.tick(FPS)

pygame.quit()

I just got that MELT.MPG from the link provided in the comment. You should be able to simply switch out that string for your actual MPG you want to play and it will work... maybe.


The pygame.movie is deprecated and not longer supported.


If you only want to show the video you can use MoviePy (see also How to be efficient with MoviePy):

import pygame
import moviepy.editor

pygame.init()
video = moviepy.editor.VideoFileClip("video.mp4")
video.preview()
pygame.quit()

An alternative solution is to use the OpenCV VideoCapture. Install OpenCV for Python (cv2) (see opencv-python). However, it should be mentioned that cv2.VideoCapture does not provide a way to read the audio from the video file.
This is only a solution to view the video but no audio is played.

Opens a camera for video capturing:

video = cv2.VideoCapture("video.mp4")

Get the frames per second form the VideoCapture object:

fps = video.get(cv2.CAP_PROP_FPS)

Create a pygame.time.Clock:

clock = pygame.time.Clock()

Grabs a video frame and limit the frames per second in the application loop:

clock.tick(fps)
success, video_image = video.read()

Convert the camera frame to a pygame.Surface object using pygame.image.frombuffer:

video_surf = pygame.image.frombuffer(video_image.tobytes(), video_image.shape[1::-1], "BGR")

See also Video:


Minimal example:

import pygame
import cv2

video = cv2.VideoCapture("video.mp4")
success, video_image = video.read()
fps = video.get(cv2.CAP_PROP_FPS)

window = pygame.display.set_mode(video_image.shape[1::-1])
clock = pygame.time.Clock()

run = success
while run:
    clock.tick(fps)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
    
    success, video_image = video.read()
    if success:
        video_surf = pygame.image.frombuffer(
            video_image.tobytes(), video_image.shape[1::-1], "BGR")
    else:
        run = False
    window.blit(video_surf, (0, 0))
    pygame.display.flip()

pygame.quit()
exit()

As you probably know, the pygame.movie module is deprecated and no longer exists in the latest version of pygame.

An alternative would be to read in frames of the video one by one and blit them onto the pygame screen using the the cv2 module (OpenCV), that can be installed with the command prompt command:

pip install opencv-python

Then, you can run the code:

import cv2
import pygame

cap = cv2.VideoCapture('video.mp4')
success, img = cap.read()
shape = img.shape[1::-1]
wn = pygame.display.set_mode(shape)
clock = pygame.time.Clock()

while success:
    clock.tick(60)
    success, img = cap.read()
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            success = False
    wn.blit(pygame.image.frombuffer(img.tobytes(), shape, "BGR"), (0, 0))
    pygame.display.update()

pygame.quit()