2015-12-24 36 views
1

我正在寻找解决方案,以使此代码线程安全的:流写和读?

private Stream ms = new MemoryStream(); 
public void PlayMp3FromUrl(string url) 
{ 
    new Thread(delegate(object o) 
    { 
     var response = WebRequest.Create(url).GetResponse(); 
     using (var stream = response.GetResponseStream()) 
     { 
      byte[] buffer = new byte[65536]; // 64KB chunks 
      int read; 
      while ((read = stream.Read(buffer, 0, buffer.Length)) > 0) 
      { 
       var pos = ms.Position; 
       ms.Position = ms.Length; 
       ms.Write(buffer, 0, read); 
       ms.Position = pos; 
      } 
     } 
    }).Start(); 

    // Pre-buffering some data to allow NAudio to start playing 
    while (ms.Length < 65536*10) 
     Thread.Sleep(1000); 

    ms.Position = 0; 
    using (WaveStream blockAlignedStream = new BlockAlignReductionStream(WaveFormatConversionStream.CreatePcmStream(new Mp3FileReader(ms)))) 
    { 
     using (WaveOut waveOut = new WaveOut(WaveCallbackInfo.FunctionCallback())) 
     { 
      waveOut.Init(blockAlignedStream); 
      waveOut.Play(); 
      while (waveOut.PlaybackState == PlaybackState.Playing) 
      { 
       System.Threading.Thread.Sleep(100); 
      } 
     } 
    } 
} 

您不能更改ms.Positionms.Write,而你使用n音讯发挥它是在同一时间,是吗?任何解决方案,使其线程安全?

此外,如果流是无尽的或非常大,如何清除已播放的流部分?

+0

为什么不使用委托作为回调线程?收到数据后,检查它是否符合您的要求,如果有,请调用回调。这就是我会做的。另一件事是创建一个'AutoResetEvent'并在需求满足时触发它。 –

回答

1

有一个从NAudio源代码中的URL流式传输MP3的例子(查看NAudioDemo项目的MP3 streaming demo)。我建议的方法是在将每个MP3帧解码为PCM之后接收到的音频填充BufferedWaveProvider