Screen Recorder / Capture Software selber programmieren

Auf der Suche nach einem einfach zu bedienenen Screen-Recorder-Tool bin ich über allerhand kostenloser sowie kostenpflichtiger Softwarelösungen gestolpert. Aus meiner Sicht waren ziemlich alle entweder völlig überladen oder auch schlecht bzw. kompliziert zu bedienen. Andere waren auch einfach nur teuer. ;-) Fazit: Selber programmieren!

Screen-Recorder-Tool selber programmieren

Dabei brauche ich lediglich ein Windows-Tool welches einen kleinen Bildschirmbereich aufnimmt und das Ganze als in eine Videodatei (Mpeg4/Avi) wirft. Da ich bis zu 3 Monitore Monitore gleichzeitig nutze wäre eine Aufnahme des gesamten Bereiches mehr als Ressourcenverschwendung. Um die Datenmengen möglichst gering zuhalten brauche ich auch keine 30 oder 60 Frames pro Sekunde. Daher wäre eine Option schön, um die Framerate zum Beispiel auf 5 Bilder pro Sekunde zu drosseln, was für meinen Anwendungsbereich vollkommen ausreicht.

Ich habe mir überlegt das man das Hauptfenster des Programmes ähnlich wie in anderen Tools einfach transparent mit einem Border gestaltet. So kann man das Fenster bequem über den jeweiligen Bereich ziehen und ausrichten, den man aufnehmen möchte. Beim Start des Aufnahmevorganges wir das Fenster einfach ausgeblendet bzw. minimiert und schon läuft das so wie ich es gerne hätte. ;-)

Wie schon erwähnt benötigte ich das Tool für Windows, eine Portierung auf andere Systeme sollte aber relativ einfach machbar sein.

Schritt 1 - FFMPEG.NET Library installieren

Programmierumgebung öffnen. In meinem Fall ist das Visual Studio 2017. Programmiert wird das Tool in CSharp / C#. Fix ein Projekt anlegen z.B. namens ScreenCapture und den NuGet-Paketmanager öffnen. Hier sucht und installiert man die Accord.NET FFMPEG-Library welche sich um das schreiben und komprimieren der Frames innerhalb der Videodatei kümmern, und uns so die meiste Arbeit abnehmen wird.

NuGet FFMPEG Accord.NET Library

Schritt 2 - Form im Designer setzen und etwas Code

Screen Recorder / Capture ToolIm Screenshot oben sieht man eine Vorschau des fertigen Tools. Hintergrund ist transparent um es exakt ausrichten zu können. Oben links werden ein paar Infos zur Ausgabe gebraucht. Daneben und im Hauptmenü oben befindet sich ein Button "Start capture" um die Aufnahme zu starten bzw. wieder zu stoppen. Aber der reihe nach....

Als erstes importieren wir den Namespace für die FFMPEG-Library.
using Accord.Video.FFMPEG;

Danach definieren wir einige Variablen um unter anderem die Frame- und Bitrate einstellen zu können. Ebenfalls werden Variablen für den ausgewählten Bildschirmbereich sowie die daraus resultierende Auflösung des Videomaterials benötigt. Fürs erste findet kein Re-Scale statt, sprich wir machen einen Screenshot von dem entsprechenden Bereich und schreiben diesen 1zu1 in die Videodatei.

private bool bCapture = false;
private VideoFileWriter videoWriter = new VideoFileWriter();

private Rectangle rectScreen = new Rectangle(0, 0, 800, 600);
private Size sizeOutput = new Size(800, 600);
//rectScreen und sizeOutput wird jeweils beim ändern (Größe, Position) der Form durch den User neu berechnen.

private static int iFrameRate = 5;
private static int iBitRateKB = 512;

Nun gehen wir in den Constructor der Form und fügen nach InitializeComponent(); folgendes hinzu. Hier wird LimeGreen als Hintergrundfarbe definiert und auch als ColorKey gesetzt. So wird unsere Form transparent.
Color bg = Color.LimeGreen;
this.BackColor = bg;
this.AllowTransparency = true;
this.TransparencyKey = bg;

Als nächstes schreiben wir eine Funktion welche anhand des ausgewählten Aufnahmebereiches (Form-Position und -Größe) die entsprechenden Variablen mit Werten füllt und vorab Rundungen vornimmt. Denn die Videogröße, also Auflösungstechnisch, müssen durch 2 teilbar sein! Das Resultat geben wir auch in einem Label zur Kontrolle aus.

private void setScreenAndCaptureSize(Rectangle rect)
{
int iRound = 10;

int x = ((int)(rect.Left / iRound)) * iRound;
int y = ((int)(rect.Top / iRound)) * iRound;

int w = ((int)(rect.Width / iRound)) * iRound;
int h = ((int)(rect.Height / iRound)) * iRound;

rectScreen = new Rectangle(x, y, w, h);

sizeOutput = rectScreen.Size;

lblInfo.Text = "CaptureRect: " + rectScreen.Left.ToString() + ":" + rectScreen.Top.ToString() + " => " + rectScreen.Width.ToString() + "x" + rectScreen.Height.ToString()
+ "\n" + "OutputSize: " + sizeOutput.Width.ToString() + "x" + sizeOutput.Height.ToString();
}

Das Ganze wird dann immer aufgerufen wenn die Form in Position oder Größe geändert wird und nicht grade bereits eine Aufnahme läuft.

private void frmMain_Resize(object sender, EventArgs e)
{
if (!bCapture && this.Bounds.Left >= 0 && this.Bounds.Top >= 0)
{
setScreenAndCaptureSize(this.Bounds);
}
}

Prüfung auf Bounds.Left und Top größer Null verhindert eine Änderung wenn wir später die Form bei der Aufnahme automatisiert minimieren bzw. ausblenden.

Im nächsten Schritt definieren wir einen Timer namens Timer1 welcher im gewünschten Interval einen Screenshot vom Aufnahmebereich erstellt und an den VideoWriter übergibt. Hier muss man aufpassen den entsprechenden Arbeitsspeicher nach dem Schreibvorgang ins Video-File wieder freizugeben. Siehe bp.dispose(); da ansonsten der Arbeitsspeicher binnen Sekunden voll läuft.

private void timer1_Tick(object sender, EventArgs e)
{
Bitmap bp = new Bitmap(rectScreen.Size.Width, rectScreen.Size.Height);

Graphics gr = Graphics.FromImage(bp);
gr.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
gr.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
gr.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
gr.CopyFromScreen(rectScreen.Left, rectScreen.Top, 0, 0, bp.Size, CopyPixelOperation.SourceCopy);
gr.Dispose();

videoWriter.WriteVideoFrame(bp);
bp.Dispose();
}

Im letzten Schritt fügen wir noch das Event für den Click hinzu, um die Aufnahme zu starten bzw. zu stoppen.

private void startCaptureToolStripMenuItem_Click(object sender, EventArgs e)
{
startCaptureToolStripMenuItem.Enabled = false;

if (bCapture)
{
timer1.Stop();
videoWriter.Close();

bCapture = false;

startCaptureToolStripMenuItem.Text = "Start capture";
beendenToolStripMenuItem.Enabled = true;
}
else
{
string sFileName = DateTime.Now.ToString().Replace(".", "_") + ".avi";
sFileName = sFileName.Replace(":", "_");
sFileName += ".avi";

string sPath = Application.StartupPath + "/" + sFileName;

videoWriter.Open(sPath, sizeOutput.Width, sizeOutput.Height, iFrameRate, VideoCodec.MPEG4, iBitRateKB * 1000);

timer1.Interval = 1000 / iFrameRate;
timer1.Start();

bCapture = true;

startCaptureToolStripMenuItem.Text = "Stop capture";
beendenToolStripMenuItem.Enabled = true;

this.WindowState = FormWindowState.Minimized;
}

startCaptureToolStripMenuItem.Enabled = true;
}

Und schon ist das Capture-Tool fertig und zeichnet brav den gewünschten Bereich des Desktops auf. Die Videodateien werden im Verzeichnis des Tools gespeichert. Als Namen habe ich einen simplen Zeitstempel gewählt damit man dort nach einiger Zeit noch durchsieht.

In einer erweiterten Version habe ich noch die statischen Werte für Bitrate und Framerate ausgelagert um diese über ein Textfeld jeweils zur Laufzeit steuern zu können. Ebenfalls wurde ein Unterverzeichnis namens "Output" angelegt und die Videodateien dorthin geschoben, ist einfach sauberer.

In jedem Fall würde ich diese Werte (Bitrate, Framerate) aber nie zu hoch einstellen, da diese Art der Videoaufnahme vom Monitor doch sehr CPU-Lastig ist. Hier gilt es einen Kompromiss zwischen Bildqualität und Rechenleistung zu finden.

Alles Kleinigkeiten, aber so bin ich wunschlos glücklich mit diesem kleinen Screen-Recorder. Vielleicht kann ja jemand diesen Beitrag hier als Ansatz für ein eigenes Tool oder ähnliches gut gebrauchen. :-)

Den Code kann man sich hier nochmal ansehen.
Feedback, Lob, Kritik etc. gerne per Mail -> zum Kontaktformular.

Zuletzt bearbeitet: 11. Juli, 2018
Tags: , , , , , , , , ,

Verwandte Beiträge

DIYS Smart-Home V1 - Irgendwo muss man ja anfangen!

Schon seit einiger Zeit plane ich mein Smart-Home. Neben dem Kostenfaktor für all die tollen Dinge die ich mir so vorstelle fehlt es oft an der notwendigen Zeit zur detailierten Planung und Umsetzung. Daher habe ich beschlossen einfach mal irgendwo anzufangen und dieses DIY-Projekt parallel niederzuschreiben...mal sehen wohin das führt...Ich bitte um Nachsicht wenn ich [...] Weiterlesen »


WordPress-Installation anpassen für Datenschutz-Grundverordnung (DSGVO) 2018

Die EU-Datenschutz-Grundverordnung (DSGVO) tritt am 25. Mai 2018 in Kraft. Dabei gibt es unter anderem für Webseitenbetreiber allerhand zu beachten. Detailierte Informationen und Text-Muster für die eigene Datenschutzerklärung gibt es seit langem auf diversen Internetseiten wie z.B. bei Datenschutz.org , aber auch in entsprechenden Büchern zur Datenschutz Grundverordnung 2018 . Es hat natürlich keiner große [...] Weiterlesen »


ESP8266-WiFi-Modul flashen

Da ich mich seit kurzem wieder intensiver mit den Themen Smart Home und "Home automation" beschäftige habe ich beschlossen einige meiner Baustellen, Stolpersteine und Lösungen hier zu veröffentlichen. Wie im Beitrag zu meinem Smart-Home-Project V1 bereits erwähnt setze ich auf das WLAN-Modul ESP8266-ESP01 , da dieses unter anderem klein, zuverlässig und günstig ist. In diesem [...] Weiterlesen »


Fitnessboard v1 - DIYS

Am Wochenende hatte ich glücklicherweise mal wieder etwas Zeit zum Basteln und dazu noch eine ganz nette Idee für ein Fitness-Board für das Training zuhause, welches aus der Liegestütz-Position bedient wird. Ein Video dazu gibt es weiter unten in diesem Artikel und im Youtube-Channel von tedokai.de. Jeder der Zuhause dann und wann Sport betreibt kennt [...] Weiterlesen »


iTunes-Connect - Sales-Reports

Wer Apple und iTunes-Connect (ITC) kennt, weiß von den Problemchen welche ITC teilweise mit sich bringt. Mich persönlich hat immer gestört, das die Sales-Reports / Verkaufszahlen des Vortages manchmal erst am späten Abend des Folgetages verfügbar waren. Das liegt wohl daran, das die Apple-Server die Reports für jeden Entwickler aufbereiten müssen und es hier öfter [...] Weiterlesen »