Schnellste Methode der screen-capturing unter Windows
Möchte ich mal ein screencasting-Programm für die Windows-Plattform, aber bin unsicher, wie auf dem Bildschirm erfassen. Die einzige Methode, die ich bewusst bin, ist die Nutzung von GDI, aber ich bin neugierig, ob es gibt andere Wege zu gehen über diese, und, wenn ja, welche verursacht am wenigsten Aufwand? Geschwindigkeit ist eine Priorität.
Den screencasting-Programm wird für Aufnahme-game footage, obwohl, falls dies nicht der verengen die Optionen, die ich bin immer noch offen für andere Vorschläge, fallen aus diesem Rahmen. Wissen ist nicht schlimm, nachdem alle.
Bearbeiten: ich stieß auf diesen Artikel: Verschiedene Methoden für die Erfassung der Bildschirm. Es hat mir den Windows-Media-API Weg, es zu tun, und der DirectX-Weg, es zu tun. Es wird in der Schlussfolgerung, dass das deaktivieren der hardware-Beschleunigung könnte drastisch verbessern die Leistung des capture-Anwendung. Ich bin neugierig, warum das so ist. Könnte jemand füllen Sie die Leerzeichen aus für mich?
Bearbeiten: ich habe gelesen, dass screencasting-Programme wie Camtasia verwenden Sie Ihre eigenen capture-Treiber. Könnte mir jemand eine genauere Erklärung, wie es funktioniert, und warum es schneller ist? Ich kann auch brauchen Führung auf die Umsetzung von sowas, aber ich bin sicher, es gibt die vorhandene Dokumentation sowieso.
Auch, ich weiß jetzt, wie FRAPS zeichnet die Bildschirm. Sie hakt sich die zugrunde liegende Grafik-API zum Lesen aus dem Puffer zurück. Von dem, was ich verstehe, ist dies schneller als das Lesen aus dem front-buffer, denn Sie sind das Lesen von system-RAM, sondern als video-RAM. Sie können den Artikel Lesen hier.
- Haben Sie sich überlegt, anstatt grafisch Aufnahme der Inhalt des Bildschirms, mit einem replay-system?
- Das war eine interessante Lektüre, aber ich glaube nicht, dass es funktionieren würde. Ich müsste irgendwie Haken die Ereignisse, was nicht möglich ist mit einem "generic application", und es klingt wie ich tun müsste, wäre, ein bisschen von hacking. Gleiches gilt für die Darstellung.
- Sie haben keine Haken nichts. Sie müssen nur geben Sie Ihre Eingabe-Ereignisse, so dass Sie keine Kontrolle über das Spiel direkt, sondern andere Funktionen aufrufen. Zum Beispiel, wenn der Spieler drückt die linke Taste, die Sie nicht einfach verringern Sie den Spieler x-position. Stattdessen werden Sie eine Funktion aufrufen, wie
MovePlayerLeft()
. Und Sie zeichnen auch den Zeitpunkt und die Dauer der Tastendrücke und anderen input. Dann, wenn Sie im Wiedergabe-Modus, können Sie einfach ignorieren Sie den Eingang, und stattdessen Lesen Sie die aufgezeichneten Daten. Wenn die Daten, die Sie sehen, eine Links-Taste drücken, rufen SieMovePlayerLeft()
. - Dies wird eine Allgemeine Anwendung für die Aufzeichnung von game footage. Es ist nicht für ein bestimmtes Spiel. Jemand drücken der linken Taste könnte bedeuten, verschieben Sie das richtige, für alle, die ich kenne. Auch, Sie nicht als Ereignisse, die nicht beeinflusst durch den Benutzer. "Und was ist rendering?
- Oh, okay. Ich habe nicht verstanden, dass ein Teil(etwa dadurch, dass ein externer Anwendung). Aber für Veranstaltungen, die nicht beeinflusst durch die Benutzer, die aufgezeichnet werden, zu. Etwas in Ihrem Spiel, das ist nicht deterministisch, müsste aufgezeichnet werden. Und das rendering behandelt werden würde von der Spiel-engine die gleiche, wie wenn jemand spielt. (dies ist, natürlich, nicht auf Ihre situation zutreffen, so verstehe ich es jetzt)
- Haben Sie getestet, die Leistung
CreateOffscreenPlainSurface
undGetFrontBufferData
im DirectX? Ich kann mir nicht vorstellen, dies könnte langsamer als GDI+.NET, Windows API, oder die anderen verfügbaren Methoden. - Ich habe nicht getan, alle tests, aber andere Menschen haben, mit Ergebnissen, die wieder meine Forderung. Außerdem, ich zitiere aus der MSDN-Dokumentation: "Diese Funktion ist sehr langsam, mit design, und sollte nicht verwendet werden in jeder performance-kritischen Weg". Dies ist, weil Sie gelesen haben, von video-RAM, das ist langsam, weil die CPU-GPU-Latenz. .NET API ist einfach ein wrapper für GDI, soweit ich weiß.
- Ok, ich denke, du machst etwas viel intensiver, habe ich eine routine mit den oben genannten Methoden zu save replay AVIs in einem Spiel bei um die 30fps ohne Probleme. Ich machte eine mehrfach-monitor-Bildschirm-recorder mithilfe der windows-API für "work-force-Optimierung", aber schlecht ausgeführt, auch auf gezielte 4fps.
- Durch Windows API redest du von GDI? Hmm, das überrascht, dass es derart schlecht im Vergleich zu DirectX ist
GetFrontBufferData
. - ehrlich gesagt, ich denke, die schlechte Leistung, hatte mehr zu tun mit der weiteren Umsetzung im Detail vor allem das streaming der frames von vielen überwachten Maschinen auf einem einzigen windows-Dienst für die Archivierung.
- sind Sie sicher, dass der WME Zeug ist schneller als GDI? Es ist möglich, Sie nur mit GDI unter...
- Rückblick auf die codeprojects link, es muss nicht wirklich erwähnen, dass WME ist schneller :/. Ich falsch gelesen, sorry. Wie es mit GDI, ich bin mir nicht mehr sicher.
- Es ist ein open-source-mirror-Treiber für windows auf UltraVNC repository Seite hier
ultravnc.svn.sourceforge.net/viewvc/ultravnc/... - Hast schreibst du dein Programm? Ich bin mal gespannt.
- Ich begann, etwas vor ein paar Jahren, aber es war bei weitem nicht vollständig. Ich hatte nicht das Gefühl, komfortabel schreiben, weil ich das Gefühl hatte, es wurden eine Menge Lücken in meinem wissen, so verlor ich die motivation. Wenn ich jemals Zeit haben, Lesen Sie ein paar Bücher über das Thema, könnte ich etwas anfangen.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dies ist, was ich verwenden, um zu erfassen, um Einzelbilder, aber wenn Sie, ändern Sie diesen und halten Sie die zwei Ziele, die ständig offen ist, dann könnten Sie "stream" auf der Festplatte mit einem statischen Zähler für die Dateinamen. - Ich kann mich nicht erinnern, wo ich dieses fand, aber es wurde geändert, vielen Dank an alle!
pRenderTarget->GetDesc
zu bekommen info aufCreateOffscreenPlainSurface
EDIT: ich kann sehen, dass dies aufgeführt unter Ihrem ersten edit-link wie "der GDI-Weg". Dies ist immer noch einen anständigen Weg zu gehen, auch mit der performance advisory auf dieser Website können Sie bekommen zu 30fps einfach, würde ich denken.
Vom diese Kommentar (ich habe keine Erfahrung, dies zu tun, ich bin nur verweisen auf jemanden, der nicht):
Ich sage nicht, dies ist die Schnellste, aber die
BitBlt
operation ist in der Regel sehr schnell, wenn Sie kopieren zwischen kompatiblen Gerät zusammenhängen.Referenz, Open Broadcaster Software implementiert, so etwas als Teil Ihrer "dc_capture" Methode, obwohl, anstatt den Ziel-Kontext
hDest
mitCreateCompatibleDC
Sie verwenden eineIDXGISurface1
, die mit DirectX 10+. Wenn es keine Unterstützung für diese, fallen Sie zurückCreateCompatibleDC
.Zu ändern, um eine bestimmte Anwendung verwenden, müssen Sie ändern Sie die erste Zeile zu
GetDC(game)
wogame
ist der Griff der Spiel-Fenster, und legen Sie dann den rechtenheight
undwidth
des Spiels Fenster zu.Sobald Sie die Pixel in hDest/hbDesktop, müssen Sie noch in eine Datei speichern, aber wenn du tust, screen-capture-dann würde ich denken, würden Sie wollen, um Puffer eine bestimmte Anzahl von Ihnen in den Speicher, und speichern Sie die video-Datei in Stücke, so dass ich nicht auf code für das speichern eines statischen Bildes auf der Festplatte.
hbDesktop
. Stellen Sie sicher, dass callDeleteObject(hbDesktop);
wenn Sie nicht mehr benötigen, HBITMAP.Schrieb ich eine video-capture-software, ähnlich wie FRAPS für DirectX-Anwendungen. Der source-code ist verfügbar und meine Artikel erläutert die Allgemeine Technik. Blick auf http://blog.nektra.com/main/2013/07/23/instrumenting-direct3d-applications-to-capture-video-and-calculate-frames-per-second/
Bezug auf Ihre Fragen in Bezug auf Leistung,
DirectX soll schneller sein als GDI-außer beim Lesen aus dem frontbuffer, was sehr langsam ist. Mein Ansatz ist ähnlich wie FRAPS (Lesen von backbuffer). Ich abzufangen, ein Methoden-set von Direct3D-Schnittstellen.
Für video-Aufzeichnung in Echtzeit (mit minimalen Auswirkungen, die Anwendungen), ein schneller codec ist wichtig. FRAPS nutzt es die eigenen lossless-video-codec. Lagarith und HUFFYUV sind generische verlustfreie video-codecs für Echtzeit-Anwendungen. Sollte man sich ansehen, wenn Sie möchten, um die Ausgabe video-Dateien.
Einen anderen Ansatz, um die Aufnahme von screencasts könnte sein, schreiben einen Mirror-Treiber. Laut Wikipedia: Beim video-mirroring aktiv ist, wird jede Zeit, die das system zieht, um das primäre video-Gerät an einem Ort innerhalb der gespiegelten Fläche, eine Kopie der zeichnen-Vorgang wird ausgeführt, auf dem die gespiegelte video-Gerät in Echtzeit. Siehe "Spiegel" - Treiber auf MSDN: http://msdn.microsoft.com/en-us/library/windows/hardware/ff568315(v=vs. 85).aspx.
Ich benutze d3d9 man den backbuffer, und speichern Sie eine png-Datei mit Hilfe der d3dx-Bibliothek:
Dies zu tun, sollten Sie Ihre swapbuffer mit
(So gewährleisten Sie, dass der backbuffer nicht gemangelt, bevor Sie den screenshot).
GetRenderTarget
ist?In meinem Eindruck, ist der GDI-Ansatz und die DX-Ansatz sind unterschiedlich in Ihrer Natur.
Malerei mit GDI gilt die Methode FLUSH der FLUSH-Ansatz zieht den Rahmen dann löschen und neu zeichnen ein anderes Bild in den gleichen Puffer, dadurch wird ein flackern in games erfordern eine hohe frame-rate.
in DX (oder Grafik-Welt), eine reifere Methode namens " Doppel-buffer rendering angewendet wird, wo zwei Puffer vorhanden sind, wenn die front-buffer an die hardware, können Sie machen, um die anderen Puffer, dann, nachdem der Rahmen 1 ist fertig Rendern, wird das system den swap auf die andere Puffer( ver-es für die Präsentation auf hardware , und lassen Sie die Vorherige Puffer ), auf diese Weise die rendering-Ineffizienz wird dadurch stark verbessert.
obwohl mit Doppel-buffer rendering, die FPS verbessert, aber die Zeit für das rendering ist noch begrenzt. moderne Grafik-hardware in der Regel beinhaltet eine Menge von Optimierung beim Rendern in der Regel wie anti-aliasing, diese Berechnung ist sehr intensiv, wenn Sie nicht verlangen, dass die Grafik von hoher Qualität, natürlich, können Sie einfach deaktivieren Sie diese option. und das, um Zeit zu sparen.
Ich denke, was Sie wirklich brauchen, ist ein replay-system, das ich völlig einverstanden mit dem, was Menschen diskutiert.
Schrieb ich eine Klasse umgesetzt, dass die GDI-Methode für screen-capture. Auch ich wollte extra Geschwindigkeit, so dass, nach der Entdeckung der DirectX-Methode (über GetFrontBuffer) habe ich versucht, erwartet, dass es schneller zu sein.
War ich bestürzt feststellen, dass GDI führt etwa 2,5 x schneller. Nach 100 trials Erfassung von meinem dual-monitor-Anzeige der GDI-Umsetzung gemittelt 0.65 s pro screen-capture, während die DirectX-Methode gemittelt 1.72 s. Also GDI ist auf jeden Fall schneller als GetFrontBuffer, nach meinen tests.
War ich nicht in der Lage zu bekommen Brandrew code arbeiten zu test-DirectX-über GetRenderTargetData. Die Bildschirm-Kopie kam rein schwarz. Allerdings könnte es kopieren, der leere Bildschirm, super schnell! Ich werde weiter basteln und hoffe auf eine funktionierende version zu sehen, echte Ergebnisse aus.
GetRenderTargetData
Ansatz funktioniert. Vielleicht werde ich schreiben meine Antwort, wenn ich zum Schluss meiner Bewerbung. Oder Sie aktualisieren könnte deins sobald Sie bekommen alles funktioniert.Ein paar Dinge, die ich in der Lage gewesen, zu Lesen: offenbar mit einem "mirror-Treiber" ist schnell obwohl ich bin mir nicht bewusst, eine OSS-one.
Warum ist RDP so schnell im Vergleich zu anderen remote-control-software?
Offenbar auch mit einigen Gehirnwindungen StretchRect sind schneller als BitBlt
http://betterlogic.com/roger/2010/07/fast-screen-capture/comment-page-1/#comment-5193
Und die, die Sie erwähnt (fraps Einhängen in die D3D dll ' s) ist wohl der einzige Weg für D3D Anwendungen, aber nicht mit Windows XP-desktop zu erfassen. So jetzt habe ich nur wünschte, es gäbe eine fraps äquivalente Geschwindigkeit her für den normalen windows-desktop...jemand?
(Ich glaube, mit aero-Sie können möglicherweise verwenden Sie fraps-wie Haken, aber XP-Nutzer würde von Glück).
Offenbar auch änderung der Bildschirm-bit-tiefen und/oder Deaktivierung von hardware-accel. helfen könnte (und/oder Deaktivierung von aero).
https://github.com/rdp/screen-capture-recorder-program umfasst eine einigermaßen schnelle BitBlt-capture-Dienstprogramm, und ein benchmarker als Teil seiner Installation, das lassen Sie benchmark BitBlt Geschwindigkeiten zu optimieren.
VirtualDub hat auch eine "opengl" screen-capture-Modul, das angeblich schnell und Dinge tun, wie ändern Sie die Erkennung http://www.virtualdub.org/blog/pivot/entry.php?id=290
Für C++, die Sie verwenden können: http://www.pinvoke.net/default.aspx/gdi32/BitBlt.html
Dies kann hower nicht auf allen Typen von 3D-Anwendungen/video-apps. Dann dieser link sinnvoller sein, als er beschreibt 3 verschiedene Methoden, die Sie verwenden können.
Alte Antwort (C#):
Sie können System.Zeichnung.Grafik.Kopieren, aber es ist nicht sehr schnell.
Einem Beispiel-Projekt, das ich schrieb, tun genau dies: http://blog.tedd.no/index.php/2010/08/16/c-image-analysis-auto-gaming-with-source/
Ich Plane, aktualisieren Sie dieses Beispiel mit einer schnelleren Methode, wie Direct3D: http://spazzarama.com/2009/02/07/screencapture-with-direct3d/
Und hier ist ein link zur Aufnahme auf video: Wie capture-Bildschirm-video mit C# .Net?
Können Sie versuchen, die c++ - open-source-Projekt WinRobot @git, ein leistungsfähiges screen capturer
Unterstützung :
ich selbst mache es mit directx und denke, es ist so schnell, wie Sie möchten, es zu sein. ich glaube nicht, haben eine schnelle code-Beispiel, aber ich fand diese, die nützlich sein sollten. die directx11-version sollten sich nicht unterscheiden sich eine Menge, directx9, vielleicht ein wenig mehr, aber das ist der Weg zu gehen
Erkenne ich den folgenden Vorschlag nicht beantworten Ihre Frage, aber die einfachste Methode die ich gefunden habe, zum erfassen einer sich rasch verändernden DirectX Ansicht Stecker a video-Kamera in den S-video Anschluss der Grafikkarte, und notieren Sie die Bilder wie einen Film. Dann übertragen Sie die Videos von der Kamera wieder zu einem MPG, WMV, AVI etc. Datei auf dem computer.
Mit Windows 8 führte Microsoft die Windows-Desktop-Duplikation API. Das ist die offiziell empfohlene Weg, es zu tun. Ein nettes feature hat es für screencasting ist, dass es erkennt, Fenster verschieben, so dass Sie übertragen können, block-deltas, wenn Fenster verschoben werden, statt der raw-Pixel. Auch, es sagt Ihnen, die Rechtecke haben sich geändert, von einem Bild zum nächsten.
Der Microsoft-Beispiel-code ist ziemlich Komplex, aber die API ist eigentlich einfach und leicht zu bedienen. Ich habe ein Beispiel Projekt, das ist viel einfacher als die offiziellen Beispiel:
https://github.com/bmharper/WindowsDesktopDuplicationSample
Docs: https://docs.microsoft.com/en-gb/windows/desktop/direct3ddxgi/desktop-dup-api
Microsoft den offiziellen Beispiel-code: https://code.msdn.microsoft.com/windowsdesktop/Desktop-Duplication-Sample-da4c696a