Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to play non buffered WAV with MediaStreamSource implementation in Silverlight 4?

Background

I'm trying to stream a wave file in Silverlight 4 using MediaStreamSource implementation found here. The problem is I want to play the file while it's still buffering, or at least give user some visual feedback while it's buffering. For now my code looks like that:

private void button1_Click(object sender, RoutedEventArgs e)
{
    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(new Uri(App.Current.Host.Source, "../test.wav"));
    //request.ContentType = "audio/x-wav";
    request.AllowReadStreamBuffering = false;
    
    request.BeginGetResponse(new AsyncCallback(RequestCallback), request);
}

private void RequestCallback(IAsyncResult ar)
{
    this.Dispatcher.BeginInvoke(delegate()
    {
        HttpWebRequest request = (HttpWebRequest)ar.AsyncState;
        HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(ar);

        WaveMediaStreamSource wavMss = new WaveMediaStreamSource(response.GetResponseStream());
        
        try
        {
            me.SetSource(wavMss);
        }
        catch (InvalidOperationException)
        {
            // This file is not valid
        }
        me.Play();
    });
}

The problem is that after setting request.AllowReadStreamBuffering = false the stream does not support seeking and the above mentioned implementation throws an exception (keep in mind I've put some of the position setting logic into if (stream.CanSeek) block):

Read is not supported on the main thread when buffering is disabled

Question

Is there a way to play WAV stream without buffering it in advance in Silverlight 4?

like image 828
kyrisu Avatar asked May 30 '10 18:05

kyrisu


1 Answers

Downloading a stream while you read it is not going to work because reading the steram for playback will move the Position property within the stream, and when you will write data to the stream, the position will not be at the right position. that's basically why you cannot seek in your stream.

What I did to solve that exact problem was to create a custom memory stream (ReadWriteMemoryStream) which would embed the logic for reading / writing so I could download the file on one end, add it to the ReadWriteMemoryStream and base my MediaStreamSource on this ReadWriteMemoryStream instead of the network stream.

You can find my implementation of this ReadWriteMemoryStream here :

https://github.com/salfab/open-syno/blob/master/OpenSyno/OpenSyno/ReadWriteMemoryStream.cs

you can also check the rest of the project in order to have a look at its usage if you are unsure about it.

Hope this helps.

like image 103
Fabio Salvalai Avatar answered Oct 15 '22 09:10

Fabio Salvalai