How to achive exactly 25 images per second. Pygame

Viewed 46

Each frame I take audio frequencies read them and convert them into a visual way. Then I take a picture.

My problem is that the following approach takes a different amount of images each second. So when I convert images into a video it becomes shorter than the audio that played as input (~5-10 seconds shorter).

FPS = 25
clock = pygame.time.Clock()

pygame.mixer.music.load(filename)
pygame.mixer.music.play(0)

running = True 
while running and pygame.mixer.music.get_busy():

    print(clock.get_fps()) #output 21 - 25 FPS

    t = pygame.time.get_ticks()
    deltaTime = (t - getTicksLastFrame) / 1000.0
    getTicksLastFrame = t

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    screen.fill((0, 0, 0))

    for b in bars:
        b.update(deltaTime, get_decibel(pygame.mixer.music.get_pos() / 1000.0, b.freq))
        b.render(screen)

    pygame.display.flip()

    pygame.display.update()
    video.make_png(screen)
    clock.tick(FPS)

I was thinking about slow down audio, so I will take only (12+- images per second), but this approach wouldn't work either because the FPS cap isn't stable. Another way I was thinking about is to stretch somehow the video to the length of the audio with an FFmpeg... However, I believe that there should be a more elegant solution.

Will really appreciate any advice!

1 Answers

Use tick_busy_loop() instead of tick().

clock.tick(FPS)

clock.tick_busy_loop(FPS)

tick():

[...] this function uses SDL_Delay function which is not accurate on every platform, but does not use much CPU.

tick_busy_loop():

[...] this function uses pygame.time.delay() which uses lots of CPU in a busy loop to make sure that timing is more accurate.

Related