Bildschirmaufnahme des Spielvideos


8

Ich möchte mich in ein laufendes Spiel "einhaken", sagt Mario Bros, und jeden gerenderten Frame erfassen ... diesen Frame in einer Bilddatei speichern. Ein gutes Beispiel für etwas Ähnliches ist FRAPS. --Hinweis: Ich möchte nicht den gesamten Bildschirm / Desktop erfassen. Ich möchte ein Zielfenster erfassen.

Ich habe mir OBS (Open Broadcasting Software) angesehen, aber es ist nicht besonders schnell. Versteh mich nicht falsch, es ist großartige Software, aber leider gibt es keine / schlechte Dokumentation, was ein massives Projekt, das in c und c ++ geschrieben wurde, für einen neuen C ++ - Programmierer fast unzugänglich macht.

Ich habe mir auch GamingAnywhere angesehen , aber leider kann ich es nicht zum Laufen bringen, es gibt sehr wenig / keine Dokumentation, läuft nur in VS2010 und ist chaotisch (mit schlechter Variablennamen). Es ist jedoch ein Forschungsprojekt und daher verständlicherweise undokumentiert und chaotisch.

Ich weiß, dass dies mit OpenGL, GDI und Direct3D möglich ist, aber ich kann im Internet keine guten Beispiele finden.

Ich habe gelesen, dass glReadlPixels (mit OpenGL) verwendet werden können, und ich habe die Dokumentation gelesen , aber der Beitrag erwähnte nichts über das Einbinden in eine laufende Spiel- / Anwendungsgrafik.

Fragen:

  1. Kann ich mich mit Direct3D in die Grafik eines mit OpenGL entwickelten Spiels einbinden? Muss die zum Einbinden verwendete Bibliothek mit der vom Spiel verwendeten identisch sein?

  2. Wie hänge ich mich in die gerenderten Frames des Spiels ein, damit ich diese Frames in Bilddateien oder in eine Videodatei ausgeben kann? (Nur ein paar Links oder eine kurze Erklärung, was ich tun muss, wäre großartig)

  3. BackBuffer - Ich habe gelesen, dass es sehr schnell ist, auf den BackBuffer zuzugreifen, um die Frames abzurufen. Hat jemand ein Beispiel für mich, wie man das mit den neuesten Bibliotheken macht? Ich habe festgestellt, dass die meisten Beispiele veraltet sind.

  4. Gibt es für meine Zwecke eindeutig "das ist schneller als das"? Was ich meine ist, würde beispielsweise OpenGL für meine Zwecke schneller sein?

Wenn jemand von einem Open-Source-Projekt weiß (das im Wesentlichen das tut, was ich brauche), das aktiv entwickelt und gut dokumentiert ist, würde ich gerne davon erfahren.


Dies scheint nur ein Mac zu sein, der mit Direct3D möglicherweise nicht funktioniert, aber Siphon Inject, das OBS auf einem Mac verwendet, kann Spielfenster erfassen, die OpenGL verwenden, viel schneller als die Standard-Videoaufnahme. Siphon "ermöglicht es Anwendungen, Bilder - Videos oder Standbilder mit voller Bildrate - in Echtzeit miteinander zu teilen", um die Website zu zitieren.
Gliderman

@Gliderman Danke, ich werde das überprüfen!
Pookie

Antworten:


7

Es ist möglich, das zu tun, was Sie beschreiben, aber ich fürchte, es ist kein trivialer Prozess. Tatsächlich hängt dies sehr stark von den Betriebssystemen ab, auf die Sie abzielen, und erfordert möglicherweise auch spezielle Anpassungen für das jeweilige Spiel / die jeweilige Anwendung.

Ich würde mich mit DLL-Injektionstechniken befassen, die es beispielsweise ermöglichen sollten, Aufrufe der Direct3D- (Windows) oder OpenGL-APIs abzufangen, mit denen Sie dann die Framebuffer der Anwendung kopieren können. Eine schnelle Suche im Internet zeigt dies und das mit detaillierten Erklärungen.

Ich habe einmal einen kleinen OpenGL-Interceptor unter MacOS geschrieben, indem ich ein benutzerdefiniertes freigegebenes Modul eingefügt habe, aber es war unter sehr kontrollierten Umständen und unter vielen Annahmen, wie z. B. Root-Berechtigungen im System, also für ein Produktionstool viel komplizierter. Sie können ein anderes sehr interessantes Projekt finden hier über das Abfangen der D3D API ein automatisiertes AI Bot auf Starcraft zu installieren, die auf sehr ähnliche Konzepte berühren sollten , was Sie suchen.

Sobald Sie es geschafft haben, die zugrunde liegende Rendering-API abzufangen, können Sie Ihren Code möglicherweise in jeden SwapBuffersoder einen gleichwertigen Aufruf einbinden, um den vorherigen Framebuffer vor dem Swap zu kopieren und dann zu speichern (hier glReadPixelswürde so etwas ins Spiel kommen).

Das effiziente Kopieren und Speichern des Framebuffers ist ebenfalls eine Herausforderung. Der einfache Weg besteht darin, jedes Bild einfach als unkomprimiertes RGB-Bild auszugeben, aber dann werden Sie für ein paar Minuten Spielzeit Hunderte von Gigabyte an Daten erhalten, es sei denn, Sie haben ein schönes HDD-Array an der Ecke von In Ihrem Tisch ;)müssen Sie sich darum kümmern, die Frames irgendwie zu komprimieren.

Der Nachteil beim Komprimieren der Frames besteht nun darin, dass viel Verarbeitung erforderlich ist. Ein naiver Ansatz kann daher die einmal interaktive Anwendung, die Sie aufzeichnen möchten, in eine interaktive Diashow verwandeln :(. In diesem Stadium müssten Sie also über Optimierungen nachdenken.

Ich kenne keine Projekte, die eine Bibliothek für eine effiziente Frame-Erfassung für Spiele bereitstellen, aber das wäre sicherlich etwas Schönes! Ich denke, eine Sache, die ein solches Projekt möglicherweise zurückhält, ist, wie ich eingangs erwähnt habe, dass dies eine sehr systemabhängige Sache ist, sodass Anwendungsfälle höchstwahrscheinlich auf eine einzelne Plattform oder ein einzelnes Betriebssystem beschränkt sind.


Danke für die Antwort. Ich denke, dass ich letztendlich, anstatt Bilder zu speichern, sie auf einen Remote-Computer streamen werde, so dass das Kopieren des Framebuffers der richtige Weg sein kann. Sie scheinen einiges an Erfahrung mit diesem Zeug zu haben. Können Sie eine der von mir gestellten Fragen erweitern? Danke für die Hilfe!
Pookie

1
@pookie Hey! Klar, ich kann das erweitern. Gibt es etwas spezielles, das ich kommentieren soll? Bei Ihren Fragen denke ich, dass 1 & 2 mit den DLL-Hooks durchgeführt werden kann. Lesen Sie daher unbedingt die Links, die ich eingefügt habe (insbesondere den über Starcraft). 3 & 4 sind API-spezifisch, aber unter OpenGL können Sie mit glReadPixels beginnen und von dort aus arbeiten, wenn Sie feststellen, dass es zu langsam ist. Meine Erfahrung besteht aus der Aufnahme von Frames aus meinen eigenen Spielen sowie einigen DLL-Hacking-Aktionen, die in der Vergangenheit durchgeführt wurden. Ich habe jedoch nie beide kombiniert, um Frames aus einer Drittanbieter-App aufzunehmen;)
glampert

Vielen Dank! Ich habe die Links überprüft - Windows DLL Injection und Starcraft Link (ziemlich genial) scheinen gute Ausgangspunkte zu sein. Ich werde auch einen kurzen Blick auf glReadPixels werfen. Mit was haben Sie Ihrer Meinung nach leichter gearbeitet und mit welchem ​​haben Sie schneller gearbeitet: DirectX oder OpenGL?
Pookie

@pookie, wenn Sie Programmiererfahrung haben, denke ich, dass Direct3D viel einfacher zu bedienen sein wird, die Bibliotheken sind besser gestaltet. OpenGL hat meiner Meinung nach auch "Ecken und Kanten" (dies kommt von jemandem, der OpenGL mehr als D3D verwendet). D3D ist nur Windows, also könnte das für Sie negativ sein, wissen Sie nicht. In Bezug auf die Leistung denke ich nicht, dass es einen großen Unterschied machen wird, welchen Sie verwenden. Der beste Rat, den ich Ihnen wahrscheinlich geben kann, ist: Finden Sie zuerst heraus, wie es funktioniert, und sorgen Sie sich dann um Optimierungen.
Glampert

1
Ah, ok, wenn Sie mit OOP-Programmierung vertraut sind, wird D3D definitiv einfacher. OpenGL ist alles prozedural und verwendet eine Menge globaler Zustände. Das habe ich hauptsächlich mit rauen Kanten gemeint. Viel Glück für Sie!
Glampert
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.