2013-01-22 27 views
7

Mam nadzieję, że to pytanie nie jest z natury bezsensowne.Czy można uruchomić Pygame jako cronjob?

Rozwijam grę. Wyodrębniłem podstawowy silnik gry (w języku Python) z komponentu graficznego. Mam skrypt, który fuzzes niektóre parametry, symuluje część gry za pomocą silnika gry, a następnie wizualizuje go za pomocą Pygame.

Chciałbym zautomatyzować następujący proces: Symulacja

  1. uruchamiany jako cronjob
  2. wizualizację za pomocą Pygame (headlessly)
  3. wizualizacja Zapisz jako plik krótki (~ 10 sec) wideo
  4. Programowo przesłać film wideo do serwisu YouTube

Idealnie, chciałbym to zrobić kilka razy dziennie tak m nietechniczne żar z mojego zespołu mógł obejrzeć film i wyrazić opinię na temat wizualnych aspektów gry.

Chciałbym użyć Pygame, ponieważ mam już gotowy kod. Ale podejrzewam, że prawdopodobnie powinienem użyć czegoś podobnego do PIL, aby stworzyć serię plików graficznych i przejść od tego miejsca.

Czy to możliwe w przypadku Pygame? Czy powinienem używać tylko PIL? Jakieś inne pomysły na osiągnięcie czegoś takiego?

Odpowiedz

3

Zakładając, że korzystasz z Linux-a, a twój silnik graficzny pracuje w X, możesz bez żadnego wysiłku uruchomić dowolną aplikację, używając Xvfb (X virtual framebuffer). Możesz uruchomić koder wideo wirtualnej (bezgłowej) sesji bufora ramki. Istnieje kilka narzędzi, aby ułatwić to zadanie:

pewnością chcesz, aby skrypt najwyższego poziomu, które:

  • Rozruch Xvfb
  • Uruchom koder wideo (np. Ffmpeg)
  • Uruchom grę w Xvfb. Nie musisz modyfikować swojej gry w żaden sposób, zakładając, że może ona działać bez wprowadzania użytkownika, po prostu ustaw zmienną środowiskową DISPLAY na poprawną wartość.
  • Zakończyć kodowanie wideo
  • Prześlij film na youtube

Xvfb i ffmpeg są zdecydowanie droga do nagrywania grę headlessly zapewnia to można nagrać swoją grę jak jest bez żadnych modyfikacji. Powinien być wykonalny, ale niekoniecznie łatwy. Powyższe skrypty powinny, miejmy nadzieję, zacząć.

1

Anton's answer zainspirowało mnie do głębszego wniknięcia w to pytanie. Na szczęście odkryłem, że jest możliwe run Pygame headlessly, co pozwoliło mi osiągnąć to, co chciałem zrobić nieco prościej niż metoda Antona.

Podstawowy przepływ pracy wygląda następująco: pygame

  1. Instalator uruchomić headlessly
  2. Uruchom moją grę, oszczędzając wyświetlanego obrazu dla każdej klatki, używając Pygame
  3. Tworzenie wideo z plików graficznych przy użyciu ffmpeg
  4. Załaduj film na Youtube, korzystając z youtube-upload

Przykładowy kod (uproszczona wersja mojego własnego kodu, więc nie został ściśle kontrolowane):

# 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='[email protected]' 
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) 

Wy zapewne chcesz usunąć wszystkie pliki graficzne raz film powstał.

miałem trochę problemów przechwytywania zrzutów ekranu headlessly, którą pracowali jak opisano tutaj: In Pygame, how can I save a screen image in headless mode?

byłem w stanie zaplanować mój skrypt uruchamiany jako cronjob bez problemów.

+0

Cieszę się, że mogę Ci pomóc, i mam nadzieję, że opisana metoda działa dobrze. W zależności od długości przechwytywania, martwię się o całą przestrzeń dyskową potrzebną do przechwytywania obrazów i procesor potrzebny do przekonwertowania ich na wideo (kodowanie sesji Xvfb powinno być tańsze, ponieważ nie potrzebuje png dekodowanie każdej klatki). Xvfb/ffmpeg razem teoretycznie byłoby mniej podatne. –

Powiązane problemy