Introduction:
This article describes
a quick and easy approach to playing sound files on an ASP.NET web page in
response to an event. The approach is based upon an included web custom control
used to embed the sound into the web page; this control exposes a sound file
path property that may be used to change the associated sound file between
postbacks and in response to events fired from the web page.
The web custom control
included with this article is compatible with Internet Explorer and Firefox; it
has not been tested against any other browsers. Aside from providing a
demonstration of playing sounds in response to events, the included source code
does provide an easy example of embedding objects in web pages by means of a web
custom control; as such, the example could be used as the basis for creating
other controls used to embed other types of objects into a web page.
Getting Started:
In order to get
started, unzip the included source code. Within the zip file you will note that
there are two separate projects, one is the custom control itself and the other
is a test website used to demonstrate the use of the control. Create a virtual
directory for the website and then open the web custom control library into the
Visual Studio 2005 IDE. If the solution does not open with the website, add the
website to the solution.
The Code: The Custom Web Control Library
Project.
Within the custom web
control library project (MakeNoise) you will note that there is a single custom
control included (PlayPageSound.vb). Open the class and take a look at the
code; the class imports and definition were all left in their default
configuration. After the class declaration, you will note the following code in
the initialization event:
Private Sub PlayPageSound_Init(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Me.Init
'just
to let you see it on the form
Me.Width
= 24
Me.Height
= 24
End Sub
This initialization
code is used to set the control to 24 pixels by 24 pixels; this does not serve
any purpose at runtime however at design time it provides the programmer with a
box that they can click on if they need to get access to the control's
properties. It is not necessary to set the box to this size, it is only done to
make it easier to manage the control at design time. At runtime the control
will not be visible to the user.
Following the
initialization, the one and only property in the control is established. The
property added used to set the path to the sound file; that code looks like
this:
<Category("Sound File")>
_
<Browsable(True)> _
<Description("Set the location
for the sound file")> _
Property SoundFile() As String
Get
Dim s As String = CStr(ViewState("SoundFile"))
If s Is Nothing Then
Return String.Empty
Else
Return s
End If
End Get
Set(ByVal Value As String)
ViewState("SoundFile")
= Value
End Set
End Property
Note that the Sound
File path is set and retrieved from view state. The attributes at the beginning
of the property declaration are used to set the text in the property grid for
both the category and the description areas.
The only remaining
code in the control is used to establish how the page will render the control at
runtime; again this is very simple and the code looks like this:
Protected Overrides Sub RenderContents(ByVal writer As HtmlTextWriter)
Try
Dim sb As New StringBuilder
sb.Append("<embed
src='" & SoundFile.ToString()
& "'")
sb.Append("
autostart='true' loop='false' visible='false'
width='0'
height='0' ")
sb.Append("</embed>")
writer.RenderBeginTag(HtmlTextWriterTag.Div)
writer.Write(sb.ToString())
writer.RenderEndTag()
Catch ex As Exception
writer.RenderBeginTag(HtmlTextWriterTag.Div)
writer.Write("PlayPageSound
Control")
writer.RenderEndTag()
End Try
End Sub
The overridden Render
Contents subroutine uses a string builder to piece together the code used to
embed the sound into the page. In this instance, only the string pointing to
the location of the sound file is changed based upon the current contents of the
Sound File property; however, using this same approach one could add other
properties such a Loop, Visible, Auto-start, Height and Width and then set them
in a manner consistent with what is shown here for setting the sound file
property. Given this configuration, the control will not display a visible UI
during the sound's playback. If one were to set the control to be visible and
then give some height and width dimension, the control will display a media
player interface to the user whenever the sound is playing. If the UI were made
visible, in Internet Explorer, the Microsoft Media Player control's interface
would be displayed, in Firefox, the Quick Time player interface would be shown.
Once the emded tag is
created, the HTML Text Writer is used to place the embed tag within a div. If
anything were to go wrong and an exception was thrown, the catch block will
capture the exception and the HTML Text Writer is then used to write the name
of the control onto the page.
The Code: The Test Web Site.
Open up the test web
site; notice that the site consists of a single web page (default.aspx). The
site is setup to simulate an online test; to that that end, the page displays
three questions to the user, keeps track of the number of correct responses, and
displays messages to the user whenever the user answers a question correctly or
incorrectly, and it plays a sound whenever the user gets an answer correct and a
different sound whenever the user misses the answer.
This web page contains
a single instance of the Play Page Sound custom control. Depending upon whether
or not a user clicks on the right answer or the wrong answer, the control's
Sound Path property is set to play the appropriate sound. Each radio button
list (used to show the user the answer options) has its AutoPostBack property
set to true so that the correct sound will load and play in response to the
user's selection. If you did not set the AutoPostBack property to true, the
sound would not play until some other event called a post back.
Take a quick look at
the handler associated with an selected index changed to one of the radio button
lists:
Protected Sub RadioButtonList1_SelectedIndexChanged(ByVal sender As Object, ByVal e AsSystem.EventArgs) Handles RadioButtonList1.SelectedIndexChanged
If RadioButtonList1.SelectedIndex
= 2 Then
Me.PlayPageSound1.SoundFile
= "applaus8.wav"
lblStatus.Text
= "<b>That's
Right!</b>"
Else
Me.PlayPageSound1.SoundFile
= "burp.wav"
lblStatus.Text
= "<b>You
missed that one, try it again</b>"
End If
EvaluateResponses()
End Sub
In this instance, the
third answer in the list is correct and the other three options are incorrect.
Whenever the user selects the correct response, the Play Page Sound control's
Sound File property is set to a wave file called "applaus8.wav". In all other
options, the Sound File property is set to a wave file called "burp.wav". After
setting the sound to point at the correct wave file, a call is made to a
subroutine called, "EvaluateResponses()". This subroutine looks like this:
Private Sub EvaluateResponses()
Dim correct As Integer =
0
If Me.RadioButtonList1.SelectedIndex
= 2 Then
correct
+= 1
End If
If Me.RadioButtonList2.SelectedIndex
= 3 Then
correct
+= 1
End If
If Me.RadioButtonList3.SelectedIndex
= 1 Then
correct
+= 1
End If
Me.lblResponses.Text
= correct.ToString() & "
of 3 Answered
Correctly."
End Sub
As you can see, this
subroutine checks each radio button list to see if the correct item has been
selected and for each correct response on the page, it updates an integer
variable called "correct" to contain that list. After calculating the score,
the integer variable is used to update the text used to display the number of
correct responses made.
That pretty much
covers it, the web page in operation looks like this:
Figure 1: Test Web Site In Operation
Summary.
This article discussed
a simple method that may be used to bring sound to a web site through the use of
a custom control. There are other available methods including pure JavaScript
methods that will do the same thing. This approach demonstrates using a
post-back event as the basis for loading and playing a new sound, if you need or
want to play sounds without the post-back, then you should look to the pure
JavaScript approaches.