65.9K
CodeProject 正在变化。 阅读更多。
Home

Visual Basic .NET 中的视频转换器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.59/5 (11投票s)

2011年6月13日

CPOL

5分钟阅读

viewsIcon

95119

downloadIcon

11916

这是我在使用 ffmpeg 时用 .NET 开发的一个简单的视频转换器。

引言

这是使用 .NET 和 ffmpeg 开发的一个简单的视频转换器。

Ffmpeg 是一个开源的命令行音视频转换器。ffmpeg 使用命令行参数进行转换,这就是我们将要用我们的 .NET 应用程序实现的功能。我们将从我们的应用程序执行 ffmpeg 并将这些参数发送给 ffmpeg,而不显示命令行窗口。

在此处 下载源代码 以了解其工作原理。

背景

该应用程序使用背景工作器。BackgroundWorker 可防止在转换进行时窗体假死。当我启动 ffmpeg 进程时遇到了这个问题。

BackgroundWorker 组件使您能够在一个与应用程序主 UI 线程不同的线程上异步地(“在后台”)执行耗时操作。要使用 BackgroundWorker,您只需告诉它要执行哪个耗时的后台工作方法,然后调用 RunWorkerAsync 方法。您的调用线程在后台方法异步运行时将继续正常运行。当方法完成时,BackgroundWorker 会通过触发 RunWorkerCompleted 事件来通知调用线程,该事件可选地包含操作结果。(MSDN 2008)

Ffmpeg 可在互联网上免费获取。您需要在项目的应用程序目录中拥有二进制版本,即 ffmpeg.exe。它包含在 zip 文件中。

如何创建转换器

让我们开始使用 ffmpeg.exe。在您的 Windows 环境中打开命令提示符,并导航到 ffmpeg.exe 所在目录。

现在,假设 ffmpeg 位于 C:\,即 C:\ffmpeg.exe。在命令提示符下,我们将导航到我们的 C: 目录并输入几个 ffmpeg 命令。假设我们在 C: 目录中有一个 .avi 视频文件,并想将其转换为 .flv 文件,我们只需输入命令

ffmpeg -i input.avi output.flv 

请注意,可以解析不同的参数给 ffmpeg 进行各种类型的转换,但就本教程而言,我们将坚持使用转换我们的视频文件所需的非常基础的命令。上面那个参数的作用是,它会在我们的 C: 目录中创建一个文件 input.avioutput.flv 的转换视频版本。基本上,这就是我们的程序要做的事情,但这次没有命令行。我们将通过我们的程序将参数发送给 ffmpeg。有关如何使用 ffmpeg 的更多文档,请查看这个 FFmpeg 网站...

现在,让我们开始我们的 .NET 程序。

步骤 1

在您的新窗体中插入三个文本框、一个滑块、一个背景工作器、打开和保存对话框以及四个命令按钮。您还需要将 ffmpeg.exe 放在应用程序目录的 /bin 文件夹中。

Untitled.png

dialogSavedialogOpen 工具使我们能够指定文件位置以及我们希望保存输出文件的位置。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

backgroundWorkerRunWorkerAsync() 方法用于启动进程。它的作用是执行我们在 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

© . All rights reserved.