Capture d'écran de la vidéo du jeu


8

Je voudrais "accrocher" à un jeu en cours, par exemple Mario Bros, et capturer chaque image rendue ... en enregistrant cette image dans un fichier image. FRAPS est un bon exemple de quelque chose de similaire. --Remarque: je ne veux pas capturer l'ensemble de l'écran / du bureau. Je veux capturer une fenêtre ciblée.

J'ai jeté un œil à OBS (Open Broadcasting Software) mais ce n'est pas particulièrement rapide. Ne vous méprenez pas, c'est un excellent logiciel, mais malheureusement il n'y a pas / peu de documentation, ce qui rend un projet massif écrit en c et c ++ presque inaccessible pour un programmeur débutant en c ++.

J'ai également jeté un œil à GamingAnywhere , mais malheureusement, je ne peux pas le faire fonctionner, il y a très peu / pas de documentation, ne fonctionne que dans VS2010 et est désordonné (avec un mauvais nom de variable). Cependant, il s'agit d'un projet de recherche et il est donc compréhensible que ce soit sans papiers et en désordre.

Je sais que cela peut être fait avec OpenGL, GDI et Direct3D, mais je ne trouve pas de bons exemples sur le net.

J'ai lu que glReadlPixels (en utilisant OpenGL) peut être utilisé et j'ai lu la documentation , mais le post ne mentionnait rien sur la connexion à un jeu / une application graphique en cours d'exécution.

Des questions:

  1. Puis-je me connecter aux graphismes d'un jeu développé avec OpenGL, en utilisant, par exemple, Direct3D? La bibliothèque utilisée pour le hook doit-elle être la même que celle utilisée par le jeu?

  2. Comment puis-je me connecter aux images rendues du jeu afin de pouvoir exporter ces images vers des fichiers image ou vers un fichier vidéo? (Juste quelques liens ou une brève explication de ce que je dois faire serait génial)

  3. BackBuffer - J'ai lu qu'il est très rapide d'accéder au BackBuffer pour récupérer les images. Quelqu'un a-t-il un exemple pour moi sur la façon de procéder avec les dernières bibliothèques? J'ai constaté que la plupart des exemples sont obsolètes.

  4. Pour mes besoins, y a-t-il clairement «c'est plus rapide que ça»? Ce que je veux dire, par exemple, serait OpenGL, serait plus rapide pour mes besoins?

Si quelqu'un connaît un projet open source (qui fait essentiellement ce dont j'ai besoin) qui est activement développé et bien documenté, j'aimerais le savoir.


Maintenant, cela semble être uniquement Mac, ce qui peut ne pas fonctionner pour vous avec Direct3D, mais Siphon Inject qu'OBS utilise sur Mac peut capturer des fenêtres de jeu qui utilisent OpenGL beaucoup plus rapidement que la capture vidéo standard. Siphon "permet aux applications de partager des images - vidéo pleine vitesse ou images fixes - les unes avec les autres en temps réel" pour citer le site Web.
Gliderman

@Gliderman Merci, je vais vérifier ça!
pookie

Réponses:


7

Il est possible de faire ce que vous décrivez, mais je crains que ce ne soit pas un processus trivial. En fait, cela sera très lié aux systèmes d'exploitation que vous ciblez et nécessitera peut-être également des ajustements spécifiques pour le jeu / l'application donné.

Je commencerais à étudier les techniques d' injection de DLL , qui devraient permettre, par exemple, d'intercepter les appels aux API Direct3D (Windows) ou OpenGL, que vous pouvez ensuite utiliser pour copier les tampons de cadre de l'application. Une recherche rapide sur Internet révèle ceci et cela avec une explication détaillée.

J'ai écrit une fois un intercepteur OpenGL à petite échelle sur MacOS en injectant un module partagé personnalisé, mais c'était dans des circonstances très contrôlées et en faisant beaucoup d'hypothèses, comme avoir des privilèges root dans le système, donc pour un outil de production, ce serait beaucoup plus compliqué. Vous pouvez trouver un autre projet très intéressant ici sur l'interception de l'API D3D pour installer un bot AI automatisé sur Starcraft, qui devrait aborder des concepts très similaires à ce que vous recherchez.

Une fois que vous avez réussi à intercepter l'API de rendu sous-jacente, vous pouvez alors peut-être accrocher votre code à chaque SwapBuffersappel ou équivalent pour simplement copier le tampon de trame précédent avant le swap, puis l'enregistrer (c'est là que quelque chose comme cela glReadPixelsentrerait en jeu).

Copier et enregistrer le framebuffer de manière efficace est également difficile. Le moyen le plus simple est de simplement vider chaque image sous forme d'image RVB non compressée, mais vous vous retrouverez ensuite avec des centaines de gigaoctets de données pour seulement quelques minutes de jeu, donc à moins que vous n'ayez un joli réseau de disques durs assis au coin de votre table ;), vous aurez besoin de regarder dans la compression des cadres en quelque sorte.

L'inconvénient de la compression des images maintenant est que cela prend beaucoup de traitement, donc une approche naïve pourrait transformer l'application une fois interactive que vous essayez d'enregistrer en un diaporama interactif :(. À ce stade, vous devez donc commencer à penser aux optimisations.

Je ne connais aucun projet proposant une bibliothèque pour une capture d'images efficace pour les jeux, mais ce serait certainement quelque chose de bien! Je pense qu'une chose qui pourrait empêcher un tel projet est, comme je l'ai mentionné au début, que c'est une chose très dépendante du système, donc les cas d'utilisation seront très probablement limités à une seule plate-forme ou un seul système d'exploitation.


Merci d'avoir répondu. Je pense qu'en fin de compte, je vais au lieu d'enregistrer des images, les diffuser sur une machine distante, donc copier le framebuffer peut être la voie à suivre. Vous semblez avoir une assez bonne expérience avec ce genre de choses. Pouvez-vous développer une des questions que j'ai posées? Merci pour l'aide!
pookie

1
@pookie Hé! Bien sûr, je peux développer cela. Y a-t-il quelque chose en particulier que vous aimeriez que je commente? Pour vos questions, je pense que 1 & 2 peut être fait avec les crochets DLL, alors assurez-vous de lire les liens que j'ai inclus (spécialement celui sur Starcraft). 3 & 4 seront spécifiques à l'API, mais sur OpenGL, vous pouvez commencer avec glReadPixels et travailler à partir de là si vous le trouvez trop lent. Mon expérience provient de l'enregistrement d'images de mes propres jeux ainsi que du piratage de DLL effectué dans le passé, mais je n'ai jamais combiné les deux dans la tentative d'enregistrement d'images d'une application tierce;)
glampert

Je vous remercie! J'ai vérifié les liens - l'injection de DLL Windows et le lien Starcraft (assez génial) semblent être de bons points de départ. Je vais aussi jeter un coup d'œil sur glReadPixels. À votre avis, avec quoi avez-vous trouvé le plus facile à travailler et lequel avez-vous trouvé le plus rapidement: DirectX ou OpenGL?
pookie

@pookie, si vous avez une certaine expérience en programmation, je pense que Direct3D sera beaucoup plus facile à utiliser, les bibliothèques sont mieux conçues. OpenGL a aussi trop de "bords rugueux" à mon avis (cela vient de quelqu'un qui utilise OpenGL plus que D3D). D3D est uniquement Windows, donc cela pourrait être négatif pour vous, je ne sais pas. En termes de performances, je ne pense pas que cela va faire une grande différence avec celui que vous utilisez. Le meilleur conseil que je peux probablement vous donner est: d'abord trouver comment le faire fonctionner, puis s'inquiéter des optimisations.
glampert

1
Ah, ok, si vous êtes familier avec la programmation OOP, alors D3D sera certainement plus facile. OpenGL est entièrement procédural et utilise un tas d'état global, c'est surtout ce que je voulais dire sur les bords rugueux. Bonne chance à vous!
glampert du
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.