使用NAudio将流数据保存到WAV文件 [英] Save streaming data to a WAV file using NAudio

查看:323
本文介绍了使用NAudio将流数据保存到WAV文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to save the incoming stream data to a WAV file on my hard disk drive. How can I change the code below to be able to record the stream into a valid WAV file?

从演示此处:

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文件:

I wouldn't take that particular approach to saving to disk. It's a bit too hands-on, because it has to deal with playing back at the right rate. Just buffer up the response, and then wrap it in an Mp3FileReader stream and use WaveFileWriter to write the WAV file:

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播放器兼容.如果不是,则还需要注入并添加WaveFormatConversion流.

That does, of course, assume that your MP3 file's wave format is compatible with WAV and in particular, your WAV player. If it isn't, you'll need to inject and add a WaveFormatConversion stream as well.

这篇关于使用NAudio将流数据保存到WAV文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆