Program your own Screen Recorder / Capture Software

Screen Recorder / Capture Tool

While searching for an easy to use screen recorder tool, I stumbled across all kinds of free and paid software solutions. From my point of view, pretty much all of them were either completely overloaded, difficult or complicated to use. Others were just expensive in relation to the functionality. My conclusion: Program yourself!

Table of contents:

Program your own Screen-Recorder-Tool

kraken.jpgAll I need is a Windows tool that records a small screen area and writes the whole thing as a video file (Mpeg4/Avi). Since I use up to 3 led monitors led monitors at the same time, a recording of the whole area would be more than just a waste of resources. To keep the amount of data as low as possible I don't need 30 or 60 frames per second. Therefore an nice option would be to reduce the frame rate for example to 5 frames per second, which is sufficient for my application and drastically reduces the required storage space.

I thought about making the main window of the program transparent with a border similar to other tools and software solutions. So you can drag and drop the window over the area you want to record. At the start of the recording process the window is simply hidden or minimized and it runs as I would like it to.

As already mentioned I needed the tool for Windows, but porting it to other systems like MacOS should be relatively easy.

Step 1 - Install FFMPEG.NET Library

Open the programming environment. In my case the Visual Studio is 2017. The tool is programmed in CSharp / C#. Simply create a project (e.g. called ScreenCapture) and open the NuGet package manager. Here you look for and install the Accord.NET FFMPEG library which takes care of writing and compressing the frames within the video file and will do most of the work for us.
NuGet ffmpeg dotnet library

Step 2 - Layout and Design the Main Dialog (Form) and write some code

The following screenshot shows a preview of the finished tool.

Screeen Capture Recorder ToolThe background is transparent to be able to align it exactly. In the upper left corner you can see some output informations. Next to it and in the main menu above there is a button with the label "Start capture" to start or stop the recording. But one after the other....

First we import the namespace for the FFMPEG library.
using Accord.Video.FFMPEG;

Then we define some variables to be able to set the frame- and bitrate. Also variables for the selected screen area and the resulting resolution of the video material are needed. Actually there is no re-scaling, i.e. we take a screenshot of the corresponding area and write it 1 to 1 into the video file.

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 and sizeOutput will be recalculated when the user is changing the shape of the dialog (size, position).

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

Now we go into the constructor of the form and add after InitializeComponent(); the following. Here LimeGreen is defined as background color and also set as ColorKey. This makes our form transparent.
Color bg = Color.LimeGreen;
this.BackColor = bg;
this.AllowTransparency = true;
this.TransparencyKey = bg;

Next, we write a function that fills the corresponding variables with values based on the selected recording area (form position and size) and rounds them beforehand. Because the video size, i.e. resolution, must be divisible by 2 (power of two)! The result is also displayed in a label for control purposes.

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();

The whole thing is called whenever the shape is changed in position or size and a recording is not already running.

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

Check for Bounds.Left and Bounds.Top greater than zero prevents a change when we automatically minimize or hide the shape during recording later. Thats a quick and dirty solution, but it works.

In the next step we define a timer called Timer1 (very imaginative) which creates a screenshot of the recording area in the desired interval and transfers it to the VideoWriter. Here, one has to be careful to release the corresponding working memory after the writing process into the video file again. See bp.dispose(); otherwise the main memory runs full within seconds.

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);


In the last step we add the event for the click to start or stop the recording.

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

if (bCapture)

bCapture = false;

startCaptureToolStripMenuItem.Text = "Start capture";
beendenToolStripMenuItem.Enabled = true;
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;

bCapture = true;

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

this.WindowState = FormWindowState.Minimized;

startCaptureToolStripMenuItem.Enabled = true;

And so the capture tool is ready to use and records the desired area of the desktop. The video files are saved in the tool's directory. I have chosen a simple timestamp as  name for the video files so that you can still look through it after some time.

Recorder Tool improvements

kraken.jpgIn an extended version I outsourced the static values for bitrate and framerate in order to be able to control them via a text field at runtime. Also a subdirectory called "Output" was created and the video files were moved there - it's just cleaner.

In any case, I would never set these values (bit rate, frame rate) too high, because this type of video recording from the monitor is very CPU-heavy. Here you have to find a compromise between picture quality and computing power.

All little things, but so I am happy with this small screen recorder. Fast and easy, and it does what it should. Maybe somebody could use this article as a starting point for his own tool or something similar. 🙂

Watch again and download the complete Code here:
Download sourcecode of Screen-Recording-Tool.

Send me feedback, praise and criticism gladly by mail or just leave a comment here at the website.

Author: Sascha from

Author: Sascha

Some words about myself. My name is Sascha - i'm a software developer, trader and martial artist from germany. Besides programming, trading and martial arts some of my interests and hobbies are cooking, fitness and hearing loud heavy metal music. :D

This might also be interesting for you

Smart Home V1 - Do it yourself

I've been planning my smart home for some time now. Besides the cost factor for all the great things I imagine, I often lack the necessary time for detailed planning and implementation. So I decided to start somewhere and write down this DIY project in parallel...let's see where it leads...I ask for your indulgence if … Continue reading "Smart Home V1 - Do it yourself"

Telegram Messenger and the Bot API - Part 2

In the first part - Telegram Messenger and the Bot API - I explained some basics how to set up a telegram bot and how to use it to send messages, states, informations and more to your . Since this tool has proven to be very practical, I decided to take up the previous article … Continue reading "Telegram Messenger and the Bot API - Part 2"

Experiment: Hacking Ethereum Wallets - Bruteforce

Some time ago I came across a YouTube video by chance with the title: "Eth Wallet Bruteforce Hack". A programmer showed a simple Python script which could generate a random private key (64 characters / 32 bytes / 256 bits). This was used to calculate the public-key and address and pass it to a blockchain … Continue reading "Experiment: Hacking Ethereum Wallets - Bruteforce"

pi_robot - Playing with Raspberry Pi, iPad and some Code

The Raspberry Pi is still one of the most popular mini computers, not only among hobbyists. Cost-effective (about 30 to 40,- EUR depending on the model), flexible in the field of application and at the latest since the equipped with enough CPU power and memory to solve even more complex tasks. With the 1.2 GHz … Continue reading "pi_robot - Playing with Raspberry Pi, iPad and some Code"

Flashing firmware - ESP8266-WiFi-Module

Since I recently started to deal more intensively with the topics "Smart Home" and "Home automation" I decided to publish some of my construction sites, stumbling blocks and solutions here. As already mentioned in the article about my Smart-Home-Project V1 I use the WLAN module , because it is small, reliable and cheap. In this … Continue reading "Flashing firmware - ESP8266-WiFi-Module"

Leave a Reply

Your email address will not be published. Required fields are marked *

I have read and accepted the privacy policy!