从 WPF 中的内存流(不包含 wav 标头)播放

Posted

技术标签:

【中文标题】从 WPF 中的内存流(不包含 wav 标头)播放【英文标题】:Play from a memory stream(which doesn't contain wav headers) in WPF 【发布时间】:2015-06-19 13:13:51 【问题描述】:

我尝试连接一些不同持续时间但采样率相同的数据。 我用MemoryStream.CopyTo(memoryStream) 方法连接数据。

有什么方法可以播放开头没有 wav 标头的内存流中的数据?

如果没有,有没有办法在附加流之后附加一个 wav 标头来启动?

(我想避免在磁盘中生成文件..)

【问题讨论】:

Play wav/mp3 from memory的可能重复 @goobering 除了他们在寻找 naudio 您好,您提供的链接会生成一个类,该类使用包含 wav 标头的缓冲区。我的缓冲区不包含标题。我得到了这个异常:> System.dll 中发生了“System.InvalidOperationException”类型的未处理异常附加信息:波头已损坏。 你可以创建文件然后动态删除它吗? 我想避免这种情况。我更喜欢在播放后处理流而不是处理文件 【参考方案1】:

要使用 NAudio 执行此操作,只需使用 RawSourceWaveStream 并将包含原始连接音频的 MemoryStream 传递给其构造函数。您还需要明确指定 WaveFormat 是。

memoryStream = ... // construct your audio
memoryStream.Position = 0; // rewind to beginning
var rs = new RawSourceWaveStream(memoryStream, new WaveFormat(sampleRate, 16, 1));

【讨论】:

【参考方案2】:

您可以将标题写入流,然后使用SoundPlayer 播放 WAV。

    //your wav streams
    MemoryStream wavNoHeader1=new MemoryStream();
    MemoryStream wavNoHeader2 = new MemoryStream();
    //result WAV stream
    MemoryStream wav=new MemoryStream();
    //create & write header
    ushort numchannels = 1;
    ushort samplelength = 1; // in bytes
    uint samplerate = 22050;
    int wavsize = (int) ((wavNoHeader1.Length + wavNoHeader2.Length)/(numchannels*samplelength));
    BinaryWriter wr = new BinaryWriter(wav);
    wr.Write(Encoding.ASCII.GetBytes("RIFF"));
    wr.Write(36 + wavsize);
    wr.Write(Encoding.ASCII.GetBytes("WAVEfmt "));
    wr.Write(16);
    wr.Write((ushort)1);
    wr.Write(numchannels);
    wr.Write(samplerate);
    wr.Write(samplerate * samplelength * numchannels);
    wr.Write(samplelength * numchannels);
    wr.Write((ushort)(8 * samplelength));
    wr.Write(Encoding.ASCII.GetBytes("data"));
    wr.Write(numsamples * samplelength);
    //append data from raw streams
    wavNoHeader1.CopyTo(wav);
    wavNoHeader2.CopyTo(wav);
    //play
    wav.Position = 0;
    SoundPlayer sp=new SoundPlayer(wav);
    sp.Play();

【讨论】:

您好,感谢您的回答,最上面的 uint numsamples = 44100 和 uint samplerate = 22050 有什么区别? 您好,我假设 wav 标头包括音频文件的总长度。但是我连接的wav文件在进度开始时是未知的...... 是的,我错过了,生成的 WAV 数据的长度应该在标题中,编辑了我的代码。如果您不知道源流的大小,您可能应该创建某种缓冲区。 如何制定结果长度?如果我的每个样本都是 2 个字节,那么 ushort samplelength 必须等于 2?

以上是关于从 WPF 中的内存流(不包含 wav 标头)播放的主要内容,如果未能解决你的问题,请参考以下文章

使用 NAudio 从内存流中播放 .wma

在 NAudio 中添加 WAV 标头

如何从内存中播放 Wav 声音样本

从 wav 流播放

使用 c# wpf 从资源文件播放声音

使用 MediaPlayer 类从内存播放 WAV 文件