python - Pygame 幻灯片延迟通常很长

标签 python pygame framebuffer libvlc pygame-surface

我正在设置一个混合图像和视频的幻灯片系统,来自一个目录。 我正在使用 Raspberry Pi B、pygame 和 vlc。 我没有安装 X,所以一切都发生在帧缓冲区中。

我的实际代码可以正常工作,但是:

  • 没有遵守 4 秒延迟。图像显示 +- 11 秒。
  • 其中一张图片没有什么特别之处,显示时间更长,+- 1 米 30。 (我真正的问题)

我用 fbi、fim、vlc 尝试了一个 bash 脚本,但没有得到合适的结果。最接近的是使用 vlc,但在帧缓冲区中渲染图像花费的时间太长。

我是 pygame 的新手。这是代码:

import pygame
import sys
import time
import vlc
import os


filesdir = '/home/pi/SMBmount/'

pygame.init()

size = (pygame.display.Info().current_w, pygame.display.Info().current_h)
black = 0, 0, 0

screen = pygame.display.set_mode(size)

while True:
    # For every file in filesdir :
    for filename in os.listdir(filesdir):
        filenamelower = filename.lower()

        # If image:
        if filenamelower.endswith('.png') or filenamelower.endswith('.jpg') or filenamelower.endswith('.jpeg'):
            fullname = filesdir + filename
            img = pygame.image.load(fullname)
            img = pygame.transform.scale(img, size)
            imgrect = img.get_rect()

            screen.fill(black)
            screen.blit(img, imgrect)
            pygame.mouse.set_visible(False)
            pygame.display.flip()

            time.sleep(4)

        # Elif video:
        elif filenamelower.endswith('.mp4') or filenamelower.endswith('.mkv') or filenamelower.endswith('.avi'):
            fullname = filesdir + filename
            # Create instane of VLC and create reference to movie.
            vlcInstance = vlc.Instance("--aout=adummy")
            media = vlcInstance.media_new(fullname)

            # Create new instance of vlc player
            player = vlcInstance.media_player_new()

            # Load movie into vlc player instance
            player.set_media(media)

            # Start movie playback
            player.play()

            # Do not continue if video not finished
            while player.get_state() != vlc.State.Ended:
                # Quit if keyboard pressed during video
                for event in pygame.event.get():
                    if event.type == pygame.KEYDOWN:
                        pygame.display.quit()
                        pygame.quit()
                        sys.exit()
            player.stop()

        # Quit if keyboard pressed during video
        for event in pygame.event.get():
            if event.type == pygame.KEYDOWN:
                pygame.display.quit()
                pygame.quit()
                sys.exit()

我愿意接受任何能够处理图片和视频的替代方法。

编辑:终于到了 pygame 使用 pygame.transform.scale() 调整(下一个)图像大小的时间了。

有什么办法可以优化吗?例如,打印全屏而不调整大图像的大小?

最佳答案

如果没有图像和视频,我无法重现该行为,但这里有一些建议应该有助于在显示图像时加快代码速度。

  1. 不要使用time.sleep()。它会在给定的时间内卡住游戏,因此所有计算都在这个时间窗口之外完成,消耗更多时间。最好用pygame time Clock .从其 tick() 方法的文档中:

    If you pass the optional framerate argument the function will delay to keep the game running slower than the given ticks per second. This can be used to help limit the runtime speed of a game. By calling Clock.tick(40) once per frame, the program will never run at more than 40 frames per second.

    tick() 方法应该在主循环中每次迭代调用一次,所以最好不要将它放在 if 语句中。

    <
  2. 这里:

    screen.fill(black)
    screen.blit(img, imgrect)
    

    第一行 screen.fill(black) 完全没用:您在第二行中重绘了整个表面,覆盖了所有黑色背景,因为图像已重新调整为屏幕大小。您可以安全地blit 图像而不用黑色填充背景。
    这样会节省时间,因为每次使用blitfill时,后台的pygame都会对Surface做很多操作来改变颜色像素(像素变化越多,所需时间越长)。

    如果您加载的任何图像具有 alpha channel ,当然会这样。如果你有带 alpha channel 的图片,你需要先把背景涂黑。为了节省时间,我建议使用其他程序从图像中删除 alpha channel 。

  3. pygame.transform.scale() 需要时间,尤其是当您有非常大的图片时。尝试使用另一个程序重新缩放图像,并加载尺寸尽可能接近屏幕的 pygame 图像。

  4. 加载图片时,添加.convert()。这将使 blitting 更快。应该是:img = pygame.image.load(fullname).convert()

最后,您的代码应如下所示:

imgexts = ['png', 'jpg', 'jpeg']
videxts = ['mp4', 'mkv']

#filtering out non video and non image files in the directory using regex
#remember to import re module
showlist = [filename for filename in os.listdir(filesdir) if re.search('[' + '|'.join(imgexts + videxts) + ']$', filename.lower())]

clock = pygame.time.Clock()
while True:
    # For every file in filesdir :
    for filename in showlist:
        filenamelower = filename.lower()

        # If image:
        if filenamelower.endswith('.png') or filenamelower.endswith('.jpg') or filenamelower.endswith('.jpeg'):
            #all your stuff but NOT the time.sleep()

        elif filenamelower.endswith('.mp4') or filenamelower.endswith('.mkv') or filenamelower.endswith('.avi'):
            #unchanged here

        clock.tick(0.25) #framerate = 0.25 means 1 frame each 4 seconds
        for event in pygame.event.get():
            #unchanged here

关于python - Pygame 幻灯片延迟通常很长,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57286669/

相关文章:

python - 在python中编辑文件

python - pygame连续和同时按键输入

java - Android Opengl ES 2.0 FrameBuffer 不工作

javascript - 如果我直接嵌入数据,为什么 MozAudioAvailable 的 Framebuffer 会抛出?

linux - 使用 fbi 作为幻灯片会导致肖像图像自动旋转

python - 我将如何创建 Python 模块?

python - 从一维列表创建二维列表

linux - ubuntu上仍然无法安装pygame

python-sqlite3.OperationalError : near "<": syntax error

Pygame 级别/菜单状态