如何在Silverlight 4中使用MediaStreamSource实现播放非缓冲的WAV文件?

14

背景

我正在尝试使用在这里找到的MediaStreamSource实现,在Silverlight 4中流式传输波形文件。问题是我想在文件仍在缓冲时播放它,或者至少在它缓冲时向用户提供一些视觉反馈。目前我的代码看起来像这样:

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();
    });
}
问题在于设置了request.AllowReadStreamBuffering = false后,该流不支持寻址,上述实现会抛出异常(请注意,我已将部分位置设置逻辑放入 if(stream.CanSeek) 块中):

当禁用缓冲区时,在主线程上不支持读取

问题

在Silverlight 4中有没有一种方法可以播放未经预先缓冲的WAV流?

1个回答

3

当你读取流进行播放时同时下载它是行不通的,因为读取流以进行播放将会移动流中的Position属性,当你向流中写入数据时,位置将不在正确的位置。这基本上就是为什么你不能在流中寻找。

我解决这个问题的方法是创建一个自定义内存流(ReadWriteMemoryStream),其中嵌入了读/写逻辑,因此我可以在一端下载文件,将其添加到ReadWriteMemoryStream中,并将我的MediaStreamSource基于此ReadWriteMemoryStream而不是网络流。

你可以在这里找到我实现的ReadWriteMemoryStream:

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

如果您对此不确定,还可以查看项目的其余部分以了解其使用方法。

希望这能帮到您。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接