mPlayer

This tutorial will show you how to create your own Media Player application, called mPlayer, which includes support for Audio and Video with features such as Playback and Audio control such as Volume and more!

www.cespage.com/vb/vb08tut15.html

Step 1

Start Microsoft Visual Basic 2008 Express Edition, then select File then New Project... Choose Windows Forms Application from the New Project Window, enter a name for the Project and then click OK, see below:

New Project

Step 2

A Blank Form named Form1 should then appear, see below:

Form1

Step 3

With Form1 selected goto the Properties box and change the Name from Form1 to frmMain

Form1 Properties

Step 4

Then select Project then Add Class... and choose the "Class" Template if it is not already selected and give it the Name "mPlayerControl.vb" without the quotes, see below:

mPlayerControl Class

Step 5

With the empty mPlayerControl Class displayed, if not double click on the "mPlayerControl.vb" item in Solution Explorer, then enter the following below the Public Class mPlayerControl line:

Inherits Control

' Public Enum

Public Enum Channels
  None = 0
  Left = 1
  Right = 2
  Both = 3
End Enum

' API Constants, Enum and Functions

Private Const MCI_NOTIFY_SUCCESSFUL As Integer = &H1
Private Const MM_MCINOTIFY As Integer = &H3B9
Private Const MCIERR_BASE As Integer = 256

' MCI Error Values Enumeration
Private Enum MCIERR As Integer
  MCIERR_NO_ERROR = 0
  MCIERR_INVALID_DEVICE_ID = (MCIERR_BASE + 1)
  MCIERR_UNRECOGNIZED_KEYWORD = (MCIERR_BASE + 3)
  MCIERR_UNRECOGNIZED_COMMAND = (MCIERR_BASE + 5)
  MCIERR_HARDWARE = (MCIERR_BASE + 6)
  MCIERR_INVALID_DEVICE_NAME = (MCIERR_BASE + 7)
  MCIERR_OUT_OF_MEMORY = (MCIERR_BASE + 8)
  MCIERR_DEVICE_OPEN = (MCIERR_BASE + 9)
  MCIERR_CANNOT_LOAD_DRIVER = (MCIERR_BASE + 10)
  MCIERR_MISSING_COMMAND_STRING = (MCIERR_BASE + 11)
  MCIERR_PARAM_OVERFLOW = (MCIERR_BASE + 12)
  MCIERR_MISSING_STRING_ARGUMENT = (MCIERR_BASE + 13)
  MCIERR_BAD_INTEGER = (MCIERR_BASE + 14)
  MCIERR_PARSER_INTERNAL = (MCIERR_BASE + 15)
  MCIERR_DRIVER_INTERNAL = (MCIERR_BASE + 16)
  MCIERR_MISSING_PARAMETER = (MCIERR_BASE + 17)
  MCIERR_UNSUPPORTED_FUNCTION = (MCIERR_BASE + 18)
  MCIERR_FILE_NOT_FOUND = (MCIERR_BASE + 19)
  MCIERR_DEVICE_NOT_READY = (MCIERR_BASE + 20)
  MCIERR_INTERNAL = (MCIERR_BASE + 21)
  MCIERR_DRIVER = (MCIERR_BASE + 22)
  MCIERR_CANNOT_USE_ALL = (MCIERR_BASE + 23)
  MCIERR_MULTIPLE = (MCIERR_BASE + 24)
  MCIERR_EXTENSION_NOT_FOUND = (MCIERR_BASE + 25)
  MCIERR_OUTOFRANGE = (MCIERR_BASE + 26)
  MCIERR_FLAGS_NOT_COMPATIBLE = (MCIERR_BASE + 28)
  MCIERR_FILE_NOT_SAVED = (MCIERR_BASE + 30)
  MCIERR_DEVICE_TYPE_REQUIRED = (MCIERR_BASE + 31)
  MCIERR_DEVICE_LOCKED = (MCIERR_BASE + 32)
  MCIERR_DUPLICATE_ALIAS = (MCIERR_BASE + 33)
  MCIERR_BAD_CONSTANT = (MCIERR_BASE + 34)
  MCIERR_MUST_USE_SHAREABLE = (MCIERR_BASE + 35)
  MCIERR_MISSING_DEVICE_NAME = (MCIERR_BASE + 36)
  MCIERR_BAD_TIME_FORMAT = (MCIERR_BASE + 37)
  MCIERR_NO_CLOSING_QUOTE = (MCIERR_BASE + 38)
  MCIERR_DUPLICATE_FLAGS = (MCIERR_BASE + 39)
  MCIERR_INVALID_FILE = (MCIERR_BASE + 40)
  MCIERR_NULL_PARAMETER_BLOCK = (MCIERR_BASE + 41)
  MCIERR_UNNAMED_RESOURCE = (MCIERR_BASE + 42)
  MCIERR_NEW_REQUIRES_ALIAS = (MCIERR_BASE + 43)
  MCIERR_NOTIFY_ON_AUTO_OPEN = (MCIERR_BASE + 44)
  MCIERR_NO_ELEMENT_ALLOWED = (MCIERR_BASE + 45)
  MCIERR_NONAPPLICABLE_FUNCTION = (MCIERR_BASE + 46)
  MCIERR_ILLEGAL_FOR_AUTO_OPEN = (MCIERR_BASE + 47)
  MCIERR_FILENAME_REQUIRED = (MCIERR_BASE + 48)
  MCIERR_EXTRA_CHARACTERS = (MCIERR_BASE + 49)
  MCIERR_DEVICE_NOT_INSTALLED = (MCIERR_BASE + 50)
  MCIERR_GET_CD = (MCIERR_BASE + 51)
  MCIERR_SET_CD = (MCIERR_BASE + 52)
  MCIERR_SET_DRIVE = (MCIERR_BASE + 53)
  MCIERR_DEVICE_LENGTH = (MCIERR_BASE + 54)
  MCIERR_DEVICE_ORD_LENGTH = (MCIERR_BASE + 55)
  MCIERR_NO_INTEGER = (MCIERR_BASE + 56)

  MCIERR_WAVE_OUTPUTSINUSE = (MCIERR_BASE + 64)
  MCIERR_WAVE_SETOUTPUTINUSE = (MCIERR_BASE + 65)
  MCIERR_WAVE_INPUTSINUSE = (MCIERR_BASE + 66)
  MCIERR_WAVE_SETINPUTINUSE = (MCIERR_BASE + 67)
  MCIERR_WAVE_OUTPUTUNSPECIFIED = (MCIERR_BASE + 68)
  MCIERR_WAVE_INPUTUNSPECIFIED = (MCIERR_BASE + 69)
  MCIERR_WAVE_OUTPUTSUNSUITABLE = (MCIERR_BASE + 70)
  MCIERR_WAVE_SETOUTPUTUNSUITABLE = (MCIERR_BASE + 71)
  MCIERR_WAVE_INPUTSUNSUITABLE = (MCIERR_BASE + 72)
  MCIERR_WAVE_SETINPUTUNSUITABLE = (MCIERR_BASE + 73)

  MCIERR_SEQ_DIV_INCOMPATIBLE = (MCIERR_BASE + 80)
  MCIERR_SEQ_PORT_INUSE = (MCIERR_BASE + 81)
  MCIERR_SEQ_PORT_NONEXISTENT = (MCIERR_BASE + 82)
  MCIERR_SEQ_PORT_MAPNODEVICE = (MCIERR_BASE + 83)
  MCIERR_SEQ_PORT_MISCERROR = (MCIERR_BASE + 84)
  MCIERR_SEQ_TIMER = (MCIERR_BASE + 85)
  MCIERR_SEQ_PORTUNSPECIFIED = (MCIERR_BASE + 86)
  MCIERR_SEQ_NOMIDIPRESENT = (MCIERR_BASE + 87)

  MCIERR_NO_WINDOW = (MCIERR_BASE + 90)
  MCIERR_CREATEWINDOW = (MCIERR_BASE + 91)
  MCIERR_FILE_READ = (MCIERR_BASE + 92)
  MCIERR_FILE_WRITE = (MCIERR_BASE + 93)

  MCIERR_NO_IDENTITY = (MCIERR_BASE + 94)
  ' Custom Driver Errors are greater or equal to this value
  MCIERR_CUSTOM_DRIVER_BASE = (MCIERR_BASE + 256)
End Enum

Private Declare Function mciSendString Lib "Winmm.dll" _
Alias "mciSendStringA" (ByVal lpszCommand As String, ByVal lpszReturnString As String, _
                        ByVal cchReturn As Integer, ByVal hwndCallback As IntPtr) As MCIERR
Private Declare Function mciGetErrorString Lib "Winmm.dll" _
Alias "mciGetErrorStringA" (ByVal fdwError As Integer, ByVal lpszErrorText As String, _
                            ByVal cchErrorText As Integer) As Integer

See Below:

mPlayerControl Imports and API Declarations

Step 6

With the mPlayerControl Class still displayed, enter the following Private Members above the "End Class" of "Public Class mPlayerControl":

' Private Members

Private pFileName As String ' The media file opened
Private pAlias As String ' Each control instance gets own unique alias
Private pLastError As MCIERR ' Error returned mciSendString last call
Private pOpenSuccess As Boolean ' Indicates Open command successful
Private pSpeed As Integer ' Playback speed
Private pMute As Channels ' Muted Channels  
Private pBalance As Integer ' Left / Right balance
Private pVolume As Integer ' Volume
Private pRepeat As Boolean ' Indicates playback looping
Private pTotalTime As Long ' Media length in milliseconds
Private pTotalFrames As Long ' Media length in frames
Private pClipStart As Long ' Start frame or milliseconds of play sequence
Private pClipEnd As Long ' End frame or milliseconds of play sequence
Private pClipFormat As String ' Time format for Clip frames or milliseconds
Private pPlaying As Boolean ' Is Playing
Private pPaused As Boolean ' IsPaused

See Below:

mPlayerControl Private Members

Step 7

Again, with the mPlayerControl Class still displayed, enter the first of the Private Methods above the "End Class" and below the "Private Members" section:

' Private Methods

''' <summary>Set Playback Speed</summary>
Private Function DoSpeed() As Boolean
  If pOpenSuccess Then
    pLastError = mciSendString("set " & pAlias & _
                               " speed " & CStr(pSpeed), _
                               vbNullString, 0, IntPtr.Zero)
    Return (pLastError = MCIERR.MCIERR_NO_ERROR)
  End If
  Return False
End Function

''' <summary>Mute the Channels</summary>
Private Function DoMute() As Boolean
  If pOpenSuccess Then
    Select Case pMute
      Case Channels.None
        pLastError = mciSendString("set " & pAlias & _
                                   " audio all on", _
                                   vbNullString, 0, IntPtr.Zero)
      Case Channels.Both
        pLastError = mciSendString("set " & pAlias & _
                                   " audio all off", _
                                   vbNullString, 0, IntPtr.Zero)
      Case Channels.Left
        pLastError = mciSendString("set " & pAlias & _
                                   " audio left off", _
                                   vbNullString, 0, IntPtr.Zero)
        pLastError = mciSendString("set " & pAlias & _
                                   " audio right on", _
                                   vbNullString, 0, IntPtr.Zero)
      Case Channels.Right
        pLastError = mciSendString("set " & pAlias & _
                                   " audio left on", _
                                   vbNullString, 0, IntPtr.Zero)
        pLastError = mciSendString("set " & pAlias & _
                                   " audio right off", _
                                   vbNullString, 0, IntPtr.Zero)
    End Select
    Return (pLastError = MCIERR.MCIERR_NO_ERROR)
  End If
  Return False
End Function

''' <summary>Set Balance factor</summary>
Private Function DoBalance() As Boolean
  If pOpenSuccess Then
    pLastError = mciSendString("setaudio " & pAlias & _
                               " left volume to " & CStr(1000 - pBalance), _
                               vbNullString, 0, IntPtr.Zero)
    pLastError = mciSendString("setaudio " & pAlias & _
                               " right volume to " & CStr(pBalance), _
                               vbNullString, 0, IntPtr.Zero)
    Return (pLastError = MCIERR.MCIERR_NO_ERROR)
  End If
  Return False
End Function

''' <summary>Set Volume Factor</summary>
Private Function DoVolume() As Boolean
  If pOpenSuccess Then
    pLastError = mciSendString("setaudio " & pAlias & _
                               " volume to " & CStr(pVolume), _
                               vbNullString, 0, IntPtr.Zero)
    Return (pLastError = MCIERR.MCIERR_NO_ERROR)
  End If
  Return False
End Function

''' <summary>Return Total number of Frames in media</summary>
Private Function GetTotalFrames() As Long
  If pOpenSuccess Then
    pLastError = mciSendString("set " & pAlias & _
                               " time format frames", _
                               vbNullString, 0, IntPtr.Zero)
    If pLastError = MCIERR.MCIERR_NO_ERROR Then
      Dim FrameStr As String = Space(128)
      pLastError = mciSendString("status " & pAlias & _
                                 " length", FrameStr, _
                                 Len(FrameStr), IntPtr.Zero)
      If pLastError = MCIERR.MCIERR_NO_ERROR Then
        Return CLng(Trim(FrameStr))
      End If
    End If
  End If
  Return -1
End Function

''' <summary>Return Total playing time in milliseconds of Media</summary>
Private Function GetTotalTime() As Long
  If pOpenSuccess Then
    pLastError = mciSendString("set " & pAlias & _
                               " time format milliseconds", _
                               vbNullString, 0, IntPtr.Zero)
    If pLastError = MCIERR.MCIERR_NO_ERROR Then
      Dim TimeStr As String = Space(128)
      pLastError = mciSendString("status " & pAlias & _
                                 " length", TimeStr, _
                                 Len(TimeStr), IntPtr.Zero)
      If pLastError = MCIERR.MCIERR_NO_ERROR Then
        Return CLng(Trim(TimeStr))
      End If
    End If
  End If
  Return -1
End Function

See Below:

mPlayerControl Private Methods

Step 8

Again, with the mPlayerControl Class still displayed, enter the Constructor and the first of the Public Methods above the "End Class" and below the "Private Methods" section:

' Constructor

Public Sub New()
  pFileName = "" ' No media loaded
  pAlias = "ALIAS" & Me.Handle.ToString ' Each Control has Unique Alias
  pLastError = MCIERR.MCIERR_NO_ERROR ' No error
  pOpenSuccess = False ' Not open
  pSpeed = 1000 ' Normal playback speed
  pMute = Channels.None ' No muted channels muted
  pBalance = 500 ' Normal left / right balance
  pVolume = 500 ' Normal volume
  pRepeat = False ' Default no playback looping
  pTotalTime = -1 ' No media
  pTotalFrames = -1 ' No media
  pClipStart = -1 ' Start at beginning
  pClipEnd = -1 ' Play until end 
  pClipFormat = "" ' No clip format
  pPlaying = False ' Not playing
  pPaused = False ' Not Paused
End Sub

' Public Methods

''' <summary>Return last MCI Error Code</summary>
Public Function GetLastError() As Integer
  Return pLastError
End Function

''' <summary>Return Description for last MCI error</summary>
Public Function GetErrorString() As String
  If pLastError <> MCIERR.MCIERR_NO_ERROR Then
    Dim ErrorText As String = Space(128)
    If mciGetErrorString(pLastError, ErrorText, _
                         Len(ErrorText)) <> 0 Then
      Return Trim(ErrorText)
    End If
  End If
  Return ""
End Function

''' <summary>Close Media File</summary>
Public Function [Close]() As Boolean
  If pOpenSuccess Then
      pLastError = mciSendString("close " & pAlias, _
                                 vbNullString, 0, IntPtr.Zero)
      If pLastError = MCIERR.MCIERR_NO_ERROR Then
          pOpenSuccess = False
          pPlaying = False
          pPaused = False
          pFileName = "" ' No File Open
          pTotalTime = -1 ' No Media
          pTotalFrames = -1 ' No Media
          Return True
      End If
  End If
  Return False
End Function

''' <summary>Stop Media</summary>
Public Function [Stop]() As Boolean
  If pOpenSuccess Then
    pLastError = mciSendString("stop " & pAlias, _
                               vbNullString, 0, IntPtr.Zero)
    If pLastError = MCIERR.MCIERR_NO_ERROR Then
      ' After stopping be kind, rewind
      pLastError = mciSendString("seek " & pAlias & _
                                 " to start", vbNullString, _
                                 0, IntPtr.Zero)
    End If
    pPlaying = False
    pPaused = False
    Return (pLastError = MCIERR.MCIERR_NO_ERROR)
  End If
  Return False
End Function

''' <summary>Pause Media</summary>
Public Function [Pause]() As Boolean
  If pOpenSuccess Then
    pLastError = mciSendString("pause " & pAlias, _
                               vbNullString, 0, IntPtr.Zero)
    pPaused = (pLastError = MCIERR.MCIERR_NO_ERROR)
    Return pPaused
  End If
  Return False
End Function

''' <summary>Resume Media</summary>
Public Function [Resume]() As Boolean
  If pOpenSuccess And pPaused Then
    pLastError = mciSendString("resume " & pAlias, _
                               vbNullString, 0, IntPtr.Zero)
    pPaused = Not (pLastError = MCIERR.MCIERR_NO_ERROR)
    Return (pLastError = MCIERR.MCIERR_NO_ERROR)
  End If
  Return False
End Function

''' <summary>Move to Media End</summary>
Public Function MoveToEnd() As Boolean
  If pOpenSuccess Then
    pLastError = mciSendString("seek " & pAlias & _
                               " to end", vbNullString, 0, IntPtr.Zero)
    pPlaying = False ' Seeks stops Playback
    pPaused = False
    Return (pLastError = MCIERR.MCIERR_NO_ERROR)
  End If
  Return False
End Function

See Below:

mPlayerControl Constructor & Public Methods

Step 9

With the mPlayerControl Class still displayed, enter the following Private Methods below the "End Function" of "GetTotalTime()" and above the "Constructor" Section:

''' <summary>Size media to fit window, preserve aspect ratio</summary>
Private Function SizeMediaWindow() As Boolean
  If pOpenSuccess Then
    Dim OptimalSize As Size = Me.OriginalSize ' Get media optimal size
    If OptimalSize.IsEmpty = False Then ' Calculate ratio to size to the width
      Dim wRatio As Double = (100 / OptimalSize.Width * Me.Width) / 100
      ' Verify window is high enough for ratio.
      If OptimalSize.Height * wRatio > Me.Height Then
          ' If not calculate ratio if size to the height
          wRatio = (100 / OptimalSize.Height * Me.Height) / 100
      End If
      ' Calculate width and height for ratio
      ' Calculate Left and Top to centre media
      Dim wWidth As Integer = CInt(OptimalSize.Width * wRatio)
      Dim wHeight As Integer = CInt(OptimalSize.Height * wRatio)
      Dim wLeft As Integer = CInt((Me.Width - wWidth) / 2)
      Dim wTop As Integer = CInt((Me.Height - wHeight) / 2)
      ' Send Command
      pLastError = mciSendString("put " & pAlias & _
                                 " window at " & CStr(wLeft) & " " _
                                 & CStr(wTop) & " " & CStr(wWidth) & " " _
                                 & CStr(wHeight), vbNullString, 0, IntPtr.Zero)
      Return (pLastError = MCIERR.MCIERR_NO_ERROR)
    End If
  End If
  Return False
End Function

''' <summary>Play Media, Specifiying which part of Media to play</summary>
''' <param name="WithClipStart">Indicates the Start Index of Clip that should be used</param>
''' <param name="WithClipEnd">Indicates the End Index of Clip that should be used</param>
''' <param name="WithPauseState">Indicates the current Pause state should be respected</param>
Private Function [Play](ByVal WithClipStart As Boolean, _
                      ByVal WithClipEnd As Boolean, _
                      ByVal WithPauseState As Boolean) As Boolean
  If pOpenSuccess Then ' Start Media Playing
      If pClipFormat.Length > 0 Then ' If Clip, specify the timer format
        pLastError = mciSendString("set " & pAlias _
                                   & " time format " & pClipFormat, _
                                   vbNullString, 0, IntPtr.Zero)
      End If
      ' Send the play command, we want to be notified when playing ends
      pLastError = mciSendString("play " & pAlias & CStr(IIf((pClipStart <> -1) And WithClipStart = True, _
                                  " from " & CStr(pClipStart), "")) & CStr(IIf((pClipEnd <> -1) And _
                                  WithClipEnd = True, " to " & CStr(pClipEnd), "")) & " notify", _
                                  vbNullString, 0, Me.Handle)
      If pLastError = MCIERR.MCIERR_NO_ERROR Then
        pPlaying = True
        ' If need to respect Pause state and Paused
        If WithPauseState And pPaused Then
          Me.Pause()
        Else ' No paused or pause state can be ignored / reset
          pPaused = False
        End If
      End If
      Return (pLastError = MCIERR.MCIERR_NO_ERROR)
  End If
  Return False
End Function

''' <summary>Clip Media</summary>
''' <param name="Start">Set Clip Start</param>
''' <param name="End">Set Clip End</param>
''' <param name="Current">Current Position</param>
''' <param name="TimeFormat">Time Format</param>
Private Function Clip(ByVal [Start] As Long, ByVal [End] As Long, _
                    ByVal Current As Long, ByVal TimeFormat As String) As Boolean
  If pOpenSuccess Then
      If [Start] <> pClipStart Or [End] <> pClipEnd _
      Or TimeFormat <> pClipFormat Then
        pClipStart = [Start]
        pClipEnd = [End]
        If pClipStart = -1 And pClipEnd = -1 Then
            pClipFormat = "" ' Start / End set to -1 Disables
        Else
            pClipFormat = TimeFormat
        End If
        If pPlaying Then ' If Playing apply Clip now
            ' Skip to start if positioned before, otherwise handled by MCI
            Me.Play(([Start] > Current And [Start] <> -1), True, True)
        End If
        Return True
      End If
  End If
  Return False
End Function

''' <summary>Move the Media to its desired Index using Specified Time Format</summary>
''' <param name="Index">Media Position Index</param>
''' <param name="TimeFormat">Desired Time Format</param>
Private Function MoveToPosition(ByVal Index As Long, _
                              ByVal TimeFormat As String) As Boolean
  If pOpenSuccess Then
      pLastError = mciSendString("set " & pAlias & _
                                 " time format " & TimeFormat, _
                                 vbNullString, 0, IntPtr.Zero)
      If pLastError = MCIERR.MCIERR_NO_ERROR Then
        pLastError = mciSendString("seek " & pAlias & _
                                   " to " & CStr(Index), _
                                   vbNullString, 0, IntPtr.Zero)
        If pLastError = MCIERR.MCIERR_NO_ERROR Then
            If pPlaying Then
                Me.Play(False, True, True) ' Resume Playback
            End If
        End If
        Return (pLastError = MCIERR.MCIERR_NO_ERROR)
      End If
  End If
  Return False
End Function

See Below:

mPlayerControl Private Methods

Step 10

Again with the mPlayerControl Class still displayed, enter the following Public Methods below the "End Function" of "MoveToEnd()" and above the "Public Properties" Section:

''' <summary>Open Media File (MIDI and CD Audio not supported)</summary>  
''' <param name="File">The filename of the Media</param>  
Public Function [Open](ByVal File As String) As Boolean
  If pOpenSuccess Then
    Me.Close() ' Close the previous file
  End If
  Dim Device_Type As String = "MPEGVideo" ' Get Device type, MPEGVideo or AVIVideo
  Dim MciExtension As Microsoft.Win32.RegistryKey = _
  Microsoft.Win32.Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\Windows NT\CurrentVersion\MCI Extensions", False)
  If Not MciExtension Is Nothing Then
    Device_Type = CStr(MciExtension.GetValue(Replace(System.IO.Path.GetExtension(File), ".", ""), "MPEGVideo"))
  End If
  ' Try to Open File, Check for Errors
  pLastError = mciSendString("open """ & File & """ type " & Device_Type & _
                             " alias " & pAlias & "  parent " & Me.Handle.ToString & _
                             " style child", vbNullString, 0, IntPtr.Zero)
  If pLastError = MCIERR.MCIERR_NO_ERROR Then
    ' Set Media Flags
    pOpenSuccess = True
    pPlaying = False
    pPaused = False
    ' Remember Filename
    pFileName = File
    ' Initialise Media
    SizeMediaWindow()
    DoSpeed()
    DoMute()
    DoBalance()
    DoVolume()
    ' Get Media Stats
    pTotalTime = GetTotalTime()
    pTotalFrames = GetTotalFrames()
    Return True
  End If
  Return False
End Function

''' <summary>Play Media</summary>  
Public Function [Play]() As Boolean
  Return Me.Play(True, True, False)
End Function

''' <summary>Move to Media to Desired Frame</summary>
''' <param name="Frame">Frame Number</param>
Public Function MoveToFrame(ByVal Frame As Long) As Boolean
  Return MoveToPosition(Frame, "frames")
End Function

''' <summary>Move to Media to Desired Time Index</summary>
''' <param name="Milliseconds">Time Index</param>
Public Function MoveToTime(ByVal Milliseconds As Long) As Boolean
  Return MoveToPosition(Milliseconds, "milliseconds")
End Function

''' <summary>Clip media to only play between Start and End frame</summary>
''' <param name="Start">Start Frame</param>
''' <param name="End">End Frame</param>
Public Function ClipFrame(ByVal [Start] As Long, ByVal [End] As Long) As Boolean
  Return Clip([Start], [End], Me.CurrentFrame, "frames") ' Undo with -1 
End Function

''' <summary>Clip media to only play between Start and End Time</summary>
''' <param name="Start">Start Time Index</param>
''' <param name="End">End Time Index</param>
Public Function ClipTime(ByVal [Start] As Long, ByVal [End] As Long) As Boolean
  Return Clip([Start], [End], Me.CurrentTime, "milliseconds") ' Undo with -1
End Function

See Below:

mPlayerControl Other Public Methods

Step 11

Finally in the mPlayerControl Class enter the following Control and Event methods above "End Class" and below the "Public Properties" Section:

' Control

''' <summary>Size media window to reflect new size</summary>
Protected Overrides Sub OnResize(ByVal e As System.EventArgs)
  SizeMediaWindow()
End Sub

''' <summary>Close and Dispose</summary>
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
  Me.Close()
  MyBase.Dispose(disposing)
End Sub

''' <summary>Handle Autorepeat Messages</summary>
''' <param name="m">Windows Forms Message</param>
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
  Select Case m.Msg
    Case MM_MCINOTIFY
        ' Only process message if success indicated
        If m.WParam.ToInt32 = MCI_NOTIFY_SUCCESSFUL Then
          If pRepeat Then
            Me.Stop()
            Me.Play()
          Else ' Raise End event to notify Media End
            Me.Stop()
            Dim e As New System.EventArgs
            RaiseEvent OnEnd(Me, e)
            e = Nothing
          End If
        End If
  End Select
  MyBase.WndProc(m)
End Sub

' Event

''' <summary>Fired when Media ends</summary>  
Public Event OnEnd(ByVal sender As Object, _
                 ByVal e As System.EventArgs)

See Below:

mPlayerControl Event Handlers

Step 12

The mPlayerControl Class is now Completed, to use it in the application click on Build, then "Build mPlayer":

Build mPlayer

You may be asked to Save your Project, when you do and the Build has completed. Select the mPlayerControl Component that appears in the Toolbox under mPlayer Components:

mPlayerControl Component

Step 13

Draw the mPlayerControl Component on the Form, make sure to position and size the mPlayerControl so it appears as below:

frmMain with mPlayerControl

Step 14

Then goto the Properties box and change the Name to "Player" and the Anchor property to "Top, Bottom, Left, Right", both without quotes, see Below:

mPlayerControl Properties

Step 15

Then from the All Windows Forms tab on the Toolbox select the Trackbar Control, see Below:

Trackbar Component

Step 16

Draw a Trackbar Component on the Form, see below:

frmMain with Trackbar

Step 17

Then goto the Properties box and change the Name to "Trackbar" and the Dock property to "Bottom", both without quotes, see Below:

Trackbar Properties

Step 18

Then from the Components tab on the Toolbox select the Timer Control, see Below:

Timer Component

Step 19

Draw a Timer on the Form, or double-click on the Timer entry in the Toolbox, and it will appear in the pane, beneath the form, see below:

Timer in Pane below frmMain

Step 20

Then goto the Properties box and change the Name to "Display, Enabled to "True" and the Interval property to "333", all without quotes, see Below:

Timer Properties

Step 21

Then from the Menus & Toolbars tab on the Toolbox select the MenuStrip Control, see Below:

MenuStrip Component

Step 22

Either double-click on the MenuStrip Control entry in the Menu & Toolbars tab on the Toolbox or keep the MenuStrip Component Clicked and then move it over the Form then let go. Change the Name of the MenuStrip in the properties to mnuPlayer. The Form will then look as below:

frmMain with MenuStrip

Step 23

Click or select where the MenuStrip says "Type Here", an editable Textbox will appear type in "File" without the quotes in this Box, then in the Box below that type in "Open...", then "Close", then "-" which is minus or the hyphen key which will appear as a Seperator, and then finally "Exit". The MenuStrip should look as below:

mnuPlayer with SubMenus

Step 23

Click or select where the MenuStrip says "Type Here" next to "File", and in this type in "Media" without the quotes in this Box, then in the Box below that type "Play/Pause", then below that "Stop", then type in "-" which is minus or the hyphen key for a Seperator, then below that "Slower Speed", then "Normal Speed", then "Faster Speed" then another "-" for a seperator and finally "Repeat". The MenuStrip should look as below:

mnuPlayer with Media Sub Menu Items

Step 24

Select the Repeat menu item in the Media menu by clicking on it and then goto the Properties box for RepeatToolStripMenuItem and change the CheckOnClick Property to True, see Below:

Repeat Menu Item Properties

Step 25

Click on or select the MenuStrip again, on this next to the Media menu will be another "Type Here" option this this box type "Audio" without the quotes, then in the "Type Here" box under that type "Volume Up", then below that "Volume Normal", then "Volume Down", then type "-" which is minus or the hyphen key for a Seperator, then "Balance Left", below that "Balance Equal", then "Balance Right", then "-" again for a Seperator, then below that type "Mute Left" and finally "Mute Right", see below:

mnuPlayer with Audio Sub Menu Items

Step 26

Select the Mute Left menu item in the Audio menu bu clicking on it and then goto the Properties box for MuteLeftToolStripMenuItem and change the CheckOnClick Property to True, also do the same for the Mute Right menu item so they both have their CheckOnClick Properties set to True, see Below:

Mute Right Menu Item Properties

Step 27

Click on the [Design] Tab to view the form again, then Click on "File" on the MenuStrip to show the MenuStrip then Double Click on the Menu Item Labeled "Open..." (OpenToolStripMenuItem) and type the following in the OpenToolStripMenuItem_Click() Sub:

Dim Open As New OpenFileDialog()
Open.Filter = "Audio|*.wma;*.mp3|Video|*.wmv;*.avi;*.mpeg;*.mpg|All files (*.*)|*.*"
Open.CheckFileExists = True
If Open.ShowDialog(Me) = Windows.Forms.DialogResult.OK Then
  Try
    Player.Open(Open.FileName)
    If Player.TotalTime >= 0 Then ' Initialise the Trackbar
        TrackBar.Value = 0
        TrackBar.Minimum = 0
        TrackBar.Maximum = CInt(Player.TotalTime)
    End If
    Player.Play() ' Play Media
    Me.Text = "mPlayer - " & Open.FileName
    Catch ex As Exception
        ' Do nothing on Exception
    End Try
End If

See Below:

File Menu Open Menu Item Click Event

Step 28

Click on the [Design] Tab to view the form again, then Click on "File" on the MenuStrip to show the MenuStrip then Double Click on the Menu Item Labeled "Close" (CloseToolStripMenuItem) and type the following in the CloseToolStripMenuItem_Click() Sub:

Dim Response As MsgBoxResult
Response = MsgBox("Are you sure you want to Close the Media?", _
                  MsgBoxStyle.Question + MsgBoxStyle.YesNo, _
                  "mPlayer")
If Response = MsgBoxResult.Yes Then
  Player.Close()
End If

See Below:

File Menu Close Menu Item Click Event

Step 29

Click on the [Design] Tab to view the form again, then Click on "File" on the MenuStrip to show the MenuStrip then Double Click on the Menu Item Labeled "Exit" (ExitToolStripMenuItem) and type the following in the ExitToolStripMenuItem_Click() Sub

Dim Response As MsgBoxResult
Response = MsgBox("Are you sure you want to Exit mPlayer?", _
                  MsgBoxStyle.Question + MsgBoxStyle.YesNo, _
                  "mPlayer")
If Response = MsgBoxResult.Yes Then
  End
End If

See Below:

File Menu Exit Menu Item Click Event

Step 30

Click on the [Design] Tab to view the form again, then Click on "Media" on the MenuStrip, then Double Click on the Menu Item Labeled "Play/Pause" (PlayPauseToolStripMenuItem) and type the following in the PlayPauseToolStripMenuItem_Click() Sub:

If Player.Playing Then
  If Player.Paused Then
    Player.Resume()
  Else
    Player.Pause()
  End If
Else
  Player.Play()
End If

Click on [Design] tab or double click on the frmMain entry in Solution Explorer again, click "Media", then Double Click on the Menu Item Labeled "Stop" (StopToolStripMenuItem) and type the following in the StopToolStripMenuItem_Click() Sub:

Player.Stop()

Click on the [Design] Tab to view the form again, then Click on "Media" on the MenuStrip, then Double Click on the Menu Item Labeled "Slower Speed" (SlowerSpeedToolStripMenuItem) and type the following in the SlowerSpeedToolStripMenuItem_Click() Sub:

If Player.Speed > 1 Then
  Player.Speed -= 100
End If

Click on the [Design] Tab to view the form again, then Click on "Media" on the MenuStrip, then Double Click on the Menu Item Labeled "Normal Speed" (NormalSpeedToolStripMenuItem) and type the following in the NormalSpeedToolStripMenuItem_Click() Sub:

Player.Speed = 1000

Click on the [Design] Tab to view the form again, then Click on "Media" on the MenuStrip, then Double Click on the Menu Item Labeled "Faster Speed" (FasterSpeedToolStripMenuItem) and type the following in the FasterSpeedToolStripMenuItem_Click() Sub:

If Player.Speed < 2000 Then
  Player.Speed += 100
End If

Click on the [Design] Tab to view the form again, then Click on "Media" on the MenuStrip, then Double Click on the Menu Item Labeled "Repeat" (RepeatToolStripMenuItem) and type the following in the RepeatToolStripMenuItem_Click() Sub:

Player.Repeat = RepeatToolStripMenuItem.Checked

See Below:

Media Menu Events

Step 31

Click on [Design] tab or double click on the frmMain entry in Solution Explorer again, click "Audio", then Double Click on the Menu Item Labeled "Volume Up" (VolumeUpToolStripMenuItem) and type the following in the VolumeUpToolStripMenuItem_Click() Sub:

If Player.Volume < 1000 Then
  Player.Volume += 100
End If

Click on [Design] tab or double click on the frmMain entry in Solution Explorer again, click "Audio", then Double Click on the Menu Item Labeled "Volume Normal" (VolumeNormalToolStripMenuItem) and type the following in the VolumeNormalToolStripMenuItem_Click() Sub:

Player.Volume = 500

Click on [Design] tab or double click on the frmMain entry in Solution Explorer again, click "Audio", then Double Click on the Menu Item Labeled "Volume Down" (VolumeDownToolStripMenuItem) and type the following in the VolumeDownToolStripMenuItem_Click() Sub:

If Player.Volume > 0 Then
  Player.Volume -= 100
End If

Click on [Design] tab or double click on the frmMain entry in Solution Explorer again, click "Audio", then Double Click on the Menu Item Labeled "Balance Left" (BalanceLeftToolStripMenuItem) and type the following in the BalanceLeftToolStripMenuItem_Click() Sub:

If Player.Balance > 0 Then
  Player.Balance = -100
End If

Click on [Design] tab or double click on the frmMain entry in Solution Explorer again, click "Audio", then Double Click on the Menu Item Labeled "Balance Equal" (BalanceEqualToolStripMenuItem) and type the following in the BalanceEqualToolStripMenuItem_Click() Sub:

Player.Balance = 500

Click on [Design] tab or double click on the frmMain entry in Solution Explorer again, click "Audio", then Double Click on the Menu Item Labeled "Balance Right" (BalanceRightToolStripMenuItem) and type the following in the BalanceRightToolStripMenuItem_Click() Sub:

If Player.Balance < 1000 Then
  Player.Balance += 100
End If

Click on [Design] tab or double click on the frmMain entry in Solution Explorer again, click "Audio", then Double Click on the Menu Item Labeled "Mute Left" (MuteLeftToolStripMenuItem) and type the following in the MuteLeftToolStripMenuItem_Click() Sub:

Player.Mute = (MuteLeftToolStripMenuItem.Checked And mPlayerControl.Channels.Left) _
        Or (MuteRightToolStripMenuItem.Checked And mPlayerControl.Channels.Right)

Click on [Design] tab or double click on the frmMain entry in Solution Explorer again, click "Audio", then Double Click on the Menu Item Labeled "Mute Right" (MuteRightToolStripMenuItem) and type the following in the MuteRightToolStripMenuItem_Click() Sub:

Player.Mute = (MuteLeftToolStripMenuItem.Checked And mPlayerControl.Channels.Left) _
        Or (MuteRightToolStripMenuItem.Checked And mPlayerControl.Channels.Right)

See Below:

Audio Menu Events

Step 32

Click on the [Design] Tab to view the form again or double click on the frmMain entry in Solution Explorer, then Double-click on the Trackbar, and type the following in the TrackBar_Scroll(...) Sub:

Dim Mute As mPlayerControl.Channels = Player.Mute
Player.Mute = mPlayerControl.Channels.Both ' Mute for Scroll
Player.MoveToTime(TrackBar.Value) ' Move to Time
Player.Mute = Mute ' Restore Previous Mute Value after Scroll

See Below:

Trackbar Scroll Event

Step 33

Click on the [Design] Tab to view the form again or double click on the frmMain entry in Solution Explorer, then Double-click on the Timer called Display in the Pane below frmMain, and type the following in the Display_Tick(...) Sub:

Dim TotalSeconds As Long = CLng(Player.TotalTime / 1000)
Dim CurrentSecond As Long = Player.CurrentTime
If CurrentSecond >= TrackBar.Minimum And CurrentSecond <= TrackBar.Maximum Then
  TrackBar.Value = CInt(CurrentSecond)
Else
  TrackBar.Value = TrackBar.Minimum
End If

See Below:

Timer Tick Event

Step 34

Click on the [Design] Tab to view the form again, then Double Click on the Form (frmMain) and type the following in the frmMain_Load() Sub

Me.Text = "mPlayer"

See Below:

frmMain Load Event

Step 35

Steps 35-38 are optional and just add Keyboard Shortcuts to the MenuItems, you don't have to do these if you don't want to!
Click on the [Design] Tab to view the form again, click on "Open" on the MenuStrip then in the Properties box look for the "ShortcutKeys" option and click on the Drop Down arrow where "None" appears. Check the "Ctrl" Checkbox in "Modifiers" and then in the "Key" dropdown list select "O", see below:

File Menu Open Menu Item Shortcut Key

Step 36

Set the "Close" "ShortcutKeys" Property in the Properties box to "Ctrl+W", the File Menu should then appear as below:

File Menu with Shortcut Keys

Step 37

Click on or select the "Media" Menu and set the "ShortcutKeys" Properties for the following Menu Items, "Play/Pause" should be set to "Ctrl+P", "Stop" to "Ctrl+S". "Slower Speed" should be "Ctrl+Shift+S", "Normal Speed" to "Ctrl+Shift+N" and "Faster Speed" to "Ctrl+Shift+G". Repeat should be set to "Ctrl+T". The Media Menu should appear as below:

Media Menu with Shortcut Keys

Step 38

Click on or select the "Audio" Menu, select "Balance Left" and in the "ShortcutKeys" property type "Ctrl+L", select "Balance Equal" and type "Ctrl+E" in the "ShortcutKeys" property, "Balance Right" should be set to "Ctrl+R". "Mute Left" to "Ctrl+Shift+L" and "Mute Right" set to "Ctrl+Shift+R". The Audio Menu should appear as below:

Audio Menu with Shortcut Keys

Step 39

Save the Project as you have now finished the application, then click on Start:

Start

When you do the following will appear:

mPlayer Running

Step 40

You can Open Audio and Video and play them using mPlayer such as MPEG and MP3 Audio, see below:

mPlayer

Step 41

Click File then Exit or click on the Close button Close on the top right of mPlayer to end the application.

As you can see this is a very useful Media Playing application, you can try adding more features such as Fast forward, Rewind and Bookmarks (using Clips). Try enhancing the user-interface with buttons and more to make it your own Media Player!