A Video Converter in Visual Basic .NET

Introduction

This is a simple video converter developed with .NET while playing with ffmpeg.

Ffmpeg is an open source command line audio / video converter. ffmpeg uses command line arguments for its conversion and this is what we are going to do with our .NET application. We will execute ffmpeg from our application and send these parameters to ffmpeg without displaying the command line window.

Background

The application uses a background worker. BackgroundWorker prevents our form from hanging while the conversion is in progress. I had that problem whenever I started the ffmpeg process.

The BackgroundWorker component gives you the ability to execute time-consuming operations asynchronously (“in the background”), on a thread different from your application’s main UI thread. To use a BackgroundWorker, you simply tell it what time-consuming worker method to execute in the background, and then you call the RunWorkerAsync method. Your calling thread continues to run normally while the worker method runs asynchronously. When the method is finished, the BackgroundWorker alerts the calling thread by firing the RunWorkerCompleted event, which optionally contains the results of the operation. (MSDN 2008)

Ffmpeg is freely available on the internet. You need to have the binary version, i.e., ffmpeg.exe in the application directory of your project. It is included in the zip file.

How to Create the Converter

Let’s get started by using ffmpeg.exe. Open the command prompt in your Windows environment and navigate to the directory where ffmpeg.exe is located.

Now let’s say ffmpeg is located in C:\ i.e., C:\ffmpeg.exe, we navigate to our C: directory on the command prompt and type in a few commands into ffmpeg. Let’s say we have a .avi video file in our C: directory and want to convert that video to a .flv file, we just need to enter the command: ffmpeg -i input.avi output.flv

Note that different arguments can be parsed to ffmpeg for various kinds on conversion, but for the purpose of this tutorial, we will stick to the very basic commands needed to convert our video file. What that argument above does is that it creates a converted video version of the file input.avi to output.flv in our C: directory. Basically, this is what our program is going to do but this time around without the command prompt. We will be sending the arguments through our program to ffmpeg. For more documentation on how to use ffmpeg, checkout this FFmpeg site…

Now let’s begin with our program in .NET.

Step 1

Insert three textboxes, a trackbar, a background worker, open and save dialog boxes and four command buttons into your new form. You also need to place ffmpeg.exe in the /bin folder of your application directory.

The dialogSave and dialogOpen tools enable us to specify where our file is located and where we want to save the output file. The backgroundWorker tool allows us to run the ffmpeg process in a different thread from our application’s UI thread, this allows our application to run properly without interruption from ffmpeg process while the actual conversion is in progress.

Step 2

Let’s create a function that performs the conversion:

Function startConversion()
Control.CheckForIllegalCrossThreadCalls = False
Dim input As String = Me.dlgOpen.FileName 'the input file
Dim output As String = Me.dlgSave.FileName 'the output file

'ffmpeg location
Dim exepath As String = Application.StartupPath + "\bin\ffmpeg.exe"
Dim quality As Integer = TrackBar1.Value * 2

Dim startinfo As New System.Diagnostics.ProcessStartInfo
Dim sr As StreamReader
Dim cmd As String = " -i """ + input + """ -ar 22050 -qscale " _
& quality & " -y """ + output + """"
'ffmpeg commands -y to force overwrite
' the –qscale option allows us to set the quality of our video with our trackbar

Dim ffmpegOutput As String

'all parameters required to run the process
'ffmpeg uses standard error to display its output

startinfo.FileName = exepath
startinfo.Arguments = cmd
startinfo.UseShellExecute = False
startinfo.WindowStyle = ProcessWindowStyle.Hidden
startinfo.RedirectStandardError = True 'redirect ffmpegs output
'to our application
startinfo.RedirectStandardOutput = True 'we don’t really need this
startinfo.CreateNoWindow = True
proc.StartInfo = startinfo
proc.Start() ' start the process
Me.lblInfo.Text = "Conversion in progress... Please wait..."
sr = proc.StandardError 'standard error is used by ffmpeg
Me.btnStart.Enabled = False
Do
If BackgroundWorker1.CancellationPending Then
'check if a cancellation request was made and
'exit the function if true
Exit Function
End If
ffmpegOutput = sr.ReadLine 'displays ffmpeg’s output
'in the textbox one line at a time
Me.txtProgress.Text = ffmpegOutput
Loop Until proc.HasExited And ffmpegOutput = Nothing Or ffmpegOutput = ""

Me.txtProgress.Text = "Finished !"
Me.lblInfo.Text = "Completed!"
MsgBox("Completed!", MsgBoxStyle.Exclamation)
Me.btnStart.Enabled = True
Return 0
End Function
We created a function startConversion() which performs the actual conversion of the file with ffmpeg.

Setting Control.CheckForIllegalCrossThreadCalls to False prevents Visual Studio from catching calls on a different thread that accesses a control’s Handle property when an application is being debugged because we will be calling our controls from another thread separate from our form’s thread, i.e., the backgroundWorker process where our function is located.

Dim cmd As String = " -i """ + input + """ -ar 22050 -qscale " _
& quality & " -y """ + output + """"
This command is parsed to ffmpeg.exe to do the actual conversion for us.

-i input” specifies our input file, e.g., sample.avi, the “-ar 22050” specifies the audio sampling frequency as 22050 which is common for flash video files, we can also specify a different one like 44100 which is actually the default in ffmpeg. “-qscale” specifies the quality of the video e.g.,. “-qscale 2” is of higher quality than “-qscale 10”. The value of our quality variable is retrieved from the trackbar. We want our users to specify the quality of the video they want using the trackbar.

Note that startinfo contains properties that allows us to specify that our process is being run. The WindowStyleproperty is set to hidden, this prevents the command prompt console from showing.

RedirectStandardOutput property is used to redirect whatever is displayed on the command prompt to a different control. But ffmpeg uses standardError to display its conversion output, this is why we have to use theRedirectStandardError and set its value to true.

BackgroundWorker1.CancellationPending shows that a cancellation request was sent to terminate the process, we use this property to exit our function, this actually kills the ffmpeg process.

A textbox ffmpegOutput is used to display the output from ffmpeg by assigning sr.ReadLine to it.

Step 3

On the startButton, insert the following code:

Private Sub btnStart_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnStart.Click
If txtOpen.Text = "" Or txtOpen.Text <> dlgOpen.FileName Then
MsgBox("Select a file to convert", MsgBoxStyle.Information, "Select a file")
Exit Sub
ElseIf txtSave.Text = "" Or txtSave.Text <> dlgSave.FileName Then
MsgBox("Select your output filename", MsgBoxStyle.Information, "Select a file")
Exit Sub
End If
BackgroundWorker1.RunWorkerAsync() ‘start the background worker
End Sub
RunWorkerAsync() action of the backgroundWorker is used to start the process. What this does is that it executes the startConversion() function we inserted in the BackgroundWorker1_DoWork procedure.

Step 4

On the save dialog tool, insert the following code:

Private Sub dlgSave_FileOk(ByVal sender As System.Object, _
ByVal e As System.ComponentModel.CancelEventArgs) Handles dlgSave.FileOk
dlgSave.OverwritePrompt = True
dlgSave.DereferenceLinks = True
dlgSave.CreatePrompt = True
dlgSave.DefaultExt = ".flv" 'this program converts to flv only,
'you can allow the user to save in any
'format by including more video file
'extension in the save option dialog box
txtSave.Text = dlgSave.FileName
End Sub

'To stop the conversion process, we send a notification to the
'backgroundWorker and kill the ffmpeg process

Private Sub btnStop_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnStop.Click
On Error GoTo handle
BackgroundWorker1.CancelAsync()
If btnStart.Enabled = False Then
lblInfo.Text = ("Conversion Canceled!")
MsgBox("Conversion has been cancelled!", MsgBoxStyle.Exclamation)
btnStart.Enabled = True
Else
MsgBox("Start conversion first", MsgBoxStyle.Critical)
End If

proc.Kill()
handle:
Exit Sub
End Sub
On our stop button, we send a CancelAsync() request to the backgroundWorker. This request enables us to handle anything we need to display or do before we end the process. For example, we can display a message box that confirms cancellation and also perform a different task on the process before the process ends.

Step 5

The backgroundWorker calls the conversion function here:

Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, _
ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
startConversion()
End Sub

Resources

Download Source

I write codes... web, mobile, desktop and hack stuffs

One Response
  • MaX
    Nov 20, 2014

    Hi, I’m writing the same kind of program, I’ve found very interesting your code, could you re-upload the ZIP source file?

    MaX Nov 20, 2014
    Reply

Leave a Reply

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