Visual Basic .NET 中的视频转换器






4.59/5 (11投票s)
这是我在使用 ffmpeg 时用 .NET 开发的一个简单的视频转换器。
引言
这是使用 .NET 和 ffmpeg 开发的一个简单的视频转换器。
Ffmpeg 是一个开源的命令行音视频转换器。ffmpeg 使用命令行参数进行转换,这就是我们将要用我们的 .NET 应用程序实现的功能。我们将从我们的应用程序执行 ffmpeg 并将这些参数发送给 ffmpeg,而不显示命令行窗口。
在此处 下载源代码 以了解其工作原理。
背景
该应用程序使用背景工作器。BackgroundWorker
可防止在转换进行时窗体假死。当我启动 ffmpeg 进程时遇到了这个问题。
BackgroundWorker
组件使您能够在一个与应用程序主 UI 线程不同的线程上异步地(“在后台”)执行耗时操作。要使用 BackgroundWorker
,您只需告诉它要执行哪个耗时的后台工作方法,然后调用 RunWorkerAsync
方法。您的调用线程在后台方法异步运行时将继续正常运行。当方法完成时,BackgroundWorker
会通过触发 RunWorkerCompleted
事件来通知调用线程,该事件可选地包含操作结果。(MSDN 2008)
如何创建转换器
让我们开始使用 ffmpeg.exe。在您的 Windows 环境中打开命令提示符,并导航到 ffmpeg.exe 所在目录。
现在,假设 ffmpeg 位于 C:\,即 C:\ffmpeg.exe。在命令提示符下,我们将导航到我们的 C: 目录并输入几个 ffmpeg 命令。假设我们在 C: 目录中有一个 .avi 视频文件,并想将其转换为 .flv 文件,我们只需输入命令
ffmpeg -i input.avi output.flv
请注意,可以解析不同的参数给 ffmpeg 进行各种类型的转换,但就本教程而言,我们将坚持使用转换我们的视频文件所需的非常基础的命令。上面那个参数的作用是,它会在我们的 C: 目录中创建一个文件 input.avi 到 output.flv 的转换视频版本。基本上,这就是我们的程序要做的事情,但这次没有命令行。我们将通过我们的程序将参数发送给 ffmpeg。有关如何使用 ffmpeg 的更多文档,请查看这个 FFmpeg 网站...
现在,让我们开始我们的 .NET 程序。
步骤 1
在您的新窗体中插入三个文本框、一个滑块、一个背景工作器、打开和保存对话框以及四个命令按钮。您还需要将 ffmpeg.exe 放在应用程序目录的 /bin 文件夹中。

dialogSave
和 dialogOpen
工具使我们能够指定文件位置以及我们希望保存输出文件的位置。backgroundWorker
工具允许我们在与应用程序 UI 线程不同的线程中运行 ffmpeg 进程,这使得我们的应用程序可以在实际转换过程中不被 ffmpeg 进程中断而正常运行。
第二步
让我们创建一个执行转换的函数
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
我们创建了一个名为 startConversion()
的函数,它使用 ffmpeg 执行实际的文件转换。
将 Control.CheckForIllegalCrossThreadCalls
设置为 False
可防止 Visual Studio 在调试应用程序时捕获在不同线程上访问控件 Handle
属性的调用,因为我们将从与窗体线程不同的另一个线程(即我们的函数所在的 backgroundWorker
进程)调用我们的控件。
Dim cmd As String = " -i """ + input + """ -ar 22050 -qscale " _
& quality & " -y """ + output + """"
此命令将被解析到 ffmpeg.exe 以替我们完成实际的转换。
"-i input
" 指定我们的输入文件,例如 sample.avi,"-ar 22050
" 指定音频采样频率为 22050,这对于 Flash 视频文件很常见,我们也可以指定一个不同的值,如 44100,这实际上是 ffmpeg 中的默认值。"-qscale
" 指定视频的质量,例如。"-qscale 2
" 比 "-qscale 10
" 质量更高。我们的质量变量的值是从滑块中获取的。我们希望用户通过滑块指定他们想要的视频质量。
请注意,startinfo
包含允许我们指定我们正在运行进程的属性。WindowStyle
属性被设置为隐藏,这可以防止命令行控制台显示。
RedirectStandardOutput
属性用于将命令行上显示的内容重定向到另一个控件。但 ffmpeg 使用 standardError
来显示其转换输出,这就是为什么我们必须使用 RedirectStandardError
并将其值设置为 true
。
BackgroundWorker1.CancellationPending
显示已发送取消请求以终止进程,我们使用此属性来退出我们的函数,这实际上会终止 ffmpeg 进程。
使用一个名为 ffmpegOutput
的文本框,通过将 sr.ReadLine
赋值给它来显示来自 ffmpeg 的输出。
步骤 3
在 startButton
上,插入以下代码
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
backgroundWorker
的 RunWorkerAsync()
方法用于启动进程。它的作用是执行我们在 BackgroundWorker1_DoWork
过程中插入的 startConversion()
函数。
步骤 4
在保存对话框工具上,插入以下代码
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
在我们的停止按钮上,我们向 backgroundWorker
发送一个 CancelAsync()
请求。此请求使我们能够处理在结束进程之前需要显示或执行的任何内容。例如,我们可以显示一个确认取消的消息框,并在进程结束前对该进程执行不同的任务。
步骤 5
backgroundWorker
在此处调用转换函数
Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, _
ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
startConversion()
End Sub
关注点
此应用程序仅将不同的视频文件转换为 .flv (Flash 视频)。要将您的视频保存为任何其他格式,只需在保存对话框的 filter 属性中添加更多视频文件扩展名即可。希望您会喜欢它。
历史
只是第一个应用程序。
此致,
Tunde Olabenjo