Last post Feb 01, 2009 01:33 PM by Ed Dolikian
Jan 29, 2009 10:48 AM|Ed Dolikian|LINK
I've got a database where I'm storing a byte stream (Contents of a Wave File) as an array.
Upon selection of a record in the GridView, I'd like to be able to play the file back when selected from a gridview object. It seems that GridView only returns text so I've resorted to some workarounds.
One is to save output to a file and then play the file. The second is to create a stream object and play the stream.
What is weird is that it works on my development server (e.g. in debug mode) but doesn't work when I publish to my website or try to access from an external machine. It seems to play but I don't hear anything. Is this a Client Side / Server side issue?
File rights issue? Postback issue?
Any ideas or guidance would be much appreciated to help me understand.
Here is a snippet of my code.. attached to the GrivView Selected Event
' The following routine will create a file from the byte stream stored in the database' I have also experimented with passing back an IOStream object but have commented out the line.
dr = DS.Tables(0).Rows(0)
recordingstream.Write(arrContent, 0, NumBytes)
' Method 2 is to pass back an IO Stream to avoid writing out to disk. / Commented Out
' Dim iostream as new System.io.memorystream(arrContent,0,numbytes)
Jan 29, 2009 01:25 PM|NC01|LINK
Probably a file permissions error. A web page cannot normally write to the root of the C drive (c:\soundfile.wav), except maybe on your dev machine where the server and client are the same.
Try: Dim tempvoicepath As String = Server.MapPath("soundfile.wav") and you will need to give the ASPNET machine account read/write access to the application virtual, which web masters do not generally like to do.
The best solution is to create a sub-folder called, lets say WavFiles inside of the application virtual, and give the ASPNET machine account read/write access just to that folder. Then the path would be:Server.MapPath("WavFiles/soundfile.wav")
Jan 29, 2009 04:41 PM|Ed Dolikian|LINK
Jan 30, 2009 07:15 AM|NC01|LINK
To enable you to set the permissions (if you see the securities tab in the file properties dialog, this is already done):
Open the folder and click on Tools in the menubar
Select Folder Options
Select the View tab
Un-check >>Use simple file sharing (Recommended)<<
To set the permissions:
Right-click on the folder/file in Windows Explorer
Choose Properties in the resultant context menu
Select the Security tab
If the ASPNET Machine Account is not listed in the upper pane
Click the Add... button
Type ASPNET in the textbox
Click the Check Names button
Click the OK button
Select the ASPNET Machine Account in the upper pane
Check Modify in the checkbox list/lower pane
Click the Apply button
Jan 30, 2009 09:27 AM|Ed Dolikian|LINK
My app is now allowing me to create the soundbyte wave file. So that "rights" issue is solved. In other words, when I select the record, the soundbyte.wav file is being updated. If I manually double click on the file in explorer, it opens media player
and plays it correctly.
I moved/copied the code to the load event of the form to play whatever is in the current file when the page loads to double check that the path is correct and not a timing issue between when file is created / played. The filepath returned points to the c:\inetpub\wwwroot\SoundbytesWebSite\Wavfiles\soundbyte.wav
which is correct.
I also wrapped it in a Try Catch block to make sure no error being return. OK.
I am still not hearing the SoundPlayer output. Normally you hear a click followed by the audio followed by another click when done playing. I'm not hearing that like I do on the development site.
Do I need to enable execution of that object as well? Add a reference? Turn on speakers?
Not to complicate things but another thing that is not working is the annoucement of the DateTime recorded using the SAPI library. Until we figured this out, I disabled that so as to keep things simple. Perhaps the same problem but a clue as to what is
missing. I use this to announce the date/time of the selected recording.
Jan 30, 2009 10:08 AM|NC01|LINK
Not sure what you are doing differently, but this worked for me:
Private Sub executeButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Dim speachText As String = "Hello to my Talking Site"
voiceObject = Server.CreateObject("SAPI.SpVoice")
Jan 30, 2009 11:10 AM|Ed Dolikian|LINK
I don't want to lose sight of the fact that my main issue is the playback of the sound. I'm curious if you are also able to playback a soundplayer object in the same way as the voiceObject.
I created a new button and inserted your code to test it again. Again it works on my development server but not on published site.
This time on the SAPI object I did get an error though and perhaps this is decribing the underlying problem ... Can you give me an idea of what I should do different? (error message at end of post)
Your sample code that you sent me did not have a Handles Button.click. Should I be coding this differeetly? Setting up an event handler? Again, I'm a newbie so excuse me if this is obvious or a dumb question.
I'm wondering if this is an issue dealing with how I have published the site. I am going to create a new site and see if that solves the problem.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Runtime.InteropServices.COMException: Exception from HRESULT: 0x80045063
Line 195: objvoice = CreateObject("SAPI.SpVoice")
Line 196: Dim strsaysomething As String = "Hello to my Talking Site"
Line 197: objvoice.speak(strsaysomething)
Line 195: objvoice = CreateObject("SAPI.SpVoice")
Source File: C:\inetpub\wwwroot\SoundBytesWebSite\DailyLog.aspx.vb Line: 197 Stack Trace:
[COMException (0x80045063): Exception from HRESULT: 0x80045063]
Microsoft.VisualBasic.CompilerServices.LateBinding.InternalLateCall(Object o, Type objType, String name, Object args, String paramnames, Boolean CopyBack, Boolean IgnoreReturn) +776
Microsoft.VisualBasic.CompilerServices.NewLateBinding.LateCall(Object Instance, Type Type, String MemberName, Object Arguments, String ArgumentNames, Type TypeArguments, Boolean CopyBack, Boolean IgnoreReturn) +367336
DailyLog.Button3_Click(Object sender, EventArgs e) in C:\inetpub\wwwroot\SoundBytesWebSite\DailyLog.aspx.vb:197
System.Web.UI.WebControls.Button.OnClick(EventArgs e) +105
System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +107
System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +7
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +11
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +33
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1746
Version Information: Microsoft .NET Framework Version:2.0.50727.1434; ASP.NET Version:2.0.50727.1434
Jan 30, 2009 01:11 PM|NC01|LINK
1. I didn't use the Handles clause because I attached the handler like this:
<asp:button id="executeButton" runat="server" text="Execute" OnClick="executeButton_Click"></asp:button>
I also do not use usually VB.NET, but that's another story [:D]
2. Since that is a generic COM error, there is no way that I (or anyone for that matter) could know what the problem actually is. Here is a link that might help you further:
Jan 30, 2009 01:45 PM|gunteman|LINK
Is this a Client Side / Server side issue?
It very much is! SoundPlayer is a wrapper around Windows' media playback functions, and while it is possible to use it from ASP.NET, doing so means that you are invoking the media functions where the code is run, i.e on the server! I doubt that is what you
wanted, unless the purpose is to entertain the server room technicians :)
If you want client side playback, you must use an embedded media player, and point to play the file from a URL you provide.
And on a completely unrelated issue...
Always use parametrized queries
strSql = "Select * from Activity_Log where RecID = @RecordID"
Dim ConnString As String = Me.SqlDataSource1.ConnectionString
DA = New SqlClient.SqlDataAdapter(strSql, ConnString)
Feb 01, 2009 01:33 PM|Ed Dolikian|LINK
Thanks for the MAJOR clarifications. So all along when I though it was working it wasn't cause "I was the consoler operator in the server room" and was hearing the messages. As Ricky Ricardo used to say "That xplains verything Lucy"[:D]
For anyone interested...
I did do more research and was able to integrate a solution using the following link as a guide. I guess SoundPlayer is embedded in page and simply setting property of file to play prior to loading page. I had actually read that before but when I had integrated
a desktop solution in a web app and thought it was working, was simply headed down the wrong path.
I am at the point where it will play a "static / existing file" when displaying page but not a file that was created just prior to/during select button click. Perhaps just a timing issue or file being saved on client side? or not available yet? <if you
have any insight to the following questions, I'd apprecaite it>. I'd really like to put this topic to bed! Again, I'm new to asp.net and these may be very basic questions.
Clicking the "Select" on the GridView serves to create / update the Soundbyte.wav file in the Wavfiles folder from the contents of the selected record.
Each time the page is loaded / posted back, the embedded control plays the contents of that same file by setting the SoundFile property. It is actually set as the default but it should play what ever is in the file. I'm finding this works if I point the
reference at a wav file not being updated. Wav file is being created as after clicking, on file in explorer, it plays correct file.
My second objective is to have a "Play all" button that literally starts at the top of the list and synchronously plays each record in succession. Perhaps I need a start/pause/stop button to stop execution. How does one know when the last record is done
Lastly, I'd like to be able to use Speech to annouce the date and time of the recording prior to playback thus the output would be...
"Sunday Feb 1, 11 15 AM... <play soundbyte.wav file> goto next record and repeat for each subsequent record in the list.
I also have come across the following SDK from Microsoft that probably would allow me to integrate this into my solution.
Thanks to all for getting me pointed it the right direction.