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

使用 VB.NET 在 Veron Media Player 中控制 Mplayer

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.61/5 (28投票s)

2013年9月3日

CPOL

4分钟阅读

viewsIcon

120942

downloadIcon

5964

代码描述了我们如何在 VB.NET Winform 应用程序中轻松控制 mplayer

引言

本文将演示我们如何在 VB.NET WinForm 应用程序中使用 mplayer 轻松控制,而无需使用任何 COM/ActiveX 控件。下载的源代码是 Veron Media Player 1.9 的一部分。首先,我们需要在主应用程序的启动路径中放置 mplayer.exe。可以从 这里下载。

背景

Mplayer 是一个命令行音频和视频播放器。它可以使用几种不同的输出驱动程序播放音频或视频文件。以前没有关于如何在 VB.NET winform 应用程序中使用 mplayer 播放音频或视频的示例。发现了控制 mplayer 的 C++ 示例,但如果使用 VB.NET 程序,则更容易和更可靠。

屏幕截图

技术

进程对象、窗口句柄控制、输入和输出重定向。

Using the Code

我们将使用 System.Diagnostics 命名空间的 Process 类来启动一个 mplayer 实例来播放文件。我们将重定向输入和输出,以便我们可以向 mplayer 发送命令并获取有关该文件的信息。

以下是我们用于声明变量和初始化进程的代码

Delegate Sub ChangeTextsSafe(ByVal percent As String)

' To declare Variables :-
  Dim args, time_length, time_pos, buffer, CDP As String
  Dim posh, tdr As Long
  Dim ps As Process = Nothing

' To initialize process :-
  ps = New Process()
  ps.StartInfo.ErrorDialog = False
  ps.StartInfo.UseShellExecute = False
  ps.StartInfo.RedirectStandardInput = True
  ps.StartInfo.RedirectStandardOutput = True
  ps.StartInfo.FileName = "mplayer.exe"
  ps.StartInfo.CreateNoWindow = True
  BackgroundWorker1.RunWorkerAsync()

这里,args 将保存将传递给进程的参数,除了文件名。ps 是进程对象,它将使用它来保留对 mplayer 进程的引用。

我们将使用“-slave”选项,因为我们希望在“slave”模式下运行 mplayer,在该模式下,它将从另一个进程读取命令并相应地执行操作。-nofs 选项用于不以全屏模式运行。-wid 选项将告诉我们要在其中显示视频输出的窗口的 ID。在这里,我们希望在 Panel1 中显示,因此我们获取其句柄并将其传递给 -wid 之后。-af-add equalizer=0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 用于提供音频效果命令。

我们使用了 BackgroundWorker1,因为我们希望以一种单独的方式运行 mplayer。这样我们就不需要计时器在 1 毫秒后连续读取 mplayer 的每一行。计时器有时会冻结表单。

当用户单击打开文件时,将打开一个对话框,并且在选择文件后,mplayer 将运行该文件。

播放文件的代码如下所示

 If OpenFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
            mplay()
        End If

' mplay() procedure :-
  Public Sub mplay()
        stp()
        args = "-nofs -noquiet -identify -slave -af-add equalizer=0:0:0:0:0:0:0:0:0:0 -volume " _
	& TrackBar1.Value & " -nomouseinput -sub-fuzziness 1 -vo direct3d, -ao dsound -osdlevel _
	0 -wid " & CInt(Panel1.Handle.ToInt32) & CDP
        ps.StartInfo.Arguments = args & " """ & OpenFileDialog1.FileName & """"
        ps.Start()
        CDP = ""
        posh = 1
        tdr = 1
        Timer1.Start()
        Timer2.Start()
    End Sub

' stp() procedure :-
    Public Sub stp()
        posh = 0
        Try
            ps.Kill()
        Catch
        End Try
        time_length = ""
        time_pos = ""
        Button1.Text = "Pause"
        Timer1.Stop()
        ProgressBar1.Value = 0
        Label1.Text = "00:00:00"
        Label2.Text = "00:00:00"
    End Sub

首先,我们要确保我们启动的任何以前的 mplayer 实例都已关闭。因此,ps.Kill 位于 try catch 中,如果该进程已经退出或尚未启动,则不会显示错误。对于特殊目的,使用 timer1,稍后我将讨论。timer2 用于激活预先选择的效果。timer2 的间隔将为 1 秒到 3 秒,否则,如果小于 1 秒,有时它将不起作用。CDP 声明为 string,用于添加参数以播放 CD。

我们可以向 mplayer 发送命令来控制正在播放的文件。每个命令必须以 vbLf 结尾。SendCommand 函数将执行向 mplayer 进程发送命令的任务。

   Public Sub SendCommand(ByVal cmd As String)
        Try
            If ps IsNot Nothing AndAlso ps.HasExited = False Then
                ps.StandardInput.Write(cmd & vbLf)
            End If
        Catch
        End Try
    End Sub

我们可以通过这个 SendCommand 函数向 mplayer 提供任何从属模式命令。所有从属模式命令都可以在 这里找到。

BackgroundWorker1 中的 DoWork 事件

  Dim safedelegate As New ChangeTextsSafe(AddressOf ChangeTexts)
        Do
            System.Threading.Thread.Sleep(1)
            Try
                If posh = 1 Then
                    Dim sLine As String = ps.StandardOutput.ReadLine
                    If sLine.Contains("ANS_LENGTH") Or sLine.Contains("ANS_TIME_POSITION") Then
                        Me.Invoke(safedelegate, sLine)
                    End If
                End If
            Catch
            End Try
        Loop

' ChangeTexts() procedure :-
Public Sub ChangeTexts(ByVal per As String)
        Try
            If posh = 1 Then
                If per.Contains("ANS_LENGTH") Then
                    ConvertTimeHHMMSS(per.Replace("ANS_LENGTH=", ""), 1)
                Else
                    ConvertTimeHHMMSS(per.Replace("ANS_TIME_POSITION=", ""), 0)
                End If
            End If
        Catch
        End Try
    End Sub

现在,关于 timer1 的描述。它用于获取文件的持续时间和时间位置。

 If tdr = 1 Then
            SendCommand("get_time_length")
        Else
            SendCommand("get_time_pos")
        End If

timer1 的间隔必须为 250 到 500 毫秒。当我们将获取文件的时间长度时,tdr 的值将为零。在为零之后,timer1 将发送时间位置命令。Mplayer 以秒为单位显示文件的时间位置,我们希望以 HH:MM:SS 格式查看它。因此,使用了 ConvertTimeHHMMSS 函数。以下代码用于该函数

    Public Sub ConvertTimeHHMMSS(ByVal timeInSeconds As Double, ByVal strx As Long)
        Try
            If timeInSeconds >= 0 Then
                Dim iSecond As Double = timeInSeconds
                Dim iSpan As TimeSpan = TimeSpan.FromSeconds(iSecond)
                If strx = 1 Then
                    time_length = iSpan.Hours.ToString.PadLeft(2, "0"c) & _
                    ":" & iSpan.Minutes.ToString.PadLeft(2, "0"c) & _
                    ":" & iSpan.Seconds.ToString.PadLeft(2, "0"c)
                    ProgressBar1.Maximum = timeInSeconds
                    tdr = 0
                Else
                    time_pos = iSpan.Hours.ToString.PadLeft(2, "0"c) & ":" _
                    & iSpan.Minutes.ToString.PadLeft(2, "0"c) & ":" _
                    & iSpan.Seconds.ToString.PadLeft(2, "0"c)
                    ProgressBar1.Value = timeInSeconds
                End If
                Label1.Text = time_pos
                Label2.Text = time_length
            End If
        Catch
        End Try
    End Sub

这里,使用 TimeSpan.FromSeconds 方法,它返回一个表示指定秒数的 timespan,其中规格精确到最接近的毫秒。

progressbar1MouseDown 事件的代码

 Try
            If e.Button = Windows.Forms.MouseButtons.Left And Button1.Text = "Pause" Then
                Dim dValue As Double
                dValue = (Convert.ToDouble(e.X) / Convert.ToDouble(ProgressBar1.Width)) * _
		(ProgressBar1.Maximum - ProgressBar1.Minimum)
                ProgressBar1.Value = Convert.ToInt32(dValue)
                SendCommand("seek " & ProgressBar1.Value & " 2")
            End If
        Catch
        End Try

我们可以通过 mplayer Rip/Read CD。因此,参数将是

' To read CD, just add string in CDP :-
 Public Sub cdplay(ByVal r1 As String, ByVal r2 As String)
        CDP = " cdda://" & r1 & " -cdrom-device " & r2
    End Sub
' r1= Track Number, r2= cd drive name 

' To Rip CD :-
ps.StartInfo.Arguments = "-nofs -noquiet -identify -slave _
	-nomouseinput cdda://" & ListBox1.SelectedIndex + 1 & " _
	-cdrom-device " & ComboBox1.SelectedItem.ToString.Replace("\", "") & " -ao pcm"

' Show CD/DVD drives name :-
    Try
            For Each drive As DriveInfo In DriveInfo.GetDrives().Where_
		(Function(d) d.DriveType = DriveType.CDRom)
                ComboBox1.Items.Add(drive.Name)
            Next
            ComboBox1.SelectedIndex = 0
        Catch
        End Try

我们还可以通过 mplayer 带有录音选项来收听互联网广播。

' To Stream :-
  ps.StartInfo.Arguments = "-nofs -noquiet -identify -slave -volume " & _
	TrackBar1.Value & " -nomouseinput -sub-fuzziness 1 " _
                & TextBox2.Text & " -capture"
' Here Textbox2 must contains Stream url and -capture command for recording. 
' It will record in mp3 format & file name is stream.dump

' To Record :- 
  Try
            If Button3.Text = "Record" Then
                Try
                    System.IO.File.Delete(Application.StartupPath & "\stream.dump")
                Catch
                End Try
                SendCommand("capturing")
                Button3.Text = "Stop"
            Else
                SendCommand("capturing 0")
                Button3.Text = "Record"
            End If
        Catch
        End Try

对于音频效果

Form1.SendCommand("af_eq_set_bands " & a1 & ":" & a2 & ":" & a3 & ":" & _
a4 & ":" & a5 & ":" & a6 & ":" & a7 & ":" & a8 & ":" & a9 & ":" & a10)
' Other effects can be found in downloaded project file

我们可以编写 mplayer 的配置文件来设置流缓存大小并激活屏幕截图、视频效果。如果不想在 config 文件中写入,我们可以在参数中添加命令。Config 文件写入过程将是

# cache setting
cache=1024
vf-add=hue=0,eq=0:0
vf-add=screenshot
vf-add=scale

关注点

Mplayer 确实是一个很棒的命令行应用程序程序,显然 VB.NET 程序是控制 mplayer 的最佳选择之一。但是,Mplayer 没有音频可视化,但可以通过使用 FFT 算法来实现。

历史

  • 2013 年 9 月 3 日 - 首次发布
  • 2013 年 12 月 9 日 - 第二次发布
  • 2015 年 7 月 12 日 - 第三次发布
© . All rights reserved.