可以将Pygame作为cronjob运行吗?

时间:2013-01-22 02:22:44

标签: python pygame

我希望这个问题本身并不荒谬。

我正在开发一款游戏。我已经从图形组件中分离出底层游戏引擎(在Python中)。我有一个脚本可以模糊一些参数,使用游戏引擎模拟游戏的一部分,然后使用Pygame将其可视化。

我想自动执行以下过程:

  1. 将模拟作为cronjob运行
  2. 使用Pygame(无头地)可视化它
  3. 将可视化保存为短(~10秒)视频文件
  4. 以编程方式将视频上传到Youtube
  5. 理想情况下,我想每天做几次,这样我的团队的非技术人员就可以观看视频并提供有关游戏视觉方面的反馈。

    我想使用Pygame,因为我已经准备好了代码。但我怀疑我应该使用像PIL这样的东西来创建一系列图像文件并从那里开始。

    这可能与Pygame有关吗?我应该只使用PIL吗?有没有其他想法来完成这样的事情?

2 个答案:

答案 0 :(得分:3)

假设您在Linux上运行,并且您的图形引擎在X中运行,您可以使用Xvfb(X虚拟帧缓冲区)无头地运行您想要的任何应用程序。您可以运行虚拟(无头)帧缓冲区会话的视频编码器。有几个实用程序可以使这项任务更容易:

你想制作一个顶级脚本:

  • 启动Xvfb
  • 启动视频编码器(即ffmpeg)
  • 在Xvfb中运行您的游戏。您不应该以任何方式修改游戏,假设它可以在没有用户输入的情况下运行,只需将DISPLAY环境变量设置为正确的值。
  • 结束视频编码
  • 将视频上传到youtube

Xvfb和ffmpeg绝对是无头录制游戏的方式,这可以确保您可以按原样录制游戏而无需修改。它应该是可行的,但不一定容易。上述脚本应该可以帮助您入门。

答案 1 :(得分:2)

Anton's answer激励我深入研究这个问题。令人高兴的是,我发现有可能run Pygame headlessly,使我能够比安东的方法更加简单地完成我想做的事。

基本工作流程如下:

  1. 设置pygame无头地运行
  2. 运行我的游戏,使用Pygame
  3. 为每个帧保存一个屏幕图像
  4. 使用ffmpeg
  5. 从图像文件创建视频
  6. 使用youtube-upload
  7. 将视频上传到Youtube

    示例代码(我自己的代码的简化版本,因此尚未经过严格测试):

    # imports
    import os
    import subprocess
    import pygame
    import mygame
    
    # setup pygame to run headlessly
    os.environ['SDL_VIDEODRIVER'] = 'dummy'
    pygame.display.set_mode((1,1))
    
    # can't use display surface to capture images for some reason, so I set up
    # my own screen using a pygame rect
    width, height = 400, 400
    black = (0,0,0)
    flags = pygame.SRCALPHA
    depth = 32
    screen = pygame.Surface((width, height), flags, depth)
    pygame.draw.rect(screen, black, (0, 0, width, height), 0)
    
    # my game object: screen becomes attribute of game object: game.screen
    game = mygame.MyGame(screen)
    
    # need this file format for saving images and encoding video with ffmpeg
    image_file_f = 'frame_%03d.png'
    
    # run game, saving images of each screen
    game.init()
    while game.is_running:
        game.update()   # updates screen
        image_path = image_file_f % (game.frame_num)
        pygame.image.save(game.screen, image_path)
    
    # create video of images using ffmpeg
    output_path = '/tmp/mygame_clip_for_youtube.mp4'
    
    ffmpeg_command = (
        'ffmpeg',
        '-r', str(game.fps),
        '-sameq',
        '-y',
        '-i', image_file_f,
        output_path
    )
    
    subprocess.check_call(ffmpeg_command)
    print "video file created:", output_path
    
    # upload video to Youtube using youtube-upload
    gmail_address='your.name@gmail.com'
    gmail_password='test123'
    
    upload_command = (
        'youtube-upload',
        '--unlisted',
        '--email=%s' % (gmail_address),
        '--password=%s' % (gmail_password),
        '--title="Sample Game Clip"',
        '--description="See https://stackoverflow.com/q/14450581/1093087"',
        '--category=Games',
        output_path
    )
    
    proc = subprocess.Popen(
        upload_command,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE
    )
    out, err = proc.communicate()
    
    print "youtube link: %s" % (out)
    

    您可能希望在创建视频后删除所有图像文件。

    我在无头捕获屏幕截图时遇到了一些麻烦,我按照此处的描述进行了处理:In Pygame, how can I save a screen image in headless mode?

    我能够安排我的脚本作为cronjob运行而没有问题。