Extending My.Computer.Audio To Play MP3’s
July 17th, 2007
The My.Computer namespace in VB.NET 2005 provides several ’speed dials’ to various system functions. For example, it can be used to play WAV audio files. Unfortunately, it can’t play other media types like MP3, WMA or MIDI so that limits its usefulness. However, you can extend this, or any other My namespace class, by using partial classes. That’s what I’ll be demonstrating in this article.
For this demo, I used the “PlayingSounds” project from the 101 Visual Basic Samples for WinForms examples from MSDN. These little demo programs are great quick examples on how to do a number of things in VB although they often need a few loose ends tied up to make them work their best.
To get started, we open up the Application Events module. This module exposes the My namespace where we can add functionality to our applications. I covered using it in this earlier article: Tip Sheet: Application Events. Now we need to add a Partial Class to the My namespace to overload the Audio property, like so:
Partial Class MyComputer
Overloads ReadOnly Property Audio() As Audio
Get
Return New Audio
End Get
End Property
End Class
This returns our own Audio object rather than the built in one. Now we are ready to create our own Audio class to play the additional sound files.
First, we need to load a reference to Windows Media Player. So, we go to My Project and the References tab and select “Add Reference”. WMP is a COM object so we select that tab and pick Windows Media Player (wmp.dll) from the list.
Next, we start our own Audio class by inheriting the base Audio class:
Public Class Audio
Inherits Microsoft.VisualBasic.Devices.Audio
The next part of our code contains a shared reference to the Windows Media Player as well as a indicator of the type of sound we’re playing, if any. Since we only want to play one sound file at a time we use a shared variable here. Also an enum for the sound types is added. We want to keep track of which type of sound is loaded into our audio object since system sounds will use the original Audio class. Here’s the code:
Private Enum SoundTypes
NoSoundLoaded
WmpSound
WavAudioSound
End Enum
Private Shared SoundType As SoundTypes = SoundTypes.NoSoundLoaded
Private Shared WMP As New WMPLib.WindowsMediaPlayer
Now we want to create our overloads for the Play function. The first one has no parameters:
Public Overloads Sub Play()
If SoundType = SoundTypes.WmpSound AndAlso _
WMP.playState = WMPLib.WMPPlayState.wmppsPaused Then
WMP.controls.play()
End If
End Sub
In this routine we want to continue playing the currently loaded sound if we’re playing a sound using Windows Media Player and the player is paused. Otherwise, we want to ignore this command. Note that the AndAlso ’short circuits’ the If..Then so if the type is not WMP the state of the player isn’t checked.
Our next two Play overloads allows us to pass in a file location to play. Note that this can be either a local file location or even a URL on a web site. The first only accepts a file location and sends the actual processing to the second play routine which also accepts the Microsoft.VisualBasic.AudioPlayMode.
Public Overloads Sub Play(ByVal fileLocation As String)
Play(fileLocation, AudioPlayMode.Background)
End Sub
Public Overloads Sub Play(ByVal fileLocation As String, _
ByVal playmode As Microsoft.VisualBasic.AudioPlayMode)
If SoundType <> SoundTypes.NoSoundLoaded Then
Me.Stop()
End If
Select Case New FileInfo(fileLocation).Extension.ToLower
Case ".wma", ".mp3", ".mid", ".wav"
WMP.URL = fileLocation
Select Case playmode
Case AudioPlayMode.BackgroundLoop
WMP.settings.setMode("loop", True)
WMP.controls.play()
Case Else
WMP.settings.setMode("loop", False)
WMP.controls.play()
End Select
SoundType = SoundTypes.WmpSound
Case Else
Throw New Exception("Invalid File Type")
End Select
End Sub
We want to stop any sound that is currently playing first and then load the new sound into Windows Media Player and play it. If the file extension isn’t a recognized type, we throw an exception. Another approach would be to try to play anything passed to the player and capture any exceptions raised by the player object or to simply ignore any invalid file names without raising an exception. If the second parameter passed in to the routine is AudioPlayMode.BackgroundLoop then we want to play the file over and over until it is stopped. Otherwise, we only want to play it once.
Our remaining Play overloads call the base class. In addition to this call, we add code to stop the currently playing file and an indicator of the file type being played. For the system sounds overloads we add an overload to the standard Play method for this purpose as well as overloading the base PlaySystemSound method.
Public Overloads Sub Play(ByVal systemSound As System.Media.SystemSound)
If SoundType <> SoundTypes.NoSoundLoaded Then
Me.Stop()
End If
MyBase.PlaySystemSound(systemSound)
SoundType = SoundTypes.WavAudioSound
End Sub
Public Overloads Sub PlaySystemSound(ByVal systemSound As System.Media.SystemSound)
If SoundType <> SoundTypes.NoSoundLoaded Then
Me.Stop()
End If
MyBase.PlaySystemSound(systemSound)
SoundType = SoundTypes.WavAudioSound
End Sub
Public Overloads Sub Play(ByVal mediaData() As Byte, _
ByVal playMode As Microsoft.VisualBasic.AudioPlayMode)
If SoundType <> SoundTypes.NoSoundLoaded Then
Me.Stop()
End If
MyBase.Play(mediaData, playMode)
SoundType = SoundTypes.WavAudioSound
End Sub
Public Overloads Sub Play(ByVal mediaStream As System.IO.Stream, _
ByVal playMode As Microsoft.VisualBasic.AudioPlayMode)
If SoundType <> SoundTypes.NoSoundLoaded Then
Me.Stop()
End If
MyBase.Play(mediaStream, playMode)
SoundType = SoundTypes.WavAudioSound
End Sub
Now that we have all the play routines taken care of, we’re ready to stop the playing.
Public Overloads Sub [Stop]()
Select Case SoundType
Case SoundTypes.WmpSound
WMP.controls.stop()
Case SoundTypes.WavAudioSound
MyBase.Stop()
Case Else
'do nothing - if desired, add code to throw an exception here
End Select
SoundType = SoundTypes.NoSoundLoaded
End Sub
In this routine we use our sound type enum to determine which method we should use to stop the sound. Note that the Stop routine name is in brackets so that the compiler won’t get it confused with the base VB command of the same name.
Lastly, we add a Pause method. This isn’t in the base class but we’re extending this base to add new functionality.
Public Sub Pause()
Select Case SoundType
Case SoundTypes.WmpSound
WMP.controls.pause()
Case Else
'do nothing - if desired, add code to throw an exception here
End Select
End Sub
Files being played in the base Audio class can only be stopped and started but by using WMP we can pause them as well. This adds another useful function to our new inherited class.
The rest of the application is simply a few improvements to the example program. I added in a pause button checkbox and made a few other enhancements to the program, such as adding in XML comments and improving the file lookup. The code should be fairly self-explanitory but feel free to ask any questions about it here in the comments section. Also, if you notice any bugs or have suggestions for enhancements, please leave a comment.
You can download the code for this project here: PlayingSoundsPlus Code Example
Entry Filed under: Code Examples
Rate This Article:










4 Comments Add your own
1. Baruch Berkovits | January 5th, 2008 at 2:32 pm
Great article and great code !!!
Thanks very much.
2. Amino | October 5th, 2008 at 11:07 pm
Very cool article.
Is it possible to loop through the songs automatically using this code?
3. Mike B | November 4th, 2008 at 6:58 pm
So, what if you wanted to play an mp3 file from an embedded resource? I can’t find a way to do that… I would stream it from the resource, but the overload for playing a stream seems to work for wav files only.
4. Raj | April 17th, 2009 at 2:12 pm
How can I play two audio files (Mp3) at the same time but each audio file should have its own controls for stop, pause, volume control etc…. i would greatly appreciate any help with the codes
Thanks!
Raj.
Leave a Comment
Some HTML allowed:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>
Trackback this post | Subscribe to the comments via RSS Feed