Screen Recorder / Capture Software selber programmieren

Amazon

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 im Verhältnis zum Funktionsumfang. Mein Fazit: Selber programmieren!

Inhaltsverzeichnis:

Screen-Recorder-Tool selber programmieren

christ schmuck.jpgDabei brauche ich lediglich ein Windows-Tool welches einen kleinen Bildschirmbereich aufnimmt und das Ganze als in eine Videodatei (Mpeg4/Avi) schreibt. Da ich bis zu 3 Monitore Monitore gleichzeitig nutze wäre eine Aufnahme des gesamten Bereiches mehr als nur 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 und den benötigten Speicherplatz drastisch reduziert.

Ich habe mir überlegt das man das Hauptfenster des Programmes ähnlich wie in anderen Tools und Softwarelösungen einfach transparent mit einem Border gestaltet. So kann man das Fenster bequem über den jeweiligen Bereich den man aufnehmen möchte ziehen und ausrichten. 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#. Einfach und schnell 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 einzelnen 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. Der Hintergrund ist transparent um es exakt ausrichten zu können. Oben links werden ein paar Infos zur Ausgabe angezeigt. Daneben und im Hauptmenü oben befindet sich ein Button mit der Aufschrift "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 (power of two) 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 (sehr einfallsreich) welcher im gewünschten Interval einen Screenshot vom Aufnahmebereich erstellt und diesen an den VideoWriter übergibt. Hier muss man aufpassen den entsprechenden Arbeitsspeicher nach dem Schreibvorgang in die Video-Datei 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.

Capture Screen Recorder Verbesserungen

amz l music.jpg

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. Schnell und einfach, und es macht was es soll. 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: 23. Mai, 2019
Tags: , , , , , , , , ,

Dies könnte dich auch interessieren

Apfel-Appstore-Reader - Update 2.0

Wie im Artikel - Apfel-Appstore-Reader - beschrieben, hält sich Apple bezüglich der App-Rankings (Positionierung im Appstore) sehr gedeckt. Auch im Report-Tool (ITC / iTunes-Connect -> Sales & Trends) keinerlei Informationen auftauchen, an welcher Position man sich mit der jeweiligen App in z.B. einer Kategorie wie “Produktivität” befindet, habe ich vor längerer Zeit ein kleines Java-Tool [...] Weiterlesen »


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 »


Telegram Messenger und die Bot API

Telegram ist im Prinzip ein Messenger ähnlich Whatsapp oder Threema , kostenlos und leicht zu bedienen. Ich möchte nicht sagen das dieser besser oder schlechter ist als andere Messenger, allerdings gefällt mir die Telegram Bot API sogut, dass ich an dieser Stelle ein kleines Tutorial dazu schreiben möchte. Inhaltsverzeichnis:Telegram Messenger Bot API programmierenSchritt 1 - [...] Weiterlesen »


Telegram Messenger und die Bot API - Teil 2

Im ersten Teil - Telegram Messenger und die Bot API - bin ich auf einige Grundlagen eingegangen wie man einen Telegram-Bot einrichtet und diesen nutzt um sich Nachrichten, Informationen und sonstiges bequem auf sein Handy zu schicken. Da sich dieses Werkzeug als äußerst praktisch erwiesen hat, habe ich mich dazu entschlossen den vorherigen Beitrag nochmal [...] Weiterlesen »


3 Gründe warum es App-Entwickler nicht einfach haben

Aus gegebenem Anlass heute mal ein kleiner Beitrag aus der Sektion "Nicht ganz so ernst gemeinte Beiträge". Hier nun einige Überlegungen warum es App-Entwickler heute schwieriger haben, als noch vor einigen Jahren. Eines vorweg: Wer in diesem Beitrag einen Hauch von Ironie und Sarkasmus findet, darf ihn behalten! ;-) Inhaltsverzeichnis:Problem 1: Die Masse an Apps [...] Weiterlesen »