Introduction
This article will demonstrate how we can use mplayer to easily control in VB.NET WinForm application without using any COM/ActiveX control. Downloaded source code is sample part of Veron Media Player 1.9. At first, we need mplayer.exe in our main application's start path. It can be downloaded from here.
Background
Mplayer is a command line audio & video player. It can play audio or video file using several different output drivers. There were no previous examples of how to use mplayer to play audio or video in VB.NET winform application. C++ examples that were found to control mplayer but it is more easy and reliable if we use VB.NET program.
Screenshot:
Techniques
Process object, Window handle control, Input and Output redirection.
Using the Code
We will use Process class of System.Diagnostics
namespace to launch an instance of mplayer to play files. We'll redirect input & output so that we can send commands to mplayer and get information about the file.
Here is the code that we use to declare variables and initialize process:
Delegate Sub ChangeTextsSafe(ByVal percent As String)
Dim args, time_length, time_pos, buffer, CDP As String
Dim posh, tdr As Long
Dim ps As Process = Nothing
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()
Here, args
will hold the arguments that will be passed to process except file name. ps is the process object which will use it to keep a reference to the mplayer process.
We will use "-slave
" option because we want to run mplayer
in 'slave' mode where it will read commands from another process and do actions accordingly. -nofs
option for not to run in full screen mode. -wid
option will tell the id of window where we want to display video output. Here we want to display in Panel1
, so we get its handle and pass it after -wid
. -af-add
equalizer=0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 used for giving audio effects command.
We used BackgroundWorker1
because we want to run mplayer on a separate way. So that we do not need timer to read mplayer's each line after 1 ms continuously. A timer can sometimes freeze the form.
When user clicks on open file, a dialog will open and after a file is selected, mplayer will run that file.
Code for playing file is as follows:
If OpenFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
mplay()
End If
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
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
First, we want to make sure that any previous instance of mplayer started by us is closed. So, ps.Kill
in try catch
used that if the process has already exited or not started, the error does not show. For special purposes, timer1
is used and I will discuss later. timer2
for activating effect if pre-selected. timer2
interval will be 1s to 3s, otherwise if less, sometimes it will not work. CDP is declared as string
for adding argument to play CD.
We can send commands to mplayer to control the file that is being played. Each command must end with vbLf
. SendCommand
function will perform the task of sending commands to mplayer process.
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
We can give any slave mode command to mplayer by this SendCommand
function. All slave mode commands can be found in here.
DoWork
event in BackgroundWorker1
:
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
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
Now, description about timer1
. It is used to get file's duration & time position.
If tdr = 1 Then
SendCommand("get_time_length")
Else
SendCommand("get_time_pos")
End If
Interval of timer1
must be 250 to 500ms. The value of tdr
will be zero, when we will get file's time length. After zero, timer1
will send time-position command. Mplayer shows file's time position in seconds and we want to see it HH:MM:SS format. Therefore, ConvertTimeHHMMSS
function was used. The following code is used for that function:
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
Here, TimeSpan.FromSeconds
method is used which returns a timespan
that represents a specified number of seconds, where the specification is accurate to the nearest millisecond.
Code for MouseDown
event in progressbar1
:
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
We can Rip/Read CD by mplayer. So, the argument will be then:
Public Sub cdplay(ByVal r1 As String, ByVal r2 As String)
CDP = " cdda://" & r1 & " -cdrom-device " & r2
End Sub
ps.StartInfo.Arguments = "-nofs -noquiet -identify -slave _
-nomouseinput cdda://" & ListBox1.SelectedIndex + 1 & " _
-cdrom-device " & ComboBox1.SelectedItem.ToString.Replace("\", "") & " -ao pcm"
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
We can also listen to internet radio by mplayer with record option.
ps.StartInfo.Arguments = "-nofs -noquiet -identify -slave -volume " & _
TrackBar1.Value & " -nomouseinput -sub-fuzziness 1 " _
& TextBox2.Text & " -capture"
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
For audio effects:
Form1.SendCommand("af_eq_set_bands " & a1 & ":" & a2 & ":" & a3 & ":" & _
a4 & ":" & a5 & ":" & a6 & ":" & a7 & ":" & a8 & ":" & a9 & ":" & a10)
We can write config file of mplayer to set stream cache size and activate screenshot, video effects. We can add commands in argument if we do not like to write in config file. Config file written process will be:
# cache setting
cache=1024
vf-add=hue=0,eq=0:0
vf-add=screenshot
vf-add=scale
Points of Interest
Mplayer is a really great command line application program and obviously VB.NET Program is one of the best to control mplayer. However, Mplayer has no audio visualization, but it can be possible by using FFT algorithm.
History
- 03 September, 2013 - First release
- 09 December, 2013 - Second release
- 12 July, 2015 - Third release