VB.NET - MPEG-4 Screen recorder. May 23rd, 2015 update
Created with Visual Basic 2010, using FFmpeg to compile captured images & audio to an MPEG-4 video. It's not perect, but when I have the time, I 'll tweak it some more.
* Adjusts frames per second (fps) and capture interval according to screen resolution's total pixels. Screen resolutions with a pixel total equal to or less than 921600 (1280x720) are captured at 30fps. Larger pixel totals (1280x1024, 1920x1080, etc...) are captured at 25fps.
* The "Crop to 16.9" checkbox is only visible if your screen resolution is not 16.9 aspect ratio.
* If "Record Mouse" is checked, along with "Crop to 16.9", the capture region follows the mouse according to actual screen bounds height.
* Creates a Folder called "Captured", which is placed in Window's system's "My Videos" folder.
* Extracts FFmpeg from resources and places it in the captured folder. FFmpeg, with dshow, captures audio from the speakers and saves it as an mp3 file, while merging captured images to a temporary mp4. Clicking "Stop" restarts FFmpeg to merge both to a dated mp4 in the captured folder.
* All captured videos are given unique Date & Time filenames.
The code had to be reposted since I exceeded the character limit here. You can find it below this thread, posts labeled May 23rd, part 1 thru 4.
Important:
For this project to work, you need to download either the 32bit or 64bit FFmpeg static builds, which needs to be added to this project's resources. The direct links above to the ffmpeg static build downloads for Windows are from it's parent site, Zeranoe FFmpeg. They are older versions, but work fine compared to the latest version which is buggy.
Your system's Stereo Mix has to be enabled in order for this app to record sound.
Enabling Stereo Mix for Windows Vista, 7 and 8
* Right-click over the Speaker icon by the system clock then choose Recording Devices to open the Recording tab of "Sound".
* Right-click Stereo Mix, and from it's dropdown menu, click Enable.
Note (Vista, 7 and 8):
If you don't see Stereo Mix, right click within the Recording tab window, then check "Show Disabled Devices".
Enabling Stereo Mix for Windows XP
* Click the Speaker icon by the system clock.
* In the window that appears, choose Options then Properties.
* In the next window, click the "Recording" radio button, then in "Show the following volume controls", click in the box for Stereo Mix, then "OK".
This project's zip is clean of binaries, but it only works on 64bit systems.
You can easily change it to 32bit in VB's Configuration Manager.
Don't forget to add FFmpeg static build (32bit or 64bit) to this project's resources.
Last edited by Peter Porter; Aug 27th, 2015 at 08:20 AM.
Re: VB.NET - Fixed! Screen Recorder, capture fullscreen with audio
Maybe you should attach the project to the first post? I for one would have difficulty whether something is 98 pixels away from something else.
when you quote a post could you please do it via the "Reply With Quote" button or if it multiple post click the "''+" button then "Reply With Quote" button.
If this thread is finished with please mark it "Resolved" by selecting "Mark thread resolved" from the "Thread tools" drop-down menu. https://get.cryptobrowser.site/30/4111672
VB.NET - Project file attached to 1st post for Screen Recorder
Hi Nightwalker83
I've attached a working project file to my first post. The code and project file above was extracted from the main body of my application which is why it doesn't look great, but it works. I'll gradually add more features as I clean-up my main application's code.
Everything works, except for the fact that the VB Timer is way off. Wish I knew a way to incorporate a High Resolution Timer.
Solved the interval problem for better frames per second.
Ok... I thought of a way of capturing more frames per second. The save function needs to be placed in two backgroundworkers called from the VidRec timer. The VidRec timer will call a save from the first backgroundworker, then configure itself to call the next save from the second backgroundworker, then back again. One backgroundworker will be saving images with odd numbers, and the other even, this way all saved images from both backgroundworkers can be played together in a picturebox.
I'll even test the capture function within a backgroundworker to see if it's faster than a timer. Maybe split this function between 2 or 3 backgroundworkers.
As soon as this project is updated, I'll repost the source code as well as a new dated zip file.
Re: Solved the interval problem for better frames per second.
Originally Posted by Peter Porter
Ok... I thought of a way of capturing more frames per second. The save function needs to be placed in two backgroundworkers called from the VidRec timer. The VidRec timer will call a save from the first backgroundworker, then configure itself to call the next save from the second backgroundworker, then back again. One backgroundworker will be saving images with odd numbers, and the other even, this way all saved images from both backgroundworkers can be played together in a picturebox.
I'll even test the capture function within a backgroundworker to see if it's faster than a timer. Maybe split this function between 2 or 3 backgroundworkers.
As soon as this project is updated, I'll repost the source code as well as a new dated zip file.
Hi Peter, sorry to bump into this old thread but am working on a similar tool and was wondering whether you were able to implment the above and get some decent improvement? I couldnt find a newer post with an updated version...so thought to ask..
Currently I am able to generate screenshots and even capture the audio seperately. I can combine them using ffmpeg but I find that the audio/video is out of sync (video lags in coparison to audio) . This might be because my application is not able to produce correct number of screenshots(though i have set video timer to 10). I plan to use the backgroundworker method. Could you please share the updated code please?
Re: VB.NET - Screen recorder with audio. Zip file and screenshots
Hi Sunny,
I have an older version of this program that captures at the correct interval... well it's a bit over the number of frames it should be capturing, which is an easy fix by deleting the few duplicate frames it captures by knowing when this occurs, that's if you can figure out how to prevent it from crashing. It crashes after 600 to 700 frames. When it crashes, you can't save the images. Haven't had time to correct this, which is why I made the updated version attached above which is great for capturing tutorials, then you would have to use some video editing software to sync the audio with it. Could also be done with ffmpeg.
With the above attached version, the saving of each frame slows it down. Worse when you try to capture a video. As soon as I can dig up the old version, I'll attach it to this post. Maybe you can fix it.
Re: VB.NET - Screen Recorder with Audio. Update 22 Dec 13
Originally Posted by Peter Porter
Updated the Screen Recorder. It now captures at 30fps while recording audio.
Thanks peter. However the code in the zip file you provided doesnt open up in my Visual Basic 2008... Could you explain in short the logic as to how to achieved to capture frames at such high fps?
Re: VB.NET - Screen Recorder with Audio. Update 22 Dec 13
Hi sunnydsouza,
I attached some code to this post, but it's been updated as well as the zipped files in 32bit and 64bit versions. My Screen Recorder now converts straight to MPEG-4 video. Hopefully the code above works for your version of Visual basic. Just one thing, Vidrec, Player and AudioRec are Timers. I haven't updated the player yet, so it will only play audio for now.
Re: VB.NET - Screen Recorder with Audio. Update 22 Dec 13
Originally Posted by Peter Porter
Hi sunnydsouza,
I attached some code to this post, but it's been updated as well as the zipped files in 32bit and 64bit versions. My Screen Recorder now converts straight to MPEG-4 video. Hopefully the code above works for your version of Visual basic. Just one thing, Vidrec, Player and AudioRec are Timers. I haven't updated the player yet, so it will only play audio for now.
Thanks a lot Peter. I will check this out. Just out of curiosity - Does the video created by ffmpeg capture the audio also with it? And if so, are they both in sync?
Re: VB.NET - Screen Recorder with Audio. Update 22 Dec 13
It doesn't merge audio with video yet, but I'll have that fixed soon.
I've updated the code again so the video and audio are saved in the same folder called Captured which this program creates in the MyVideos or Videos folder.
Re: VB.NET - Screen Recorder with Audio. Update 22 Dec 13
It doesn't merge audio with video yet, but I'll have that fixed soon.
I've updated the code again so the video and audio are saved in the same folder called Captured which this program creates in the MyVideos or Videos folder.
Re: VB.NET - Screen Recorder with audio. Converts to MPEG-4 video now. Update 29 Dec
Is it possible to add an option to capture the mouse cursor to?
when you quote a post could you please do it via the "Reply With Quote" button or if it multiple post click the "''+" button then "Reply With Quote" button.
If this thread is finished with please mark it "Resolved" by selecting "Mark thread resolved" from the "Thread tools" drop-down menu. https://get.cryptobrowser.site/30/4111672
Re: VB.NET - Screen Recorder with audio. Converts to MPEG-4 video now. Update 29 Dec
Hi Peter,
I use your code (64 bit. Because My OS is 64 bit). I can Record Screen Activities when I click stop button. But, I'm recording about 2 minutes but recorded file (test.mp4) is about 22 second. It's very fast.
I just want to record video. I don't have record audio. By the way, the recorded file size haven't very big. It must be small.
Dim BMP As New System.Drawing.Bitmap(MonitorWidth, MonitorHeight)
Dim Cap As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(BMP)
Cap.CopyFromScreen(New Point(0, 0), New Point(0, 0), ScreenSize)
BMP.Save(writer.BaseStream, System.Drawing.Imaging.ImageFormat.Bmp)
Label3.Text = Convert.ToString(Frames)
If Label1.Text = "stop" Then
VidREC.Enabled = False
ComboBox1.SelectedIndex = 2
writer.Close()
End If
BMP.Dispose()
Cap.Dispose()
GC.Collect()
How can I set time of original record between time of recorded video?(Duration)
Re: VB.NET - Screen Recorder with audio. Converts to MPEG-4 video now. Update 29 Dec
Sorry for the wait, mrhydn, Nightwalker83, ankan. I have another version of my screen recorder that merges audio with the video. I created back in January before I dropped this project. The video plays back slow, or sometimes the frame rate fluctuates, so it's not in sync. The audio might be 5 minutes long, but the video might end up being over 5 minutes, or just a little under. I'll attach an update soon.
Last edited by Peter Porter; Jun 25th, 2014 at 08:32 AM.
Re: VB.NET - Screen Recorder with audio. Converts to MPEG-4 video now. Update 29 Dec
Originally Posted by Peter Porter
I thought I corrected the frame rate. Maybe it runs fast depending on the system. Works great on my pc. When I have time I'll look over my program again.
First of all thanks for sharing!
I would love to see a fix for the playback speed, I've tried all sorts of command line options for ffmpeg but the output file was always playing about 2x faster then the real capture time.
EDIT UPDATE
I changed my experiment code again, capture at lower FPS, (still a lot of junk in this, bunch of DoEvents,etc..)
This captures the mouse pointer and draws a red circle around the mouse pointer when left mouse button is down.
Last edited by Edgemeal; Sep 28th, 2014 at 09:52 PM.
Re: VB.NET - Screen Recorder with audio. Converts to MPEG-4 video now. Update 29 Dec
@Edgemeal: Nice work on the screen grab code.
From your timings, it looks like you are hoping for 75 fps (13.33ms timing loops). Might be a tad optimistic? The best I can achieve is about 18 fps for a screen grab and stream to FFmpeg process with a screen resolution of 1920 x 1080.
I think half the problem stems from the fps values, both those expected and those that are passed as settings to FFmpeg.
For example, let's say I was specifying 30 fps for the video playback rate in the call to FFmpeg
but I was only able to grab screencaps at 15fps. Then that would account for the doubling in speed on playback.
You might think the obvious solution would be to cap the screen grab rate at a value that your hardware can handle, and set the playback rate via FFmpeg to the same value. That would be too easy .
I capped the grab rate to 12.5 fps (timing loop = 80ms) and passed -r 12.5 to FFmpeg. After recording for 60 seconds, the code had grabbed 737 frames (should have been 750; the grab rate is not consistent, with about 5% of screencaps taking longer than 80ms.) The output video file played back at 12.5 fps as expected, but only contained 371 frames. So at 12.5 fps, 371 frames play back in 29 seconds. That's still twice the expected speed, so matching frame rate to grab rate hasn't worked.
To force the frame rate of the input file (valid for raw formats only) to 1 fps and the frame rate of the output file to 24 fps:
ffmpeg -r 1 -i input.m2v -r 24 output.avi
Quite how that applies to streaming a bitmap, I don't know, but it does have an affect on the results.
After a fair bit of trial and error and a lot of observation, I deduced the following points:
If you don't specify a value for the input rate, it defaults to 25.
If you don't specify a value for the output rate, it defaults to the input rate, or if no input rate has been specified, the input rate's default value.
The actual number of frames present in the output video seems to be derived as:
num frames in video = num screen caps * ( output rate / input rate )
From that last point, it can be shown (I won't bore you with the maths) that the undesired speed factor is given by:
speed factor = input rate / screen grab rate
So in the above example, where I hadn't specified an input rate, it will have defaulted to 25fps, the screen grab rate was capped at 12.5 fps, which gives:
speed factor = 25 / 12.5 = 2
and indeed, the video payed twice as fast as I expected.
Another example:
Screen grab rate capped at 12.5fps (80ms timing loop)
Grabbed 744 frames in 60 seconds
Actual Screen Grab rate = 744 / 60 = 12.4fps
Input rate set = 18fps
Output rate set = 12.5fps
and here come the calculations:
Expected frames in video = num screen grabs * ( output rate / input rate )
= 744 * ( 12.5 / 18 ) = 517
Speed factor = input rate / screen grab rate = 18 / 12.4 = 1.4516
which gives expected video run time of 60 / 1.4516 = 41.3337 seconds.
And these values compare well to the actual values for the video produced:
video contains 518 frames,
playback rate = 12.5 fps,
run time = 41.440 seconds.
So my current thinking would be to cap the screen grab rate at a value that the PC hardware can comfortably cope with (12.5 to 15 fps for my PC @ 1920x1080 screen res.), ony pass the input rate as an argument to FFmpeg (which will then be used by default as the output rate), and as the input rate value, use the same value as the screen grab rate is capped to.
As long as the input rate always equals the screen grab rate, then the speed factor (input rate / screen grab rate ) will always be 1.
I should add that I know nothing about FFmpeg, and there may well be a command line that does all this in a sensible manner. I should read the documentation for FFmpeg, but there's far too much of it for me to do that at the moment. Perhaps someone knows of a simpler method, and would be willing to share?
Last edited by Inferrd; Jun 24th, 2014 at 04:21 PM.
Re: VB.NET - Screen Recorder with audio. Converts to MPEG-4 video now. Update 29 Dec
Originally Posted by Inferrd
@Edgemeal: Nice work on the screen grab code.
Thanks for checking it out, I know I tried what you did and was just mad I couldn't get more FPS, I give up this for now.
btw, I updated post #17 for anyone interested in the way I add the mouse pointer and red circle to the captures.
UPDATE Did a couple quick timing test @ 1920x1080, my capture takes about 24ms, and the write to ffmpeg is another 24-30ms, and every so often there is a spike where it adds another 20~30ms to the total time. I just assumed writing to ffmpeg would be super fast.
Also tried saving the bmp captures directly to files on the fly and it only takes about 5.5 ~ 5.7m to save them.
Last edited by Edgemeal; Jun 24th, 2014 at 11:35 PM.
Re: VB.NET - Screen Recorder with audio. Converts to MPEG-4 video now. Update 29 Dec
Hi Edgemeal. I do have a fix that I created back in January. It's not perfect. Sometimes the video plays back too slow, or the frame rate fluctuates, so it's never in sync. Basically it merges the saved video with the saved audio, but maybe if I could merge both together while recording, it could improve the syncronization. I'm gonna play with it a bit now and upload this version, maybe tonight.
Last edited by Peter Porter; Jun 25th, 2014 at 09:04 AM.
Re: VB.NET - Screen Recorder with audio. Converts to MPEG-4 video now. Update 29 Dec
Great screen recorder, Edgemeal!
I posted an update, but I'm gonna rewrite it using both of our ideas. My project is still not perfect. It's records YouTube fullscreen videos almost in sync, but if you're not recording videos, then it's grossly out of sync. Gonna add options to where a user can set what kinda of capture is going to be performed so the program could adjust to a set frame rate.
What I'm trying to workout now is to play the created video in a user's system's default Media Player. It's currently broke.
Re: VB.NET - Screen Recorder with audio. Converts to MPEG-4 video now. Update 29 Dec
Was playing with your july 14 code, not much difference, playback is still too fast, On my pc calls to ffmpeg are taking about 30ms, and screenshot (@ 1920x1080) adds another 25ms+, so time to capture a frame might take 60ms which already limits me to 16.6FPS, so for quick test I changed both -r commands to -r 15 and playback speed was about perfect, but 15FPS is just too choppy for capturing video, So its really not your code, my PC just cant do a screenshot and also call ffmpeg fast enough to do decent FPS captures.
Re: VB.NET - Screen Recorder with audio. Converts to MPEG-4 video now. Update 29 Dec
Originally Posted by Edgemeal
First of all thanks for sharing!
I would love to see a fix for the playback speed, I've tried all sorts of command line options for ffmpeg but the output file was always playing about 2x faster then the real capture time.
Dear sir, greetings. hope you are fine
sir, i have tried your sample/example:
And this is my modified code:
Code:
Dim objBitmap As System.Drawing.Bitmap
Dim objFProcess As System.Diagnostics.Process
Dim objStream As System.IO.BinaryWriter
Dim strFiles() As String
Dim strEachFile As String
Dim intFile As Integer
Dim intFrame As Integer
Dim intFLoop As Integer
objFProcess = New System.Diagnostics.Process
objFProcess.StartInfo.FileName = "c:\ffmpeg.exe"
objFProcess.StartInfo.Arguments = "-r 1 -f image2pipe -i pipe:.bmp -pix_fmt yuv420p -crf 35.0 -vcodec libx264 -an -coder 1 -rc_lookahead 50 -threads 0 D:\test.mp4"
objFProcess.StartInfo.UseShellExecute = False
objFProcess.StartInfo.RedirectStandardInput = True
objFProcess.StartInfo.RedirectStandardOutput = True
objFProcess.StartInfo.RedirectStandardError = True
'objFProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
'objFProcess.StartInfo.CreateNoWindow = True
objFProcess.Start()
objStream = New System.IO.BinaryWriter(objFProcess.StandardInput.BaseStream)
strFiles = My.Computer.Clipboard.GetText().Split({System.Environment.NewLine}, StringSplitOptions.None)
intFrame = 0
intFile = 0
For Each strEachFile In strFiles
'MessageBox.Show(strEachFile)
intFile = intFile + 1
objBitmap = New System.Drawing.Bitmap(strEachFile)
For intFLoop = 0 To 24
intFrame = intFrame + 1
cmd1.Text = intFile.ToString & "-" & intFrame.ToString
My.Application.DoEvents()
objBitmap.Save(objStream.BaseStream, System.Drawing.Imaging.ImageFormat.Bmp) Rem this line give me below (attached) error :(
Next
objBitmap.Dispose()
Next
System.Threading.Thread.Sleep(3000)
objStream.Close()
MessageBox.Show("Done!")
'objFProcess.Kill()
Re: VB.NET - MPEG-4 Screen recorder. Update 14 Feb 2015
I've attached the screen capture zipped project file in my first post above. Capture is now done with a background worker.
Code:
Option Strict On
Imports System.IO
Imports System.Net
Imports System.Text
Imports System.Threading
Imports System.Drawing
Imports System.Drawing.Image
Imports System.Runtime.InteropServices
Public Class Form1
'dll import and initializing function needed for recording and saving audio
<DllImport("winmm.dll")> _
Private Shared Function mciSendString(ByVal command As String, ByVal buffer As String, ByVal bufferSize As Integer, ByVal hwndCallback As IntPtr) As Integer
End Function
'for dragging form
Dim drag As Boolean
Dim a As Integer
Dim b As Integer
'to get screen resolution
Dim MW As Integer = Screen.PrimaryScreen.Bounds.Width
Dim MH As Integer = Screen.PrimaryScreen.Bounds.Height
Dim MH2 As Integer
Public ScreenSize As Size = New Size(MW, MH)
Dim bdr As Integer = 152
Dim bdr2 As Integer
'get mouse position, and set it's bitmap
Dim mousex As Integer
Dim mousey As Integer
Dim mousecursor As Bitmap
'for the ffmpeg processes, started in Record button sub
Dim proc As New Process
Dim proc2 As New Process
'for the ffmpeg merge process, located in BW2 (background worker)
Dim proc3 As New Process
'for the play process
Dim proc4 As New Process
'Used within the video recording Backgroundworker sub, renamed BW1
Dim audiostr As String = "Stereo Mix (Realtek High Defini"
Dim istr As FileStream
Dim stopwatch1 As New Stopwatch
Dim stopwatch2 As New Stopwatch
Dim fcounter As Integer = 1
Dim Frames As String
'for date and time in final video's filename
Dim strDate As String
'timer for 2nd Backgroundworker, BW2
Dim stopwatch3 As New Stopwatch
'directory path to system's video folder where Captured folder will be created
Dim dir As String = Environment.GetFolderPath(Environment.SpecialFolder.MyVideos)
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'creates required folder for captured video and audio if it doesn't already exist
If My.Computer.FileSystem.DirectoryExists(dir) = False Then
Throw New Exception("The specified Directory doesn't exist. Please check it's spelling.")
ElseIf My.Computer.FileSystem.DirectoryExists(dir & "\" & "\Captured") Then
Else
My.Computer.FileSystem.CreateDirectory(dir & "\" & "\Captured")
End If
MH2 = MH
'set crop of capture if the primary screen height is 1024
If MW = 1280 And MH = 1024 Then
MH2 = 720
Else
End If
End Sub
'next 3 subs is for dragging the application
Private Sub Form1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
drag = True
a = Windows.Forms.Cursor.Position.X - Me.Left
b = Windows.Forms.Cursor.Position.Y - Me.Top
End Sub
Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
If drag Then
Me.Top = Windows.Forms.Cursor.Position.Y - b
Me.Left = Windows.Forms.Cursor.Position.X - a
End If
End Sub
Private Sub Form1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseUp
drag = False
End Sub
Private Sub Record_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Record.Click
CloseButton.Enabled = False
StopRec.Enabled = True
Play.Enabled = False
bdr = 152
stopwatch2.Reset()
'starts ffmpeg process for mp3 capture
proc.StartInfo.FileName = Application.StartupPath + "\ffmpeg.exe"
proc.StartInfo.Arguments = String.Format("-f dshow -i audio=""" + audiostr + """ -acodec libmp3lame -b:a 128k -y " + dir + "\Captured\CapturedAudio.mp3")
proc.StartInfo.UseShellExecute = False
proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
proc.StartInfo.RedirectStandardInput = True
proc.StartInfo.RedirectStandardOutput = True
proc.StartInfo.CreateNoWindow = True
proc.Start()
'starts ffmpeg process for captured frames
proc2.StartInfo.FileName = Application.StartupPath + "\ffmpeg.exe"
proc2.StartInfo.Arguments = String.Format("-f image2pipe -r 30 -i pipe:.bmp -pix_fmt yuv420p -c:v libx264 -crf 18 -g 1 -y -r 30 " + dir + "\Captured\Temp.mp4")
proc2.StartInfo.UseShellExecute = False
proc2.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
proc2.StartInfo.RedirectStandardInput = True
proc2.StartInfo.RedirectStandardOutput = True
proc2.StartInfo.CreateNoWindow = True
proc2.Start()
Label4.Text = "Recording"
BW1.RunWorkerAsync()
Record.Enabled = False
End Sub
Private Sub StopRec_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StopRec.Click
strDate = DateTime.Now.ToString("ddMMMyyyy_hhmmss")
CloseButton.Enabled = True
Label4.Text = "Saving..."
MediaMerger.Enabled = True
Play.Enabled = True
Record.Enabled = True
End Sub
Private Sub Play_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Play.Click
proc4.StartInfo.FileName = dir + "\Captured\Movie.mp4"
proc4.Start()
End Sub
Private Sub MinimizeButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MinimizeButton.Click
Me.WindowState = FormWindowState.Minimized
End Sub
Private Sub CloseButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CloseButton.Click
Me.Close()
End Sub
'delegate & sub used by BW2 (backgroundworker)
Delegate Sub SetLabelTextInvoker(ByVal label As Label, ByVal Text As String)
Sub SetLabelText(ByVal Label As Label, ByVal Text As String)
If Label4.InvokeRequired = True Then
Label4.Invoke(New SetLabelTextInvoker(AddressOf SetLabelText), Label, Text)
Else
Label4.Text = Text
End If
End Sub
'delegate & sub used by BW1 (backgroundworker)
Delegate Sub SetLabelTextInvoker2(ByVal label As Label, ByVal Text As String)
Sub SetLabelText2(ByVal Label As Label, ByVal Text As String)
If Label6.InvokeRequired = True Then
Label6.Invoke(New SetLabelTextInvoker2(AddressOf SetLabelText2), Label, Text)
Else
Label6.Text = Text
End If
End Sub
'backgroundworker for capturing images and relaying them to ffmpeg for video creation
Private Sub BW1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BW1.DoWork
On Error GoTo error_handler2
Dim writer As New BinaryWriter(proc2.StandardInput.BaseStream)
For i As Integer = 0 To 1000000
stopwatch1.Start()
stopwatch2.Start()
Frames = Format(fcounter, "000000")
Dim BMP As New System.Drawing.Bitmap(MW, MH2, System.Drawing.Imaging.PixelFormat.Format32bppArgb)
Dim Cap As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(BMP)
Cap.CopyFromScreen(New Point(0, bdr), New Point(0, 0), ScreenSize, System.Drawing.CopyPixelOperation.SourceCopy)
'if checkbox is checked, then the mouse will be recorded
If CheckBox1.Checked = True Then
mousex = Cursor.Position.X
mousey = Cursor.Position.Y - bdr
mousecursor = New Bitmap(My.Resources.mouse)
Dim g As Graphics = Graphics.FromImage(BMP)
g.DrawImage(mousecursor, mousex, mousey)
If MW = 1280 And MH = 1024 Then
'capture region follows the mouse
If mousey <= bdr + 30 Then
bdr = CInt(mousey - 30)
If bdr < 0 Then
bdr = 0
Else
End If
Else
If mousey >= 690 Then
bdr2 = mousey + bdr
bdr = bdr2 - mousey
bdr = bdr + 30
If bdr >= 304 Then
bdr = 304
Else
End If
Else
End If
End If
Else
End If
Else
End If
BMP.Save(writer.BaseStream, System.Drawing.Imaging.ImageFormat.Bmp)
If Label4.Text = "Saving..." Then
BMP.Dispose()
Cap.Dispose()
GC.Collect()
writer.Close()
stopwatch1.Stop()
stopwatch2.Stop()
proc.StandardInput.WriteLine("q")
BW1.CancelAsync()
Else
BW1.ReportProgress(i)
End If
fcounter = fcounter + 1
i = i + 1
BMP.Dispose()
Cap.Dispose()
GC.Collect()
'below code displays time during capture
'uses SetLabelTextInvoker2 delegate, SetLabelText2 sub, label6 & custom stopwatch (timer2)
SetLabelText2(Label6, CStr(stopwatch2.Elapsed.ToString("hh\:mm\:ss\.fff")))
'Do Until Loop for ensuring capture interval, which is purposely not set to-
'400000 (actual interval for 25fps), because the For Next loop wastes time during loop
Do
Loop Until stopwatch1.Elapsed.Ticks >= 333040
stopwatch1.Reset()
Next
error_handler2:
End Sub
Private Sub BW1_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BW1.ProgressChanged
'for Captured Frames counter
Label2.Text = Convert.ToString(Frames)
End Sub
'started by the MediaMerger timer, this backgroundworker detects if ffmpeg is done merging audio with video
Private Sub BW2_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BW2.DoWork
For i As Integer = 0 To 1000000
stopwatch3.Start()
BW2.ReportProgress(i)
If Process.GetProcessesByName("ffmpeg").Length > 0 Then
Else
stopwatch3.Stop()
SetLabelText(Label4, "Done")
BW2.CancelAsync()
Exit Sub
End If
Next
End Sub
Private Sub BW2_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BW2.ProgressChanged
End Sub
Private Sub MediaMerger_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MediaMerger.Tick
'starts ffmpeg detector to detect if it's still running
BW2.RunWorkerAsync()
'stopwatch delayer to give enough time for captured audio and video to save before merge
stopwatch1.Start()
Do
Loop Until stopwatch1.Elapsed.Ticks >= 999999
stopwatch1.Stop()
'merges the audio with the video, with a final date & Time filename, ex. 15Feb2015_124202.mp4
proc3.StartInfo.FileName = Application.StartupPath + "\ffmpeg.exe"
proc3.StartInfo.Arguments = String.Format("-r 30 -i " + dir + "\Captured\Temp.mp4 -i " + dir + "\Captured\CapturedAudio.mp3 -r 30 -c:v copy -c:a aac -async 30 -strict experimental -map 0 -map 1 -y " + dir + "\Captured\" + strDate + ".mp4")
proc3.StartInfo.UseShellExecute = False
proc3.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
proc3.StartInfo.RedirectStandardInput = True
proc3.StartInfo.RedirectStandardOutput = True
proc3.StartInfo.CreateNoWindow = True
proc3.Start()
StopRec.Enabled = False
'resets Frames' counter
fcounter = 1
MediaMerger.Enabled = False
End Sub
End Class
Last edited by Peter Porter; Feb 22nd, 2015 at 10:24 AM.
Re: VB.NET - MPEG-4 Screen recorder. 22 Feb 2015 update
Some strange things going on with that example. Like for example you use an environment variable thats created by the system yet if it does not exist ask the user to check the spelling. How do they have any control over it?
Re: VB.NET - MPEG-4 Screen recorder. 22 Feb 2015 update
ident, I removed that check for that environment variable. It only checks for the Captured folder now.
I've made some other changes and fixes, but I'm gonna rebuild this whole project from scratch to see if that fixes one major issue. I can't publish a working installation executable. But the weird thing, from my updated app that I haven't posted to replace the above zip, if I copy the executable from the bin Debug folder to another folder outside the project and run it, my app works fine.
Last edited by Peter Porter; Mar 23rd, 2015 at 06:06 AM.
Since it's too long to add to the top post, I have to split it between 4 posts:
From the Properties sidepanel:
* Set FormBorderStyle to None
* DoubleBuffered to True
* Size 645x72
Controls:
* 2 backgroundworkers named BW1 and BW2
* Timer named MediaMerger
* 5 Buttons named Record, StopRec, Play, MinimizeButton, CloseButton
* CheckBox: From it's properties, enter "Record Mouse" for Text
* 7 labels
Label 1's Text is "Captured Frames:"
Label 2's Text is "000000"
Label 3's Text is "Status:
Label 4's Text is "--------------"
Label 5's Text is "Time:"
Label 6's Text is "00:00:00.000"
Label 7's Text is "hr min sec msec"
Extra forms used as regionbars:
* 2 forms named TopBar and BottomBar
Project's Resources:
* Mouse image, png or jpeg
* FFmpeg.exe - download either the 32bit or 64bit static builds and add ffmpeg.exe to resources.
* BackgroundImage for Topbar and Bottombar forms. (No image? Set their BackColor's to DarkSeaGreen)
Form1's code:
Code:
Option Strict On
Imports System.IO
Imports System.Net
Imports System.Text
Imports System.Threading
Imports System.Drawing
Imports System.Drawing.Image
Imports System.Runtime.InteropServices
Public Class Form1
' P/Invoke declarations
<DllImport("gdi32.dll")> _
Private Shared Function BitBlt(ByVal hdcDest As IntPtr, ByVal xDest As Integer, ByVal yDest As Integer, ByVal wDest As Integer, ByVal hDest As Integer, ByVal hdcSource As IntPtr, _
ByVal xSrc As Integer, ByVal ySrc As Integer, ByVal rop As CopyPixelOperation) As Boolean
End Function
<DllImport("user32.dll")> _
Private Shared Function ReleaseDC(ByVal hWnd As IntPtr, ByVal hDc As IntPtr) As Boolean
End Function
<DllImport("gdi32.dll")> _
Private Shared Function DeleteDC(ByVal hDc As IntPtr) As IntPtr
End Function
<DllImport("gdi32.dll")> _
Private Shared Function DeleteObject(ByVal hDc As IntPtr) As IntPtr
End Function
<DllImport("gdi32.dll")> _
Private Shared Function CreateCompatibleBitmap(ByVal hdc As IntPtr, ByVal nWidth As Integer, ByVal nHeight As Integer) As IntPtr
End Function
<DllImport("gdi32.dll")> _
Private Shared Function CreateCompatibleDC(ByVal hdc As IntPtr) As IntPtr
End Function
<DllImport("gdi32.dll")> _
Private Shared Function SelectObject(ByVal hdc As IntPtr, ByVal bmp As IntPtr) As IntPtr
End Function
<DllImport("user32.dll")> _
Public Shared Function GetDesktopWindow() As IntPtr
End Function
<DllImport("user32.dll")> _
Public Shared Function GetWindowDC(ByVal ptr As IntPtr) As IntPtr
End Function
'for dragging form
Dim drag As Boolean
Dim a As Integer
Dim b As Integer
'to get screen resolution
Dim MW As Integer = Screen.PrimaryScreen.Bounds.Width
Dim MH As Integer = Screen.PrimaryScreen.Bounds.Height
Dim AspectH As Integer = CInt(Screen.PrimaryScreen.Bounds.Width / 1920 * 1080)
Dim totalp As Integer
Public ScreenSize As Size = New Size(MW, MH)
Dim bdr As Integer = 0
Dim bdr2 As Integer
'get mouse position, and set it's bitmap
Dim mousex As Integer
Dim mousey As Integer
Dim mousecursor As Bitmap
'for the ffmpeg processes, started in Record button sub
Dim proc As New Process
Dim proc2 As New Process
'for the ffmpeg merge process, located in BW2 (background worker)
Dim proc3 As New Process
'for the play process
Dim proc4 As New Process
'for overwritting temp file before deletion
Dim BMP3 As New Bitmap(1, 1)
'Used within the video recording Backgroundworker sub (BW1)
Dim audiostr As String = "Stereo Mix (Realtek High Defini"
Dim istr As FileStream
Dim stopwatch1 As New Stopwatch
Dim stopwatch2 As New Stopwatch
Dim fcounter As Integer = 1
Dim Frames As String
Dim rr As Integer
Dim fps As Integer
Dim CLoop As Integer
'for date and time in final video's filename
Dim strDate As String
'timer for 2nd Backgroundworker, BW2
Dim stopwatch3 As New Stopwatch
'directory path to system's video folder where Captured folder will be created
Dim dir As String = Environment.GetFolderPath(Environment.SpecialFolder.MyVideos)
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim pProcess() As Process = System.Diagnostics.Process.GetProcessesByName("ffmpeg")
For Each p As Process In pProcess
p.Kill()
Next
'creates required folder for captured video and audio if it doesn't already exist
If My.Computer.FileSystem.DirectoryExists(dir & "\" & "\Captured") = False Then
My.Computer.FileSystem.CreateDirectory(dir & "\" & "\Captured")
Else
End If
'delayer, to give enough time for the captured folder to be created
stopwatch1.Start()
Do
Loop Until stopwatch1.Elapsed.Ticks >= 333040
stopwatch1.Reset()
stopwatch1.Stop()
'extracts ffmpeg from resources to the captured folder
If My.Computer.FileSystem.FileExists("C:\Users\Web\Videos\Captured\ffmpeg.exe") = False Then
savefromresources("C:\Users\Web\Videos\Captured\ffmpeg.exe", My.Resources.ffmpeg)
Else
End If
'application location at runtime
Dim appx As Integer = MW
Dim appy As Integer = MH
appx = CInt((appx - 645) / 2)
appy = CInt((appy - 72) / 2)
Me.Location = New Point(appx, appy)
'sets fps for ffmpeg, and BW1's (backgroundworker) capture interval loop
totalp = MW * MH
If totalp <= 921600 Then
fps = 30
CLoop = 333333
Else
fps = 25
CLoop = 400000
End If
'if AspectH (primary screen's width / 1920 * 1080) is less than the
'primary screen's height, the "Crop to 16.9" checkbox is set to visible
If AspectH < Screen.PrimaryScreen.Bounds.Height Then
CheckBox2.Visible = True
Else
End If
End Sub
Public Sub savefromresources(ByVal filepath As String, ByVal file As Object)
Dim fbyte() As Byte = CType(file, Byte())
My.Computer.FileSystem.WriteAllBytes(filepath, fbyte, True)
End Sub
'next 3 subs is for dragging the application
Private Sub Form1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
drag = True
a = Windows.Forms.Cursor.Position.X - Me.Left
b = Windows.Forms.Cursor.Position.Y - Me.Top
End Sub
Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
If drag Then
Me.Top = Windows.Forms.Cursor.Position.Y - b
Me.Left = Windows.Forms.Cursor.Position.X - a
End If
End Sub
Private Sub Form1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseUp
drag = False
End Sub
Private Sub Record_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Record.Click
CheckBox2.Enabled = False
If CheckBox2.Checked = False And totalp > 921600 Then
fps = 25
CLoop = 400000
MW = Screen.PrimaryScreen.Bounds.Width
MH = Screen.PrimaryScreen.Bounds.Height
bdr = 0
Else
fps = 30
CLoop = 333040
bdr = CInt((Screen.PrimaryScreen.Bounds.Height - AspectH) / 2)
End If
Me.WindowState = FormWindowState.Minimized
'set crop of capture if the primary screen height is 1024
If CheckBox2.Checked = True Then
TopBar.Top = -152
BottomBar.Top = Screen.PrimaryScreen.Bounds.Height - 152
TopBar.Show()
BottomBar.Show()
TopBar.TopMost = True
BottomBar.Size = New System.Drawing.Size(1280, 111)
bdr = CInt((Screen.PrimaryScreen.Bounds.Height - AspectH) / 2)
MH = AspectH
If CheckBox1.Checked = True Then
BottomBar.Size = New System.Drawing.Size(1280, 304)
BottomBar.TopMost = True
Else
End If
Else
End If
'overwritting/deleting temp mp4. Reason for this, sometimes capturing wont overwrite the temp mp4.
Try
BMP3.Save("C:\Users\Web\Videos\Captured\Temp.mp4")
Catch ex As Exception
BottomBar.Size = New System.Drawing.Size(1280, BottomBar.Height - 30)
MsgBox("Temp.mp4 is in use. It must be free in order to capture.")
Exit Sub
End Try
stopwatch1.Start()
Do
Loop Until stopwatch1.Elapsed.Ticks >= 333040
stopwatch1.Reset()
stopwatch1.Stop()
System.IO.File.Delete("C:\Users\Web\Videos\Captured\Temp.mp4")
CloseButton.Enabled = False
StopRec.Enabled = True
Play.Enabled = False
stopwatch2.Reset()
'starts ffmpeg process for mp3 capture
proc.StartInfo.FileName = "C:\Users\Web\Videos\Captured\ffmpeg.exe"
proc.StartInfo.Arguments = String.Format("-f dshow -i audio=""" + audiostr + """ -acodec libmp3lame -b:a 128k -y " + dir + "\Captured\CapturedAudio.mp3")
proc.StartInfo.UseShellExecute = False
proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
proc.StartInfo.RedirectStandardInput = True
proc.StartInfo.RedirectStandardOutput = True
proc.StartInfo.CreateNoWindow = True
proc.Start()
'starts ffmpeg process for captured frames
proc2.StartInfo.FileName = "C:\Users\Web\Videos\Captured\ffmpeg.exe"
proc2.StartInfo.Arguments = String.Format("-f image2pipe -r " & fps & " -i pipe:.bmp -pix_fmt yuv420p -c:v libx264 -crf 18 -g 1 -y -r " & fps & " " & dir & "\Captured\Temp.mp4")
proc2.StartInfo.UseShellExecute = False
proc2.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
proc2.StartInfo.RedirectStandardInput = True
proc2.StartInfo.RedirectStandardOutput = True
proc2.StartInfo.CreateNoWindow = True
proc2.Start()
Label4.Text = "Recording"
BW1.RunWorkerAsync()
Record.Enabled = False
End Sub
Private Sub StopRec_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StopRec.Click
CheckBox2.Enabled = True
strDate = DateTime.Now.ToString("ddMMMyyyy_hhmmss")
Label4.Text = "Saving..."
TopBar.Hide()
BottomBar.Hide()
MediaMerger.Enabled = True
'starts background worker to detect if the ffmpeg audio save process is still running
BW2.RunWorkerAsync()
End Sub
Private Sub Play_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Play.Click
proc4.StartInfo.FileName = dir + "\Captured\" & strDate & ".mp4"
proc4.Start()
End Sub
Private Sub MinimizeButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MinimizeButton.Click
Me.WindowState = FormWindowState.Minimized
End Sub
Private Sub CloseButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CloseButton.Click
Me.Close()
End Sub
Continued in next post...
Last edited by Peter Porter; Jul 20th, 2015 at 09:39 AM.
'delegate & sub used by BW2 (backgroundworker)
Delegate Sub SetLabelTextInvoker(ByVal label As Label, ByVal Text As String)
Sub SetLabelText(ByVal Label As Label, ByVal Text As String)
If Label4.InvokeRequired = True Then
Label4.Invoke(New SetLabelTextInvoker(AddressOf SetLabelText), Label, Text)
Else
Label4.Text = Text
End If
End Sub
'delegate & sub used by BW1 (backgroundworker)
Delegate Sub SetLabelTextInvoker2(ByVal label As Label, ByVal Text As String)
Sub SetLabelText2(ByVal Label As Label, ByVal Text As String)
If Label6.InvokeRequired = True Then
Label6.Invoke(New SetLabelTextInvoker2(AddressOf SetLabelText2), Label, Text)
Else
Label6.Text = Text
End If
End Sub
'backgroundworker for capturing images and relaying them to ffmpeg for video creation
Private Sub BW1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BW1.DoWork
Try
Dim writer As New BinaryWriter(proc2.StandardInput.BaseStream)
For i As Integer = 0 To 1000000
stopwatch1.Start()
stopwatch2.Start()
Frames = Format(fcounter, "000000")
Dim hDesk As IntPtr = GetDesktopWindow()
Dim hSrce As IntPtr = GetWindowDC(hDesk)
Dim hDest As IntPtr = CreateCompatibleDC(hSrce)
Dim hBmp As IntPtr = CreateCompatibleBitmap(hSrce, MW, MH)
Dim hOldBmp As IntPtr = SelectObject(hDest, hBmp)
Dim b As Boolean = BitBlt(hDest, 0, 0, MW, MH, hSrce, 0, bdr, CopyPixelOperation.SourceCopy Or CopyPixelOperation.CaptureBlt)
Dim bmp As Bitmap = Bitmap.FromHbitmap(hBmp)
SelectObject(hDest, hOldBmp)
DeleteObject(hBmp)
DeleteDC(hDest)
ReleaseDC(hDesk, hSrce)
'if checkbox is checked, then the mouse will be recorded
If CheckBox1.Checked = True Then
mousex = Cursor.Position.X
mousey = Cursor.Position.Y - bdr
mousecursor = New Bitmap(My.Resources.mouse)
Dim g As Graphics = Graphics.FromImage(BMP)
g.DrawImage(mousecursor, mousex, mousey)
If AspectH < Screen.PrimaryScreen.Bounds.Height And CheckBox2.Checked = True Then
'capture region follows the mouse
If mousey <= bdr + 30 Then
bdr = CInt(mousey - 30)
If bdr < 0 Then
bdr = 0
Else
End If
Else
If mousey >= 690 Then
bdr = bdr + 30
If bdr >= 304 Then
bdr = 304
Else
End If
Else
End If
End If
Else
End If
Else
End If
BMP.Save(writer.BaseStream, System.Drawing.Imaging.ImageFormat.Bmp)
If Label4.Text = "Saving..." Then
BMP.Dispose()
'Cap.Dispose()
GC.Collect()
writer.Close()
stopwatch1.Stop()
stopwatch2.Stop()
proc.StandardInput.WriteLine("q")
BW1.CancelAsync()
Else
BW1.ReportProgress(i)
End If
fcounter = fcounter + 1
i = i + 1
BMP.Dispose()
'Cap.Dispose()
GC.Collect()
'below code displays time during capture
'uses SetLabelTextInvoker2 delegate, SetLabelText2 sub, label6 & custom stopwatch (timer2)
SetLabelText2(Label6, CStr(stopwatch2.Elapsed.ToString("hh\:mm\:ss\.fff")))
'Do Until Loop for ensuring capture interval, which is purposely not set to-
'400000 (actual interval for 25fps), because the For Next loop wastes time during loop
Do
Loop Until stopwatch1.Elapsed.Ticks >= CLoop
stopwatch1.Reset()
Next
Catch ex As Exception
End Try
End Sub
Private Sub BW1_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BW1.ProgressChanged
'for Captured Frames counter
Label2.Text = Convert.ToString(Frames)
If CheckBox1.Checked = True Then
BottomBar.Size = New System.Drawing.Size(1280, 304)
If mousey <= bdr + 30 Then
If bdr <= 0 Then
TopBar.Top = bdr - 304
Else
TopBar.Top = bdr - 304
BottomBar.Top = bdr + 720
End If
Else
If mousey >= 512 Then
If bdr >= 304 Then
BottomBar.Top = 1025
Else
TopBar.Top = bdr - 304
BottomBar.Top = bdr + 720
End If
End If
End If
Else
End If
End Sub
'started by the Stop button & MediaMerger timer, this backgroundworker detects if ffmpeg process is still running
Private Sub BW2_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BW2.DoWork
For i As Integer = 0 To 1000000
BW2.ReportProgress(i)
If Process.GetProcessesByName("ffmpeg").Length > 0 Then
Else
SetLabelText(Label4, "Done")
BW2.ReportProgress(i)
BW2.CancelAsync()
Exit Sub
End If
Next
End Sub
Private Sub BW2_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BW2.ProgressChanged
If Label4.Text = "Done" Then
CloseButton.Enabled = True
Play.Enabled = True
Record.Enabled = True
End If
End Sub
Private Sub MediaMerger_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MediaMerger.Tick
If Label4.Text = "Done" Then
Label4.Text = " Merging Media"
stopwatch1.Start()
Do
Loop Until stopwatch1.Elapsed.Ticks >= 999999
stopwatch1.Reset()
'starts background worker again to detect if the ffmpeg merge process is still running
BW2.RunWorkerAsync()
'merges the audio with the video, with a final date & Time filename, ex. 15Feb2015_124202.mp4
proc3.StartInfo.FileName = "C:\Users\Web\Videos\Captured\ffmpeg.exe"
proc3.StartInfo.Arguments = String.Format("-r " & fps & " -i " & dir & "\Captured\Temp.mp4 -i " & dir & "\Captured\CapturedAudio.mp3 -r " & fps & " -c:v copy -c:a aac -async " & fps & " -strict experimental -map 0 -map 1 -y " & dir & "\Captured\" & strDate & ".mp4")
proc3.StartInfo.UseShellExecute = False
proc3.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
proc3.StartInfo.RedirectStandardInput = True
proc3.StartInfo.RedirectStandardOutput = True
proc3.StartInfo.CreateNoWindow = True
proc3.Start()
StopRec.Enabled = False
'resets Frames' counter
fcounter = 1
MediaMerger.Enabled = False
Else
End If
End Sub
Private Sub CheckBox2_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox2.CheckedChanged
fps = 30
CLoop = 333040
End Sub
End Class
Next to posts contain code and information for the regionbar forms (TopBar, BottomBar).
Last edited by Peter Porter; May 23rd, 2015 at 10:53 AM.
From the Properties sidepanel:
* Set FormBorderStyle to None
* DoubleBuffered to True
* BackColor to DarkSeaGreen
* Size 1280x304
* Opacity to 75%
Code:
Public Class TopBar
Private Sub TopBar_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.Location = New Point(0, -152)
Me.TopMost = True
End Sub
End Class
Last edited by Peter Porter; May 23rd, 2015 at 10:53 AM.
From the Properties sidepanel:
* Set FormBorderStyle to None
* DoubleBuffered to True
* BackColor to DarkSeaGreen
* Size 1280x304
* Opacity to 75%
Code:
Public Class BottomBar
Private Sub BottomBar_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.Location = New Point(0, 874)
Me.TopMost = True
End Sub
End Class
Last edited by Peter Porter; May 23rd, 2015 at 10:54 AM.
Re: MPEG-4 Screen recorder. April 8th, 2015 update
Latest version adjusts frames per second (fps) and capture interval according to screen resolution's total pixels. Screen resolutions with a pixel total equal to or less than 921600 pixels (1280x720) are captured at 30fps. Larger pixel totals (1280x1024, 1920x1080, etc...) are captured at 25fps.
It no longer automatically crops. You must check "Crop to 16.9". If "Record mouse" is checked, along with "Crop to 16.9", the capture region follows the mouse according to actual screen bounds height.
Last edited by Peter Porter; Apr 9th, 2015 at 05:59 PM.
Re: VB.NET - MPEG-4 Screen recorder. May 23rd, 2015 update
I fixed a few bugs.
No more endless saves, or crashes during a restart of the screen recorder. This was caused by stopping the app from the VB dashboard during a recording, which left an FFmpeg process running. Now a check is done for any FFmpeg processes at initial runtime, which is then stopped before any recording is made.
Regionbars issues have been solved. They are realigned, resized, and displayed for every recording.
Re: VB.NET - MPEG-4 Screen recorder. April 30th, 2015 update
vinodvin42, the polished looking version you quoted wont be available online as a project file. It has some extras, but it uses the same recording code as my older version.
Have you downloaded the FFmpeg static build and placed it within this project's resources folder? It needs FFmpeg in order to record audio as well as video.
The recorder was designed to work with older versions of FFmpeg below, but might work with the latest static builds now. 32bit version 64bit version
If you have FFmpeg, the only other thing could be is that you don't have your system's Stereo Mix enabled.
Enabling Stereo Mix for Windows Vista, 7 and 8
* Right-click over the Speaker icon by the system clock then choose Recording Devices to open the Recording tab of "Sound".
* Right-click Stereo Mix, and from it's dropdown menu, click Enable.
Note (Vista, 7 and 8):
If you don't see Stereo Mix, right click within the Recording tab window, then check "Show Disabled Devices".
Enabling Stereo Mix for Windows XP
* Click the Speaker icon by the system clock.
* In the window that appears, choose Options then Properties.
* In the next window, click the "Recording" radio button, then in "Show the following volume controls", click in the box for Stereo Mix, then "OK".
Last edited by Peter Porter; Jul 31st, 2015 at 05:05 AM.