c# - 使用 NAudio 将流数据保存到 WAV 文件

标签 c# naudio

我想将传入的流数据保存到硬盘驱动器上的 WAV 文件中。如何更改下面的代码才能将流录制到有效的 WAV 文件中?

来自演示here :

private void StreamMP3(object state)
{
    this.fullyDownloaded = false;
    string url = (string)state;
    webRequest = (HttpWebRequest)WebRequest.Create(url);
    HttpWebResponse resp = null;
    try
    {
        resp = (HttpWebResponse)webRequest.GetResponse();
    }
    catch(WebException e)
    {
        if (e.Status != WebExceptionStatus.RequestCanceled)
        {
            ShowError(e.Message);
        }
        return;
    }
    byte[] buffer = new byte[16384 * 4]; // Needs to be big enough to hold a decompressed frame

    IMp3FrameDecompressor decompressor = null;
    try
    {
        using (var responseStream = resp.GetResponseStream())
        {
            var readFullyStream = new ReadFullyStream(responseStream);
            do
            {
                if (bufferedWaveProvider != null &&
                    bufferedWaveProvider.BufferLength - bufferedWaveProvider.BufferedBytes <
                      bufferedWaveProvider.WaveFormat.AverageBytesPerSecond / 4)
                {
                    Debug.WriteLine("Buffer getting full, taking a break");
                    Thread.Sleep(500);
                }
                else
                {
                    Mp3Frame frame = null;
                    try
                    {
                        frame = Mp3Frame.LoadFromStream(readFullyStream);
                    }
                    catch (EndOfStreamException)
                    {
                        this.fullyDownloaded = true;

                        // Reached the end of the MP3 file / stream
                        break;
                    }
                    catch (WebException)
                    {
                        // Probably we have aborted download from the GUI thread
                        break;
                    }
                    if (decompressor == null)
                    {
                        // I don't think these details matter too much - just help ACM select the right codec.
                        // However, the buffered provider doesn't know what sample rate it is working at
                        // until we have a frame.
                        WaveFormat waveFormat = new Mp3WaveFormat(
                                                  frame.SampleRate,
                                                  frame.ChannelMode == ChannelMode.Mono ? 1 : 2,
                                                  frame.FrameLength,
                                                  frame.BitRate);
                        decompressor = new AcmMp3FrameDecompressor(waveFormat);
                        this.bufferedWaveProvider = new BufferedWaveProvider(decompressor.OutputFormat);
                        this.bufferedWaveProvider.BufferDuration = TimeSpan.FromSeconds(20); // Allow us to get well ahead of ourselves
                        //this.bufferedWaveProvider.BufferedDuration = 250;
                    }
                    int decompressed = decompressor.DecompressFrame(frame, buffer, 0);
                    //Debug.WriteLine(String.Format("Decompressed a frame {0}", decompressed));
                    bufferedWaveProvider.AddSamples(buffer, 0, decompressed);
                }

            } while (playbackState != StreamingPlaybackState.Stopped);

            Debug.WriteLine("Exiting");
            // I was doing this in a finally block, but for some reason
            // we are hanging on response stream .Dispose, so we never get there.
            decompressor.Dispose();
        }
    }
    finally
    {
        if (decompressor != null)
        {
            decompressor.Dispose();
        }
    }
}

最佳答案

我不会采用这种特定的方法来保存到磁盘。这有点太手动了,因为它必须以正确的速率进行播放。只需缓冲响应,然后将其包装在 Mp3FileReader 流中并使用 WaveFileWriter 写入 WAV 文件:

MemoryStream mp3Buffered = new MemoryStream();
using (var responseStream = resp.GetResponseStream())
{
    byte[] buffer = new byte[65536];
    int bytesRead = responseStream.Read(buffer, 0, buffer.Length);
    while (bytesRead > 0)
    {
        mp3Buffered.Write(buffer, 0, bytesRead);
        bytesRead = responseStream.Read(buffer, 0, buffer.Length);
    }
}

mp3Buffered.Position = 0;
using (var mp3Stream = new Mp3FileReader(mp3Buffered))
{    
    WaveFileWriter.CreateWaveFile("file.wav", mp3Stream);
}

当然,假设您的 MP3 文件的波形格式与 WAV 兼容,特别是与您的 WAV 播放器兼容。如果不是,您还需要注入(inject)并添加 WaveFormatConversion 流。

关于c# - 使用 NAudio 将流数据保存到 WAV 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15441980/

相关文章:

c# - .Net WebDAV 服务器

c# - 如何玩ISampleProvider

c# - 获取麦克风输入电平音频

c# - NAudio算法播放频率可以实时平滑变化的正弦波

c# - 这个函数如何改变我的只读变量?

c# - 将 XNA 3.1 转换为 XNA 4.0。 StorageContainer.TileLocation

c# - ConfigurationManager.AppSettings 使用另一个配置文件

c# - 如何取消合并单元格 EPPlus?

c# - 使用 WPF 播放 MIDI 文件并与视觉同步时间

c# - 如何在 C#\NAudio 音乐播放器中创建搜索栏?